[飞桨机器学习]随机森林
一 、简介
随机森林是利用多棵树对样本进行训练并预测的一种分类器。
随机选择特征数目,随机选择训练数据,对同一个预测数据取出现次数最多的预测标签为最终预测标签。
随机森林实际上是一种特殊的bagging方法,它将决策树用作bagging中的模型。首先,用bootstrap方法生成m个训练集,然后,对于每个训练集,构造一颗决策树,在节点找特征进行分裂的时候,并不是对所有特征找到能使得指标(如信息增益)最大的,而是在特征中随机抽取一部分特征,在抽到的特征中间找到最优解,应用于节点,进行分裂。随机森林的方法由于有了bagging,也就是集成的思想在,实际上相当于对于样本和特征都进行了采样(如果把训练数据看成矩阵,就像实际中常见的那样,那么就是一个行和列都进行采样的过程),所以可以避免过拟合。
prediction阶段的方法就是bagging的策略,分类投票,回归均值。
二、算法
- 用N来表示训练用例(样本)的个数,M表示特征数目。
- 输入特征数目m,用于确定决策树上一个节点的决策结果;其中m应远小于M。
- 从N个训练用例(样本)中以有放回抽样的方式,取样N次,形成一个训练集(即bootstrap取样),并用未抽到的用例(样本)作预测,评估其误差。
- 对于每一个节点,随机选择m个特征,决策树上每个节点的决定都是基于这些特征确定的。根据这m个特征,计算其最佳的分裂方式。
- 每棵树都会完整成长而不会剪枝,这有可能在建完一棵正常树状分类器后会被采用)。
三、优点
1)对于很多种资料,它可以产生高准确度的分类器;
2)它可以处理大量的输入变数;
3)它可以在决定类别时,评估变数的重要性;
4)在建造森林时,它可以在内部对于一般化后的误差产生不偏差的估计;
5)它包含一个好方法可以估计遗失的资料,并且,如果有很大一部分的资料遗失,仍可以维持准确度;
6)它提供一个实验方法,可以去侦测variable interactions;
7)对于不平衡的分类资料集来说,它可以平衡误差;
8)它计算各例中的亲近度,对于数据挖掘、侦测离群点(outlier)和将资料视觉化非常有用;
9)使用上述。它可被延伸应用在未标记的资料上,这类资料通常是使用非监督式聚类。也可侦测偏离者和观看资料;
10)学习过程是很快速的。
四、代码实现
决策树构建等
参考决策树算法
import csv
import numpy as np
import random
import copy
import operator
def loadDataset(filename):
with open(filename, 'r') as f:
lines = csv.reader(f)
data_set = list(lines)
if filename != 'titanic.csv':
for i in range(len(data_set)):
del(data_set[i][0])
# 整理数据
for i in range(len(data_set)):
del(data_set[i][0])
del(data_set[i][2])
data_set[i][4] += data_set[i][5]
del(data_set[i][5])
del(data_set[i][5])
del(data_set[i][6])
del(data_set[i][-1])
category = data_set[0]
del (data_set[0])
# 转换数据格式
for data in data_set:
data[0] = int(data[0])
data[1] = int(data[1])
if data[3] != '':
data[3] = float(data[3])
else:
data[3] = None
data[4] = float(data[4])
data[5] = float(data[5])
# 补全缺失值 转换记录方式 分类
for data in data_set:
if data[3] is None:
data[3] = 28
# male : 1, female : 0
if data[2] == 'male':
data[2] = 1
else:
data[2] = 0
# age <25 为0, 25<=age<31为1,age>=31为2
if data[3] < 60: # 但是测试得60分界准确率最高???!!!
data[3] = 0
else:
data[3] = 1
# sibsp&parcg以2为界限,小于为0,大于为1
if data[4] < 2:
data[4] = 0
else:
data[4] = 1
# fare以64为界限
if data[-1] < 64:
data[-1] = 0
else:
data[-1] = 1
return data_set, category
def gini(data, i):
num = len(data)
label_counts = [0, 0, 0, 0]
p_count = [0, 0, 0, 0]
gini_count = [0, 0, 0, 0]
for d in data:
label_counts[d[i]] += 1
for l in range(len(label_counts)):
for d in data:
if label_counts[l] != 0 and d[0] == 1 and d[i] == l:
p_count[l] += 1
print(label_counts)
print(p_count)
for l in range(len(label_counts)):
if label_counts[l] != 0:
gini_count[l] = 2*(p_count[l]/label_counts[l])*(1 - p_count[l]/label_counts[l])
gini_p = 0
for l in range(len(gini_count)):
gini_p += (label_counts[l]/num)*gini_count[l]
print(gini_p)
return gini_p
def get_best_feature(data, category):
if len(category) == 2:
return 1, category[1]
feature_num = len(category) - 1
data_num = len(data)
feature_gini = []
for i in range(1, feature_num+1):
feature_gini.append(gini(data, i))
min = 0
for i in range(len(feature_gini)):