问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

实验:SVM实现多分类

创作时间:
作者:
@小白创作中心

实验:SVM实现多分类

引用
CSDN
1.
https://blog.csdn.net/2201_75467743/article/details/143950497

本实验旨在帮助读者理解支持向量机(SVM)的基本原理,掌握如何利用Scikit-learn库构建和训练SVM分类器,并评估其在分类任务中的表现。通过该实验,读者将学会如何选择合适的核函数、调整参数以及分析模型性能。

实验环境

  • Python 3.x
  • Scikit-learn库
  • Jupyter Notebook

实验数据集

使用sklearn提供的鸢尾花(Iris)数据集。该数据集包含150条记录,每条记录有4个特征(萼片长度、萼片宽度、花瓣长度、花瓣宽度),属于3个类别之一(Setosa、Versicolor、Virginica),是一个典型的多分类数据集。注意:若从本地导入iris.csv则还需要对标签进行编码成如0、1、2;如果直接load_iris()则不用,因为这时已经被自动编码好了。

实验步骤

一、导入必要的库

导入Scikit-learn中的数据集模块、划分数据集和评估模型的模块,以及用于构建SVM分类器的相关模块。

from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix

二、加载数据集,并划分训练集和测试集

使用datasets.load_iris()加载鸢尾花数据集。接着,使用train_test_split将数据集按7:3的比例划分为训练集和测试集。

# 加载数据集
iris = datasets.load_iris()
X = iris.data
y = iris.target

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

三、数据标准化

由于SVM对特征的尺度非常敏感,因此需要对数据进行标准化处理。使用StandardScaler对训练集进行拟合并转换,然后对测试集进行转换。

scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)

四、构建和训练SVM模型

Linear:适用于数据集本身就接近线性可分的情况
Rbf:适用于数据分布复杂且非线性可分的情况
Poly:适用于数据集包含一定的多项式关系

SVM是一种强大的分类方法,尤其擅长处理高维数据,能够通过选择不同的核函数灵活地应对不同类型的数据。

svm_model = SVC(kernel='linear', C=1.0)
svm_model.fit(X_train, y_train)

五、预测

使用训练好的SVM模型对测试集进行预测。

y_pred = svm_model.predict(X_test)

六、评估模型

使用accuracy_score评估模型的准确率;使用classification_report输出分类的精度、召回率和F1分数;使用confusion_matrix查看预测标签与真实标签之间的关系。

print("模型准确率:", accuracy_score(y_test, y_pred))
print("\n分类报告:\n", classification_report(y_test, y_pred))
print("\n混淆矩阵:\n", confusion_matrix(y_test, y_pred))

七、在测试集上进行预测

svm_model_rbf = SVC(kernel='rbf', C=1.0)
svm_model_rbf.fit(X_train, y_train)
y_pred_rbf = svm_model_rbf.predict(X_test)
print("RBF核模型准确率:", accuracy_score(y_test, y_pred_rbf))
print("\nRBF核分类报告:\n", classification_report(y_test, y_pred_rbf))

八、调整SVM的超参数

SVM的性能受参数影响很大,尤其是C(惩罚参数)和gamma(核函数参数,尤其是对于RBF核)。可以通过网格搜索(GridSearchCV)来找到最佳的超参数。

from sklearn.model_selection import GridSearchCV
param_grid = {
    'C': [0.1, 1, 10],
    'gamma': ['scale', 'auto'],
    'kernel': ['linear', 'rbf']
}
grid_search = GridSearchCV(SVC(), param_grid, cv=5)
grid_search.fit(X_train, y_train)
print("最佳参数组合:", grid_search.best_params_)
best_model = grid_search.best_estimator_
y_pred_best = best_model.predict(X_test)
print("优化后模型准确率:", accuracy_score(y_test, y_pred_best))

实验总结

  1. 分析不同核函数和惩罚系数等参数设置对分类结果的影响,各种核函数分别适合什么类型的数据集?总结SVM在分类任务中的表现。

