支持向量机算法原理及案例实践
支持向量机(SVM)是一种二分类模型,有别于感知机(误分类点到超平面的总距离)。支持向量机的学习策略是间隔最大化,当训练样本完全线性可分时,采用硬间隔最大化,称为线性可分支持向量机;当训练样本近似线性可分时,增加松弛变量,采用软间隔最大化,称为线性支持向量机;在非线性问题中引入了核函数和软间隔最大化,称为非线性支持向量机。
1.超平面与支持向量
超平面是决策边界,有助于对数据点进行分类,落在超平面两侧的数据划分为不同的类。超平面的尺寸取决于特征的数量,如果输入要素的数量是2,则超平面是一条直线。如果输入要素的数量是3,则超平面变为二维平面。
最接近超平面的数据点就称为支持向量,支持向量确定超平面的方向和位置,以便最大化分类器边界。
2.SVM算法原理
1)点到超平面的距离公式
2)最大间隔的优化模型
3)学习的对偶算法
于是,对于训练数据,总有。
若,则样本不会出现在上述求和公式中,也不会对产生任何影响;
若,则必有,所对应样本点位于最大间隔上,是一个支持向量。
这里显示出支持向量重要性质:训练完成后,大部分训练样本都不要保留,最终模型仅与支持向量有关。
4)松弛变量
现实中,很多样本数据都不能用一个超平面把数据完全分开。如果数据集中存在噪点的话,那么在求超平面就会出现问题。因此,引入松弛变量来允许少量数据可以处以分割面错误的一侧。
5)核函数
以上讨论的都是线性可分的情况,但是实际中数据并不都是线性可分的。对于低维平面内不可分的数据,放在一个高维空间中就有可能变得可分。具体地,在线性不可分的情况下,支持向量机首先在低维空间中完成计算,然后通过核函数输入空间映射到高维特征空间,最终在高维特征空间中构造出最优分离超平面,从而把平面上难以区分的非线性数据分开。
常见的核函数有线性核函数、多线性核函数、高斯核函数、指数核函数、拉普拉斯核函数、sigmoid核函数。
3.案例实践-信用卡欺诈交易数据预测
利用网格搜索,获取最优参数
#支持向量机
from sklearn.svm import SVC
def svc_gs(x_train, y_train):
svc_param = {
'C':[0.01, 0.1, 0.5, 0.7, 0.9, 1],
'kernel':['rbf', 'poly', 'sigmoid','linear']
}
svc_gs = GridSearchCV(SVC(), param_grid = svc_param, n_jobs=1, scoring='accuracy')
svc_gs.fit(x_train, y_train)
svc_estimators = svc_gs.best_estimator_
return svc_estimators
svc_gs(x_us_train, y_us_train)
网格搜索结果表明,C取值0.01、使用线性核函数时,模型分类效果较好。
模型训练
#模型训练
svc1 = SVC(C = 0.01, kernel='linear')
svc = svc1.fit(x_us_train, y_us_train)
模型评估
#模型评估
from sklearn.metrics import precision_recall_fscore_support
from sklearn.metrics import accuracy_score
y_us_pre = svc.predict(x_us_test)
#准确率
accuracy = accuracy_score(y_us_test, y_us_pre)
#精确度、召回率、f1_score
precision, recall, f1_score,_ = precision_recall_fscore_support(y_us_test, y_us_pre)
print('accuracy:', accuracy)
print('precision:', precision)
print('recall:', recall)
print('f1_score:',f1_score)
绘制混淆矩阵
#绘制混淆矩阵
import itertools
def plot_confusion_matrix(cm,
classes,
title = 'Confusion matric',
cmap = plt.cm.Blues):
plt.imshow(cm, interpolation='nearest', cmap=cmap)
plt.title(title)
plt.colorbar()
tick_marks = np.arange(len(classes))
plt.xticks(tick_marks, classes, rotation = 0)
plt.yticks(tick_marks, classes)
thresh = cm.max()/2
for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
plt.text(j ,i, cm[i, j],
horizontalalignment="center",
color = 'white' if cm[i, j] > thresh else 'black')
plt.tight_layout()
plt.ylabel('True label')
plt.xlabel('Predicted label')
#下采样新数据的测试集混淆矩阵
cnf_matrix_ustest = confusion_matrix(y_us_test, y_us_pre)
print("Recall metric in the us_test_dataset: {}%".format(100*cnf_matrix_ustest[1,1]/(cnf_matrix_ustest[1,0]+cnf_matrix_ustest[1,1])))
class_names = [0, 1]
plt.figure()
plot_confusion_matrix(cnf_matrix_ustest,class_names, title = 'Confusion matrix')
plt.show()
ROC曲线
#ROC曲线
from sklearn.metrics import roc_auc_score
fpr, tpr, thresholds = roc_curve(y_us_test, y_us_pre)
roc_auc = roc_auc_score(y_us_test, y_us_pre)
plt.title('Receiver Operating Chararcteristic')
plt.plot(fpr, tpr, 'b', label = 'AUC = %0.3f'% roc_auc)
plt.legend(loc = 'lower right')
plt.plot([0, 1], [0, 1], 'r--')
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.show()
ROC曲线显示,支持向量机对信用卡欺诈交易数据分类模型的AUC值为0.911,模型分类效果有待提升。
参考资料:
https://www.cnblogs.com/liuxiaochong/p/14269313.html;
https://www.cnblogs.com/pinard/p/6097604.html。