Scikit-Learn を使用して、MNIST データセットを分類するための K 近傍法アルゴリズムを構築する

Scikit-Learn を使用して、MNIST データセットを分類するための K 近傍法アルゴリズムを構築する

K 最近傍アルゴリズム、K-NN とも呼ばれます。今日のディープラーニングの時代では、この古典的な機械学習アルゴリズムは過小評価されることがよくあります。このチュートリアルでは、Scikit-Learn を使用して K 最近傍アルゴリズムを構築し、それを MNIST データセットに適用する方法を説明します。次に、著者は、独自の K-NN アルゴリズムを構築し、Scikit-Learn K-NN よりも正確で高速なアルゴリズムを開発する方法を説明します。

1. K近傍分類モデル

K 最近傍アルゴリズムは実装が簡単な教師あり機械学習アルゴリズムであり、その分類パフォーマンスは非常に堅牢です。 K-NN の利点の 1 つは、SVM、回帰、多層パーセプトロンなどのトレーニングを必要とする他の ML アルゴリズムとは異なり、トレーニングなしでモデルがデータを分類できる、つまり遅延アルゴリズムであることです。

K-NNの仕組み

特定のデータ ポイント p を分類するために、K-NN モデルはまず、何らかの距離メトリックを使用して p をデータベース内の他のポイントと比較します。

距離メトリックは、ユークリッド距離のように、2 つのポイントを入力として受け取り、それらの間の距離を返す単純な関数です。

したがって、2 つのポイント間の距離が短い方が、2 つのポイント間の距離が長い場合よりも類似していると考えられます。これがK-NNの核となる考え方です。

この手順では、各エントリがモデル データベース内の p と n のデータ ポイント間の距離を表す順序付けられていない配列を返します。したがって、返される配列のサイズは n です。

K 最近傍の K の意味は次のとおりです。k は、p を分類するときにモデルが考慮する最も類似したポイントの数を示す任意の値 (通常は 3 ~ 11) です。次に、モデルは最も類似した k 個の値を記録し、投票アルゴリズムを使用して、下の図に示すように、p がどのクラスに属するかを決定します。

上図の K-NN モデルの k 値は 3 で、矢印が指している中心点は p であり、これがアルゴリズムが分類するポイントです。

ご覧のとおり、円内の 3 つの点は p に最も近い、または最も類似した 3 つの点です。したがって、単純な投票アルゴリズムを使用すると、最も類似した k 個の値の中で白が多数派であるため、p は「白」に分類されます。

すごいですね!しかし驚くべきことに、この単純なアルゴリズムは、特定の状況では素晴らしい結果を達成でき、さまざまな問題に適用できます。これについては以下で説明します。

2. Scikit-LearnでK-NNアルゴリズムを実装してMNIST画像を分類する

1. データ

この例では、一般的な MNIST データセットを使用します。 MNIST データセットは、実装が簡単で、モデルを検証するための信頼性の高い方法であるため、機械学習で最もよく使用されるデータセットの 1 つです。

MNIST は、0 ~ 9 の手書き数字 70,000 個のデータセットです。手書きの数字はどれも同じではなく、正しく分類するのが難しい数字もあります。

2. アルゴリズム

まず、Scikit-Learn Python ライブラリの KNeighborsClassifier() 関数から始めます。この関数には多くのパラメータがありますが、この例ではいくつかのパラメータのみを使用します。具体的には、n_neighbors パラメータの値 (つまり、k 値) のみを渡します。

weights パラメータは、モデルで使用される投票アルゴリズムのタイプを指定します。デフォルト値は、uniform です。これは、p を分類するときに、k 個の各ポイントが同じ重みを持つことを意味します。また、Scikit-Learn で MNIST データを分類するための最適なアルゴリズムを自動的に見つけられるようにしたいので、アルゴリズム パラメータにはデフォルト値の auto を使用します。

Scikit-Learn を使用して K-NN 分類器を構築するための Jupyter Notebook は次のとおりです: Scikit-Learn を使用した MNIST の K 近傍法アルゴリズム

