Pythonではじめる機械学習1~2章(~2.3.2)メモ

Pythonではじめる機械学習という本を読みはじめたので内容を記録していきたいと思う。本の内容は私のようにあまり詳しくなくても結構わかりやすく取り組みやすいと感じている。

1章最初のモデル:k-最近傍法(k-Nearest Neighbors)

1章は基本的な概要と最後にscikit-learnを用いてk-Nearest Neighborsを説明している。
k-Nearest Neighborsでクラス分類を行う手順としては、

  1. 正解クラスが既知なデータを用いてモデルを構築する。
  2. 新しくクラスが未知なデータがあるときに訓練セットで用いたデータと特徴量の値が近いものを取得
  3. そのデータのクラスを新しいデータのクラスとして採用する。

kとは近いデータを取得する際にいくつのデータを対象とするかの個数であり、

  • k=1であればそのデータと同じクラスを採用
  • k>=2であれば取得したデータのうち多数を含むクラスを採用する。

k= 1であれば下の図のようなイメージ。
○と△がクラスが既知のデータ、☆が新規のデータでクラスが未知であり最も近いデータが線で結ばれている。

f:id:futurasan:20200726141924p:plain
k=1

1章ではk-Nearest Neighborsをscikit-learnで実施する方法を紹介してくれている。scikit-learnには複数のアルゴリズムに基づくクラス分類や回帰モデルが用意されており、基本的に実施するフォーマットが統一されている。k-Nearest Neighborsを実施する際はscikit-learnからKneighborsClassifierクラスをインポートし、そのインスタンスを生成して用いる。scikit-learnがインストールされていない場合には

pip install scikit-learn

をすれば良い。

from sklearn.neighbors import KNeighborsClassifirer
knn=KNeighborsClassifier(n_neighbors=1)
knn.fit(X_train, y_train) 
knn.predit(X_new)

基本的にはこのような形で既知のデータでモデルを構築し新規のデータに対して予測が可能となる。

2章

KNeighborsClassifier詳細

n_neighborsを変更した際の精度を確認することで、モデルの複雑さと汎化性能の確認を行う。n_neighborsは近傍点を何個用いるかを指定するパラメータである。ここでは1から10まで順にパラメータを指定してモデル構築を行い、精度を検証する。データはscikit-learnに含まれるcancerデータを用いる。最適なパラメータはデータによっても異なるだろうが、例では6あたりがtraining,testデータの両者における精度のバランスが良さそうである。
f:id:futurasan:20200726145343p:plain

from sklearn.neighbors import KNeighborsClassifier
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt

cancer = load_breast_cancer()
X_train, X_test, y_train, y_test = train_test_split(cancer.data, cancer.target, stratify=cancer.target, random_state=66)
training_accuracy = []
test_accuracy = []
neighbors_settings = range(1, 11)

# n_neighborsを1から順に設定しモデル構築、精度取得
for n_neighbors in neighbors_settings:
    clf = KNeighborsClassifier(n_neighbors=n_neighbors)
    clf.fit(X_train, y_train)
    training_accuracy.append(clf.score(X_train, y_train))
    test_accuracy.append(clf.score(X_test, y_test))

# trainとtestの精度結果を描画
plt.plot(neighbors_settings, training_accuracy, label="training accuracy")
plt.plot(neighbors_settings, test_accuracy, label="test accuracy")
plt.ylabel("Accuracy")
plt.xlabel("n_neighbors")
plt.legend()

データをtrainとtestに分割する際にtrain_test_split()を用いている。引数のうちstratifyというものがあるが、これに元データのlabel(cancer.target)を指定することでtrainとtestに分割した際にも正解ラベルが元データと同じ比率に指定することができるようだ。
stratifyについて下記参考にさせていただきました。
scikit-learnでデータを訓練用とテスト用に分割するtrain_test_split | note.nkmk.me

k-Nearest Neighbors 回帰

k-Nearest Neighborsはクラス分類の他に回帰を行うこともできる。

  1. 正解クラスが既知なデータを用いてモデルを構築する。
  2. 新しくクラスが未知なデータがあるときに訓練セットで用いたデータと特徴量の値が近いものを取得
  3. そのデータの値を新しいデータの値として用いる。
    • k=1であればそのデータと同じ値を採用
    • k>=2であれば取得したデータを平均した値を用いる。

f:id:futurasan:20200726151704p:plain

from sklearn.neighbors import KNeighborsRegressor

をすれば後はKneighborsClassifierと同じようにモデル構築、予測ができる。

k-Nearest Neighbors における近いとは?

近いデータを取得する際にはユークリッド距離を用いることが多いようだ。
ユークリッド距離とはx, yという2つのデータがあった場合にその距離dが

$$
d(x, y) = {\sqrt{(x_1 - y_1)^2+(x_2 - y_2)^2 + \cdots + (x_n - y_n)^2}}
$$

で表される。x1, y1などは特徴量の値であり、x1は1つ目の特徴量、x2はふたつめの特徴量で良さそうだ。
ユークリッド距離について下記参考にさせていただきました。
クラスター分析の手法①(概要) | データ分析基礎知識