Matplotlibでk-NN決定境界を可視化する方法
本記事では、PythonのMatplotlibとscikit-learnを使って、k-NN(k近傍法)の決定境界をグラフ化する方法を解説します。定番のアイリス(iris)データセットを例に、3クラス分類の判断領域を視覚的に表現する手順を、サンプルコード付きでわかりやすく紹介します。
実装の手順
k-NNの決定境界を描くには、以下のステップに沿ってコードを組み立てます。
- 図のサイズを設定し、サブプロット間および周囲の余白(パディング)を調整します。
- 近傍数を表す変数 n_neighbors を初期化します。
- アイリス(iris)データセット(分類用)を読み込みます。
- x と y のデータポイントを作成します。
- 背景用の淡色カラーマップと、散布図用の濃色カラーリストをそれぞれ定義します。
- k近傍投票を実装した分類器(KNeighborsClassifier)を作成します。
- x_min、x_max、y_min、y_max を算出し、予測用のメッシュグリッドを生成します。
- 新しい図を作成(または既存の図をアクティブ化)します。
- contourf プロットで決定境界となる領域を塗り分けます。
- X データセットの散布図を作成します。
- x 軸・y 軸のラベル、タイトル、軸の表示範囲を設定します。
- show() メソッドで図を表示します。
サンプルコード
以下が実際のPythonコードです。アイリスデータセットの最初の2つの特徴量(がく片の長さと幅)を使い、k=15の一様重み(uniform)で分類しています。
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from matplotlib.colors import ListedColormap
from sklearn import neighbors, datasets
plt.rcParams["figure.figsize"] = [7.00, 3.50]
plt.rcParams["figure.autolayout"] = True
# 近傍数の設定
n_neighbors = 15
# アイリスデータセットの読み込み
iris = datasets.load_iris()
X = iris.data[:, :2] # 最初の2つの特徴量を使用
y = iris.target
h = .02 # メッシュのステップサイズ
# 淡色(背景用)と濃色(点用)のカラーマップ
cmap_light = ListedColormap(['orange', 'cyan', 'cornflowerblue'])
cmap_bold = ['darkorange', 'c', 'darkblue']
# k-NN分類器の作成と学習
clf = neighbors.KNeighborsClassifier(n_neighbors, weights='uniform')
clf.fit(X, y)
# 表示範囲の設定とメッシュグリッドの生成
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
np.arange(y_min, y_max, h))
# 各メッシュ点に対するクラス予測
Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.figure()
# 決定境界の塗り分け(等高線プロット)
plt.contourf(xx, yy, Z, cmap=cmap_light)
# 学習データの散布図
sns.scatterplot(x=X[:, 0], y=X[:, 1], hue=iris.target_names[y],
palette=cmap_bold, alpha=1.0, edgecolor="black")
plt.xlim(xx.min(), xx.max())
plt.ylim(yy.min(), yy.max())
plt.title("3-Class classification (k = %i, weights = '%s')"
% (n_neighbors, 'uniform'))
plt.xlabel(iris.feature_names[0])
plt.ylabel(iris.feature_names[1])
plt.show()
コードのポイント
- np.meshgrid:表示範囲全体を細かい格子状に分割し、各格子点に対して分類器の予測を行うために使用します。ステップサイズ h を小さくすると境界線がより滑らかになります。
- plt.contourf:予測結果 Z を色分けして塗りつぶすことで、どの領域がどのクラスに分類されるかを直感的に把握できます。
- sns.scatterplot:seabornを使うことで、クラスごとに色分けされた見やすい散布図を簡単に描画できます。
- n_neighbors:kの値を変更すると決定境界の形状が変化します。値が小さいほど複雑な境界になり、大きいほど滑らかな境界になります。
出力結果
上記のコードを実行すると、以下のように3クラス分類の決定境界が色分けされたグラフが表示されます。オレンジ・シアン・ブルーの領域がそれぞれのクラスに割り当てられた領域を示し、黒枠の点が実際の学習データです。

このように決定境界を可視化することで、k-NNモデルがデータ空間をどのように分割しているかを一目で確認でき、パラメータ調整やモデルの理解に役立ちます。
-
【Python】Matplotlibで回転する3Dグラフをアニメーション化する方法
Matplotlibで回転する3Dグラフを作成するには、Animationクラスを使用して関数を繰り返し呼び出します。この記事では、3Dサーフェスプロットをアニメーション化し、時間の経過とともに形状が変化する様子を可視化する手順を解説します。 実装の手順 メッシュグリッドの分割数(N)、1秒あたりのフレームレート(fps)、総フレーム数(frn)などの変数を初期化します。 曲線を描くための x、y、z の配列を作成します。 lambda関数を使って z 配列を生成する関数を定義します。 Animationクラスに関数を渡すために、前のフレームのプロットを削除し、新しい x、y、z 配列からサ
-
Matplotlibでヒストグラムデータから折れ線グラフを描画する方法
Matplotlibでヒストグラムのデータをもとに折れ線グラフを描画するには、NumPyのhistogram()メソッドを使ってデータセットのヒストグラムを事前に計算しておくのが便利です。この記事では、同じデータをヒストグラムと折れ線グラフの両方で可視化する手順を解説します。実装の手順現在の図にサブプロットを追加します。nrows=2、ncols=1とし、index=1を指定します。NumPyのhistogram()メソッドを使用して、データセットのヒストグラム(度数とビンの境界値)を取得します。edgecolor=blackを指定してhist()メソッドでヒストグラムを描画します。インデック