使用文本数据

本指南的目标是探讨scikit-learn 一个实际任务中的一些主要工具:分析二十个不同主题的文本文档(新闻组帖子)集合。

在本节中,我们将看到如何:

  • 加载文件内容和类别
  • 提取适用于机器学习的特征向量
  • 训练线性模型进行分类
  • 使用网格搜索策略来查找特征提取组件和分类器的良好配置

教程设置

要开始使用本教程,您首先必须安装 scikit-learn及其所有必需的依赖项。

有关详细信息和每个系统的说明,请参阅安装说明页面。

本教程的源码可以在您的scikit-learn文件夹中找到:

  1. scikit - learn / doc / tutorial / text_analytics /

该教程文件夹应包含以下文件夹:

  • *.rst files - 使用sphinx编写的教程文档的源代码
  • data - 用于放置教程中使用的数据集的文件夹
  • skeletons - 练习的示例不完整脚本
  • solutions - 练习的解决方案

您可以将骨架复制到您的硬盘驱动器上的某个位置的新文件夹中sklearn_tut_workspace,您将在其中编辑自己的文件以进行练习,同时保持原始的骨架不变:

  1. cp - r skeletonons work_directory / sklearn_tut_workspace

机器学习算法需要数据。转到每个$TUTORIAL_HOME/data 子文件夹并fetch_data.py从那里运行脚本(首先阅读它们之后)。

例如:

  1. cd $ TUTORIAL_HOME / data / languages
  2. fetch_data.py
  3. python fetch_data.py

加载20个新闻组数据集

数据集称为“二十新闻组”。这是官方的说明,从网站引用:

20个新闻组数据集是大约20,000个新闻组文档的集合,在20个不同的新闻组中平均分配(几乎)。据我们所知,它最初是由肯朗收集的,可能是他的论文“Newsweeder:学习过滤网络新闻”,虽然他没有明确提及这个集合。20个新闻组集合已成为机器学习技术的文本应用中的实验的流行数据集,如文本分类和文本聚类。

在下面我们将使用内置的数据集加载器来从scikit学习的20个新闻组。或者,可以从网站手动下载数据集,并通过将该sklearn.datasets.load_files 功能指向20news-bydate-train未压缩归档文件夹的子文件夹来使用该功能。

为了在第一个例子中获得更快的执行时间,我们将在数据集中的20个可用数据集中仅处理4个类别的部分数据集:

>>>

  1. >>> categories = ['alt.atheism', 'soc.religion.christian',
  2. ... 'comp.graphics', 'sci.med']

我们现在可以加载与这些类别匹配的文件列表,如下所示:

>>>

  1. >>> from sklearn.datasets import fetch_20newsgroups
  2. >>> twenty_train = fetch_20newsgroups(subset='train',
  3. ... categories=categories, shuffle=True, random_state=42)

返回的数据集是一个scikit-learn“束”:一个简单的持有者对象,其字段可以作为python dict 键或object属性被方便地访问,例如 target_names保存所请求的类别名称的列表:

>>>

  1. >>> twenty_train.target_names
  2. ['alt.atheism', 'comp.graphics', 'sci.med', 'soc.religion.christian']

文件本身被加载到data属性的内存中。作为参考,文件名也可用:

>>>

  1. >>> len(twenty_train.data)
  2. 2257
  3. >>> len(twenty_train.filenames)
  4. 2257

我们先打印第一个加载文件的第一行:

>>>

  1. >>> print("\n".join(twenty_train.data[0].split("\n")[:3]))
  2. From: sd345@city.ac.uk (Michael Collier)
  3. Subject: Converting images to HP LaserJet III?
  4. Nntp-Posting-Host: hampton
  5.  
  6. >>> print(twenty_train.target_names[twenty_train.target[0]])
  7. comp.graphics

受监督的学习算法将需要训练集中的每个文档的类别标签。在这种情况下,类别是新闻组的名称,它也恰好是保存单个文档的文件夹的名称。

为了速度和空间效率的原因,scikit-learn将目标属性加载为与target_names列表中类别名称的索引对应的整数数组。每个样本的类别整数id存储在target属性中:

>>>

  1. >>> twenty_train.target[:10]
  2. array([1, 1, 3, 3, 3, 3, 3, 2, 2, 2])

可以如下回到类别名称:

>>>

  1. >>> for t in twenty_train.target[:10]:
  2. ... print(twenty_train.target_names[t])
  3. ...
  4. comp.graphics
  5. comp.graphics
  6. soc.religion.christian
  7. soc.religion.christian
  8. soc.religion.christian
  9. soc.religion.christian
  10. soc.religion.christian
  11. sci.med
  12. sci.med
  13. sci.med

