机器学习(12)——随机森林

前言:前面已经介绍了的几种算法,应该对算法有了一个基本的认识了,本章主要是在前面已经学到的基础上,对前面的算法模型进行整合操作,训练出效果更好的分类器模型。

集成学习

集成学习的思想是将若干个学习器(分类器&回归器)组合之后产生一个新学习器。弱分类器( weak learner)指那些分类准确率只稍微好于随机猜测的分类器( errorrate<0.5);集成算法的成功在于保证弱分类器的多样性( Diversity)。而且集成不稳定的算法也能够得到一个比较明显的性能提升。
常见的集成学习思想有:
(1)投票选举(bagging: 自举汇聚法 bootstrap aggregating): 是基于数据随机重抽样分类器构造的方法
(2)再学习(boosting): 是基于所有分类器的加权求和的方法
对于不同的数据进行不同的集成算法的构建,大致来说可以分为以下四种情况:
(1)弱分类器间存在一定的差异性,这会导致分类的边界不同,也就是说可能存在错误。那么将多个弱分类器合并后,就可以得到更加合理的边界,减少整体的错率,实现更好的效果;
(2)对于数据集过大或者过小,可以分别进行划分和有放回的操作产生不同的数据子集,然后使用数据子集训练不同的分类器,最终再合并成为一个大的分类器;
(3)如果数据的划分边界过于复杂,使用线性模型很难描述情况,那么可以训练多个模型,然后再进行模型的融合;
(4)对于多个异构的特征集的时候,很难进行融合,那么可以考虑每个数据集构建一个分类模型,然后将多个模型融合。
例如下图,是构建三个不同的分类器,在做一个合并。


随机森林

随机森林是在 Bagging策略的基础上进行修改后的一种算法。那随机森林具体如何构建呢?,所谓的随机森林,重点要理解“随机”这两个关键字,表现为以下两个方面:

(1)数据的随机性化

(2)待选特征的随机化

使得随机森林中的决策树都能够彼此不同,提升系统的多样性,从而提升分类性能。数据的随机化:使得随机森林中的决策树更普遍化一点,适合更多的场景。

构建流程

采取有放回的抽样方式 构造子数据集,保证不同子集之间的数量级一样(不同子集/同一子集 之间的元素可以重复)

利用子数据集来构建子决策树,将这个数据放到每个子决策树中,每个子决策树输出一个结果。

然后统计子决策树的投票结果,得到最终的分类 就是 随机森林的输出结果。

具体构建过程如下:

(1)从样本集中用 Bootstrap采样选出n个样本;

(2)从所有属性中随机选择K个属性,选择出最佳分割属性作为节点创建决策树

(3)重复以上两步m次,即建立m棵决策树

(4)这m个决策树形成随机森林,通过投票表决结果决定数据属于那一类

注意:(有放回的准确率在:70% 以上, 无放回的准确率在:60% 以上)

如下图,假设随机森林中有3棵子决策树,2棵子树的分类结果是A类,1棵子树的分类结果是B类,那么随机森林的分类结果就是A类。

image.png

待选特征的随机化过程

(1)子树从所有的待选特征中随机选取一定的特征。

(2)在选取的特征中选取最优的特征。

下图中,蓝色的方块代表所有可以被选择的特征,也就是目前的待选特征;黄色的方块是分裂特征。 左边是一棵决策树的特征选取过程,通过在待选特征中选取最优的分裂特征完成分裂。 右边是一个随机森林中的子树的特征选取过程。

image.png

随机森林推广算法

算法总结

RF的主要优点

1.训练可以并行化,对于大规模样本的训练具有速度的优势;

2.由于进行随机选择决策树划分特征列表,这样在样本维度比较高的时候,仍然具有比较高的训练性能;

3.给以给出各个特征的重要性列表;

4.由于存在随机抽样,训练出来的模型方差小,泛化能力强;

5.RF实现简单;

6.对于部分特征的缺失不敏感。

RF的主要缺点:

1..在某些噪音比较大的特征上,RF模型容易陷入过拟;

2.取值比较多的划分特征对RF的决策会产生更大的影响,从而有可能影响模型的效果;

示例:乳腺癌预测

在现实生活中,机器学习的应用非常广泛,在医学方面也发挥着非常重要的作用,下面就以一个宫颈癌预测的例子来简要说明一下随机森林算法的思想。

比如,小明的妈妈感觉身体非常不好,医生通过询问和调查,收集和小明妈妈的很多数据,比如年龄,工作,是否抽烟等等,把这些数据输入计算机,计算机就会给一个患有某种病的概率,医生则可以根据这个概率做出疾病的最终结果,例如把这些数据输入一个患有乳腺癌的模型,可如何构建这个模型呢?这是我们应该关注的问题。构建此模型的步骤如下:

首先收集数据

这是最基础也是最重要的过程,为了方便,我们直接下载权威结构公开的数据:

