赞
踩
TFIDF由TF和IDF相乘而来,TF是指某个单词在一个文档中出现次数归一化后的结果;IDF是一个单词普遍重要性的度量。它基本原理是单词的重要性随着它在文档中出现的次数而增加,随着它在所有文档中出现的频率而下降。
one-hot矩阵是单词编码的一种方式,它先根据单词在所有文档中的出现顺序建立一个词汇表,然后每个文档对应one-hot矩阵的一行,每行长度为词汇表的大小。根据词汇表中每个单词是否出现在某一篇文档中,如果出现,对应的位置就为1,否则为0。
但one-hot矩阵只表示某个单词是否在文档中出现,并不能表示某个单词的出现次数,所以Bag-of-Words在one-hot基础上做出了改进,其中每一行对应一个文档,每个值对应词表的位置上该词语出现的次数。
但Bag-of-Words的统计方法更偏向于长文档,也就是说同一个词语在长文档里可能会比短文件有更高的词频,而不管该词语重要与否,所以TF在此基础上又做出改进,进将各词频归一化以消除文件长度的影响。所以得到TF的公式如下
t f i , d = n i , d ∑ k n k , d tf_{i,d}=\frac{n_{i,d}}{\sum_k{n_{k,d}}} tfi,d=∑knk,dni,d
上式中 n i , d n_{i,d} ni,d是指单词 i i i在文档 d d d中出现的次数,而分母则是文档 d d d中所有单词出现的次数之和。
TF虽然能表示一个单词在一个文档中的重要性,但不能表示它和所有文档的关系,因为一个单词的重要性还会随着出现的文档数而下降,因此又引入一个指标IDF(反文档频率)它的公式如下:
i d f i = l o g ∣ D ∣ ∣ j : t i ∈ d j ∣ idf_i=log\frac{|D|}{|{j:t_i\in{d_j}}|} idfi=log∣j:ti∈dj∣∣D∣
上式中 ∣ D ∣ |D| ∣D∣表示总的文档数,分母则表示单词 i i i出现的文档总数,如果一个单词出现的次数越少,由于 ∣ D ∣ |D| ∣D∣是固定的,则 ∣ D ∣ ∣ j : t i ∈ d j ∣ \frac{|D|}{|{j:t_i\in{d_j}}|} ∣j:ti∈dj∣∣D∣的值越大,则 i d f i idf_i idfi 越大,表示该单词越重要,反之亦然。为了进一步改进,会在分母+1,主要为了防止分母出现0,如下式:
i d f i = l o g ∣ D ∣ ∣ j : t i ∈ d j ∣ + 1 idf_i=log\frac{|D|}{|{j:t_i\in{d_j}}|+1} idfi=log∣j:ti∈dj∣+1∣D∣
至此,我们就可以将反文档频率和词频相乘,作为TFIDF矩阵的一个元素
i f i d f i , j = t f i , j × i d f i ifidf_{i,j}=tf_{i,j}\times idf_i ifidfi,j=tfi,j×idfi
1.定义的全局变量
vector<vector<string>> words; //存储所有的单词,words[i][j] 表示第i个文档的第j个单词。
unordered_map<string,int> dict; //hash,存储单词表,每个键值对表示<单词,出现顺序> dict[wordd[i][j]]表示第i个文档中第j个单词在单词表中的序号。
vector<int> appear; //appear[i] 表示出现了单词i的文章数,
int index; //记录此时单词出现的次序
2.统计每个单词在文档中出现的次数以及出现的文档数
void get_data (vector<vector<double>>& TFIDF) {
for (int i = 0; i < words.size(); i++) {//遍历每个单词
for (int j = 0; j < words[i].size(); j++) {
if (TFIDF[i][dict[words[i][j]]] == 0) appear[dict[words[i][j]]]++; // 如果words[i][j] 还没有在文档i中出现过,说明该单词在一篇新文章出现了。
TFIDF[i][dict[words[i][j]]]++; //文档i中单词j的出现次数加1;
}
}
}
3.根据统计结果计算每个tfidf值
void get_TFIDF (vector<vector<double>>& TFIDF) {
for (int i = 0; i < words.size(); i++) { //处理文档i
for (int j = 0; j < dict.size(); j++) { //处理文档i中单词表中顺序为j的单词
TFIDF[i][j] = TFIDF[i][j] * log((double)words.size() / (1.0 + (double)appear[j])) / (double) words[i].size(); //根据工式计算每个值
}
}
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。