您可以注意到样品已经随机洗牌(使用固定的RNG种子):如果您仅选择第一个样品来快速培养模型并在完成数据集之前重新训练之前获得结果的第一个想法,这很有用。

从文本文件中提取特征

为了对文本文档执行机器学习,我们首先需要将文本内容转换为数字特征向量。

袋子

最直观的方式是这样做:

  1. 为训练集的任何文档中发生的每个单词分配一个固定的整数id(例如通过从单词到整数索引建立词典)。
  2. 对于每个文档#i,对每个单词的出现次数进行计数w,并将其存储为特征值, 其中是词典中的单词索引X[i, j]#jjw

词汇表示意味着n_features语料库中不同单词的数量:这个数字通常大于100,000。

如果存储为float32类型的numpy数组将需要10000 x 100000 x 4字节= 4GB的RAM,这在今天的计算机上几乎不可管理。n_samples == 10000X

幸运的是,X中的大多数值将为零,因为对于给定的文档,将少于几千个不同的单词将被使用。因此,我们说袋子里的单词通常是 高维稀疏数据集。通过将特征向量的非零部分存储在存储器中,可以节省大量的存储空间。

scipy.sparse矩阵是完全这样做的数据结构,并且scikit-learn内置了对这些结构的支持。

用表征文本scikit-learn

文本预处理,令牌化和过滤的无效词包含在高级组件中,能够构建特征字典并将文档转换为特征向量:

>>>

  1. >>> from sklearn.feature_extraction.text import CountVectorizer
  2. >>> count_vect = CountVectorizer()
  3. >>> X_train_counts = count_vect.fit_transform(twenty_train.data)
  4. >>> X_train_counts.shape
  5. (2257, 35788)

CountVectorizer支持N克单词或连续字符的计数。一旦装配,矢量化器已经建立了一个特征索引字典:

>>>

  1. >>> count_vect.vocabulary_.get(u'algorithm')
  2. 4690

词汇中单词的索引值与其在整个训练语料库中的频率相关。

从出现到频率

发生次数是一个好的开始,但有一个问题:更长的文档将具有比较短的文档更高的平均值,即使他们可能会讨论相同的主题。

为了避免这些潜在的差异,将文档中每个单词的出现次数除以文档中的单词总数就足够了:这些新功能被称为tf“术语频率”。

在tf之上的另一个改进是对在语料库中的许多文档中出现的单词进行缩减权重,因此比仅在较小部分语料库中发生的单词更少的信息量。

这个缩减被称为tf-idf,用于“Term Frequency times Inverse Document Frequency”。

两个TFTF-IDF可以计算如下:

>>>

  1. >>> from sklearn.feature_extraction.text import TfidfTransformer
  2. >>> tf_transformer = TfidfTransformer(use_idf=False).fit(X_train_counts)
  3. >>> X_train_tf = tf_transformer.transform(X_train_counts)
  4. >>> X_train_tf.shape
  5. (2257, 35788)

在上面的示例代码中,我们首先使用该fit(..)方法将我们的估计器与数据进行匹配,其次是transform(..)将我们的计数矩阵转换为tf-idf表示法的方法。通过跳过冗余处理,可以组合这两个步骤,以更快地实现相同的最终结果。这是通过使用fit_transform(..)如下所示的方法完成的 ,如上一节中的注释所述:

>>>

  1. >>> tfidf_transformer = TfidfTransformer()
  2. >>> X_train_tfidf = tfidf_transformer.fit_transform(X_train_counts)
  3. >>> X_train_tfidf.shape
  4. (2257, 35788)

训练分类器

现在我们有了我们的功能,我们可以训练一个分类器来尝试预测一个职位的类别。让我们从一个朴素的贝叶斯 分类器开始,为这个任务提供了一个很好的基准。scikit-learn包括该分类器的几个变体; 最适合单词计数的是多项式:

>>>

  1. >>> from sklearn.naive_bayes import MultinomialNB
  2. >>> clf = MultinomialNB().fit(X_train_tfidf, twenty_train.target)

为了尝试预测新文档的结果,我们需要使用与以前几乎相同的特征提取链来提取特征。不同的是,我们所说transform的,而不是fit_transform 对变压器,因为它们已经适应训练集:

>>>

  1. >>> docs_new = ['God is love', 'OpenGL on the GPU is fast']
  2. >>> X_new_counts = count_vect.transform(docs_new)
  3. >>> X_new_tfidf = tfidf_transformer.transform(X_new_counts)
  4.  
  5. >>> predicted = clf.predict(X_new_tfidf)
  6.  
  7. >>> for doc, category in zip(docs_new, predicted):
  8. ... print('%r => %s' % (doc, twenty_train.target_names[category]))
  9. ...
  10. 'God is love' => soc.religion.christian
  11. 'OpenGL on the GPU is fast' => comp.graphics