C值的选择需要通过交叉验证来调整,确保模型既不出现过拟合,也不出现欠拟合。

(1)线性核函数(linear):适用于数据线性可分或接近线性可分的情形。计算效率较高,尤其是在特征维度较高时。线性核和较小的C通常适合数据简单、线性可分的任务。

(2)高斯径向基核(RBF):适用于数据存在非线性关系的情况。它能通过映射到高维空间,使数据点变得可分。对参数gamma较为敏感,gamma越大,模型越复杂,容易过拟合;gamma越小,模型越简单,可能导致欠拟合。RBF核适用于较为复杂、非线性的数据集。

(3)多项式核(poly):适用于数据呈现出多项式关系的情况。参数degree控制多项式的次数,通常需要在实验中调整。多项式核需要较精确的参数调节,适合数据呈现复杂非线性关系的场景。

  1. 理解SVM如何实现多分类(一对一、一对多策略),可在示例代码的基础上进行可视化展示。

SVM本身是二分类算法,但可以通过扩展来处理多分类问题。常见的多分类策略有一对一和一对多。

一对一:
优点:分类器之间的决策边界较为明确,分类效果通常较好。
缺点:计算开销较大,尤其是类别数目很多时。

一对多:
优点:训练速度较快,尤其是类别数目较多时。
缺点:如果类别之间差异较小,可能会导致误分类。

可视化展示:

from sklearn.datasets import load_iris
from sklearn.svm import SVC
from sklearn.multiclass import OneVsRestClassifier, OneVsOneClassifier
import matplotlib.pyplot as plt
import numpy as np

# 载入数据集
iris = load_iris()
X, y = iris.data, iris.target

# 只选择前两个特征
X = X[:, :2]

# 训练一对多和一对一的SVM模型
svm_ovr = OneVsRestClassifier(SVC(kernel='linear', C=1))
svm_ovo = OneVsOneClassifier(SVC(kernel='linear', C=1))

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

# 绘制决策边界
def plot_decision_boundary(clf, X, y, ax):
    h = .02
    x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
    y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
    xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
                         np.arange(y_min, y_max, h))
    Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
    Z = Z.reshape(xx.shape)
    ax.contourf(xx, yy, Z, alpha=0.8)
    scatter = ax.scatter(X[:, 0], X[:, 1], c=y, edgecolors='k', marker='o')
    return scatter

# 可视化
fig, axes = plt.subplots(1, 2, figsize=(12, 6))
scatter_ovr = plot_decision_boundary(svm_ovr, X, y, axes[0])
axes[0].set_title("One-vs-Rest SVM")
axes[1].set_title("One-vs-One SVM")
scatter_ovo = plot_decision_boundary(svm_ovo, X, y, axes[1])
plt.show()
  1. 分析实验过程遇到的难点或问题,比较SVM和其他分类方法的区别。

实验过程遇到的难点或问题:

(1)模型调参复杂:在实际应用中,选择合适的核函数和调整C、gamma等超参数需要大量的实验和交叉验证。

(2)数据预处理的影响:SVM对数据的预处理非常敏感,特征的标准化和归一化对于模型的效果有显著影响。

(3)计算开销较大:尤其在使用一对一策略时,需要训练多个二分类器,对于数据集较大的问题,训练时间较长。

与其他分类方法的区别:

(1)与决策树:决策树较易理解且训练速度较快,但容易过拟合,尤其是当树的深度较大时。SVM能有效处理高维空间中的非线性问题,且具有较好的泛化能力。

(2)与K近邻:KNN没有显式的训练过程,计算代价较高,尤其在数据集较大时。SVM则通过核函数映射将问题转化为更高维度,使得复杂的数据问题得以解决。

(3)与逻辑回归:逻辑回归适用于线性分类问题,并且计算速度较快,但其线性假设限制了其对非线性问题的处理能力。SVM在处理复杂边界时优势更加明显,尤其是使用RBF核的情况。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号