目录
在机器学习入门研究(九)-决策树 知道决策树缺点在于容易出现多度拟合,在解决这个问题的时候有一种方案就是随机森林。
随机森林
是一个集成学习方法。
集成学习方法
集成学习方法就是建立几个模型组合来解决单一预测问题。
工作原理:生成多个分类器/模型,各自独立的学习和作出预测。这些预测最后组合成组合预测,因此优于任何一个单分类的作出的预测。
随机森林
是一个包含多个决策树的分类器,并且输出的类别是由个别树输出的类别的众数而定(少数服从多数)。
例如训练了5棵树,有4棵树得出分类为True,有1棵树得出的分类为False,则该最后的分类就是True。
原理
为了生成不同的树,需要随机从训练集和特征中抽取。假设有N个样本,每个样本有M个特征,其中随机森林的两个随机指的是:
- 训练集随机
从N个样本集中随机抽取一个样本放到新的训练集合中,然后在放回到原训练集中,然后在从原样本集在抽取在抽取一个样本放到新的训练集中,直至循环抽取放回N次;
采用的是bootstrap抽样;
有可能会出现重复样本;
- 特征随机
随机选取m个特征来建立决策树,m<<M;
可以起到降维效果,由于特征维数比较少,可以提高计算速度。
- 为什么采用bootstrap抽样
(1)随机抽取
如果不随机抽取,那么每次得到的训练集都一样,那么最终训练出的树分类结果也一致。
(2)有放回的抽样
如果不是有放回的抽样,那么每棵树的训练样本都是不同的,都是没有交集的,训练出来的每棵树出来都是有很大的差异的;而随机森林取决于多棵树的投票结果。
sklearn的API
sklearn.ensemble.RandomForestClassifier( n_estimators='warn',
criterion="gini",
max_depth=None,
min_samples_split=2,
min_samples_leaf=1,
min_weight_fraction_leaf=0.,
max_features="auto",
max_leaf_nodes=None,
min_impurity_decrease=0.,
min_impurity_split=None,
bootstrap=True,
oob_score=False,
n_jobs=None,
random_state=None,
verbose=0,
warm_start=False,
class_weight=None)
其中参数如下:
参数 | 含义 |
n_estimators | 默认为10.森林中的树木的数量 |
criterion | 决策树对应的criterion,默认为gini,也可以为entropy,可参见 |
max_depth | 决策树对应的max_depth,树的最大深度,可参见 |
min_samples_split | 决策树对应的min_samples_split,可参见 |
min_samples_leaf | 决策树对应的min_samples_leaf,可参见 |
min_weight_fraction_leaf | 决策树对应的min_weight_fraction_leaf,可参见 |
max_features | 决策树的最大特征数量 默认为None,样本数<50的时候,使用该值 auto:其值就是sqrt(特征值) sqrt:其值就是sqrt(特征值) log2:其值就是log2(特征值) None:其值就是最大特征值数 |
max_leaf_nodes | 决策树对应的max_leaf_nodes,可参见 |
min_impurity_decrease | 决策树对应的min_impurity_decrease,可参见 |
min_impurity_split | 决策树对应的min_impurity_split,可参见 |
bootstrap | 构建树的时候是否使用随机放回抽样。默认为True |
oob_score | 是否使用袋外样本来估计泛化精度。 |
n_jobs | 并行运行的工作(作业)数量。如果值为-1,那么工作数量被设置为核的数量。 |
random_state | 随机种子 |
verbose | 控制决策树建立过程的冗余度。 |
warm_start | 当被设置为True时,重新使用之前呼叫的解决方案,用来给全体拟合和添加更多的估计器,反之,仅仅只是为了拟合一个全新的森林 |
class_weight | 决策树对应的class_weight,可参见 |
其中n_estimators、max_depth、min_samples_leaf、min_samples_spli为超参数,可以用之前机器学习入门研究(七)-模型选择与调优提到的网格搜索进行获取到最佳参数。
实例分析
用随机森林来分析之前的泰坦尼克号生存情况的问题。直接看下代码,并且使用网格搜索和交叉验证来得到n_estimators、max_depth的最佳参数
def random_forest():
# (1)获取数据
titanic = pd.read_csv("tree_titanic.txt")
# "row.names","pclass","survived","name","age","embarked","home.dest","room","ticket","boat","sex"
print(titanic.head())
# (2)数据处理 - 需要进行挑选特征值和目标值
x = titanic[["pclass", "age", "sex"]]
y = titanic["survived"]
print("特征:\n", x.head())
# (2)数据处理 - 因为年龄数据有缺失,则需要进行填充:采用年龄的平均值进行补充
x["age"].fillna(x["age"].mean(), inplace=True)
# (2)数据处理 - 转换成字典,然后进行特征工程的字典抽取
x = x.to_dict(orient="records")
print("转换成字典之后的特征:\n", x)
# (3)划分训练集、测试集
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=22)
# (4)特征工程-进行字典特征抽取
transfer = DictVectorizer()
x_train = transfer.fit_transform(x_train)
x_test = transfer.transform(x_test)
print("特征工程之后的训练集的特征:\n", x_train)
print("特征:\n", transfer.get_feature_names())
# (5)训练模型
classifier = RandomForestClassifier()
#网格搜索
param = {"max_depth": range(2, 50, 2),"n_estimators": [120, 200, 300, 500, 800, 1200]}
classifier = GridSearchCV(classifier, param_grid=param, cv=6)
classifier.fit(x_train, y_train)
y_predict = classifier.predict(x_test)
print("测试结果为:\n", y_predict == y_test)
print("最好预估器为:\n", classifier.best_estimator_)
# (6)模型评估
score = classifier.score(x_test, y_test)
print("准确度为: ", score)
return None
从代码中我看可以看到在训练模型的过程中增加了网格搜索来得到n_estimators、max_depth的最佳参数 ,采用相同的数据集我们看下运行结果如下:
最好预估器为:
RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini',
max_depth=5, max_features='auto', max_leaf_nodes=None,
min_impurity_decrease=0.0, min_impurity_split=None,
min_samples_leaf=1, min_samples_split=2,
min_weight_fraction_leaf=0.0, n_estimators=500,
n_jobs=None, oob_score=False, random_state=None,
verbose=0, warm_start=False)
准确度为: 0.7872340425531915
相比较前面的决策树,准确度有所提高。
总结
优点
(1)极好的准确率
(2)能够有效的运行在数据集上,特别是具有高维特征的输入样本,不需要降维
(3)能够评估各个特征在分类问题上的重要性
继续努力,感觉越来越入门了,但是分类应该是最简单的,要继续加油!