
机器学习与模式识别实验_Anaconda3_Python
第三次实验:支持向量机在仿真数据集上的应用第三次实验:支持向量机在仿真数据集上的应用前言一、实验内容概述二、编程思路及步骤1、检查python以及机器学习的版本是否达到要求,导入一些基础的包,并设置字体、创建图像保存的地址。2、生成符合实验要求的make_blobs数据集,输出其散点图并保存。3、使用线性支持向量机对生成的数据进行分类4、查找支持向量。5、编写一个输出支持向量机边界线的函数,方便后
第三次实验:支持向量机在仿真数据集上的应用
1、检查python以及机器学习的版本是否达到要求,导入一些基础的包,并设置字体、创建图像保存的地址。
2、生成符合实验要求的make_blobs数据集,输出其散点图并保存。
7、生成符合实验要求的make_moons数据集,输出其散点图并保存。
前言
前两次实验写得太差了,就不上传了。
一、实验内容概述
1. 生成Blobs data 仿真数据,n_features=2, centers=2,其它未指定参数自定(若没有使用默认参数请标出实际使用值),在平面上绘制生成数据散点图;
2. 使用线性支持向量机(分别使用硬间隔和软间隔)对生成的数据进行分类,输出类似于下图的支持向量机边界线,标出支持向量,并分析比较两种间隔的分类效果;
3. 生成moon data,noise= 0.17,其它未指定参数自定(若没有使用默认参数请标出实际使用值),在平面上绘制生成数据散点图;
4. 分别用线性核SVM和高斯核SVM对生成的moon data 进行分类,输出类似下图的分类边界,并比较它们的分类效果。
二、编程思路及步骤
1、检查python以及机器学习的版本是否达到要求,导入一些基础的包,并设置字体、创建图像保存的地址。
# coding: utf-8
import sys
assert sys.version_info >= (3, 5)
import sklearn
assert sklearn.__version__ >= "0.20"
import os
import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['Microsoft YaHei']
np.random.seed(211)
IMAGES_PATH = os.path.join(".", "images", "svm")
2、生成符合实验要求的make_blobs数据集,输出其散点图并保存。
from sklearn.datasets import make_blobs # 多类单标签数据集
X1, Y1 = make_blobs(n_features=2, # 每个样本两个特征维度
centers=2, # 产生两个中心点
random_state=211)
plt.scatter(X1[:, 0], X1[:, 1], marker='o', c=Y1, s=25, edgecolor='k')
plt.title("生成的blobs数据集散点图")
plt.savefig(IMAGES_PATH + r'\blobs数据集的散点图.png', dpi=300)
plt.show()
3、使用线性支持向量机对生成的数据进行分类
由于惩罚系数越小,街道越宽,间隔违规越多,故软间隔的惩罚系数应尽可能小,此处取0.5,硬间隔的惩罚系数应尽可能大,此处取100即可。
# 使用线性支持向量机对生成的数据进行分类
from sklearn import datasets
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.svm import LinearSVC
scaler = StandardScaler()
# 软间隔分类:惩罚系数小,街道宽,间隔违规多
svm_clf1 = LinearSVC(C=0.5, loss="hinge", random_state=211)
# 硬间隔分类:C取100,模拟无穷大
svm_clf2 = LinearSVC(C=100, loss="hinge", random_state=211)
scaled_svm_clf1 = Pipeline([
("scaler", scaler),
("linear_svc", svm_clf1),
])
scaled_svm_clf2 = Pipeline([
("scaler", scaler),
("linear_svc", svm_clf2),
])
scaled_svm_clf1.fit(X1, Y1)
scaled_svm_clf2.fit(X1, Y1)
4、查找支持向量。
# Convert to unscaled parameters
b1 = svm_clf1.decision_function([-scaler.mean_ / scaler.scale_])
b2 = svm_clf2.decision_function([-scaler.mean_ / scaler.scale_])
w1 = svm_clf1.coef_[0] / scaler.scale_
w2 = svm_clf2.coef_[0] / scaler.scale_
svm_clf1.intercept_ = np.array([b1])
svm_clf2.intercept_ = np.array([b2])
svm_clf1.coef_ = np.array([w1])
svm_clf2.coef_ = np.array([w2])
# Find support vectors (LinearSVC does not do this automatically)
t = Y1 * 2 - 1
support_vectors_idx1 = (t * (X1.dot(w1) + b1) < 1).ravel()
support_vectors_idx2 = (t * (X1.dot(w2) + b2) < 1).ravel()
svm_clf1.support_vectors_ = X1[support_vectors_idx1]
svm_clf2.support_vectors_ = X1[support_vectors_idx2]
5、编写一个输出支持向量机边界线的函数,方便后续使用。
# 输出支持向量机边界线
def plot_svc_decision_boundary(svm_clf, xmin, xmax):
w = svm_clf.coef_[0]
b = svm_clf.intercept_[0]
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, "k-", linewidth=2)
plt.plot(x0, gutter_up, "k--", linewidth=2)
plt.plot(x0, gutter_down, "k--", linewidth=2)
6、将第3、4和5步的结果可视化,并保存。
# 先创建图形网络
# ax是一个包含两个Axes对象的数组
fig, ax = plt.subplots(ncols=2, figsize=(10, 2.7), sharey=True)
plt.sca(ax[0])
plt.plot(X1[:, 0][Y1==1], X1[:, 1][Y1==1], "g^", label="类A")
plt.plot(X1[:, 0][Y1==0], X1[:, 1][Y1==0], "bs", label="类B")
plot_svc_decision_boundary(svm_clf1, 0, 15)
plt.xlabel("特征一", fontsize=14)
plt.ylabel("特征二", fontsize=14)
plt.legend(loc="upper right", fontsize=14) # 设置图例的位置_右上
plt.title("软间隔分类 C取{}".format(svm_clf1.C), fontsize=16)
plt.axis([3, 12, -12.5, 7])
plt.sca(ax[1])
plt.plot(X1[:, 0][Y1==1], X1[:, 1][Y1==1], "g^")
plt.plot(X1[:, 0][Y1==0], X1[:, 1][Y1==0], "bs")
plot_svc_decision_boundary(svm_clf2, 0, 15)
plt.xlabel("特征一", fontsize=14)
plt.title("硬间隔分类 C取{}".format(svm_clf2.C), fontsize=16)
plt.axis([3, 12, -12.5, 7])
plt.suptitle("软/硬间隔分类")
plt.savefig(IMAGES_PATH + r'\软硬间隔分类.png', dpi=300)
plt.show()
7、生成符合实验要求的make_moons数据集,输出其散点图并保存。
# 生成数据集并输出散点图
from sklearn.datasets import make_moons
X, y = make_moons(noise=0.17, # 加入高斯噪声
random_state=211)
plt.scatter(X[:, 0], X[:, 1], marker='o', c=y, s=25, edgecolor='k')
plt.title("生成的moons数据集散点图")
plt.savefig(IMAGES_PATH + r'\moons数据集的散点图.png', dpi=300)
plt.show()
8、用线性核SVM对生成的moon data 进行分类,输出分类边界。
如果模型过拟合,可以减小多项式核的阶数,如果是过拟合,可以增大阶数,经检验,4阶线性核SVM效果最佳。
# 用线性核SVM对生成的数据进行分类
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import PolynomialFeatures
from sklearn.svm import LinearSVC
polynomial_svm_clf = Pipeline([
("poly_features", PolynomialFeatures(degree=4)),
("scaler", StandardScaler()),
("svm_clf", LinearSVC(C=10, loss="hinge", random_state=211,max_iter=10000))
])
polynomial_svm_clf.fit(X, y)
plot_predictions(polynomial_svm_clf, [-1.5, 2.5, -1, 1.5])
plot_dataset(X, y, [-1.5, 2.5, -1, 1.5])
plt.title("4阶的多项式线性核SVM分类器", fontsize=16)
plt.savefig(IMAGES_PATH + r'\线性核SVM.png', dpi=300)
plt.show()
9、用高斯核SVM对生成的数据进行分类。
增大y使钟型曲线更窄,导致每个样本的影响范围变的更小,判定边界最终变得更不规则,在单个样本周围环绕。相反的﹐较小的y值使钟型曲线更宽﹐样本有更大的影响范围﹐判定边界最终则更加平滑。所以如果模型过拟合,你应该减小y值﹐若欠拟合﹐则增大y(与超参数c 相似)。
# 用高斯核SVM对生成的数据进行分类
from sklearn.svm import SVC
gamma1, gamma2 = 0.1, 5
C1, C2 = 0.001, 1000
hyperparams = (gamma1, C1), (gamma1, C2), (gamma2, C1), (gamma2, C2)
svm_clfs = []
for gamma, C in hyperparams:
rbf_kernel_svm_clf = Pipeline([
("scaler", StandardScaler()),
("svm_clf", SVC(kernel="rbf", gamma=gamma, C=C))
])
rbf_kernel_svm_clf.fit(X, y)
svm_clfs.append(rbf_kernel_svm_clf)
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(10.5, 7), sharex=True, sharey=True)
for i, svm_clf in enumerate(svm_clfs):
plt.sca(axes[i // 2, i % 2])
plot_predictions(svm_clf, [-1.5, 2.45, -1, 1.5])
plot_dataset(X, y, [-1.5, 2.45, -1, 1.5])
gamma, C = hyperparams[i]
plt.title(r"$\gamma = {}, C = {}$".format(gamma, C), fontsize=16)
if i in (0, 1):
plt.xlabel("")
if i in (1, 3):
plt.ylabel("")
plt.suptitle("高斯核SVM")
plt.savefig(IMAGES_PATH + r'\高斯核SVM.png', dpi=300)
plt.show()
后记
新手上路,请多指正!
附:源代码
3_make_blobs.py
# coding: utf-8
import sys
assert sys.version_info >= (3, 5)
import sklearn
assert sklearn.__version__ >= "0.20"
import os
import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['Microsoft YaHei']
np.random.seed(211)
IMAGES_PATH = os.path.join(".", "images", "svm")
# 输出支持向量机边界线
def plot_svc_decision_boundary(svm_clf, xmin, xmax):
w = svm_clf.coef_[0]
b = svm_clf.intercept_[0]
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, "k-", linewidth=2)
plt.plot(x0, gutter_up, "k--", linewidth=2)
plt.plot(x0, gutter_down, "k--", linewidth=2)
# 生成数据集并输出散点图
from sklearn.datasets import make_blobs # 多类单标签数据集
X1, Y1 = make_blobs(n_features=2, # 每个样本两个特征维度
centers=2, # 产生两个中心点
random_state=211)
plt.scatter(X1[:, 0], X1[:, 1], marker='o', c=Y1, s=25, edgecolor='k')
plt.title("生成的blobs数据集散点图")
plt.savefig(IMAGES_PATH + r'\blobs数据集的散点图.png', dpi=300)
plt.show()
# 使用线性支持向量机对生成的数据进行分类
from sklearn import datasets
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.svm import LinearSVC
scaler = StandardScaler()
# 软间隔分类:惩罚系数小,街道宽,间隔违规多
svm_clf1 = LinearSVC(C=0.5, loss="hinge", random_state=211)
# 硬间隔分类:C取100,模拟无穷大
svm_clf2 = LinearSVC(C=100, loss="hinge", random_state=211)
scaled_svm_clf1 = Pipeline([
("scaler", scaler),
("linear_svc", svm_clf1),
])
scaled_svm_clf2 = Pipeline([
("scaler", scaler),
("linear_svc", svm_clf2),
])
scaled_svm_clf1.fit(X1, Y1)
scaled_svm_clf2.fit(X1, Y1)
# Convert to unscaled parameters
b1 = svm_clf1.decision_function([-scaler.mean_ / scaler.scale_])
b2 = svm_clf2.decision_function([-scaler.mean_ / scaler.scale_])
w1 = svm_clf1.coef_[0] / scaler.scale_
w2 = svm_clf2.coef_[0] / scaler.scale_
svm_clf1.intercept_ = np.array([b1])
svm_clf2.intercept_ = np.array([b2])
svm_clf1.coef_ = np.array([w1])
svm_clf2.coef_ = np.array([w2])
# Find support vectors (LinearSVC does not do this automatically)
t = Y1 * 2 - 1
support_vectors_idx1 = (t * (X1.dot(w1) + b1) < 1).ravel()
support_vectors_idx2 = (t * (X1.dot(w2) + b2) < 1).ravel()
svm_clf1.support_vectors_ = X1[support_vectors_idx1]
svm_clf2.support_vectors_ = X1[support_vectors_idx2]
# 先创建图形网络
# ax是一个包含两个Axes对象的数组
fig, ax = plt.subplots(ncols=2, figsize=(10, 2.7), sharey=True)
plt.sca(ax[0])
plt.plot(X1[:, 0][Y1==1], X1[:, 1][Y1==1], "g^", label="类A")
plt.plot(X1[:, 0][Y1==0], X1[:, 1][Y1==0], "bs", label="类B")
plot_svc_decision_boundary(svm_clf1, 0, 15)
plt.xlabel("特征一", fontsize=14)
plt.ylabel("特征二", fontsize=14)
plt.legend(loc="upper right", fontsize=14) # 设置图例的位置_右上
plt.title("软间隔分类 C取{}".format(svm_clf1.C), fontsize=16)
plt.axis([3, 12, -12.5, 7])
plt.sca(ax[1])
plt.plot(X1[:, 0][Y1==1], X1[:, 1][Y1==1], "g^")
plt.plot(X1[:, 0][Y1==0], X1[:, 1][Y1==0], "bs")
plot_svc_decision_boundary(svm_clf2, 0, 15)
plt.xlabel("特征一", fontsize=14)
plt.title("硬间隔分类 C取{}".format(svm_clf2.C), fontsize=16)
plt.axis([3, 12, -12.5, 7])
plt.suptitle("软/硬间隔分类")
plt.savefig(IMAGES_PATH + r'\软硬间隔分类.png', dpi=300)
plt.show()
3_make_moons.py
# coding: utf-8
import sys
assert sys.version_info >= (3, 5)
import sklearn
assert sklearn.__version__ >= "0.20"
import os
import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['Microsoft YaHei']
np.random.seed(211)
IMAGES_PATH = os.path.join(".", "images", "svm")
def plot_dataset(X, y, axes):
plt.plot(X[:, 0][y==0], X[:, 1][y==0], "bs")
plt.plot(X[:, 0][y==1], X[:, 1][y==1], "g^")
plt.axis(axes)
plt.grid(True, which='both')
plt.xlabel(r"$x_1$", fontsize=20)
plt.ylabel(r"$x_2$", fontsize=20, rotation=0)
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)
# 生成数据集并输出散点图
from sklearn.datasets import make_moons
X, y = make_moons(noise=0.17, # 加入高斯噪声
random_state=211)
plt.scatter(X[:, 0], X[:, 1], marker='o', c=y, s=25, edgecolor='k')
plt.title("生成的moons数据集散点图")
plt.savefig(IMAGES_PATH + r'\moons数据集的散点图.png', dpi=300)
plt.show()
# 用线性核SVM对生成的数据进行分类
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import PolynomialFeatures
from sklearn.svm import LinearSVC
polynomial_svm_clf = Pipeline([
("poly_features", PolynomialFeatures(degree=4)),
("scaler", StandardScaler()),
("svm_clf", LinearSVC(C=10, loss="hinge", random_state=211,max_iter=10000))
])
polynomial_svm_clf.fit(X, y)
plot_predictions(polynomial_svm_clf, [-1.5, 2.5, -1, 1.5])
plot_dataset(X, y, [-1.5, 2.5, -1, 1.5])
plt.title("4阶的多项式线性核SVM分类器", fontsize=16)
plt.savefig(IMAGES_PATH + r'\线性核SVM.png', dpi=300)
plt.show()
# 用高斯核SVM对生成的数据进行分类
from sklearn.svm import SVC
gamma1, gamma2 = 0.1, 5
C1, C2 = 0.001, 1000
hyperparams = (gamma1, C1), (gamma1, C2), (gamma2, C1), (gamma2, C2)
svm_clfs = []
for gamma, C in hyperparams:
rbf_kernel_svm_clf = Pipeline([
("scaler", StandardScaler()),
("svm_clf", SVC(kernel="rbf", gamma=gamma, C=C))
])
rbf_kernel_svm_clf.fit(X, y)
svm_clfs.append(rbf_kernel_svm_clf)
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(10.5, 7), sharex=True, sharey=True)
for i, svm_clf in enumerate(svm_clfs):
plt.sca(axes[i // 2, i % 2])
plot_predictions(svm_clf, [-1.5, 2.45, -1, 1.5])
plot_dataset(X, y, [-1.5, 2.45, -1, 1.5])
gamma, C = hyperparams[i]
plt.title(r"$\gamma = {}, C = {}$".format(gamma, C), fontsize=16)
if i in (0, 1):
plt.xlabel("")
if i in (1, 3):
plt.ylabel("")
plt.suptitle("高斯核SVM")
plt.savefig(IMAGES_PATH + r'\高斯核SVM.png', dpi=300)
plt.show()
更多推荐





所有评论(0)