Kmeans 聚類之建立文檔向量模型(VSM)

來源:互聯網
上載者:User

作者:finallyliuyu 轉載使用等請註明出處

在上一篇博文《Kmeans聚類之特徵詞選擇DF》中我們已經給出了特徵詞選擇的代碼,這裡我們將給出建立文檔向量模型的代碼,以及將文檔向量模型寫成Weka資料格式的代碼。關於Weka資料格式等相關內容,請見:教程。

首先我們給出寫Arff標頭檔的代碼

void Preprocess::WriteHeadArff(){ofstream ofile(arffFileAddress,ios::binary);ofile<<"@relation aticle"<<endl;ofile<<"\n";vector<string> myKeys=GetFinalKeyWords();for(vector<string>::iterator it=myKeys.begin();it!=myKeys.end();it++){//string temp="@attribute "+"'"+(*it)+"'"+" real";string temp="";temp+="@attribute ";temp+="'";temp+=*(it);temp+="'";temp+=" real";/*strcpy(temp,"@attribute ");strcpy(temp,"'");strcpy(temp,*(it));strcpy(temp,"'");strcpy(temp," real");*/ofile<<temp<<endl;}ofile<<"\n"<<endl;ofile<<"@data"<<endl;ofile.close();}

下面重點介紹採用TF-IDF權重建立文檔向量模型:

在給出代碼之前先簡要介紹下什麼是TF,DF

對於一個特定的Term t

TF,指的是它在嗎某一篇文章中出現的次數;

DF,指的是整個文檔集合中出現該詞的文章篇數;

文檔向量模型(Vector Space Model):向量。向量的屬性為用《Kmeans聚類之特徵詞選擇DF》中的特徵詞選擇方法選定的特徵詞。

整個文檔集合的VSM模型實際上是以矩陣的格式儲存的。矩陣的每一行,代表一篇文章,是一個文檔向量。

TF-IDF模型有很多權重計算模式:(注意:以下來自於計算所王斌老師的課件《現代資訊檢索》)在這裡順便給大家介紹一本十分不錯的書《資訊檢索導論》 (Introduction to Information Retrieval)原版第一作者為斯坦福大學電腦語言學副教授Christopher D. Manning。該書由王斌老師翻譯成中文,現在已經出版。

TF權重計算模式:

IDF權重計算模式:

歸一化方式:

考慮到一篇文章可能完全不含有我們用DF選擇法選擇的特徵詞。

那麼這篇文章的VSM就是{0,0,0,..0}

為了避免產生這種類型的稀疏資料,我採用的TF-IDF計算模式為

a-l-c。

大家對應上面三個表找一下,就找到相應的計算公式了。

下面開始建立文檔向量模型:

獲得每個特徵詞對應的maxTF和DF:

ector<pair<int,int> >Preprocess::GetfinalKeysMaxTFDF(map<string,vector<pair<int,int>>> &mymap){vector<pair<int,int> >maxTFandDF;vector<string>myKeys=GetFinalKeyWords();for(vector<string>::iterator it=myKeys.begin();it!=myKeys.end();it++){  int DF=mymap[*it].size();int maxTF=0;for(vector<pair<int,int> >::iterator subit=mymap[*it].begin();subit!=mymap[*it].end();subit++){if(subit->second>maxTF){maxTF=subit->second;}}maxTFandDF.push_back(make_pair(maxTF,DF));//find_if(mymap[*it].begin(),mymap[*it].end(),}return maxTFandDF;}

 

************************************************************************//* 文檔向量模型歸一化                                                                     *//************************************************************************/vector<pair<int,double> >Preprocess::NormalizationVSM(vector<pair<int,double> > tempVSM){double sum=0;for(vector<pair<int,double> >::iterator vsmit=tempVSM.begin();vsmit!=tempVSM.end();++vsmit){sum+=pow(vsmit->second,2);}for(vector<pair<int,double> >::iterator vsmit=tempVSM.begin();vsmit!=tempVSM.end();++vsmit){vsmit->second/=sqrt(sum);}return tempVSM;}
有了上面的輔助函數,那麼我們可以一邊對文檔集合建立文檔向量模型,一邊寫arff檔案的data部分了。
首先還要給出兩個輔助函數,分別完成浮點數和整數字串化的功能
/************************************************************************//* 將整數轉化成字串                                                   *//************************************************************************/string Preprocess::do_fraction(int val){ostringstream out;out<<val;string str= out.str(); //從流中取出字串str.swap(string(str.c_str()));//刪除nul之後的多餘字元return str;}
 
 
/************************************************************************//* 將浮點數轉化成指定精度的字串                                       *//************************************************************************/string Preprocess::do_fraction(double val,int decplaces){//int prec=numeric_limits<double>::digits10;char DECIMAL_POINT='.'; ostringstream out;//out.precision(prec);out<<val;string str=out.str();size_t n=str.find(DECIMAL_POINT);if((n!=string::npos)&&n+decplaces<str.size()){str[n+decplaces]='\0';}str.swap(string(str.c_str()));return str;}

 

將一篇文檔的VSM字串化的函數:

 

************************************************************************//*              單個文檔向量模型字串化                                                        *//************************************************************************/string Preprocess::FormatVSMtoString(vector<pair<int,double> > tempVSM){string ret="{";int commaindication=0;for(vector<pair<int,double> >::iterator vsmit=tempVSM.begin();vsmit!=tempVSM.end();++vsmit){   ret+=do_fraction(vsmit->first)+" "+do_fraction(vsmit->second,8);if(commaindication<tempVSM.size()-1){ret+=",";}commaindication++;}ret+="}";return ret;}

 

 

下面的函數調用上面的FormatVSMtoString 填寫arff檔案的data欄位

 

/************************************************************************//* 將實驗資料寫成arff @data格式                                                                     *//************************************************************************/void Preprocess::VSMFormation(map<string,vector<pair<int,int>>> &mymap){   int corpus_N=endIndex-beginIndex+1;ofstream ofile1(articleIdsAddress,ios::binary);//儲存文章編號的檔案ofstream ofile2(arffFileAddress,ios::binary|ios::app);vector<string> myKeys=GetFinalKeyWords();vector<pair<int,int> >maxTFandDF=GetfinalKeysMaxTFDF(mymap);for(int i=beginIndex;i<=endIndex;i++){   vector<pair<int,double> >tempVSM;for(vector<string>::size_type j=0;j<myKeys.size();j++){//vector<pair<int,int> >::iterator findit=find_if(mymap[myKeys[j]].begin(),mymap[myKeys[j]].end(),PredTFclass(i));double TF=(double)count_if(mymap[myKeys[j]].begin(),mymap[myKeys[j]].end(),PredTFclass(i));TF=0.5+0.5*(double)TF/(maxTFandDF[j].first);TF*=log((double)corpus_N/maxTFandDF[j].second);if(TF!=0){tempVSM.push_back(make_pair(j,TF));}}if(!tempVSM.empty()){tempVSM=NormalizationVSM(tempVSM);string vsmStr=FormatVSMtoString(tempVSM);ofile1<<i<<endl;ofile2<<vsmStr<<endl;}tempVSM.clear();}ofile1.close();ofile2.close();}
至此文檔向量模型建立模組的代碼已經介紹完畢。
未完,待續,下次我們將介紹如何從weka獲得計算出的聚類中心,完成文本聚類。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.