【自然语言处理】文本表示:One-Hot、BOW、TF-IDF、N-Gram

1.One-Hot 编码

One-Hot 编码,又称 “独热编码”,是比较常用的文本特征提取方法。这种方法把每个词表示为一个很长的向量。这个向量的维度是词表大小,只有一个维度的值为 1 1 1,这个向量就代表了当前的词,其他元素为 0 0 0。One-Hot 在特征提取上属于词袋模型(Bag-of-Words),假设语料库中有三句话:

  • 我爱中国
  • 爸爸妈妈爱我
  • 爸爸妈妈爱中国

构造一个字典,Dictionary = {1:“我”, 2:“爱”, 3:“爸爸”, 4:“妈妈”, 5:“中国”}

所以最终得到的每句话的特征向量就是:

  • 我爱中国:[1, 1, 0, 0, 1]
  • 爸爸妈妈爱我:[1, 1, 1, 1, 0]
  • 爸爸妈妈爱中国:[0, 1, 1, 1, 1]
# 导入keras中的词汇映射器Tokenizer
from tensorflow.keras.preprocessing.text import Tokenizer

# 假定vocab为语料集所有不同词汇集合
vocab = {"我", "爱", "北京", "天安门", "升国旗"}
# 实例化一个词汇映射器对象
t = Tokenizer(num_words=None, char_level=False)
# 使用映射器拟合现有文本数据
t.fit_on_texts(vocab)

print(vocab)
for token in vocab:
    zero_list = [0]*len(vocab)
    # 使用映射器转化现有文本数据, 每个词汇对应从1开始的自然数
    # 返回样式如: [[2]], 取出其中的数字需要使用[0][0]
    token_index = t.texts_to_sequences([token])[0][0] - 1
    zero_list[token_index] = 1
    print(token, "的one-hot编码为:", zero_list)

在这里插入图片描述

2.词袋模型(Bag-of-Words,BOW)

Bag-of-Words(BOW)模型是信息检索领域常用的文档表示方法。在信息检索中,BOW 模型假定对于一个文档,忽略它的单词顺序、语法、句法等要素,将其仅仅看作是若干个词汇的集合,文档中每个单词的出现都是独立的,不依赖于其它单词是否出现。也就是说,文档中任意一个位置出现的任何单词,都不受该文档语意影响而独立选择的。例如有如下两个文档:

  • Bob likes to play basketball, Jim likes too.
  • Bob also likes to play football games.

基于这两个文本文档,构造一个词典:

  • Dictionary = {1:‘also’, 2:‘basketball’, 3:‘bob’, 4:‘football’, 5:‘games’, 6:‘jim’, 7:‘likes’, 8:‘play’, 9:‘to’, 10:‘too’}

这个词典一共包含 10 个不同的单词,利用词典的索引号,上面两个文档每一个都可以用一个 10 维向量表示(用整数数字 0~n(n 为正整数)表示某个单词在文档中出现的次数):

  • [0, 1, 1, 0, 0, 1, 2, 1, 1, 1]
  • [1, 0, 1, 1, 1, 0, 1, 1, 1, 0]

向量中每个元素表示词典中相关元素在文档中出现的次数。不过,在构造文档向量的过程中可以看到,我们并没有表达单词在原来句子中出现的次序,这也是 Bag-of-Words 模型的缺点之一。

from sklearn.feature_extraction.text import CountVectorizer

vectorizer = CountVectorizer()
data_corpus = ['Bob likes to play basketball, Jim likes too.']
vocabulary = vectorizer.fit(data_corpus)
x = vectorizer.transform(data_corpus)
print(vocabulary.get_feature_names())
print(x.toarray())

在这里插入图片描述

3.TF-IDF 模型

对区别文档最有意义的词语应该是那些在文档中出现频率高,而在整个文档集合的其他文档中出现频率少的词语,所以如果特征空间坐标系取词频 TF(Term Frequency)作为测度,就可以体现同类文本的特点。

另外考虑到单词区别不同类别的能力,TF-IDF 认为一个单词出现的文本频数越小,它区别不同类别文本的能力就越大。因此引入了逆文本频度 IDF(Inverse Document Frequency)的概念。

