I.距離メトリック
まず、データセット内の特徴(列)の数は、kNNで使用する距離メトリックを選択する際の要因にはなりません。正確にこの質問に向けられた出版された研究はかなり多く、比較のための通常の基準は次のとおりです。
データのサンプリング元の分布について事前の知識がない場合、少なくとも1つの(十分に文書化された完全な)調査により、ユークリッド距離が最良の選択であると結論付けられます。
メガスケールのWebレコメンデーションエンジンおよび現在の学術研究で使用されているYEuclideanメトリック。ユークリッド距離は、直感的な意味と計算スケールで計算されます。つまり、ユークリッド距離は、2点が2次元空間にあるか22次元空間にあるかにかかわらず、同じ方法で計算されます。
私にとって数回失敗しただけです。それらのケースのそれぞれで、ユークリッド距離は失敗しました。たとえば、パスの長さ(距離)が加算されないため、通常はこれを認識します。たとえば、距離空間がチェス盤の場合、マンハッタン距離はユークリッド距離よりも優れています。距離空間が地球で距離がトランスの場合も同様です。 -大陸便、極座標系に適した距離メトリックは良い考えです(たとえば、ロンドンからウィーンまでは2.5時間、ウィーンからサンクトペテルブルグまでは同じ方向に多かれ少なかれ3時間ですが、ロンドンからセントまで。Petersburgは5.5時間ではなく、3時間強です。)
ただし、データが非デカルト座標系に属している場合を除いて、距離メトリックの選択は通常重要ではありません。(CS学生からのこのブログ投稿を参照し、kNN分類器への影響を調べることによっていくつかの距離メトリックを比較します-カイ二乗は最良の結果を与えますが、違いは大きくありません;より包括的な研究は学術論文の比較研究最近傍の距離関数-マハラノビス(本質的には次元共分散を説明するために正規化されたユークリッド)がこの研究で最高でした。
重要な条件の1つ:距離メトリックの計算を意味のあるものにするには、再スケーリングする必要がありますデータ-これを行わずにkNNモデルを構築して正確な予測を生成することはほとんどありません。たとえば、運動パフォーマンスを予測するためのkNNモデルを構築していて、期待変数が身長(cm)、体重(kg)、体脂肪(%)、および安静時の脈拍(1分あたりの拍数)である場合、一般的なデータポイントは次のようになります:[180.4、66.1、11.3、71]。明らかに、距離の計算は高さによって支配されますが、体脂肪率による寄与はほとんど無視できます。別の言い方をすれば、代わりにデータが異なる方法で報告され、体重がキログラムではなくグラムであった場合、元の値86.1は86,100になり、結果に大きな影響を与えます。欲しくない。
X_new = (X_old - mu) / sigma
II。データ構造
kdツリー構造のパフォーマンスが心配な場合、ボロノイテッセレーションは概念的には単純なコンテナーですが、パフォーマンスが大幅に向上し、kdツリーよりも適切にスケーリングされます。
これは、kNNトレーニングデータを永続化するための最も一般的な方法ではありませんが、この目的でのVTの適用と、その結果としてのパフォーマンスの利点は十分に文書化されています(たとえば、このMicrosoft Researchレポートを参照)。これの実際的な重要性は、「主流」の言語を使用している場合(例:TIOBEインデックス)、VTを実行するためのライブラリーを見つける必要があることです。私はPythonとRで、各言語に複数のオプションがあることを知っています(たとえば、CRANで利用可能なR のボロノイパッケージ)
kNNにVTを使用すると、次のように機能します。
データからw個の点をランダムに選択します。これらはボロノイ中心です。ボロノイセルは、各中心に最も近いすべての隣接ポイントをカプセル化します。各ボロノイセンターに異なる色を割り当て、特定のセンターに割り当てられた各ポイントにその色が塗られるように想像してみてください。十分な密度がある限り、これを行うと、各ボロノイ中心の境界が(2つの色を分ける境界として)うまく表示されます。
ボロノイセンターの選択方法 2つの直交するガイドラインを使用します。wポイントをランダムに選択した後、トレーニングデータのVTを計算します。次に、各ボロノイセンターに割り当てられたデータポイントの数を確認します。これらの値はほぼ同じである必要があります(データ空間全体で均一なポイント密度が与えられている場合)。2次元では、これにより同じサイズのタイルを持つVTが発生します。これが最初のルールで、2番目のルールです。反復によるwを選択します-変数パラメーターとしてwを使用してkNNアルゴリズムを実行し、パフォーマンス(VTをクエリして予測を返すのに必要な時間)を測定します。
したがって、100万のデータポイントがあると想像してください.....ポイントが通常の2Dデータ構造またはkdツリーで永続化されている場合、平均でそれぞれについて数百万の距離計算を実行します。応答変数を予測する新しいデータポイント。もちろん、これらの計算は単一のデータセットに対して実行されます。V / Tを使用すると、2つの異なるデータ母集団に対して、次の2つのステップで最近傍探索が実行されます。最初にボロノイ中心に対して、次に最近傍が見つかると、その中心は、実際の最近傍を見つけるために検索されます(連続距離計算により)。これらの2つのルックアップを組み合わせると、1つの総当たりルックアップよりもはるかに高速になります。これは簡単に確認できます。1Mのデータポイントの場合、250のボロノイセンターを選択してデータスペースをテッセレーションするとします。平均して、各ボロノイセルには4,000のデータポイントがあります。したがって、平均500,000の距離計算(ブルートフォース)を実行する代わりに、はるかに少ない、平均125 + 2,000を実行します。
III。結果の計算(予測応答変数)
kNNトレーニングデータのセットから予測値を計算するには、2つのステップがあります。1つ目は、n、つまりこの計算に使用する最近傍の数を特定することです。2つ目は、予測値への寄与に重みを付ける方法です。
最初のコンポーネントのW / R / Tを使用すると、最適化問題(最小二乗最適化とよく似ている)を解くことにより、nの最適値を決定できます。それが理論です。実際には、ほとんどの人はn = 3を使用します。どのような場合でも、n = 1、n = 2、n = 3などの一連のテストインスタンスに対して(予測値を計算するために)kNNアルゴリズムを実行し、nの関数としてエラーをプロットするのは簡単です。nのもっともらしい値を開始したいだけの場合も、n = 3を使用します。
2番目のコンポーネントは、各近傍の寄与をどのように重み付けするかです(n> 1と仮定)。
最も単純な重み付け手法は、各隣接要素に1 /(dist * K)の重み付け係数を乗算するか、その隣接要素からテストインスタンスまでの距離の逆数に、経験的に得られた定数Kを乗算することです。Iこの手法のファンではありません。これは、最も近いネイバーに重みを付けすぎることが多いためです(同時に、より遠いものに比べて重みが小さくなります)。これの重要性は、特定の予測がほぼ完全に単一の近傍に依存している可能性があることであり、これにより、ノイズに対するアルゴリズムの感度が向上します。
この制限を実質的に回避する、より良い重み付け関数は、ガウス関数です。これは、Pythonでは次のようになります。
def weight_gauss(dist, sig=2.0) :
return math.e**(-dist**2/(2*sig**2))
kNNコードを使用して予測値を計算するには、応答変数を予測するデータポイント( 'テストインスタンス')に最も近いn個の近傍を識別し、n個の近傍のそれぞれについて一度、weight_gauss関数を呼び出して、この関数は、各近隣の重みをテストポイントに返します。この関数は、各近隣の重みを返します。これは、加重平均計算でその近隣の係数として使用されます。