机器学习(五)——支持向量机SVM(支持向量、间隔、正则化参数C、误差容忍度ε、核函数、软间隔、SVR、回归分类源码)
目录
- 关于
- 1 间隔与支持向量
- 2 对偶问题
- 3 核函数
- 4 软间隔与正则化
- 5 支持向量回归
- 6 核方法
- X 案例代码
- X.1 分类任务
- X.1.1 源码
- X.1.2 数据集(鸢尾花数据集)
- X.1.3 模型效果
- X.2 回归任务
- X.2.1 源码
- X.2.2 数据集(加州房价数据)
- X.2.3 模型效果
关于
- 本文是基于西瓜书(第六章)的学习记录。内容包括SVM模型间隔、支持向量、正则化参数C、误差容忍度 ε ε ε、核函数、软间隔、SVR模型、Python实现分类和回归的源码。
- 西瓜书电子版:百度网盘分享链接
1 间隔与支持向量
-
支持向量机(SVM)是一种监督学习算法,用于分类和回归分析。
-
分类学习最基本的想法就是基于训练集D在样本空间中找到一个划分超平面,将不同类别的样本分开.
-
怎样的超平面是最好的?——找位于两类训练样本“正中间”的划分超平面,这样的超平面对训练样本的局部扰动的“容忍性”最好。
-
支持向量机的基本思想是找到样本空间中的最佳划分超平面,以区分不同类别的样本。
-
支持向量:距离超平面最近的训练样本点,它们决定了超平面的位置。
-
间隔:两个异类支持向量到超平面的距离之和,称为间隔,SVM的目标是最大化这个间隔。
-
支持向量机的基本型:
2 对偶问题
- SVM的优化问题可以通过拉格朗日乘子法转化为对偶问题,这样可以更高效地求解。
- 问题的求解不是本文重心所在,在此不介绍,大家可参考电子书学习。
3 核函数
-
在现实任务中,原始样本空间内也许并不存在一个能正确划分两类样本的超平面,可将样本从原始空间映射到一个更高维的特征空间,使得样本在这个特征空间内线性可分
-
但是映射到高维空间意味着更大的计算量,这时候就引出了核函数:核函数允许SVM在高维空间或无穷维空间中寻找最优超平面,而无需显式地映射样本。
-
核函数生效的技巧:通过核函数计算原始样本空间中的内积,避免了直接在高维空间中计算。
-
哪些函数可以作为核函数:只要一个对称函数所对应的核矩阵半正定,它就能作为核函数使用。
-
常用核函数:包括线性核、多项式核、高斯核等。
4 软间隔与正则化
-
在现实任务中,训练样本往往不是线性可分的(即便恰好找到了某个核函数使训练集在特征空间中线性可分,也很难断定这个貌似线性可分的结果不是由于过拟合所造成的.),这时可以引入软间隔和正则化来提高模型的泛化能力。
-
软间隔:允许一些样本不满足硬间隔的约束,通过引入松弛变量来实现。
-
替代损失函数:如hinge损失、指数损失和对率损失,用于代替0/1损失函数,使得问题更容易求解,常用的替代损失函数:
-
如果使用对率损失函数替代0/1损失函数,则几乎得到了对率回归模型。实际上两者确实优化目标相近,性能相近。
-
正则化参数C:这个参数控制着模型对误分类的惩罚程度。C值越大,模型对误分类的惩罚越高,可能导致过拟合;C值越小,模型对误分类的惩罚越低,可能导致欠拟合。
5 支持向量回归
-
支持向量回归(SVR)是SVM在回归问题上的应用,它假设模型输出与真实输出之间存在一定的容忍度。
-
ε ε ε-不敏感损失:仅当模型输出与真实输出的差值超过 ε ε ε时才计算损失。
-
SVR的优化问题:通过引入松弛变量和正则化项来求解。
-
SVR的支持向量:与SVM类似,SVR的支持向量是落在 ε ε ε间隔带之外的样本。
6 核方法
-
核方法是一种基于核函数的学习方法,可以将线性学习器扩展为非线性学习器。
-
表示定理:任何在再生核希尔伯特空间中的学习问题都可以用核函数的线性组合来表示。
-
核化线性判别分析:通过核化将线性判别分析扩展到非线性情况。
X 案例代码
X.1 分类任务
X.1.1 源码
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.svm import SVC
from sklearn.metrics import confusion_matrix, accuracy_score, classification_report
import seaborn as sns
# 1. 加载数据集
iris = load_iris()
X, y = iris.data, iris.target
print("此时X,y的数据类型为:", type(X), type(y), '\n')
# 2. 将数据集分为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
print("此时X_train,y_train的数据类型为:", type(X_train), type(y_train), '\n')
print("X_train的前10条数据展示:")
print(pd.DataFrame(X_train).head(10).to_string(index=False, justify='left'), '\n')
# 3. 构建并训练SVM分类模型
model = SVC(kernel='rbf', random_state=42) # 使用高斯核函数
model.fit(X_train, y_train)
# 4. 预测测试集上的目标变量
y_pred = model.predict(X_test)
# 5. 评估模型性能
accuracy = accuracy_score(y_test, y_pred)
print("模型准确率:", accuracy)
print("分类报告:")
print(classification_report(y_test, y_pred))
# 6. 绘制混淆矩阵
conf_matrix = confusion_matrix(y_test, y_pred)
plt.figure(figsize=(8, 6))
sns.heatmap(conf_matrix, annot=True, fmt='d', cmap='Blues', xticklabels=iris.target_names, yticklabels=iris.target_names)
plt.xlabel('Predicted Labels')
plt.ylabel('True Labels')
plt.title('Confusion Matrix for Iris Dataset')
plt.tight_layout()
plt.show()
# 可选:将结果保存到DataFrame中以便进一步分析
results = pd.DataFrame({
'Actual': y_test,
'Predicted': y_pred
})
print("模型预测结果:")
print(results.head())
X.1.2 数据集(鸢尾花数据集)
-
鸢尾花数据集是机器学习领域中最著名的数据集之一,常被用于分类算法的测试和演示。
-
概览
- 样本数量:150个样本
- 特征数量:4个特征
- 标签种类数量:3个类别,每个类别有50个样本
-
特征描述
- 萼片长度 (sepal length):花萼的长度,单位为厘米。
- 萼片宽度 (sepal width):花萼的宽度,单位为厘米。
- 花瓣长度 (petal length):花瓣的长度,单位为厘米。
- 花瓣宽度 (petal width):花瓣的宽度,单位为厘米。
-
目标变量是鸢尾花的种类,共有三种:
- Iris setosa
- Iris versicolor
- Iris virginica
-
使用
- 可以使用
sklearn.datasets.load_iris()
函数来加载这个数据集,并查看其详细信息。
- 可以使用
X.1.3 模型效果
X.2 回归任务
X.2.1 源码
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVR
from sklearn.metrics import mean_squared_error, r2_score
# 1. 加载数据集
data = fetch_california_housing()
X, y = data.data, data.target
print("此时X,y的数据类型为:", type(X), type(y), '\n')
# 2. 将数据集分为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
print("此时X_train,y_train的数据类型为:", type(X_train), type(y_train), '\n')
print("X_train的前10条数据展示:")
print(pd.DataFrame(X_train).head(10).to_string(index=False, justify='left'), '\n')
# 3. 数据标准化
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
# 4. 构建并训练SVR模型
# 使用RBF核
svr = SVR(kernel='rbf', C=100, gamma=0.1, epsilon=.1)
# 训练模型
svr.fit(X_train, y_train)
# 5. 预测测试集上的目标变量
y_pred = svr.predict(X_test)
# 6. 评估模型性能
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
print("SVR模型性能:")
print(f"Mean Squared Error: {mse:.2f}")
print(f"R^2 Score: {r2:.2f}", '\n')
# 6. 绘制实际值和预测值的折线图
plt.figure(figsize=(12, 6))
plt.plot(y_test[:50], label='Actual', marker='o', color='blue')
plt.plot(y_pred[:50], label='Predicted', marker='x', color='red', linestyle='--')
plt.title('Actual vs Predicted Values for California Housing Dataset (50 Samples)')
plt.xlabel('Sample Index')
plt.ylabel('Target Value')
plt.legend()
plt.tight_layout()
plt.show()
# 可选:将结果保存到DataFrame中以便进一步分析
results = pd.DataFrame({
'Actual': y_test,
'Predicted': y_pred
})
# 可选:打印模型的一些参数
print("模型预测结果:")
print(results)
print("模型参数:")
print("C:", svr.C)
print("Gamma:", svr.gamma)
print("Epsilon:", svr.epsilon)
print("Kernel:", svr.kernel)
X.2.2 数据集(加州房价数据)
-
加州房价数据集是机器学习领域中常用的数据集之一,常被用于回归算法的测试和演示。
-
概览
- 样本数量:20640个样本
- 特征数量:8个特征
- 标签:1个连续的目标变量
-
特征描述
- MedInc (Median Income in block group):区块组的中位数收入,单位为10,000美元。
- HouseAge (Median House Age in block group):区块组中房屋的中位数年龄,单位为年。
- AveRooms (Average number of rooms per household):每个家庭的平均房间数。
- AveBedrms (Average number of bedrooms per household):每个家庭的平均卧室数。
- Population (Block group population):区块组的人口数。
- AveOccup (Average house occupancy):每个房屋的平均居住人数。
- Latitude (Block group latitude):区块组的纬度。
- Longitude (Block group longitude):区块组的经度。
-
目标变量
- MedHouseVal (Median house value for households in block group):区块组中房屋的中位数价值,单位为100,000美元。
-
使用
- 可以使用
sklearn.datasets.fetch_california_housing()
函数来加载这个数据集,并查看其详细信息。
- 可以使用
X.2.3 模型效果