使用随机森林分类文本文件

5

我有一组4k个文本文件,它们属于10个不同的类别。我正在尝试使用随机森林方法进行分类。问题在于我的特征提取类提取了200k个特征(包括单词、二元组和短语等的组合)。这是高度稀疏的数据,而sklearn中的随机森林实现不能处理稀疏数据输入。

Q. 我有哪些选择?减少特征数量?如何减少? Q. 是否有任何可以处理稀疏数组的随机森林实现?

以下是我的相关代码:

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<String, double>,其中字符串键是特征,double值是该文档中该项的频率。如果您像这样对所有内容进行矢量化,然后将每个文档表示为标准的double[]数组,则算法应该会自动处理。换句话说,如果DOC1看起来像a,b,而DOC2看起来像a,c,则在规范化/矢量化之后,DOC1应变为a=1,b=1,c=0,而DOC2则为a=1,b=0,c=1。 - Mark Giaconia
1
0.16.1版本的文档来看,sklearn.ensemble.RandomForestClassifier.fit现在可以接受稀疏矩阵作为输入:参数: X : 形状为 [n_samples, n_features] 的数组或稀疏矩阵 - jul
2个回答

6

有几个选择:通过将 max_features=10000 传递给 CountVectorizer,并使用 to array 方法将结果转换为密集的 numpy 数组,仅选取最受欢迎的 10000 个特征:

X_train_array = X_train.toarray()

否则,使用以下语句将维度降至100或300维:
pca = TruncatedSVD(n_components=300)
X_reduced_train = pca.fit_transform(X_train)

然而根据我的经验,我从未发现RF能比原始稀疏数据上的精调线性模型(例如带有网格搜索正则化参数的逻辑回归)表现更好(可能加上TF-IDF标准化)。


1
s/RandomizedPCA/TruncatedSVD - Fred Foo
通过使用max_features,我可以让它运行。但是我想我发现了与线性模型相比随机森林表现不佳的相同行为。 - Yantra
你发现哪些参数是经过良好调整的逻辑回归的最佳参数,@ogrisel? - tumbleweed
这取决于数据。否则,如果超参数存在普遍好的值,那么首先运行网格搜索来调整它们就没有意义了。 - ogrisel

4

选项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

谢谢您的快速回复,安德鲁。您有任何可以帮助我的 R 代码示例吗?我更熟悉 Python。 - Yantra
我还添加了一些关于相关变量的内容...这可以更大程度地减少变量数量,并为您提供许多有关输入的见解。如果这些内容有所帮助,请告诉我。 - Andrew Cassidy
我会尝试您的建议并在此发布结果。谢谢。 - Yantra
关于选项2,使用LinearSVC(penalty='l1', C=some_value).fit_transform(X)进行特征选择是另一种降低维度的好方法。 - Fred Foo
我不确定sklearn中的随机森林是否具有特征重要性选项,但它确实具有feature_importances_,所以是的(不知道为什么有下划线,但已记录,因此必须是公共的)。 - Mark

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接