建立管道

为了使vectorizer => transformer =>分类器更容易​​使用,scikit-learn提供了一个Pipeline类似复合分类器的类:

>>>

  1. >>> from sklearn.pipeline import Pipeline
  2. >>> text_clf = Pipeline([('vect', CountVectorizer()),
  3. ... ('tfidf', TfidfTransformer()),
  4. ... ('clf', MultinomialNB()),
  5. ... ])

名称vecttfidfclf(分类)是任意的。我们将在下面的网格搜索部分看到他们的使用。我们现在可以用一个命令来训练模型:

>>>

  1. >>> text_clf = text_clf.fit(twenty_train.data, twenty_train.target)

测试集上的性能评估

评估模型的预测准确性同样容易:

>>>

  1. >>> import numpy as np
  2. >>> twenty_test = fetch_20newsgroups(subset='test',
  3. ... categories=categories, shuffle=True, random_state=42)
  4. >>> docs_test = twenty_test.data
  5. >>> predicted = text_clf.predict(docs_test)
  6. >>> np.mean(predicted == twenty_test.target)
  7. 0.834...

即,我们达到83.4%的准确度。让我们看看我们是否可以用线性支持向量机(SVM)来做得更好,这是广泛认为是最好的文本分类算法之一(尽管它也比初学贝叶斯慢一点)。我们可以通过将不同的分类对象插入到我们的管道中来改变学习者:

>>>

  1. >>> from sklearn.linear_model import SGDClassifier
  2. >>> text_clf = Pipeline([('vect', CountVectorizer()),
  3. ... ('tfidf', TfidfTransformer()),
  4. ... ('clf', SGDClassifier(loss='hinge', penalty='l2',
  5. ... alpha=1e-3, n_iter=5, random_state=42)),
  6. ... ])
  7. >>> _ = text_clf.fit(twenty_train.data, twenty_train.target)
  8. >>> predicted = text_clf.predict(docs_test)
  9. >>> np.mean(predicted == twenty_test.target)
  10. 0.912...

scikit-learn 进一步提供实用程序以更详细地对结果进行性能分析:

>>>

  1. >>> from sklearn import metrics
  2. >>> print(metrics.classification_report(twenty_test.target, predicted,
  3. ... target_names=twenty_test.target_names))
  4. ...
  5. precision recall f1-score support
  6.  
  7. alt.atheism 0.95 0.81 0.87 319
  8. comp.graphics 0.88 0.97 0.92 389
  9. sci.med 0.94 0.90 0.92 396
  10. soc.religion.christian 0.90 0.95 0.93 398
  11.  
  12. avg / total 0.92 0.91 0.91 1502
  13.  
  14. >>> metrics.confusion_matrix(twenty_test.target, predicted)
  15. array([[258, 11, 15, 35],
  16. [ 4, 379, 3, 3],
  17. [ 5, 33, 355, 3],
  18. [ 5, 10, 4, 379]])

如预期的那样,混乱矩阵表明,无神论和基督教的新闻组的帖子比计算机图形更容易彼此混淆。

参数整定使用格搜索

我们已经遇到了一些参数,如use_idf在 TfidfTransformer。分类器也有许多参数; 例如,MultinomialNB包括一个平滑参数alpha, 并且在目标函数中SGDClassifier具有惩罚参数alpha和可配置的损失和惩罚项(参见模块文档,或使用Python help函数来获取这些描述)。

而不是调整链的各种组件的参数,可以对可能值的网格上的最佳参数进行详尽的搜索。我们尝试使用或不使用idf的单词或双字母分隔符,对于线性SVM,可以使用0.01或0.001的惩罚参数:

>>>

  1. >>> from sklearn.model_selection import GridSearchCV
  2. >>> parameters = {'vect__ngram_range': [(1, 1), (1, 2)],
  3. ... 'tfidf__use_idf': (True, False),
  4. ... 'clf__alpha': (1e-2, 1e-3),
  5. ... }

显然,这种详尽的搜索可能是昂贵的。如果我们拥有多个CPU内核,我们可以告诉电网搜索者与参数并行地尝试这八个参数组合n_jobs。如果我们给这个参数一个值-1,网格搜索将会检测到安装了多少个内核并使用它们:

>>>

  1. >>> gs_clf = GridSearchCV(text_clf, parameters, n_jobs=-1)

网格搜索实例的行为与普通scikit-learn 模型类似。让我们在较小的训练数据子集上进行搜索,以加速计算:

>>>

  1. >>> gs_clf = gs_clf.fit(twenty_train.data[:400], twenty_train.target[:400])

