Pyts 入門のための時系列の分類 --- K 最近傍アルゴリズムとパラメーター調整のヒント (2)

序章

上記(2021.11.05)の続きで、pyts時系列の簡単な特徴抽出を紹介した後、時系列の分類アルゴリズムを紹介し、KNN(k-nearest neighbors)アルゴリズムから始めて分類アルゴリズムを紹介する記事です。仕事で面倒なことがあったため、最近記事を書いていません。おそらく、私をフォローしている友達は、なぜ私をフォローしたか忘れています。本当に申し訳ありません。それでは、本題に入ります。まず、KNN アルゴリズム (分類) について一般的に理解する必要があります。 1. K 平均法アルゴリズムではありません (K 平均法は教師なしクラスタリング アルゴリズムであり、初心者はよく混同します)

2. 教師あり学習アルゴリズムです。
3. K は投票する K 個の最近傍 (近傍) を選択することを意味し、どちらのタイプがより多くの票を持っているかをどのタイプに分類するかを示します。K=1 の場合、サンプルに最も近いクラスがそのクラスになります。
4. 距離の定義はたくさんありますが、空間内の 2 点間の距離はユークリッド距離であるとよく言われます。
5. KNN はデータセットの構造に敏感です。
6. 実際に使用する前に、通常、データセットに対して特徴抽出 (または次元削減) が実行されます。これにより、顔認識で opencv によって使用される haar カスケード分類などのアルゴリズムの安定性と精度が向上します。

ここに画像の説明を挿入
上の図はwikiから引用したものですが、図中の緑の丸が分類対象のサンプル点で、K=3の場合、青い四角と2つの赤い三角形を含む3つの最も近い点(実線の円)を選択すると、赤い三角形として分類されます。

上記の紹介の後、このアルゴリズムには非常に重要な 3 つのパラメーターがあることもおわかりいただけると思います。

1. K (近傍)の数。つまり、選択される近傍の数は、選択が大きいほどアルゴリズムは安定しますが、ある程度の区別は失われます。たとえば、近傍の数がサンプルの数と等しい場合、すべての点が分類基準として使用されるため、新しいサンプルをどのように分類しても、結果は同じになります。

2. 距離の選択(メートル法)。点間の距離をどのように測定するかによって、サンプル点を判断する距離が決まります。
減算の二乗差であるユークリッド距離 (sqrt(sum((x - y)^2))) などの古典的な距離が多数あります。
マンハッタン距離 (sum(|x - y|))、減算の絶対値。
ミンコフスキー距離 (sum(w * |x - y| p) (1/p))、q=1 は絶対距離、q=2 はユークリッド距離です。

3. 重量の影響(重量)。重みを導入するという考え方は、近い点が遠い点よりもサンプル 点に大きな影響を与えることを考慮することです。一般的な方法は 1/d (d は点とサンプル 点の間の距離) を導入することです。

練習

from pyts.classification import KNeighborsClassifier
from pyts.datasets import load_gunpoint
X_train, X_test, y_train, y_test = load_gunpoint(return_X_y=True)
clf = KNeighborsClassifier()
clf.fit(X_train, y_train)
clf.score(X_test, y_test)
#score:0.913333333333333333333333

1 つ目はデフォルトのパラメータの結果で、正解率は 0.91333 です。次に、正解率を向上させるためにパラメータを調整してみます。
デフォルトのパラメーター (つまり、入力パラメーターなし) は次のとおりです:
n_neighbors=1、weights='uniform'、algorithm='auto'、leaf_size=30、p=2、metric='minkowski'、metric_params=None、n_jobs=1

パラメータ 説明する
n_neighbors=1 近傍数は 1 (整数) です。
重み='均一' デフォルトでは重みは追加されませんが、「距離」の場合は 1/d の重みが追加されます
アルゴリズム='自動' 最近傍を計算するには {'auto'、'ball_tree'、'kd_tree'、'brute'} の 4 つの方法があり、それぞれ計算パフォーマンスが異なります (大規模なサンプル セット)
葉のサイズ=30 ball_tree または kd_tree のリーフの数は、リーフの構築速度に影響し、パフォーマンスにも影響します。
p=2 ミンコフスキー距離の p 値は、2 に等しい場合はユークリッド距離に相当し、1 に等しい場合はマンハッタン距離に相当します。
metric='ミンコフスキー' 距離ルール。「ユークリッド」、「マンハッタン」などのさまざまな距離を渡すことができます。詳細については、sklearn の DistanceMetric クラスを参照してください。
metric_params 一部の距離に対する特定のパラメータ。デフォルトはなしです。
n_ジョブ=1 近隣スレッドの検索に使用される並列スレッドの数。-1 に設定すると、すべてのリソースを使用して検索することを意味します。デフォルトは 1 です。

