分类算法之随机森林
概述
在机器学习中, 随机森林是一个包含多个决策树的分类器. 并且其输出的类别是由个别树输出的类别的众数而定. 利用相同的训练数搭建多个独立的分类模型, 然后通过投票的方式, 以少数服从多数的原则作出最终的分类决策. 例如, 如果你训练了 5 个树, 其中有 4 个树的结果是 True, 1 个树的结果是 False, 那么最终结果会是 True.
在前面的决策当中我们提到, 一个标准的决策树会根据每维特征对预测结果的影响程度进行排序. 进而决定不同的特征从上至下构建分裂节点的顺序. 如此一来, 所有在随机森林中的决策树都会受这一策略影响而构建的完全一致, 从而丧失的多样性. 所以在随机森林分类器的构建过程中, 每一棵决策树都会放弃这一固定的排序算法, 转而随机选取特征.
学习算法
根据下列算法而建造每棵树:
- 用 N 来表示训练用例 (样本) 的个数, M 表示特征数目
- 输入特征数目 m, 用于确定决策树上一个节点的决策结果. 其中 m 应远小于 M
- 从 N 个训练用例 (样本) 中以有放回抽样的方式, 取样 N 次, 形成一个训练集 (即 bootstrap 取样). 并用抽到的用例 (样本) 做预测, 评估其误差.
- 对于每一个节点, 随机选择 m 个特征, 决策树上每个节点的决定都是基于这些特征确定的. 根据这 m 个特征, 计算其最佳的分类方式
sklearn.ensemble (集成方法模块)
sklearn.ensemble 提供了准确性更好的集成方法. 里面包含了主要的 RandomForestClassifier (随机森林) 方法.
class sklearn.ensemble.RandomForestClassifier(n_estimators=10, criterion=’gini’, max_depth=None, bootstrap=True, oob_score=False, n_jobs=1, random_state=None)
"""
:param n_estimators:integer,optional(default = 10) 森林里的树木数量。
:param criteria:string,可选(default =“gini”)分割特征的测量方法
:param max_depth:integer或None,可选(默认=无)树的最大深度
:param bootstrap:boolean,optional(default = True)是否在构建树时使用自举样本。
"""
属性
- classes_ shape = [n_classes] 的数组或者这样的数组列表, 类标签 (单输出问题) 或类标签数组列表 (多输出问题)
- featureimportances: array = [n_features] 的数组, 特征重要性 (越好, 功能越重要)
方法
- fit (x, y[, sample_weight]) 从训练集 (x, y): 构建一棵树林
- predict (x): 预测 X 的类
- score(x, y[, sample_weight]): 返回给定测试数据和标签的平均精度
- decision_path (x) 返回森林中的决策路径
泰坦尼克号乘客数据案例
此案例我们通过决策树和随机森林对这个数据进行一个分类, 判断乘客的生还.
完整代码
import pandas as pd
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.feature_extraction import DictVectorizer
from sklearn.tree import export_graphviz
def randomTree():
"""
随机森林对泰坦尼克号进行预测生死
:return: None
"""
# 获取数据
titan = pd.read_csv("titanic.csv")
print(titan.head())
# 处理数据, 找出特征值和目标值
x = titan[["Pclass", "Age", "Sex"]]
y = titan["Survived"]
# 缺失值处理
x["Age"].fillna(x["Age"].mean(), inplace=True)
# 分割数据集到训练集合和测试集
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.25)
# 进行处理 (特征工程)
dict = DictVectorizer(sparse=False)
x_train = dict.fit_transform(x_train.to_dict(orient="records"))
x_test = dict.transform(x_test.to_dict(orient="records"))
print(dict.get_feature_names())
# 用随机森林进行预测 (超参数调优)
rf = RandomForestClassifier()
param = {"n_estimators": [120, 200, 300, 500, 800, 1200], "max_depth": [5, 8, 15, 25, 30]}
# 网格搜索进行交叉验证
gc = GridSearchCV(rf, param_grid=param, cv=10)
gc.fit(x_train, y_train)
# 预测准确率
print("预测的准确率: ", gc.score(x_test, y_test))
print("最优准确率: ", gc.best_score_)
print("查看选择参数模型: ", gc.best_params_)
return None
if __name__ == "__main__":
randomTree()
输出结果:
预测的准确率: 0.7757847533632287
最优准确率: 0.8218562874251497
查看选择参数模型: {'max_depth': 8, 'n_estimators': 300}