调用的结果fit一上GridSearchCV对象的分类,我们可以用它来predict

>>>

  1. >>> twenty_train.target_names[gs_clf.predict(['God is love'])[0]]
  2. 'soc.religion.christian'

对象best_score_best_params_属性存储与该分数相对应的最佳平均分数和参数设置:

>>>

  1. >>> gs_clf.best_score_
  2. 0.900...
  3. >>> for param_name in sorted(parameters.keys()):
  4. ... print("%s: %r" % (param_name, gs_clf.best_params_[param_name]))
  5. ...
  6. clf__alpha: 0.001
  7. tfidf__use_idf: True
  8. vect__ngram_range: (1, 1)

更详细的搜索摘要可在gs_clf.cv_results_

cv_results_参数可以很容易地导入熊猫作为 DataFrame进一步检查。

练习

要做练习,将“skeleton”文件夹的内容复制为名为“workspace”的新文件夹:

  1. % cp -r skeletons workspace

然后,您可以编辑工作区的内容,而不用担心丢失原始的运动说明。

然后启动一个ipython shell并运行正在进行的工作脚本:

  1. [1] %run workspace/exercise_XX_script.py arg1 arg2 arg3

如果触发了异常,则可以使用%debug来启动post mortem ipdb会话。

优化实施并重复运算直到练习解决。

对于每个练习,骨架文件提供了所有必需的导入语句,样板代码来加载数据和样本代码,以评估模型的预测准确性。

练习1:语言识别

  • 使用自定义预处理器编写文本分类管道,并 CharNGramAnalyzer使用维基百科文章中的数据作为培训集。
  • 评估某些测试套件的性能。

ipython命令行:

  1. %run workspace/exercise_01_language_train_model.py data/languages/paragraphs/

练习2:电影评论的情绪分析

  • 写一个文本分类管道将电影评论分为正面或负面。
  • 使用网格搜索找到一组好的参数。
  • 评估一个持有的测试集的性能。

ipython命令行:

  1. %run workspace/exercise_02_sentiment.py data/movie_reviews/txt_sentoken/

练习3:CLI文本分类实用程序

使用以前练习的结果和cPickle 标准库的模块,编写一个命令行实用程序,用于检测提供的一些文本的语言,stdin并且如果文本用英语写成,则可以估计极性(正或负)。

奖金点,如果公用事业能够给出其预测的置信水平。

从这里到

以下是一些建议,以帮助您在完成本教程后进一步提高您的scikit学习直觉:

使用文本数据

本指南的目标是探讨scikit-learn 一个实际任务中的一些主要工具:分析二十个不同主题的文本文档(新闻组帖子)集合。

在本节中,我们将看到如何:

  • 加载文件内容和类别
  • 提取适用于机器学习的特征向量
  • 训练线性模型进行分类
  • 使用网格搜索策略来查找特征提取组件和分类器的良好配置

教程设置

要开始使用本教程,您首先必须安装 scikit-learn及其所有必需的依赖项。

有关详细信息和每个系统的说明,请参阅安装说明页面。

本教程的源码可以在您的scikit-learn文件夹中找到:

  1. scikit - learn / doc / tutorial / text_analytics /

该教程文件夹应包含以下文件夹:

  • *.rst files - 使用sphinx编写的教程文档的源代码
  • data - 用于放置教程中使用的数据集的文件夹
  • skeletons - 练习的示例不完整脚本
  • solutions - 练习的解决方案

您可以将骨架复制到您的硬盘驱动器上的某个位置的新文件夹中sklearn_tut_workspace,您将在其中编辑自己的文件以进行练习,同时保持原始的骨架不变:

  1. cp - r skeletonons work_directory / sklearn_tut_workspace

机器学习算法需要数据。转到每个$TUTORIAL_HOME/data 子文件夹并fetch_data.py从那里运行脚本(首先阅读它们之后)。

例如:

  1. cd $ TUTORIAL_HOME / data / languages
  2. fetch_data.py
  3. python fetch_data.py

加载20个新闻组数据集

数据集称为“二十新闻组”。这是官方的说明,从网站引用:

20个新闻组数据集是大约20,000个新闻组文档的集合,在20个不同的新闻组中平均分配(几乎)。据我们所知,它最初是由肯朗收集的,可能是他的论文“Newsweeder:学习过滤网络新闻”,虽然他没有明确提及这个集合。20个新闻组集合已成为机器学习技术的文本应用中的实验的流行数据集,如文本分类和文本聚类。

在下面我们将使用内置的数据集加载器来从scikit学习的20个新闻组。或者,可以从网站手动下载数据集,并通过将该sklearn.datasets.load_files 功能指向20news-bydate-train未压缩归档文件夹的子文件夹来使用该功能。

