SVM 基本原理

第一次接触到SVM支持向量机(Support Vector Machine)就让我想到一个镜头:

看过这个电影的友友们该有一个概念了,难道说....SVM和分界线有关?

SVM 的核心思想可以用一句话概括:寻找一个最优的决策边界,使得该边界到两类样本中最近点的距离最大化。

  1. 决策边界(超平面)在一个 n 维空间中,SVM 的目标是找到一个 (n-1) 维的“超平面”来完美地分开两类数据。在二维空间中,这个超平面就是一条直线;在三维空间中,是一个平面。
  2. 支持向量: 这是 SVM 名字的由来。支持向量是离决策边界最近的那些数据点

  3. 最大间隔: SVM 不满足于仅仅找到一个能分开数据的超平面,它要找到那个“最好”的——即到两类支持向量的距离都最远的那个超平面。这个距离被称为“间隔”。

说人话就是,比如这张电影图,这几个士兵就是朝韩(看作两类数据)的支持向量(支持向量就相当于两个区域的边界点),看他们之间的那道警卫线,就是超平面,如果我们只看地面,那道线就是超平面,如果我们用三维空间视角看,从地表那条线垂直于地表的平面,就是超平面的平面;电影最后的镜头,一位游客的帽子被风刮进警备线另一端了,她的帽子就越过超平面了hhhhh。但是最大间隔在这张图不适用,毕竟这几个士兵还偷摸在一起吃吃喝喝,所以这根本不是去最大间隔的车!
 

SVM分类实现

言归正传,让我们说中文,不是,说代码。

导入相关库:

import numpy as np
import pandas as pd
from sklearn.svm import SVC
from sklearn.model_selection import GridSearchCV
import ast

1.Numpy:算数的。导入 NumPy 库并将其简写为 np,是 Python 科学计算的基础库。

2.Pandas:看数据结构的。能用它来展示表格。就类似EXCEl,SQL这种表,但Numpy是N维,上限比Pandas不知道高到哪里去了(+1,+1,+1,👓)。

3.SVC:从 scikit-learn 导入支持向量机分类器 (SVC)。

4.GridSearchCV:网格搜索。GridSearchCV 是 scikit-learn 库中的一个工具,用于自动化地搜索机器学习模型的最佳超参数组合。

5.ast:ast(Abstract Syntax Trees,抽象语法树)是 Python 的内置模块,用于将 Python 代码解析为语法树结构。总之会比eval安全,因为它把数据结构解析成树结构了,不然遇到某些危险(恶意代码),直接运行就gg了。

定义一个读取文件的函数(Java使用者喜欢叫这个叫做“方法”)

def read_data(path):
    with open(path) as f:
        lines=f.readlines()
    lines=[ast.literal_eval(line.strip()) for line in lines]
    X,y=zip(*lines)
    X=np.array(X)
    y=np.array(y)
    return X,y

1.def read_data(path):定义一个名为 read_data 的函数,它接受一个参数 path(文件路径)。

2.with open(path) as f:一个文件句柄。使用 with 语句安全地打开文件。这种方式可以确保文件在使用后正确关闭,即使发生异常也是如此。

3.lines=f.readlines(): 读取文件的所有行并将其存储在列表 lines 中。

4.line.strip(): 去除每行字符串首尾的空白字符(如空格、换行符等)。

5.ast.literal_eval:将字符串解析为 Python 表达式并求值。

6.zip(*lines):用于"解压"列表。如果 lines 是一个元组列表 [(x1, y1), (x2, y2), ...],那么 zip(*lines) 会返回 ([x1, x2, ...], [y1, y2, ...])。

7.X,y=...: 将解压后的两个部分分别赋值给 X(特征)和 y(标签)。
np.array(X) 和 np.array(y): 将 Python 列表转换为 NumPy 数组,这样可以进行高效的数值运算。

8.return X,y: 返回特征数组 X 和标签数组 y。

加载训练和测试数据,行了,导入文件试试这个函数吧,顺便看看形状

X_train,y_train=read_data("路径/train_data")
display(X_train.shape)
X_test,y_test=read_data("路径/test_data")
display(X_test.shape)

