您的位置:首页 > 编程语言 > C语言/C++

c++实现之 -- 文章TF-IDF值的计算

2014-12-06 20:18 2346 查看
首先,是关键词的选取:
好吧这个我这模型实在是太简单了,但还是讲一讲比较好呢。。。
我们现在手头有的是一堆百度百科词条w的DF(w, c)值,c是整个百科词条。。。原因是。。。方便嘛~(而且人家现成的只有介个了啦~)
我们发现有830W+的词条数目,都存下来显然是不理智、不科学、不魔法的。所以选取一部分作为关键词。
如何选取关键词呢?我选择了DF值在[100, 5000]之间的词。虽然也很不理智、不科学、不魔法,但是比直接存下来理智、科学、魔法多了,恩!
于是就全读进来,然后找到需要的词语,顺便计算下IDF值什么的输出到新的文件里去。

#include <cstdio>
#include <iostream>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <map>

using namespace std;
typedef double lf;
const int mod1 = 19997;
const int mod2 = 30001;
const int bin = 1 << 9;

struct TF_IDF {
int TF;
lf IDF, TF_IDF;
};

struct Word {
string st;
int h1, h2;

inline bool operator < (const Word &x) const {
return h1 == x.h1 ? h2 < x.h2 : h1 < x.h1;
}
inline bool operator == (const Word &x) const {
return h1 == x.h1 && h2 == x.h2;
}

#define x (int) st[i]
#define Weight 3001
inline void calc_hash() {
int len = st.length(), tmp, i;
for (i = tmp = 0; i < len; ++i)
((tmp *= Weight) += (x < 0 ? x + bin : x)) %= mod1;
h1 = tmp;
for (i = tmp = 0; i < len; ++i)
((tmp *= Weight) += (x < 0 ? x + bin : x)) %= mod2;
h2 = tmp;
}
#undef x
#undef Weight
} w;

typedef map <Word, TF_IDF> map_for_words;
typedef map_for_words :: iterator iter_for_words;

map_for_words passage;

void read_in_passage() {
Word w;
freopen("E:\\test\\test.in", "r", stdin);
while (cin >> w.st) {
w.calc_hash();
passage[w].TF += 1;
}
fclose(stdin);
}

void read_in_IDF_and_work() {
int id, tot = 1, i;
lf IDF;
string st;
Word w;
iter_for_words it;
freopen("E:\\test\\new.dat", "r", stdin);
ios::sync_with_stdio(false);
cin >> tot;
for (i = 1; i <= tot; ++i) {
cin >> id >> w.st >> IDF;
w.calc_hash();
it = passage.find(w);
if (it != passage.end()) {
it -> second.IDF = IDF;
it -> second.TF_IDF = (lf) it -> second.TF * it -> second.IDF;
}
}
fclose(stdin);
}

void print() {
iter_for_words it;
cout << passage.size() << endl;
for (it = passage.begin(); it != passage.end(); ++it)
cout << it -> first.st << ' ' << it -> second.TF << ' ' << it -> second.IDF << ' ' << it -> second.TF_IDF << endl;
}

int main() {
freopen("E:\\test\\test.out", "w", stdout);
read_in_passage();
read_in_IDF_and_work();
print();
return 0;
}


View Code
特别被坑死的点:

第一次打开test.in不能加上"ios::sync_with_stdio(false);",但是第二次必须加上"ios::sync_with_stdio(false);"

否则第二次是可以打开文件的,但是什么都读不到= =

谁能告诉我这是什么坑货?、、、跪求巨神解答。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: