Skip to main content

支持向量机

支持向量机

这是一个分类算法。

在这个算法中我们将每一个数据作为一个点在一个 n 维空间上作图(n 是特征数),每一个特征值就代表对应坐标值的大小。

比如说我们有两个特征:一个人的身高和发长。我们可以将这两个变量在一个二维空间上作图,图上的每个点都有两个坐标值(这些坐标轴也叫做支持向量)。

在这个示例中,我们首先导入了 scikit-learn 库中的 svm 模块以及 NumPy 库。然后,我们创建了一些示例数据 X 和 y,其中 X 是特征,y 是目标标签。

接下来,我们创建了一个 SVM 分类器,使用线性核函数(kernel='linear')。

然后,我们使用 fit 方法拟合了模型,并在新数据点上使用 predict 方法进行预测,以获取新数据点的类别。

from sklearn import svm
import numpy as np

# 创建一些示例数据
X = np.array([[1, 2], [2, 3], [2, 5], [3, 2], [3, 3], [4, 5]]) # 特征
y = np.array([0, 0, 1, 0, 1, 1]) # 目标标签

# 创建SVM分类器
model = svm.SVC(kernel="linear")

# 拟合模型
model.fit(X, y)

# 要预测的新数据点
new_data_point = np.array([[3, 4]])
# 预测新数据点的类别
predicted_class = model.predict(new_data_point)

print("预测类别:", predicted_class)

简单示例

from sklearn.model_selection import train_test_split
from sklearn.datasets import load_breast_cancer
from sklearn import svm

# 导入一个数据量较多的数据,乳腺癌
iris = load_breast_cancer()
# 获取数据集
X, y = iris.data ,iris.target

# 直接使用数据
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)
# 创建SVM分类器
clf = svm.SVC()
# 拟合模型
clf.fit(X_train, y_train)

效果评估

# .score()返回的是准确度
# 和之前学习的accuracy_score、cross_val_score一样都是检测准确度的方法
print('预测是准确度为{}%'.format(clf.score(X_test, y_test)*100))

数据 normalization

from sklearn import preprocessing
# normalization是指将数据按比例缩放,使之落入一个小的特定区间
# 先标准化数据再使用数据
X2 = preprocessing.scale(X) # normalization step
# print(X2)
X2_train, X2_test, y2_train, y2_test = train_test_split(X2, y, test_size=0.3)

clf2 = svm.SVC()
clf2.fit(X2_train, y2_train)
print('预测是准确度为{}%'.format(clf2.score(X2_test, y2_test)*100))
# 简单验证后发现处理后的数据显然表现更好,预测是准确度为98.83040935672514%

from sklearn import model_selection

# 但是并不是每次验证得到的结果都是一致的,验证具有随机性,因此需要交叉验证
# 把数据分成5份,分别做测试集,提取分数并求平均值,显然处理后的数据表现更好
print(model_selection.cross_validate(clf,X_test, y_test,cv=5)['test_score'].mean())
print(model_selection.cross_validate(clf2,X2_test, y2_test,cv=5)['test_score'].mean())
'''
0.8947899159663866 # 未处理的数据
0.9825210084033614 # 处理后的数据
'''

防止过拟合

from __future__ import print_function
from sklearn.model_selection import learning_curve
from sklearn.datasets import load_digits
from sklearn.svm import SVC
import matplotlib.pyplot as plt
import numpy as np
# 载入数据
digits = load_digits()
X = digits.data
y = digits.target

# learning_curve()函数用于计算在不同大小的训练集上训练得到的模型在验证集上的得分情况
# 进而分析模型是否过拟合或者欠拟合
# 这里我们使用SVC模型,gamma=0.01
# gamma参数用于控制模型的复杂度,gamma越大,模型越复杂,越容易过拟合
# 通过train_sizes参数来指定训练集的大小
# 通过cv参数来指定交叉验证的次数
# 通过scoring参数来指定评价指标,这里使用的是负均方误差
train_sizes, train_loss, test_loss= learning_curve(
SVC(gamma=0.01), X, y, cv=10, scoring="neg_mean_squared_error",
train_sizes=[0.1, 0.25, 0.5, 0.75, 1])

# 计算平均值和标准差
train_loss_mean = -np.mean(train_loss, axis=1)
test_loss_mean = -np.mean(test_loss, axis=1)

# 绘制曲线
# 这里我们使用的是负均方误差,因此数值越小,模型越好
# ro-表示红色圆形实线,go-表示绿色圆形实线
plt.plot(train_sizes, train_loss_mean, 'ro-',
label="Training")
plt.plot(train_sizes, test_loss_mean, 'go-',
label="test-Cross-validation")
plt.xlabel("Training examples")
plt.ylabel("Loss")
# 显示图例,loc="best"表示自动选择最佳位置
plt.legend(loc="best")
plt.show()
# 这个图表示:
# 刚开始只有200个数据的时候,误差很大,这是因为数据量太少,模型无法很好地拟合数据
# 随着数据量的增加,误差逐渐减小,这是因为模型可以更好地拟合数据
# 但是随着数据集进一步增加,误差反而增大了,这说明模型出现了过拟合