1.read_data(''路径''): 调用之前定义的函数读取训练数据。

2.display(X_train.shape): 显示训练数据的形状。shape 属性返回数组的维度,例如 (n_samples, n_features)。我的这个数据集是(500,2),500行2个特征。

建模预测

svc=SVC(kernel='sigmoid')
svc.fit(X_train,y_train.ravel())
svc.score(X_test,y_test.ravel())

1.SVC(kernel='sigmoid'): 创建一个使用 Sigmoid 核函数的 SVM 分类器,再用svc接一下(救一下.jpg)。

2.kernel='sigmoid':核函数的作用: 将数据映射到高维空间,使其更容易线性可分。还有就是sigmoid公式是:

$S(x) = \frac{1}{1 + e^{-x}} = \frac{e^x}{e^x + 1}$

3.svc.fit(): 使用训练数据训练 SVM 模型,算法会寻找最优的超平面来分隔不同类别的数据。

4.y_train.ravel(): 平铺,将标签数组展平为一维。如果 y_train 是二维数组(如形状为 (n, 1)),ravel() 会将其转换为一维数组(形状为 (n,))。

5.score(): 跑分的。计算模型在测试数据上的准确率,即正确分类的样本比例。俺的输出score是0.83。

SVM超参数优化

svc=SVC(kernel="sigmoid")
params={'C':np.logspace(-3,3,50),'tol':[0.0001,0.001,0.01,0.1,1]}
gc=GridSearchCV(estimator=svc,param_grid=params,cv=5)
gc.fit(X_train,y_train.ravel())
print("最优超参数:",gc.best_params_)
best_model=gc.best_estimator_
best_model.score(X_test,y_test.ravel())

1.SVC(kernel='sigmoid'): 重新创建一个使用 Sigmoid 核函数的 SVM 分类器,用于网格搜索。

2.params = {'C':np.logspace(-3,3,50),'tol':[0.0001,0.001,0.01,0.1,1]}:

        C: 正则化参数。较小的 C 值强调间隔最大化,较大的 C 值强调正确分类。

        np.logspace(-3,3,50): 在对数尺度上从 10⁻³ 到 10³ 生成 间隔相同的50 个数值。

        tol: 容忍度,控制停止训练的误差容限。就是说小于这个值就停吧,已经收敛了,可以可以了。

        尝试 5 个不同的值: 0.0001, 0.001, 0.01, 0.1, 1。

3.GridSearchCV: 执行网格搜索交叉验证。

        estimator=svc:咱的模型使用svc。

        param_grid=params:要搜索的参数网格,咱们上一行设置的这些参数传进去。

        cv=5:5折交叉验证。就比如你手里有一个5*5的矩阵的纸,沿斜对角一对折,诶您猜怎么着,斜对角5个值有折痕诶,拿这5个值用来测试,其他的用来训练,没错就跟线性代数矩阵一样。

4.gc.fit(X_train,y_train.ravel()):执行网格搜索,尝试所有参数组合,并使用交叉验证评估每种组合的性能(都试一哈,目的是找出最好的)。

5.print('最优超参数:',gc.best_params_):行了,打印吧。gc.best_params_,返回性能最佳的超参数组合。

6.best_model.score(X_test,y_test.ravel()):评估最佳模型在测试集上的性能,依旧看看分数(can can need)。我的数据集输出结果是:最优超参数: {'C': np.float64(0.21209508879201905), 'tol': 0.0001}

打印前十成绩单试试:

results = pd.DataFrame(gc.cv_results_)
print(results[['param_C', 'param_tol', 'mean_test_score']].sort_values('mean_test_score', ascending=False).head(10))

根据交叉验证的平均得分降序排序(ascending=False):

OKOK,结束了。

以上内容可能营养价值不高,属于是学习之余给自己找点喜欢的事干了属于是,如果有误人子弟的地方(orz抱歉),欢迎大佬批评指正,我很乐意学习的。

一想到我一回到小出租屋里扑面而来的泡面味我就想笑。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