使用随机森林对文本文档进行分类

Posted

技术标签:

【中文标题】使用随机森林对文本文档进行分类【英文标题】:Classifying text documents with random forests 【发布时间】:2014-03-08 11:43:47 【问题描述】:

我有一组 4k 文本文档。 它们属于 10 个不同的类别。 我想看看随机森林方法是如何进行分类的。 问题是我的特征提取类提取了 20 万个特征。(单词、bigrams、搭配等的组合) 这是高度稀疏的数据,sklearn 中的随机森林实现不适用于稀疏数据输入。

问。我在这里有什么选择?减少功能数量 ?如何 ? 问:是否有任何随机森林的实现可以与稀疏数组一起使用。

我的相关代码如下:

import logging
import numpy as np
from optparse import OptionParser
import sys
from time import time
#import pylab as pl

from sklearn.datasets import load_files
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.ensemble import RandomForestClassifier
from special_analyzer import *


data_train  =  load_files(RAW_DATA_SRC_TR)
data_test   =  load_files(RAW_DATA_SRC_TS)
# split a training set and a test set
y_train, y_test = data_train.target, data_test.target

vectorizer = CountVectorizer( analyzer=SpecialAnalyzer()) # SpecialAnalyzer is my class extracting features from text
X_train = vectorizer.fit_transform(data_train.data)



rf = RandomForestClassifier(max_depth=10,max_features=10)
rf.fit(X_train,y_train)

【问题讨论】:

我只在 Java 中使用过 RF,但您似乎需要对每个文档进行“标准化”矢量表示。在 Java 中,这可以首先表示为 SortedMap,其中字符串键是特征,双精度值是该文档中术语的频率。如果你像这样对所有内容进行矢量化,然后将每个文档表示为标准的 double[] 数组,那么算法应该做到这一点。换句话说,DOC1 看起来像 a,b 而 DOC2 看起来像 a,c,规范化/矢量化后的 doc 1 应该变成 a=1,b=1,c=0 并且 DOC2 会变成 a=1,b=0, c=1. 从the doc of version 0.16.1看来sklearn.ensemble.RandomForestClassifier.fit现在接受稀疏矩阵作为输入:Parameters: X : array-like or sparse matrix of shape = [n_samples, n_features] 【参考方案1】:

选项 1: “如果变量的数量非常大,可以使用所有变量运行一次森林,然后只使用第一次运行中最重要的变量再次运行。”

来自:http://www.stat.berkeley.edu/~breiman/RandomForests/cc_home.htm#giniimp

我不确定 sklearn 中的随机森林是否有特征重要性选项。 R中的随机森林实现了基尼杂质的平均减少以及准确性的平均减少。

选项 2: 进行降维。使用 PCA 或其他降维技术将 N 维的密集矩阵变为更小的矩阵,然后将这个更小的稀疏矩阵用于分类问题

选项 3: 删除相关特征。我相信与多项逻辑回归相比,随机森林应该对相关特征更稳健。话虽这么说……您可能有许多相关的特征。如果你有很多成对的相关变量,你可以去掉这两个变量中的一个,理论上你应该不会失去“预测能力”。除了成对相关之外,还有多重相关。签出:http://en.wikipedia.org/wiki/Variance_inflation_factor

【讨论】:

感谢您的快速回复 Andrew,您是否有任何示例 R 代码可以帮助您进行。我最熟悉 python。 我还添加了更多关于相关变量的信息...这可以更大程度地减少变量的数量,并让您对输入有更多的了解。让我知道这是否有效/有帮助 我会尝试您的建议并在此处发布结果。谢谢。 Re: 选项 2,使用LinearSVC(penalty='l1', C=some_value).fit_transform(X) 进行特征选择是另一种降低维度的好方法。 I'm not sure about the random forest in sklearn has a feature importance option 它确实有 feature_importances_,所以是的(不知道为什么 _,但它已记录在案,因此必须公开)。【参考方案2】:

几个选项:通过将max_features=10000 传递给CountVectorizer,只获取最流行的 10000 个特征,然后使用 to array 方法将结果转换为密集的 numpy 数组:

X_train_array = X_train.toarray()

否则将维度减少到 100 或 300 个维度:

pca = TruncatedSVD(n_components=300)
X_reduced_train = pca.fit_transform(X_train)

但是,根据我的经验,我无法使 RF 比在原始稀疏数据(可能使用 TF-IDF 归一化)上经过良好调整的线性模型(例如带有网格搜索正则化参数的逻辑回归)更好地工作。

【讨论】:

s/RandomizedPCA/TruncatedSVD 通过使用 max_features 我可以让它继续运行..但我想我发现 RF 没有优于线性模型的相同行为。 您发现哪些参数是优化逻辑回归@ogrisel 的最佳参数? 这取决于数据。超参数没有普遍的良好价值,否则首先运行网格搜索来调整它们是没有意义的。

以上是关于使用随机森林对文本文档进行分类的主要内容,如果未能解决你的问题,请参考以下文章

如何对法律领域的文本文档进行分类

使用学习对文本文档进行排名?

在 Python 中使用 h2o4gpu K-Means 对文本文档进行聚类

如何将文本文档表示为特征向量进行文本分类?

最佳文本文档分类算法 [关闭]

在图像文本文档中随机生成合成噪声