浅浅聊聊支持向量机

第一次看到SVM还是初次接触到机器学习的时候,感觉这个算法很高级,什么超平面,核函数之类,搞得挺晕乎的,接着又用这个算法,感觉性能比决策树等一般的机器学习算法并没有什么优势,所以也没啥兴趣学这玩意,这次在数据分析实战四十五讲上看到这个算法的讲解,就顺便做个笔记吧,我也只能算粗略地了解下这个算法,所以这篇文章中并没有什么复杂的数学公式推导,这种网上也是一艘一大堆。

概念和基本理解

SVM的英文全称是Support Vector Machines,我们叫它支持向量机。支持向量机是我们用于分类的一种算法,是属于有监督的学习算法。

SVM不光可以处理线性可分的数据,还可以处理非线性可分的数据。所谓的线性可分,就是可以找到一个线,将样本分成两个部分;对于非线性可分的数据,比如在一个平面中红球和白球混在一起,这时候没办法找到直线将样本分开,对于SVM算法来说可以找一个核函数,将数据映射到更高的维度,然后找到超平面将样本分开,就像将平面拍下,让球都弹起来,如果红球和白球的质量不同,则质量轻的弹的更高,这样就可以把两种球找到了。

无法线性可分的

映射到更高维度后可分
分类间隔:如果在二维平面上,划分一条线可以将样本分为两类,如果是多维空句,直线就变成了决策面,这样的直线或决策面不是一个,在平移的时候,可以找到非常靠近两类的极限位置,超过这个位置,就会分类错误,这两个极限位置中间的距离称为分类间隔,中间的分类线就是我们找最优分类决策面。
如果我们在转动最优决策面,可能存在多个最优决策面,我们就找最大分类间隔的决策面,那么最优决策面离两类的距离才最远,这样分类器的泛化能力才最好,因为样品毕竟是这个部分的,不是所有的数据。

支持向量:支持向量是上面说的最靠近两类数据的样本,这些样本数据决定了决策面,其他的样本对结果影响不大。

超平面: 在二维空间分开两类数据是一条线(线性情况下),在三维空间中就是一个平面,维数还可能更多,我们给这个线性的函数起个名字就叫“超平面”。
SVM算法就是去找一个超平面,使用分类间隔的距离最大。
比如下图中,右面的分类间隔更大,显然中间的那条线就是我们要找到的超平面。
支持向量

硬间隔:SVM分类器分的是完全准确的没有错误的。
软间隔:准许存在一定量的样本是分类错误的。

例子

在sklearn中同样有SVM算法的工具包可以使用,SVM既可以做回归,也可以做分类。做回归的时候使用的是SVR或LinearSVR;做分类的时候可以用的是SVC即Support Vector Classification。

