Vamos a trabajar con el dataset Iris:
import pandas as pd
iris=pd.read_csv('Iris.csv')
iris
import seaborn as sns
sns.scatterplot('PetalLengthCm', 'PetalWidthCm', hue='Species', data=iris)
Usaremos una SVM para separar setosa de versicolor
setosa_versicolor=iris[(iris.Species=='Iris-setosa')|(iris.Species=='Iris-versicolor')]
setosa_versicolor
sns.scatterplot('PetalLengthCm', 'PetalWidthCm', hue='Species', data=setosa_versicolor)
X=setosa_versicolor[['PetalLengthCm', 'PetalWidthCm']]
y=setosa_versicolor['Species']
from sklearn.svm import SVC
svm_clf = SVC(kernel='linear', C=float('inf')) # Definir
svm_clf.fit(X,y) # Ajustar
Los $w_1$ y $w_2$:
svm_clf.coef_
El $b$:
svm_clf.intercept_
Los vectores soporte:
svm_clf.support_vectors_
Para pintarnos el hiperplano separador:
import matplotlib.pyplot as plt
import numpy as np
def plot_svc_decision_boundary(svm_clf, xmin, xmax):
w = svm_clf.coef_[0]
b = svm_clf.intercept_[0]
# At the decision boundary, w0*x0 + w1*x1 + b = 0
# => x1 = -w0/w1 * x0 - b/w1
x0 = np.linspace(xmin, xmax, 200)
decision_boundary = -w[0]/w[1] * x0 - b/w[1]
margin = 1/w[1]
gutter_up = decision_boundary + margin
gutter_down = decision_boundary - margin
svs = svm_clf.support_vectors_
plt.scatter(svs[:, 0], svs[:, 1], s=180, facecolors='#FFAAAA')
plt.plot(x0, decision_boundary, "r-", linewidth=2)
plt.plot(x0, gutter_up, "k--", linewidth=2)
plt.plot(x0, gutter_down, "k--", linewidth=2)
plot_svc_decision_boundary(svm_clf,0, 5.5)
sns.scatterplot('PetalLengthCm', 'PetalWidthCm', hue='Species', data=setosa_versicolor)
plt.axis([0,5.5,0,2])
Xs=np.array([[1,50],[5,20],[3,80],[5,60]]).astype(np.float64)
ys=np.array([0,0, 1,1])
svm_clf = SVC(kernel='linear',C=100)
svm_clf.fit(Xs,ys)
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_scaled=scaler.fit_transform(Xs)
svm_clf_scaled = SVC(kernel='linear',C=100)
svm_clf_scaled.fit(X_scaled,ys)
plt.figure(figsize=(12,3.2))
plt.subplot(121)
plot_svc_decision_boundary(svm_clf, 0, 6)
sns.scatterplot(Xs[:,0],Xs[:,1], hue=ys)
plt.title("Unscaled", fontsize=16)
plt.axis([0, 6, 0, 90])
plt.subplot(122)
plot_svc_decision_boundary(svm_clf_scaled, -2, 2)
sns.scatterplot(X_scaled[:,0],X_scaled[:,1], hue=ys)
plt.title("Scaled", fontsize=16)
plt.axis([-2, 2, -2, 2])
Vamos a separar ahora virginica y versicolor
virginica_versicolor = iris[(iris.Species=='Iris-virginica')|(iris.Species=='Iris-versicolor')]
virginica_versicolor
sns.scatterplot('PetalLengthCm','PetalWidthCm',hue='Species',data=virginica_versicolor)
No son linealmente separables.
X=virginica_versicolor[['PetalLengthCm','PetalWidthCm']]
y=virginica_versicolor['Species']
# Escalamos X
X=scaler.fit_transform(X)
Modelos con distintos valores de C
svm_C_grande = SVC(kernel='linear', C=100)
svm_C_pequeño = SVC(kernel='linear', C=1)
svm_C_grande.fit(X,y)
svm_C_pequeño.fit(X,y)
plt.figure(figsize=(12,3.2))
plt.subplot(121)
plot_svc_decision_boundary(svm_C_grande, -3,3)
sns.scatterplot(X[:,0],X[:,1], hue=y)
plt.title('C=100')
plt.subplot(122)
plot_svc_decision_boundary(svm_C_pequeño, -3,3)
sns.scatterplot(X[:,0],X[:,1], hue=y)
plt.title('C=1')
Vamos a usar make_moons
, que es un paquete dentro de Scikit-learn que nos genera grupos de puntos del plano aleatoriamente.
from sklearn.datasets import make_moons
help(make_moons)
X, y = make_moons(n_samples=100, noise=0.15, random_state=42)
sns.scatterplot(X[:,0],X[:,1], hue=y)
Vamos a escalar los datos:
X = scaler.fit_transform(X)
sns.scatterplot(X[:,0],X[:,1], hue=y)
Vamos a usar un script para pintarnos las fronteras de clasificacion:
def plot_predictions(clf, axes):
x0s = np.linspace(axes[0], axes[1], 100)
x1s = np.linspace(axes[2], axes[3], 100)
x0, x1 = np.meshgrid(x0s, x1s)
X = np.c_[x0.ravel(), x1.ravel()]
y_pred = clf.predict(X).reshape(x0.shape)
y_decision = clf.decision_function(X).reshape(x0.shape)
plt.contourf(x0, x1, y_pred, cmap=plt.cm.brg, alpha=0.2)
plt.contourf(x0, x1, y_decision, cmap=plt.cm.brg, alpha=0.1)
$K(\mathbf{a},\mathbf{b})=(\mathbf{a}\cdot \mathbf{b} + r)^d$
degree
coef0
poly_kernel_svm=SVC(kernel='poly', degree=3, coef0=1, C=5)
poly_kernel_svm.fit(X,y)
plot_predictions(poly_kernel_svm, [-2.5,2.5,-2.5,2.5])
sns.scatterplot(X[:,0],X[:,1], hue=y)
plt.title('$d=3, r=1, C=5$')
# Con otros d y r
poly_kernel_svm=SVC(kernel='poly', degree=10, coef0=100, C=5)
poly_kernel_svm.fit(X,y)
plot_predictions(poly_kernel_svm, [-2.5,2.5,-2.5,2.5])
sns.scatterplot(X[:,0],X[:,1], hue=y)
plt.title('$d=10, r=100, C=5$')
$K(\mathbf{a},\mathbf{b})=\exp(-\gamma ||\mathbf{a}-\mathbf{b}||^2)$
gammas = [0.1, 5]
Cs = [0.001, 1000]
for gamma in gammas:
for C in Cs:
rbf_kernel_svm_clf = SVC(kernel='rbf', gamma=gamma, C=C) # Definir
rbf_kernel_svm_clf.fit(X,y) # Ajustar
plot_predictions(rbf_kernel_svm_clf, [-2.5,2.5,-2.5,2.5])
sns.scatterplot(X[:,0],X[:,1], hue=y)
plt.title(r"$\gamma = {}, C={}$".format(gamma,C))
plt.show()