ノートブックのアドレス: https://gist.github.com/samgrassi01/82d0e5f89daac3e65531a6ef497cc129#file-skl-knn-ipynb

必要なライブラリを直接インポートすることから始めます。

  1. [1]では:
  2. numpyをnpとしてインポートする
  3.  
  4. sklearn からデータセットをインポートし、model_selection を実行します。
  5. sklearn.neighbors から KNeighborsClassifier をインポートします
  6. sklearn.metricsからclassification_reportをインポート
  7.  
  8. mnist = datasets.fetch_mldata ('MNIST オリジナル')
  9. データ、ターゲット= mnist.data 、mnist.target
  10.  
  11. # すべてが正しくインポートされたことを確認する
  12. データ.shape、ターゲット.shape
  13. アウト[1]:
  14. ((70000, 784), (70000,))

(1)データセットの構築

さまざまなデータセットを作成して K-NN モデルを構築します。特定のサイズのデータ​​セットを受け取り、そのデータセットのサイズを返す関数を作成します。

  1. [2]では:
  2. # データ セットの作成に使用する MNIST のサイズのインデックス配列を作成します。
  3. # この配列はランダムな順序になっているので、MNISTデータを混ぜ合わせるために使うことができます
  4. indx = np .random.choice(len(target), 70000, replace = False )
  5.  
  6. # テスト用のデータセットを構築する方法
  7. mk_dataset(サイズ)を定義します:
  8. 「サイズ」のデータセットを作成し、そのデータセットの画像とターゲットを返します。
  9. これは、モデルによって保存され、
  10. 保存されたデータセットのサイズを変えて実験する
  11. 「」
  12. train_img = [データ[i]、iはindx[:size]]
  13. train_img = np.array (train_img)
  14. train_target = [target[i] for i in indx[:size]]
  15. トレーニングターゲット= np .array(トレーニングターゲット)

良い。ここで、この関数を使用して、異なるサイズの 2 つのデータセットを構築し、異なるデータ量でのモデルの分類パフォーマンスがどのようになるかを確認します。

ヒント: データセットを小さくしても分類は実行できますが、モデルのデータが少なくなり、分類エラーが発生する可能性があります。

  1. [3]では:
  2. # データセットのサイズを50,000にします。つまり、モデルには50,000個のデータポイントがあり、それぞれを比較することになります。
  3. # 新しいポイントは分類することです
  4. 50_x、 50_y = mk_dataset (50000)
  5. 50_x.形状、50_y.形状
  6. アウト[3]:
  7. ((50000, 784), (50000,))
  8. [4]では:
  9. # サイズ 20,000 のものをもう 1 つ作成し、それを使用したときに分類精度がどのように低下​​するかを確認します。
  10. 20_x、 20_y = mk_dataset (20000)
  11. 20_x の形状、20_y の形状
  12. アウト[4]:
  13. ((20000, 784), (20000,))

モデルのデータがどのようにラベル付けされているかに注目してください。モデルは、各ポイントが何を表しているかを理解するためにこれらのラベルを必要とするため、「これは分類したいポイントに最も類似するクラスです」と言うのではなく、分類したいポイントを特定のクラスに分類することができます。

ここで、サイズ 10000 のテスト セットを構築します。

  1. [5]では:
  2. # モデルテストデータセットを構築する
  3. test_img = [データ[i]、iはindx[60000:70000]]
  4. test_img1 = np.array (テスト_img)
  5. test_target = [target[i] 、i が indx[60000:70000] の場合]
  6. test_target1 = np .array(test_target)
  7. test_img1.shape、test_target1.shape
  8. アウト[5]:
  9. ((10000, 784), (10000,))

素晴らしい!これですべてのデータ処理が完了したので、K-NN モデルの構築を開始できます。

(2)モデル構築

