极客时间已完结课程限时免费阅读

23丨SVM(下):如何进行乳腺癌检测?

23丨SVM(下):如何进行乳腺癌检测?-极客时间

23丨SVM(下):如何进行乳腺癌检测?

讲述:陈旸

时长10:21大小23.71M

讲完了 SVM 的原理之后,今天我来带你进行 SVM 的实战。
在此之前我们先来回顾一下 SVM 的相关知识点。SVM 是有监督的学习模型,我们需要事先对数据打上分类标签,通过求解最大分类间隔来求解二分类问题。如果要求解多分类问题,可以将多个二分类器组合起来形成一个多分类器。
上一节中讲到了硬间隔、软间隔、非线性 SVM,以及分类间隔的公式,你可能会觉得比较抽象。这节课,我们会在实际使用中,讲解对工具的使用,以及相关参数的含义。

如何在 sklearn 中使用 SVM

在 Python 的 sklearn 工具包中有 SVM 算法,首先需要引用工具包:
from sklearn import svm
SVM 既可以做回归,也可以做分类器。
当用 SVM 做回归的时候,我们可以使用 SVR 或 LinearSVR。SVR 的英文是 Support Vector Regression。这篇文章只讲分类,这里只是简单地提一下。
当做分类器的时候,我们使用的是 SVC 或者 LinearSVC。SVC 的英文是 Support Vector Classification。
我简单说一下这两者之前的差别。
从名字上你能看出 LinearSVC 是个线性分类器,用于处理线性可分的数据,只能使用线性核函数。上一节,我讲到 SVM 是通过核函数将样本从原始空间映射到一个更高维的特质空间中,这样就使得样本在新的空间中线性可分。
如果是针对非线性的数据,需要用到 SVC。在 SVC 中,我们既可以使用到线性核函数(进行线性划分),也能使用高维的核函数(进行非线性划分)。
如何创建一个 SVM 分类器呢?
我们首先使用 SVC 的构造函数:model = svm.SVC(kernel=‘rbf’, C=1.0, gamma=‘auto’),这里有三个重要的参数 kernel、C 和 gamma。
kernel 代表核函数的选择,它有四种选择,只不过默认是 rbf,即高斯核函数。
linear:线性核函数
poly:多项式核函数
rbf:高斯核函数(默认)
sigmoid:sigmoid 核函数
这四种函数代表不同的映射方式,你可能会问,在实际工作中,如何选择这 4 种核函数呢?我来给你解释一下:
线性核函数,是在数据线性可分的情况下使用的,运算速度快,效果好。不足在于它不能处理线性不可分的数据。
多项式核函数可以将数据从低维空间映射到高维空间,但参数比较多,计算量大。
高斯核函数同样可以将样本映射到高维空间,但相比于多项式核函数来说所需的参数比较少,通常性能不错,所以是默认使用的核函数。
了解深度学习的同学应该知道 sigmoid 经常用在神经网络的映射中。因此当选用 sigmoid 核函数时,SVM 实现的是多层神经网络。
上面介绍的 4 种核函数,除了第一种线性核函数外,其余 3 种都可以处理线性不可分的数据。
参数 C 代表目标函数的惩罚系数,惩罚系数指的是分错样本时的惩罚程度,默认情况下为 1.0。当 C 越大的时候,分类器的准确性越高,但同样容错率会越低,泛化能力会变差。相反,C 越小,泛化能力越强,但是准确性会降低。
参数 gamma 代表核函数的系数,默认为样本特征数的倒数,即 gamma = 1 / n_features。
在创建 SVM 分类器之后,就可以输入训练集对它进行训练。我们使用 model.fit(train_X,train_y),传入训练集中的特征值矩阵 train_X 和分类标识 train_y。特征值矩阵就是我们在特征选择后抽取的特征值矩阵(当然你也可以用全部数据作为特征值矩阵);分类标识就是人工事先针对每个样本标识的分类结果。这样模型会自动进行分类器的训练。我们可以使用 prediction=model.predict(test_X) 来对结果进行预测,传入测试集中的样本特征矩阵 test_X,可以得到测试集的预测分类结果 prediction。
同样我们也可以创建线性 SVM 分类器,使用 model=svm.LinearSVC()。在 LinearSVC 中没有 kernel 这个参数,限制我们只能使用线性核函数。由于 LinearSVC 对线性分类做了优化,对于数据量大的线性可分问题,使用 LinearSVC 的效率要高于 SVC。
如果你不知道数据集是否为线性,可以直接使用 SVC 类创建 SVM 分类器。
在训练和预测中,LinearSVC 和 SVC 一样,都是使用 model.fit(train_X,train_y) 和 model.predict(test_X)。

