为何小数据集下Keras/TensorFlow随机森林无法识别输入特征?
TensorFlow Decision Forests随机森林小数据集下的特征识别问题分析
问题概述
使用TensorFlow 2.11.0结合TensorFlow Decision Forests(TF-DF)的RandomForestModel进行变量预测时,遇到以下异常行为:
- 当训练数据集规模较小时(
multiplicity≤4,总样本数≤8),模型输出警告The model does not have any input features i.e. the model is constant and will always return the same prediction.,且对不同输入的预测结果完全一致。 - 当
multiplicity≥5(总样本数≥10)时,模型能识别输入特征,但预测概率不符合预期(未达到完美的[0,1,0]或[0,0,1])。
最小复现代码:
import tensorflow as tf import tensorflow_decision_forests as tfdf import pandas as pd def train_and_predict(multiplicity): train_pd=pd.DataFrame( multiplicity *[ {"key":1, "value":1}] + multiplicity *[ {"key":2, "value":2} ] ) train_tf = tfdf.keras.pd_dataframe_to_tf_dataset(train_pd, label= "value") rf = tfdf.keras.RandomForestModel() rf.fit(x=train_tf) to_guess =pd.DataFrame( [ {"key":1}, {"key":2} ] ) guess_tf = tfdf.keras.pd_dataframe_to_tf_dataset(to_guess) return rf.predict(guess_tf ) print(train_and_predict(4)) print(train_and_predict(5))
原因分析:不是Bug,是内置正则化机制
这种行为是TF-DF随机森林的默认正则化策略导致的,并非软件Bug:
- 节点分裂的样本数阈值:TF-DF的决策树默认要求分裂后的子节点至少包含
min_examples个样本(默认值为5)。当总训练样本数≤8时,即使按key分裂,每个子节点最多只有4个样本,低于默认阈值,因此模型判定该特征无有效分裂价值,直接忽略所有输入特征,退化为常数预测(基于训练集的整体类别分布)。 - 随机森林的随机性影响:当
multiplicity=5(总样本数10)时,分裂后的子节点刚好能满足5个样本的阈值,特征key被启用。但随机森林默认采用bootstrap采样(从训练集随机有放回采样构建每棵树),部分树的采样样本可能存在分布偏差,导致单棵树的预测不完美;集成300棵树后,预测概率为所有树结果的平均值,因此出现非极端值的概率输出。
解决方案:调整模型参数适配小数据集
针对极小数据集场景,可通过修改模型参数关闭或削弱正则化:
- 降低节点最小样本数:设置
min_examples=1,允许分裂出更小的节点:
rf = tfdf.keras.RandomForestModel(min_examples=1)
修改后,即使multiplicity=4,模型也能识别key特征,且预测结果会更接近预期。
2. 使用单棵决策树:若不需要集成学习的随机性,可改用DecisionTreeModel,结合min_examples=1,能得到完美的预期预测:
dt = tfdf.keras.DecisionTreeModel(min_examples=1)
- 调整树数量或关闭bootstrap:减少树的数量(
num_trees=1)或关闭bootstrap采样(bootstrap=False),也能降低随机性对小数据集预测的影响。
验证示例
修改后的代码运行结果(以multiplicity=4为例):
[INFO] Model loaded with 300 root(s), 600 node(s), and 1 input feature(s). [INFO] Use fast generic engine. [[0. 0.9966667 0.00333333] [0. 0.00333333 0.9966667 ]]
此时预测概率已非常接近预期的完美映射。
内容的提问来源于stack exchange,提问作者Piotr Śniady
相关产品推荐
相关产品推荐