まず、Scikit-Learn K-NN モデルを関数に配置して、簡単に呼び出して調整できるようにします。

  1. [6]では:
  2. def skl_knn(k, テストデータ, テストターゲット, 保存データ, 保存ターゲット):
  3. """k: 分類に使用する近傍の数
  4. test_data: 分類器をテストするために使用されるデータ/ターゲット
  5. 保存データ: テストデータを分類するために使用されるデータ/ターゲット
  6. 「」
  7.  
  8. 分類子= K近隣分類子( n_近隣= k )
  9. 分類器.fit(保存されたデータ、保存されたターゲット)
  10.  
  11. y_pred =分類器.予測(テストデータ)
  12.  
  13. 印刷(分類レポート(テストターゲット、y_pred))

(3)テスト

ここで、このモデルが 2 つの異なるテスト セットでどのように機能するかを見てみましょう。

  1. [7]では:
  2. %%時間
  3. # 保存データセットのサイズは 50,000
  4. skl_knn(5、テスト画像1、テストターゲット1、50_x、50_y)

  1. [8]では:
  2. %%時間
  3. # 保存データセットのサイズは 20,000
  4. skl_knn(5、テスト画像1、テストターゲット1、20_x、20_y)

はい!私たちのモデルは人間の目とほぼ同じくらい優れています!ご覧のとおり、モデルが処理するデータが多いほど(20,000 ポイントではなく 50,000 ポイント)、パフォーマンスが大幅に向上します。さらに印象的なのは、そのシンプルさと、さまざまな画像間の複雑な関係を人間レベルで捉える能力です。より詳細な分析については、この GitHub リポジトリをご覧ください。

https://github.com/samgrassi01/Cosine-Similarity-Classifier をご覧ください。

素晴らしい! Scikit-Learn を使用して、MNIST データセットで驚くほど優れたパフォーマンスを発揮する非常にシンプルな K 近傍法モデルを構築しました。

欠点は、これらのポイントを分類するのに長い時間がかかることです (2 つのデータセットでそれぞれ 8 分と 4 分)。皮肉なことに、K-NN は依然として最も高速な分類方法の 1 つです。もっと速い方法が必要です。

3. より高速なモデルを構築する

ほとんどの K-NN モデルでは、距離メトリックとしてユークリッド距離またはマンハッタン距離が使用されます。これらのインジケーターは非常にシンプルで、さまざまな状況でうまく機能します。

あまり一般的ではない別の距離メトリックは、コサイン類似度です。コサイン類似度は、三角不等式に違反し、負の数に対しては無効であるため、通常は距離測定基準として適していません。しかし、コサイン類似度は MNIST に非常に適しています。これは高速で、アルゴリズムが単純であり、MNIST に適用される他の距離メトリックよりもわずかに正確です。

ただし、最高のパフォーマンスを得るには、K-NN モデルを自分で記述する必要があります。そうすれば、Scikit-Learn モデルよりも高いパフォーマンスとさらに高い精度を実現できるはずです。確立された K-NN モデルの次のノートブックを見てみましょう。

より高速な KNN 分類器の構築

ノートブックアドレス:

https://gist.github.com/samgrassi01/15a1fe53dcde8813eed9367b103676b2#file-cos-knn-ipynb

このノートブックでは、より高速でより正確なモデルを見つけるために、距離メトリックとしてコサイン類似度を使用して MNIST 画像を分類する単純な K-NN モデルを構築します。

まず、必要なライブラリをインポートし、Scikit-Learn K-NN ノートブックと同じデータセットを構築する必要があります。

  1. [1]では:
  2. numpyをnpとしてインポートする
  3. heapq をインポートする
  4. コレクションからカウンターをインポート
  5. sklearn.metrics.pairwise から cosine_similarity をインポートします
  6. sklearn からデータセットをインポートし、model_selection を実行します。
  7. sklearn.metricsからclassification_reportをインポート
  8.  
  9. mnist = datasets.fetch_mldata ('MNIST オリジナル')
  10. データ、ターゲット= mnist.data 、mnist.target
  11.  
  12. # すべてが正しくインポートされたことを確認する
  13. データ.shape、ターゲット.shape
  14. アウト[1]:
  15. ((70000, 784), (70000,))

Scikit-Learn K-NN ノートブックと同じ方法を使用して、まったく同じデータセットを設定します。

  1. [2]では:
  2. # データ セットの作成に使用する MNIST のサイズのインデックス配列を作成します。
  3. # この配列はランダムな順序になっているので、MNISTデータを混ぜ合わせるために使うことができます
  4. indx = np .random.choice(len(target), 70000, replace = False )
  5.  
  6. # テスト用のデータセットを構築する方法
  7. mk_dataset(サイズ)を定義します:
  8. 「サイズ」のデータセットを作成し、そのデータセットの画像とターゲットを返します。
  9. これは、モデルによって保存され、
  10. 保存されたデータセットのサイズを変えて実験する
  11. 「」
  12. train_img = [データ[i]、iはindx[:size]]
  13. train_img = np.array (train_img)
  14. train_target = [target[i] for i in indx[:size]]
  15. トレーニングターゲット= np .array(トレーニングターゲット)
  16.  
  17. train_img、train_targetを返す
  18. [3]では:
  19. # データセットのサイズを50,000にします。つまり、モデルには50,000個のデータポイントがあり、それぞれを比較することになります。
  20. # 新しいポイントは分類することです
  21. 50_x、 50_y = mk_dataset (50000)
  22. 50_x.形状、50_y.形状
  23. アウト[3]:
  24. ((50000, 784), (50000,))
  25. [4]では:
  26. # サイズ 20,000 のものをもう 1 つ作成し、それを使用したときに分類精度がどのように低下​​するかを確認します。
  27. 20_x、 20_y = mk_dataset (20000)
  28. 20_x の形状、20_y の形状
  29. アウト[4]:
  30. ((20000, 784), (20000,))
  31. [5]では:
  32. # モデルテストデータセットを構築する
  33. test_img = [データ[i]、iはindx[60000:70000]]
  34. test_img1 = np.array (テスト_img)
  35. test_target = [target[i] の i が indx[60000:70000] の場合]
  36. test_target1 = np .array(test_target)
  37. test_img1.shape、test_target1.shape
  38. アウト[5]:
  39. ((10000, 784), (10000,))

1. モデルを構築する

次に、MNIST データセットの分類子として関数 cos_knn() を作成します。関数のコメントを使用すると、関数がどのように動作するかを理解できます。

  1. [6]では:
  2. cos_knn(k, テストデータ, テストターゲット, 保存データ, 保存ターゲット):
  3. """k: 投票に使用する近隣の数
  4. test_data: 分類する未観測画像のセット
  5. test_target: test_data のラベル (精度を計算するため)
  6. saved_data: すでに観測され、モデルで利用可能な画像
  7. storage_target: 保存データのラベル
  8. 「」
  9.  
  10. # test_data のすべてのポイントと、stored_data の他のすべてのポイント間のコサイン類似度を求める
  11. cosim =コサイン類似度(テストデータ、保存データ)
  12.  
  13. # 任意の test_data ポイントに最も類似する、stored_data 内の画像の上位 k 個のインデックスを取得します。
  14. top = [(heapq.nlargest((k), range(len(i)), i.take)) i が cosim 内にある場合]
  15. # 保存されたターゲット値を使用してインデックスを数値に変換します
  16. top = [[stored_target[j]、j は i[:k]]、i は top]
  17.  
  18. # 投票し、test_data 内のすべての画像の予測を返します
  19. pred = [max(set(i), key = i .count) for i in top]
  20. pred = np .array(pred)
  21.  
  22. # test_target を使用して分類器の精度を示す表を印刷する
  23. 印刷(分類レポート(テストターゲット、予測))

2. モデルをテストする

ここで、Scikit-Learn K-NN モデルと同様に、2 つのデータセットで cos_knn() モデルをテストし、パフォーマンスを確認してみましょう。

  1. [7]では:
  2. %%時間
  3. # 保存データセットのサイズは 50,000
  4. cos_knn(5, テスト画像1, テストターゲット1, 50_x, 50_y)

  1. [8]では:
  2. %%時間
  3. # 保存データセットのサイズは 20,000
  4. cos_knn(5, テスト画像1, テストターゲット1, 20_x, 20_y)

素晴らしい! コサイン類似度モデルは Scikit-Learn K-NN よりも優れています! また、このモデルは Scikit-Learn K-NN よりも高速かつ正確であり (速度が大幅に向上)、モデルがはるかにシンプルであることも注目に値します。

モデルがどのように機能するか、またさまざまな状況で Scikit-Learn K-NN モデルよりも優れている理由をさらに分析するには、次の GitHub リポジトリを参照してください。

https://github.com/samgrassi01/Cosine-Similarity-Classifier をご覧ください。

ノートブックに示されているように、この K-NN モデルは分類速度と精度の両方で Scikit-Learn K-NN を上回っており、1 つのデータセットで速度が大幅に向上し、精度が 1% 向上しています。そうなると、このモデルを実際に使い続けることができます。

