Matrices, Regularized Regression and Interpretation
数値計算・機械学習
分子・反応を行、記述子を列とする行列を定義し、再現可能な前処理、正則化回帰、次元削減、モデル解釈へ進みます。
- 数値基盤
- NumPy・線形代数
- モデル
- Ridge・Lasso・Elastic Net・PCA
- 解釈
- 係数、loading、SHAP
1. 化学データを行列にする
個の分子・反応と個の特徴量を、design matrix に並べます。目的変数はです。
列にはfingerprint bit、物性記述子、Sterimol、%Vbur、cubeから抽出したfield特徴量などが入ります。定義・単位・欠損処理をmetadataとして保存します。
2. NumPy配列の基礎
線形代数でもnumpy.matrixではなく通常のndarrayを使います。*は要素積、@は行列積です。
import numpy as np
X = np.array([
[2.1, 0.32, 71.4],
[2.5, 0.41, 74.8],
[3.0, 0.55, 80.2],
], dtype=float)
y = np.array([1.2, 1.8, 2.5])
print(X.shape) # (n_samples, n_features)
print(X[:, 0]) # first feature
print(X.T @ X) # Gram matrix
print(X.mean(axis=0))
print(X.std(axis=0, ddof=1))| 処理 | NumPy | 意味 |
|---|---|---|
| 内積・行列積 | a @ b | shapeの内側の次元を縮約 |
| 連立方程式 | np.linalg.solve(A, b) | を解く |
| 最小二乗 | np.linalg.lstsq(X, y) | residual normを最小化 |
| 固有値分解 | np.linalg.eigh(C) | 対称行列向け |
| 特異値分解 | np.linalg.svd(X) | rank・主成分・conditionを調べる |
3. 最小二乗と行列計算
形式的なnormal equationはですが、逆行列を明示的に作ると数値誤差が増えます。lstsq、QR、SVD、scikit-learn estimatorを使います。
beta, residuals, rank, singular_values = np.linalg.lstsq(
X, y, rcond=None
)
condition_number = singular_values.max() / singular_values.min()
print(beta, rank, condition_number)非常に大きいcondition numberは、特徴量のscale差や多重共線性を示します。化学記述子は互いに強く相関しやすいため、標準化と正則化を検討します。
4. 正則化回帰
Ridge
L2 penaltyで係数を連続的に縮小します。相関した記述子を含む場合にも比較的安定ですが、通常は係数を完全な0にはしません。
Lasso・Elastic Net
がLasso、がElastic Netです。Lassoはsparseな係数を作れますが、強く相関した特徴群から一つを不安定に選ぶ場合があります。
from sklearn.linear_model import ElasticNetCV
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
model = make_pipeline(
StandardScaler(),
ElasticNetCV(
l1_ratio=[0.1, 0.5, 0.9, 1.0],
alphas=100,
cv=5,
max_iter=20000,
),
)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)5. 分割・前処理・評価
Pipeline内でstandardizationとfeature selectionをfitすると、各cross-validation foldのtraining部分だけから変換parameterを学習できます。
| 指標 | 式・意味 | 注意 |
|---|---|---|
| MAE | 絶対誤差の平均 | outlierの影響がRMSEより小さい |
| RMSE | 二乗誤差平均の平方根 | 大誤差を強くpenalize |
| 平均予測からの改善度 | test setでは負にもなり得る |
random splitは同一scaffoldや類似触媒をtrain/testへ分散し、性能を過大評価する場合があります。scaffold、基質系列、触媒系列、文献sourceなど、実際の外挿課題に対応するgroup splitを併記します。
6. PCA
PCAはcentered matrixを、分散を最大化する直交方向へ射影します。scikit-learnのPCAはcenterしますがscaleは揃えないため、単位の異なる記述子では通常StandardScalerを先に適用します。
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
X_scaled = StandardScaler().fit_transform(X)
pca = PCA(n_components=0.95)
scores = pca.fit_transform(X_scaled)
loadings = pca.components_.T
print(pca.explained_variance_ratio_)
print(scores.shape, loadings.shape)scoreはsampleの位置、loadingは元特徴量が主成分へ寄与する方向です。符号は主成分全体で反転可能なので、符号そのものではなく相対方向を解釈します。PCAは目的変数を使わない教師なし解析です。
7. SHAPによるモデル解釈
SHAPは予測値をbaselineと各特徴量の寄与へ加法分解します。
| 図 | 読む内容 |
|---|---|
| bar / beeswarm | dataset全体での寄与の大きさと方向 |
| waterfall | 一つのsampleがbaselineから予測値へ移る内訳 |
| scatter | 特徴量値とSHAP値の関係、非線形性・interactionの候補 |
import shap
explainer = shap.Explainer(fitted_model, X_background)
shap_values = explainer(X_test)
shap.plots.beeswarm(shap_values)
shap.plots.waterfall(shap_values[0])
shap.plots.scatter(shap_values[:, "B5"])SHAPはmodelとbackground distributionに対する説明です。相関した特徴量間で寄与の配分が変わり、未測定交絡も残ります。「特徴量を操作すれば選択性が変わる」という因果主張には追加の仮定・実験が必要です。
8. 実践workflow
- 解析単位と外挿したいchemical spaceを定義する。
- train/testまたはgroup splitを最初に固定する。
- 欠損補完・標準化・特徴量選択をPipelineへ入れる。
- inner CVでhyperparameterを選び、outer testで性能を評価する。
- baseline、MAE/RMSE、prediction plot、applicability domainを確認する。
- 係数、PCA loading、SHAPの安定性をbootstrapや分割変更で調べる。
- data、code、random seed、library version、feature定義を保存する。
9. 参考資料
- NumPy User Guide
- scikit-learn: Linear Models
- scikit-learn: PCA and matrix decomposition
- scikit-learn: Pipeline and data leakage
- SHAP API and plot reference
- SHAP: predictive explanation and causal interpretation
最終更新: