【问题标题】:Accuracy with TF-IDF and non-TF-IDF featuresTF-IDF 和非 TF-IDF 特征的准确性
【发布时间】:2020-09-27 19:05:49
【问题描述】:

我使用 TF-IDF 和非 TF-IDF 特征运行随机森林算法。

特征总数约为 130k(在对 TF-IDF 特征进行特征选择后),训练集的观察数约为 120k。

其中大约 500 个是非 TF-IDF 特征。

问题在于随机森林在同一测试集上的准确性等与

- 只有非 TF-IDF 特征是 87%

- TF-IDF 和非 TF-IDF 特征为 76%

准确度的这种显着恶化在我的脑海中引发了一些问题。

我与模型训练相关的代码如下:

drop_columns = ['labels', 'complete_text_1', 'complete_text_2']

# Split to predictors and targets
X_train = df.drop(columns=drop_columns).values
y_train = df['labels'].values


# Instantiate, train and transform with tf-idf models
vectorizer_1 = TfidfVectorizer(analyzer="word", ngram_range=(1,2), vocabulary=tf_idf_feature_names_selected)
X_train_tf_idf_1 = vectorizer_1.fit_transform(df['complete_text_1'])

vectorizer_2 = TfidfVectorizer(analyzer="word", ngram_range=(1,2), vocabulary=tf_idf_feature_names_selected)
X_train_tf_idf_2 = vectorizer_2.fit_transform(df['complete_text_2'])


# Covert the general features to sparse array
X_train = np.array(X_train, dtype=float)
X_train = csr_matrix(X_train)


# Concatenate the general features and tf-idf features array
X_train_all = hstack([X_train, X_train_tf_idf_1, X_train_tf_idf_2])


# Instantiate and train the model
rf_classifier = RandomForestClassifier(n_estimators=150, random_state=0, class_weight='balanced', n_jobs=os.cpu_count()-1)
rf_classifier.fit(X_train_all, y_train)

就个人而言,我没有在我的代码中看到任何错误(上面的这段代码和一般情况)。

我为解释这种准确性下降而制定的假设如下。

  1. 非 TF-IDF 特征的数量只有 500 个(总共 130k 特征)
  2. 这提供了一些机会,即非 TF-IDF 特征在每次被随机森林的树分割时不会被挑选那么多(例如,因为 max_features 等)
  3. 因此,如果非 TF-IDF 功能确实很重要,那么这将产生问题,因为它们没有得到足够的考虑。

与此相关,当我在训练后检查随机森林的特征重要性时,我发现非 TF-IDF 特征的重要性非常低(尽管我不确定特征重要性的指标有多可靠尤其是包含 TF-IDF 功能)。

您能否以不同的方式解释我的分类器准确度下降的原因?

无论如何,你会建议做什么?

结合 TF-IDF 和非 TF-IDF 功能的其他一些想法如下。

一种选择是拥有两个独立的(随机森林)模型 - 一个用于 TF-IDF 功能,一个用于非 TF-IDF 功能。 然后这两个模型的结果将通过(加权)投票或元分类进行组合。

【问题讨论】:

  • 在此处提供有关您的任务的更多信息会非常有帮助,例如:任务是什么、损失函数、您使用的数据点数量等。
  • 我的意思是从代码来看,您似乎对具有交叉熵损失的文本文档有一个二进制分类任务,但明确地拼写它会使阅读您的问题更简单一些。当然,数据点的数量也非常重要(在任何地方都没有提到)。
  • @AlexanderPivovarov,好点。在这里提供所有这些信息有点太费时了,这就是为什么我到目前为止还没有。首先,训练集的观测数约为 120k。
  • 如果您查看 max_features 的文档,默认情况下它将使用 sqrt(n_features),这大约是任何给定树将看到的 360 个特征。即使不同树之间的这些特征没有重叠,150*360 = 54k。所以你的 130k 特征中的大部分将永远不会被模型看到
  • @Swier,我当然同意max_features,这也是我在帖子中提到这个的原因。但是,除非我遗漏了什么,否则请记住,每次在每次拆分时并且不仅在每棵树上都会选择一组新的特征,这些特征基于随机森林,但也基于 RandomForestClassifier (max_features{“auto”, “sqrt”, “log2”}, int or float, default=”auto” The number of features to consider when looking for the best split:) 的 SkLearn 文档。

标签: python machine-learning random-forest tf-idf


【解决方案1】:

您认为 130K 的特征对于随机森林来说太过分了,这听起来是对的。您没有提到数据集中有多少示例,这对于选择可能的后续步骤至关重要。以下是我的一些想法。

如果数据点的数量足够大,您可能希望为 TF-IDF 功能训练一些转换 - 例如您可能希望将这些 TF-IDF 特征的小维嵌入训练到 64 维空间中,然后例如一个小的NN(甚至可能是一个线性模型)。嵌入后,您可以将它们用作转换,为每个示例生成 64 个附加特征,以替换 TF-IDF 特征以进行 RandomForest 训练。或者只是用这种架构的NN替换整个随机森林,例如TF-IDF 都通过全连接层组合成几个神经元,然后与其他特征连接(与嵌入几乎相同,但作为 NN 的一部分)。

如果您没有足够的数据来训练大型 NN,也许您可​​以尝试训练 GBDT 集成而不是随机森林。与随机森林相比,它可能在选择好的特征方面做得更好,随机森林肯定会受到很多嘈杂的无用特征的影响。你也可以先训练一些粗略的版本,然后在此基础上进行特征选择(同样,我希望它与随机森林相比应该做得更合理)。

【讨论】:

  • 感谢您的回答 :) 只是为了澄清一下,我并没有确切地说“130K 的功能对于随机森林来说太多了”。从某种意义上说,如果我有 130k 个fatures 都是 TF-IDF 功能,那么实际上我认为它会相当不错。问题更多的是,我认为有 130k 个功能,其中 500 个(非 TF-IDF 的)可能非常重要(正如我只使用它们时显示的那样)。
  • 好吧,也许我的措辞有点太强了。但是随机森林(和其他树集成算法,如 GBDT)很难与词袋等稀疏特征一起使用(而 TF-IDF 只是在这里设置词袋特征权重的一个很好的权重)。当然,在你的例子中,可以想象多个调整来帮助随机森林做得更好——例如显然在这个例子中,如果你可以为随机森林训练加权你的特征,这可能有助于避免你的例子中的准确性损失,但据我所知,sklearn 随机森林不支持这样的事情。
  • 如果你真的想要一些非常简单的东西来帮助这里的 RandomForest 训练,我建议进行 2 步训练:(第一步 - 特征选择)使用你拥有的所有特征训练一个更大的森林,然后得到任何从该训练中输出某种特征重要性(sklearn 的特征重要性输出可能没问题)并基于此仅修剪 TF-IDF 特征(例如,使用所有非 TF-IDF 特征 + 最佳 M TF-IDF 特征基于特征重要性),然后(第二步)使用修剪后的特征集训练一个常规大小的集合。
  • 当然这个选项肯定是有效的,但实际上这是我已经做过的——130k 个特征是在特征选择之后(基于特征重要性),特别是它们大约是前 1% 的特征总 TF-IDF 特征。我想我可以做得更加“选择性”,但我不确定它是否一定是准确性的最佳选择。另一种选择是我在帖子最后一段中描述的那个。
  • 最后,“但是随机森林(和其他树集成算法,如 GBDT)很难与词袋等稀疏特征一起使用”,你有这个说法的来源吗?尽管有一些案例(例如stats.stackexchange.com/a/228786/193309),但我并没有真正听到太多,但也有相反的说法(例如stats.stackexchange.com/a/47467/193309)。另外,我自己在其他情况下测试了 TF-IDF 高维数据(没有非 TF-IDF)上的随机森林,总体而言,它比其他模型运行得非常好。
【解决方案2】:

我的猜测是你的假设是部分正确的。

当使用完整数据集(在 130K 特征模型中)时,树中的每个拆分仅使用 500 个非 TF-IDF 特征中的一小部分。因此,如果非 TF-IDF 特征很重要,那么每次拆分都会错过很多有用的数据。一次拆分被忽略的数据可能会用于树中的另一个拆分,但结果不如每次拆分都使用更多数据时那样好。

我认为 TF-IDF 也有一些非常重要的特性。我们拥有如此多的特征这一事实意味着在每次拆分时都会考虑这些特征的一小部分。

换句话说:问题不在于我们削弱了非 TF-IDF 功能。 问题在于我们正在削弱所有有用的功能(非 TF-IDF 和 TF-IDF)。这与 Alexander 的回答类似。

鉴于此,您提出的解决方案不会很好地解决问题。如果你制作两个随机森林模型,一个有 500 个非 TF-IDF 特征,另一个有 125K TF-IDF 特征,第二个模型会表现不佳,并对结果产生负面影响。如果您将 500 模型的结果作为附加功能传递给 125K 模型,那么您仍然表现不佳。

如果我们想坚持使用随机森林,更好的解决方案是增加 max_features 和/或树的数量。这将增加在每次拆分时考虑有用特征的几率,从而产生更准确的模型。

【讨论】:

  • 我可能几乎完全同意The problem is that we're weakening all of the useful features (both non-TF-IDF and TF-IDF).,但我试图在我的帖子中找到答案的问题是:The issue is that the accuracy of the Random Forest on the same test set etc with only the non-TF-IDF features is 87% and with the TF-IDF and non-TF-IDF features is 76%,因此我对非 TF-IDF 功能的回答.
猜你喜欢
  • 2012-08-28
  • 2015-05-07
  • 2014-07-10
  • 2020-11-08
  • 2020-01-18
  • 1970-01-01
  • 2012-07-02
  • 2012-09-11
  • 1970-01-01
相关资源
最近更新 更多