大家好,今天我学习了SVM(支持向量机),主要简单给大家讲解一下原理与案例。至于为什么不像之前一样把原理讲一遍 : 因为太复杂了,感觉也没有必要深究SVM的原理,毕竟以后做的也不会跟这个太有关系。所以只是简单的了解了一下,用其代码实现了iris的分类而已。(真不是我偷懒 :)
email:yuhan.huang@whu.edu.cn
源代码https://github.com/pilipala5/sklearn/blob/master/code/9_SVM.ipynb
SVM
怎么说呢,虽然不会太细致的讲,但是还是有必要了解SVM中的基本原理。其本质就在于让决策边界的margin最大,其是一种监督学习方法。怎么理解呢?以二维点的二分类为例子,我们得到的分类边界是这样的一条线,那么我们平移这个线,直到碰到训练集中的样本点为止,那么这两条直线之间的距离就是margin!然后SVM的发明者通过数学证明了,margin越大,分类效果越好!这就是svm的由来。当然,在更广泛的情况下都可以使用。只是这种决策边界比较直观好理解。更复杂了我也不懂。
在sklearn的官方文档中,其对SVM做出了如下简介,我挑选几句个人觉得比较重要的发给大家,感兴趣的也可以去观看一下原文。
1. SVM可以用来分类也可以用来进行回归
2. SVM适用于高纬特征的情况
3. 内核可以自定义 也可以使用人家封装好的
4. 不提供概率估计,是通过昂贵的交叉验证获取的。
sklearn中大概封装了这些SVM函数:
案例 SVC
sklearn中的监督学习算法其实就那么几步:导入数据集、声明模型、训练模型、得到结果。这里我直接把代码和结果给大家,不懂得可以问问kimi或者gpt哈,不难很简单。看看人家官方文档一下就会了。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.svm import SVC
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
iris = load_iris()
X = iris.data[:, :2] # only select 2 feature, just for simpler visualization.
y = iris.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=42)
svc = SVC(kernel="linear", C=1.0).fit(X_train, y_train)
y_hat = svc.predict(X_test)
# plot classification results
_, axes = plt.subplots(1, 2, figsize=(8, 3))
axes[0].set_title("y_test") ; axes[1].set_title("y_hat(linear kernel)")
axes[0].scatter(X_test[:, 0], X_test[:, 1], c=y_test); axes[1].scatter(X_test[:, 0], X_test[:, 1], c=y_hat)
# plot decision boundary
n = 200
xx, yy = np.meshgrid(np.linspace(X[:, 0].min(), X[:, 0].max(), n),
np.linspace(X[:, 1].min(), X[:, 1].max(), n))
Z = svc.predict(np.c_[xx.ravel(), yy.ravel()])
axes[1].contourf(xx, yy, Z.reshape(n, n), alpha=0.3)
得到结果如下:分类结果还是可以的~
评价指标
写完了回过头来看,发现自己疏忽了一个玩意。那就是模型的评价,对于一般的监督学习,我们可以通过混淆矩阵与ROC(AUC)进行模型的一个模型有效性的评价。接下来我简单的给大家介绍一下哈。
对于二分类问题,混淆矩阵是一个2x2的矩阵,包含以下四个元素:
- 真正例(True Positives, TP):模型正确预测为正例的数量。
- 假正例(False Positives, FP):模型错误预测为正例的数量(实际上是负例)。
- 真负例(True Negatives, TN):模型正确预测为负例的数量。
- 假负例(False Negatives, FN):模型错误预测为负例的数量(实际上是正例)。
对于多分类问题,混淆矩阵是一个nxn的矩阵,其中n是类别的数量。每一行代表实际的类别,每一列代表预测的类别。本质含义还是一样的。
在scikit-learn
中,可以使用函数来计算各类指标。例如:
from sklearn.metrics import confusion_matrix, accuracy_score, precision_score, recall_score, f1_score
# 假设y_true是真实的标签,y_pred是模型预测的标签
y_true = [2, 0, 2, 2, 0, 1]
y_pred = [0, 0, 2, 2, 0, 2]
# 计算混淆矩阵
cm = confusion_matrix(y_true, y_pred)
print("Confusion Matrix:")
print(cm)
# 计算评估指标
accuracy = accuracy_score(y_true, y_pred)
precision = precision_score(y_true, y_pred, average='macro')
recall = recall_score(y_true, y_pred, average='macro')
f1 = f1_score(y_true, y_pred, average='macro')
print(f"Accuracy: {accuracy}")
print(f"Precision: {precision}")
print(f"Recall: {recall}")
print(f"F1 Score: {f1}")
在机器学习领域,特别是在分类问题中,接收者操作特征曲线(Receiver Operating Characteristic curve,简称ROC曲线)和曲线下面积(Area Under the Curve,简称AUC)是评估模型性能的重要工具。以下是这两个概念的规范描述:
ROC曲线是一种用于展示二分类系统性能的图形工具。它通过绘制真正例率(True Positive Rate,TPR)对假正例率(False Positive Rate,FPR)的图表来展示模型在不同阈值下的性能。其中:
- 真正例率(TPR)也称为召回率(Recall),计算公式为 TPR=TPTP+FNTPR=TP+FNTP,表示所有正例中被正确识别的比例。
- 假正例率(FPR)计算公式为 FPR=FPFP+TNFPR=FP+TNFP,表示所有负例中被错误识别为正例的比例。
ROC曲线的横轴是FPR,纵轴是TPR。理想情况下,模型的ROC曲线会尽可能地靠近左上角,这意味着模型具有较高的TPR和较低的FPR。
AUC是ROC曲线下的面积,它量化了模型的整体性能。AUC的值介于0和1之间,其中:
- AUC = 0.5 表示模型没有区分能力,相当于随机猜测。
- AUC = 1 表示模型具有完美的区分能力。
- AUC值越接近1,表示模型的性能越好。
在Python的scikit-learn
库中,可以使用roc_auc_score
函数来计算AUC值,使用roc_curve
函数来获取ROC曲线的坐标点。
from sklearn.metrics import roc_curve, roc_auc_score
import matplotlib.pyplot as plt
# 假设y_true是真实的标签,y_scores是模型预测的概率
y_true = [0, 1, 0, 1]
y_scores = [0.1, 0.4, 0.35, 0.8]
# 计算ROC曲线的坐标点
fpr, tpr, thresholds = roc_curve(y_true, y_scores)
# 计算AUC值
auc = roc_auc_score(y_true, y_scores)
# 绘制ROC曲线
plt.figure()
plt.plot(fpr, tpr, color='darkorange', lw=2, label='ROC curve (area = %0.2f)' % auc)
plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver Operating Characteristic')
plt.legend(loc="lower right")
plt.show()