1
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

scikit-learnによる機械学習実装 ~ diabetes編 ~

Last updated at Posted at 2021-02-20

初めに

内容

scikit-learnを用いた機械学習を行います。
データセットはscikit-learnから提供されるデータセットを使用します。

本記事では「Diabetes」(糖尿病患者の診断データ)を取り扱います。

irisデータセットの記事はこちらです。
Bostonデータセットの記事はこちらです。
digitsデータセットの記事はこちらです。
その他のデータセットは別の記事にて更新しようと思います。

対象

主に初心者向けです。が、入門向けではないです。

本記事は友人に向けて作成してますが、
「機械学習したい」と思っている方にも読んでもらえるように書いています。

実装に関しての解説は記載しますが、アルゴリズムなどの解説は(基本的に)しませんのでご理解のほどを。

環境

  • Google Colaboratory
  • Python 3.6.9
  • sklearn 0.22.2
  • pandas 1.1.5
  • matplotlib 3.2.2

ローカルで環境をそろえるのは難しいので(Dockerやクラウドを使えばできますが)
今回はColaboratoryを用います。
上記のバージョンに合わせるとローカル環境でも実行できます。


以降は実際にpythonを用いながらになるのでColaboratoryの用意をお願いします。

Diabetes について

Diabetsは糖尿病患者442人の検査数値と1年後の疾患進行状況についてのデータセットです。

目的変数

まず、目的変数について確認しましょう。

from sklearn.datasets import load_diabetes
import pandas as pd

diabetes = load_diabetes()
target = diabetes.target

df_target = pd.DataFrame(target, columns=['progression'])
df_target.head()

次のような表が生成されます。
image.png
これは1年後に糖尿病がどれくらい進行しているかを定量的に表したものだそうです。

友人Tへ 「151.0ってどれくらい進行してるの?」と気になると思います。(私も気になります) 結論を言うと「わっかんねぇ!」ですね。 (詳細を探すのもいいですが、これに時間を使いすぎて無駄にしないように!) 「データを提供してくれた側が前処理をしておいてくれた」という状況だと思えばあとの学習がはかどるかと思います。 「データの収集」や「データの分析」を行ってデータセットを作成することは、今後の勉強課題となりそうですね。

ちなみに、以下のようにすることでデータセットの説明を表示することもできます。
(英語ですが...)

print(diabetes.DESCR)

説明変数

次に、説明変数について確認しましょう。

data = diabetes.data
feature_names = diabetes.feature_names

df_data = pd.DataFrame(data, columns=feature_names)
df_data.head()

次のような表が生成されます。
image.png

ageやsexまでもがfloatなのは、datasetを用意した側ですでに正規化を行ったからです。
正規化に関してdiabetes.sdata.txtには次のように書かれてます。(一部抜粋)

first 10 columns have been normalized to have mean 0 and Euclidean
norm 1 and the last column y has been centered (mean 0).

各説明変数の内容は以下の通りです。

変数名 内容
age 年齢
sex 性別
bmi 肥満度指数
bp 平均血液圧力
s1~s6 血清測定値(詳細不明?)
s1~s6についてはあまり情報がありませんでした。
こちらサイトではs1~s6を次のようにとらえているようです。
変数名 内容
s1 総コレステロール値
s2 悪玉コレステロール値
s3 善玉コレステロール値
s4 総コレステロール値
s5 ラモトリギン
s6 グルコース
s1とs4の違いがわからんですね...
もっと詳しく知りたい人はこちらの論文をご覧ください。
Google先生に頼めば論文の翻訳もしてもらえますので頑張って...
(ちなみに、上記6項目は「Serum Measurements」だそうです。詳細がわからん...)
df_data.shape # => (442, 10)

レコード数は442件だそうです。

相関関係を見る

pandasのscatter_matrixを用いて、すべての目的変数のペアプロットを作成します。

import matplotlib.pyplot as plt

pd.plotting.scatter_matrix(pd.concat([df_data, df_target], axis=1), figsize=(20, 20))
plt.show()

image.png
s1とs2に強い相関がありますね。(s系同士は相関が見れますね)

機械学習しよう

前処理

データそのものはすでに正規化処理が行われているので、
欠損値の確認及び補完とデータの分割を行います。

まず欠損値についてです。

df_data.isnull().any()

image.png
データに欠損値はないようです。

次に分割作業です。

from sklearn.model_selection import train_test_split

x_train, x_test, y_train, y_test = train_test_split(df_data, df_target, test_size=0.2, random_state=141)

print('x_train :', x_train.shape) # => x_train : (353, 10)
print('y_train :', y_train.shape) # => y_train : (353, 1)
print('x_test :', x_test.shape) # => x_test : (89, 10)
print('y_test :', y_test.shape) # => y_test : (89, 1)

学習

今回の目的変数の予測には回帰モデルを使用します。
bostonデータセットではlassoを使用したので、今回はARDRegressionを使用してみましょう。
他のモデルを使用したいのであれば公式リファレンスやほかの方のQiita記事をご覧ください。

データセットの特徴に合わせて、適切なモデルを選ぶことが重要になりますので、各モデルについての勉強をしたほうが良いですね。

from sklearn.linear_model import ARDRegression

model = ARDRegression()
model.fit(x_train, y_train)

推論

モデルの評価には$R^2$, RMSE, MAEの3つとも確認してみましょう。
$R^2$は1に近いほど、RMSE,MAEは小さければよいモデルと判断します。

from sklearn.metrics import r2_score
from sklearn.metrics import mean_squared_error
from sklearn.metrics import mean_absolute_error
import numpy as np

pred = model.predict(x_test)

r2 = r2_score(y_test, pred)
rmse = np.sqrt(mean_squared_error(y_test, pred))
mae = mean_absolute_error(y_test, pred)

print('R2 :', r2) # => 0.601853388737597
print('RMSE :', rmse) # => RMSE : 50.73687625628082
print('MAE :', mae) # => MAE : 41.407855314776924

random_stateの値によっては0.4を下回ったりするので、考え物ですね...
評価指数についてはこちらのサイトが参考になるやもしれません。

実測値と予測値を折れ線グラフで可視化し、確認してみましょう。

x = np.arange(y_test.shape[0])
plt.title('Comparison of measured and predicted values')
plt.ylabel('progression')
plt.plot(x, y_test, label='y_test')
plt.plot(x, pred, label='pred')
plt.legend()
plt.show()

image.png
縦軸が疾患の進行度を表す値で、横軸がデータ89件分(train_test_splitの分割数により変化する)を表します。
凡例の通り青線がy_test、オレンジ線がpredです。

たしかに大まかに表現できてはいますが、いまいちなモデル、そんな印象を見受けられますね。

最後に

モデルのインスタンス作成時にハイパーパラメータ(人が調整するパラメータ)を設定できます。
公式リファレンスに設定できるハイパーパラメータの詳細が載っているので参考になるかと。

model_selection.GridSearchCV などで最適なハイパーパラメータの探索などができますので、使用してみてください。

次回は定番の手書き文字の認識を行います。

1
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?