如何用 SVM 进行乳腺癌检测

在了解了如何创建和使用 SVM 分类器后,我们来看一个实际的项目,数据集来自美国威斯康星州的乳腺癌诊断数据集,点击这里进行下载
医疗人员采集了患者乳腺肿块经过细针穿刺 (FNA) 后的数字化图像,并且对这些数字图像进行了特征提取,这些特征可以描述图像中的细胞核呈现。肿瘤可以分成良性和恶性。部分数据截屏如下所示:
数据表一共包括了 32 个字段,代表的含义如下:
上面的表格中,mean 代表平均值,se 代表标准差,worst 代表最大值(3 个最大值的平均值)。每张图像都计算了相应的特征,得出了这 30 个特征值(不包括 ID 字段和分类标识结果字段 diagnosis),实际上是 10 个特征值(radius、texture、perimeter、area、smoothness、compactness、concavity、concave points、symmetry 和 fractal_dimension_mean)的 3 个维度,平均、标准差和最大值。这些特征值都保留了 4 位数字。字段中没有缺失的值。在 569 个患者中,一共有 357 个是良性,212 个是恶性。
好了,我们的目标是生成一个乳腺癌诊断的 SVM 分类器,并计算这个分类器的准确率。首先设定项目的执行流程:
首先我们需要加载数据源;
在准备阶段,需要对加载的数据源进行探索,查看样本特征和特征值,这个过程你也可以使用数据可视化,它可以方便我们对数据及数据之间的关系进一步加深了解。然后按照“完全合一”的准则来评估数据的质量,如果数据质量不高就需要做数据清洗。数据清洗之后,你可以做特征选择,方便后续的模型训练;
在分类阶段,选择核函数进行训练,如果不知道数据是否为线性,可以考虑使用 SVC(kernel=‘rbf’) ,也就是高斯核函数的 SVM 分类器。然后对训练好的模型用测试集进行评估。
按照上面的流程,我们来编写下代码,加载数据并对数据做部分的探索:
# 加载数据集,你需要把数据放到目录中
data = pd.read_csv("./data.csv")
# 数据探索
# 因为数据集中列比较多,我们需要把dataframe中的列全部显示出来
pd.set_option('display.max_columns', None)
print(data.columns)
print(data.head(5))
print(data.describe())
这是部分的运行结果,完整结果你可以自己跑一下。
Index(['id', 'diagnosis', 'radius_mean', 'texture_mean', 'perimeter_mean',
'area_mean', 'smoothness_mean', 'compactness_mean', 'concavity_mean',
'concave points_mean', 'symmetry_mean', 'fractal_dimension_mean',
'radius_se', 'texture_se', 'perimeter_se', 'area_se', 'smoothness_se',
'compactness_se', 'concavity_se', 'concave points_se', 'symmetry_se',
'fractal_dimension_se', 'radius_worst', 'texture_worst',
'perimeter_worst', 'area_worst', 'smoothness_worst',
'compactness_worst', 'concavity_worst', 'concave points_worst',
'symmetry_worst', 'fractal_dimension_worst'],
dtype='object')
id diagnosis radius_mean texture_mean perimeter_mean area_mean \
0 842302 M 17.99 10.38 122.80 1001.0
1 842517 M 20.57 17.77 132.90 1326.0
2 84300903 M 19.69 21.25 130.00 1203.0
3 84348301 M 11.42 20.38 77.58 386.1
4 84358402 M 20.29 14.34 135.10 1297.0
接下来,我们就要对数据进行清洗了。
运行结果中,你能看到 32 个字段里,id 是没有实际含义的,可以去掉。diagnosis 字段的取值为 B 或者 M,我们可以用 0 和 1 来替代。另外其余的 30 个字段,其实可以分成三组字段,下划线后面的 mean、se 和 worst 代表了每组字段不同的度量方式,分别是平均值、标准差和最大值。
# 将特征字段分成3组
features_mean= list(data.columns[2:12])
features_se= list(data.columns[12:22])
features_worst=list(data.columns[22:32])
# 数据清洗
# ID列没有用,删除该列
data.drop("id",axis=1,inplace=True)
# 将B良性替换为0,M恶性替换为1
data['diagnosis']=data['diagnosis'].map({'M':1,'B':0})
然后我们要做特征字段的筛选,首先需要观察下 features_mean 各变量之间的关系,这里我们可以用 DataFrame 的 corr() 函数,然后用热力图帮我们可视化呈现。同样,我们也会看整体良性、恶性肿瘤的诊断情况。
# 将肿瘤诊断结果可视化
sns.countplot(data['diagnosis'],label="Count")
plt.show()
# 用热力图呈现features_mean字段之间的相关性
corr = data[features_mean].corr()
plt.figure(figsize=(14,14))
# annot=True显示每个方格的数据
sns.heatmap(corr, annot=True)
plt.show()
这是运行的结果:
热力图中对角线上的为单变量自身的相关系数是 1。颜色越浅代表相关性越大。所以你能看出来 radius_mean、perimeter_mean 和 area_mean 相关性非常大,compactness_mean、concavity_mean、concave_points_mean 这三个字段也是相关的,因此我们可以取其中的一个作为代表。
那么如何进行特征选择呢?
特征选择的目的是降维,用少量的特征代表数据的特性,这样也可以增强分类器的泛化能力,避免数据过拟合。
我们能看到 mean、se 和 worst 这三组特征是对同一组内容的不同度量方式,我们可以保留 mean 这组特征,在特征选择中忽略掉 se 和 worst。同时我们能看到 mean 这组特征中,radius_mean、perimeter_mean、area_mean 这三个属性相关性大,compactness_mean、daconcavity_mean、concave points_mean 这三个属性相关性大。我们分别从这 2 类中选择 1 个属性作为代表,比如 radius_mean 和 compactness_mean。
这样我们就可以把原来的 10 个属性缩减为 6 个属性,代码如下:
# 特征选择
features_remain = ['radius_mean','texture_mean', 'smoothness_mean','compactness_mean','symmetry_mean', 'fractal_dimension_mean']
对特征进行选择之后,我们就可以准备训练集和测试集:
# 抽取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[features_remain]
train_y=train['diagnosis']
test_X= test[features_remain]
test_y =test['diagnosis']
在训练之前,我们需要对数据进行规范化,这样让数据同在同一个量级上,避免因为维度问题造成数据误差:
# 采用Z-Score规范化数据,保证每个特征维度的数据均值为0,方差为1
ss = StandardScaler()
train_X = ss.fit_transform(train_X)
test_X = ss.transform(test_X)
最后我们可以让 SVM 做训练和预测了:
# 创建SVM分类器
model = svm.SVC()
# 用训练集做训练
model.fit(train_X,train_y)
# 用测试集做预测
prediction=model.predict(test_X)
print('准确率: ', metrics.accuracy_score(test_y,prediction))
运行结果:
准确率: 0.9181286549707602
准确率大于 90%,说明训练结果还不错。完整的代码你可以从GitHub上下载。

