欢迎访问集智主站: 集智, 通向智能时代的引擎
在使用机器学习方法解决实际问题的时候, 往往我们所得到的并不是纯粹的数据文件, 它们有可能是图片文本视频等包含有效信息的复杂数据, 这时候就需要我们从这些数据中提取数字特征, 以便于我们之后的分析和训练过程本节将介绍 Scikit-learn 中可用于文本分类的一些功能, 它们包括
从硬盘读取文本内容和分类信息
从文本信息中提取可用于机器学习过程的特征向量
关于具体的使用文本特征进行模型训练评估和优化过程, 我们将在下一节的文章中进行讨论
获取数据文件
首先来了解我们所要用到的数据集本文所用到的数据集被称为 20 种新闻组, 是一个经常被用来进行机器学习和自然语言处理的数据集它包含 20 种新闻类别的近 20000 篇新闻, 其官方简介可参见 http://qwone.com/~jason/20Newsgroups/
我们有多种方式来获取这个数据集, 一种简单的方法是使用 sclearn 的自带函数
sklearn.datasets.fetch_20newsgroups
这个函数能自动从网上下载 20 种新闻组的数据并进行读取, 示例如下为了节省计算和处理的时间, 我们仅选取 20 种分类中的四种进行之后的分析工作
注意: 由于数据包体积较大且数据源地址在国外, 下述示例运行将比较缓慢, 因此不提供运行
- from sklearn.datasets import fetch_20newsgroups
- # 选取需要下载的新闻分类
- categories = ["alt.atheism", "soc.religion.christian",
- "comp.graphics", "sci.med"]
- # 下载并获取训练数据
- twenty_train = fetch_20newsgroups(subset="train",
- categories=categories, shuffle=True, random_state=42)
- # 显示训练数据的分类
- twenty_train.target_names
当然, 我们更常用的方法是直接从网络下载我们所需要的数据我们可以用 Python 所提供的 urllib 库来完成数据包的下载工作, 并解压从网络下载文件可以使用
urllib.request.urlretrieve
这个函数通常, 我们下载到的数据包都是压缩文件, 这时候我们可以使用 tarfile 这个库来完成, 如下面的例子所示
- # 从网络下载数据包
- from urllib import request
- request.urlretrieve("http://jizhi-10061919.cos.myqcloud.com/sklearn/20news-bydate.tar.gz", "data.tar.gz")
- # 解压下载的数据包
- import tarfile
- tar = tarfile.open("data.tar.gz", "r:gz")
- tar.extractall()
- tar.close()
- # 选取需要下载的新闻分类
- categories = ['alt.atheism','soc.religion.christian',
- 'comp.graphics', 'sci.med']
- # 从硬盘获取训练数据
- from sklearn.datasets import load_files
- twenty_train = load_files('20news-bydate/20news-bydate-train',
- categories=categories,
- load_content = True,
- encoding='latin1',
- decode_error='strict',
- shuffle=True,random_state=42)
- # 显示训练数据的分类
- print(twenty_train.target_names)
如上所示, 数据包下载完成后, 我们可以使用
sklearn.datasets.load_files
来获取数据我们同样只采集四种分类的文本数据用于分析, 并检查所读取文本数据的一些信息以确定数据已被读取
提取文本特征
无论是什么机器学习方法, 都只能针对向量特征 (也就是一系列的数字组合) 进行分析, 因此在读取文本之后, 我们要将文本转化为数字化的特征向量
词袋模型(Bags of words)
提取文本特征最常用的一种方法就是使用词袋模型, 其具体表述如下: 为训练集文档中所有出现的词语给予一个固定的数字 ID(也就是为所有的词语建立一个由整数进行索引的字典) 对于每一篇文档 #i, 计算每个词语 w 出现的次数并将其记录在 X[i, j]中作为特征 #j 的值, j 代表词语 w 在字典中的位置
词袋模型假设每个数据集中存在 n_features 个不同的单词, 而这个数字通常会超过 100000 这会带来什么问题呢? 考虑一下, 如果采样数 (也就是文档的个数) 为 10000, 特征以 32 位浮点数存储, 则总的文本特征需要
, 而这 4GB 必须全部存储在计算机内存中, 这对于现在的计算机而言几乎是不可能的
幸运的是, 上述方法得到的特征数据中大部分特征数值都会是零值, 这是因为每篇文档实际上仅使用了几百个不同的词汇由于这个原因, 我们将词袋模型称之为高维度稀疏数据集我们可以通过仅存储非零特征来大幅节省内存使用量
scipy.sparse 模型正是处理这个过程的一系列数据结构, 而它们也得到了 scikit-learn 的支持
- from sklearn.feature_extraction.text import CountVectorizer
- count_vect = CountVectorizer()
- X_train_counts = count_vect.fit_transform(twenty_train.data)
- # 打印特征相关信息
- print("训练数据共有 {0} 篇, 词汇计数为 {1} 个".format(X_train_counts.shape[0], X_train_counts.shape[1]))
- # 查看某个词语的计数
- count = count_vect.vocabulary_.get(u'algorithm')
- print("algorithm 的出现次数为{0}".format(count))
- from sklearn.feature_extraction.text import TfidfTransformer
- # 使用 TF-IDF 提取文本特征
- tf_transformer = TfidfTransformer(use_idf=False).fit(X_train_counts)
- X_train_tf = tf_transformer.transform(X_train_counts)
- # 查看特征结果
- X_train_tf.shape
- from sklearn.feature_extraction.text import TfidfTransformer
- tfidf_transformer = TfidfTransformer()
- X_train_tfidf = tfidf_transformer.fit_transform(X_train_counts)
- # 查看特征结果
- X_train_tfidf.shape
来源: https://juejin.im/post/5a8fba41f265da4e976ea370