web-dev-qa-db-ja.com

ロジスティック回帰の決定境界のプロット

ロジスティック回帰を実装しています。私はなんとかそれから確率を得ることができ、2クラスの分類タスクを予測することができました。

私の質問は:

最終モデルには、重みとトレーニングデータがあります。 2つの機能があるため、私の重みは2行のベクトルです。

これをどのようにプロットしますか? この投稿 を見ましたが、答えはよくわかりません。等高線図が必要ですか?

15
user2773013

ロジスティック回帰分類器の利点は、適合すると、任意のサンプルベクトルの確率を取得できることです。プロットする方が面白いかもしれません。 scikit-learnを使用した例を次に示します。

import numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import make_classification
import matplotlib.pyplot as plt
import seaborn as sns
sns.set(style="white")

最初に、データを生成し、分類器をトレーニングセットに適合させます。

X, y = make_classification(200, 2, 2, 0, weights=[.5, .5], random_state=15)
clf = LogisticRegression().fit(X[:100], y[:100])

次に、値の連続グリッドを作成し、グリッド内の各(x、y)ポイントの確率を評価します。

xx, yy = np.mgrid[-5:5:.01, -5:5:.01]
grid = np.c_[xx.ravel(), yy.ravel()]
probs = clf.predict_proba(grid)[:, 1].reshape(xx.shape)

次に、確率グリッドを等高線図としてプロットし、さらにその上にテストセットのサンプルを表示します。

f, ax = plt.subplots(figsize=(8, 6))
contour = ax.contourf(xx, yy, probs, 25, cmap="RdBu",
                      vmin=0, vmax=1)
ax_c = f.colorbar(contour)
ax_c.set_label("$P(y = 1)$")
ax_c.set_ticks([0, .25, .5, .75, 1])

ax.scatter(X[100:,0], X[100:, 1], c=y[100:], s=50,
           cmap="RdBu", vmin=-.2, vmax=1.2,
           edgecolor="white", linewidth=1)

ax.set(aspect="equal",
       xlim=(-5, 5), ylim=(-5, 5),
       xlabel="$X_1$", ylabel="$X_2$")

enter image description here

ロジスティック回帰では、必要なしきい値に基づいて新しいサンプルを分類できるため、本質的に「決定境界」は1つありません。しかし、もちろん、使用する一般的な決定ルールはp = .5です。上記のコードを使用して、その輪郭レベルを描画することもできます。

f, ax = plt.subplots(figsize=(8, 6))
ax.contour(xx, yy, probs, levels=[.5], cmap="Greys", vmin=0, vmax=.6)

ax.scatter(X[100:,0], X[100:, 1], c=y[100:], s=50,
           cmap="RdBu", vmin=-.2, vmax=1.2,
           edgecolor="white", linewidth=1)

ax.set(aspect="equal",
       xlim=(-5, 5), ylim=(-5, 5),
       xlabel="$X_1$", ylabel="$X_2$")

enter image description here

37
mwaskom

受け入れられた答えはこれにはいいですが、特に重みの意味を理解しようとするとき、重みを勾配/インターセプト形式に変換して決定境界を描くだけでも役立ちます。

ロジットの形式はwx + bただし、バイナリ分類の場合、xwは2次元です。そして、それらのx値の1つは、実際にプロット上のyを表します。つまり、線の方程式は次のようになります。

w[1] * y = w[0] * x + b 
# to solve for y
y = (w[0] * x)/w[1] + b / w[1]

プロットx_npはデータであり、w + bは学習したパラメーターであり、次のような単純なものになります。

plt.scatter(x_np[:,0], x_np[:,1], c=y_np.reshape(-1),cmap=mpl.colors.ListedColormap(colors))
ax = plt.gca()
ax.autoscale(False)
x_vals = np.array(ax.get_xlim())
y_vals = -(x_vals * w_guess[0] + b_guess[0])/w_guess[1]
plt.plot(x_vals, y_vals, '--', c="red")

enter image description here

7
Mark Meyer