データ化学工学研究室物語
第I部 研究室配属前夜のデータ化学工学
研究室配属前の学部三年生が、AI・機械学習を化学・化学工学の研究に使う考え方を学ぶ。
第7章 初めての予測モデル
新人トレーニングの六週目に与えられた課題は、これまで眺め、図にし、地図を作ってきた数字から、まだ見ていない数字を推定することだった。
polymer_membrane_modeling.csv を用いて、高分子の構造記述子と作製条件から、二酸化炭素の透過係数を予測する回帰モデルを作成してください。
データをトレーニングデータとテストデータに分け、実測値と推定値を比較してください。
まずは研究室のサンプルプログラムをそのまま実行し、その後に、プログラムの各処理と結果の意味を説明してください。
第6章の報告会が終わった日の夕方、先輩から slack に届いた課題を、遥は研究室の席でもう一度読んだ。
回帰モデル。
トレーニングデータ。
テストデータ。
実測値と推定値。
第6章までは、正解となる物性値を使わずに、高分子の分布や近さを見てきた。
今度は、既知の高分子がもつ構造、作製条件、透過係数の関係をモデルに学ばせ、新しい高分子の透過係数を推定する。
遥は polymer_membrane_modeling.csv を開いた。
縦には、120個の高分子膜サンプル。
横には、前の章で残った121個の構造記述子と、preparation_temperature。
最後の列には、co2_permeability があった。
測定温度は、第3章で決めた方針に従って一つにそろえられていた。
サンプルIDは表の左端にあるが、モデルの入力には使わない。
遥はノートに書いた。
説明変数 x:121個の構造記述子と製膜温度。
目的変数 y:二酸化炭素の透過係数。
第3章で一度考えた内容だった。
しかし今度は、その区別が実際のプログラムの中に現れていた。
サンプルプログラムの最初には、次の処理があった。
y = np.log10(dataset.loc[:, “co2_permeability”])
x = dataset.drop(columns=[“co2_permeability”])
遥は、y の前にある np.log10 で手を止めた。
透過係数そのものではなく、その常用対数を目的変数にしている。
第4章では、透過係数が何桁にも広がっていたため、対数目盛の図を作った。
今度は、図の軸だけでなく、モデルに学ばせる値そのものを対数に変えている。
遥は対話型AIに尋ねた。
何桁にも広がる正の目的変数を、対数変換して回帰分析する理由を説明してください。元の値を予測する場合との違いと、注意点も挙げてください。
回答には、大きい値の影響を抑えやすいこと、倍率としての違いを扱いやすいこと、予測後に元の単位へ戻す必要があることなどが示された。
遥は研究室の入門資料でも同じ考え方を確認した。
例えば、対数値で0.3の誤差は、元の透過係数ではおよそ2倍の違いに対応する。
対数値で1違えば、元の値は10倍違う。
遥はノートに書いた。
今回のモデルが直接予測するもの:log10(co2_permeability)。
元の透過係数へ戻すとき:10を推定値乗する。
ただし、対数に変えれば必ず良いモデルになるわけではない。
目的と誤差の考え方に応じて、変換前後を比較する必要がある。
次の処理では、データを二つに分けていた。
x_train, x_test, y_train, y_test = train_test_split(
x, y, test_size=0.25, random_state=0
)
遥は行数を確認した。
トレーニングデータは90サンプル。
テストデータは30サンプル。
120サンプルすべてをモデル構築に使った方が、多くの情報を学べるのではないだろうか。
わざわざ30サンプルを使わずに残すことが、少しもったいなく思えた。
遥は、まずサンプルプログラムのコメントを読んだ。
トレーニングデータ:モデルを構築するために使用するデータ。
テストデータ:構築したモデルの予測性能を、未知サンプルを想定して評価するためのデータ。
テストデータにも実際の透過係数は入っている。
しかしモデルを構築するときには、その値を見せない。
モデルの完成後に初めて推定値と実測値を比較する。
実際には答えを知っている問題を、答えを隠して解かせるようなものだった。
遥はノートに書いた。
トレーニングデータ:学習に使う。
テストデータ:学習に使わず、未知サンプルへの予測を模擬する。
次に、特徴量の標準化が行われていた。
x_train_mean = x_train.mean()
x_train_std = x_train.std()
autoscaled_x_train = (x_train – x_train_mean) / x_train_std
autoscaled_x_test = (x_test – x_train_mean) / x_train_std
第6章で行った標準化と同じに見えた。
しかし、テストデータからはテストデータ自身の平均値や標準偏差を計算していない。
トレーニングデータの平均値と標準偏差を使って、テストデータを変換している。
遥は理由を考えた。
モデルを作るときに決めた尺度を、新しいサンプルにもそのまま使う。
予測したい未知サンプルが一つだけなら、そのサンプル自身から平均値や標準偏差を計算することはできない。
それに、テストデータの情報を使って標準化の尺度を決めたら、答えを見せてはいなくても、テストデータの分布をモデル構築の途中で使ったことになる。
遥は、コードの横にコメントを加えた。
テストデータも、トレーニングデータで決めた同じ物差しで測る。
モデルとして使われていたのは、k近傍法による回帰だった。
number_of_neighbors = 5
model = KNeighborsRegressor(n_neighbors=number_of_neighbors)
model.fit(autoscaled_x_train, y_train)
k近傍法。
第6章で、似ている材料を距離によって探したこととつながっていた。
新しいサンプルについて、標準化後の説明変数空間で近いトレーニングサンプルを5個探す。
その5個の透過係数の対数値を平均し、新しいサンプルの推定値とする。
遥は、自分の言葉でモデルの処理を書いた。
似た構造記述子と似た製膜温度をもつ既知の高分子膜を5個探す。
その5個の透過係数を手がかりに、未知の高分子膜の透過係数を推定する。
前の章では、似ている材料を見つけること自体が目的だった。
今度は、似ている材料がもつ既知の物性値を利用して、目的変数を推定する。
PCAやクラスタリングでは、透過係数を正解として使わなかった。
k近傍回帰では、トレーニングデータの透過係数を正解として使う。
教師なし学習と、教師あり学習。
遥は入門資料で二つの違いを確認した。
教師なし学習:目的変数を与えず、データの分布やまとまりを見る。
教師あり学習:説明変数と目的変数の組を使い、未知サンプルの目的変数を推定する。
今回の目的変数は連続した数値であるため、回帰分析になる。
もし透過係数を「高い」「低い」の二つのクラスに分け、そのクラスを予測するなら、クラス分類になる。
遥はプログラムを実行した。
画面に、実測値を横軸、推定値を縦軸とした散布図が二枚表示された。
一枚はトレーニングデータ。
もう一枚はテストデータ。
対角線上に点があれば、実測値と推定値が一致している。
対角線から上に離れれば、モデルが実際より大きく推定した。
下に離れれば、実際より小さく推定した。
トレーニングデータの点は、比較的対角線の近くに並んでいた。
テストデータの点は、それより広く散らばっていた。
結果の下には、数値が表示されていた。
r2_train = 0.86
rmse_train = 0.22
mae_train = 0.16
r2_test = 0.52
rmse_test = 0.34
mae_test = 0.26
遥は、まず MAE を見比べた。
トレーニングデータでは 0.16、テストデータでは 0.26。
モデル構築に使っていないテストデータの方が、平均的な絶対誤差は大きかった。
対話型AIに質問すると、決定係数 r2、二乗平均平方根誤差 RMSE、平均絶対誤差 MAE の説明が返ってきた。
遥は、そのままスライドへ貼らず、サンプルプログラムの説明資料でも確認した。
r2:評価するデータセットにおける目的変数のばらつきを基準として、モデルがそのばらつきをどの程度説明できたかを表す指標。1に近いほどよい。
RMSE:誤差を二乗して平均した後に平方根を取った値。大きな誤差の影響を受けやすい。
MAE:誤差の絶対値の平均。平均的にどの程度外れたかを理解しやすい。
ただし、r2 は、評価するデータセットにおける y のばらつきを基準に計算される。
トレーニングデータとテストデータではサンプルが異なり、y のばらつきも異なるため、r2_train と r2_test の大小をそのまま比較して、予測誤差がどれだけ増えたかを判断してはいけない。
異なるデータセット間で誤差の大きさを比較するときは、同じ尺度で計算される RMSE や MAE を確認する。
また、r2_test が 0.52 なら実用できる、0.50 未満なら使えない、という一つの境界があるわけでもない。目的、測定誤差、既存手法、必要な精度によって判断は変わる。
遥は、MAE の 0.16 と 0.26 を見比べた。
テストデータでは、対数値における平均絶対誤差が 0.10 大きい。
テストデータの MAE 0.26 は、倍率に直すと 10 の 0.26 乗、すなわち約 1.8 倍であり、元の透過係数における平均的な絶対誤差の大きさを見る目安になる。
RMSE は 0.34 であり、大きな誤差をより強く反映すると、約 2.2 倍の尺度だった。
平均的な数値だけでなく、散布図にある一つ一つの点も見た。
透過係数の低いサンプルは高めに推定され、高いサンプルは低めに推定される傾向があった。
5個の近傍サンプルの平均を取るため、極端な値が全体の中央へ引き寄せられているように見える。
特に、対角線から大きく下へ離れた点があった。
polymer_047。
第4章では、透過係数と選択性がともに高く、散布図の右上に離れていた。
第6章では、構造記述子のPCAでも他の高分子から離れていた。
今度は、モデルの予測でも大きく外れている。
実測の log10(co2_permeability) は3.42。
推定値は2.72。
元の透過係数に戻すと、推定値は実測値のおよそ5分の1だった。
遥は、polymer_047 に最も近い5個のトレーニングサンプルを表示した。
それらは、他の多くの高分子と比べれば近い。
しかし、polymer_047 に特徴的だった嵩高い置換基を持たず、透過係数も大幅に低かった。
最も近いサンプルとの距離も、一般的なテストサンプルより大きい。
モデルは、本当によく似た材料を見つけたのではなく、用意されたトレーニングデータの中で相対的に近い材料を選んだだけだった。
遥はノートに書いた。
近傍サンプルがあることと、十分に似た近傍サンプルがあることは違う。
モデルは、知らない範囲でも必ず数字を返す。
数字が返ったことは、予測を信頼できることを意味しない。
翌日の午後、遥は紺色のパーカーの先輩に、実測値と推定値の散布図を見せた。
「初めてモデルを作れました」
言ったあとで、「作れた」という表現が少し大きすぎるように感じた。
実際には、研究室のサンプルプログラムを実行しただけだった。
先輩は画面を見た。
「プログラムは動きましたね。では、このモデルは何をしていますか」
遥は、用意していた説明を話した。
「構造記述子と製膜温度を標準化し、新しいサンプルに近いトレーニングサンプルを5個探して、その透過係数の対数値を平均しています」
「モデルは、高分子化学を理解していますか」
遥は少し考えた。
「理解しているとは言えないと思います。私たちが選んだ記述子と製膜温度を数字として比較し、その距離に基づいて計算しています。化学構造のどの情報を入れるかは、人が決めています」
「そうですね。では、推定値は実験結果ですか」
「いいえ。既存データから計算した予測です。実際の透過係数を知るには、膜を作って測定する必要があります」
先輩は、トレーニングデータとテストデータの結果を指した。
「なぜ、トレーニングデータの MAE の方が小さいのでしょう」
「モデルを作るために使ったデータだからです。モデルはトレーニングデータに合うように構築されるため、学習に使っていないテストデータより、誤差が小さくなりやすいです」
「では、r2_train と r2_test も、同じように大小を比較できますか」
遥は、先ほど確認した r2 の式を思い出した。
r2 は、それぞれの評価データに含まれる y のばらつきを基準にしている。
トレーニングデータとテストデータではサンプルが異なり、透過係数のばらつきも同じとは限らない。
「直接比較してはいけないと思います。二つのデータセットで誤差を比較するなら、同じ単位で計算される MAE や RMSE を確認します」
先輩はうなずいた。
「その通りです。では、テストデータの結果だけを見れば十分ですか」
遥は、30サンプルしかないこと、どのサンプルがテスト側に入るかで結果が変わる可能性を考えた。
「一回の分割だけでは、偶然の影響があります」
「それは次に考えましょう」
遥は、k の値を変えた結果も見せた。
number_of_neighbors = 1
number_of_neighbors = 3
number_of_neighbors = 5
number_of_neighbors = 10
課題にはなかったが、近傍の数で予測がどう変わるかを確かめていた。
k = 1 では、トレーニングデータの MAE と RMSE がどちらも 0.00 になり、r2 も 1.00 になった。
すべてのトレーニングサンプルにとって、自分自身が最も近いサンプルになるためだった。
しかし、テストデータの MAE は 0.31 だった。
k = 3 では、テストデータの MAE は 0.27。
k = 5 では 0.26。
k = 10 では 0.29。
「k = 5 が一番良いように見えます」
遥が言うと、先輩は尋ねた。
「何を見て、一番良いと判断しましたか」
「テストデータの MAE です」
「テストデータを見ながら、kを選んだということですね」
その言葉で、遥は手を止めた。
モデルを評価するために、学習に使わず残したはずのテストデータ。
しかし、その結果を何度も見て、都合のよいkを選べば、テストデータの特徴に合わせてモデルを調整したことになる。
「テストデータまで、モデルを決めるために使ってしまったことになりますか」
「近い状態になります。今回はkの働きを理解する練習なので、比較すること自体はよいです。ただ、最終的な性能評価として同じテストデータの値を使うなら、注意が必要です」
「では、kは何で決めるんですか」
「トレーニングデータの中で、さらに学習用と検証用を入れ替えながら評価する方法があります。詳しくは次のトレーニングで扱います」
クロスバリデーション。
以前の資料で名前だけ見た言葉だった。
先輩は、k = 1 の結果をもう一度指した。
「トレーニングデータの MAE が 0.00 で、r2 が 1.00 です。これは、完璧なモデルですか」
「トレーニングデータを完全に再現していますが、テストデータの MAE は候補の中で最も大きくなりました。トレーニングデータを正確に再現できることと、新しいサンプルを予測できることは同じではありません」
遥は答えながら、第1章の言葉を思い出した。
AIは魔法ではない。
今度は、その続きが少し見えた気がした。
高い精度も、魔法ではない。
どのデータで、どのように計算した精度なのかを確認しなければならない。
新人トレーニング六回目の進捗報告会で、遥は最初に、説明変数と目的変数を示した。
説明変数:121個の構造記述子と製膜温度。
目的変数:log10(co2_permeability)。
測定温度は一定。
サンプルIDと目的変数は、説明変数に含めない。
先生が尋ねた。
「なぜ、透過係数を対数変換したのですか」
「値が何桁にも広がっていて、元の値の差より倍率としての違いを扱いやすくするためです。ただし、予測値を元の単位へ戻す必要があり、変換前より常に良いとは限りません」
「回帰モデルとは何ですか」
遥は、モデルという言葉をなるべく大きく言いすぎないように答えた。
「説明変数 x と連続した目的変数 y との関係を、データから学んで、未知サンプルの y を推定するための規則です。今回は、近い5個のトレーニングサンプルの y の平均を使っています」
「PCAやクラスタリングとの違いは何ですか」
「PCAやクラスタリングでは目的変数を正解として使いませんでした。今回の回帰では、トレーニングデータの透過係数を正解として使っています」
先生は、実測値と推定値の散布図を見た。
「この対角線は、何を表していますか」
「実測値と推定値が一致する位置です。点が対角線から離れるほど、推定誤差が大きいことを表します」
「トレーニングデータとテストデータで、誤差はどう変わりましたか」
「MAE は、トレーニングデータで 0.16、テストデータで 0.26 でした。テストデータの方が平均絶対誤差は大きくなりました。一方、r2 は評価データの y のばらつきを基準にするため、サンプルの異なる二つの r2 を直接比較して、誤差が増えたとは判断していません」
先生は続けた。
「では、mae_test = 0.26 なら、このモデルは使えますか」
「この数字だけでは決められません。必要な精度、測定誤差、既存の方法との比較、どのサンプルで外れているかを確認する必要があります。対数値の MAE 0.26 は、元の透過係数では倍率にして約 1.8 倍のずれを示す目安です。RMSE は 0.34 で、大きな誤差も含めると約 2.2 倍の尺度になります」
先生は、polymer_047 の点を指した。
「このサンプルでは、なぜ大きく外れたと考えましたか」
「構造記述子の空間で他のサンプルから離れていて、十分に似たトレーニングサンプルがありませんでした。モデルは最も近い5個を使いましたが、その5個もpolymer_047に十分近いとは限りません」
「モデルが数字を出したら、予測できたと言えますか」
「計算はできます。でも、その値を信頼できるかは別に確認する必要があります」
先生はうなずいた。
「大切な点です。モデルは、入力があれば基本的に何らかの値を返します。返された値に、モデル自身が『この予測は危ない』と自動的に書いてくれるとは限りません」
続いて、遥はkを変えた結果を示した。
「k = 1 では、トレーニングデータの MAE が 0.00 になりましたが、テストデータの MAE は 0.31 で、今回比較した中では最も大きくなりました」
先生が尋ねた。
「なぜ、kを変えたのですか」
「サンプルプログラムにあるk = 5を、そのまま正しい値として使いたくなかったからです。近傍数によって、予測がどのように変わるか確認しました」
「では、k = 5を採用しますか」
「今のテストデータでは k = 5 の MAE が最も小さいですが、その結果を見て選ぶと、テストデータをモデル選択に使うことになります。適切な決め方はまだ確認できていません」
先生は、少し笑った。
「『まだ決められない理由』を説明できれば十分です。次は、その決め方を考えましょう」
遥は最後のスライドを示した。
教師あり学習では、説明変数と目的変数の関係を学ぶ。
トレーニングデータはモデル構築に、テストデータは未知サンプルを想定した評価に使う。
推定値は実測値ではなく、モデルとデータに基づく計算結果。
異なるサンプル集合の r2 は、y のばらつきが異なるため大小を直接比較しない。
トレーニングデータとテストデータの誤差比較には、MAE や RMSE のような同じ尺度を使う。
全体の評価指標だけでなく、個々のサンプルの誤差と、似た既知サンプルの有無を確認する。
先生は尋ねた。
「初めて予測モデルを作って、何が一番変わりましたか」
遥は少し考えた。
「モデルを動かす前は、数値が出れば予測できたことになると思っていました。でも、今は、誰から何を学び、どのデータを見せずに評価し、どのサンプルで外れたかまで考えないと、モデルの意味は分からないと思います」
「では、モデルを作ることと、モデルを信じることは同じですか」
「同じではありません」
報告会が終わったあと、遥は実測値と推定値の散布図をもう一度見た。
対角線の近くにある点。
大きく離れた点。
トレーニングデータでは良く見えるモデル。
テストデータでは変わる評価。
モデルは、表の数字を一つの推定値へ変えてくれた。
けれど、その推定値の意味を判断する仕事は、まだ人の側に残っていた。
作業を終えると、先輩から次の課題が slack に届いた。
同じデータを用いて、以下を比較してください。
トレーニングデータとテストデータの MAE および RMSE。
random_state を変えて、トレーニングデータとテストデータの分け方を変えた結果。
number_of_neighbors を変えた結果。
クロスバリデーションを用いて、number_of_neighbors を決めた結果。
同じ評価データに対して r2 が高い、あるいは MAE が小さいときほど、なぜその値になったのかを確認してください。
random_state を変えてテストサンプルが変わると、y のばらつきも変わります。異なるテストデータ間の r2 を単純に比較せず、MAE、RMSE、y の分布も確認してください。
テストデータは、どの段階までモデルの選択に使ってよいのかも考えてください。
遥は、新しいNotebookを開いた。
今回、k = 1 のモデルは、トレーニングデータの MAE を 0.00 にした。
けれど、未知のサンプルに対する MAE は、比較した候補の中で最も小さくなかった。
高い精度という言葉は、単純な褒め言葉ではないらしい。
どのデータに対する精度なのか。
その精度を高くするために、何を選び、何を見たのか。
遥はノートの新しいページに、次の章の題名を書いた。
高い精度は本当に良いのか。
===
続きはこちら
