我真的可以使用提示来帮助我绘制决策边界以分离数据类.我通过Python NumPy创建了一些样本数据(来自高斯分布).在这种情况下,每个数据点是2D坐标,即由2行组成的1列向量.例如,
[ 1
2 ]
Run Code Online (Sandbox Code Playgroud)
假设我有2个类,class1和class2,我通过下面的代码为class1创建了100个数据点,为class2创建了100个数据点(分配给变量x1_samples和x2_samples).
mu_vec1 = np.array([0,0])
cov_mat1 = np.array([[2,0],[0,2]])
x1_samples = np.random.multivariate_normal(mu_vec1, cov_mat1, 100)
mu_vec1 = mu_vec1.reshape(1,2).T # to 1-col vector
mu_vec2 = np.array([1,2])
cov_mat2 = np.array([[1,0],[0,1]])
x2_samples = np.random.multivariate_normal(mu_vec2, cov_mat2, 100)
mu_vec2 = mu_vec2.reshape(1,2).T
Run Code Online (Sandbox Code Playgroud)
当我绘制每个类的数据点时,它看起来像这样:

现在,我想出了一个决策边界的等式来分离两个类,并希望将它添加到图中.但是,我不确定如何绘制此函数:
def decision_boundary(x_vec, mu_vec1, mu_vec2):
g1 = (x_vec-mu_vec1).T.dot((x_vec-mu_vec1))
g2 = 2*( (x_vec-mu_vec2).T.dot((x_vec-mu_vec2)) )
return g1 - g2
Run Code Online (Sandbox Code Playgroud)
我真的很感激任何帮助!
编辑:直觉(如果我的数学正确)我会期望决定边界在我绘制函数时看起来有点像这条红线...

luc*_*asg 36
你的问题比简单的情节更复杂:你需要画出最大化班级间距离的轮廓.幸运的是,这是一个经过充分研究的领域,特别是对于SVM机器学习.
最简单的方法是下载scikit-learn模块,它提供了很多很酷的方法来绘制边界:http://scikit-learn.org/stable/modules/svm.html
代码:
# -*- coding: utf-8 -*-
import numpy as np
import matplotlib
from matplotlib import pyplot as plt
import scipy
from sklearn import svm
mu_vec1 = np.array([0,0])
cov_mat1 = np.array([[2,0],[0,2]])
x1_samples = np.random.multivariate_normal(mu_vec1, cov_mat1, 100)
mu_vec1 = mu_vec1.reshape(1,2).T # to 1-col vector
mu_vec2 = np.array([1,2])
cov_mat2 = np.array([[1,0],[0,1]])
x2_samples = np.random.multivariate_normal(mu_vec2, cov_mat2, 100)
mu_vec2 = mu_vec2.reshape(1,2).T
fig = plt.figure()
plt.scatter(x1_samples[:,0],x1_samples[:,1], marker='+')
plt.scatter(x2_samples[:,0],x2_samples[:,1], c= 'green', marker='o')
X = np.concatenate((x1_samples,x2_samples), axis = 0)
Y = np.array([0]*100 + [1]*100)
C = 1.0 # SVM regularization parameter
clf = svm.SVC(kernel = 'linear', gamma=0.7, C=C )
clf.fit(X, Y)
Run Code Online (Sandbox Code Playgroud)
w = clf.coef_[0]
a = -w[0] / w[1]
xx = np.linspace(-5, 5)
yy = a * xx - (clf.intercept_[0]) / w[1]
plt.plot(xx, yy, 'k-')
Run Code Online (Sandbox Code Playgroud)

C = 1.0 # SVM regularization parameter
clf = svm.SVC(kernel = 'rbf', gamma=0.7, C=C )
clf.fit(X, Y)
h = .02 # step size in the mesh
# create a mesh to plot in
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))
# Plot the decision boundary. For that, we will assign a color to each
# point in the mesh [x_min, m_max]x[y_min, y_max].
Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
# Put the result into a color plot
Z = Z.reshape(xx.shape)
plt.contour(xx, yy, Z, cmap=plt.cm.Paired)
Run Code Online (Sandbox Code Playgroud)

