机器学习实验—文档建模

来源:互联网 发布:忒修斯之船 知乎 编辑:程序博客网 时间:2024/06/17 00:39

一、实验目的和内容

        1、掌握选择term的方法;

        2、权重计算(TermWeighting):即计算每篇文 权重计算(Term Weighting):即计算每篇文 档中每个term的权重,计算TF、IDF;

        3、查询和文档的相似度计算(Siili • 查询和文档的相似度计算(Similarity Computation)。

二、实验过程

        1、读取文档
        使用 vector_map来存储文件。
        2、去除停用词
        文档总有一些比如”的”、”是”、”在”这一类最常用的词,它们叫做”停用词”(stop words),对找到结果毫无帮助,所以计算特征词权重时需要把它们过滤掉。实际操作中通常会有一个停用词文件,事先需要读取该文件获取所有停用词,判断一个词是否是停用词,只需要在停用词表查找即可。
        3、计算TF-IDF
        TF计算因子代表了词频,即一个单词在文档中出现的次数,一般来说,在某个文档中反复出现的单词,往往能够表征文档的主题信息,即Tf值越大,越能代表文档所反映的内容,那么应该给于这个单词更大的权值。 
        具体计算词频因子的时候,基于不同的出发点,可以采用不同的计算公式。 最直接是使用词频数作为TF。 
        一种词频因子的变体计算公式是:Tf=1+log(Tf),即将词频数值Tf取log值作为词频权值,比如单词在文档中出现过4次,则它的词频因子权值为3。公式中加1是为了考虑词频等于1的情况,如果不加1只计算log(TF),那么Tf就等于0了。之所以要对词频取log,是基于如下考虑:如果一个单词出现了10次,也不应该在计算特征权值时,比出现1次的情况权值大10倍,所以加入log抑制这种过大的差异。 
        另外一种单词词频因子的变体计算公式是:Tf=α+(1−α)∗Tf/max(Tf),α是调节因子,过去经验取值0.5,新的研究表明取值为0.4效果最好。公式中的Tf代表这个单词的实际词频数目,而max(Tf)代表了文档中所有单词出现次数最多的那个单词对应的词频数目。之所以要如此操作,主要出于对长文档的一种抑制,因为如果文档较长,与短文档相比,则长文档中所有单词的Tf值会普遍比短文档的值高,但是这并不意味着长文档与查询更相关。用单词实际词频除以文档中最高词频,等于将绝对的数值进行了规范化转换,公式的含义就转换为:同一个文档内单词之间的相对重要性。即使一个文档很长,单词词频普遍很高,但是除以文档最高词频,那么通过这种计算方式得出的数值比短文档来说并不一定就大。这样就剔除了文档长度因素的影响,长文档和短文档的词频因子就成为可比的了。
        IDF的计算公式为:IDF=log(N/nk),其中N代表文档集合(包含不相关和相关文档的总和)中总共有多少个文档,而nk代表特征单词k在其中多少个文档中出现过,即文档频率。由公式可知,文档频率nk越高,其IDF值越小,即越多的文档包含某个单词,那么其IDF权值越小。IDF反映了一个特征词在整个文档集合中的分布情况,特征词出现在其中的文档数目越多,IDF值越低,这个词区分不同文档差异的能力越差,所以IDF衡量了单词对不同文档内容差异的区分能力。
        4、求特征向量
        利用TF*IDF框架计算用户查询除停用词外所有分词的权重,提权权重词最大的若干词作为特征词。由特征词权重组成的向量就是用户查询的特征向量。 
        TF*IDF框架是结合了词频因子和逆文档频率因子的计算框架,一般是将两者相乘作为特征权值,特征权值越大,则越可能是好的关键词,即:Weight(word) = TF * IDF。

        5、相似度计算


        实验中采用的是Jaccard方法。
        其中q代表文本的特征向量。d代表另一个文本的特征向量。 
        计算特征空间中两个向量之间的夹角,夹角越小,说明两个特征向量内容越相似,夹角越大,说明两个向量内容越不同。
        2、主要函数
        计算相似度:

void CalcSimilarity(){cout << "正在计算相似度...";ofstream fileout_one("相似度大于定值的文本.txt");ofstream fileout_two("所有文本之间的相似度.txt");map<string, tf_idf>::iterator map_first;map<string, tf_idf>::iterator map_second;map<string, tf_idf>::iterator map_t_t;double dq, d, q, d_sqrt, q_sqrt;dq = d = q = 0.0;for (int i = 0; i < allTxtTID.size()-1; i++) {for (int j = i + 1; j < allTxtTID.size(); j++) {dq = d = q = 0.0;map<string, tf_idf> map_second = allTxtTID[j];for (map_first = allTxtTID[i].begin(); map_first != allTxtTID[i].end(); map_first++) {map_t_t = map_second.find(map_first->first);if (map_t_t == map_second.end()) {d += map_first->second.result*map_first->second.result;continue;}dq += map_first->second.result * map_t_t->second.result;d += map_first->second.result * map_first->second.result;q += map_t_t->second.result *  map_t_t->second.result;map_second.erase(map_first->first);}for (map_t_t = map_second.begin(); map_t_t != map_second.end(); map_t_t++) {q += map_t_t->second.result *  map_t_t->second.result;}d_sqrt = sqrt(d);q_sqrt = sqrt(q);//Jaccard方法double result_t = dq / (d + q - dq) * 100;if (result_t >= 100.0) {cout <<"错误信息:"<< i << "和" << j << "相似度为:" << result_t << "%" << endl;}else if(result_t>=70.0){fileout_one << "文本" << i << "和" << "文本" << j << "相似度为:" << result_t << "%" << endl;}fileout_two << "文本" << i << "和" << "文本" << j << "相似度为:" << result_t << "%" << endl;}}cout << endl;}
        3、导入数据,编译运行,查看结果
        该实验提供了训练数据Chinese-StopWords.txt和input.txt。

三、实验结果

        以下是实验结果:

        整个实验耗时:16.28s。
        查看输出文件:

        输出所有的文本之间的相似度:

        实验中设定的是相似度大于0.7的会输出到相似度大于定值的文本.txt,从结果可以看出,文本中只有15对文本之间相似度大于0.7。

四、总结

        本次实验计算的时候是采用了Jaccard相似度,还可以用dice、jaccad、cosine、内积相似度等方法 。


         注:本博客源代码下载地址:http://download.csdn.net/detail/dmxexcalibur/9920653