使用 Sci-Kit 学习对具有大型语料库的文本进行分类
Posted
技术标签:
【中文标题】使用 Sci-Kit 学习对具有大型语料库的文本进行分类【英文标题】:Using Sci-Kit learn to classify text with a large corpus 【发布时间】:2013-10-20 14:49:03 【问题描述】:我的数据库中有大约 1600 篇文章,每篇文章都预先标记了以下类别之一:
Technology
Science
Business
World
Health
Entertainment
Sports
我正在尝试使用 sci-kit learn 来构建一个分类器来对新文章进行分类。 (我想我会将我的训练数据分成两半,用于训练和测试?)
我希望使用 tf-idf,因为我没有停用词列表(不过,我可以使用 NLTK 仅提取形容词和名词,但我宁愿提供 scikit-learn 全文)。
我已经阅读了关于 scikit-learn 的所有文档,但他们的示例涉及单词出现和 N-gram(这很好),但他们从未指定如何将一条数据绑定到标签。
我试过查看他们的示例代码,但是太混乱了,无法理解。
有人可以帮我解决这个问题,或者指出正确的方向吗?
谢谢。
【问题讨论】:
请展示您的尝试。 @larsmans 我不知道从哪里开始,是问题所在。我读过的所有文档(仅此而已)似乎都不适用于标记数据。我正在寻找有更多经验的人为我指明正确的方向。 example gallery 中有几个文档分类示例,其他许多示例也是关于分类的。 首先,SVM 又名。支持向量机。 Sci-kit learn 可以与 Pandas 一起工作,并与各种分类器很好地集成(例如,Naive Bayes 是一个不错的选择,或者我实际上推荐 Pattern 的 LDA)。见gist.github.com/zacstewart/5978000。您甚至可以创建自己的向量。 scikit-learn.org/stable/modules/svm.html。这一切都基于距离(欧几里得、tf-idf + 余弦等以及某种形式的聚类)。如有必要,可以使用特征提取器。 【参考方案1】:当我开始将自己的数据提供给分类器时,我认为您遇到了同样的问题。
您可以使用函数sklearn.datasets.load_files
,但要这样做,您需要创建这个结构:
train
├── science
│ ├── 0001.txt
│ └── 0002.txt
└── technology
├── 0001.txt
└── 0002.txt
train
的子目录被命名为标签,标签目录中的每个文件都是具有相应标签的文章。然后使用load_files
加载数据:
In [1]: from sklearn.datasets import load_files
In [2]: load_files('train')
Out[2]:
'DESCR': None,
'data': ['iphone apple smartphone\n',
'linux windows ubuntu\n',
'biology astrophysics\n',
'math\n'],
'filenames': array(['train/technology/0001.txt', 'train/technology/0002.txt',
'train/science/0002.txt', 'train/science/0001.txt'],
dtype='|S25'),
'target': array([1, 1, 0, 0]),
'target_names': ['science', 'technology']
返回的对象是一个sklearn.datasets.base.Bunch
,它是一个简单的数据包装器。这是开始使用分类器的一种直接方法,但是当您的数据较大且经常更改时,您可能希望停止使用文件并使用例如数据库来存储标记的文档,并且可能具有比普通的更多的结构文本。基本上,您需要生成类别列表(或target_names
),例如['science', 'technology', ...]
,并将data
列表中每个文档的target
值分配为target_names
列表中标记类别的索引。 data
和target
的长度必须相同。
您可以查看我之前编写的用于运行分类器的脚本:https://github.com/darkrho/yatiri/blob/master/scripts/run_classifier.py#L267
【讨论】:
我正在尝试加载一个与您采用的示例类似的自定义数据集,我需要创建训练和测试数据集。我得到与上述类似的结果。我尝试使用 train, 'test = train_test_split(data, train_size = 0.8)' 进行拆分,但这会返回错误。我该怎么办?我在这里详细问过问题:goo.gl/bpp9mn【参考方案2】:也许从这里的例子开始:http://scikit-learn.org/dev/auto_examples/document_classification_20newsgroups.html#example-document-classification-20newsgroups-py
一个更高级的例子是:http://scikit-learn.org/dev/auto_examples/grid_search_text_feature_extraction.html#example-grid-search-text-feature-extraction-py
示例库中还有很多文本示例: http://scikit-learn.org/dev/auto_examples/index.html
【讨论】:
谢谢,我会看看那些。我希望能够使用自己的数据,如何预处理它以用于 scikit? 如果是纯文本应该可以。 Scikit-learn 期望训练数据是一个文档列表。只需阅读所有文件并创建其内容列表。 如何将文档的标签传入 scikit? 已编辑以指向功能更丰富的 20newsgroups 示例。 @Yoni201 作为y
适合的参数。
@larsmans 所以我需要两个数组,一个以某种顺序包含我的所有文档,第二个以与文档对应的顺序包含我的所有标签?以上是关于使用 Sci-Kit 学习对具有大型语料库的文本进行分类的主要内容,如果未能解决你的问题,请参考以下文章
将 IMDB 数据用于 sci-kit 回归模型包,该包在特征变量中具有文本值
python+NLTK 自然语言学习处理四:获取文本语料和词汇资源