机器学习第8章------集成学习
- 8.集成学习
-
- 8.1个体与集成
- [8.2 Boosting](#8.2 Boosting)
- [8.3 Bagging与随机森林](#8.3 Bagging与随机森林)
- [8.4 AdaBoost实现](#8.4 AdaBoost实现)
- [8.5 随机森林实现------宫颈癌分类](#8.5 随机森林实现——宫颈癌分类)
8.集成学习
8.1个体与集成
集成学习是现在非常火爆的机器学习方法。它本身不是一个单独的机器学习算法,而是通过构建并结合多个机器学习器来完成学习任务。集成学习可以用于分类问题集成,回归问题集成,特征选取集成,异常点检测集成等等。
定义:集成学习是使用一系列学习器进行学习,并使用某种规则把各个学习结果进行整合从而获得比单个学习器更好的学习效果的一种机器学习方法。
如果把单个分类器比作一个决策者的话,集成学习的方法就相当于多个决策者共同进行一项决策。
-
在概率近似正确(PAC)学习的框架中,一个概念(一个类),如果存在一个多项式的学习算法能够学习它,
- 如果正确率很高,那么就称这个概念是强可学习的。
- 如果正确率不高,仅仅比随机猜测略好,那么就称这个概念是弱可学习的。
-
后来证明强可学习与弱可学习是等价的
弱分类器之间的关系
- 第一种就是所有的个体学习器都是一个种类的,或者说是同质的。比如说都是决策树个体学习器,或者都是神经网络个体学习器
- 第二种是所有的个体学习器不全是一个种类的,或者说是异质的。比如我们有个分类问题,对训练集采用支持向量机个体学习器,逻辑回归个体学习器和朴素贝叶斯个体学习器来学习,再通过某种结合策略来确定最终的分类强学习器。
- 目前而言,同质个体学习器应用最广泛,一般我们常说的集成学习的方法都是指的同质个体学习器。而同质个体学习器使用最多的模型是CART决策树和神经网络。
- 同质个体学习器按照个体学习器之间是否存在依赖关系可以分为两类
- 第一个是个体学习器之间存在强依赖关系,一系列个体学习器基本都需要串行 生成,代表算法是
boosting 系列算法- 串行:下一个分类器只在前一个分类器预测不够准的实例上进行训练或检验。
- 第二个是个体学习器之间不存在强依赖关系,一系列个体学习器可以并行 生成,代表算法是bagging 和随机森林系列算法。
- 并行:所有的弱分类器都给出各自的预测结果,通过组合把这些预测结果转化为最终结果。
- 第一个是个体学习器之间存在强依赖关系,一系列个体学习器基本都需要串行 生成,代表算法是
组合时,如何选择学习器
-
需要考虑准确性和多样性
- 准确性指的是个体学习器不能太差,要有一定的准确度
- 多样性则是个体学习器之间的输出要具有差异性
怎么组合弱分类器
-
平均法:对于数值类的回归预测问题
-
思想:对于若干个弱学习器的输出进行平均得到最终的预测输出
-
简单平均法
H ( x ) = 1 T ∑ i = 1 T h i ( x ) H(x)=\frac{1}{T}\sum_{i=1}^Th_i(x) H(x)=T1i=1∑Thi(x) -
加权平均法
H ( x ) = ∑ i = 1 T w i h i ( x ) w i 是个体学习器 h i 的权重 , ∑ i = 1 T w i = 1 H(x)=\sum_{i=1}^Tw_ih_i(x)\\ w_i是个体学习器h_i的权重,\sum_{i=1}^Tw_i=1 H(x)=i=1∑Twihi(x)wi是个体学习器hi的权重,i=1∑Twi=1
-
-
投票法:对于分类问题的预测
- 思想:多个基本分类器都进行分类预测,然后根据分类结果用某种投票的原则进行投票表决,按照投票原则使用不同投票法。(一票否决,一致表决,少数服从多数、阈值表决)
- 阈值表决:首先统计出把实例x划分为Ci和不划分为Ci的分类器数目分别是多少,然后当这两者比例超过某个阈值的时候把x划分到Ci。
- 思想:多个基本分类器都进行分类预测,然后根据分类结果用某种投票的原则进行投票表决,按照投票原则使用不同投票法。(一票否决,一致表决,少数服从多数、阈值表决)
-
学习法:以上两种方法可能会使学习误差较大
- 思想:不是对弱学习器的结果做简单的逻辑处理,而是再加上一层学习器 ,分为2层。
第一层是用不同的算法形成T个弱分类器,同时产生一个与原数据集大小相同的新数据集,利用这个新数据集和一个新算法构成第二层的分类器。(方法:Stacking)
- 思想:不是对弱学习器的结果做简单的逻辑处理,而是再加上一层学习器 ,分为2层。
boosting和Bagging
-
boosting
- 重赋权法:即在训练过程的每一轮中,根据样本分布为每一个训练样本重新赋予一个权重。对无法接受带权样本的基学习算法,则可以通过重采样法来处理,即在每一轮的学习中,根据样本分布对训练集重新进行采样,在用重采样而来的样本集对基学习器进行训练。
-
Bagging
- 从样本集中用Bootstrap(有放回)采样选出n个样本
- 在所有属性上,对这n个样本建立分类器
- 重复以上两步m次,建立了m个分类器
- 将数据放在这m个分类器上跑,最后投票看到底分到哪一类
- Bootstrap方法是非常有用的一种统计学上的估计方法。Bootstrap是对观测信息进行再抽样,进而对总体的分布特性进行统计推断。Bootstrap是一种有放回的重复抽样方法,抽样策略就是简单的随机抽样。
bagging | boosting | |
---|---|---|
取样方式 | bagging采用均匀取样(bootstrap) | boosting根据错误率来采样 |
精度、准确性(二者比较) | 较低 | 较高 |
训练集选择 | 随机的,各轮训练集之前互相独立 | 各轮训练集的选择与前面各轮的学习结果相关 |
预测函数权重 | 各个预测函数没有权重 | boost有权重 |
函数生成顺序 | 并行生成 | 顺序生成 |
应用 | 像神经网络 这样极为消耗时间的算法,bagging可通过并行节省大量的时间开销 bagging和boosting都可以有效地提高分类的准确性 | bagging和boosting都可以有效地提高分类的准确性 一些模型中会造成模型的退化(过拟合) boosting思想的一种改进型AdaBoost方法再邮件过滤、文本分类中有很好的性能 |
随机森林 | 梯度提升树 | |
主要是降低方差 度量了同样大小的数据集的变动所导致的学习性能的变化。刻画了数据扰动所造成的影响 随机选择部分样本来训练处理不同的模型,再综合来减小方差 bagging是对许多强的分类器求平均 | 主要降低偏差 偏差刻画了学习算法本身的拟合能力 对判断错误的样本不停的加大权重,为了更好地拟合当前数据,所以降低了偏差,因为boosting能基于泛化性能相当弱的学习器构建出很强的集成 boosting是把许多弱的分类器组合成一个强的分类器 |
8.2 Boosting
-
弱学习机:对一定分布的训练样本给出假设(仅仅强于随机猜测),例如只根据有云猜测可能会下雨
-
强学习机:根据得到的弱学习机和相应的权重给出假设(最大程度上符合实际情况),根据CNN,ABC,CBS以往的预测表现及实际天气情况作出综合准确的天气预测
-
实现步骤
- ①.原始训练集输入,带有原始分布
- ②.给出训练集中各样本的权重
- ③.将改变分布后的训练集输入已知的弱学习机,弱学习机对每个样本给出假设
- ④.对此次的弱学习机给出权重
- ⑤.转到②,直到循环到达一定次数或者某度量标准符合要求
- ⑥.将弱学习机按其相应的权重加权组合形成强学习机
-
样本的权重
- 没有先验知识的情况下,初始的分布应为等概分布,也就是训练集如果有N个样本,每个样本的分布概率为1/N
- 每次循环一后提高错误样本的分布概率,分错样本在训练集中所占权重增大,使得下一次循环的弱学习机能够集中力量对这些错误样本进行判断。
-
弱学习机的权重
- 准确率越高的弱学习机权重越高
-
循环控制:损失函数达到最小
- 在强学习机的组合中增加一个加权的弱学习机,使准确率提高,损失函数值减小。
-
算法描述
-
训练集
{ ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . , ( x N , y N ) } x i ∈ R m , y i ∈ { − 1 , + 1 } \{(x_1,y_1),(x_2,y_2),...,(x_N,y_N)\}\\ x_i\in R^m,y_i\in\{-1,+1\} {(x1,y1),(x2,y2),...,(xN,yN)}xi∈Rm,yi∈{−1,+1} -
D t D_t Dt
为第t次循环时的训练样本分布(每个样本在训练集中所占的概率,总和应该为1)
-
h t : X → { − 1 , + 1 } h_t:X→\{-1,+1\} ht:X→{−1,+1}
为第t次循环时的弱学习器,对每个样本给出相应的假设,应该满足强于随机猜测:
P ( x , y ) ∈ D t [ y = h t ( x ) ] > 1 2 + ε P_{(x,y)\in D_t}[y=h_t(x)]>\frac{1}{2}+\varepsilon P(x,y)∈Dt[y=ht(x)]>21+ε -
w t 为 h t 的权重 H t ( X i ) = s i g n ( ∑ i = 1 t w i h t ( X i ) ) w_t为h_t的权重 H_t(X_i)=sign(\sum_{i=1}^tw_ih_t(X_i))\\ wt为ht的权重Ht(Xi)=sign(i=1∑twiht(Xi))
为t次循环得到的强学习器
-
-
弱学习器权重
-
思想:错误率越低,该学习机的权重应该越大
-
ε t = P ( x , y ) ∈ D t [ t ≠ h t ( x ) ] \varepsilon_t=P_{(x,y)\in D_t}[t\neq h_t(x)] εt=P(x,y)∈Dt[t=ht(x)]
为学习机的错误概率
-
采用的函数形式和指数函数相呼应
w t = 1 2 l n ( 1 − ε t ε t ) w_t=\frac{1}{2}ln\bigg(\frac{1-\varepsilon_t}{\varepsilon_t}\bigg) wt=21ln(εt1−εt)
-
AdaBoost
AdaBoost是一种迭代算法,其核心思想是针对同一个训练集训练不同的分类器(弱分类器),然后把这些弱分类器集合起构成一个强分类器。
-
对于boosting算法,存在两个问题
-
如何调整训练集,使得在训练集上训练的弱分类器得以进行,即
B o o s t i n g 并没有说明 D t → D t + 1 的具体实现 Boosting并没有说明D_t→D_{t+1}的具体实现 Boosting并没有说明Dt→Dt+1的具体实现 -
如何将训练得到的各个弱分类器联合起来形成强分类器,即
B o o s t i n g 并没有说明 w t 的具体实现 Boosting并没有说明w_t的具体实现 Boosting并没有说明wt的具体实现
-
-
针对以上两个问题,AdaBoost算法进行了调整
- 使用加权后选取的训练数据代替随机选取的训练样本,这样将训练的焦点集中在比较难分的训练数据样本上
- 将弱分类器联合起来,使用加权的投票机制代替平均投票机制。让分类效果好的弱分类器具有较大的权重,而分类效果差的分类器具有较小的权重。
算法步骤
- 给定训练样本集s,其中x和Y分别对应于正例样本和负例样本;T为训练的最大循环次数
- 初始化样本权重为1/D,即为训练样本的初始概率分布;
- 第一次迭代:
- (1)训练样本的概率分布相当,训练弱分类器
- ⑵计算弱分类器的错误率
- (3)选取合适阙值,使得误差最小
- (4)更新样本权重;
经T次循环后,得到T个弱分类器,按更新的权重叠加,最终得到的强分类器。
训练过程
-
初始化
训练样本 x i , 权重 D 1 ( i ) , i = 1 , . . . , N 训练样本x_i,权重D_1(i),i=1,...,N 训练样本xi,权重D1(i),i=1,...,N-
若正负样本数目一致,则
D 1 ( i ) = 1 N D_1(i)=\frac{1}{N} D1(i)=N1 -
若正负样本数目不一致
正样本数 : N + , 负样本数 : N − 正样本数:N_+,负样本数:N_- 正样本数:N+,负样本数:N−则
正样本 : D 1 ( i ) = 1 2 N + 负样本 : D 1 ( i ) = 1 2 N − 正样本:D_1(i)=\frac{1}{2N_+}\\ 负样本:D_1(i)=\frac{1}{2N_-} 正样本:D1(i)=2N+1负样本:D1(i)=2N−1
-
-
for m=1,...,M
-
训练弱分类器
f m ( x ) = L ( D , D m ) ∈ { − 1 , + 1 } f_m(x)=L(D,D_m)\in\{-1,+1\} fm(x)=L(D,Dm)∈{−1,+1} -
估计弱分类器的分类错误率
e m = 1 2 ∑ i = 1 N D m ( i ) ∣ f m ( x i ) − y i ∣ e m < 0.5 e_m=\frac{1}{2}\sum_{i=1}^ND_m(i)|f_m(x_i)-y_i|\quad e_m<0.5 em=21i=1∑NDm(i)∣fm(xi)−yi∣em<0.5 -
估计弱分类器的权重
α m = log 1 − e m e m \alpha_m=\log\frac{1-e_m}{e_m} αm=logem1−em -
基于弱分类器调整各样本权重,并归一化
-
调整
D m + 1 ( i ) = D m ( i ) exp ( α m ⋅ 1 ( f m ( x i ) ≠ y i ) ) = { D m ( i ) , 若 f m ( x i ) = y i D m ( i ) ⋅ 1 − e m e m , 若 f m ( x i ) ≠ y i D_{m+1}(i)=D_m(i)\exp(\alpha_m\cdot1_{(f_m(x_i)\neq y_i)})\\ = \begin{cases} D_m(i), & 若f_m(x_i)=y_i \\ D_m(i)\cdot\frac{1-e_m}{e_m}, & 若f_m(x_i)\neq y_i \\ \end{cases} Dm+1(i)=Dm(i)exp(αm⋅1(fm(xi)=yi))={Dm(i),Dm(i)⋅em1−em,若fm(xi)=yi若fm(xi)=yi -
归一化
D m + 1 ( i ) ← D m + 1 ( i ) ∑ j = 1 N D m + 1 ( j ) , i = 1 , . . . , N D_{m+1}(i)←\frac{D_{m+1}(i)}{\sum_{j=1}^ND_{m+1}(j)},i=1,...,N Dm+1(i)←∑j=1NDm+1(j)Dm+1(i),i=1,...,N
-
-
-
强分类器
H ( x ) = s i g n [ ∑ m = 1 M α m f m ( x ) ] H(x)=sign\big[\sum_{m=1}^M\alpha_mf_m(x)\big] H(x)=sign[m=1∑Mαmfm(x)]
8.3 Bagging与随机森林
随机采样(bootstrap)
随机采样就是从我们的训练集里面采集固定个数的样本,但是每采集一个样本后,都将样本放回。也就是说,之前采集到的样本在放回后有可能继续被采集到。对于我们的Bagging算法,一般会随机采集和训练集样本数m ---样
个数的样本。这样得到的采样集和训练集样本的个数相同,但是样本内容不同。如果我们对有m个样本训练集做Ⅰ次的随机采样,则由于随机性,T个采样集各不相同。
-
对于一个样本,它在某一次含m个样本的训练集的随机采样中,每次被采集到的概率是
1 m \frac{1}{m} m1不被采集到的概率为
1 − 1 m 1-\frac{1}{m} 1−m1如果m次采样都没有被采集中的概率是
( 1 − 1 m ) m (1-\frac{1}{m})^m (1−m1)m当m趋于无穷时
lim m − > + ∞ ( 1 − 1 m ) m → = 1 e ≈ 0.368 \lim_{m->+\infty}(1-\frac{1}{m})^m→=\frac{1}{e}≈0.368 m−>+∞lim(1−m1)m→=e1≈0.368也就是说,在bagging的每轮随机采样中,训练集中大约有36.8%的数据没有被采样集采集中。
-
对于这部分大约36.8%的没有被采样到的数据,我们常常称之为袋外数据(OOB)。这些数据没有参与训练集模型的拟合,因此可以用来检测模型的泛化能力。
弱学习器
最常用的弱学习器为决策树和神经网络
结合策略
- 分类问题,通常使用简单投票法,得到最多票数的类别或者类别之一为最终的模型输出。
- 回归问题,通常使用简单平均法,对T个弱学习器得到的回归结果进行算术平均得到最终的模型输出。
方差与偏差
- Bagging每次都进行采样来训练模型
- 因此泛化能力很强,对于降低模型的方差很有作用。
- 对于训练集的拟合程度差一些,模型的偏倚会大一些。
算法流程
-
输入
样本集 : D = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . , ( x m , y m ) } 弱学习器算法 : ξ 弱分类器迭代次数 : T 样本集:D=\{(x_1,y_1),(x_2,y_2),... ,(x_m,y_m)\}\\ 弱学习器算法:\xi\\ 弱分类器迭代次数:T 样本集:D={(x1,y1),(x2,y2),...,(xm,ym)}弱学习器算法:ξ弱分类器迭代次数:T -
输出
强分类器 : f ( x ) 强分类器:f(x) 强分类器:f(x) -
过程:
-
①.对于t = 1,2,... ,T:
-
对训练集进行第t次随机采样,共采集m次,得到包含m个样本的采样集
D t D_t Dt -
用采样集训练第t个弱学习器
G t ( x ) = ξ ( D t ) G_t(x)=\xi(D_t) Gt(x)=ξ(Dt)
-
-
②.如果是分类算法预测,则T个弱学习器投出最多票数的类别或者类别之一为最终类别。如果是回归算法,T个弱学习器得到的回归结果进行算术平均得到的值为最终的模型输出。
-
随机森林
-
随机森林(RF)是Bagging算法的扩展变体
- RF使用了CART决策树作为弱学习器
- RF改进了CART决策树的构建过程:
- 普通的决策树,在节点上所有的n个样本特征中选择一个最优的特征来做决策树的左右子树划分
- RF通过随机选择节点上的一部分样本特征,这个数字小于n,假设为k,然后在这些随机选择的k个样本特征中,选择一个最优的特征来做决策树的左右子树划分
- 这样进一步增强了模型的泛化能力
-
算法流程
-
输入
样本集 : D = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . , ( x m , y m ) } 弱学习器算法 : ξ 弱分类器迭代次数 : T 样本集:D=\{(x_1,y_1),(x_2,y_2),...,(x_m,y_m)\}\\ 弱学习器算法:\xi\\ 弱分类器迭代次数:T 样本集:D={(x1,y1),(x2,y2),...,(xm,ym)}弱学习器算法:ξ弱分类器迭代次数:T -
输出:强分类器
f ( x ) f(x) f(x) -
过程:
-
①.对于t = 1,2,... ,T:
-
对训练集进行第t次随机采样,共采集m次,得到包含m个样本的采样集
D t D_t Dt -
用采样集训练第t个弱学习器
G t ( x ) = ξ ( D t ) G_t(x)=\xi(D_t) Gt(x)=ξ(Dt)训练决策树模型的节点时,在节点上所有的样本特征中选择一部分样本特征,在这些随机选择的部分样本特征中选择一个最优的特征来做决策树的左右子树划分
-
-
②.如果是分类算法预测,则T个弱学习器投出最多票数的类别或者类别之一为最终类别。如果是回归算法,T个弱学习器得到的回归结果进行算术平均得到的值为最终的模型输出。
-
-
8.4 AdaBoost实现
python
import numpy as np
import matplotlib.pyplot as plt
from sklearn.ensemble import AdaBoostClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import make_gaussian_quantiles #高斯分布数据集
- 创建数据
python
#用make_gaussian_quantiles生成分组多维正态分布的数据。
#关健参数有n_samples(生成样本数),n_features(正态分布的维数),mean(特征均值)
#cov(样本协方差的系数),mean(均值),n_classes(数据在正态分布中按分位数分配的组数)
X1,y1 = make_gaussian_quantiles(cov=2.,
n_samples=200,n_features=2,
n_classes=2,random_state=1)
X2,y2 = make_gaussian_quantiles(mean=(3,3),cov=1.5,
n_samples=300,n_features=2,
n_classes=2,random_state=1)
plt.scatter(X1[:,0],X1[:,1],marker='o',c=y1)
plt.scatter(X2[:,0],X2[:,1],marker='o',c=y2)
- 数组拼接
python
#默认axios=0
X = np.concatenate((X1,X2))
y = np.concatenate((y1,-y2+1))#把另一组高斯分布的点正负对调,增加分类器难度
print(np.shape(X1),np.shape(X2),np.shape(X))
print(np.shape(y1),np.shape(y2),np.shape(y))
plt.scatter(X[:,0],X[:,1],marker='o',c=y)
- AdaBoost
python
#algorithm有两个可选择参数SAMME和SAMME.R。两者的主要区别是弱学习器权重的度量,SAMME使用了和我们的原理篇里二元分类Adaboost算法的扩展,
#即用对样本集分类效果作为弱学习器权重,而SAMME.R使用了对样本集分类的预测概率大小来作为弱学习器权重。
#由于SAMME.R使用了概率度量的连续值,迭代一般比SAMME快,因此AdaBoostClassifier的默认算法algorithm的值也是SAMME.R
#max_depth:最大深度为1,也就是说只有一次分叉
#n_estimators:进行迭代的次数
bdt=AdaBoostClassifier(DecisionTreeClassifier(max_depth=1),
algorithm="SAMME",
n_estimators=200)
bdt.fit(X,y)
plot_colors="br"
plot_step=0.02
class_names="AB"
plt.figure(figsize=(10,5))
x_min,x_max=X[:,0].min()-1,X[:,0].max()+1
y_min,y_max=X[:,1].min()-1,X[:,1].max()+1
xx,yy=np.meshgrid(np.arange(x_min,x_max,plot_step),
np.arange(y_min,y_max,plot_step))
## ravel()和flatten()函数,将多维数组降为一维,ravel返回视图,flatten返回拷贝
#np.r_是按列连接两个矩阵,就是把两矩阵上下相加,要求列数相等,类似子pandas中的concat()
#np.c_是按行连接两个矩阵,就是把两矩阵左右相加,要求行数相等,类似于pandas中的merge()。
Z=bdt.predict(np.c_[xx.ravel(),yy.ravel()])
Z=Z.reshape(xx.shape)
cs=plt.contourf(xx,yy,Z,cmap=plt.cm.Paired)
plt.axis("tight")
#到这儿生成的只是分类面
# Plot the training points
for i,n,c in zip(range(2),class_names,plot_colors):
idx = np.where(y == i)
plt.scatter(X[idx,0],X[idx,1],
c=c,cmap=plt.cm.Paired,
s=20,edgecolor='k',
label="Class %s"%n)# s size of point
plt.xlim(x_min,x_max)
plt.ylim(y_min,y_max)
plt.legend(loc='upper right')
plt.xlabel('x')
plt.ylabel('y')
plt.title('Decision Boundary')
8.5 随机森林实现------宫颈癌分类
python
from sklearn import tree
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.model_selection import GridSearchCV
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import MinMaxScaler
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import label_binarize
from sklearn.decomposition import PCA
from sklearn import metrics
import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
#解决中文显示问题
mpl.rcParams['font.sans-serif']=[u'simHei']
mpl.rcParams['axes.unicode_minus']=False
- 导入数据
python
# 前面u是避免乱码问题
names=[u'Age',u'Number of sexual partners',u'First sexual intercourse',
u'Num of pregnancies',u'Smokes', u'Smokes (years)',
u'Smokes (packs/year)',u'Hormonal Contraceptives',
u'Hormonal Contraceptives (years)',u'IUD',u'IUD (years)',u'STDs',
u'STDs (number)',u'STDs:condylomatosis',
u'STDs:cervical condylomatosis',u'STDs:vaginal condylomatosis',
u'STDs:vulvo-perineal condylomatosis',u'STDs:syphilis',
u'STDs:pelvic inflammatory disease',u'STDs:genital herpes',
u'STDs:molluscum contagiosum',u'STDs:AIDS',u'STDs:HIV',
u'STDs:Hepatitis B',u'STDs:HPV',u'STDs: Number of diagnosis',
u'STDs: Time since last diagnosis',u'STDs: Time since last diagnosis',
u'Dx:Cancer',u'Dx:CIN',u'Dx:HPV',u'Dx',u'Hinselmann',u'Schiller',
u'Citology',u'Biopsy'] #df.columns
path="risk_factors_cervical_cancer.csv" #数据文件路径
data=pd.read_csv(path)
print(type(data))
- 数据分割和异常值处理
python
#数据分割
X=data[names[0:-4]]#从第1列到倒数第4列(不包括倒数第4列)
Y=data[names[-4:]]
#异常值处理
X = X.replace("?",np.NAN)
# print(X)
imp = SimpleImputer(missing_values=np.nan, strategy='mean')
X = imp.fit_transform(X,Y)
# print(X)
- 数据集分割
python
# test_size:设置测试集大小为20%
x_train,x_test,y_train,y_test = train_test_split(X,Y,test_size=0.2,random_state=0)
print("训练样本数量:%d,特征属性数目:%d,目标属性数目:%d"\
%(X_train.shape[0],X_train.shape[1],y_train.shape[1]))
print ("测试样本数量:%d" % X_test.shape[0])
- 数据标准化和降维
python
# 数据标准化
ss = MinMaxScaler() # 分类模型,经常使用的是minmaxscaler归一化,回归模型经常用standardscaler
x_train = ss.fit_transform(x_train,y_train)
x_test = ss.transform(x_test)
#降维
pca=PCA(n_components=2)
x_train=pca.fit_transform(x_train)
x_test=pca.transform(x_test)
- 随机森林模型、模型效果评估和模型预测
python
# 随机森林模型
#max_depth:一般不宜设置过大,将每一个模型设置为一个弱分类器
forest = RandomForestClassifier(n_estimators=100,criterion="gini",max_depth=1,random_state=0)
forest.fit(x_train,y_train)
# 模型效果评估
score = forest.score(x_test, y_test)
print("准确率:%.2f%%" %(score * 100))
#模型预测(返回测试集中每个测试样例,分类为每个类的概率)
forest_y_score = forest.predict_proba(x_test)# prodict_proba输出概率
# print(forest_y_score)
- 计算ROC值和AUC值
python
#计算ROC值
#ravel将多维数组降为一维
forest_fpr1,forest_tpr1,thresholds1 = metrics.roc_curve(label_binarize(y_test[names[-4]],classes=(0,1,2)).T[0:-1].T.ravel(),forest_y_score[0].ravel())
forest_fpr2,forest_tpr2,thresholds2 = metrics.roc_curve(label_binarize(y_test[names[-3]],classes=(0,1,2)).T[0:-1].T.ravel(), forest_y_score[1].ravel())
forest_fpr3,forest_tpr3,thresholds3 = metrics.roc_curve(label_binarize(y_test[names[-2]],classes=(0,1,2)).T[0:-1].T.ravel(), forest_y_score[2].ravel())
forest_fpr4,forest_tpr4,thresholds4 = metrics.roc_curve(label_binarize(y_test[names[-1]],classes=(0,1,2)).T[0:-1].T.ravel(), forest_y_score[3].ravel())
# AUC值
auc1 = metrics.auc(forest_fpr1, forest_tpr1)
auc2 = metrics.auc(forest_fpr2, forest_tpr2)
auc3 = metrics.auc(forest_fpr3, forest_tpr3)
auc4 = metrics.auc(forest_fpr4, forest_tpr4)
print ("Hinselmann目标属性AUC值:%.2f"%auc1)
print ("Schiller目标属性AUC值:%.2f"%auc2)
print ("Citology目标属性AUC值:%.2f"%auc3)
print ("Biopsy目标属性AUC值:%.2f"%auc4)
- 绘图
python
# 画图(ROC图)
plt.figure(figsize=(8,6),facecolor='w')
plt.plot(forest_fpr1,forest_tpr1,c='r',lw=2,label=u'Hinselmann目标属性,AUC=%.3f' % auc1)
plt.plot(forest_fpr2,forest_tpr2,c='b',lw=2,label=u'Schiller目标属性,AUC=%.3f' % auc2)
plt.plot(forest_fpr3,forest_tpr3,c='g',lw=2,label=u'Citology目标属性,AUC=%.3f' % auc3)
plt.plot(forest_fpr4,forest_tpr4,c='y',lw=2,label=u'Biopsy目标属性,AUC=%.3f' % auc4)
plt.plot((0,1),(0,1),c='#a0a0a0',lw=2,ls='--')
plt.xlim(-0.001, 1.001)
plt.ylim(-0.001, 1.001)
plt.xticks(np.arange(0, 1.1, 0.1))
plt.yticks(np.arange(0, 1.1, 0.1))
plt.xlabel('False Positive Rate(FPR)', fontsize=16)
plt.ylabel('True Positive Rate(TPR)', fontsize=16)
plt.grid(True, ls=':')
plt.legend(loc='lower right', fancybox=True, framealpha=0.8, fontsize=12)
plt.title(u'随机森林多目标属性分类ROC曲线', fontsize=18)
plt.show()
从图中可以看出Hinselmann优化效果是相对比较好的