支持向量机(Support Vector Machine,SVM)是一种二分类模型,它的基本模型是定义在特征空间上的间隔最大的线性分类器。当训练数据线性可分时,通过硬间隔最大化(hard margin maximization)学习一个线性分类器;当训练数据近似线性可分时,通过软间隔最大化(soft margin maximization)学习一个线性分类器;当训练数据线性不可分时,通过使用核技巧(kernel trick)及软间隔最大化,学习一个非线性分类器。
核函数的定义与作用
核函数(Kernel Function)是一个在支持向量机(SVM)和其他机器学习算法中广泛使用的概念。给定两个输入向量xi和xj,核函数k(xi,xj)计算它们在某个隐式定义的高维特征空间中的内积φ(xi)Tφ(xj),其中φ是一个将输入向量映射到高维空间的映射函数。
核函数的主要作用是避免在高维空间中直接进行复杂的计算。在处理非线性可分的数据时,SVM 等算法通过将数据映射到高维空间,使得数据在高维空间中可能变得线性可分。然而,显式地计算高维空间中的映射向量可能会非常复杂,甚至在计算上不可行。核函数允许我们在原始输入空间中计算高维空间内积的等效值,从而大大降低了计算成本,同时也能有效地处理非线性问题。
在这里插入图片描述

实现代码如下:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, confusion_matrix
from sklearn.preprocessing import StandardScaler

可视化Iris数据集的决策边界和数据点

def plot_iris_decision_boundary(X, y, clf, title):
h = 0.02
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1 #获取特征数据X中第一列特征(通常对应Iris数据集中的某个特征,比如花萼长度)的最小值和最大值。
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1 #这里获取特征数据X中第二列特征(比如花萼宽度)的最小值和最大值
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)

plt.contourf(xx, yy, Z, cmap=plt.cm.Paired, alpha=0.8)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Paired)
plt.xlabel('Sepal length')
plt.ylabel('Sepal width')
plt.title(title)
plt.show()

在Iris数据集上进行SVM实验

def iris_svm_experiment():
iris = datasets.load_iris()
X = iris.data[:, :2] # 取前两个特征方便可视化,取Iris数据集的前两个特征
y = iris.target

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

kernels = ['linear', 'poly', 'rbf'] #定义一个列表,包含了要使用的SVM核函数类型,分别是线性核、多项式核和径向基核(RBF核)。
for kernel in kernels:
    clf = SVC(kernel=kernel)   # 根据当前循环的核函数类型,创建一个SVM分类器对象。
    clf.fit(X_train, y_train) # 使用训练集数据(特征X_train和对应的标签y_train)对创建好的SVM分类器进行训练,使分类器学习数据中的模式和规律。
    y_pred = clf.predict(X_test) # 使用训练好的SVM分类器对测试集数据(特征X_test)进行预测,得到预测的类别标签,存储在y_pred中。
    accuracy = accuracy_score(y_test, y_pred)
    print(f"{kernel}核SVM在Iris数据集上的准确率: {accuracy}")

    if kernel == 'linear':
        plot_iris_decision_boundary(X, y, clf, f'Iris Dataset - {kernel} SVM Decision Boundary')
    elif kernel == 'poly':
        plot_iris_decision_boundary(X, y, clf, f'Iris Dataset - {kernel} SVM Decision Boundary')
    elif kernel == 'rbf':
        plot_iris_decision_boundary(X, y, clf, f'Iris Dataset - {kernel} SVM Decision Boundary')

在Sonar数据集上进行SVM实验

def sonar_svm_experiment():
path = r"C:\Users\lenovo\Downloads\connectionist+bench+sonar+mines+vs+rocks\sonar.all-data"
data = pd.read_csv(path, header=None, sep=‘,’)
X = data.iloc[:, :-1].values
y = data.iloc[:, -1].values

# 数据标准化,提升模型效果(尤其是对rbf和poly核)
scaler = StandardScaler()
X = scaler.fit_transform(X)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

kernels = ['linear', 'rbf', 'poly']
for kernel in kernels:
    clf = SVC(kernel=kernel)
    clf.fit(X_train, y_train)
    y_pred = clf.predict(X_test)
    accuracy = accuracy_score(y_test, y_pred)
    print(f"{kernel}核SVM在Sonar数据集上的准确率: {accuracy}")

    # 计算混淆矩阵
    conf_matrix = confusion_matrix(y_test, y_pred)
    print(f"{kernel}核SVM在Sonar数据集上的混淆矩阵:\n{conf_matrix}")

    # 可以根据混淆矩阵进一步可视化(例如使用热力图展示混淆矩阵,方便更直观查看分类情况)
    plt.figure(figsize=(8, 6))
    plt.imshow(conf_matrix, interpolation='nearest', cmap=plt.cm.Reds)  #使用 imshow 函数绘制混淆矩阵的热力图,设置颜色映射为 cm.reds(红色系的颜色映射,常用于表示此类统计信息,颜色越深表示对应的值越大)
    plt.title(f"{kernel} Visualization of Confusion Matrix for Nuclear SVM on Sonar Data Set")
    plt.colorbar()

    classes = np.unique(y)
    tick_marks = np.arange(len(classes))
    plt.xticks(tick_marks, classes, rotation=45)
    plt.yticks(tick_marks, classes)

    thresh = conf_matrix.max() / 2.
    for i in range(conf_matrix.shape[0]):
        for j in range(conf_matrix.shape[1]):
            plt.text(j, i, format(conf_matrix[i, j], 'd'),
                     horizontalalignment="center",
                     color="white" if conf_matrix[i, j] > thresh else "black")

    plt.ylabel('True label')
    plt.xlabel('Predicted label')
    plt.tight_layout()
    plt.show()

if name == “main”:
print(“Iris数据集SVM实验结果:”)
iris_svm_experiment()
print(“\nSonar数据集SVM实验结果:”)
sonar_svm_experiment()
结果:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