下载的地址如下:http://archive.ics.uci.edu/ml/datasets/Cervical+cancer+(Risk+Factors)

然后观察目标属性和特征特征属性如下:

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 first 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'

最后就是建立模型,建立模型的步骤如下:

  1. 导入模块。
#导入我们要用的包,包括算法数据导入模块,算法评估模块,算法模块,以及画图模块。

最后要画roc和auc曲线图,因而导入相应的画图包。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
from sklearn import tree
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler,Imputer,LabelBinarizer

from sklearn import metrics#参数,roc和auc
from sklearn.preprocessing import label_binarize#二值化
mpl.rcParams['font.sans-serif'] = [u'SimHei']
mpl.rcParams['axes.unicode_minus'] = False
  1. 导入数据
#这里的导入数据就是导入刚刚下载的数据

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 first 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="datas/risk_factors_cervical_cancer.csv"
df = pd.read_csv(path)
print(df.shape)

查看数据,查看一下总的数据

print(df.shape)

 输出结果如下:

(858, 36)
  1. 建划分数据集
#.划分测试集合训练集

x=df.iloc[:,0:-4]
y=df.iloc[:,-4:]

x=x.replace("?", np.NAN)
#通过平局值来替换nan
imputer=Imputer(missing_values="NaN")
x=imputer.fit_transform(x,y)

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]))

输出的结果如下:

训练样本数量:686,特征属性数目:32,目标属性数目:4
  1. 模型构建和预测:
ss = MinMaxScaler()
x_train = ss.fit_transform(x_train)
x_test = ss.transform(x_test)

rf = RandomForestClassifier(n_estimators=50,criterion="gini",max_depth=1,random_state=10)
rf.fit(x_train,y_train)

score = rf.score(x_test,y_test)
  1. 模型的评估
print("准确率:%.2f%%"%(score*100))
forest_y_score = rf.predict_proba(x_test)
# print(forest_y_score)
#计算roc和auc
forest_fpr1, forest_tpr1, _ = 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, _ = 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, _ = 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, _ = 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值:", auc1)
print ("Schiller目标属性AUC值:", auc2)
print ("Citology目标属性AUC值:", auc3)
print ("Biopsy目标属性AUC值:", auc4)

输出的结果为:

准确率:89.53%

Hinselmann目标属性AUC值: 0.984586262844781

Schiller目标属性AUC值: 0.9629867495943752

Citology目标属性AUC值: 0.9453082747431043

Biopsy目标属性AUC值: 0.9642712276906437
  1. 画auc曲线
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(b=True, ls=':')
plt.legend(loc='lower right', fancybox=True, framealpha=0.8, fontsize=12)
plt.title(u'随机森林多目标属性分类ROC曲线', fontsize=18)
plt.show()

结果如下图所示:

image.png

分析:由于目标属性含有多个,在进行评估的时候应该考虑多个目标属性的影响,从上图看出,模型的整体效果还是挺不错的。

7.比较不同树的数量和不同深度下对模型的影响

# 比较不同树数目、树最大深度的情况下随机森林的正确率
# 一般情况下,初始的随机森林树个数是100,深度1,如果需要我们再进行优化操作
x_train2, x_test2, y_train2, y_test2 = train_test_split(x,y, test_size=0.5, random_state=0)
print("训练样本数量%d,测试样本数量:%d" % (x_train2.shape[0], x_test2.shape[0]))
## 比较
estimators = [1, 50, 100, 500]
depth = [1, 2, 3, 7, 15]
err_list = []
for es in estimators:
       es_list = []
       for d in depth:
              tf = RandomForestClassifier(n_estimators=es, criterion='gini', max_depth=d, max_features=None,
                                          random_state=0)
              tf.fit(x_train2, y_train2)
              st = tf.score(x_test2, y_test2)
              err = 1 - st
              es_list.append(err)
              print("%d决策树数目,%d最大深度,正确率:%.2f%%" % (es, d, st * 100))
       err_list.append(es_list)

## 画图
plt.figure(facecolor='w')
i = 0
colors = ['r', 'b', 'g', 'y']
lw = [1, 2, 4, 3]
max_err = 0
min_err = 100
for es, l in zip(estimators, err_list):
       plt.plot(depth, l, c=colors[i], lw=lw[i], label=u'树数目:%d' % es)
       max_err = max((max(l), max_err))
       min_err = min((min(l), min_err))
       i += 1
plt.xlabel(u'树深度', fontsize=16)
plt.ylabel(u'错误率', fontsize=16)
plt.legend(loc='upper left', fancybox=True, framealpha=0.8, fontsize=12)
plt.grid(True)
plt.xlim(min(depth), max(depth))
plt.ylim(min_err * 0.99, max_err * 1.01)
plt.title(u'随机森林中树数目、深度和错误率的关系图', fontsize=18)
plt.show()

得到的结果如下:

image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容