【特征工程】词袋模型/TF-IDF模型/词汇表模型的代码实现(文本特征提取)

1.词袋模型

  • 词集模型:单词构成的集合,集合中仅统计单词的有无,不统计具体单词的出现的次数
  • 词袋模型:在词集模型的基础上,统计单词出现的次数

两者区别在于词袋模型增加了对具体单词(特征)频率的维度。

1.1导包

from sklearn.feature_extraction.text import CountVectorizer

1.2函数介绍

CountVectorizer:收集的文本文档转换为矩阵的令牌数量

class sklearn.feature_extraction.text.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:string {‘filename’, ‘file’, ‘content’}, default=’content’。如果“filename”,作为参数传递给fit的序列应该是一个文件名列表,需要读取这些文件名以获取要分析的原始内容。如果“file”,序列项必须有一个“read”方法(类文件对象),该方法被调用来获取内存中的字节;否则,输入应该是一个项目序列,类型可以是string或byte。
  • encoding:string, default=’utf-8’,如果字节或文件被给予分析,这种编码被用来解码。
  • lowercase:bool, default=True。在标记之前将所有字符转换为小写。
  • analyzer:string, {‘word’, ‘char’, ‘char_wb’} or callable, default=’word’。该特征是由n个字母组成还是由n个字母组成。选择“char_wb”创建角色-gram只从文本单词边界;字格词带的边缘空间。
  • stop_words:string {‘english’}, list, default=None。如果“english”,则使用内置的英语停止词列表。如果“english”,则使用内置的英语停止词列表。如果一个列表,则假定该列表包含停止词,所有这些词都将从结果标记中删除。只适用于analyzer == ‘word’。
  • min_df:float in range [0.0, 1.0] or int, default=1。在构建词汇表时,忽略那些文档频率严格低于给定阈值的术语。这个值在文献中也称为cut-off。如果是浮点数,则该参数表示文档的比例,整数绝对计数。

1.3 代码示例

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()
X = vectorizer.fit_transform(corpus)
# 获取词袋化特征向量
print(X.toarray())
# 获取对应的字节名称
print(vectorizer.get_feature_names())

输出:

[[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]]
['and', 'document', 'first', 'is', 'one', 'second', 'the', 'third', 'this']

使用现有的词袋的词汇表,对其他文本进行特征提取,我们定义词袋的特征空间叫做词汇表(vocabulary),针对其他文本进行词袋处理时,可以直接使用现有的词汇表:

my_vocalulary = vectorizer.vocabulary_ # 获取词汇表,术语到特征索引的映射,属于字典类型。
new_vectorizer = CountVectorizer(vocabulary=my_vocalulary)
new_corpus = ['And the first']
new_X = new_vectorizer.transform(new_corpus) # 无需再fit,直接使用transform函数
print(new_X.toarray())
print(new_vectorizer.get_feature_names())

输出:

[[1 0 1 0 0 0 1 0 0]]
['and', 'document', 'first', 'is', 'one', 'second', 'the', 'third', 'this']

2.TF-IDF模型

词频与反文档频率模型(term frequency-inverse document frequency,TF-IDF),用以评估某一字词对于一个文件集或一个语料库的重要程度,字词的重要性跟它在文件中出现的次数成正比,同时跟它在语料库中出现的频率成反比。
TF-IDF的主要思想:TF-IDF是指TF乘IDF,其中词频(TF)是根据某个词或短语在一篇文章中出现的频率即词频,如果频率高,并且在其他文章中很少出现,则认为该词具有很好的区分能力;反文档频率(IDF)指:如果包含词条a的文档越少,也就说n越小,IDF越大,说明词条a具有很好的区分能力。

2.1 导包

from sklearn.feature_extraction.text import TfidfTransformer

2.2 函数介绍

class sklearn.feature_extraction.text.TfidfTransformer(*, norm='l2', use_idf=True, smooth_idf=True, sublinear_tf=False)

参数:

  • norm:{‘l1’, ‘l2’}, default=’l2’。每个输出行都有单位范数,可以是: ’ l2 ':向量元素的平方和为1。当应用l2范数时,两个向量之间的余弦相似度是它们的点积。‘l1’:向量元素的绝对值之和为1。
  • use_idf:bool, default=True。使inverse-document-frequency权重。
  • smooth_idf:bool, default=True。通过在文档频率上增加1来平滑idf权重,就好像在一个额外的文档中只包含集合中的每一个词一样。防止零分歧。
  • sublinear_tf:bool, default=False。应用次线性tf缩放,即将tf替换为1 + log(tf)。

具体关于TF-IDF的计算方法可详见scikit-learn中文社区

2.3 代码示例

TF-IDF模型常用和词袋模型配合使用,对词袋模型生成的数组进一步处理。