TF-IDF中,字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。 T F − I D F = 词频( T F ) × 逆文档频率( I D F ) TF-IDF=词频(TF)×逆文档频率(IDF) TFIDF=词频(TF×逆文档频率(IDF

from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer
import numpy as np

corpus = [
    'This is the first document.',
    'This is the second document.',
    'And the third document.',
    'Is this the first document?'
]

vectorizer = CountVectorizer()
x = vectorizer.fit_transform(corpus)
word = vectorizer.get_feature_names()

print('Vocabulary:', word, '\n')
print(x.toarray(), '\n')

# TF-IDF 转换
transfomers = TfidfTransformer()
tfidf = transfomers.fit_transform(x)
print(np.around(tfidf.toarray(), 4), '\n')

from sklearn.metrics.pairwise import cosine_similarity
# 比较最后一句与其他句子的相似度
print(cosine_similarity(tfidf[-1], tfidf[:-1], dense_output=False))

在这里插入图片描述
在这里插入图片描述

4.N-Gram 模型

分布假设:相似的词往往出现在同一环境中。出现在非常相似的部分(其相邻的词是相似的)中的两个词具有相似的含义。

n n n- g r a m gram gram 模型为了保持词的顺序,做了一个滑窗的操作,这里的 n n n 表示的就是滑窗的大小,例如 2 2 2- g r a m gram gram 模型,也就是把 2 2 2 个词当做一组来处理,然后向后移动一个词的长度,再次组成另一组词,把这些生成一个字典,按照词袋模型的方式进行编码得到结果。该模型考虑了词的顺序。

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

以上两句可以构造一个词典:

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

那么第一句的向量表示为:[1, 1, 1, 1, 1, 1, 0, 0, 0, 0],其中第一个 1 1 1 表示 John likes 在该句中出现了 1 1 1 次,依次类推。

缺点:随着 n n n 的大小增加,词表会成指数型膨胀,会越来越大。

# 一般n-gram中的n取2或者3, 这里取3为例
ngram_range = 3

def create_ngram_set(input_list):
    """
    description: 从数值列表中提取所有的n-gram特征
    :param input_list: 输入的数值列表, 可以看作是词汇映射后的列表,
                       里面每个数字的取值范围为[1, 25000]
    :return: n-gram特征组成的集合

    eg:
    # >>> create_ngram_set([1, 4, 9, 4, 1, 4])
    {(4, 9), (4, 1), (1, 4), (9, 4)}
    """
    return set(zip(*[input_list[i:] for i in range(ngram_range)]))

if __name__ == '__main__':
    input_list = ['明天', '有', '可能', '会', '下雨']
    res = create_ngram_set(input_list)
    print(res)

在这里插入图片描述

  • 7
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
本文主要介绍NLP中的预处理技术。预处理是指将原始文本转换为计算机可以理解和使用的形式。常见的预处理技术包括分词、停用词过滤、词干提取和词向量表示等。这些技术可以帮助我们更好地理解文本数据,从而进行文本分类、情感分析等任务。 使用向量空间模型表示文本可以将文本转换为向量形式,便于计算机进行处理。其中,one-hot表示将每个单词表示为一个唯一的向量,该向量中只有一个元素为1,其余元素为0。tf-idf表示除了考虑单词出现的次数,还考虑了单词在整个文本语料库中的重要性。具体实现可以使用gensim库。 以下是示例代码: ``` import gensim from gensim import corpora, models # 定义文本 text = ['本文主要介绍NLP中的预处理技术。预处理是指将原始文本转换为计算机可以理解和使用的形式。常见的预处理技术包括分词、停用词过滤、词干提取和词向量表示等。这些技术可以帮助我们更好地理解文本数据,从而进行文本分类、情感分析等任务。'] # 分词 texts = [[word for word in text.split()] for text in text] # 创建词典 dictionary = corpora.Dictionary(texts) # 使用doc2bow文本转换为稀疏向量 corpus = [dictionary.doc2bow(text) for text in texts] # 计算tf-idftfidf = models.TfidfModel(corpus) # 将文本表示tf-idf向量 corpus_tfidf = tfidf[corpus] # 输出结果 print('one-hot表示:', corpus) print('tf-idf表示:', corpus_tfidf) ``` 输出结果如下: ``` one-hot表示: [[(0, 1), (1, 1), (2, 1), (3, 1), (4, 1), (5, 1), (6, 1), (7, 1), (8, 1), (9, 1), (10, 1), (11, 1), (12, 1), (13, 1), (14, 1)]] tf-idf表示: [[(0, 0.1767766952966369), (1, 0.1767766952966369), (2, 0.1767766952966369), (3, 0.1767766952966369), (4, 0.1767766952966369), (5, 0.1767766952966369), (6, 0.1767766952966369), (7, 0.1767766952966369), (8, 0.1767766952966369), (9, 0.1767766952966369), (10, 0.1767766952966369), (11, 0.1767766952966369), (12, 0.1767766952966369), (13, 0.1767766952966369), (14, 0.1767766952966369)]] ``` 可以看到,one-hot表示中每个单词对应一个唯一的向量,而tf-idf表示中每个单词的权重不同。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

G皮T

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值