为了在第一个例子中获得更快的执行时间,我们将在数据集中的20个可用数据集中仅处理4个类别的部分数据集:

>>>

  1. >>> 类别 = [ 'alt.atheism' 'soc.religion.christian'
  2. ... 'comp.graphics' ' sci.med ' ]

我们现在可以加载与这些类别匹配的文件列表,如下所示:

>>>

  1. >>> from sklearn.datasets import fetch_20newsgroups
  2. >>> twenty_train = fetch_20newsgroups subset = 'train'
  3. ... categories = categories shuffle = True random_state = 42

返回的数据集是一个scikit-learn“束”:一个简单的持有者对象,其字段可以作为python dict 键或object属性被方便地访问,例如 target_names保存所请求的类别名称的列表:

>>>

  1. >>> twenty_train target_names
  2. ['alt.atheism''comp.graphics''sci.med''soc.religion.christian']

文件本身被加载到data属性的内存中。作为参考,文件名也可用:

>>>

  1. >>> LEN twenty_train 。数据)
  2. 2257
  3. >>> LEN twenty_train 。文件名)
  4. 2257

我们先打印第一个加载文件的第一行:

>>>

  1. >>> 打印(“ \ n 。加入(twenty_train 。数据[ 0 ] 。分裂(“ \ n )[:3 ]))
  2. 来自:sd345@city.ac.uk(迈克尔科利尔)
  3. 主题:将图像转换为HP LaserJet III
  4. Nntp-Posting-Host:汉普顿
  5.  
  6. >>> 打印(twenty_train target_names [ twenty_train 。靶向[ 0 ]])
  7. comp.graphics

受监督的学习算法将需要训练集中的每个文档的类别标签。在这种情况下,类别是新闻组的名称,它也恰好是保存单个文档的文件夹的名称。

为了速度和空间效率的原因,scikit-learn将目标属性加载为与target_names列表中类别名称的索引对应的整数数组。每个样本的类别整数id存储在target属性中:

>>>

  1. >>> twenty_train 。目标[:10 ]
  2. 阵列([1133333222])

可以如下回到类别名称:

>>>

  1. >>> 用于 twenty_train 。目标[:10 ]:
  2. ... 打印(twenty_train target_names [ 吨])
  3. ...
  4. comp.graphics
  5. comp.graphics
  6. soc.religion.christian
  7. soc.religion.christian
  8. soc.religion.christian
  9. soc.religion.christian
  10. soc.religion .christian
  11. sci.med
  12. sci.med
  13. sci.med

您可以注意到样品已经随机洗牌(使用固定的RNG种子):如果您仅选择第一个样品来快速培养模型并在完成数据集之前重新训练之前获得结果的第一个想法,这很有用。

从文本文件中提取特征

为了对文本文档执行机器学习,我们首先需要将文本内容转换为数字特征向量。

袋子

最直观的方式是这样做:

  1. 为训练集的任何文档中发生的每个单词分配一个固定的整数id(例如通过从单词到整数索引建立词典)。
  2. 对于每个文档#i,对每个单词的出现次数进行计数w,并将其存储为特征值, 其中是词典中的单词索引X[i, j]#jjw

词汇表示意味着n_features语料库中不同单词的数量:这个数字通常大于100,000。

如果存储为float32类型的numpy数组将需要10000 x 100000 x 4字节= 4GB的RAM,这在今天的计算机上几乎不可管理。n_samples == 10000X

幸运的是,X中的大多数值将为零,因为对于给定的文档,将少于几千个不同的单词将被使用。因此,我们说袋子里的单词通常是 高维稀疏数据集。通过将特征向量的非零部分存储在存储器中,可以节省大量的存储空间。

scipy.sparse矩阵是完全这样做的数据结构,并且scikit-learn内置了对这些结构的支持。

用表征文本scikit-learn

文本预处理,令牌化和过滤的无效词包含在高级组件中,能够构建特征字典并将文档转换为特征向量:

>>>

  1. >>> from sklearn.feature_extraction.text import CountVectorizer
  2. >>> count_vect = CountVectorizer ()
  3. >>> X_train_counts = count_vect fit_transform twenty_train 。数据)
  4. >>> X_train_counts 。形状
  5. 2257,35788

CountVectorizer支持N克单词或连续字符的计数。一旦装配,矢量化器已经建立了一个特征索引字典:

