点一下关注吧!!!非常感谢!!持续更新!!!
目前已经更新到了:
- Hadoop(已更完)
- HDFS(已更完)
- MapReduce(已更完)
- Hive(已更完)
- Flume(已更完)
- Sqoop(已更完)
- Zookeeper(已更完)
- HBase(已更完)
- Redis (已更完)
- Kafka(已更完)
- Spark(已更完)
- Flink(已更完)
- ClickHouse(已更完)
- Kudu(已更完)
- Druid(已更完)
- Kylin(已更完)
- Elasticsearch(已更完)
- DataX(已更完)
- Tez(已更完)
- 数据挖掘(正在更新…)
章节内容
上节我们完成了如下的内容:
- 决策树 sklearn
- 绘制决策树 防止过拟合
剪枝参数
max_depth
限制树的最大深度,超过设定深度的树全部剪掉,一般用做树的精修。
这是用的最广泛的剪枝参数,在高维度低样本量时非常有效,决策树多生长一层,对样本量的需求会增加一倍,所以限制树深度能够有效的限制过拟合。这在集成算法中也非常实用。
实际使用时,建议从=3 开始尝试,看看拟合的效果再决定是否增加设定深度。
min_samples_leaf
一个节点在分支后的每个子节点都必须包含至少 min_samples_leaf 个样本,否则分支就不会发生,或者分支会朝着满足每个子节点都包 min_samples_leaf 个样本的方向去发生。
一般搭配 max_depth 使用,在回归树中有神奇的效果,可以让模型变得更加平滑,这个参数的数量设置得太小会引起过拟合,设置的太大会阻止模型学习数据。
一般来说,建议从=5 开始使用,如果叶节点中含有样本量变化很大,建议输入浮点数作为样本量的百分比来使用。同时,这个参数可以保证每个叶子的最小尺寸,避免低方差,过拟合的叶子节点出现。
min_samples_split
一个节点必须要包含至少 min_samples_split 个训练样本,这个节点才允许被分支,否则分支就不会发生。
max_features
max_features 限制分支时考虑的特征个数,超过限制个数的特征都会被舍弃。和 max_depth 异曲同工,max_features 是用来限制高维度数据的过拟合的剪枝参数,但其方法比较暴力,是直接限制可以使用的特征数量而强行决策树停下的参数,在不知道决策树中的各个特征的重要性的情况下,强行设置这个参数可能会导致模型学习不足。
如果希望通过降维的方式防止过拟合,建议使用 PCA,ICA或者特征选择模块中的降维算法。
min_impurity_decrease
限制信息增益的大小,信息增益小于设定数值小于设定数值的分支不会发生,这是0.19 版本中更新的功能,在 0.19 版本之前时使用 min_impurity_split。
确认最优的剪枝参数
那具体怎么来确定每个参数写什么值?这时候,我们要使用确定超参数的曲线来进行判断,继续使用我们已经训练好的决策模型 CLF。
超参数的学习曲线,是一条以超参数的取值为衡坐标,模型的度量指标为纵坐标的曲线,它是来衡量不同超参数取值下模型的表现的线。在我们建好的决策树里,我们的模型度量指标就是score。
test = []
for i in range(10):
clf = tree.DecisionTreeClassifier(max_depth=i+1,criterion="entropy",random_state=30,splitter="random")
clf = clf.fit(Xtrain, Ytrain)
score = clf.score(Xtest, ytest) # 记录下不同 max_depth 下模型在测试集分数
test.append(score)
plt.plot(range(1,11),test,color="red",label="学习曲线")
plt.ylabel("socre")
plt.xlabel("max_depth")
plt.legend()
plt.show();
运行结果如下图所示:
最后总结
思考:
- 剪枝参数一定能够提升模型在测试集上的表现吗?调参是没有绝对的答案的,一切都需要看数据的本身。
无论如何,剪枝参数的默认值会让树无尽的生长,这些树在某些数据集上可能非常巨大,对内存的消耗也非常巨大。
属性是模型训练之后,能够调用查看的模型的各种性质,对决策树来说,最重要的是 feature_importances,能够查看各个特征对模型的重要性。
sklearn 中许多算法的接口都是相似的,比如说我们之前已经用到 fit 和 score,几乎对每个算法都可以使用,除了两个接口之外,决策树最常用的接口还有 apply 和 predict。
- apply 中输入测试集返回每个测试样本所在的叶子节点的索引
- predict 输入测试集返回每个测试样本的标签,返回的内容一目了然并且非常容易
这里不得不提的是,所有接口中要求输入 Xtrain、Xtest 的部分,输入的特征的矩阵必须至少是一个二维矩阵,sklearn 不接受任何一维矩阵作为特征矩阵被输入。如果你的数据的确只有一个特征,那必须用 reshape(-1,1)来给矩阵增维。
样本不均匀的问题
对于分类问题,永远都逃不过一个问题就是样本不均匀。
样本不均衡是指在一组数据集中,标签的一类天生占有很大的比例,但我们有捕捉出某种特定分类的需求的状况。
比如,我们现在要对潜逃人员和普通人进行分类,潜在犯罪占总人口比例是相当低的,也许是 2%,这样 98% 都是普通人,而我们的目标是要捕获潜在犯罪者。这样的标签分布会带来很多问题。
首先,分类模型天生会倾向于多数的类,让多数类更容易被判断正确,少数类被牺牲掉。因为对于模型而言,样本量越大的标签可以学习的信息越多,算法就会更依赖于从多数类中学习到的信息来进行判断,若我们希望捕获少数类,模型就会失败。
其次,模型评估指标会失去意义,这种分类状况下,即使模型什么也不做,全把所有人当作不会犯罪的人,准确率也会非常的高。这使得模型的评估标准的 Accuracy 变得毫无意义,根本无法达到我们要的“识别犯罪的人”的建模目的。
所以现在,我们要让算法意识到数据的标签不是均衡的,通过施加一些惩罚或者改变样本本身,来让模型捕获少数类的方向建模。
我们可以使用上采样和下采样来达到这个目的,所用的方法就叫做SMOTE,这种方法通过将少数的特征重新组合,创造出更多少数类样本。但这些采样方法会增加样本的总数,对于决策树这个样本总是对计算速度影响巨大的算法来说,我们完全不想轻易的增加样本数量,所以我们要寻求另一条路:改进我们的模型评估指标,使用更加针对于少数类的指标来优化模型。
class_weight
在决策中,存在着调节样本均衡的参数:class_weight 和接口 fit 中可以设定的 sample_weight。
在决策树中,参数 class_weight 默认 None,此模式表示假设数据集中的所有标签是均衡的,即自动认为标签比例是:1:1,所以当样本不均衡的时候,我们可以使用形如:
{
"标签的值 1": 权重1,
"标签的值 2": 权重2
}
用这种字典输入真实的样本标签比例,来让算法意识到样本是不平衡的,或者使用 balanced 模型。
有了权重之后,样本量就不再是单纯的记录数目,而是受输入的权重影响了,因此这时候剪枝,就需要搭配 min_weight_fraction_leaf 这个基于权重的剪枝参数来使用。
另请注意,基于权重的剪枝参数(例如 min_weight_fraction_leaf)将比不知道样本权重的标准(比如 min_samples_leaf)更少偏向主导类。如果是样本是加权的,则使用基于权重的预修剪标准来更容易优化树结构,这确保叶节点至少包含样本权重总和的一小部分。