返回
机器学习练习六:用SKLearn实现支持向量机(SVM)
人工智能
2023-10-22 18:13:23
机器学习练习六:用SKLearn实现支持向量机(SVM)
在本练习中,我们将从一些简单的2D数据集开始使用SVM来查看它们的工作原理。顾名思义,基于线性核函数的SVM主要是用来实现线性决策边界的分类问题的。我们可以看到这是一个线性决策边界的简单数据集,并且在(0.2,4.2)位置有一个异常点,下面我们将探索SVM中的超参数C(可以理解为惩罚项或正则化项)和核函数(线性核函数、高斯核函数、多项式核函数)对SVM分类结果的影响。
1. 导入必要的库
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.svm import SVC
2. 加载数据
我们使用的是一个简单的人工生成的数据集,其中包含200个数据点,分为两类。
data = pd.read_csv('data.csv')
X = data[['x1', 'x2']]
y = data['y']
3. 划分训练集和测试集
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
4. 训练SVM模型
我们使用的是线性核函数的SVM模型,并使用默认参数进行训练。
model = SVC()
model.fit(X_train, y_train)
5. 评估模型
from sklearn.metrics import accuracy_score
y_pred = model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print('Accuracy:', accuracy)
6. 绘制决策边界
def plot_decision_boundary(model, X, y):
# Generate a grid of points
x1_min, x1_max = X[:, 0].min() - 1, X[:, 0].max() + 1
x2_min, x2_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.linspace(x1_min, x1_max, 100), np.linspace(x2_min, x2_max, 100))
# Predict the class for each point in the grid
Z = model.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
# Plot the decision boundary
plt.contourf(xx, yy, Z, alpha=0.5)
plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='viridis')
plt.xlabel('x1')
plt.ylabel('x2')
plt.title('Decision boundary')
plt.show()
plot_decision_boundary(model, X, y)
7. 探索超参数C的影响
超参数C控制SVM的惩罚项,较大的C值意味着对误分类的惩罚更大,较小的C值意味着对误分类的惩罚更小。我们可以通过改变C值来观察对SVM分类结果的影响。
C_values = [0.1, 1, 10, 100]
for C in C_values:
model = SVC(C=C)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print('C:', C)
print('Accuracy:', accuracy)
print()
plot_decision_boundary(model, X, y)
8. 探索核函数的影响
SVM支持多种核函数,常用的核函数包括线性核函数、高斯核函数和多项式核函数。我们可以通过改变核函数来观察对SVM分类结果的影响。
kernel_functions = ['linear', 'rbf', 'poly']
for kernel in kernel_functions:
model = SVC(kernel=kernel)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print('Kernel:', kernel)
print('Accuracy:', accuracy)
print()
plot_decision_boundary(model, X, y)
9. 处理异常点
异常点可能会对SVM的分类结果产生负面影响。我们可以通过删除异常点来提高SVM的分类准确性。
# 识别异常点
outlier_index = np.argmax(np.abs(model.support_vectors_ - np.mean(model.support_vectors_, axis=0)))
outlier = X_train[outlier_index]
# 删除异常点
X_train = np.delete(X_train, outlier_index, axis=0)
y_train = np.delete(y_train, outlier_index)
# 重新训练SVM模型
model = SVC()
model.fit(X_train, y_train)
# 评估模型
y_pred = model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print('Accuracy without outlier:', accuracy)
# 绘制决策边界
plot_decision_boundary(model, X, y)
10. 总结
在本次练习中,我们探索了SVM的基本原理和使用方法。我们通过改变超参数C和核函数来观察对SVM分类结果的影响。我们还学习了如何处理异常点以提高SVM的分类准确性。