import numpy as np
count = [[1, 1, 1, 1, 0, 1, 0, 0],
       [1, 2, 0, 1, 1, 1, 0, 0],
       [1, 0, 0, 1, 0, 1, 1, 1],
       [1, 1, 1, 1, 0, 1, 0, 0]]
transformer = TfidfTransformer()
tfidf = transformer.fit_transform(count)
print(tfidf.toarray())

输出:

[[0.38408524 0.46979139 0.58028582 0.38408524 0.         0.38408524        0.         0.       ]
 [0.28108867 0.6876236  0.         0.28108867 0.53864762 0.28108867        0.         0.        ]
 [0.31091996 0.         0.         0.31091996 0.         0.31091996        0.59581303 0.59581303]
 [0.38408524 0.46979139 0.58028582 0.38408524 0.         0.38408524        0.         0.        ]]

3.词汇表模型

虽然词袋模型能表现文本由哪些词汇组成,但是无法表达词汇直接的前后关系,词汇表模型弥补了这方面不足。

由于没有找到现成的API直接供我们使用,因此借用TensorFlow2手动实现了该方法:

import tensorflow as tf # 当前测试版本为2.3
x_text = [
    'i love you',
    'me too',
    'i me too'
]
x_text_list = [tf.keras.preprocessing.text.text_to_word_sequence(a) for a in x_text] # 拆分
# x_text_list:[['i', 'love', 'you'], ['me', 'too'], ['i', 'me', 'too']]
word_set = set() # 获取所有的单词
for text in x_text_list:
    for word in text:
        word_set.add(word) 
# word_set:{'i', 'love', 'me', 'too', 'you'}
word_list = list(word_set) # 转换为list
word_index =  dict((word, word_list.index(word) + 1) for word in word_list) # 获取序号与单词的映射
# word_index:{'me': 1, 'love': 2, 'too': 3, 'you': 4, 'i': 5}
x_index_list = []
for text in x_text_list:
    x_index_list.append([word_index.get(word, 0) for word in text]) 
# x_index_list:[[5, 2, 4], [1, 3], [5, 1, 3]]
result = tf.keras.preprocessing.sequence.pad_sequences(x_index_list).tolist() # 统一长度
print(result)
# [[5, 2, 4], [0, 1, 3], [5, 1, 3]]

最终
i love you -> [5,2,4]
me to -> [0,1,3]
i me to -> [5,1,3]

一般情况下,在深度学习模型的搭建过程中还将搭配嵌入层Embedding作为后续处理

特征提取类(FeatureExtraction)在NLP项目中可能包含以下子类: 1. 词袋模型类(Bag-of-Words Model Class):将文本表示为词汇表中每个词的出现频率或计数。可以使用不同的计数方法,例如二进制计数、词频(Term Frequency)、逆文档频率(Inverse Document Frequency)等。 2. TF-IDF类(Term Frequency-Inverse Document Frequency Class):将文本表示为每个词的TF-IDF值,该值考虑了词频和逆文档频率。TF-IDF可以用于衡量词语在文本中的重要程度。 3. 词嵌入类(Word Embedding Class):将文本中的词语映射为低维度的实数向量,以捕捉词语之间的语义相似性。常见的词嵌入方法包括Word2Vec、GloVe和FastText等。 4. N-gram模型类(N-gram Model Class):将文本表示为连续的n个词语序列。N-gram模型可以捕捉到n个连续词语之间的关系,常用于语言建模和文本分类等任务。 5. 文本统计特征类(Text Statistical Features Class):提取文本的统计特征,例如句子长度、平均词长、标点符号个数等。这些特征可以用于文本分类和情感分析等任务。 6. 句法特征类(Syntactic Features Class):提取文本中的句法特征,例如词性标签、依存关系等。这些特征可以帮助理解句子结构和语法信息。 7. 主题模型类(Topic Modeling Class):根据文本中的词语分布,推断文档的主题分布。主题模型可以用于文本聚类、文本摘要和推荐系统等任务。 8. 神经网络特征提取类(Neural Network Feature Extraction Class):使用预训练的神经网络模型(如CNN、RNN或Transformer)从文本中提取高级语义特征。这些特征可以用于各种下游NLP任务。 9. 图特征提取类(Graph Feature Extraction Class):将文本表示为图结构,并提取图结构中的节点和边的特征。这些特征可以用于基于图的文本分类和关系抽取等任务。 10. 基于知识图谱的特征提取类(Knowledge Graph-based Feature Extraction Class):利用外部知识图谱,将文本中的实体映射到知识图谱中的概念,并提取与之相关的特征。这些特征可以用于实体识别、关系抽取和问答系统等任务。 以上是特征提取类可能包含的一些子类,具体在项目中的使用与需求相关,你可以根据具体任务的要求选择适合的子类进行特征提取
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值