k 近傍法(k-NN)2D 分類シミュレーター 戻る
機械学習シミュレーター

k 近傍法(k-NN)2D 分類シミュレーター — 決定境界と LOO 精度

3 クラスの 2D 学習データに対する k-NN 分類器を可視化。k 値・クエリ点・学習データの分散を変えて、決定境界の形状と LOO 交差検証精度を直感的に学べます。

パラメータ設定
k(近傍数)
クエリ点 x
クエリ点 y
学習データの分散 σ

データはシード 42 の LCG で決定論的に生成(クラスごとに 15 点、計 45 点)。距離はユークリッド距離を使用。

計算結果
k(近傍数)
クエリ点の予測クラス
クエリから k 近傍までの平均距離
LOO 交差検証精度
学習データと決定境界

赤=クラス 0/青=クラス 1/緑=クラス 2/黒×=クエリ点/破線円=k 番目最近傍までの距離

理論・主要公式

k 近傍法は、学習データを記憶しておき、クエリ点 $\mathbf{x}$ から距離が近い k 個の学習点を選び、その多数決でクラスを予測する遅延学習アルゴリズムです。

2 次元ユークリッド距離。学習点 $\mathbf{x}_i = (x_{i1}, x_{i2})$ とクエリ $\mathbf{x} = (x_1, x_2)$:

$$d(\mathbf{x},\mathbf{x}_i) = \sqrt{(x_1 - x_{i1})^2 + (x_2 - x_{i2})^2}$$

予測クラス。$\mathcal{N}_k(\mathbf{x})$ はクエリの k 近傍集合、$y_i$ は学習点 $\mathbf{x}_i$ のクラス:

$$\hat{y}(\mathbf{x}) = \arg\max_{c}\;\sum_{\mathbf{x}_i \in \mathcal{N}_k(\mathbf{x})}\mathbb{1}[y_i = c]$$

LOO 交差検証精度(一個抜き)。$\hat{y}^{(-i)}$ は $\mathbf{x}_i$ を除いて学習した分類器の予測:

$$\text{Acc}_\text{LOO} = \frac{1}{N}\sum_{i=1}^{N}\mathbb{1}[\hat{y}^{(-i)}(\mathbf{x}_i) = y_i]$$

多数決がタイの場合は、各候補クラスについて k 近傍までの平均距離を比較し、より小さい方を予測クラスとします。

k 近傍法(k-NN)2D 分類シミュレーターとは

🙋
機械学習を勉強し始めたんですけど、k 近傍法って一番シンプルなのに、ちゃんと使えるって聞きました。本当ですか?
🎓
本当だよ。ざっくり言うと、k-NN は「モデルを学習しない」アルゴリズムなんだ。学習データをそのまま記憶しておいて、新しい点が来たら「一番近い k 個」を探して、その多数決でクラスを決める。それだけ。上のシミュレーターで赤・青・緑の点が見えるだろう?黒い × がクエリ点で、k=5 だと一番近い 5 点を見て多数決を取っている。
🙋
k のスライダーを動かしてみると、背景の色の塗り方がガラッと変わりますね。これは何ですか?
🎓
それが「決定境界」だよ。平面の各点について「もしここがクエリだったら何クラスと予測するか」を計算して、結果のクラスの色で薄く塗っている。k=1 だとガタガタの境界になるはずだ。1 つの外れ値に引っ張られるからね。k を 11 や 21 まで上げると、境界が滑らかになるけど、今度は細かい構造を見落とすようになる。
🙋
じゃあ k は大きい方がいいんですか?小さい方がいいんですか?
🎓
どちらでもなく、「データに合わせて選ぶ」が正解。LOO 交差検証精度のカードを見てごらん。学習データの 1 点を抜いて残りで予測する、を全点繰り返したときの正解率だ。シード 42 のデータだと k=5 で 90% 前後になる。実務では k を 1, 3, 5, ... と動かして精度が最大の k を選ぶ。多数決で同票にならないように、奇数を選ぶのが定石だよ。
🙋
「学習データの分散 σ」を 3.0 まで上げたら、クラスタが混ざりあって精度がガクッと落ちました。
🎓
そう、これが k-NN の弱点でもあり強みでもあるところだ。データがきれいに分かれていれば高精度が出るけど、クラスタが重なりだすと、どんな k を選んでも限界がある。実務では「特徴量を工夫してクラスを分離させる」のが先で、分類器を凝るのは後。シンプルな k-NN がベースラインとして強いのは、特徴量設計の良し悪しを素直に映し出してくれるからなんだ。

よくある質問

