随机森林
用随机的方式建立一个森林,森林里面有很多的决策树组成,随机森林的每一棵决策树之间是没有关联的。在得到森林之后,当有一个新的输入样本进入的时候,就让森林中的每一棵决策树分别进行一下判断,看看这个样本应该属于哪一类(对于分类算法),然后看看哪一类被选择最多,就预测这个样本为那一类。
实现过程如下:
1)从样本集中有放回随机采样选出n个样本;
2)从所有特征中随机选择k个特征,对选出的样本利用这些特征建立决策树(一般是CART,也可是别的或混合);
3)重复以上两步m次,即生成m棵决策树,形成随机森林;
4)对于新数据,经过每棵树决策,最后投票确认分到哪一类。
随机森林有很多优点:
1) 每棵树都选择部分样本及部分特征,一定程度避免过拟合;
2) 每棵树随机选择样本并随机选择特征,使得具有很好的抗噪能力,性能稳定;
3) 能处理很高维度的数据,并且不用做特征选择;
4) 适合并行计算;
5) 实现比较简单;
缺点:
1) 参数较复杂;
2) 模型训练和预测都比较慢。
构建随机森林代码如下:
def createForest(dataSet, featureLabels, numTress):
''' 创建随机森林
:param dataSet: 数据集
:param featureLabels: 每个特征名称的列表
:param numTress: 随机森林中决策树的个数
:return:
'''
row, col = shape(dataSet)
forest = []
for i in range(numTress):
# 随机抽取一半的数据
samples = unique(random.randint(0, row, size=(row+1)//2))
sampleDatas = array(dataSet)[samples.tolist()]
# 从抽取的数据中随机抽取一半的特征
features = unique(random.randint(0, col-1, col//2))
features_list = features.tolist()
feature_labels = array(featureLabels)[features_list]
features_list.append(-1)
sample_feature_data = sampleDatas[:, features_list]
# 根据抽样的数据构建决策树
tree = create_tree(sample_feature_data.tolist(), feature_labels.tolist())
forest.append(tree)
return forest
其中create_tree方法可以采用ID3,C4.5等方法来创建决策树。
使用随机森林分类:
def classify(inputTree, featureLabels, testVec):
''' 使用决策树进行分类
:param inputTree:决策树
:param featureLabels:
:param testVec:
:return:
'''
first_lable = list(inputTree.keys())[0]
second_dict = inputTree[first_lable]
feature_index = featureLabels.index(first_lable)
feature_value = testVec[feature_index]
#特殊处理,如果树中找不到该属性的值,则从树中随机选取一个,或者直接返回错误
value = second_dict.get(feature_value, "false")
if value == "false":
return "cannot"
# values = second_dict.values();
# r = random.randint(0, len(values))
# value = values[r]
if type(value).__name__ == 'dict':
class_label = classify(value, featureLabels, testVec)
else:
class_label = value
return class_label
def predict(forest, featureLabels, test_data):
''' 使用随机森林forest对测试数据test_data进行预测
:param forest:
:param featureLabels:
:param test_data:
:return:
'''
predict_labels = []
# 对每一个样本
for row in test_data:
dic = {}
# 使用所有的决策树做预测,返回预测最多的作为结果
for tree in forest:
predict_label = classify(tree, featureLabels, row)
if predict_label == "cannot":
continue
dic[predict_label] = dic.get(predict_label, 0) + 1
l = sorted(dic.items(), key=lambda ele:ele[1], reverse=True)
if len(l) == 0:
label = row[-1]
predict_labels.append(label)
else:
predict_labels.append(l[0][0])
return array(predict_labels)
参考:
http://blog.csdn.net/hexingwei/article/details/50740404
http://www.2cto.com/kf/201605/509184.html
完整代码参考github:
https://github.com/zhanggw/algorithm/tree/master/machine-learning/RandomForest