大纲
算法背景
SVM(支持向量机)是在样本数据空间中找到一个超平面将不同类别的样本进行分割。划分的方式有很多,为了提高模型的泛化能力和鲁棒性,应尽量选择具有最大分类间隔的分割超平面,分类间隔可以理解为样本点到分割超平面的距离(实质为点到平面的距离公式—高中几何知识)
按照svm的演化路线,可分为3个方向:(1,2处理线性可分的数据情况,3处理线性不可分的情况)
1.硬间隔:严格不允许分类错误,有时候因为数据噪声的影响使得所能找到的最大间距很小,模型泛化能力差
2.软间隔:允许一定的分类错误,避免数据过拟合
3.引入核函数:样本数据线性不可分时,利用核函数将当前维的数据映射到更高维的空间中以实现对样本数据的线性划分。
常用的核函数有:
线性核、多项式核、高斯径向核、sigmoid核或者这些核函数的组合
二分类向多分类问题的推广
1.one VS one
比较常用的是一对一方法,举例:如果要对ABC三类进行分类,则需要训练C(3,2)=3个分类器,分别为:A对B,A对C,B对C。做预测时把样本输入到三个分类器进行分类投票,某一个类别的票数最多就将其归到某一类中。不足之处是若类别数过多,则需要构建的分类器也会很多(相比于第二种方法),但出现新的类别数据时,只需要构建新的分类器,而不用改变已训练好的。
2.one VS rest
另一种方法是一对多,举例:还是对ABC三类分类,则需要训练3个分类器,分别为:A对B+C、B对A+C、C对A+B,存在的一个问题是正负样本数量可能会不对称,且如果数据集中出现了新的类别数据,前面训练好的模型可能要重新训练。
乳腺癌数据挖掘实战
导入相关库:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings("ignore")
from sklearn.svm import SVC,LinearSVC
from sklearn import metrics
pd.set_option('display.max_columns', None)
医疗人员采集了患者乳腺肿块经过细针穿刺后的数字化图像,并且对图像进行了特征提取,数据展示如下:(详情参见GitHub链接)
data = pd.read_csv("data.csv",engine="python")
print(data.shape)
data.head()
其中,id是对分类没有作用的可以剔除,diagnosis是要预测的类别特征(M-恶性;B-良性),其他30个特征实质上是radius,texture,perimeter,area,smoothness,compactness,concavity,concave points,symmetry和fractak_dimension_mean 10个特征的3个维度(mean,se,wrost)
对三类特征分组(_mean、_se、_wrost):
features_mean,features_se,features_worst =[],[],[]
for feat in data.columns:
if "mean" in feat:
features_mean.append(feat)
elif "se" in feat:
features_se.append(feat)
elif "worst" in feat:
features_worst.append(feat)
对三组特征分别可视化相关系数(热力图):
mean_corr = data[features_mean].corr()
plt.figure(figsize=(8,8))
sns.heatmap(mean_corr,annot=True)
plt.show()
se_corr = data[features_se].corr()
plt.figure(figsize=(8,8))
sns.heatmap(se_corr,annot=True)
plt.show()
worst_corr = data[features_worst].corr()
plt.figure(figsize=(8,8))
sns.heatmap(worst_corr,annot=True)
plt.show()
特征选择:
通过热力图可以看出,这三组变量的模式/关系实际上是很接近的,我们就选取第一组mean的特征进行分析,根据相关系数从10个特征中又可以筛选出其中没那么相关的6个特征,以实现维度规约。
#三组属性极其相似,只保留一组,并根据相关性选取6个特征
shaixuan_feature_mean = ['radius_mean','texture_mean','smoothness_mean','compactness_mean','symmetry_mean','fractal_dimension_mean']
x_data= data[shaixuan_feature_mean]
提取目标变量并编码
y_data = data["diagnosis"]
del data["diagnosis"]
del data["id"]
y_data = y_data.map({'M':0,'B':1})
我们观察发现,数据中的量纲是不同的,如有些特征的取值上到了1000+,而有的特征取值只有0.XXX,因此数据分析前可以先进行标准化(StandardScaler)
from sklearn.preprocessing import StandardScaler
x_data = StandardScaler().fit_transform(x_data)
模型训练和评估
from sklearn.model_selection import train_test_split,cross_val_score
x_train,x_test,y_train,y_test = train_test_split(x_data,y_data,test_size=0.33)
svc_model = SVC().fit(x_train,y_train)
print("svc分类准确率为:",metrics.accuracy_score(svc_model.predict(x_test),y_test))
print(metrics.classification_report(svc_model.predict(x_test),y_test))
最后补充一点:使用所有的数据进行分析的结果反倒不如规约筛选后的模型效果。
小结:本实验完成了《数据分析实战45讲》中支持向量机部分的理论与实战部分,支持向量机SVM涉及到的数学公式、推导很多,有KKT条件,拉格朗日乘法、SMO算法等等,具体流程可以看看B站上浙大的一门相关课程,老师做了很详细的推导(除了具体的SMO求解过程)。另外,实战时,使用svm需要调节的参数一共有三个:核函数的选择(rbf,ploy,sigmoid,linear),惩罚系数C,gamma值(rbf公式中的一个超参数)。最后的补充,还发现数据并不一定是越多越好的,规约后的数据一样能达到甚至超过原有的数据一样的分析效果。