初识机器学习(SVM)
一、机器学习十大常见算法本篇主要介绍支持向量机Support Vector Machine简称 SVM是一种监督学习算法主要用于分类和回归问题。SVM 的核心思想是找到一个最优的超平面将不同类别的数据分开。这个超平面不仅要能够正确分类数据还要使得两个类别之间的间隔最大化。二、SVM 的核心原理2.1 线性可分与最大间隔想象一个二维平面上面有两类数据点用圆圈和叉号表示。我们的任务是画一条直线把两类点分开。最简单的做法是“随便画一条线只要分开就行”。但 SVM 不满足于此——它要找到最优的那条线。什么样的线是最优的SVM 认为能让两类数据点离这条线都尽可能远的那条线就是最优的。这个“距离”被称为间隔Margin。SVM 的目标就是最大化间隔。位于间隔边界上的那些数据点就是支持向量——它们决定了最终分类器的位置。2.2 线性不可分与核函数现实中的数据往往没有那么“乖巧”——很多时候在低维空间中根本无法用一条直线或一个平面将两类数据完全分开。这时SVM 祭出了它的“秘密武器”——核函数Kernel Function。核函数的核心思想是将数据从低维空间映射到高维空间在高维空间中原本线性不可分的数据可能就变得线性可分了。SVM 中最常用的核函数是RBF径向基函数核也就是高斯核。在sklearn的SVC中默认使用的就是 RBF 核。简单总结一下超平面在二维空间中超平面是一个直线。在三维空间中超平面是一个平面。在更高维空间中超平面是一个分割空间的超平面。支持向量支持向量是离超平面最近的样本点。这些支持向量对于定义超平面至关重要。支持向量机通过最大化支持向量到超平面的距离即最大化间隔来选择最佳的超平面。最大间隔SVM的目标是最大化分类间隔使得分类边界尽可能远离两类数据点。这可以有效地减少模型的泛化误差。核技巧Kernel Trick对于非线性可分的数据SVM使用核函数将数据映射到更高维的空间在这个空间中数据可能是线性可分的。常用的核函数有线性核、多项式核、径向基函数RBF核等。SVM 分类流程选择一个超平面找到一个能够最大化分类边界的超平面。训练支持向量通过支持向量机算法选择离超平面最近的样本点作为支持向量。通过最大化间隔来找到最优超平面选择一个最优超平面使得间隔最大化。使用核函数处理非线性问题通过核函数将数据映射到高维空间来解决非线性可分问题。三、SVM 的关键参数在使用sklearn.svm.SVC时有两个参数对模型性能影响最大3.1 惩罚系数 CC 是正则化参数控制着模型对训练样本分类错误的容忍程度。C 值越大模型对分类错误越“不能容忍”会尽量正确分类每一个训练样本。这可能导致模型过于复杂容易过拟合。C 值越小模型对分类错误越“宽容”允许一些样本被分错但决策边界会更平滑泛化能力可能更好。简单来说C 在“训练集上的准确率”和“决策边界的平滑度”之间做权衡。3.2 RBF 核参数 gammagamma 定义了单个训练样本的影响力范围。gamma 值越小单个样本的影响力范围越“远”决策边界会比较平滑、简单。gamma 值越大单个样本的影响力范围越“近”决策边界会更复杂会紧密围绕训练数据。gamma 可以理解为“模型选出的支持向量的影响半径的倒数”。gamma 太大同样容易导致过拟合。C 和 gamma 的配合当 C 比较大、gamma 比较小时模型会有更多支持向量模型更复杂容易过拟合。四、实战案例智能寝室分配数据集介绍可看往期KNN算法第一步加载数据data np.loadtxt(datingTestSet2.txt) data pd.DataFrame(data) x data.iloc[:, :-1] y data.iloc[:, -1]np.loadtxt读取文本格式的数据文件每行是一个样本。我们将数据转换为 DataFrame方便操作。x是前三列特征y是最后一列标签。第二步数据标准化 —— 至关重要的一步x StandardScaler().fit_transform(x) x pd.DataFrame(x)这是 SVM 使用中极其重要的一步 SVM 依赖于样本之间的距离计算尤其是使用 RBF 核时。如果不同特征的量纲差异很大那么量级大的特征会主导距离计算模型会忽略量级小的特征。StandardScaler将每个特征转换为均值为 0、标准差为 1 的标准正态分布公式为其中 μ 是均值σ 是标准差。标准化后所有特征处于同一量级模型才能公平地看待每一个特征。第三步划分训练集和测试集train_x, test_x, train_y, test_y train_test_split(x, y, test_size0.2, random_state0)将数据按 8:2 的比例划分为训练集和测试集。random_state0保证每次运行结果一致。第四步交叉验证 —— 找到最优参数这是本代码的核心部分scores [] C_values [0.01, 0.1, 1, 10, 100, 1000, 10000] gamma_values [0.01, 0.1, 1, 10, 100, 1000, 10000] for i in C_values: for j in gamma_values: model SVC(Ci, gammaj, random_state0) score cross_val_score(model, train_x, train_y, cv10, scoringaccuracy) score_mean sum(score) / len(score) scores.append(score_mean) best_c C_values[np.argmax(scores) // len(gamma_values)] best_g gamma_values[np.argmax(scores) % len(gamma_values)]网格搜索Grid Search我们定义了 7 个 C 值和 7 个 gamma 值共 7×7497×749 种参数组合。通过双重循环遍历所有组合对每一种组合都训练模型并评估效果。交叉验证Cross Validation对于每一种参数组合我们不是只用一次训练/验证划分来评估而是使用10 折交叉验证。10 折交叉验证将训练集随机分成 10 份轮流用其中 9 份训练、1 份验证重复 10 次后取平均准确率作为该参数组合的得分。这样评估出来的得分更加稳定可靠。参数还原由于我们将所有得分保存在一维列表scores中np.argmax(scores)返回的是最大得分在一维列表中的索引。通过整除和取余运算我们可以反推出对应的 C 和 gammabest_c C_values[np.argmax(scores) // len(gamma_values)]best_g gamma_values[np.argmax(scores) % len(gamma_values)]np.argmax(scores) // 7得到的是第几个 C 值np.argmax(scores) % 7得到的是第几个 gamma 值。第五步使用最优参数训练最终模型model SVC(Cbest_c, gammabest_g, random_state0) model.fit(train_x, train_y)用网格搜索找到的最优参数best_c和best_g创建 SVM 模型并在完整的训练集上进行训练。第六步模型评估train_pred model.predict(train_x) print(metrics.classification_report(train_y, train_pred)) test_pred model.predict(test_x) print(metrics.classification_report(test_y, test_pred))classification_report会输出精确率Precision、召回率Recall、F1-score 等详细的分类评估指标帮助我们全面了解模型在训练集和测试集上的表现。完整代码如下import pandas as pd import numpy as np from sklearn.preprocessing import StandardScaler from sklearn.model_selection import train_test_split from sklearn.svm import SVC from sklearn.model_selection import cross_val_score from sklearn import metrics # 1. 加载数据 data np.loadtxt(datingTestSet2.txt) data pd.DataFrame(data) x data.iloc[:, :-1] # 特征 y data.iloc[:, -1] # 标签 # 2. 数据标准化 x StandardScaler().fit_transform(x) x pd.DataFrame(x) # 3. 划分训练集和测试集 train_x, test_x, train_y, test_y train_test_split( x, y, test_size0.2, random_state0 ) # 4. 网格搜索 交叉验证 寻找最优参数 scores [] C_values [0.01, 0.1, 1, 10, 100, 1000, 10000] gamma_values [0.01, 0.1, 1, 10, 100, 1000, 10000] for i in C_values: for j in gamma_values: model SVC(Ci, gammaj, random_state0) score cross_val_score(model, train_x, train_y, cv10, scoringaccuracy) score_mean sum(score) / len(score) scores.append(score_mean) # 从一维列表中还原最优参数 best_c C_values[np.argmax(scores) // len(gamma_values)] best_g gamma_values[np.argmax(scores) % len(gamma_values)] print(f最优 C: {best_c}, 最优 gamma: {best_g}) # 5. 使用最优参数训练模型 model SVC(Cbest_c, gammabest_g, random_state0) model.fit(train_x, train_y) # 6. 模型评估 train_pred model.predict(train_x) print(训练集评估报告) print(metrics.classification_report(train_y, train_pred)) test_pred model.predict(test_x) print(测试集评估报告) print(metrics.classification_report(test_y, test_pred))五、SVM 的使用流程总结通过上面的实战案例我们可以总结出使用 SVM 的详细流程步骤操作说明1. 数据准备加载数据分离特征和标签确保数据格式正确2. 数据预处理标准化/归一化SVM 依赖距离计算必须做3. 划分数据集train_test_split训练集用于调参测试集用于最终评估4. 参数调优网格搜索 交叉验证寻找最优的 C 和 gamma5. 训练模型用最优参数训练在完整训练集上训练6. 模型评估在测试集上评估检验模型的泛化能力六、SVM 的优缺点优点缺点在高维空间中表现优异对大规模数据集训练时间较长使用核函数可以处理非线性分类对参数C 和 gamma和核函数的选择敏感决策边界由支持向量决定内存效率高模型可解释性较差在样本量较小时仍有良好表现对数据标准化要求较高七、总结支持向量机通过最大化分类间隔来寻找最优决策边界借助核函数可以处理线性不可分的数据。在实际使用中数据标准化和参数调优C 和 gamma是决定模型性能的关键环节。希望通过这篇文章大家能够理解 SVM 的核心思想并能够独立使用 sklearn 实现 SVM 分类任务。