model = svm.SVC(kernel='rbf',C=1.0,gamma='auto'

说明:

kernel 表示核函数 取值如下:
linear:线性函数,用于线性可分场景,速度快效果好。
poly:多项式函数, 将数据从低维空间映射到高维度空间,参数多,计算量大。
rbf:高斯核函数(默认),同样将样本映射到高维空间,但是参数少,性能更好。
sigmoid:sigmoid核心函数,此函数通常用在神经网络中,实现的是多层神经网络。

参数C 表示惩罚的系数,C越大,分类错误惩罚越大,数据拟合更好,但是容错性毕竟差。
C越小,泛化能力强,分类准确度不高。

参数gamma表示核函数系数,一般取值为样本数量的倒数。

利用老师课上的例子,数据见链接:https://github.com/cystanford/breast_cancer_data/
探索数据:
数据相关性图
数字越接近1相关性越大,通过相关性视图我们有两种方式来选特征:

  1. 相关性大的特征我们可以选择其中一个代表,其他的删除。
  2. 找和结果值相关性大的特征。

根据上面的相关性分析,我选择了下面的特征:

features_remain = ['radius_mean','perimeter_mean','area_mean','concave points_mean','radius_worst','perimeter_worst','area_worst','concave points_worst']

目前选择是采用第二种方法,如果想进一步减少,还可以分析下这里面的特征的相关性,去掉相关性大的特征。
在原有代码上稍加改动代码示例:

# -*- coding: utf-8 -*-

# -*- coding: utf-8 -*-
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

# 加载数据集,你需要把数据放到目录中
data = pd.read_csv("./data.csv")

# 数据探索
# 因为数据集中列比较多,我们需要把dataframe中的列全部显示出来
##显示所有列
pd.set_option('display.max_columns', None)
#显示所有行 
pd.set_option('display.max_rows',None)

#大概浏览下数据
#print(data.columns)
#print(data.head(5))
#print(data.describe())

features_mean= list(data.columns[1:32])

# 数据清洗
# ID列没有用,删除该列
data.drop("id",axis=1,inplace=True)
# 将B良性替换为0,M恶性替换为1
data['diagnosis']=data['diagnosis'].map({'M':1,'B':0})

# 将肿瘤诊断结果可视化
sns.countplot(data['diagnosis'],label="Count")
plt.show()

'''
参数1:method:可选值为{‘pearson’, ‘kendall’, ‘spearman’}

pearson:Pearson相关系数来衡量两个数据集合是否在一条线上面,即针对线性数据的相关系数计算[默认] 
kendall:用于反映分类变量相关性的指标,即针对无序序列的相关系数,非正太分布的数据
spearman:非线性的,非正太分析的数据的相关系数

参数2:min_periods:样本最少的数据量

返回值:各类型之间的相关系数DataFrame表格。
'''
# 用热力图呈现features_mean字段之间的相关性
corr = data[features_mean].corr(method='kendall',min_periods=1)
print('=========================================')
sorted_features = corr['diagnosis'].sort_values(ascending=False)

plt.figure(figsize=(32,32))
# annot=True显示每个方格的数据
sns.heatmap(corr, annot=True)
plt.show()

print(sorted_features.index)
chose_features = []
#选择相关性最大的top10数据
for i in sorted_features[1:10].index:
    print (i+":"+str(sorted_features[i]))
    chose_features.append(i)
print(chose_features)

利用SVM算法进行训练和预测

# -*- coding: utf-8 -*-
# 乳腺癌诊断分类
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split
from sklearn import svm
from sklearn import metrics
from sklearn.preprocessing import StandardScaler

# 加载数据集,你需要把数据放到目录中
data = pd.read_csv("./data.csv")

# 数据清洗
# ID列没有用,删除该列
data.drop("id",axis=1,inplace=True)
# 将B良性替换为0,M恶性替换为1
data['diagnosis']=data['diagnosis'].map({'M':1,'B':0})

#特征选择
all_mean= list(data.columns[0:32])
corr = data[all_mean].corr(method='pearson')
sorted_features = corr['diagnosis'].sort_values(ascending=False)
chose_features = []
#选择相关性最大的top10数据
feture_num = 10
for i in sorted_features[1:feture_num].index:
    chose_features.append(i)
print(chose_features)

# 抽取30%的数据作为测试集,其余作为训练集
train, test = train_test_split(data, test_size = 0.3)# in this our main data is splitted into train and test
# 抽取特征选择的数值作为训练和测试数据
train_X = train[chose_features]
train_y=train['diagnosis']
test_X= test[chose_features]
test_y =test['diagnosis']

# 采用Z-Score规范化数据,保证每个特征维度的数据均值为0,方差为1
ss = StandardScaler()
train_X = ss.fit_transform(train_X)
test_X = ss.transform(test_X)

# 创建SVM分类器
#0.9707602339181286
#model = svm.LinearSVC()
#0.9532163742690059
#model = svm.SVC(kernel='rbf', degree=2, gamma=1.7)
#0.8187134502923976
#model = svm.SVC(kernel='poly', degree=2, gamma=1.7)
#0.9532163742690059
model = svm.SVC(kernel='linear',gamma = 1/feture_num)
# 用训练集做训练
model.fit(train_X,train_y)
# 用测试集做预测
prediction=model.predict(test_X)
print('准确率: ', metrics.accuracy_score(prediction,test_y))

参考
https://wenku.baidu.com/view/fa8e7f2eccbff121dd368336.html
https://www.cnblogs.com/sharryling/p/9429589.html
https://www.cnblogs.com/sharryling/p/9429589.html
padas 数据相关性解释:https://blog.csdn.net/walking_visitor/article/details/85128461

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值