いいえ、用途に応じて選びます。本シミュレーターは 2 次元で直感的に分かりやすいユークリッド距離(L2 ノルム)を使っていますが、実務ではマンハッタン距離(L1)、コサイン類似度、マハラノビス距離などもよく使われます。特に文書分類のような高次元疎ベクトルではコサイン類似度、特徴量のスケールが大きく異なる場合はマハラノビス距離が定番です。
予測時の計算コストの大きさです。新しい点を分類するたびに全学習点との距離を計算するため、N 点のデータに対し O(N) かかります。データ量が大きいと予測が遅くなり、リアルタイム用途では使いにくくなります。実務では kd-tree や ball-tree などの空間データ構造、あるいは近似最近傍探索(FAISS、Annoy 等)で高速化します。
必須です。k-NN は距離に基づくため、スケールの大きい特徴量(例:年収)がスケールの小さい特徴量(例:年齢)を圧倒してしまいます。標準化(平均 0、分散 1)か Min-Max 正規化を必ず実施してください。本シミュレーターはどの特徴量も同じスケールの 2D データなので、スケーリング不要で動作します。
k が学習データ数に近づくと、どんなクエリも「全データの多数決」つまり最頻クラスを返すようになります。決定境界はほぼ消え、少数派クラスは決して予測されません。一方で k=1 は学習データに対する完全フィットになるため過学習しがちです。LOO 精度のカードを見ながら適切な k を選ぶのが現実的な解です。

実世界での応用

レコメンドシステム:映画や商品のレコメンドで、ユーザーや商品を多次元ベクトルとして表現し、「似ているユーザー」「似ている商品」を k-NN で探索します。Amazon の「この商品を買った人はこんな商品も…」や、Netflix の協調フィルタリングの基本にはこの考え方があります。本格的なシステムでは数億ベクトルから k 近傍を瞬時に取り出すため、近似最近傍探索ライブラリが裏で動いています。

異常検知(Anomaly Detection):製造ラインのセンサーデータやネットワークトラフィックで、「k 近傍までの平均距離」を異常スコアとして使う手法があります。正常データが密に分布する空間で、k 近傍がどれも遠ければ「孤立した点 = 異常」と判定できます。シミュレーターの「クエリから k 近傍までの平均距離」のカードがまさにこの指標です。

画像分類・OCR の基礎:手書き数字認識(MNIST)のような古典的ベンチマークでは、k-NN がディープラーニング以前の強いベースラインでした。生のピクセル値を 784 次元ベクトルとして扱い、k-NN で分類するだけで誤分類率 3% 前後を達成します。現在もモデルの妥当性確認のための「最低ライン」として使われ続けています。

地理情報・空間検索:地図アプリで「現在地から最も近い 5 つのカフェ」を返すような処理は、本質的に k 近傍探索です。緯度経度を 2 次元座標、距離を球面距離として、k-NN を空間インデックス(R-tree 等)で高速化したものが多くのジオサービスの根幹を支えています。

よくある誤解と注意点

最も多い誤解は、「k-NN は学習が不要だから簡単」と考えてしまうことです。確かに学習フェーズは「データを保存するだけ」ですが、その代わり予測フェーズが重く、特徴量設計の良し悪しがすべてです。シミュレーターで「学習データの分散 σ」を 3.0 まで上げてみてください。クラスタが重なって、どんな k を選んでも LOO 精度が大幅に落ちます。これは「特徴量空間でクラスが分離されていない」ことを示しており、k-NN だけでは解決できません。学習が不要に見えても、特徴量を作る段階で人間が頭を使う必要があるわけです。

次に多いのが、「k は大きいほど精度が上がる」と思い込むことです。k=1 は確かに過学習しやすいですが、k を上げ続けると今度は「少数派クラスが多数派に飲まれる」逆の問題が起きます。本シミュレーターで k を 1 から 25 まで動かしながら LOO 精度を見てください。最適 k は中間にあり、データの分布によって変わります。k は「データに合わせて選ぶ」ハイパーパラメータであり、交差検証で系統的に決めるべきです。「とりあえず大きく」も「とりあえず 1」も間違いです。

最後に、「LOO 精度が高ければ実運用でも同じ精度が出る」と過信するのは危険です。LOO 交差検証は、学習データの分布が運用時のデータ分布と一致していることを暗黙に仮定しています。実際にはデータの収集時期やセンサーの違いで分布が変わる「ドメインシフト」が起こり、LOO で 90% だったのに本番で 70% に落ちる、ということが普通にあります。シミュレーターの LOO 精度は理想的な条件下の値であり、運用時はホールドアウト検証や時系列クロスバリデーションで追加検証することを忘れないでください。