>>>

  1. >>> count_vect vocabulary_ 。得到(ü “算法”
  2. 4690

词汇中单词的索引值与其在整个训练语料库中的频率相关。

从出现到频率

发生次数是一个好的开始,但有一个问题:更长的文档将具有比较短的文档更高的平均值,即使他们可能会讨论相同的主题。

为了避免这些潜在的差异,将文档中每个单词的出现次数除以文档中的单词总数就足够了:这些新功能被称为tf“术语频率”。

在tf之上的另一个改进是对在语料库中的许多文档中出现的单词进行缩减权重,因此比仅在较小部分语料库中发生的单词更少的信息量。

这个缩减被称为tf-idf,用于“Term Frequency times Inverse Document Frequency”。

两个TFTF-IDF可以计算如下:

>>>

  1. >>> from sklearn.feature_extraction.text import TfidfTransformer
  2. >>> tf_transformer = TfidfTransformer use_idf = False )。fit X_train_counts
  3. >>> X_train_tf = tf_transformer transform X_train_counts
  4. >>> X_train_tf 。形状
  5. 2257,35788

在上面的示例代码中,我们首先使用该fit(..)方法将我们的估计器与数据进行匹配,其次是transform(..)将我们的计数矩阵转换为tf-idf表示法的方法。通过跳过冗余处理,可以组合这两个步骤,以更快地实现相同的最终结果。这是通过使用fit_transform(..)如下所示的方法完成的 ,如上一节中的注释所述:

>>>

  1. >>> tfidf_transformer = TfidfTransformer ()
  2. >>> X_train_tfidf = tfidf_transformer fit_transform X_train_counts
  3. >>> X_train_tfidf 。形状
  4. 2257,35788

训练分类器

现在我们有了我们的功能,我们可以训练一个分类器来尝试预测一个职位的类别。让我们从一个朴素的贝叶斯 分类器开始,为这个任务提供了一个很好的基准。scikit-learn包括该分类器的几个变体; 最适合单词计数的是多项式:

>>>

  1. >>> sklearn.naive_bayes 导入 MultinomialNB
  2. >>> CLF = MultinomialNB () 。适合(X_train_tfidf twenty_train 。目标)

为了尝试预测新文档的结果,我们需要使用与以前几乎相同的特征提取链来提取特征。不同的是,我们所说transform的,而不是fit_transform 对变压器,因为它们已经适应训练集:

>>>

  1. >>> docs_new = [ 'God ​​is love' 'OpenGL on the GPU is fast' ]
  2. >>> X_new_counts = count_vect transform docs_new
  3. >>> X_new_tfidf = tfidf_transformer 。变换(X_new_counts
  4.  
  5. >>> 预测 = CLF 。预测(X_new_tfidf
  6.  
  7. >>> DOC 类别 拉链(docs_new 预测):
  8. ... 打印(' %R => %S ' DOC twenty_train target_names [ 类别]))
  9. ...
  10. '神是爱'=> soc.religion.christian'GPU上
  11. 的OpenGL很快'=> comp.graphics

建立管道

为了使vectorizer => transformer =>分类器更容易​​使用,scikit-learn提供了一个Pipeline类似复合分类器的类:

>>>

  1. >>> sklearn.pipeline 进口 管道
  2. >>> text_clf = 管道([('VECT' CountVectorizer ()),
  3. ... 'TFIDF' TfidfTransformer ()),
  4. ... 'CLF' MultinomialNB )),
  5. ... ])

名称vecttfidfclf(分类)是任意的。我们将在下面的网格搜索部分看到他们的使用。我们现在可以用一个命令来训练模型:

>>>

  1. >>> text_clf = text_clf 。配合(twenty_train 。数据, twenty_train 。目标)

测试集上的性能评估

评估模型的预测准确性同样容易:

>>>

  1. >>> import numpy as np
  2. >>> twenty_test = fetch_20newsgroups subset = 'test'
  3. ... categories = categories shuffle = True random_state = 42
  4. >>> docs_test = twenty_test 。数据
  5. >>> 预测 = text_clf 。预测(docs_test
  6. >>> np

即,我们达到83.4%的准确度。让我们看看我们是否可以用线性支持向量机(SVM)来做得更好,这是广泛认为是最好的文本分类算法之一(尽管它也比初学贝叶斯慢一点)。我们可以通过将不同的分类对象插入到我们的管道中来改变学习者:

>>>

  1. ])>>> _ = text_clf 。配合(twenty_train 。数据,twenty_train 。目标)>>> 预测= text_clf 。预测(docs_test )>>> np 。意思是(预测== twenty_test 。目标)0.912 ... 目标)>>> 预测= text_clf 。预测(docs_test )>>> np 。意思是(预测== twenty_test 。目标)0.912 ... 目标)>>> 预测= text_clf 。预测(docs_test )>>> np 。意思是(预测== twenty_test 。目标)0.912 ...

scikit-learn 进一步提供实用程序以更详细地对结果进行性能分析:

