Quantcast
Channel: 初心者タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 21081

K最近傍法(K-Nearest Neighbor) 分類 基礎

$
0
0

K近傍法 (K-Nearest Neighbor) 概要

k近傍法(以下k-NN)はもっとも単純な分類アルゴリズムであり、予測したいデータと距離の近い、k個の訓練データの正解ラベルから予測値を決定するアルゴリズムである。

<メリット>
- モデルの過度な調整無しにある程度の精度が出る
- アルゴリズムの理解が容易

<デメリット>
- データの前処理必須
- 特徴量(数百以上)の多いデータセットでは上手く機能しない
- 疎なデータセットでは精度が出ない
- 処理速度が遅い

上記デメリットから実務上あまり使われることはない。

K-NNの以下の2つのうち分類(Classification)について本記事ではまとめる。

  1. Nearest Neighbor Classification (分類)
  2. Nearest Neighbor Regression (回帰)

分類: Nearest Neighbor Classification

予測のためのHyper Parameter は以下。
参考=> sklearn

Parameters詳細
n_neighborsアルゴリズム判断に用いる近傍点の数 (default=5)
weights予測判断に用いる重みの設定 (default="uniform")

"uniform":均一な重み
"distance":距離に応じた重み
algorithm予測のためのアルゴリズム (default="auto")

"ball_tree":BallTreeアルゴリズム
"kd_tree":KD Treeアルゴリズム
"brute":総当たり探索
"auto": 最適なアルゴリズムを自動で選択
leaf_sizeKD Tree, Ball Treeアルゴリズムを用いるときのリーフサイズ
metric距離の測定方法 (default="minkowski)
pMinkowski metricにおけるPower Parameter
n_jobs利用するCPU数の設定 (default=1)

Cancer Datasetでの予測分類

実際にsklearnのcancer datasetにて分類予測を行う。

まず必要なライブラリを読み込む。
classfication_reportは予測値の評価に用いる。

#必要なライブラリの読み込み
%matplotlibinlineimportnumpyasnpimportmatplotlib.pyplotaspltimportpandasaspdfromsklearn.model_selectionimporttrain_test_splitfromsklearn.metricsimportclassification_report#sklean cancer dataの読み込み
fromsklearn.datasetsimportload_breast_cancer

Cancer DataSetの詳細を確認する。
sklearn cancer datasetには説明変数(特徴量)が30、569のデータポイントがある。
目的変数(ラベル)のうち"0"が悪性の腫瘍(malignant)、"1"が良性の腫瘍(benign)を示す。

dataset=load_breast_cancer()# 特徴量 (説明変数)
X=pd.DataFrame(dataset.data,columns=dataset.feature_names)#ラベル(目的変数)
y=pd.Series(dataset.target,name='y')# データ詳細確認
print('X shape: (%i,%i)'%X.shape)print(y.value_counts())display(X.join(y).head())

image.png

実際に訓練データ/テストデータに分割の上、予測精度の確認を行う。
ハイパーパラメーターのうち近傍オブジェクト数を変数(1~10)とし、予測精度の変化をプロットする。

fromsklearn.neighborsimportKNeighborsClassifier#データセットをtest sampleを割合20%でホールドアウトする。
X_train,X_test,y_train,y_test=train_test_split(X,y,random_state=0,test_size=0.2)#近傍オブジェクト数とその予測スコアを格納するリストを準備
List_n_neighbors=[]List_train_score=[]List_test_score=[]#近傍オブジェクト数を1-10で予測値を比較。訓練データに対してfitする。
forn_neighborsinrange(1,11):clf=KNeighborsClassifier(n_neighbors=n_neighbors).fit(X_train,y_train)#訓練スコアと予測スコアを算出してリストに格納
List_n_neighbors.append(n_neighbors)List_train_score.append(clf.score(X_train,y_train))List_test_score.append(clf.score(X_test,y_test))#近傍オブジェクト数に対して訓練スコア、テストスコアをプロットする
fig=plt.figure(figsize=(10,6))plt.plot(List_n_neighbors,List_train_score,label="training accuracy")plt.plot(List_n_neighbors,List_test_score,label="test accuracy")plt.ylabel("Accuracy")plt.xlabel("n_neighbors")plt.xticks(np.linspace(1,11,11))plt.legend()

image.png

まとめ

Cancer Datasetを用いた予測においては近傍オブジェクト数(k)がk=6あたりが最良の性能であることがうかがえる。ただしK=2の場合でも88%程度の精度が担保されており、特徴量30程度のCancer Datasetに関してはNearest Neighbor Classificationによる分類は十分に機能しているといえる。

以下classification_reportによる結果を確認しても再現率(recall)、適合率(precision)ともに大きな偏りなく精度を保っていることが確認できる。

ただし実際に実務上、ガンの診断に使えるかというと以下classification_reportによる結果を確認するとmalignant再現率(recall)の精度から悪性47件のうち3件程度は悪性腫瘍(malignant)を良性(benign)と判断してしまう点から十分な精度ではないと思われる。

clf=KNeighborsClassifier(n_neighbors=6).fit(X_train,y_train)predict_result=clf.predict(X_test)print(classification_report(y_test,predict_result,target_names=["malignant","benign"]))

image.png


Viewing all articles
Browse latest Browse all 21081

Trending Articles