机器学习算法往往无法直接处理文本数据,需要把文本数据转换为数值型数据,One-Hot表示把文本转换为数值的一种方法。

一,One-Hot表示

One-Hot表示是把语料库中的所有文本进行分词,把所有单词(词汇)收集起来,并对单词进行编号,构建一个词汇表(vocabulary),词汇表是一个字典结构,key是单词,value是单词的索引

vocabulary = { 'one':0,'hot':1, ...'term':n-1}

如果词汇表有n个单词构成,那么单词的索引从0开始,到n-1结束。

有了词汇表之后,就可以使用向量来表示单个词汇。每一个词汇都表示为一个由n列构成的向量,称作词向量,词向量的第0列对应词汇表(vocabulary)中的第0号索引,词向量的第1列对应词汇表(vocabulary)中的第1号索引,依次类推。

词汇向量有n列,但是只有一列的值为1,把值为1的列的索引带入到词汇表(vocabulary)中,就可以查找到该词向量表示的词汇,也就是说,对于某个单词 term,如果它出现在词汇序列中的位置为 k,那么它的向量表示就是“第 k 位为1,其他位置都为0 ”,这就是One-Hot(独热)名称的由来。

1,用One-Hot表示单词

例如,有语料库(corpus)如下:

John likes to watch movies. Mary likes movies too.
John also likes to watch football games.

把上述语料中的词汇整理出来并进行排序(具体的排序原则可以有很多,例如可以根据字母表顺序,也可以根据出现在语料库中的先后顺序),假设我们的词汇表排序结果如下:

{"John": 1, "likes": 2, "to": 3, "watch": 4, "movies": 5, "also":6, "football": 7, "games": 8, "Mary": 9, "too": 10}

那么,得出如下词向量表示:
John: [1, 0, 0, 0, 0, 0, 0, 0, 0, 0] 
likes: [0, 1, 0, 0, 0, 0, 0, 0, 0, 0]
……

2,文档向量

文档向量的表示方法是直接把各词的词向量表示加和,那么原来的两句话的向量表示如下:
[1, 2, 1, 1, 2, 0, 0, 0, 1, 1]

[1, 1, 1, 1, 0, 1, 1, 1, 0, 0]

文档向量中,列的值表示词在文档中出现的次数。

3,One-Hot表示的缺点 

One-Hot方法很简单,但是它的问题也很明显:

  • 没有考虑单词之间的相对位置,任意两个词之间都是孤立的;
  • 如果文档中有很多词,词向量会有很多列,但是只有一个列的值是1;

4,One-Hot表示的应用

sklearn使用词袋(Bag of Words)和TF-IDF模型来表示文本数据,这两个模型都是One-Hot表示的应用,其中,词袋模型对应的就是文档向量。

二,词袋模型

词袋模型(BoW)是用于文本表示的最简单的方法, BoW把文本转换为文档中单词出现次数的矩阵,该模型只关注文档中是否出现给定的单词和单词出现频率,而舍弃文本的结构、单词出现的顺序和位置。

1,构建词袋模型的步骤

对于一个文本语料库,构建词袋模型有三个步骤:

  • 文本分词:把每个文档中的文本进行分词
  • 构建词汇表:把文本分词得到的单词构建为一个词汇表,包含文本语料库中的所有单词,并对单词进行编号,假设词汇表有n个单词,单词编号从0开始,到n-1结束,可以把单词编号看作是单词的索引,通过单词编号可以唯一定位到该单词。
  • 词向量表示:每个单词都表示为一个n列的向量,在单词编号(词汇索引)位置上的列值为1,其他列的值为0
  • 统计频次:统计每个文档中每个单词出现的频次。

举个例子,有如下包含三个文档(doc)的语料库,每个文档是一行文本:

Doc 1: I love dogs.
Doc 2: I hate dogs and knitting.
Doc 3: Knitting is my hobby and passion.

根据语料库,对文本进行分词,创建词汇表。根据词汇表计算每个文档中的单词出现的次数,这个矩阵叫做文档-词矩阵(DTM,Document-Term Matrix)。

这个矩阵使用的是单个词,也可以使用两个或多个词的组合,叫做bi-gram模型或tri-gram模型,统称n-gram模型。

使用sklearn构建词袋模型:

CountVectorizer(input=’content’, encoding=’utf-8’, decode_error=’strict’, strip_accents=None,
lowercase=True, preprocessor=None, tokenizer=None, stop_words=None,
token_pattern=’(?u)\b\w\w+\b’, ngram_range=(1, 1), analyzer=’word’,
max_df=1.0, min_df=1, max_features=None, vocabulary=None, binary=False,
dtype=<class ‘numpy.int64’>)

常用参数注释:

  • input:默认值是content,表示输入的是顺序的字符文本
  • decode_error:默认为strict,遇到不能解码的字符将报UnicodeDecodeError错误,设为ignore将会忽略解码错误
  • lowercase:默认值是True,在分词(Tokenize)之前把文本中的所有字符转换为小写。
  • preprocessor:预处理器,在分词之前对文本进行预处理,默认值是None
  • tokenizer:分词器,把文本字符串拆分成各个单词(token),默认值是None
  • analyzer:用于预处理和分词,可设置为string类型,如’word’, ‘char’, ‘char_wb’,默认值是word
  • stop_words:停用词表,如果值是english,使用内置的英语停用词列表;如果是一个列表,那么使用该列表作为停用词,设为None且max_df∈[0.7, 1.0)将自动根据当前的语料库建立停用词表
  • ngram_range:tuple(min_n,max_n),表示ngram模型的范围
  • max_df:可以设置为范围在[0.0 1.0]的浮点数,也可以设置为没有范围限制的整数,默认为1.0。这个参数的作用是作为一个阈值,当构造语料库的词汇表时,如果某个词的document frequence大于max_df,这个词不会被当作关键词。如果这个参数是float,则表示词出现的次数与语料库文档数的百分比,如果是int,则表示词出现的次数。如果参数中已经给定了vocabulary,则这个参数无效
  • min_df:类似于max_df,不同之处在于如果某个词的document frequence小于min_df,则这个词不会被当作关键词
  • max_features:对所有关键词的term frequency进行降序排序,只取前max_features个作为关键词集
  • vocabulary:默认为None,自动从输入文档中构建关键词集,也可以是一个字典或可迭代对象。
  • binary:默认为False,一个关键词在一篇文档中可能出现n次;如果binary=True,非零的n将全部置为1,这对需要布尔值输入的离散概率模型的有用的
  • dtype :用于设置fit_transform() 或 transform()函数返回的矩阵元素的数据类型

模型的属性和方法:

  • vocabulary_:词汇表,字典类型
  • get_feature_names():所有文本的词汇,列表型
  • stop_words_:停用词列表

模型的主要方法:

  • fit(raw_document):拟合模型,对文本分词,并构建词汇表等
  • transform(raw_documents):把文档转换为文档-词矩阵
  • fit_transform(raw_documents):拟合文档,并返回该文档的文档-词矩阵

2,单个词的词袋模型

使用CounterVectorizer()函数构建单个词的词袋模型:

>>> from sklearn.feature_extraction.text import CountVectorizer
>>> corpus = [
... 'This is the first document.',
... 'This document is the second document.',
... 'And this is the third one.',
... 'Is this the first document?',
... ]
>>> vectorizer = CountVectorizer()
>>> dt = vectorizer.fit_transform(corpus)
>>> print(vectorizer.get_feature_names())
['and', 'document', 'first', 'is', 'one', 'second', 'the', 'third', 'this']
>>> print(dt.toarray())
[[0 1 1 1 0 0 1 0 1]
[0 2 0 1 0 1 1 0 1]
[1 0 0 1 1 0 1 1 1]
[0 1 1 1 0 0 1 0 1]]

三,TF-IDF模型

TF-IDF模型用于对特征信息量进行缩放,当一个词在特定的文档中经常出现,而在其他文档中出现的频次很低,那么给予该词较高的权重;当一次词在多个文档中出现的频次都很高,那么给予该词较低的权重。如果一次单词在特定的文档中出现的频次很高,而在其他文档中出现的频次很低,那么这个单词很可能是该文档独有的词,能够很好地描述该文档。

1,TF-IDF模型计算原理

TF( Term Frequency)是词频,表示每个单词在文档中的数量(频数),TF依赖于BoW模型的输出。

IDF(Inverse Document Frequency)是逆文档频率,代表一个单词的普遍成都,当一个词越普遍(即有大量文档包含这个词)时,其IDF值越低;反之,则IDF值越高。IDF是包含该单词的文档数量和文档总数的对数缩放比例

TF-IDF(术语频率 - 逆文档频率)模型是TF和IDF相乘的结果:TF-IDF=TF*IDF。

在文档中具有高tf-idf的单词,大多数情况下,只发生在给定的文档中,并且在其他文档中不存在,所以这些词是该文档的特征词汇。

2,构建TF-IDF模型

使用TfidfVectorizer()函数构建TF-IDF模型

TfidfVectorizer(input=’content’, encoding=’utf-8’, decode_error=’strict’, strip_accents=None,
lowercase=True, preprocessor=None, tokenizer=None, stop_words=None,
token_pattern=’(?u)\b\w\w+\b’, ngram_range=(1, 1), analyzer=’word’,
max_df=1.0, min_df=1, max_features=None, vocabulary=None, binary=False,
dtype=dtype=<class ‘numpy.float64’>,
norm=’l2’, use_idf=True, smooth_idf=True, sublinear_tf=False)

大部分参数和CountVectorizer相同,TfidfVectorizer独有的参数注释:

  • norm=’l2’:每个输出行具备单位规范,当引用'l2'范式时,所有向量元素的平方和为1;当应用l2范数时,两个向量之间的余弦相似度是它们的点积。 *'l1':向量元素的绝对值之和为1。
  • use_idf=True:启用IDF来重新加权
  • smooth_idf=True:平滑idf权重,向文档-词频矩阵的所有位置加1,就像存在一个额外的文档,只包含词汇表中的每个术语一次,目的是为了防止零分裂。
  • sublinear_tf=False:应用次线性tf缩放,默认值是False。

举个例子,使用TfidfVectorizer()函数构建以下四个句子的TF-IDF模型:

>>> from sklearn.feature_extraction.text import TfidfVectorizer
>>> corpus = [
... 'This is the first document.',
... 'This document is the second document.',
... 'And this is the third one.',
... 'Is this the first document?',
... ]
>>> vectorizer = TfidfVectorizer()
>>> X = vectorizer.fit_transform(corpus)
>>> print(vectorizer.get_feature_names())
['and', 'document', 'first', 'is', 'one', 'second', 'the', 'third', 'this']
>>> print(X.toarray())
[[0. 0.46979139 0.58028582 0.38408524 0. 0.          0.38408524   0.   0.38408524]
[0. 0.6876236 0. 0.28108867 0. 0.53864762     0.28108867   0.   0.28108867]
[0.51184851 0. 0. 0.26710379 0.51184851 0.          0.26710379   0.51184851   0.26710379]
[0. 0.46979139 0.58028582 0.38408524 0. 0.          0.38408524   0.    0.38408524]]

四,查看文档的特征

对Bow和TF-IDF算法生成的模型进行操作

1,查看文本特征

从原始文档列表(语料)中获取特征列表:

>>> print(vectorizer.get_feature_names())
['adr', 'authorized', 'contact', 'device', 'distributor', 'hub', 'information', 'installer',
'interested', 'microsoft', 'partner', 'program', 'receive', 'reseller', 'sign', 'surface', 'updates', 'website']

2,查看词汇表

查看词汇表中的词汇和其对应的索引:

>>> items=vectorizer.vocabulary_.items()
>>> print(items)
dict_items([('information', 6), ('surface', 15), ('hub', 5), ('microsoft', 9), ('authorized', 1),
('device', 3), ('reseller', 13), ('adr', 0), ('interested', 8), ('contact', 2), ('distributor', 4),
('sign', 14), ('receive', 12), ('updates', 16), ('program', 11), ('partner', 10), ('website', 17), ('installer', 7)])

把dict_items结构转换为Python的字典结构,key是索引,value是词汇:

>>> feature_dict = {v: k for k, v in vectorizer.vocabulary_.items()}

3,查看词-文档矩阵

模型的fit_transform()或tranform()函数返回的是词-文档矩阵,在词-文档矩阵中列代表的是特征,行代表的原始文档的数量,列代表该文档包含的特征(即词汇),列值是特征的TD-IDF值,范围从0-1。

>>> print(X.toarray())
[[0. 0.46979139 0.58028582 0.38408524 0. 0.          0.38408524   0.   0.38408524]
[0. 0.6876236 0. 0.28108867 0. 0.53864762     0.28108867   0.   0.28108867]
[0.51184851 0. 0. 0.26710379 0.51184851 0.          0.26710379   0.51184851   0.26710379]
[0. 0.46979139 0.58028582 0.38408524 0. 0.          0.38408524   0.    0.38408524]]

参考文档:

5.2. Feature extraction

文本中的特征提取与特征选择

sklearn.feature_extraction.text.TfidfVectorizer

python 文本特征提取 CountVectorizer, TfidfVectorizer

TF-IDF提取行业关键词

使用sklearn做文本特征提取的更多相关文章

  1. sklearn文本特征提取

    http://cloga.info/2014/01/19/sklearn_text_feature_extraction/ 文本特征提取 词袋(Bag of Words)表征 文本分析是机器学习算法的 ...

  2. Feature extraction - sklearn文本特征提取

    http://blog.csdn.net/pipisorry/article/details/41957763 文本特征提取 词袋(Bag of Words)表征 文本分析是机器学习算法的主要应用领域 ...

  3. Python机器学习笔记 使用sklearn做特征工程和数据挖掘

    特征处理是特征工程的核心部分,特征工程是数据分析中最耗时间和精力的一部分工作,它不像算法和模型那样式确定的步骤,更多的是工程上的经验和权衡,因此没有统一的方法,但是sklearn提供了较为完整的特征处 ...

  4. python 文本特征提取 CountVectorizer, TfidfVectorizer

    1. TF-IDF概述 TF-IDF(term frequency–inverse document frequency)是一种用于资讯检索与文本挖掘的常用加权技术.TF-IDF是一种统计方法,用以评 ...

  5. 机器学习之路: python nltk 文本特征提取

    git: https://github.com/linyi0604/MachineLearning 分别使用词袋法和nltk自然预言处理包提供的文本特征提取 from sklearn.feature_ ...

  6. 机器学习之路:python 文本特征提取 CountVectorizer, TfidfVectorizer

    本特征提取: 将文本数据转化成特征向量的过程 比较常用的文本特征表示法为词袋法词袋法: 不考虑词语出现的顺序,每个出现过的词汇单独作为一列特征 这些不重复的特征词汇集合为词表 每一个文本都可以在很长的 ...

  7. 【转】使用sklearn做特征工程

    1 特征工程是什么? 有这么一句话在业界广泛流传:数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限而已.那特征工程到底是什么呢?顾名思义,其本质是一项工程活动,目的是最大限度地从原始数据中 ...

  8. 《机器学习系统设计》之应用scikit-learn做文本分类(上)

    前言: 本系列是在作者学习<机器学习系统设计>([美] WilliRichert)过程中的思考与实践,全书通过Python从数据处理.到特征project,再到模型选择,把机器学习解决这个 ...

  9. 使用sklearn做单机特征工程(Performing Feature Engineering Using sklearn)

    本文转载自使用sklearn做单机特征工程 目录 目录 特征工程是什么 数据预处理 1 无量纲化 11 标准化 12 区间缩放法 13 标准化与归一化的区别 2 对定量特征二值化 3 对定性特征哑编码 ...

随机推荐

  1. HDU 1212 Big Number(C++ 大数取模)(java 大数类运用)

    Big Number 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1212 ——每天在线,欢迎留言谈论. 题目大意: 给你两个数 n1,n2.其中n1 ...

  2. ExtJS中layout的12种布局风格

    总览 extjs的容器组件都可以设置它的显示风格,它的有效值有 1. absolute,2. accordion, 3. anchor, 4. border, 5. card, 6. column, ...

  3. html留言功能

    <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8&quo ...

  4. mssql sqlserver 验证整型函数分享

    转自:http://www.maomao365.com/?p=6227 摘要: 下文将制作一个isnumber验证整型的函数,供在sql脚本中做数值判断,如下所示: 例: 实现原理:判断 是否包含特殊 ...

  5. mssql sqlserver update delete表别名用法简介

    转自:http://www.maomao365.com/?p=6973  摘要: 在sql脚本编写中,如果需要在update delete 中使用表别名的方法,必须按照一定的规则编写,否则将会出现相应 ...

  6. 洗礼灵魂,修炼python(64)--爬虫篇—re模块/正则表达式(2)

    前面学习了元家军以及其他的字符匹配方法,那得会用啊对吧?本篇博文就简单的解析怎么运用 正则表达式使用 前面说了正则表达式的知识点,本篇博文就是针对常用的正则表达式进行举例解析.相信你知道要用正则表达式 ...

  7. 智能合约 solidity 开发的环境基本搭建

    以太坊Dapp开发快速入门 以太坊为开源社区,虽然设计东西都很优秀,但是组件十分的杂乱,因此下面首先简单介绍下以太坊的一些常用组件以及各种工具介绍 Geth Geth是由以太坊基金会提供的官方客户端软 ...

  8. Thread和Runnable的区别和联系、多次start一个线程会怎么样

    一.Java有两种方式实现多线程,第一个是继承Thread类,第二个是实现Runnable接口.他们之间的联系:   1.Thread类实现了Runable接口. 2.都需要重写里面Run方法. 二. ...

  9. lua时间戳和日期转换及踩坑

    介绍lua的日期函数常用方法及我的一个踩坑. 时间戳转日期 os.date("%Y%m%d%H",unixtime) --os.date("%Y%m%d%H", ...

  10. Shell编程基础知识(一)

    一.基本的运行Linux程序的3种方法: (1) 使文件具有可执行权限,直接运行文件.eg:  chmod a+x testfile.sh   ./testfile.sh (2) 直接调用命令解释器来 ...