web-dev-qa-db-fra.com

traçage de la limite de décision de la régression logistique

J'implémente une régression logistique. J'ai réussi à en extraire des probabilités et je peux prédire une tâche de classification en 2 classes.

Ma question est:

Pour mon modèle final, j'ai des poids et les données d'entraînement. Il y a 2 fonctionnalités, donc mon poids est un vecteur à 2 rangées.

Comment puis-je tracer cela? J'ai vu ce post , mais je ne comprends pas très bien la réponse. Ai-je besoin d'un tracé de contour?

15
user2773013

Un avantage du classificateur de régression logistique est qu'une fois que vous l'ajustez, vous pouvez obtenir des probabilités pour n'importe quel vecteur échantillon. Cela peut être plus intéressant à tracer. Voici un exemple d'utilisation de 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")

Tout d'abord, générez les données et adaptez le classificateur à l'ensemble d'apprentissage:

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

Ensuite, faites une grille continue de valeurs et évaluez la probabilité de chaque point (x, y) dans la grille:

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)

Maintenant, tracez la grille de probabilité sous forme de carte de contour et affichez en plus les échantillons de l'ensemble de test par-dessus:

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

La régression logistique vous permet de classer de nouveaux échantillons en fonction du seuil que vous souhaitez, de sorte qu'il n'a pas intrinsèquement une "limite de décision". Mais, bien sûr, une règle de décision commune à utiliser est p = 0,5. Nous pouvons également simplement dessiner ce niveau de contour en utilisant le code ci-dessus:

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

La réponse acceptée est Nice pour cela, mais elle peut également être utile en particulier lorsque vous essayez de comprendre ce que les poids signifient, de convertir les poids en forme de pente/d'interception et de simplement dessiner la frontière de décision.

Les logits sont au format wx + b mais dans le cas d'une classification binaire x et w sont bidimensionnels. Et l'une de ces valeurs x représente en fait y sur le graphique. Cela signifie que l'équation de la ligne ressemblera à:

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

Tracer cela où x_np est vos données et w + b sont vos paramètres appris, ce sera quelque chose d'aussi simple que:

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