为什么如果数据集非常小,Keras / TensorFlow在随机森林模型中看不到输入特征?

6xfqseft  于 2023-05-18  发布在  其他
关注(0)|答案(1)|浏览(167)

我正在尝试使用Keras和TensorFlow通过随机森林来预测变量。我遇到了一个意外的行为,我设法将其追溯到以下问题。如果我的训练数据集太小,即使数据集中有一个特征,我也会得到警告The model does not have any input features i.e. the model is constant and will always return the same prediction.。这是一个bug,还是一个深度未文档化的特性?
下面是一个最小的非工作示例。训练数据集只是说键1总是与值1相关联,键2与值2相关联。该信息被编码“多重性”次数。
正确的行为应该是,每当我们得到关键字“1”作为输入时,“0”是正确答案的概率等于0.0,“1”是正确答案的概率等于1.0,而“2”是正确答案的概率等于0.0。这意味着我想要的答案是概率向量(0,0,0,1.0)。如果“2”是密钥,则期望的答案应该是(0.0,0.0,1.0)]。
程序的真实的输出如下:如果多重性最多为4,则TensorFlow看不到任何输入特征;如果多重性为5或更大,则TensorFlow可以看到1个特征。这种行为变化可能表明存在错误。
此外,预测的输出似乎非常奇怪,例如多重性=5,我们得到了非常疯狂的概率:对于“1”,我们得到[0., 0.61333287, 0.3866664 ],对于“2”,我们得到[0., 0.35999975, 0.6399995 ]

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))

输出中有趣的部分:

[WARNING] The model does not have any input features i.e. the model is constant and will always return the same prediction.
[INFO] Model loaded with 300 root(s), 300 node(s), and 0 input feature(s).
[INFO] Engine "RandomForestGeneric" built
[INFO] Use fast generic engine

[[0.         0.6033329  0.39666638]
 [0.         0.6033329  0.39666638]]

[INFO] Model loaded with 300 root(s), 452 node(s), and 1 input feature(s).
[INFO] Use fast generic engine.

[[0.         0.61333287 0.3866664 ]
 [0.         0.35999975 0.6399995 ]]

我在Kaggle上使用TensorFlow 2.11.0版本。你能帮我弄清楚这个问题是出在软件错误上还是出在我不理解什么东西上?

clj7thdc

clj7thdc1#

这里面有三个问题,让我来一一回答。
1.默认情况下,Tensorflow决策森林不会创建任何节点中样本少于5个的节点。如果你只有8个例子(multiplicity = 4),你不能分割这些例子以得到至少有5个例子的2个节点,所以没有分割,模型是恒定的。您可以通过设置为1来控制此超参数,例如rf = tfdf.keras.RandomForestModel(min_examples=1) .
1.概率向量是三维的,因为标签是整数1和2,所以TF-DF隐含地假设范围[0,1,2]中的所有整数都是有效标签。这样做主要是为了避免计算从真实的标签到实际标签的Map-您可以通过底层C++库的dataspec详细控制此过程。
1.你得到“奇怪”概率的原因是由于随机森林的定义。随机森林(RF)基于装袋技术。每棵树都在不同的数据集上训练**,从原始数据集中随机抽样**(替换)。对你来说,这意味着树1(总是)在完整的数据集上训练,这给出了你可能期望的完美的0-1概率。对于所有其他树,这些树是在可能没有良好分割的数据集样本上采样的(参见答案的第1部分),因此树将仅预测优先级类别。当对所有树求平均值时,你最终会得到你看到的概率。
绘制单个树的图以便用

# Text representation of all trees
print(rf.make_inspector().extract_all_trees())
# In Colab / IPython, we have interactive plots for individual trees
tfdf.model_plotter.plot_model_in_colab(rf, tree_idx=77)

TF-DF允许您通过设置rf = tfdf.keras.RandomForestModel(bootstrap_training_dataset=False)来禁用bagging,但这样做完全破坏了随机森林的主要思想之一。你也可以只创建一棵树rf = tfdf.keras.RandomForestModel(num_trees=1),因为第一棵树不使用bagging。
注意:通常,RF也使用特征装袋,即采样属性的随机子集,但由于数据集仅具有一个特征,因此不使用它。
完整披露:Tensorflow Decision Forests的作者之一。

相关问题