糖尿病のデータセットを用いた教師あり機械学習
はじめに
文系出身python初心者が成果物として本ブログを作成いたします。
理解が乏しい項目もあり、復習と確認の意味も兼ねてアウトプットしていきます。
本記事の概要
使用するデータセットは,scikit-learnにサンプルデータとしてあるDiabetes Dataset。糖尿病患者 442 人のデータとなっており、目的変数として 1 年後の「進行状況」と,説明変数として年齢、性別やBMIなどの下記10項目のデータ構成となっております。
Age:年齢
Sex:性別
Body mass index:BMI値
Average blood pressure:平均血圧
S1:TC(血液中の総コレステロール値)
S2:LDL(低比重リポタンパク質、悪玉コレステロール)
S3:HDL(高比重リポタンパク質、善玉コレステロール)
S4:TCH(=TC÷HDL=総コレステロール値/善玉コレステロール)
S5:LTG(血液中の中性脂肪値の対数)
S6:GLU(血糖値)
講座の中で学んだ回帰モデルを使用して最も精度の良いものを探してみます。モデルはLinearRegression、Lasso、ElasticNet、Ridgeの4種類を使用し精度を比較していきます。
実行環境はgoolgle colaboratoryを使用します。
作成したプログラム
scikit-learnのライブラリから「diabetes」のデータセットを読み込みます。
必要なライブラリのインポートとデータの中身を確認します。
Xが特徴量、Yが教師データになります。
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.linear_model import Lasso
from sklearn.linear_model import Ridge
from sklearn.linear_model import ElasticNet
from sklearn.datasets import load_diabetes
#sklearnからデータセットを読み込み変数に格納します。
diabetes = load_diabetes()
#データをPandasのデータフレームに格納します。
X = pd.DataFrame(diabetes["data"],columns=diabetes["feature_names"])
Y = pd.DataFrame(diabetes["target"],columns=["target"])
#データの中身を確認
print(X.head(5))
print(Y.head(5))
各項目の値は(平均0、ユークリッドノルム1)で正規化された値となってい ます。
欠損値があるかを確認します。
print(X.isnull().sum())
print(Y.isnull().sum())
どちらにも欠損値は見られませんでした。
Scikit-learnの train_test_split メソッドを使ってデータを学習用と評価用に分割します。
# テストデータとトレーニングデータに分割します。
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.2, random_state=42)
20%を評価用のデータに指定して、性能比較のため乱数のシード値は42に固定します。
教師データと各特徴量の相関を見ます。
train = pd.concat([X_train,y_train],axis=1,sort=False)
sns.heatmap(train.corr(),vmax=1,vmin=-1,annot=True)
targetに対してbmi,S5:LTG(血液中の中性脂肪値の対数)が相関が強め、次いでAverage blood pressure:平均血圧、S4:TCH(=TC÷HDL=総コレステロール値/善玉コレステロール)、S5:LTG(血液中の中性脂肪値の対数)も多少がありそうです。
今回は全ての特徴量を使用して機械学習を行います。
目的変数の予測には下記4種類の回帰モデルを使用します。
線形回帰
Lasso回帰
Ridge回帰
Elastic Net回帰(L1正則化が50%、L2正則化が50%)
決定係数を変数に格納し、4つのモデルのうち精度が良いもの表示します。
#比較用変数
max_score = 0
best_model = ""
#線形回帰
model1 = LinearRegression()
model1.fit(X_train, y_train)
score = model1.score(X_test, y_test)
if max_score < score:
max_score = score
best_model = "線形回帰"
#ラッソ回帰
model2 = Lasso()
model2.fit(X_train, y_train)
score = model2.score(X_test, y_test)
if max_score < score:
max_score = score
best_model = "ラッソ回帰"
#リッジ回帰
model3 = Ridge()
model3.fit(X_train, y_train)
score = model3.score(X_test, y_test)
if max_score < score:
max_score = score
best_model = "リッジ回帰"
#ElasticNet回帰
model4 = ElasticNet(l1_ratio=0.7)
model4.fit(X_train,y_train)
score = model4.score(X_test, y_test)
if max_score < score:
max_score = score
best_model = "ElasticNet回帰"
print("モデル:{}".format(best_model))
print("決定係数:{}".format(max_score))
決定係数が1に近づくほどが精度が良いため、あまり精度がよくなさそうです。
線形回帰モデルの予測値と実測値を折れ線グラフで可視化し、確認します。
pred = model1.predict(X_test)
x = np.arange(y_test.shape[0])
plt.plot(x, y_test, label='y_test')
plt.plot(x, pred, label='pred')
plt.legend()
plt.show()
縦軸が糖尿病の進行状況、横軸がデータ件数になり、ざっくりとした再現はできていることが確認できました。
今回、定義したモデル以外のモデルも実装したり、ハイパーパラメータチューニング等を行い正確性を向上させていくことを目標に引き続き学習していきたいです。
おわりに
学習できない環境が続いたり、速足で学習をした内容もあって自分がわかる範囲でアウトプットをしましたが、Pythonも統計学もまだまだ復習が必要だと感じました。
今回は、本来一番時間がかかるデータの前処理が少なかったため、ウェブページ上から自分でデータを取得したり、複雑なデータセットの分析にも取り組めるように頑張りたいです。
また今回ブログを作成して、受け身で問題を解くよりこうしてアウトプットすることが学習する上で重要だと実感できました。
この記事が気に入ったらサポートをしてみませんか?