つくるって楽しい

主にpythonとか。画像処理とか。

最小二乗フィッティングで糖尿病の進行度予測

糖尿病のサンプルデータを使って最小二乗フィッティングしました。糖尿病のサンプルデータを使って最小二乗フィッティングしました。

理論

観測値x,yy=f(x)というモデルで表されるとします。モデルが x_{i} (i=1,..n)の線形結合で表される時、 f(x) = \Sigma a_{i} x_{i}と書けます。 a_{i} x_{i}の係数です。
次のようなk個の観測値の集合がある場合を考えます。

{
(x_{11}, x_{12}, \dots ,x_{1n}, y_{1}), 
(x_{21}, x_{22}, \dots ,x_{2n}, y_{2}), 
\dots, 
(x_{k1}, x_{k2}, \dots ,x_{kn}, y_{k})
\tag{1}
}

この集合からモデルに最も当てはまる係数 a_{i}を求めるには、モデルから求めた理論値f(x)と観測値yを最小にします。理論値と観測値の二乗誤差の総和は、

{
J 
= \Sigma {(f(x)- y_{i})}^{2} 
= \Sigma {( \Sigma a_{i} x_{i} - y_{i})}^{2}
\tag{2}
}

と書けます。Jを最小にすればよいということが分かります。
(2)の \Sigma a_{i} x_{i} - y_{i}を行列で表すと以下のようになります。

{
\begin{pmatrix}
x_{11} && x_{12}  && \dots && x_{1n} \\
x_{21} && x_{22}  && \dots && x_{2n} \\
&& && \dots && \\
x_{k1} && x_{k2}  && \dots && x_{kn} \\
\end{pmatrix}
\begin{pmatrix}
a_{1} \\
a_{2} \\
\vdots \\
a_{n} \\
\end{pmatrix}
-
\begin{pmatrix}
y_{1} \\
y_{2} \\
\vdots \\
y_{k} \\
\end{pmatrix}
\tag{3}
}

(2)の Jを最小にするということは、(3)の大きさを最小にすればいいですね。簡略化&理想的な場合を考えると、(3) = 0と置いてこれを解けばよいということが分かります。

実装

scikit-learnのLinearRegression()を使います。[1]の例では、1次元の特徴量に限定してフィッティングしていますが、全特徴量を使ってフィッティングしました。Variance scoreはフィッテイングの良さを示す値で、データのばらつきをもとに計算します。[1]では0.47でしたが、全特徴量を使った場合0.59となり、よりよくフィッティング出来ています。

出力

Coefficients:  [ 2.06069866e-04 -7.05675908e-02  4.14834780e-01  2.49574079e-01 -7.11907159e-01  4.82683572e-01  9.08289960e-02  1.50462309e-01  6.01524431e-01  6.48063127e-02]
Mean squared error: 0.02
Variance score: 0.59

学習データ、テストデータをそれぞれプロットし求めたフィッティングを描画してみました。各特徴量に対する観測値の値です。プロット点はデータ、線は予測結果を表しています。各プロットのタイトルには求めた係数を表示しています。係数の大きさが大きいほど重要な特徴量と考えられるのです。ここで最も大きいものは s1という特徴量でしたが、プロット点を見ると観測値と相関がないように見えます。また、データの傾向に反して負の係数であるのが気になります。未解決です。

f:id:mikekochang:20190319135801j:plain
Fig1. 学習データのプロット、フィッテイング結果

f:id:mikekochang:20190319135611p:plain
Fig2. テストデータのプロット、フィッテイング結果