scikit-learnを使ったロジスティック回帰¶
scikit-learnを使ってロジスティック回帰でのクラス分類をやっていきたいと思います。
# ロジスティック回帰を行うクラス
from sklearn.linear_model import LogisticRegression
# 特徴量のスケーリングに使用
from sklearn.preprocessing import MinMaxScaler
# トレーニングデータと検証データの分割に使用
from sklearn.model_selection import train_test_split
# 特徴量のスケーリングから学習モデルまでの入力のパイプラインを作成します。
from sklearn.pipeline import make_pipeline
# モデルの結果を評価する指標
from sklearn.metrics import accuracy_score, roc_auc_score, confusion_matrix, precision_score, recall_score
from seaborn import load_dataset
import pandas as pd
import numpy as np
import warnings
warnings.filterwarnings('ignore')
データセットのロードとデータの確認¶
関数load_datasetを使ってタイタニックの生存者についてのデータを読み込みます。
このデータを使って、性別や年齢、客室の等級などの乗船者のデータからその人が生存したかどうかを分類するモデルを作成します。
df = load_dataset('titanic')
#df.head()
データセットのデータ型の確認¶
データを見た所カテゴリカルなデータが含まれているので、各カラムのデータ型を確認します。
df.dtypes
データの前処理¶
ロジスティック回帰には数値のデータを入力する必要があります。
そのため、pandasのget_dummies関数を使ってone hot encoding(各カテゴリを列にわけてそれぞれの0,1でどのカテゴリかを表すデータに変換すること)
を行います。
また、Null(Nan)が入力されるとロジスティック回帰ではエラーになってしまうので、Nullは0埋めをします。
# カテゴリ変数をone hot encoding
df_category = pd.get_dummies(df, columns=['sex', 'embarked', 'class', 'who', 'adult_male', 'deck', 'embark_town', 'alone'])
# 「pclass」カラムは客室の等級を表す「class」カラムと同じなので削除、「alive」カラムは答えそのものになってしまうので、削除します。
df_category = df_category.drop(['pclass', 'alive'], axis=1)
# データ内のNullを0で置換します。
df_category = df_category.fillna(0)
#df_category.head()
トレーニングデータの作成¶
「survived」を教師カラムに、そのほかのカラムを特徴量に学習データを作成します。
y = df_category['survived']
X = df_category.drop('survived', axis=1)
print(y.shape)
print(X.shape)
トレーニングデータと検証用データの分割¶
scikit-learnのtrain_test_splitを使って、トレーニングデータの一部を検証用データとして分けておきます。
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42)
学習パイプラインの作成¶
モデルの学習パイプラインを作成します。
今回はロジスティック回帰に特徴量を入れる前にMinMaxScalerでスケーリングを行います。
MinMaxScalerを使うことで全ての入力値が0から1の間に正規化されます。
また、ロジスティック回帰で設定できるパラメーターでよく使うものには以下のものがあります。
パラメーター変数 | 概要 | 設定可能な値 |
---|---|---|
penalty | 正則化の方法 | 文字列で、'l1','l2','elasticnet','none'のいずれかを入力(デフォルトはl2) |
C | 正則化の強さを設定する | 0以上の実数値で数字を大きくするほど正則化が強くなる(デフォルト値は1.0) |
class_weight | クラスの数に偏りがある場合に、クラスごとの重みを調整する変数 | {class_label: weight}のdict形式か'balanced'が設定できる(デフォルトはNone(全てのクラスが同じ重み)) |
multi_class | マルチクラス分類の場合に設定する変数 | 二値分類の時は'ovr'、多クラス分類は'multinomial' |
そのほかの設定値は公式ドキュメント
に詳しく載っています。
pipe_lr = make_pipeline(MinMaxScaler(), LogisticRegression(C=5.0))
学習の実行¶
学習を実行します。
pipe_lr.fit(X_train, y_train)
検証データでの精度の検証¶
検証データを使ってモデルの精度を検証します。
今回は正解率を出してみます。
y_pred = pipe_lr.predict(X_val)
accuracy_score(y_val, y_pred)
検証データでの正解率はおよそ79.8%でした。
ロジスティック回帰の係数の学習結果から変数ごとの重要度を分析する¶
ロジスティック回帰でモデルを学習させると変数ごとに回帰係数が求まります。
この回帰係数を変数ごとにどのような値になっているかを確認することで、各変数が分類結果にどのように寄与しているかを見ることができます。
for col in np.argsort(pipe_lr.steps[1][1].coef_[0])[::-1]:
print("coef {0}: {1}".format(X.columns[col], pipe_lr.steps[1][1].coef_[0][col]))
変数ごとの回帰係数は上記のようになっています。
係数がプラスの場合は、その変数が大きいほどクラス1に分類されやすいということになります。
例えば、deckのEやDにいた人は分類結果が1になりやすい(生存しやすい)ということがわかります。
逆にsibspが1の人はクラスが0に分類されやすい(生存しにくい)ということがわかります。
まとめ¶
この記事ではscikit-learnを使ったクラス分類をタイタニックのサンプルデータを使って紹介しました。
ロジスティック回帰は機械学習でクラス分類を行う時に良く使うアルゴリズムなので、しっかりと使えるようになりましょう。
また、モデルの学習と予測だけでなく、学習結果を使った変数ごとの重みの分析方法についても紹介しました。