【Scikit-Learn 中文文档】处理文本数据 - scikit-learn 教程 | ApacheCN
中文文档: http://sklearn.apachecn.org/cn/stable/tutorial/text_analytics/working_with_text_data.html
英文文档: http://sklearn.apachecn.org/en/stable/tutorial/text_analytics/working_with_text_data.html
官方文档: http://scikit-learn.org/stable/
GitHub: https://github.com/apachecn/scikit-learn-doc-zh(觉得不错麻烦给个 Star,我们一直在努力)
贡献者: https://github.com/apachecn/scikit-learn-doc-zh#贡献者
关于我们: http://www.apachecn.org/organization/209.html
处理文本数据
本指南旨在一个单独实际任务中探索一些主要的 scikit-learn
工具: 分析关于20 个不同主题的一个文件汇编(新闻组帖子).
- 读取文件内容以及所属的类别
- 提取合适于机器学习的特征向量
- 训练一个线性模型来进行分类
- 使用网格搜索策略来找到特征提取组件以及分类器的最佳配置
教程设置
开始这篇教程之前,必须首先安装 scikit-learn 以及所有其要求的库.
这篇入门教程的源代码可以在您的 scikit-learn 文件夹下面找到:
scikit-learn/doc/tutorial/text_analytics/
这个入门教程应该包含以下的子文件夹:
*.rst files
- 用 sphinx 编写的该教程的源代码data
- 用来存放在该教程中用到的数据集的文件夹skeletons
- 用来练习的未完成的示例脚本solutions
- 练习的答案
你也可以将这个文件结构拷贝到您的电脑的硬盘里名为 sklearn_tut_workspace
的文件夹中来编辑你自己的文件完成练习,同时保持原结构紧凑:
% cp -r skeletons work_directory/sklearn_tut_workspace
机器学习算法需要数据. 进入每一个 $TUTORIAL_HOME/data
子文件夹,然后运行 fetch_data.py
脚本(在您已经事先读取它们之后).
例如:
% cd $TUTORIAL_HOME/data/languages % less fetch_data.py % python fetch_data.py
加载这20个新闻组的数据集
该数据集名为 “Twenty Newsgroups”. 下面就是这个数据集的介绍, 来源于 网站:
为了在第一个示例中节约时间,我们将使用部分数据:从20类别中选出4个:
>>> categories = ['alt.atheism', 'soc.religion.christian', ... 'comp.graphics', 'sci.med']
如下所示,我们现在能够加载包含对应类别的文件的列表:
>>> from sklearn.datasets import fetch_20newsgroups >>> twenty_train = fetch_20newsgroups(subset='train', ... categories=categories, shuffle=True, random_state=42)
返回的数据类型是一个 scikit-learn
“bunch”: 一个简单的包含多个 “field” 的存储对象 , 方便使python 中的 dict
keys 或 object
中属性来读取, 比如 target_names
包含了所要求的类别名称:
>>> twenty_train.target_names ['alt.atheism', 'comp.graphics', 'sci.med', 'soc.religion.christian']
这些文件本身被读进内存的 data
属性中. 另外,这些文件名称也可以容易获取到:
>>> len(twenty_train.data) 2257 >>> len(twenty_train.filenames) 2257
让我们打印出所加载的第一个文件的前几行:
>>> print("\n".join(twenty_train.data[0].split("\n")[:3])) From: sd345@city.ac.uk (Michael Collier) Subject: Converting images to HP LaserJet III? Nntp-Posting-Host: hampton>>> print(twenty_train.target_names[twenty_train.target[0]]) comp.graphics
监督学习需要让训练集中的每个文档对应一个类别标签. 在这个例子中,类别是每个新闻组的名称,也刚好是每个储存文本文件的文件夹的名称.
由于速度和空间上效率的原因 scikit-learn
加载目标属性为一个整型数列, 它与 target_names
列表中类别名称的 index(索引)相对应. 每个样本的类别的整数型 id 存放在 target
属性中:
>>> twenty_train.target[:10] array([1, 1, 3, 3, 3, 3, 3, 2, 2, 2])
也可以通过如下方式取得类别名称:
>>> for t in twenty_train.target[:10]: ... print(twenty_train.target_names[t]) ... comp.graphics comp.graphics soc.religion.christian soc.religion.christian soc.religion.christian soc.religion.christian soc.religion.christian sci.med sci.med sci.med
你可以发现所有的样本都被随机打乱(使用了修正的 RNG 种子): 当你在训练进行整个数据集之前,你只要选取前几个样本来快速训练一个模型的时候以及获得初步结果.这是非常有用的.
从文本文件中提取特征
为了在文本文件中执行机器学习算法, 我们首先要做的是将文本内容转化成数值形式的特征向量.
词袋
- 在训练集中每一个出现在任意文中的单词分配一个特定的整数id(比如,通过建立一个从单词到整数索引的字典).
- 对于每个文档
#i
,计算每个单词w
的出现次数并将其存储在X[i, j]
中作为特征#j
的值,其中j
是在字典中词w
的索引.
在这种方法中 n_features
是在整个文集(文章集合的缩写,下同)中不同单词的数量: 这个值一般来说超过 100,000.
如果 n_samples == 10000
, 存储 X
为 “float32” 型的numpy数组将会需要 10000 x 100000 x 4 bytes = 4GB内存 ,在当前的计算机中非常不好管理的.
幸运的是, X 数组中大多是 0 ,是因为特定的文档中使用的单词数量远远少于总体的词袋单词个数. 因此我们可以称词袋模型是典型的 high-dimensional sparse datasets(高维稀疏数据集). 我们可以通过只保存那些非0的部分的特征向量在内存中来节省大量内存.
scipy.sparse
矩阵正是能完成上述操作的数据结构,同时 scikit-learn
有内置的支持这样的数据结构.
使用 scikit-learn
来对文本进行分词
文本的预处理, 分词以及过滤停词包含在可以构建特征字典和将文本转换成特征向量的高级组件中
>>> from sklearn.feature_extraction.text import CountVectorizer >>> count_vect = CountVectorizer() >>> X_train_counts = count_vect.fit_transform(twenty_train.data) >>> X_train_counts.shape (2257, 35788)
CountVectorizer
提供了 N-gram 模型以及连续词模型. 一旦拟合, 向量化程序就会构建一个包含特征索引的字典:
>>> count_vect.vocabulary_.get(u'algorithm') 4690
在词汇表中一个单词的索引值对应的是该单词在整个训练的文集中出现的频率.
从出现次数到出现频率
出现次数的统计是非常好的开始,但是有个问题:长的文本相对于短的文本有更高的平均单词出现次数,尽管他们可能在描述同一个主题.
使用每个单词出现的次数被除以总共单词出现的次数,这种方法就能避免以上这种潜在的差别:这些新的特征称之为词频(tf).
基于这词频上的精简提炼的是降低这个文集里出现在很多文档中的单词的比重,因此它会比那些仅出现在一些文档中的单词有更少的信息量.
这种downscaling(降低比重)的方法称为 tf–idf ,全称为 “Term Frequency times Inverse Document Frequency”.
>>> from sklearn.feature_extraction.text import TfidfTransformer >>> tf_transformer = TfidfTransformer(use_idf=False).fit(X_train_counts) >>> X_train_tf = tf_transformer.transform(X_train_counts) >>> X_train_tf.shape (2257, 35788)
在上面的例子中,我们首先使用了 fit(..)
方法来拟合数据的estimator(估算器),接下来使用 transform(..)
方法来把我们的次数矩阵转换成 tf-idf 型. 这两步可以结合起来,通过省去多余的处理来更快地得到同样的结果. 那就是使用上节提到过的 fit_transform(..)
方法,如下:
>>> tfidf_transformer = TfidfTransformer() >>> X_train_tfidf = tfidf_transformer.fit_transform(X_train_counts) >>> X_train_tfidf.shape (2257, 35788)
训练分类器
>>> from sklearn.naive_bayes import MultinomialNB >>> clf = MultinomialNB().fit(X_train_tfidf, twenty_train.target)
为了尝试预测新文档所属的类别,我们需要和之前同样的步骤来抽取特征. 区别是,对transformer使用 transform
而不是 fit_transform
,因为文档已经与训练集拟合了:
>>> docs_new = ['God is love', 'OpenGL on the GPU is fast'] >>> X_new_counts = count_vect.transform(docs_new) >>> X_new_tfidf = tfidf_transformer.transform(X_new_counts)>>> predicted = clf.predict(X_new_tfidf)>>> for doc, category in zip(docs_new, predicted): ... print('%r => %s' % (doc, twenty_train.target_names[category])) ... 'God is love' => soc.religion.christian 'OpenGL on the GPU is fast' => comp.graphics
构建 Pipeline(管道)
为了使得 向量化 => 转换 => 分类器 过程更加简单,``scikit-learn`` 提供了一个 Pipeline
类,操作起来像一个复合分类器:
>>> from sklearn.pipeline import Pipeline >>> text_clf = Pipeline([('vect', CountVectorizer()), ... ('tfidf', TfidfTransformer()), ... ('clf', MultinomialNB()), ... ])
名称 vect
, tfidf
和 clf
(分类器)都是任意的. 我们将会在下面的 grid search(网格搜索)小节中看到它们的用法. 现在我们使用下行命令来训练模型:
>>> text_clf.fit(twenty_train.data, twenty_train.target) Pipeline(...)
评估测试集上的性能
>>> import numpy as np >>> twenty_test = fetch_20newsgroups(subset='test', ... categories=categories, shuffle=True, random_state=42) >>> docs_test = twenty_test.data >>> predicted = text_clf.predict(docs_test) >>> np.mean(predicted == twenty_test.target) 0.834...
如上, 我们模型的精度为 83.4%. 我们使用线性分类模型 支持向量机(SVM), 一种公认的最好的文本分类算法(尽管训练速度没有朴素贝叶斯快). 我们改变分类算法只需要在 pipeline(管道)中添加不同的算法即可:
>>> from sklearn.linear_model import SGDClassifier >>> text_clf = Pipeline([('vect', CountVectorizer()), ... ('tfidf', TfidfTransformer()), ... ('clf', SGDClassifier(loss='hinge', penalty='l2', ... alpha=1e-3, random_state=42, ... max_iter=5, tol=None)), ... ]) >>> text_clf.fit(twenty_train.data, twenty_train.target) Pipeline(...) >>> predicted = text_clf.predict(docs_test) >>> np.mean(predicted == twenty_test.target) 0.912...
scikit-learn
同样提供了更加细节化的模型评估工具:
>>> from sklearn import metrics >>> print(metrics.classification_report(twenty_test.target, predicted, ... target_names=twenty_test.target_names)) ... precision recall f1-score support alt.atheism 0.95 0.81 0.87 319 comp.graphics 0.88 0.97 0.92 389 sci.med 0.94 0.90 0.92 396 soc.religion.christian 0.90 0.95 0.93 398 avg / total 0.92 0.91 0.91 1502>>> metrics.confusion_matrix(twenty_test.target, predicted) array([[258, 11, 15, 35], [ 4, 379, 3, 3], [ 5, 33, 355, 3], [ 5, 10, 4, 379]])
从混淆矩阵中可以看出,新闻所属类别在无神论以及基督教两者之间是非常令人困惑的,而与计算机图形学差别是特别大的.
使用网格搜索进行参数调优
>>> from sklearn.model_selection import GridSearchCV >>> parameters = {'vect__ngram_range': [(1, 1), (1, 2)], ... 'tfidf__use_idf': (True, False), ... 'clf__alpha': (1e-2, 1e-3), ... }
很明显的可以发现, 如此的搜索是非常耗时的. 如果我们有多个 cpu 核心可以使用, 通过设置 n_jobs
参数能够进行并行搜索. 如果我们将该参数设置为 -1
, 该方法会使用机器的所有 cpu 核心:
>>> gs_clf = GridSearchCV(text_clf, parameters, n_jobs=-1)
网格搜索在 scikit-learn
中是非常常见的. 让我们来选择一部分训练集来加速训练:
>>> gs_clf = gs_clf.fit(twenty_train.data[:400], twenty_train.target[:400])
在 GridSearchCV
中使用 fit
,因此我们也能够使 predict
:
>>> twenty_train.target_names[gs_clf.predict(['God is love'])[0]] 'soc.religion.christian'
对象 best_score_
和 best_params_
存放了最佳的平均分数以及其所对应的参数:
>>> gs_clf.best_score_ 0.900... >>> for param_name in sorted(parameters.keys()): ... print("%s: %r" % (param_name, gs_clf.best_params_[param_name])) ... clf__alpha: 0.001 tfidf__use_idf: True vect__ngram_range: (1, 1)
更多的详细信息可以在 gs_clf.cv_results_
中发现.
cv_results_
参数也能够被导入进 DataFrame
,供后期使用.
练习
为了做这个练习, 请拷贝 ‘skeletons’ 文件夹到新的文件夹,并将其命名为 ‘workspace’:
% cp -r skeletons workspace
这时候可以任意更改练习的代码而不会破坏原始的代码结构.
然后启动 ipython 交互环境,并键入以下代码:
[1] %run workspace/exercise_XX_script.py arg1 arg2 arg3
如果出现错误, 请使用 %debug
来启动 ipdb 调试环境.
迭代更改答案直到练习完成.
在每个练习中, skeleton 文件包含了做练习使用的一切数据及代码.
练习 1:语言识别
%run workspace/exercise_01_language_train_model.py data/languages/paragraphs/
练习 2:电影评论上的情绪分析
%run workspace/exercise_02_sentiment.py data/movie_reviews/txt_sentoken/
练习 3:CLI 文本分类实用程序
快速链接
中文文档: http://sklearn.apachecn.org/cn/stable/tutorial/text_analytics/working_with_text_data.html
英文文档: http://sklearn.apachecn.org/en/stable/tutorial/text_analytics/working_with_text_data.html
官方文档: http://scikit-learn.org/stable/
GitHub: https://github.com/apachecn/scikit-learn-doc-zh(觉得不错麻烦给个 Star,我们一直在努力)
贡献者: https://github.com/apachecn/scikit-learn-doc-zh#贡献者
关于我们: http://www.apachecn.org/organization/209.html
有兴趣的们也可以和我们一起来维护,持续更新中 。。。
机器学习交流群: 629470233
【Scikit-Learn 中文文档】处理文本数据 - scikit-learn 教程 | ApacheCN相关推荐
- 【Scikit-Learn 中文文档】流形学习 - 监督学习 - 用户指南 | ApacheCN
中文文档: http://sklearn.apachecn.org/cn/stable/modules/manifold.html 英文文档: http://sklearn.apachecn.org/ ...
- 【Scikit-Learn 中文文档】特征提取 - 数据集转换 - 用户指南 | ApacheCN
中文文档: http://sklearn.apachecn.org/cn/stable/modules/feature_extraction.html 英文文档: http://sklearn.apa ...
- 【Scikit-Learn 中文文档】集成方法 - 监督学习 - 用户指南 | ApacheCN
中文文档: http://sklearn.apachecn.org/cn/stable/modules/ensemble.html 英文文档: http://sklearn.apachecn.org/ ...
- 【Scikit-Learn 中文文档】广义线性模型 - 监督学习 - 用户指南 | ApacheCN
中文文档: http://sklearn.apachecn.org/cn/0.19.0/tutorial/basic/tutorial.html 英文文档: http://sklearn.apache ...
- 【Scikit-Learn 中文文档】概率校准 - 监督学习 - 用户指南 | ApacheCN
中文文档: http://sklearn.apachecn.org/cn/0.19.0/modules/calibration.html 英文文档: http://sklearn.apachecn.o ...
- 官方中文文档上线了!Python各种教程已汉化。
终于,Python有官方中文文档了. 从今往后,不论是版本新变化,入门教程,语法讲解,Python模块安装指南--各种各样的手册,都可以直接看中文了. 你看,比起英文原版,中文的语气好像更加鸡冻一些: ...
- React-Redux 中文文档
介绍 快速开始 React-Redux是Redux的官方React绑定库.它能够使你的React组件从Redux store中读取数据,并且向store分发actions以更新数据 安装 在你的Rea ...
- 最新 | Python 官方中文文档正式发布!
点击上方"AI有道",选择"置顶"公众号 重磅干货,第一时间送达 千呼万唤始出来!Python 官方文档终于发布中文版了!受英语困扰的小伙伴终于可以更轻松地阅读 ...
- 【Scikit-Learn 中文文档】34 预处理数据 - 数据集转换 - 用户指南 | ApacheCN
中文文档: http://sklearn.apachecn.org/cn/stable/modules/preprocessing.html 英文文档: http://sklearn.apachecn ...
- 【Scikit-Learn 中文文档】数据集加载工具 - 用户指南 | ApacheCN
中文文档: http://sklearn.apachecn.org/cn/stable/datasets/index.html 英文文档: http://sklearn.apachecn.org/en ...
最新文章
- git——从远程库克隆
- MySQL中MyISAM 与innoDB的区别(转)
- Linux-awk及内置变量
- PHP 实现列出目录的内容
- 恭喜了!5 月逼自己学下这项技能,年薪 35 万起
- 成为一名斜杠程序员,你还差点什么?
- jar包的生成及运行
- [BZOJ3506] [Cqoi2014] 排序机械臂 (splay)
- spring源码学习(1)- bean
- 802.1q VLAN
- OpenCV人工智能图像处理学习笔记1目录
- css中换行的几种方式
- 线性代数知识点汇总:行列式和矩阵
- Dennis Gabor与全息摄影
- 除了Navicat和DBeaver,还有没有免费又好用的数据库管理工具推荐
- 大数据最佳实践-hbase
- Python3爬取企查查网站的企业年表并存入MySQL
- leetcode 周赛214 学习笔记(5561、1647)
- 关于一个大学生如何利用编程赚钱
- 对盖得排行APP内容方面的一些看法