词袋模型
独特编码表示系统由,独热编码(Onehot Encoding )、频数编码(Count Encoding)、TF-IDF编码三种方法逐层递进构成。
1.1 Onehot Encoding
对非数值型调特征来说,最常见的特征编码方法就是标签编码(Label Encoding)和独热编码(Onehot Encoding )。Onehot Encoding凭借任意不同类别编码向量间距离相同的特性,可简化文本表示中对单词文本相似度的考量(因为任意两不同单词编码结果的相似度都相同),成为了最先发展起来的文本表示方法。(注:独热编码中,任意两不同单词的编码向量间的距离相同,所以词库中单词排列的先后顺序对编码结果无影响。)
在单词表示层面的优势,也不能掩饰其在语句表示层面的不足:在表示句子时,它首先提取语料库中出现过的每一种单词构建成词库,然后将句子编码成一个维度大小等于词库大小的一维向量,向量中句子所含种类单词在词库中对应位置的元素为1、其他位置元素全为0,这仅考虑了句中所出现单词种类对句子语义的影响。
1.2 Count Encoding
对Onehot Encoding表示法仅考虑句中单词种类对语义影响的局限,Count Encoding表达法作出了相应改进。它在Onehot Encoding表示法基础上,统计句中每种单词的出现次数,令编码向量中,句中单词对应位置元素等于单词出现次数、其他位置元素为0。这同时表示了句中单词种类和每种单词出现次数对句子语义的影响。
实现代码:
from sklearn.feature_extraction.text import CountVectorizer
# 加载文本数据
corpus = [
'I like this course.',
'I like this game.',
'I like this course, but I also like that game',
]
# 文本表示
vectorizer = CountVectorizer()
X = vectorizer.fit_transform(corpus)
# 查看结果
print(vectorizer.get_feature_names()) # 查看词典
# print(X) # 为节省内存,CountVectorizer编码结果以scipy.sparse.csr_matrix稀疏矩阵形式储存
print(X.toarray()) # 调用toarray()方法,查看矩阵的完整形态
1.3 TF-IDF
TF-IDF表示法在Count Encoding表示法基础上,增加考虑了单词自身重要性对句子语义的影响。它令编码向量中,句中单词对应位置元素等于该单词的TF-IDF值(即:单词在句中出现次数与单词自身重要性加权值的乘积)、其他位置元素。TF-IDF表示法极具实用性,至今仍与词向量并列的两大最常用文本表方法之一。
TF-IDF值得具体计算公式如下:
t
f
i
d
f
(
w
)
=
t
f
(
d
,
w
)
∗
i
d
f
(
N
,
w
)
tfidf(w) = tf(d, w)*idf(N, w)
tfidf(w)=tf(d,w)∗idf(N,w)
其中,
t
f
(
d
,
w
)
=
d
(
w
)
tf(d, w)=d(w)
tf(d,w)=d(w) 表示文档d中单词w出现的词频,
i
d
f
(
N
,
w
)
idf(N, w)
idf(N,w) 表示单词
w
w
w 的重要性系数。
单词
w
w
w 重要性系数的计算公式如下:
i
d
f
(
N
,
w
)
=
l
o
g
(
N
N
(
w
)
)
idf(N, w) = log(\frac{N}{N(w)})
idf(N,w)=log(N(w)N)
式中,
N
N
N 表示语料库中的文档总数,
N
(
w
)
N(w)
N(w) 表示语料库中包含单词w的文档个数。所以,TF-IDF算法中,单词越普遍出现在不同的文档中,单词的重要性越低(即
N
(
w
)
N(w)
N(w) 越大,单词重要性系数
i
d
f
(
N
,
w
)
idf(N, w)
idf(N,w) 越小)。
实际工程中,上述原生公式碰到计算训练数据语料库中没有的生僻词时,会出现分母等于0的特殊情况,为避免报错我们常在实际中使用平滑后的 IDF(单词重要性系数)计算公式,如下所示:
i
d
f
(
N
,
w
)
=
l
o
g
(
N
+
1
N
(
w
)
+
1
+
1
)
idf(N, w) = log(\frac{N+1}{N(w)+1}+1)
idf(N,w)=log(N(w)+1N+1+1)
实现代码:
from sklearn.feature_extraction.text import TfidfVectorizer
# 加载文本数据
corpus = [
'I like this course.',
'I like this game.',
'I like this course, but I also like that game',
]
# 文本表示
vectorizer = TfidfVectorizer()
X = vectorizer.fit_transform(corpus)
# 查看结果
# print(vectorizer.get_feature_names()) # 查看词典
# print(vectorizer.idf_) # 查看单词重要性(已平滑)
print(dict(zip(vectorizer.get_feature_names(), vectorizer.idf_)), '\n')
# print(X) # 为节省内存,CountVectorizer编码结果以scipy.sparse.csr_matrix稀疏矩阵形式储存
print(X.toarray()) # 调用toarray()方法,查看矩阵的完整形态