总结

今天我带你一起做了乳腺癌诊断分类的 SVM 实战,从这个过程中你应该能体会出来整个执行的流程,包括数据加载、数据探索、数据清洗、特征选择、SVM 训练和结果评估等环节。
sklearn 已经为我们提供了很好的工具,对上节课中讲到的 SVM 的创建和训练都进行了封装,让我们无需关心中间的运算细节。但正因为这样,我们更需要对每个流程熟练掌握,通过实战项目训练数据化思维和对数据的敏感度。
最后给你留两道思考题吧。还是这个乳腺癌诊断的数据,请你用 LinearSVC,选取全部的特征(除了 ID 以外)作为训练数据,看下你的分类器能得到多少的准确度呢?另外你对 sklearn 中 SVM 使用又有什么样的体会呢?
欢迎在评论区与我分享你的答案,也欢迎点击“请朋友读”,把这篇文章分享给你的朋友或者同事,一起来交流,一起来进步。
分享给需要的人,Ta购买本课程,你将得18
生成海报并分享

赞 16

提建议

上一篇
22丨SVM(上):如何用一根棍子将蓝红两色球分开?
下一篇
24丨KNN(上):如何根据打斗和接吻次数来划分电影类型?
unpreview
 写留言

精选留言(41)

  • Geek_dancer
    2019-02-27
    默认SVC训练模型,6个特征变量,训练集准确率:96.0%,测试集准确率:92.4% 默认SVC训练模型,10个特征变量,训练集准确率:98.7% ,测试集准确率:98.2% LinearSVC训练模型, 6个特征变量, 训练集准确率:93.9%,测试集准确率:92.3% LinearSVC训练模型, 10个特征变量, 训练集准确率:99.4%,测试集准确率:96.0% 结论: 1. 增加特征变量可以提高准确率,可能是因为模型维度变高,模型变得更加复杂。可以看出特征变量的选取很重要。 2. 训练集拟合都比较好,但是测试集准确率出现不同程度的下降。 3. 模型训练的准确率与人类水平之间偏差可以通过增加特征变量或采用新的训练模型来降低;模型训练的准确率与测试集测试的准确率之间的方差可以通过正则化,提高泛化性能等方式来降低。
    展开

    编辑回复: 赞下,不光做了练习,还做了分析总结。

    共 2 条评论
    45
  • reverse
    2019-03-06
    极客时间数据分析实战45讲的详细笔记(包含markdown、图片、思维导图 代码) github地址: https://github.com/xiaomiwujiecao/DataAnalysisInAction
    共 2 条评论
    31
  • 2019-04-18
    利用SVM做分类,特征选择影响度大,要想SVM分类准确,人工处理数据这一步很重要

    编辑回复: 对的 特征选择,以及数据的处理都很重要。选择不同的特征,有时候比选择不同的分类算法更重要。

    13
  • hlz-123
    2019-03-16
    首先要说,老师的课讲得非常好,深奥的算法和理论通过生动有趣的例子让人通俗易懂,兴趣盎然。 老师的本课案例中,对特征数据都做了Z-Score规范化处理(正态分布),准确率在90%以上,如果数据不做规范化处理,准确率在88%左右,我的问题: 1、数据规范化处理,是不是人为地提供了准确率?实际情况,数据不一定是正态分布。 2、模型建好后,在实际应用中去评估某个案例时,该案例数据是不是也要规范化,这样做是不是很麻烦并且数据对比不是很直观呢?
    展开

    编辑回复: 1、首先需要理解数据规范化的意义,当我们在做数据挖掘之前,不同的指标可能具有不同的量纲,如果我们不消除这些指标之间的取值范围差别,以及不同量纲所造成的影响的话,就会影响到后续数据分析(分类、聚类等)的结果。因此我们需要进行规范化处理,也就是让数据按照一定的标准落入到一个特定的区间内,便于我们后续分析使用。 2、在做处理的时候,训练集和测试集都需要进行数据规范化,其实在代码上并不麻烦,而且这么做属于数据挖掘前的一项基础工作。

    10
  • mickey
    2019-02-26
    # encoding=utf-8 from sklearn import svm from sklearn import metrics from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler import pandas as pd import seaborn as sns import matplotlib.pyplot as plt # 加载数据集,你需要把数据放到目录中 data = pd.read_csv("./data.csv") # 数据探索 # 因为数据集中列比较多,我们需要把dataframe中的列全部显示出来 pd.set_option('display.max_columns', None) #print(data.columns) #print(data.head(5)) #print(data.describe()) # 将特征字段分成3组 features_mean= list(data.columns[2:12]) features_se= list(data.columns[12:22]) features_worst=list(data.columns[22:32]) # 数据清洗 # ID列没有用,删除该列 data.drop("id",axis=1,inplace=True) # 将B良性替换为0,M恶性替换为1 data['diagnosis']=data['diagnosis'].map({'M': 1, 'B': 0}) # 特征选择 features_remain = ['radius_mean', 'texture_mean', 'perimeter_mean', 'area_mean', 'smoothness_mean', 'compactness_mean', 'concavity_mean', 'concave points_mean', 'symmetry_mean', 'fractal_dimension_mean', 'radius_se', 'texture_se', 'perimeter_se', 'area_se', 'smoothness_se', 'compactness_se', 'concavity_se', 'concave points_se', 'symmetry_se', 'fractal_dimension_se', 'radius_worst', 'texture_worst', 'perimeter_worst', 'area_worst', 'smoothness_worst', 'compactness_worst', 'concavity_worst', 'concave points_worst', 'symmetry_worst', 'fractal_dimension_worst'] # 抽取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[features_remain] train_y=train['diagnosis'] test_X= test[features_remain] test_y =test['diagnosis'] # 采用Z-Score规范化数据,保证每个特征维度的数据均值为0,方差为1 ss = StandardScaler() train_X = ss.fit_transform(train_X) test_X = ss.transform(test_X) # 创建SVM分类器 model = svm.LinearSVC() # 用训练集做训练 model.fit(train_X,train_y) # 用测试集做预测 prediction=model.predict(test_X) print('准确率: ', metrics.accuracy_score(prediction,test_y)) 准确率: 0.9707602339181286
    展开
    共 1 条评论
    7
  • Rickie
    2019-02-05
    思考题: 使用全部数据进行训练得到的准确率为0.9766,高于示例中的准确率。是否是由于多重共线性,使得测试结果偏高?

    编辑回复: 如果选择全部的特征,一是运算量大,二是可能会过于拟合,造成实验中的准确率高,但是在实际工作中可能会存在偏差。

    7
  • 明翼
    2019-11-10
    老师我利用了结果和特征的相关性,选择特征,发现结果更好: # 特征选择 按照结果和数据相关性选择特征准确率0.9707602339181286 features_remain = ['radius_mean','perimeter_mean','area_mean','concave points_mean','radius_worst','perimeter_worst','area_worst','concave points_worst']

    作者回复: 不错的分享,从EDA中找到特征的关系,大家都可以看下

    共 3 条评论
    4
  • Ricky
    2020-04-15
    谢谢,提2个问题, 1)在实际应用中如何平衡特征变量和准确率的关系?有没有方法论? 增加特征变量意味着增加运算时间,提高准确率,但是这个得失怎么把握?同时如何评估会增加多少运算时间,一个一个尝试似乎比较费劲吧 2)此文的案例是选用平均值,丢弃了最大值和标准差,这个是多少案例的通用做法么? 谢谢
    展开

    作者回复: 问题1: 确实没有定论。在日常业务场景中,按对任务目标的理解,把相关的特征的数据拉齐后建模,再筛减特征提高准确率。在比赛中,由于对该业务不一定十分了解,那么久需要做各种特征工程的尝试,如:特征提取、特征转换、特征组合等等,同学可以多看看kaggle比赛的高分开源notebook。 问题2:老师这里进行了简化,实际你可以对data.corr()相关系数进行热力图展示,和目标值diagnosis低相关性的特征常会被舍弃,比如se的特征;另外当几个特征之间相关性非常强趋近于1时,常称之为多重共线性,对于存在多重共线性的特征,常只保留其中一个特征。当然做特征选择时,还有其他工具,比如:PCA、低方差分析等,老师这里只展示了相关系数可视化后进行特征选择的方法。

    2
  • 恬恬
    2020-03-31
    对比几组feature后,发现用feature_worst进行训练,效果更好。 1)SVC(kernel='linear')的测试集准确率为:99.42%; 2) LinearSVC()的测试集准确率为:97.07% 2)SVC()的测试集准确率为:96.49% 觉得建模过程中,特征选择很重要,不同的数据集划分,正负样本是否平衡也会对结果有一定的影响,所以最好是可以采用交叉验证来训练模型。这个地方多次测试SVC(kernel='linear')和LinearSVC(),感觉还是会存在2个百分点左右的差异,这两个都算是线性分类,是因为采用了不同的线性核函数吗?还是其他参数或是方法差异的原因呢?
    展开

    作者回复: SVC(kernel='linear')和LinearSVC()使用的都是线性核。 默认情况下,LinearSVC最小化squared hinge loss,而SVC最小化hinge loss。LinearSVC基于liblinear实现,事实上会惩罚截距(penalize the intercept), 然而,SVC是基于libsvm实现的,并不会惩罚截距。

    共 2 条评论
    2
  • Ronnyz
    2019-11-14
    选取全部特征: SVM分类器准确率: 0.9824561403508771 cross_val_score的准确率为:0.9727 linearSVM分类器的准确率: 0.9766081871345029 cross_val_score的准确率为:0.9652 选取mean相关特征: SVM分类器准确率: 0.9239766081871345 cross_val_score的准确率为:0.9321 linearSVM分类器的准确率: 0.9298245614035088 cross_val_score的准确率为:0.9247 数据结果上看: SVM的结果要好于linearSVM; 选取多特征的结果要好于选取少特征的结果
    展开

    作者回复: 对 一般是这个规律,具体还是要看数据集的分布情况,所以不同的模型之间没有绝对好坏之分,和数据集也有关系

    1
  • 2019-04-18
    语言Python3.6 没有z-score规范化数据以及规范化后两种情况前提预测准确率,使用LinearSVC,选取所有mean属性 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 #导入数据 path = '/Users/apple/Desktop/GitHubProject/Read mark/数据分析/geekTime/data/' data = pd.read_csv(path + 'breast_cancer/data.csv') #数据探索 pd.set_option('display.max_columns', None) print(data.columns) print(data.head(5)) print(data.describe()) #将特征字段进行分组 features_mean = list(data.columns[2:12]) features_se = list(data.columns[12:22]) features_worst = list(data.columns[22:32]) #数据清洗 #删除ID列 data.drop('id',axis=1,inplace=True) #将良性B替换为0,将恶性替换为1 data['diagnosis'] = data['diagnosis'].map({'B':0,'M':1}) #将肿瘤诊断结果可视化 sns.countplot(data['diagnosis'],label='count') plt.show() #计算相关系数 corr = data[features_mean].corr() plt.figure(figsize=(14,14)) #用热力图呈现相关性,显示每个方格的数据 sns.heatmap(corr,annot=True) plt.show() #特征选择,选择所有的mean数据 feature_remain = ['radius_mean', 'texture_mean', 'perimeter_mean', 'area_mean', 'smoothness_mean', 'compactness_mean', 'concavity_mean', 'concave points_mean', 'symmetry_mean', 'fractal_dimension_mean'] #抽取30%特征选择作为测试数据,其余作为训练集 train,test = train_test_split(data,test_size=0.3) #抽取特征选择作为训练和测试数据 train_data = train[feature_remain] train_result = train['diagnosis'] test_data = test[feature_remain] test_result = test['diagnosis'] #创建SVM分类器 model = svm.LinearSVC() #用训练集做训练 model.fit(train_data,train_result) #用测试集做预测 prediction = model.predict(test_data) #准确率 print('准确率:', metrics.accuracy_score(prediction,test_result)) #规范化数据,再预估准确率 z_score = StandardScaler() train_data = z_score.fit_transform(train_data) test_data = z_score.transform(test_data) #用新数据做训练 new_model = svm.LinearSVC() new_model.fit(train_data,train_result) #重新预测 new_prediction = new_model.predict(test_data) #准确率 print('准确率:',metrics.accuracy_score(new_prediction,test_result))
    展开

    作者回复: Good Job 滢

    1
  • 三硝基甲苯
    2019-03-10
    用K折交叉验证,LinearSVC的准确率是92.64% SVC是92.98% 至于SVC的使用,我一开始直接按照自己的想法写完以后,会有聚合警告,然后看了一下,是数据没有进行StandardScaler,我觉得这个步骤容易忘记。
    1
  • third
    2019-02-18
    第二个,准确率 0.935672514619883。 感觉还蛮好用的,只是不是很熟练的使用各个算法做分类和回归

    编辑回复: 挺好的,慢慢来,做的多了就好了!

    1
  • Python
    2019-02-04
    老师可以用PCA进行特征选择吗?如果可以,那和你这种手动的方法比有什么差别

    作者回复: 可以用PCA做特征选择,PCA相当于是降维工具,手动的可解释性会比较强

    1
  • 方志刚
    2022-11-25 来自广东
    为何执行多次程序,没有任何改动,但是精确率每次都会发生变化
  • Soul of the Drago...
    2021-04-19
    本人在思考题的基础上,进行了进一步的探索。使用features_se和features_worst的数据,分别采用SVC和LinearSVC建模进行训练。将不同样本训练的准确率进行比较后,得出以下结论: 1. 从模型选择上看,使用SVC模型训练的准确率总体要高于LinearSVC; 2. 从样本数量上来看,除features_worst数据集外,选择全样本训练的准确率要高于选择筛选特征后样本的准确率; 3. 从数据集的比较来看,选择features_worst数据集进行训练的准确率在三个数据集中总体是最高的。
    展开
  • 晨曦
    2021-01-23
    老师,如果这个病症改为不得病,轻症,重症三个分类,不是二分类问题,对应改成分类序号,0,1,2。那么这套算法是不是也不算错

    作者回复: SVM也是支持多分类的

  • McKee Chen
    2020-12-18
    学习过程中遇到以下两个问题: 1.随机划分不同的训练集训练出来的模型最后得出来的准确率是不一样的,有95%的准确率,也有97%的准确率,等等,这种情况下是要不断训练模型,直到观察到最高的准确率,然后选用该模型吗?还是随意选择一个模型,只要准确率够高就行? 2.准确率高等价于预测效果精度高吗? #用 LinearSVC,选取全部的特征(除了 ID 以外)作为训练数据,查看分类器的准确度 import pandas as pd import seaborn as sns from sklearn.preprocessing import StandardScaler from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score #数据加载 data = pd.read_csv(r'C:\Users\chentaoyu\Desktop\breast_cancer_data&codes\data.csv') #数据探索 pd.set_option('display.max_columns', None)#显示全部列,不隐藏中间列 # print(data.info())#说明各特征没有缺失值 # print(data.head())#列出前五行 # print(data.columns)#看出所有特征名 # print(data.tail())#列出后五行 #数据清洗 data.drop('id',axis=1,inplace=True)#舍去ID列 data['diagnosis'] = data['diagnosis'].map({'B':0, 'M':1})#将诊断特征中的结果数据化 #选取全部的特征值进行训练,选30%为测试数据,其余为训练数据 features = data[list(data.columns[1:31])] test = data['diagnosis'] train_X, test_X, train_y, test_y = train_test_split(features, test ,test_size=0.3) #对数据进行规范化,避免因数据量级不同造成误差 train_X = StandardScaler().fit_transform(train_X) test_X = StandardScaler().fit_transform(test_X) #创建SVM分类器 from sklearn import svm linear_svc = svm.LinearSVC() linear_svc.fit(train_X, train_y) #输入测试值,通过该模型预测测试结果 prediction = linear_svc.predict(test_X) print('准确率: ', accuracy_score(test_y, prediction)) #输出结果 准确率: 0.9766081871345029
    展开
  • 非同凡想
    2020-11-22
    import seaborn as sns import matplotlib.pyplot as plt from sklearn import svm from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.metrics import accuracy_score import pandas as pd df = pd.read_csv('~/Documents/breast_cancer_data/data.csv') print(df.info()) features = df.columns[2:] #features = ['radius_mean','texture_mean', 'smoothness_mean','compactness_mean','symmetry_mean', 'fractal_dimension_mean'] # 将B良性替换为0,M恶性替换为1 df['diagnosis'] = df['diagnosis'].map({'M':1,'B':0}) train , test = train_test_split(df, test_size=0.3) train_x = train[features] train_y = train['diagnosis'] test_x = test[features] test_y = test['diagnosis'] ##z_score标准化数据 ss = StandardScaler() train_x = ss.fit_transform(train_x) test_x = ss.transform(test_x) model = svm.LinearSVC() model.fit(train_x, train_y) prediction = model.predict(test_x) print('accuracy : %f',accuracy_score(prediction, test_y)) ## SVC 30个特征值 准确度为:98 % ## SVC 6个特征值 准确度为:92 % ## LinearSVC 30个特征值 准确度为:97 % ## LinearSVC 6个特征值 准确度为:92 %
    展开
  • 邹洲
    2020-08-26
    # coding=utf-8 import pandas as pd import seaborn as sns import matplotlib.pyplot as plt from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler #导入sklearn中的SVM库 from sklearn import svm, metrics #构造线性分类模型 model = svm.SVC(kernel="rbf",C=1.0,gamma="auto") model2 = svm.LinearSVC() """ kernel : linear:线性模型,当模型为linearsvm时,就表明没有kernel参数 poly:多项式模型 rbf:高斯函数 sigmoid:sigmoid核函数 C:目标函数的惩罚系数 gamma :核函数系数 """ #实战开始--加载数据 data = pd.read_csv('data.csv',engine='python') # pd.set_option('display.max_columns',None) #查看一下数据信息 # print(data.columns) # print(data.info()) # print(data.head(5)) # print(data['diagnosis'].value_counts()) #数据处理 #id字段对于分类无用,删除即可 data.drop('id',axis=1,inplace=True) #diagnosis字段为字符型,组需转换为数值型0 1 data['diagnosis'] = data['diagnosis'].map({'M':1,'B':0}) feature_mean = data.columns[1:11] feature_se = data.columns[11:21] feature_max = data.columns[21:31] #统计一下肿瘤人数情况 sns.countplot(data['diagnosis'],label='Count') # plt.show() #查看各个特征的相关度 corr = data[feature_mean].corr() plt.figure(figsize=(14,14)) sns.heatmap(corr,annot=True) # plt.show() feature_sel = ['radius_mean','texture_mean','smoothness_mean','compactness_mean','symmetry_mean','fractal_dimension_mean'] train_data,test_data = train_test_split(data,test_size=0.3) train_feature = train_data[feature_sel] train_label = train_data['diagnosis'] test_feature = test_data[feature_sel] test_label = test_data['diagnosis'] #开始训练数据和测试数据 #采用Z-Score规范化处理,保证每一个特征维度的数据均值为0,方差为1 ss = StandardScaler() train_feature = ss.fit_transform(train_feature) test_feature = ss.transform(test_feature) #开始预测 model.fit(train_feature,train_label) model2.fit(train_feature,train_label) predict_label = model.predict(test_feature) predict_label2 = model2.predict(test_feature) #准确度 -- 每次运行不一样 print("高斯准确率:",metrics.accuracy_score(test_label,predict_label)) print("线性准确度:",metrics.accuracy_score(test_label,predict_label2))
    展开

    作者回复: 之所以每次运行不一样,是因为拆分数据集的方法train_test_split()每次会随机拆分数据集;可以通过它的参数random_state指定一个整数作为随机数种子,可以保证每次运行拆分得到的都是同样的数据集。