次に、主にn_neighbors、weights、p の3 つのパラメーターを変更して、結果の変化を確認します。

from sklearn.model_selection import GridSearchCV #网格搜索
parameters = {
    
    'weights':('uniform', 'distance'),'n_neighbors':[1,2,3,4,5],'p':[1,2]} #定义搜索参数
clf_grid = GridSearchCV(clf, parameters)#传入之前定义好的实例和参数
clf_grid.fit(X_train, y_train)
clf_grid.cv_results_ #打印在训练集上的结果

パラメータに対してグリッド検索を行って最適なパラメータを見つけました。cv_results_ は長いリストを出力します。その一部を取り出して説明します。

'params': [{
    
    'n_neighbors': 1, 'p': 1, 'weights': 'uniform'},
  {
    
    'n_neighbors': 1, 'p': 1, 'weights': 'distance'},
  {
    
    'n_neighbors': 1, 'p': 2, 'weights': 'uniform'},
  {
    
    'n_neighbors': 1, 'p': 2, 'weights': 'distance'},
  {
    
    'n_neighbors': 2, 'p': 1, 'weights': 'uniform'},
  {
    
    'n_neighbors': 2, 'p': 1, 'weights': 'distance'},
  {
    
    'n_neighbors': 2, 'p': 2, 'weights': 'uniform'},
  {
    
    'n_neighbors': 2, 'p': 2, 'weights': 'distance'},
  {
    
    'n_neighbors': 3, 'p': 1, 'weights': 'uniform'},
  {
    
    'n_neighbors': 3, 'p': 1, 'weights': 'distance'},
  {
    
    'n_neighbors': 3, 'p': 2, 'weights': 'uniform'},
  {
    
    'n_neighbors': 3, 'p': 2, 'weights': 'distance'},
  {
    
    'n_neighbors': 4, 'p': 1, 'weights': 'uniform'},
  {
    
    'n_neighbors': 4, 'p': 1, 'weights': 'distance'},
  {
    
    'n_neighbors': 4, 'p': 2, 'weights': 'uniform'},
  {
    
    'n_neighbors': 4, 'p': 2, 'weights': 'distance'},
  {
    
    'n_neighbors': 5, 'p': 1, 'weights': 'uniform'},
  {
    
    'n_neighbors': 5, 'p': 1, 'weights': 'distance'},
  {
    
    'n_neighbors': 5, 'p': 2, 'weights': 'uniform'},
  {
    
    'n_neighbors': 5, 'p': 2, 'weights': 'distance'}]

この長いリストは、検索を定義するパラメータのすべての可能な結果を​​順列および組み合わせたもので、実際には、どれが最適であるかを 1 つずつトレーニングすることになります。

'rank_test_score': array([ 4,  4,  1,  1,  4,  4, 17,  1,  9,  9, 13, 13, 13,  9, 20,  9, 13,
         4, 19, 17]

この一連の数字は、上記の非常に多くのテスト結果のランキングです。3番目と 4 番目の結果が最も優れていることがわかります。同時に、注意深い友人なら、重みを導入した場合の結果が導入しない場合よりも一般に優れていることがわかります。3 番目のパラメーターはデフォルトのパラメーターと同じなので、テスト セットの 4 番目のパラメーターの結果を確認してみましょう。

clf = KNeighborsClassifier(n_neighbors=1,weights='distance',p=2)
clf.fit(X_train, y_train)
clf.score(X_test, y_test)
#0.91333333

「これは改善されていないのではないか?」と思われるかもしれません。このグリッド検索は何を検索しているのか。トレーニング セットでの良好な CV 結果は、テスト セットでの良好な効果を保証するものではありませんが、トレーニング セットでの CV 結果が悪いと、テスト セットでも悪くなる可能性があることに注意してくださいそこで参考になるのがグリッド検索です。実際の機械学習はより複雑で、テスト セットで良好な結果が得られたからといって、新しいサンプルで良好な結果が得られたことを意味するわけではありませんが、いくつかの基本的な常識に従うことで汎化パフォーマンスを向上させることができます。

clf = KNeighborsClassifier(n_neighbors=1,weights='distance',p=1)
clf.fit(X_train, y_train)
clf.score(X_test, y_test)
#0.9533333333333334

実際、距離をマンハッタンに切り替えた後、テスト セットの正解率は大幅に増加し、0.953333 に達します。ただし、これは実際には小さなサンプル セットであり、その形状は (50,150) です。

参考文献

1.https://en.wikipedia.org/wiki/K-nearest_neighbors_algorithm
2.https://scikit-learn.org/stable/modules/generated/sklearn.metrics.DistanceMetric.html?highlight= distance#sklearn.metrics.DistanceMetric
3.https://pyts.readthedocs.io/en/stable/modules/classification.html

おすすめ

転載: blog.csdn.net/weixin_43945848/article/details/123175689