本文始发于个人公众号:TechFlow,原创不易,求个关注
今天是机器学习专题的第26篇文章,我们一起聊聊另外一个集成学习模型,它就是大名鼎鼎的随机森林。
随机森林在业内名气和使用范围都很广,曾经在许多算法比赛当中拔得头筹。另外,它也是一个通过组合多个弱分类器构建强分类器的经典模型,因此它在业内广受欢迎。
本文基于决策树相关的文章,没有阅读过的同学可以从最上方的专辑查看过往决策树相关的文章。
算法原理
上一篇文章介绍AdaBoost的时候把集成学习的几种思路大概介绍了一遍,集成学习主要是三种方法,Bagging、Boosting和Stacking。AdaBoost属于Boosting,而随机森林则属于Bagging。
Bagging最大的特点就是"民主",其中的思路很容易理解,针对同一份训练数据我们会训练出多个弱分类器来。当面临一个新的样本的时候,由这些分类器聚集在一起进行民主投票,每一个分类器都是平等的,它们的权重一样。最后,根据所有这些弱分类器的结果整合出最后的结果来。比如说我们一共训练了50个弱分类器,在面对一个样本的时候,其中的35个给出类别1,15个给出类别0,那么整个模型的结果就是类别1。
另外一点是,Bagging在训练每一个分类器的时候所使用的数据并不是固定的,而是通过有放回抽样选择出来的。所以样本在训练集中出现的分布也是各不相同的,有些样本可能在同一个分类器中出现了多次,同样也有一些样本没有出现过。单单有样本随机性还是不够的,因为训练样本的分布大体上是差不多的,虽然我们随机采样,也不会使得每一份训练样本会有很大的差距。所以为了保证每个分类器的侧重点不同,拥有更强的随机性,我们还可以从特征入手,限制每个分类器只能随机使用部分特征。这样得到的分类器每一个的特征都各不相同,侧重点也就不同,可以尽可能地增强随机的效果,让模型专注于数据。
随机森林这个模型的名字当中隐藏了两个关键点,分别是随机和森林。随机我们已经解释过了,一方面是每一个分类器样本的随机,另外一个是分类器可以使用的特征的随机。而森林也很好理解,因为我们使用的分类器是决策树,所以多棵决策“树”组成的模型,自然就是森林了。
抓住这两个特征,随机森林很好理解,也很好实现,毕竟决策树模型我们之前已经实现过好几次了。
代码实现
我们选择决策树当中最经典的CART算法来实现决策树,数据我们依然沿用上次AdaBoost模型当中乳腺癌预测的数据。
首先,我们还是一样,先读入数据:
import numpy as np
import pandas as pd
from sklearn.datasets import load_breast_cancer
breast = load_breast_cancer()
X, y = breast.data, breast.target
# reshape,将一维向量转成二维
y = y.reshape((-1, 1))
之后我们利用sklearn库中的train_test_split工具将数据拆分成训练数据和测试数据。
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=23)
随机森林的核心结构依然是决策树,我们可以直接沿用之前CART决策树的代码,只需要稍稍做一些小小的改动即可。首先是计算GIni指数和根据所选的特征拆分数据的函数,这两个函数不需要做任何改动,我们从之前的文章当中复制过来。
from collections import Counter
def gini_index(dataset):
dataset = np.array(dataset)
n = dataset.shape[0]
if n == 0:
return 0
counter = Counter(dataset[:, -1])
ret = 1.0
for k, v in counter.items():
ret -= (v / n) ** 2
return ret
def split_gini(dataset, idx, threshold):
left, right = [], []
n = dataset.shape[0]
# 根据阈值拆分,拆分之后计算新的Gini指数
for data in dataset: