文章目录
分析 SVM 使用不同 keenel 在不同分布数据上的分类表现
说明:
已经将笔记的内容删除了,现在存储在这里。
实验内容:
- 生成5类实验数据,分别是:
1.1. 生成两组线性均匀分布的数据(完全线性可分)
1.2. 生成两组线性均匀分布的数据(线性不可分)
1.3. 生成两组高斯分布的数据(完全线性可分)
1.4. 生成两组高斯分布的数据(线性不可分)
1.5 生成环状数据 - 使用不同的方法对数据进行分类:
2.1. 使用线性svm对 1.1 中生成的数据进行分类,并画出分类界面
2.2. 使用线性svm对 1.2 中生成的数据进行分类,并画出分类界面
2.3. 使用svm对 1.3 中生成的数据进行分类,并画出分类界面
2.4. 使用svm对 1.4 中生成的数据进行分类,并画出分类界面
2.5. 使用svm对 1.5 中生成的数据进行分类,并画出分类界面
实验步骤:
一. 生成数据
1.1. 生成两组线性均匀分布的数据(完全线性可分)
通过约束线性数据的最大值和最小值,来保证两组数据之间不会出现交叉,即数据完全线性可分。
1.2. 生成两组线性均匀分布的数据(线性不可分)
通过约束线性数据的最大值和最小值,来保证两组数据之间出现交叉,使得数据线性不可分。
1.3. 生成两组高斯分布的数据(完全线性可分)
通过设置两组高斯分布的中心之间的距离来保证两组数据完全线性可分,即将两个高斯的中心设置的距离较远。
1.4. 生成两组高斯分布的数据(线性不可分)
通过设置两组高斯分布的中心之间的距离来保证两组数据完全线性不可分,即将两个高斯的中心设置的距离较近。
1.5 生成环状数据
直接调用库实现,需要设置总生成点数和环的分布特性。
二. 数据分类
2.1. 使用线性svm对(一) 1中生成的数据进行分类,并画出分类界面。
红色实线是超分平面,两条虚线是根据支持向量和超分平面的斜率生成的分界面。
2.2. 使用线性svm对(一) 2中生成的数据进行分类,并画出分类界面。
红色实线是超分平面,两条虚线是根据支持向量和超分平面的斜率生成的分界面。
2.3. 使用svm对(一) 3中生成的数据进行分类,并画出分类界面。
2.3.1 使用线性 svm
红色实线是超分平面,两条虚线是根据支持向量和超分平面的斜率生成的分界面。
2.3.2 使用 rbf 核
能有效分类,分类结果见下图:
2.3.3 使用多项式核
degree=2
不能有效分类,分类结果见下图:
degree=3
能有效分类,分类结果见下图:
2.4. 使用svm对(一) 4中生成的数据进行分类,并画出分类界面。
2.4.1 使用线性 svm
能有效分类,分类结果见下图:
2.4.2 使用 rbf 核
能有效分类,分类结果见下图:
2.4.3 使用多项式核
2.4.3.1. degree=2
不能有效分类,分类结果见下图:
2.4.3.2. degree=3
能有效分类,分类结果见下图:
2.5. 使用svm对(一) 5中生成的数据进行分类,并画出分类界面。
2.5.1. rbf
能有效分类,分类结果见下图:
2.5.2. 多项式 degree=2
能有效分类,分类结果见下图:
2.5.3. 多项式 degree=3
不能有效分类,分类结果见下图:
所有代码如下:
# -*-conding=utf-*-
import numpy as np
from sklearn.datasets import make_circles # 用于生成数据
from sklearn import svm
# 绘图库
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
def RBFKernelSVC(gamma): # 用于绘图 kernel="rbf"
return Pipeline([
("stand_c", StandardScaler()),
("svcc", svm.SVC(kernel="rbf", gamma=gamma))
])
def PolyKernelSVC(degree): # 用于绘图 kernel="poly"
return Pipeline([
("stand_c", StandardScaler()),
("svcc", svm.SVC(kernel="poly", degree=degree))
])
def plot_decision_boundary(model, axis): # 绘制边界
x0, x1 = np.meshgrid(
np.linspace(axis[0], axis[1], int((axis[1] - axis[0]) * 100)).reshape(-1, 1),
np.linspace(axis[2], axis[3], int((axis[3] - axis[2]) * 100)).reshape(-1, 1),
)
X_new = np.c_[x0.ravel(), x1.ravel()]
y_predict = model.predict(X_new)
zz = y_predict.reshape(x0.shape)
from matplotlib.colors import ListedColormap
custom_cmap = ListedColormap(['#EF9A9A', '#FFF59D', '#90CAF9'])
plt.contourf(x0, x1, zz, cmap=custom_cmap)
# plt.figure(figsize=(100, 100), dpi=100)
# 1. 生成两组线性均匀分布发的数据(完全线性可分)
num1 = 100
data0 = np.random.random((num1, 2)) * 6 + [4, 4]
data1 = np.random.random((num1, 2)) * 6 + [4, -4]
x1 = np.vstack((data0, data1)) # 垂直方向合并两个数据
y1 = [0] * num1 + [1] * num1 # label 标签
plt.scatter(x1[:, 0], x1[:, 1], c=y1)
plt.title("data 1")
plt.show()
# 2. 生成两组线性均匀分布发的数据(完全线性 不可分)
num2 = 100
data0 = np.random.random((num2, 2)) * 6 + [4, 2]
data1 = np.random.random((num2, 2)) * 6 + [4, -3]
x2 = np.vstack((data0, data1)) # 垂直方向合并两个数据
y2 = [0] * num2 + [1] * num2 # label 标签
plt.scatter(x2[:, 0], x2[:, 1], c=y2)
plt.title("data 2")
plt.show()
# 3. 生成两组高斯分布的数据(完全线性可分)
num3 = 300
mean0 = [-4, -4]
mean1 = [4, 4]
cov = [[1, 0], [0, 1]]
data0 = np.random.multivariate_normal(mean0, cov, num3)
data1 = np.random.multivariate_normal(mean1, cov, num3)
x3 = np.vstack((data0, data1)) # 垂直方向合并两个数据
y3 = [0] * num3 + [1] * num3 # label 标签
plt.scatter(x3[:, 0], x3[:, 1], c=y3)
plt.title("data 3")
plt.show()
# 4. 生成两组高斯分布的数据(完全线性 不可分)
num4 = 300
mean0 = [-2, -2]
mean1 = [1, 1]
cov = [[1, 0], [0, 1]]
data0 = np.random.multivariate_normal(mean0, cov, num4)
data1 = np.random.multivariate_normal(mean1, cov, num4)
x4 = np.vstack((data0, data1)) # 垂直方向合并两个数据
y4 = [0] * num4 + [1] * num4 # label 标签
plt.scatter(x4[:, 0], x4[:, 1], c=y4)
plt.title("data 4")
plt.show()
# 5. 生成环状数据
x5, y5 = make_circles(n_samples=100, factor=0.3, noise=0.1) # 两个圈的 总点数
x5 *= 5
# print(x1) # 所有点的坐标
# print(y1) # 如:[0 1 1 1 1 0 1 0 0 0]
plt.scatter(x5[:, 0], x5[:, 1], marker='o', c=y5)
plt.title("data 5")
plt.show()
# ######### 上面是生成 5 类数据 下面是分类####################
# # 使用 SVM 进行分类
# 1. 使用SVM 对数据 1 进行分类,并画出分类界面。
for i, (x, y) in enumerate([[x1, y1], [x2, y2]]):
clf = svm.SVC(kernel='linear')
clf.fit(x, y)
# 获取分离的超平面
w = clf.coef_[0]
a = - w[0] / w[1]
xx = np.linspace(4, 10)
yy = a * xx - (clf.intercept_[0]) / w[1]
# 绘制通过支撑向量的分离超平面的平行线
b = clf.support_vectors_[0]
yy_down = a * xx + (b[1] - a * b[0])
b = clf.support_vectors_[-1]
yy_up = a * xx + (b[1] - a * b[0])
plt.scatter(x[:, 0], x[:, 1], c=y)
plt.plot(xx, yy, 'k-', c="r")
plt.plot(xx, yy_down, 'k--', c="b")
plt.plot(xx, yy_up, 'k--', c="y")
plt.title("data %d, kernel=linear" % (i+1))
plt.show()
# 3. 使用SVM对 数据 3 进行分类,并画出分类界面
# 31 使用 线性SVM
for i, (x, y) in enumerate([[x3, y3], [x4, y4]]):
clf = svm.SVC(kernel='linear')
clf.fit(x, y)
# 获取分离的超平面
w = clf.coef_[0]
a = - w[0] / w[1]
xx = np.linspace(-5, 5)
yy = a * xx - (clf.intercept_[0]) / w[1]
# 绘制通过支撑向量的分离超平面的平行线
b = clf.support_vectors_[0]
yy_down = a * xx + (b[1] - a * b[0])
b = clf.support_vectors_[-1]
yy_up = a * xx + (b[1] - a * b[0])
plt.scatter(x[:, 0], x[:, 1], c=y3)
plt.plot(xx, yy, 'k-', c="r")
plt.plot(xx, yy_down, 'k--', c="b")
plt.plot(xx, yy_up, 'k--', c="y")
plt.title("data %d, kernel=linear" % (i+3))
plt.show()
# 32 使用 rbf 核
for i, (x, y) in enumerate([[x3, y3], [x4, y4], [x5, y5]]):
svc = RBFKernelSVC(gamma=1)
svc.fit(x, y)
plot_decision_boundary(svc, axis=[-7, 7, -8, 7])
plt.scatter(x[y == 0, 0], x[y == 0, 1])
plt.scatter(x[y == 1, 0], x[y == 1, 1])
plt.scatter(x[:, 0], x[:, 1], c=y) # 原始的数据
plt.title("data %d, kernel=rbf" % (i+3))
plt.show()
# 33 使用 多项式核 degree = 2 和 3
for i, (x, y) in enumerate([[x3, y3], [x4, y4], [x5, y5]]):
for degree in [2, 3]:
svc = PolyKernelSVC(degree=degree)
svc.fit(x, y)
plot_decision_boundary(svc, axis=[-7, 7, -8, 7])
plt.scatter(x[y == 0, 0], x[y == 0, 1])
plt.scatter(x[y == 1, 0], x[y == 1, 1])
plt.scatter(x[:, 0], x[:, 1], c=y) # 原始的数据
plt.title("data %d, kernel=Poly degree=%d" % (i + 3, degree))
plt.show()
# end