【scikit-learn】k近傍法(k-NN)を用いたデータ分類方法
を用いたデータ分類方法.jpg)
Python の機械学習ライブラリである scikit-learn の KNeighborsClassifier を使って k 近傍法 (k-NN) によるデータ分類を行う方法を解説します。
目次
k 近傍法(k-NN)
k 近傍法 (k-NN) とは、分類の手法の 1 つです。分類の中では非常に単純なアルゴリズムにであり、他のアルゴリズムのように識別関数、識別モデル、生成モデルのようなものを学習するわけではないため、機械学習の中でも怠惰学習と呼ばれたりします。
k 近傍法の概要を見てみましょう。k-NN は、k-Nearest Neighbors という名の通り、分類したい対象データから k 個の近傍のデータ点を見つけて多数決によって分類するクラスを決めます。近傍を求める際の距離尺度としては、一般的には距離はユークリッド距離が使用されます。距離尺度には他にもマンハッタン距離やマハラノビス距離といったものがあります。
k 近傍法の例を少し見てみましょう。以下のようなデータで黄色のデータ点が青なのか緑なのかを分類したいとしましょう。k=3 とすると、青 : 1、緑 : 2 となるので分類結果は緑となります。しかし、k=8 とすると青 : 5、緑 : 3 となるため青に分類されます。このようにいくつの近傍数を見るかによって分類結果は変わってきます。


k 近傍法は、Python の機械学習ライブラリである scikit-learn にて KNeighborsClassifier で実装がされています。この記事では、scikit-learn の KNeighborsClassifier を使って k 近傍法によるデータ分類する方法を紹介します。
KNeighborsClassifier を使って
k 近傍法によるデータ分類をする方法
以降では、scikit-learn を使用します。インストールがされていない場合は pip でインストールしておいてください。
pip install scikit-learn
k 近傍法の使い方(sklearn.neighbors.KNeighborsClassifier)
実装例
scikit-learn の make_classification で生成したデータを使って、k 近傍法を実現する KNeighborsClassifier の使い方を紹介します。k 近傍法は、近傍数をいくつにするかで結果が変わるのでそれも比較してみようと思います。
import matplotlib.pyplot as plt
import numpy as np
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
def main():
"""メイン関数"""
np.random.seed(1)
# ===== データの用意
data, label = make_classification(
n_samples=1000,
n_classes=2,
n_features=4,
n_informative=4,
n_redundant=0,
)
# データセットを訓練用、テスト用に分割する
train_data, test_data, train_label, test_label = train_test_split(data, label)
# ===== 複数のkで性能が分類性能がどのように変わるか確認
k_list = [k for k in range(1, 11)]
acc_list = []
# ===== kを変えながらモデルを順番に学習
for k in k_list:
# モデルの構築
model = KNeighborsClassifier(n_neighbors=k)
# モデルの学習
model.fit(train_data, train_label)
# 正解率の評価
acc_list.append(model.score(test_data, test_label))
# ===== 正解率をプロットする
plt.plot(k_list, acc_list)
plt.title("accuracy list")
plt.xlabel("n_neighbors")
plt.ylabel("accuracy")
plt.show()
if __name__ == "__main__":
main()
実装内容の解説
上記で紹介した実装例の各部分ごとに内容を紹介していきます。
必要モジュールのインポート
import matplotlib.pyplot as plt import numpy as np from sklearn.datasets import make_classification from sklearn.model_selection import train_test_split from sklearn.neighbors import KNeighborsClassifier
必要なモジュール類をインポートします。今回は scikit-learn の KNeighborsClassifier を使用するので、sklearn.neighbors からインポートします。またデータ生成用に make_classification、データ分割のために train_test_split をインポートしています。NumPy と Matplotlib はデータの操作や可視化用です。
データセットの準備
np.random.seed(1)
# ===== データの用意
data, label = make_classification(
n_samples=1000,
n_classes=2,
n_features=4,
n_informative=4,
n_redundant=0,
)
# データセットを訓練用、テスト用に分割する
train_data, test_data, train_label, test_label = train_test_split(data, label)データは make_classification を使って生成します。指定しているパラメータとしては以下のような項目です。
n_samples:データ点数n_classes:データのクラス数n_features:各データの次元数n_infomative:各データで情報を持ってる特徴数n_redundant:各データで冗長な特徴数
今回は 4 次元の特徴を持つ 1,000 点のデータで、2 つのクラスに分かれているデータを生成します。
n_infomative は 4 次元のうち意味のある特徴数で、n_redundant は冗長な特徴数という意味ですが、公式ドキュメントの記載を見ると「infomative な特徴のランダムな線形結合で生成される特徴の数」ということです。他の特徴で表現できるということは情報はもっていないような特徴ということですね。
乱数シードは、np.random.seed で設定していますが make_classification の randam_state 引数で乱数シードを指定することも可能です。train_test_split を使ってデータを訓練用とテスト用に分割しています。
モデルの生成と正解率
# ===== 複数のkで性能が分類性能がどのように変わるか確認
k_list = [k for k in range(1, 11)]
acc_list = []
# ===== kを変えながらモデルを順番に学習
for k in k_list:
# モデルの構築
model = KNeighborsClassifier(n_neighbors=k)
# モデルの学習
model.fit(train_data, train_label)
# 正解率の評価
acc_list.append(model.score(test_data, test_label))上記部分が k 近傍法を実行している部分です。まずは、KNeighborsClassifier をインスタンス化します。その際の引数としては近傍数の n_neighbors を指定します。
モデルの学習については、fit を使用して train_data と train_label を使用します。また、正解率は、訓練データとは異なる test_data と test_label を用いて score により計算します。
今回は k=1 ~ 10 までの数を順番に変えながら for 文で実行し、正解率をリストに追加していきます。
正解率のプロット
# ===== 正解率をプロットする
plt.plot(k_list, acc_list)
plt.title("accuracy list")
plt.xlabel("n_neighbors")
plt.ylabel("accuracy")
plt.show()
こちらの部分は、計算した正解率のリストをプロットしている部分です。正解率は、どうやら n_neighbors=3 の時が最も高いようです。
今回のデータではという意味ですので、3 が常に適切ということはありません。対象とする問題によりハイパーパラメータとして調整する必要があります。近傍数が多すぎると分類範囲の狭いようなカテゴリーではうまく分類されない場合もあります。
以上が、scikit-learn の KNeighborsClassifier を使った k 近傍法 (k-NN) によるデータ分類方法の紹介でした。
まとめ
Python の機械学習ライブラリである scikit-learn の KNeighborsClassifier を使って k 近傍法 (k-NN) によるデータ分類を行う方法を解説しました。
k 近傍法は、分類アルゴリズムの中ではかなりシンプルな考え方の方法で簡単に適用できます。まずデータ分類するときに使ってみるのもよいでしょう。必ずしも複雑な分類モデルが常に適切ということはなく、k 近傍法で十分な例もあるかもしれません。
今回紹介したように簡単に使用できますので、試しに使ってみてください。
上記で紹介しているソースコードについては GitHub にて公開しています。参考にしていただければと思います。


とランダムフォレスト(RandomForest)の使用方法.jpg)