>>>

  1. >>> sklearn 进口 度量
  2. >>> 打印(度量。classification_report twenty_test 。目标, 预测,
  3. ... target_names = twenty_test target_names ))
  4. ...
  5. 精度召回F1-得分支持
  6.  
  7. 替代性主义0.95 0.81 0.87 319
  8. comp.graphics 0.88 0.97 0.92 389
  9. sci.med 0.94 0.90 0.92 396
  10. soc.religion.christian 0.90 0.95 0.93 398
  11.  
  12. 平均/总0.92 0.91 0.91 1502
  13.  
  14. >>> 指标。confusion_matrix twenty_test 。目标, 预测)
  15. 阵列([[258111535],
  16. [437933],
  17. [5333553],
  18. [5104379] ])

如预期的那样,混乱矩阵表明,无神论和基督教的新闻组的帖子比计算机图形更容易彼此混淆。

参数整定使用格搜索

我们已经遇到了一些参数,如use_idf在 TfidfTransformer。分类器也有许多参数; 例如,MultinomialNB包括一个平滑参数alpha, 并且在目标函数中SGDClassifier具有惩罚参数alpha和可配置的损失和惩罚项(参见模块文档,或使用Python help函数来获取这些描述)。

而不是调整链的各种组件的参数,可以对可能值的网格上的最佳参数进行详尽的搜索。我们尝试使用或不使用idf的单词或双字母分隔符,对于线性SVM,可以使用0.01或0.001的惩罚参数:

>>>

  1. >>> sklearn.model_selection 进口 GridSearchCV
  2. >>> 参数 = { 'vect__ngram_range' [(1 1 ), 1 2 )],
  3. ... 'tfidf__use_idf' :( 真,假),... ' clf__alpha” :(1E-2 ,1E-3 ),... }

显然,这种详尽的搜索可能是昂贵的。如果我们拥有多个CPU内核,我们可以告诉电网搜索者与参数并行地尝试这八个参数组合n_jobs。如果我们给这个参数一个值-1,网格搜索将会检测到安装了多少个内核并使用它们:

>>>

  1. >>> gs_clf = GridSearchCV text_clf parameters n_jobs = - 1

网格搜索实例的行为与普通scikit-learn 模型类似。让我们在较小的训练数据子集上进行搜索,以加速计算:

>>>

  1. >>> gs_clf = gs_clf 。适合(twenty_train 。数据[:400 ], twenty_train 。目标[:400 ])

调用的结果fit一上GridSearchCV对象的分类,我们可以用它来predict

>>>

  1. >>> twenty_train target_names [ gs_clf 。预测([ '上帝是爱' ])[ 0 ]]
  2. 'soc.religion.christian'

对象best_score_best_params_属性存储与该分数相对应的最佳平均分数和参数设置:

