ロジスティック回帰:機械学習

%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap


def plot_regions(clf, X, y):
    """ モデルが学習した領域をプロット """
    X, y = X.to_numpy(), y.to_numpy()
    x1_min, x1_max = X[:, 0].min() - 1, X[:, 0].max() + 1
    x2_min, x2_max = X[:, 1].min() - 1, X[:, 1].max() + 1

    xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, 0.3),
                           np.arange(x2_min, x2_max, 0.3))

    Z = clf.predict(np.array([xx1.ravel(), xx2.ravel()]).T)
    Z = Z.reshape(xx1.shape)
    plt.contourf(xx1, xx2, Z, alpha=0.4, cmap=ListedColormap(('red', 'blue')))

    plt.xlim(xx1.min(), xx1.max())
    plt.ylim(xx2.min(), xx2.max())

    plt.scatter(x=X[y == 0, 0], y=X[y == 0, 1], alpha=0.8, c='red')
    plt.scatter(x=X[y == 1, 0], y=X[y == 1, 1], alpha=0.8, c='blue')

plot_regionsはグラフをプロットするための関数で、それを定義している。

import pandas as pd
df = pd.read_csv('./input/jh_heights_weights.csv')

X = df[["height", "weight"]]
y = df["y"]
from sklearn.linear_model import LogisticRegression

sklearn(scikit-learn)から機械学習のモデルを読み込み、初期化します

# ロジスティック回帰モデルを作成

lr = LogisticRegression(C=1000, random_state=0, solver='liblinear')
lr.fit(X, y)

fit を呼び出して学習させます

LogisticRegression(C=1000, class_weight=None, dual=False, fit_intercept=True,
                   intercept_scaling=1, l1_ratio=None, max_iter=100,
                   multi_class='auto', n_jobs=None, penalty='l2',
                   random_state=0, solver='liblinear', tol=0.0001, verbose=0,
                   warm_start=False)
lr.predict([
    (170, 50),
    (175, 60),
    (165, 70),
])

.predictを使って、身長と体重から性別を予想させます

array([1, 1, 0])

予測の結果の表示

plot_regions(lr, X, y);

機械学習が学習した「境界」をプロットします

ロジスティック回帰を使った分類

scikit-learnの、ロジスティック回帰用のクラスLogisticRegressionを使えばたったの数行で機械学習のモデルを作って、分類できます。

lr = LogisticRegression(...)  # 初期化
lr.fit(X, y)  # 学習
lr.predict([(160, 80)])  # 分類

今回はロジスティック回帰という機械学習の 分類器 を使って分類しています。
ロジスティック回帰はデータを線形に分類できる手法です。
今回のようにデータが 線形分離可能 な場合に有効な手法です。

線形分離可能とは、ふたつの点の集合が2次元平面上にあるとき、それらの集合を一本の直線で分離できることをいいます。

プロットされた結果を見ると、前回までで手動で引いた直線と似た直線が、ロジスティック回帰によって引かれてデータが分類されています。
機械学習がデータの傾向を学習し、分類ルールを作成してくれています。

処理の流れ

  1. plot_regions を定義
    • 機械学習のモデルが学習したことを可視化する関数です
    • 詳細は割愛して問題ありません(プロットする領域にメッシュ状に点を作り、各点全てのクラスラベルを判定、可視化しています)
  2. データをpandasで読み込み、scikit-learnに学習させるために X、 y に変換
    • X: 身長と体重のDataFrame
    • y: 男性か女性かのSeries
  3. scikit-learnから LogisticRegression 分類器をインポート
  4. 分類器にパラメーターを指定して初期化(このパラメーターを ハイパーパラメーター と呼びます)
    • C=: 逆正則化パラメーター、詳細は後のクエストで学びます
    • random_state=0: 学習時の乱数のシード値です
    • solver='liblinear': liblinearというソルバーの指定です
  5. lr.fit(X, y) を呼び出して学習
    • 第1引数に学習させるデータ X
    • 第2引数に分類の答え(クラスラベル) y
  6. lr.predict([...]) を呼び出して結果を分類
       * 3人のデータを分類しています
       * 身長170センチ、体重50キロの人であれば 1 (男性)という分類結果になっています
  7. plot_regions 関数を使って、分類した領域のプロット

学習させるデータにX、正解(クラスラベル)にyという変数名を使っています。
Xを特徴行列あるいは説明変数、yを目的変数と呼ぶこともあります。

本クエストのXとyは、次のようになります。

X: 身長、体重が各行に入った値
y: Xの各値に対応するクラスラベル
ここで身長と体重のようなデータは、特徴とも呼びます。
また、2つの特徴があるデータを「2次元のデータ」と呼びます。

コメント

タイトルとURLをコピーしました