如果您想自己实现它,您需要解决以下二次方程:

维基百科文章
不幸的是,对于像你绘制的那样的非线性边界,这是一个依赖于核心技巧的难题,但是没有一个明确的解决方案.
mwa*_*kom 19
根据您编写的方式,decision_boundary您将要使用该contour功能,如上所述Joe.如果您只想要边界线,则可以在0级绘制单个轮廓:
f, ax = plt.subplots(figsize=(7, 7))
c1, c2 = "#3366AA", "#AA3333"
ax.scatter(*x1_samples.T, c=c1, s=40)
ax.scatter(*x2_samples.T, c=c2, marker="D", s=40)
x_vec = np.linspace(*ax.get_xlim())
ax.contour(x_vec, x_vec,
decision_boundary(x_vec, mu_vec1, mu_vec2),
levels=[0], cmap="Greys_r")
Run Code Online (Sandbox Code Playgroud)
这使得:

您可以为边界创建自己的等式:

在那里你必须找到位置x0和y0,以及常量ai和bi为半径公式.所以,你有2*(n+1)+2变量.使用scipy.optimize.leastsq对于此类问题很简单.
下面附带的代码构建了用于leastsq惩罚超出边界的点的残差.您的问题的结果,获得:
x, y = find_boundary(x2_samples[:,0], x2_samples[:,1], n)
ax.plot(x, y, '-k', lw=2.)
x, y = find_boundary(x1_samples[:,0], x1_samples[:,1], n)
ax.plot(x, y, '--k', lw=2.)
Run Code Online (Sandbox Code Playgroud)
使用n=1:

使用n=2:

使用n=5:

使用n=7:

import numpy as np
from numpy import sin, cos, pi
from scipy.optimize import leastsq
def find_boundary(x, y, n, plot_pts=1000):
def sines(theta):
ans = np.array([sin(i*theta) for i in range(n+1)])
return ans
def cosines(theta):
ans = np.array([cos(i*theta) for i in range(n+1)])
return ans
def residual(params, x, y):
x0 = params[0]
y0 = params[1]
c = params[2:]
r_pts = ((x-x0)**2 + (y-y0)**2)**0.5
thetas = np.arctan2((y-y0), (x-x0))
m = np.vstack((sines(thetas), cosines(thetas))).T
r_bound = m.dot(c)
delta = r_pts - r_bound
delta[delta>0] *= 10
return delta
# initial guess for x0 and y0
x0 = x.mean()
y0 = y.mean()
params = np.zeros(2 + 2*(n+1))
params[0] = x0
params[1] = y0
params[2:] += 1000
popt, pcov = leastsq(residual, x0=params, args=(x, y),
ftol=1.e-12, xtol=1.e-12)
thetas = np.linspace(0, 2*pi, plot_pts)
m = np.vstack((sines(thetas), cosines(thetas))).T
c = np.array(popt[2:])
r_bound = m.dot(c)
x_bound = popt[0] + r_bound*cos(thetas)
y_bound = popt[1] + r_bound*sin(thetas)
return x_bound, y_bound
Run Code Online (Sandbox Code Playgroud)
小智 6
我喜欢 mglearn 库来划定决策边界。以下是 A. Mueller 所著的《Python 机器学习简介》一书中的一个示例:
fig, axes = plt.subplots(1, 3, figsize=(10, 3))
for n_neighbors, ax in zip([1, 3, 9], axes):
clf = KNeighborsClassifier(n_neighbors=n_neighbors).fit(X, y)
mglearn.plots.plot_2d_separator(clf, X, fill=True, eps=0.5, ax=ax, alpha=.4)
mglearn.discrete_scatter(X[:, 0], X[:, 1], y, ax=ax)
ax.set_title("{} neighbor(s)".format(n_neighbors))
ax.set_xlabel("feature 0")
ax.set_ylabel("feature 1")
axes[0].legend(loc=3)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
70574 次 |
| 最近记录: |