Как добавить границу к фигуре (набору данных) с помощью matplotlib и алгоритма SVM?

Мой код:

import matplotlib.pyplot as plt
import pandas as pd

data = pd.read_csv('data/data.csv')
X = data[['x1','x2']]
y = data['y']

from sklearn.svm import SVC
classifier = SVC()
classifier.fit(X,y)

plt.scatter(data['x1'], data['x2'], c=y, s=50)
plt.show()

Мои данные:

x1,x2,y
0.336493583877,-0.985950993354,0.0
-0.0110425297266,-0.10552856162,1.0
0.238159509297,-0.61741666482,1.0
-0.366782883496,-0.713818716912,1.0
1.22192307438,-1.03939898614,0.0

Мой текущий результат:  введите описание изображения здесь

Вероятно, Support Vector Machine - не лучший алгоритм для использования там, но я хотел бы увидеть границы, сгенерированные для этого. Как это сделать?


И применив идеальный ответ Пола, вот результат:  введите описание изображения здесь


person Marcel    schedule 29.08.2017    source источник
comment
Посмотрите на примеры здесь, чтобы узнать, подходит ли что-нибудь для вас. Но, как сказал @Sun Yi в своем ответе, это, вероятно, не будет очень полезно для нелинейных данных.   -  person Vivek Kumar    schedule 29.08.2017
comment
Я не уверен, правильно ли я понимаю ваш вопрос, но если вам нужна граница вокруг всех желтых точек (y-значение 1, я полагаю), почему бы просто не отфильтровать данные по y-значению и вычислить выпуклая оболочка вокруг них?   -  person Thomas Kühn    schedule 29.08.2017
comment
Потому что я учусь, Томас. Тогда я хотел бы увидеть, как matplotlib работает с этим.   -  person Marcel    schedule 29.08.2017


Ответы (2)


Основываясь на ответе Sun Yi, вы можете использовать пример кода из здесь. Например, у вас нет всех точек в вашем data.csv в вашем вопросе, но мы можем построить график с границей принятия решения следующим образом:

import pandas as pd
import numpy as np
from matplotlib.colors import ListedColormap
from sklearn.svm import SVC
import matplotlib.pyplot as plt

# load the data
data = pd.read_csv('data/data.csv')
X = data[['x1','x2']]
y = data['y']

# fit the classifier
classifier = SVC(kernel='rbf')
classifier.fit(X,y)

# first we determine the grid of points -- i.e. the min and max  for each of 
# the axises and then build a grid
resolution=0.02
x1_min, x1_max = X["x1"].min() - 1, X["x1"].max() + 1
x2_min, x2_max = X["x2"].min() - 1, X["x2"].max() + 1
xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, resolution),
   np.arange(x2_min, x2_max, resolution))

# setup marker generator and color map
markers = ('s', 'x', 'o', '^', 'v')
colors = ('red', 'blue', 'lightgreen', 'gray', 'cyan')
cmap = ListedColormap(colors[:len(np.unique(y))])

# plot the classifier decision boundaries
Z = classifier.predict(np.array([xx1.ravel(), xx2.ravel()]).T)
Z = Z.reshape(xx1.shape)
plt.contourf(xx1, xx2, Z, alpha=0.4, cmap=cmap)
plt.xlim(xx1.min(), xx1.max())
plt.ylim(xx2.min(), xx2.max())

# plot the data points
for idx, cl in enumerate(np.unique(y)):
    plt.scatter(x=X["x1"][y == cl].values, 
                y=X["x2"][y == cl].values,
                alpha=0.6, 
                c=cmap(idx),
                edgecolor='black',
                marker=markers[idx], 
                label=cl)    
plt.show()

Это в значительной степени взято из примера кода в приведенной выше ссылке. Я попытался включить только то, что было необходимо, чтобы было проще. Вот изображение на выходе:  введите описание изображения здесь

Вы заметите, что я явно использовал ядро ​​rbf, поскольку полные данные в вашем примере нельзя разделить линейно. Этот ответ хорош для хорошего, более общего, чем у меня, ответа на эти контуры.

person Paul    schedule 29.08.2017

ваши данные не являются линейно разделяемыми, вы можете использовать алгоритм svm, ваши данные - 2d, и этот алгоритм может передавать ваши данные в 3d с помощью функции ядра
вы можете найти этот алгоритм в sklearn

person Sun Yi    schedule 29.08.2017
comment
вы можете изменить свой код classifier = SVC (kernel = 'rbf'), вы можете использовать справку (SVC), чтобы показать другие аргументы для этого алгоритма. - person Sun Yi; 29.08.2017