ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

如何从文本中提取特征信息?

2021-01-03 22:56:44  阅读:338  来源: 互联网

标签:提取 get 特征 hey Hey 文档 corpus 文本


虽然之前也写过gensim库的word2vec的教程,但是对于文本分析的特征提取并不太理解。最近看了几篇scikit的外文教程,对机器学习中文本的特征提取有了一些了解。

首先做文本的机器学习(自然语言处理),我们要理解这几个概念:

  • 文档(document)这里是指一段单独的文本信息。这可能是一则短信、一条推特、一封邮件、一本书、或者一首歌词。一般一个文档对应于一个观测值或一行数据。

  • 语料(corpus) 文档的集合(语料大于等于1条文档)。这相当于我们要研究对象的所有文本数据

  • 单词或词语(token) 英文中对应的是单词,汉语是词语。例如“How are you”这个文档,是由how、are、you三个单词组成的。token相当于机器学习中的特征(列)。

首先让我们给出一个语料例子。

corpus = ["Hey hey hey lets go get lunch today :)",
           "Did you go home?",
           "Hey!!! I need a favor"]

CountVectorizer
首先我们要明白,计算机是不能从文本字符串中发现规律的。只有将字符串编码为计算机可以理解的数字,计算机才有可能发现文本中的规律。

最容易理解的实现思路:

  • 对文本编码,就是让词语与数字对应起来,建立基于给定文本的词典。(fit方法 )

  • 再根据词典对所有的文本数据进行转码。(transform方法)

scikit库的CountVectorize类就是这种思路。


from sklearn.feature_extraction.text import CountVectorizer

vectorize = CountVectorizer()

使用fit方法,CountVectorizer()类的会从corpus语料中学习到所有词语,进而构建出corpus词典。

#fit学会语料中的所有词语,构建词典


vectorize.fit(corpus)
CountVectorizer(analyzer='word', binary=False, decode_error='strict',
        dtype=<class 'numpy.int64'>, encoding='utf-8', input='content',
        lowercase=True, max_df=1.0, max_features=None, min_df=1,
        ngram_range=(1, 1), preprocessor=None, stop_words=None,
        strip_accents=None, token_pattern='(?u)\\b\\w\\w+\\b',
        tokenizer=None, vocabulary=None)
#这里我们查看下“词典”,也就是特征集(11个特征词)
vectorize.get_feature_names()
['did',
 'favor',
 'get',
 'go',
 'hey',
 'home',
 'lets',
 'lunch',
 'need',
 'today',
 'you']

这里,特征集(get_feature——name)返回的结果,有要注意的事情:

  • 所有的单词都是小写

  • 单词长度小于两个字母的,会被剔除掉

  • 标点符号会剔除掉

  • 不重复

  • 这个特征集是有顺序的

接下来会按照这个顺序去编码文本数据,这里会出现一个新概念文档-词频矩阵(document-term matrix),英文简写为dtm。我们让机器挖掘文本中的规律时,喂给机器的数据就是 这文档-词频矩阵(document-term matrix)。

#构建 文档词频矩阵
dtm = vectorize.transform(corpus)dtm
<3x11 sparse matrix of type '<class 'numpy.int64'>'
    with 13 stored elements in Compressed Sparse Row format>

构建文档词频矩阵。结果3*11。

3指的是语料中的三个文档;11指的是corpus中11个特征词。为了方便我们理解,我用pandas库将其展现出来


import pandas as pd

pd.DataFrame(dtm.toarray(), columns = vectorize.get_feature_names())

如何从文本中提取特征信息?
从上面的dataframe表中,行代表一个文档,列代表特征词。比如第1行,hey列的所对应的单元格值为3,说明corpus中第一个document(Hey hey hey lets go get lunch today :) 出现了三次hey。

这里有一个我要提示的重点,在此时我们已经构件号了文档词频矩阵dtm,如果你还想加入新的文档。我们应该注意tranform和fit的区别。


new_document = ['Hey lets go get a drink tonight']
new_dtm = vectorize.transform(new_document)
pd.DataFrame(new_dtm.toarray(), columns=vectorize.get_feature_names())

如何从文本中提取特征信息?

即使new_document含有6个单词,但是在上面的dataframe表中只有4个特征词被有效编码,drink和tonight词未被表征。这是因为我们初识的corpus语料所构建的词典并未含有这些词。但是对文本进行特征表征时,使用的确实corpus所生产的词典。

我们机器学习所用的数据,一般被分成训练集和测试集。训练集是为了让机器学习数据的规律,测试集是为了验证规律的有效性。训练集本质上代表的是过去及现在已知的数据,测试集本质上代表的是未来的未知数据(现在不存在的数据),我们是用已知的数据预测未来。

所以我们只能让fit方法操作于训练集,构建基于过去或已知数据的特征集。

TfidfVectorizer
scikit库除了CountVectorizer类,还有TfidfVectorizer类。TF-IDF这个定义相信大家应该已经耳熟能详了:

TF 词频出现的次数 IDF = 1/(语料中含有该词语的文档的数目)

TF简单点说有的时候词语出现越多,这个词越是特征词。但同时,有些“的它呢”等无意义词出现的多并没有什么意义,反而是像“核能”这种词,虽然不怎么出现,但是一出现往往很具有特征性。

综合TF*IDF,就能很好的刻画一个词语是否具有表征文本信息能力,作为特征是否合适。有了上面的基础知识,我们接下来继续写代码,便于理解TFIDF


from sklearn.feature_extraction.text import TfidfVectorizer

def createDTM(corpus):
    """构建文档词语矩阵"""
    vectorize = TfidfVectorizer()
    #注意fit_transform相当于fit之后又transform。
    dtm = vectorize.fit_transform(corpus)

    #打印dtm
    return pd.DataFrame(dtm.toarray(), columns=vectorize.get_feature_names()) 

corpus = ["Hey lets get lunch :)",
           "Hey!!! I need a favor"]
createDTM(corpus)

如何从文本中提取特征信息?
我们看到hey这个词在所有大于0的值里面,是最小的。因为hey同时出现在两个文档中,不具有文本的表征能力,所以TFIDF小。而favor和need因为他们仅仅出现在第二个文档中,所以他们的TFIDF值更高。

现在我们改变corpus内容。将第一个文档从Hey lets get lunch改为Hey hey hey lets get lunch。我们希望第一个文档的hey词频增大,进而使得其TFIDF值变大。


corpus = ["Hey hey hey lets get lunch :)",
           "Hey!!! I need a favor"]

createDTM(corpus)

如何从文本中提取特征信息?

我们发现第一个文档hey的TFIDF值变大,但这里有两点要注意:

  • 第一个文档中其余特征词的TFIDF值变小了

  • 第二个文档中hey的TFIDF未发生变化

上面的例子是通过TF词频操作TFIDF值的。下面我们从IDF出发,改变TFIDF值。


corpus = ["Hey hey hey lets get lunch :)",
           "I need a favor"]

createDTM(corpus)

如何从文本中提取特征信息?

标签:提取,get,特征,hey,Hey,文档,corpus,文本
来源: https://blog.51cto.com/15069487/2581471

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有