赞
踩
NLP基础1-词向量之序号化,One-Hot,BOW/TF,TF-IDF
NLP基础2-词向量之Word2Vec
NLP基础3-词向量之Word2Vec的Gensim实现
在分词之后,需要将文本数据转换成数值型数据。常用方式如下:
根据单词字典来序号化文本中的每个单词 (token):
假设现在有已经经过分词后的三个文本:
[[“我”, “是”, “小明”],
[“我”, “来自”, “湖南”, “长沙”],
[“我”, “喜欢”, “辣椒”]]
根据单词词典:
dict = {“<\PAD>”: 0, “<\UNK>”: 1, “我”: 2, “湖南”: 3, “长沙”: 4, “是”: 5, “来自”: 6, “喜欢”: 7, “辣椒”: 8 , …}
那么对应三个文本序号化后就是
[[2, 5, 1, 0],
[2, 6, 3, 4 ],
[2, 7, 8, 0]]
其中:<\PAD>表示填充字符, <\UNK>未知字符
# 1. 得到分词后的文本 text = [["我", "是", "小明"], ["我", "来自", "湖南", "长沙"], ["我", "喜欢", "辣椒"]] print("="*100) print("text:") print(text) # 2. 构建词典 tokens = set() for sentence in text: for token in sentence: tokens.add(token) tokens = list(tokens) # {} → [] set转换为list tokens.insert(0, "<PAD>") # 在第一个位置插入<PAD> tokens.insert(1, "<UNK>") # 在第二个位置插入<UNK> print("="*100) print("tokens:") print(tokens) dict = {token: i for i, token in enumerate(tokens)} # 构建字典 # dict = {token: i for i, token in zip(tokens, range(len(tokens)))} print("="*100) print("dict:") print(dict) # 3. 序列化 max_len = 6 token2id = [] for sentence in text: sentence2id = [dict.get(token, dict["<UNK>"]) for token in sentence] # dict.get(key, default=None) 返回指定键的值,如果值不在字典中返回默认值 sentence2id = sentence2id[:max_len] + [dict["<PAD>"]] * (max_len - len(sentence2id)) # 截断补齐 token2id.append(sentence2id) # 将每个句子的id添加到token2id中 print("="*100) print("token2id:") print(token2id) print("="*100)
假设现在单词词典中有 n 个单词, 那么转换的特征向量就是 n 维度, 仅在对应位置为 1, 其它位置全部为 0
举例说明:
文本:text = [“我”, “来自”, “湖南”, “长沙”]
单词字典:dict = {“<\PAD>”: 0, “<\UNK>”: 1, “我”: 2, “湖南”: 3, “长沙”: 4, “是”: 5, “来自”: 6, “喜欢”: 7, “辣椒”: 8 }
One-Hot编码后:
“我” → [0, 0, 1, 0, 0, 0 ,0 0, 0]
“来自” → [0, 0, 0, 0, 0, 0 , 1, 0, 0]
“湖南” → [0, 0, 0, 1, 0, 0 , 0, 0, 0]
“长沙” → [0, 0, 0, 0, 1, 0 , 0, 0, 0]
文本 → [0, 0, 1, 1, 1, 0 , 1, 0, 0]
import torch import torch.nn.functional as F # 1. 示例 x = torch.randint(0, 10, (5, 1), dtype=torch.long) x_onehot = F.one_hot(x, 10) print("="*100) print(x) print(x_onehot) print("="*100) # 2. token2id 见序列化 token2id = torch.tensor(token2id) text_onehot = F.one_hot(token2id, 10) print(text) print(text_onehot) print("="*100)
对于这种离散表征单词有明显的问题:
对一个文档(document)或一个文本(text)而言,Bag of Word (BOW)模型忽略了单词顺序、语法、语义信息等,将文档/文本看成是若干单词 (token)的集合,仅仅统计文档中每个单词出现的频率/频数(文档中单词出现次数的累加),该方法生成的向量就是该文档/文本的特征信息
适用场景:在巨大的文档集中,里面有 N 个文档,因为每个文档都可以用一个向量表示,因此我们可以计算余弦相似度来求两个文档之间的相似度
给定两个文本
d1:this is a sample is a sample
d2:this is another example another example
根据上述两个文本出现过的单词,构建一个单词字典
dict:{“this”,“is”,“a”,“sample”,“another”,“example”}
那么那么上述两个文本就可以用六维的向量表示
d1 = [1, 2, 2, 2, 0, 0]
d2 = [1, 1, 0, 0, 2, 2]
### sklearn 可以用一下包 ### bow:from sklearn.feature_extraction.text import CountVectorizer ### tfidf:from sklearn.feature_extraction.text import TfidfVectorizer from gensim.models import TfidfModel from gensim.corpora import Dictionary # 1. 得到分词后的文本 text = [["this", "is", "a", "sample", "a", "sample"], ["this", "is", "another", "example", "another", "example"]] print("="*100) print("text:") print(text) # 2. 构建词典 dct = Dictionary(text) print("="*100) print("dict:") print(dict.token2id) # 3. 构建bow模型 bow = [dct.doc2bow(sentence) for sentence in text] print("="*100) print("bow:") print(bow) print("="*100) # 4. 构建tfidf模型 tfidf = TfidfModel(bow)
改进措施:TF-IDF,N-gram
词频(Term-Frequency):统计每个单词在当前文本中的出现的频数/频率;换句话说,单词出现的次数越多,该单词对于当前文本的重要性就越高
T
F
=
某个单词在该文本中的频数
TF = 某个单词在该文本中的频数
TF=某个单词在该文本中的频数
考虑到不同文本之前的长度不一致,TF 也可以用某个单词在当前文本中出现的频率表示:
T
F
=
某个单词在该文本中的频数
该文本单词的总数量
TF = \frac{某个单词在该文本中的频数}{该文本单词的总数量}
TF=该文本单词的总数量某个单词在该文本中的频数
IDF (Inverse Document Frequency) :同时单词的重要性会对着语料库中出现的频率成反比的下降,也就是说出现的频率越高,表示该单词越常见,该单词对文本的重要性就越低。比如说:“的”,“是”,“了” 这些停顿词
I
D
F
=
l
o
g
文本总数量
包含该单词的文本数量
IDF=log\frac{文本总数量}{包含该单词的文本数量}
IDF=log包含该单词的文本数量文本总数量
因此,TF-IDF 的计算公式就如下所示:
T
F
−
I
D
F
=
词频(
T
e
r
m
−
F
r
e
q
u
e
n
c
y
)
∗
I
D
F
(
I
n
v
e
r
s
e
D
o
c
u
m
e
n
t
F
r
e
q
u
e
n
c
y
)
TF-IDF = 词频(Term-Frequency)* IDF (Inverse Document Frequency)
TF−IDF=词频(Term−Frequency)∗IDF(InverseDocumentFrequency)
适用场景:1. 计算当前文档的关键字 2. 求不同文档之间的相似度
见词袋法
我们可以使用序号化和独热编码(One-Hot)来简单表示词向量,也可以使用词袋模型(BOW)根据频数来表示词向量。此外,我们还可以使用 TF-IDF 来衡量单词的重要程度。然而,当面对庞大的词汇表时,这些方法的词向量通常都是高维且稀疏,同时无法捕捉单词之间的相似性,因为我们期望相似的词向量在空间中更加接近。那么,如何解决这个问题呢?在下一篇文章中,我们将介绍词嵌入技术,即 Word Embedding,它能够很好地解决上述问题。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。