>>>

  1. >>> gs_clf best_score_
  2. 0.900 ...
  3. >>> PARAM_NAME 排序(参数。键()):
  4. ... 打印(“ S :%R PARAM_NAME gs_clf best_params_ [ PARAM_NAME ]))
  5. ...
  6. clf__alpha0.001
  7. tfidf__use_idfTrue
  8. vect__ngram_range:(11

更详细的搜索摘要可在gs_clf.cv_results_

cv_results_参数可以很容易地导入熊猫作为 DataFrame进一步检查。

练习

要做练习,将“skeleton”文件夹的内容复制为名为“workspace”的新文件夹:

  1. cp - r 骨架 工作区

然后,您可以编辑工作区的内容,而不用担心丢失原始的运动说明。

然后启动一个ipython shell并运行正在进行的工作脚本:

  1. [ 1 ] run workspace / exercise_XX_script py arg1 arg2 arg3

如果触发了异常,则可以使用%debug来启动post mortem ipdb会话。

优化实施并重复运算直到练习解决。

对于每个练习,骨架文件提供了所有必需的导入语句,样板代码来加载数据和样本代码,以评估模型的预测准确性。

练习1:语言识别

  • 使用自定义预处理器编写文本分类管道,并 CharNGramAnalyzer使用维基百科文章中的数据作为培训集。
  • 评估某些测试套件的性能。

ipython命令行:

  1. run workspace / exercise_01_language_train_model py 数据/ 语言/ 段落/

练习2:电影评论的情绪分析

  • 写一个文本分类管道将电影评论分为正面或负面。
  • 使用网格搜索找到一组好的参数。
  • 评估一个持有的测试集的性能。

ipython命令行:

  1. run workspace / exercise_02_sentiment py data / movie_reviews / txt_sentoken /

练习3:CLI文本分类实用程序

使用以前练习的结果和cPickle 标准库的模块,编写一个命令行实用程序,用于检测提供的一些文本的语言,stdin并且如果文本用英语写成,则可以估计极性(正或负)。

奖金点,如果公用事业能够给出其预测的置信水平。

从这里到

以下是一些建议,以帮助您在完成本教程后进一步提高您的scikit学习直觉:

scikit-learning教程(三)使用文本数据的更多相关文章

  1. CRL快速开发框架系列教程三(更新数据)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

  2. 基础学习总结(三)--文本、SD卡数据读写

    简单的文本数据写入文件不需要权限,读写SD卡在4.0版本前需要写权限.在4.0后需要读写权限 布局: <LinearLayout xmlns:android="http://schem ...

  3. Deep learning:三十八(Stacked CNN简单介绍)

    http://www.cnblogs.com/tornadomeet/archive/2013/05/05/3061457.html 前言: 本节主要是来简单介绍下stacked CNN(深度卷积网络 ...

  4. 如何使用 scikit-learn 为机器学习准备文本数据

    欢迎大家前往云+社区,获取更多腾讯海量技术实践干货哦~ 文本数据需要特殊处理,然后才能开始将其用于预测建模. 我们需要解析文本,以删除被称为标记化的单词.然后,这些词还需要被编码为整型或浮点型,以用作 ...

  5. NLP相关问题中文本数据特征表达初探

    1. NLP问题简介 0x1:NLP问题都包括哪些内涵 人们对真实世界的感知被成为感知世界,而人们用语言表达出自己的感知视为文本数据.那么反过来,NLP,或者更精确地表达为文本挖掘,则是从文本数据出发 ...

  6. Deep Learning 教程翻译

    Deep Learning 教程翻译 非常激动地宣告,Stanford 教授 Andrew Ng 的 Deep Learning 教程,于今日,2013年4月8日,全部翻译成中文.这是中国屌丝军团,从 ...

  7. Hand on Machine Learning第三章课后作业(1):垃圾邮件分类

    import os import email import email.policy 1. 读取邮件数据 SPAM_PATH = os.path.join( "E:\\3.Study\\机器 ...

  8. Elasticsearch入门教程(三):Elasticsearch索引&映射

    原文:Elasticsearch入门教程(三):Elasticsearch索引&映射 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文 ...

  9. CRL快速开发框架系列教程九(导入/导出数据)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

随机推荐

  1. linux块设备驱动(一)——块设备概念介绍

    本文来源于: 1. http://blog.csdn.net/jianchi88/article/details/7212370 2. http://blog.chinaunix.net/uid-27 ...

  2. 项目Beta冲刺(团队3/7)

    项目Beta冲刺(团队3/7) 团队名称: 云打印 作业要求: 项目Beta冲刺(团队) 作业目标: 完成项目Beta版本 团队队员 队员学号 队员姓名 个人博客地址 备注 221600412 陈宇 ...

  3. Xcode6.1 Prefix.pch添加方式

     本文转载:http://blog.csdn.net/foolsong/article/details/40653497     在Xcode6.1中创建工程默认是没有Prefix.pch文件的,需要 ...

  4. MapReduce算法形式六:只有Map独自作战

    案例六:Map独自直接输出 之前一直没有用过这个map独自输出的模式,就算是输出一些简单的我也会经过一次reduce输出,但是,发现这个map输出的结果跟我预想的有点不一样,我一直以为shuffle的 ...

  5. Multitier architecture

    Multitier architecture - Wikipedia https://en.wikipedia.org/wiki/Multitier_architecture Common layer ...

  6. Java,多个线程对同一个数据源的访问

    当多个线程对同一个数据源进行访问时,应对线程同步或加锁.为何?举个简单的例子:有一个共享的数据源dataSource,其值为0.有两个线程,Thread1和Thread2.Thread1的任务是将da ...

  7. HDU 6119 小小粉丝度度熊 【预处理+尺取法】(2017"百度之星"程序设计大赛 - 初赛(B))

    小小粉丝度度熊 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Sub ...

  8. YTU 1439: 2.4.5 Fractions to Decimals 分数化小数

    1439: 2.4.5 Fractions to Decimals 分数化小数 时间限制: 1 Sec  内存限制: 64 MB 提交: 194  解决: 13 题目描述 写一个程序,输入一个形如N/ ...

  9. Axios 请求配置参数详解

    axios API 可以通过向 axios 传递相关配置来创建请求 axios(config)   // 发送 POST 请求   axios({   method: 'post',   url: ' ...

  10. jQuery常用插件大全(9)ResponsiveSlides插件

    ResponsiveSlides.js是一个展示同一容器内图片的轻量级响应式jQuery幻灯片插件(tiny responsive slideshow jQuery plugin).它支持包括IE6在 ...