文章目录
一、什么是支持向量机(SVM)
- 机器学习中的SVM(Support Vector Machine,支持向量机)是一种监督学习算法,广泛应用于分类和回归分析中。它的基本思想是通过找到一个最优超平面来最大化不同类别之间的间隔,从而实现对数据的分类。
1、SVM两个基本概念
-
支持向量:支持向量是离超平面最近的那些样本点,它们对于确定超平面的位置和方向至关重要。
-
超平面:在二维空间中,超平面是一条直线;在三维空间中,它是一个平面;在更高维的空间中,它是一个超平面。SVM的目标是找到一个最优超平面,使得不同类别的样本点能够尽可能地被分开,并且这个超平面与最近的样本点(即支持向量)之间的距离最大化。
2、SVM的原理
-
线性可分情况:
- 当数据线性可分时,SVM的目标是找到一个最优超平面,将两个不同类别的样本点完全分开,并且这个超平面与最近的样本点(支持向量)之间的距离最大化。这个距离被称为间隔。
- SVM通过计算样本点到超平面的距离来定义间隔,并尝试最大化这个间隔,从而增强分类器的鲁棒性和泛化能力。
-
非线性可分情况:
- 当数据非线性可分时,SVM引入了核函数的概念。核函数能够将样本从原始特征空间映射到更高维的特征空间,使得数据在新的空间中线性可分。
- 常用的核函数包括线性核、多项式核和高斯核(径向基函数)等。这些核函数允许SVM处理更复杂的非线性分类问题。
二、示例:支持向量机(SVM)实现二分类问题
- 下面是一个含有100个样本,且每个样本都含有4个特征的数据集
- 为了方便获取数据,这个数据集被刻意处理过,前50个样本标签为0,后50个样本标签为1
- 这些样本被分为两个标签类,分别是0和1
- 第一列为每个样本的序列值没有作用,获取数据时要跳过它,最后一列为标签列
- 由于这个数据每个样本都有4个特征,属于四维空间,无法进行可视化展示,所以我们先选取其中的两个特征进行可视化展示和构建模型训练,再通过所有的特征构建模型,并对模型进行评估
1、先选取两个特征,并进行可视化
-
1、获取数据并可视化原始数据
import pandas as pd """获取数据""" data = pd.read_csv('iris.csv', header=None) """可视化原始数据""" import matplotlib.pyplot as plt data1 = data.iloc[:50, :] data2 = data.iloc[50:, :] # 原始数据是四维,无法展示,选择两个特征进行展示 plt.scatter(data1[1], data1[3], marker='+') plt.scatter(data2[1], data2[3], marker='o') plt.show()
-
2、使用SVM进行训练
- SVC() 是 Scikit-learn(一个流行的 Python 机器学习库)中用于实现支持向量分类(Support Vector Classification, SVC)的一个类。SVC 是一种基于监督学习的分类算法,它试图找到一个超平面来最大化不同类别之间的间隔,从而实现分类。
- SVC()有以下一些参数:
- kernel:字符串,指定要在算法中使用的核函数类型。常用的核函数包括 ‘linear’(线性核)、‘poly’(多项式核)、‘rbf’(径向基函数核,也称为高斯核)、‘sigmoid’(双曲正切核)等。默认值是 ‘rbf’。
- C:浮点数,正则化参数 C 的大小。C 的值越大,对错误分类的惩罚就越大,这可能导致过拟合。C 的值越小,对错误分类的惩罚就越小,这可能导致欠拟合。默认值是 1.0。
- degree:整数,当使用多项式核时,该参数指定多项式的维度。默认值是 3。
- gamma:浮点数,‘rbf’、‘poly’ 和 ‘sigmoid’ 核的系数。对于 ‘rbf’ 核,gamma 是核函数中的系数(exp(-gamma * ||x-y||^2));对于 ‘poly’ 和 ‘sigmoid’ 核,gamma 用于定义核函数中的 coef0。默认值是 ‘scale’ 或 ‘auto’,这意呀着 Scikit-learn 将自动选择 gamma 的值。
- coef0:浮点数,仅当使用 ‘poly’ 和 ‘sigmoid’ 核时有用。它是核函数中的独立项。默认值是 0.0。
- tol:浮点数,停止训练的容差。默认值是 1e-3。
- max_iter:整数,求解器中的最大迭代次数(对于 ‘newton-cg’、‘sag’ 和 ‘lbfgs’ 求解器)。默认值是 -1,表示无限制。
- class_weight:字典或字符串,指定类别权重。如果给出字典,则可以直接为不同的类别指定不同的权重;如果给出字符串 ‘balanced’,则算法会自动调整权重,使得每个类别的权重与其样本数成反比。默认值是 None,表示所有类别的权重都相等。
- probability:布尔值,是否启用概率估计。这必须在训练模型之前启用,并且会减慢训练速度,因为它需要使用 5-fold 交叉验证。默认值是 False。
from sklearn.svm import SVC x = data.iloc[:, [1, 3]] # 获取第1,3特征作为训练数据 y = data.iloc[:, -1] # 获取最后一列标签列 # 因为这里样本数量不是很多,可以使用C的默认值1,也可以适当增加,来观察模型效果的变化 svm = SVC(kernel='linear', C=1.0, random_state=0) svm.fit(x, y) # 传入数据进行训练
-
3、可视化SVM结果
-
svm.coef_[0] 表示的是SVM模型中第一个决策函数的权重系数
-
svm.intercept_[0] 表示的是SVM模型中第一个决策函数的截距项
-
svm.support_vectors_ 是支持向量机(SVM)模型中的一个重要属性,它包含了模型中的所有支持向量。支持向量是那些位于决策边界上或非常接近决策边界的训练数据点,它们对于定义决策边界至关重要。在SVM中,决策边界完全由这些支持向量决定,而非支持向量的数据点对决策边界的位置没有任何影响。
# 参数w[原始数据为二维数组] w = svm.coef_[0] # 偏置项b[原始数据为一维数组] b = svm.intercept_[0] # 超平面方程:w1*x1+w2*x2+b=0 # --> x2 = -(w1*x1+b)/w2 import numpy as np # 在0~7之间产生300个数据 x1 = np.linspace(0, 7, 300) # 超平面方程 x2 = -(w[0] * x1 + b) / w[1] # 计算得到x2 # 上超平面方程 x3 = (1 - (w[0] * x1 + b)) / w[1] # 下超平面方程 x4 = (-1 - (w[0] * x1 + b)) / w[1] # 可视化超平面 plt.plot(x1, x2, linewidth=2, color='r') plt.plot(x1, x3, linewidth=1, color='r', linestyle='--') plt.plot(x1, x4, linewidth=1, color='r', linestyle='--') # 进行坐标轴限制 plt.xlim(4, 7) plt.ylim(0, 5) # 找到支持向量[二维数组],可视化支持向量 vets = svm.support_vectors_ plt.scatter(vets[:, 0], vets[:, 1], c='b', marker='x') plt.show()
-
2、选取所有的特征传入模型,并对模型进行评估
- 1、获取数据并划分数据集
import pandas as pd
# 读取数据
data = pd.read_csv('iris.csv', header=None)
x = data.iloc[:, 1:-1] # 读取所有的样本作为数据集
y = data.iloc[:, -1] # 读取标签列
from sklearn.model_selection import train_test_split
# 切出20%的数据作为测试集,其余的作为训练集,并抛出一个随机种子,为了后面每次运行所划分的数据都与第一次相同
x_train, x_test, y_train, y_test = \
train_test_split(x, y, test_size=0.2, random_state=0)
- 2、使用SVM进行训练
from sklearn.svm import SVC
# 因为是多维的数据,所以选取的核函数为 rbf 或 poly
svm = SVC(kernel='rbf', C=1.0, random_state=0)
svm.fit(x_train, y_train) # 传入训练集进行训练
- 3、传入测试集进行测试,并进行评估
from sklearn import metrics
# 传入训练集进行测试
test_score = svm.score(x_test, y_test)
print(test_score)
# 评估模型
test_predict = svm.predict(x_test)
print(metrics.classification_report(y_test, test_predict))
- 结果如下:
- 由结果可以看出, 支持向量机(SVM)在小样本训练集的二分类问题上可以得到非常好的效果