質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

557閲覧

【Scikit-learnのdigitsデータセット分類タスク】K最近傍法アルゴリズムの認識精度に関する質問

datascientist_s

総合スコア11

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2019/05/05 17:52

編集2019/05/05 19:38

K最近傍法アルゴリズムの認識精度について

Scikit-learnのdigitsデータセットについて、不均衡データの認識精度の検証を行うためラベルを「8」「8以外」の2値分類となるよう貼り替え、各種モデルのテストデータセットに対する認識精度を測定したところ、K最近傍法アルゴリズムが異常に高い認識精度だったので、原因が分かる方がいれば回答お願い致します。

ソースコード

訓練データ・テストデータの作成

Python

1from sklearn.datasets import load_digits 2from sklearn.model_selection import train_test_split 3 4digits = load_digits() 5# ラベルを「8である」「8でない」に貼り替える 6y = digits.target == 8 7 8X_train, X_test, y_train, y_test = train_test_split( 9 digits.data, y, random_state=42, stratify=y)

ダミー分類器

python

1from sklearn.dummy import DummyClassifier 2dummy_clf = DummyClassifier(strategy='most_frequent').fit(X_train, y_train) 3pred_dummy = dummy_clf.predict(X_test) 4print('test accuracy:', dummy_clf.score(X_test, y_test))

test accuracy: 0.9022222222222223

K最近傍法

python

1from sklearn.neighbors import KNeighborsClassifier 2from sklearn.model_selection import GridSearchCV 3 4param_grid = [{'n_neighbors': [1, 3, 5, 7, 9]}] 5 6grid_search = GridSearchCV(KNeighborsClassifier(), param_grid, cv=5) 7grid_search.fit(X_train, y_train) 8print(f"Best parameters: {grid_search.best_params_}") 9print(f"Best validation score {grid_search.best_score_}") 10 11knn_clf = grid_search.best_estimator_ 12print('test accuracy:', knn_clf.score(X_test, y_test))

Best parameters: {'n_neighbors': 1}
Best validation score 0.9948032665181886
test accuracy: 0.9933333333333333

決定木

python

1from sklearn.tree import DecisionTreeClassifier 2 3param_grid = [{'max_depth': [1, 3, 5, 7, 9]}] 4 5grid_search = GridSearchCV(DecisionTreeClassifier(random_state=42), param_grid, cv=5) 6grid_search.fit(X_train, y_train) 7print(f"Best parameters: {grid_search.best_params_}") 8print(f"Best validation score {grid_search.best_score_}") 9 10tree_clf = grid_search.best_estimator_ 11print('test accuracy:', tree_clf.score(X_test, y_test))

Best parameters: {'max_depth': 5}
Best validation score 0.9465478841870824
test accuracy: 0.94

ロジスティック回帰

python

1from sklearn.linear_model import LogisticRegression 2 3param_grid = [{'C': [0.001, 0.01, 0.1, 1, 10]}] 4 5grid_search = GridSearchCV(LogisticRegression(random_state=42, solver='lbfgs', max_iter=10000), param_grid, cv=5) 6grid_search.fit(X_train, y_train) 7print(f"Best parameters: {grid_search.best_params_}") 8print(f"Best validation score {grid_search.best_score_}") 9 10logreg_clf = grid_search.best_estimator_ 11print('test accuracy:', logreg_clf.score(X_test, y_test))

est parameters: {'C': 0.01}
Best validation score 0.9665924276169265
test accuracy: 0.9644444444444444

ランダムフォレスト

python

1from sklearn.ensemble import RandomForestClassifier 2 3forest_clf = RandomForestClassifier(n_estimators=400, random_state=42) 4forest_clf.fit(X_train, y_train) 5 6print('test accuracy:', forest_clf.score(X_test, y_test))

test accuracy: 0.9688888888888889

追記

t-SNE(多様体学習)により訓練データを2次元表現に変換し可視化。rbfカーネルのSVMによる認識精度を測った所、KNNに近い精度が確認できました。

t-SNEによる変換と可視化

python

1from sklearn.manifold import TSNE 2import matplotlib.pyplot as plt 3 4tsne = TSNE(random_state=42) 5X_train_tsne = tsne.fit_transform(X_train) 6 7plt.scatter(X_train_tsne[:, 0], X_train_tsne[:, 1], c=y_train)

tsne

SVC

python

1from sklearn.svm import SVC 2 3param_grid = [{'kernel': ['rbf'], 4 'C': [0.001, 0.01, 0.1, 1, 10, 100], 5 'gamma': [0.001, 0.01, 0.1, 1, 10, 100]}, 6 {'kernel': ['linear'], 7 'C': [0.001, 0.01, 0.1, 1, 10, 100]}] 8 9grid_search = GridSearchCV(SVC(random_state=42), param_grid, cv=5) 10grid_search.fit(X_train, y_train) 11print(f"Best parameters: {grid_search.best_params_}") 12print(f"Best validation score {grid_search.best_score_}") 13 14svc_clf = grid_search.best_estimator_ 15pred_svc = svc_clf.predict(X_test) 16print('test accuracy:', svc_clf.score(X_test, y_test))

Best parameters: {'C': 10, 'gamma': 0.001, 'kernel': 'rbf'}
Best validation score 0.9910913140311804
test accuracy: 0.9844444444444445

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

ベースライン的な手法が意外と良い性能出しちゃって、(アピールするつもりだった新手法がかすんで見えるので)困る・・・というのはこの分野、よくある話です。

digitsは割ときれいなデータですので、KNNのようなものが威力を発揮しやすいのでしょう。世の中にはdigitsほどきれいなデータは少ない、ということは留意しておくべきです。

投稿2019/05/05 18:36

hayataka2049

総合スコア30933

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

datascientist_s

2019/05/05 19:00 編集

回答ありがとうございます。 n_neighbors=1のKNNで過学習を起こさず99%の精度が出る時点で、ほぼ全てのテストデータの最近傍点が同一クラスということですもんね。 このような綺麗なデータセットに対してKNNが威力を発揮するのはある意味当然の結果だと思うのですが、そのような綺麗なデータセットに対しては他のアルゴリズムも同等に高精度となると想定していたので意外でした。(おおよその精度を見ることが目的なのでハイパーパラメータの選択はかなり雑ですが)
hayataka2049

2019/05/05 20:00

ロジスティック回帰は線形分離可能でなければ有効に働きませんし、決定木系は軸と垂直な分離境界しか引けないので意外とだめなときがあるのです。また、不均衡データに耐性がない手法だと、クラスの重みを考慮しないで使えば不利です(KNNはある意味関係ない)。 ちなみに、こういうケースだと正解率よりはf1のマクロ平均などで評価するべきです。
datascientist_s

2019/05/05 20:39

回答ありがとうございます。 rbfカーネルを使ったSVMでは近い精度が出たので、高次でも線形分離可能でない部分があることが影響してそうですね。改めて各種アルゴリズムについて実践的な理解が必要なことを認識致しました。 「不均衡データを精度で評価してはいけない」っていうことを確認するためにまず精度だけだしてみた所KNNの精度がやたら高い・・・と思って質問させて頂いた次第なのでf1のマクロ平均等については存じております。 こちらでベストアンサーとさせて頂きます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問