最も基本的な予測モデルの1つに線形回帰モデルがあります。scikit-learnでサンプルデータとして用意されている糖尿病患者の年齢・性別などの基本情報と採血データから1年後の糖尿病の進行度の関係を表したデータセットを用いて、線形回帰モデルで進行度を予測する機械学習の例を見てみましょう。
開発環境
- Python 3.7.9
- scikit-learn 0.23.2
線形回帰モデルとは
線形回帰モデルは最も基本的な回帰モデルの1つで、目的変数(\(y\))を説明変数(\(X_1, X_2, X_3, … \)) を用いて次のように表現するモデルです。
$$y=β_0+β_1 X_1 + β_2 X_2 + β_3 X_3 + … + ε$$
目的変数が説明変数の線型結合で表現されていることが特徴で、このモデルでは目的変数は連続値(量的変数)となります。なお、線形回帰モデルにおいて説明変数が1つだけの場合を単回帰モデル、2つ以上の場合を重回帰モデルと呼ぶ場合もあります。
詳細はWikipedia等をご覧ください。
データセットの取得と確認
ここでは線形回帰モデルを用いた解析の例として、糖尿病の診察データと1年後の進行度の関係のデータセットを用います。このデータセットはscikit-learnでサンプルデータとして提供されておりload_diabetes関数で取得できます。まずはこれから解析するデータを俯瞰してみましょう。なおここで取得するデータ形式はBunchオブジェクトですが、Bunchオブジェクトについては次の記事をご覧ください。
データ解析を行う際の基本として、まずはそのデータの全体像を見てみましょう。データ全体を見るためにはDataFrameとして取得した方が操作しやすいので、load_diabetes関数のas_frame引数をTrueに設定して取得します。
# データの取得・確認
from sklearn.datasets import load_diabetes
diabetes_data = load_diabetes(as_frame=True)
print(diabetes_data.frame.describe())
frameキーの値に説明変数と目的変数の両方が統合されたDataFrameが格納されているので、そのdescribeメソッドで基本的な統計量をまとめて表示させてデータを要約しています。target以外はmeanがほぼ0で、stdも同じになっていることから、このデータセットの説明変数の値はすべて標準化されていることが分かります。また、countもすべてそろっていることから欠損値もないようです。
なお、それぞれの項目は次のようになります。
- age : 年齢
- sex : 性別
- bmi : BMI
- bp : 平均血圧
- s1 : 総コレステロール
- s2 : LDL
- s3 : HDL
- s4 : 総コレステロール / HDL
- s5 : トリグリセリド(対数)
- s6 : GLU(血糖値レベル)
- target : ベースラインから1年後の糖尿病の進行度
age, sex, bmi, bp, s1, s2, … などの項目名の意味については、DESCRでそのデータセットの説明を確認することができます。
print(diabetes_data.DESCR)
データの前処理
データを取得したら欠損値を除いたり、標準化・正規化などの前処理を行いましょう。データの前処理は解析前に非常に重要なプロセスです。ただし、今回使うサンプルデータセットでは欠損値はなく、データもすでに標準化されていることが確認されているので、特にここでの処理は必要なさそうです。
データセットを訓練用データと評価用データに分ける
scikit-learnではデータセットを指定した割合で訓練用と評価用のデータにランダムに分ける関数としてtrain_test_split関数が用意されています。ここではこの関数を用いて、20%を評価用のデータに指定して分割してみましょう。
# 訓練用データと評価用データに分割
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(diabetes_data.data, diabetes_data.target, test_size=0.2, random_state=100)
これで訓練用データ(X_train, y_train)と評価用データ(X_test, y_test)に分割できました。ただし、X_***が説明変数でy_***が目的変数です。
また、ここでは乱数のシードを100に固定しています。この値は任意でいいのですが、機械学習のモデルの性能を比較する場合は乱数をデータセットの分割方法をそろえる必要があるので気をつけましょう。
線形回帰モデルで予測を行ってみる
ここまで準備できたら、早速線形回帰モデルを作成してみましょう。まずモデル(LinearRegressionクラス)をインスタンス化して、そのfitメソッドに訓練用のデータを指定することでそのデータに合うモデルが生成されます。
# モデル作成
from sklearn.linear_model import LinearRegression
model = LinearRegression()
model.fit(X_train, y_train)
生成されたモデルの評価を行う
訓練データでモデルを作成したら、その評価を行いましょう。モデルの評価方法には様々な方法がありますが、ここではよく用いられる決定係数(R2)を用いた評価方法を見ていきます。決定係数はLinearRegressionクラスのscoreメソッドで求めることができます。
# モデルの評価
print(model.score(X_train, y_train))
print(model.score(X_test, y_test))
0.516777469253317 0.5041759376283348
これより訓練用データから求めたR2値は0.517であり、評価用データから求めたR2値は0.504となります。決定係数が0.5を超えているので比較的当てはまりの良い予測ができていそうです。
コードまとめ
最後に上記のコードをまとめてみましょう。
from sklearn.datasets import load_diabetes
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
# データの取得・確認
diabetes_data = load_diabetes(as_frame=True)
print(diabetes_data.frame.describe())
# 訓練用データと評価用データに分割
X_train, X_test, y_train, y_test = train_test_split(diabetes_data.data, diabetes_data.target, test_size=0.2, random_state=100)
# モデル作成
model = LinearRegression()
model.fit(X_train, y_train)
# モデルの評価
print(model.score(X_train, y_train))
print(model.score(X_test, y_test))
これにより糖尿病の診療データその進行度を予測するモデルを線形回帰モデルで構築することができました。
コメント