用Python实现SVM分类器:从数据到决策边界可视化,以鸢尾花数据集为例
前言
在机器学习的世界里,支持向量机(Support Vector Machine,简称SVM)是一种非常强大的分类算法。它通过寻找最优的决策边界,将不同类别的数据分开。本文将通过一个简单的Python代码示例,展示如何使用SVM对数据进行分类,并可视化决策边界和支持向量。
数据准备
为了方便演示,我们使用了经典的鸢尾花(Iris)数据集。这个数据集包含了三种不同种类的鸢尾花,每种花有四个特征:花萼长度、花萼宽度、花瓣长度和花瓣宽度。为了简化问题,我们只取前两个特征(花萼长度和花萼宽度),并且只考虑其中的两类数据(类别0和类别1)。
from sklearn import datasets
iris = datasets.load_iris()
X = iris.data[:, :2] # 只取前两个特征:花萼长度和花萼宽度
y = iris.target
# 只取两类数据(为了简单起见,我们只取类别0和1)
X = X[y != 2]
y = y[y != 2]
数据划分与标准化
接下来,我们将数据集划分为训练集和测试集,其中70%的数据用于训练,30%的数据用于测试。为了确保模型的泛化能力,我们对数据进行了标准化处理,使每个特征的均值为0,标准差为1。
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
模型训练
我们使用了sklearn
库中的SVC
类来创建一个SVM分类器,并选择了线性核函数。然后,我们用训练集数据对模型进行训练。
from sklearn.svm import SVC
clf = SVC(kernel='linear') # 选择线性核函数
clf.fit(X_train, y_train)
可视化决策边界和支持向量
为了更好地理解模型的工作原理,我们绘制了训练数据点、决策边界以及支持向量。决策边界是SVM模型的核心,它将不同类别的数据分隔开来;而支持向量则是距离决策边界最近的几个数据点,它们对决策边界的位置起到了决定性的作用。
import numpy as np
import matplotlib.pyplot as plt
plt.figure(figsize=(8, 6))
plt.scatter(X_train[:, 0], X_train[:, 1], c=y_train, cmap='coolwarm', s=50, edgecolors='k')
ax = plt.gca()
x_min, x_max = ax.get_xlim()
y_min, y_max = ax.get_ylim()
xx, yy = np.meshgrid(np.linspace(x_min, x_max, 100), np.linspace(y_min, y_max, 100))
Z = clf.decision_function(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.contour(xx, yy, Z, levels=[0], linewidths=2, colors='black')
plt.scatter(clf.support_vectors_[:, 0], clf.support_vectors_[:, 1], s=100, facecolors='none', edgecolors='k', label='Support Vectors')
plt.title('SVM')
plt.xlabel('Feature 1 (Sepal Length)')
plt.ylabel('Feature 2 (Sepal Width)')
plt.legend()
plt.show()
模型评估
最后,我们用测试集数据对模型进行评估,计算模型的准确率。准确率是衡量模型性能的一个重要指标,它表示模型正确分类的样本数占总样本数的比例。
from sklearn.metrics import accuracy_score
y_pred = clf.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print(f"模型在测试集上的准确率: {accuracy:.2f}")
总结
通过上述代码,我们成功地实现了一个简单的SVM分类器,并对模型的决策边界和支持向量进行了可视化。SVM算法在处理线性可分数据时表现出了强大的分类能力。当然,SVM也有其局限性,例如在处理大规模数据集时可能会遇到性能瓶颈。不过,这并不妨碍它在许多实际应用中发挥重要作用。希望本文能帮助你更好地理解和应用SVM算法。
完整代码
# 导入必要的库
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import accuracy_score
# 创建一个简单的数据集
iris = datasets.load_iris()
X = iris.data[:, :2] # 只取前两个特征:花萼长度和花萼宽度
y = iris.target
# 只取两类数据(为了简单起见,我们只取类别0和1)
X = X[y != 2]
y = y[y != 2]
# 划分数据集,70%的数据用来训练,30%的数据用来测试
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# 数据标准化
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
# 创建一个SVM分类器
clf = SVC(kernel='linear') # 选择线性核函数
# 训练模型
clf.fit(X_train, y_train)
# 可视化数据点和决策边界
plt.figure(figsize=(8, 6))
# 绘制训练数据点
plt.scatter(X_train[:, 0], X_train[:, 1], c=y_train, cmap='coolwarm', s=50, edgecolors='k')
# 绘制决策边界
ax = plt.gca()
x_min, x_max = ax.get_xlim()
y_min, y_max = ax.get_ylim()
xx, yy = np.meshgrid(np.linspace(x_min, x_max, 100), np.linspace(y_min, y_max, 100))
Z = clf.decision_function(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.contour(xx, yy, Z, levels=[0], linewidths=2, colors='black')
# 绘制支持向量
plt.scatter(clf.support_vectors_[:, 0], clf.support_vectors_[:, 1], s=100, facecolors='none', edgecolors='k', label='Support Vectors')
# 显示图形
plt.title('SVM')
plt.xlabel('Feature 1 (Sepal Length)')
plt.ylabel('Feature 2 (Sepal Width)')
plt.legend()
plt.show()
# 预测并评估模型
y_pred = clf.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print(f"模型在测试集上的准确率: {accuracy:.2f}")