IV. 結論

まず、K-NN がどのように機能し、どのように簡単に実装するかがわかります。しかし、最も重要なことは、解決すべき問題とそれを解決するためのツールについて常に考えることが重要だということが分かりました。場合によっては、問題解決の過程では、時間をかけて練習し、もちろん独自のモデルを構築するのが最善です。ノートブックで実証されているように、これには劇的な利点があります。2 番目の独自モデルでは 1.5 ~ 2 倍の高速化が達成され、多くの時間を節約できました。

オリジナルリンク:

https://towardsdatascience.com/building-improving-ak-nearest-neighbors-algorithm-in-python-3b6b5320d2f8

[この記事は51CTOコラム「Machine Heart」、WeChatパブリックアカウント「Machine Heart(id:almosthuman2014)」によるオリジナル翻訳です]

この著者の他の記事を読むにはここをクリックしてください

<<:  人工知能が教育改革にどのように貢献しているかをご覧ください

>>:  多くの人がまだブロックチェーンについて漠然とした理解しか持っていない中、これらのブロックチェーンの応用シナリオはすでに実装されている。

ブログ    

推薦する

5つの異なるタイプの人工知能

近年、人工知能は、データから洞察を引き出すことに関する企業の考え方を一変させました。ほとんどの人はこ...

...

ドローンやAIなどハイテクが大学入試特別編をエスコート!

昨日(7月7日)、流行病の影響で延期されていた2020年度大学入試センター試験が正式に始まりました。...

AIは「GitHub危機」を乗り越えられるか?

機械学習は現在、この分野の急速な発展を妨げるいくつかの危機に直面しています。これらの危機は、より広範...

疫病流行後、自動運転開発の方向性がより明確になりました!

自動運転は長い間、人々に「とても人気があるが、とても遠い存在」という印象を与えてきました。それは、何...

...

江長建、世界初のサイボーグと対談 - JD Smart Community 2.0 全国ローンチカンファレンス ライブプレビュー

[[374688]] 「半オーク」「半魚」… SF映画、漫画、おとぎ話では、それは驚くことではありま...

...

テルアビブ大学は、SOTAメソッドとアーキテクチャの新たな進歩を完全に理解するためにStyleGANを要約しました。

GAN の高解像度画像を生成する能力は、画像合成および処理の分野に革命をもたらしています。 201...

海外で最も人気のあるディープラーニング実践コースの新バージョンがリリースされました。100%新しい最先端のコンテンツを備えています。

良いニュースです。お勧めの新しいコースがあります!理論と実践を組み合わせた完全無料の海外で最も人気の...

...

uSens 馬 源宇: 人工知能と仮想現実が出会うとき

[51CTO.comより引用] 2017年7月21日から22日まで、51CTO主催の人工知能をテーマ...