代码急转弯——高维线性可分
二维线性不可分,但三维线性可分。
1、线性可分
在二维的情况下,线性可分是指用一条直线将两类点分开,如下图所示。
2、高维线性可分
也许可用一条曲线将两类点分开,这时,线性模型就不好用了。
如果能找到一个映射,把平面点升维到三维空间的点,平面曲线也升维到三维空间的平面,于是这两类点就重归线性可分,这就是高维线性可分,见篇首图。
3、DIY (Do It Yourself)
如何实现上面的立体图?
先设置绘图方式,以便观察3D效果。在Spyder中选【tools】、【preferences】、【IPython console】、【Graphics】、【Graphics backend】、Qt5,重新启动命令窗口(Restart Kernel),或者重启spyder。
执行下列操作:
1)数据点,生成二维的均匀分布的随机点
2)分类,以
y
=
x
2
y=x^2
y=x2为边界。边界之上的点为第1类,之下的为第0类
3)建模,用LinearSVC进行分类,准确率=0.88
4)3d绘图
设想这些点位于一张纸面上,弯曲纸面(左右翘起),
从侧面观察弯曲纸面上的曲线,可以是一条直线
5)升维,将二维点升为3维点,
6)再次建模,还是用LinearSVC进行分类,准确率=0.99
下列代码中,每一步操作在一个单元中,In[1]~In[6]。
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
# In[1]
np.random.seed(123)
n = 500
x = np.random.rand(n, 2)*2 - 1
# In[2]
def f(x):
return x[0]**2 <= x[1]
y = np.array([1 if f(x[k]) else 0 for k in range(n)])
plt.plot(x[y==1, 0],x[y==1, 1],'om')
plt.plot(x[y==0, 0],x[y==0, 1],'og')
x0 = np.linspace(-1,1,20)
plt.plot(x0, x0**2, 'r')
plt.show()
# In[3]
from sklearn.svm import LinearSVC
mm = LinearSVC()
mm.fit(x, y)
ss = mm.score(x, y)
print(ss)
'''
0.886
'''
# In[4]
ax = plt.gca(projection='3d')
ax.clear()
ax.scatter(x[y==1,0], x[y==1,1], x[y==1,0]**2,'.m')
ax.scatter(x[y==0,0], x[y==0,1], x[y==0,0]**2,'.g')
x_s = np.linspace(-1, 1, 2)
y_s = np.linspace(-1, 1, 2)
X, Y = np.meshgrid(x_s, y_s)
ax.plot_surface(X=X, Y=Y, Z=Y,
color='g', alpha=0.3)
x0 = np.linspace(-1,1,50)
x1 = x0**2
x2 = x0**2
ax.plot(x0,x1,x2,'-r')
# In[5]
x = np.hstack([x, x[:,[0]]**2])
y = np.array([1 if f(x[k]) else 0
for k in range(n)])
# In[6]
mm = LinearSVC()
mm.fit(x, y)
ss = mm.score(x, y)
print(ss)
'''
0.994
'''