随机计算TFIDF作为权重,然后利用余弦距离进行聚类,用的是简单k-means算法。
来源:互联网 发布:怎么取消淘宝卖家的钻 编辑:程序博客网 时间:2024/06/07 03:45
#include <iostream>
#include <string>#include <vector>#include <map>#include <utility>#include <sstream>#include <cmath>#include <cstdlib>#include <ctime>using namespace std;struct Kmeans{ vector< pair<string,map<string,int>> > asAllLines; //存储所有文本行以及每一行各个单词出现次数,用于计算TF vector< vector<double> > aaLinesTf; //所有文本行对应所有单词的TF*IDF map<string,int> mKeyAprLines; //每个单词在多少行里出现过,用于计算IDF vector< vector<double> > aCluCenter; //聚类中心 vector<int> aiLinesInCenter; //每个中心聚集了多少文本行 vector<int> aLinesCenter; //每个文本行属于哪个聚类中心 int iKeyNum; //单词种类 int iLineNum; //总文本行数 int iCenterNum; //中心个数};#define MAX_DISTANCE 1e6void stringToLower(string &key){ for(int i=0;i<(int)key.size();) { if(key[i]<0) { i+=2; } else { if('A'<=key[i] && key[i]<='Z') { key[i]=key[i]-'A'+'a'; } i++; } }}void kMeansCentersRandomInit(Kmeans *pKmeans){ srand((unsigned int)time(NULL)); for(int i=0;i<pKmeans->iCenterNum;++i) { bool bContinue=true; do { int iToSelect=rand()%pKmeans->iLineNum; if(pKmeans->aLinesCenter[iToSelect]==-1) { for(int j=0;j<pKmeans->iKeyNum;++j) { pKmeans->aCluCenter[i][j]=pKmeans->aaLinesTf[iToSelect][j]; } pKmeans->aLinesCenter[iToSelect]=i; cout<<"初始化中心"<<i<<":"<<pKmeans->asAllLines[iToSelect].first<<endl; bContinue=false; } }while(bContinue); }}int kMeansInit(Kmeans *pKmeans,const vector<string> &asAllLines,int iLineNum,int iCenterNum){ if(pKmeans==NULL) { return -1; } pKmeans->asAllLines.assign(iLineNum,pair< string,map<string,int> >()); pKmeans->aaLinesTf.assign(iLineNum,vector<double>()); pKmeans->aCluCenter.assign(iCenterNum,vector<double>()); pKmeans->aiLinesInCenter.assign(iCenterNum,0); pKmeans->aLinesCenter.assign(iLineNum,0); pKmeans->iLineNum=iLineNum; pKmeans->iCenterNum=iCenterNum; //拆分单词,统计数据 for(int i=0;i<(int)asAllLines.size();++i) { pKmeans->asAllLines[i].first=asAllLines[i]; istringstream istrm(asAllLines[i]); string key; while(istrm>>key) { stringToLower(key); if(pKmeans->asAllLines[i].second.find(key)==pKmeans->asAllLines[i].second.end()) { pKmeans->asAllLines[i].second[key]=1; } else { pKmeans->asAllLines[i].second[key]++; } if(pKmeans->asAllLines[i].second[key]==1) { pKmeans->mKeyAprLines[key]++; } } } pKmeans->iKeyNum=pKmeans->mKeyAprLines.size(); for(int i=0;i<pKmeans->iLineNum;++i) { pKmeans->aaLinesTf[i].assign(pKmeans->iKeyNum,0); pKmeans->aLinesCenter[i]=-1; } for(int i=0;i<pKmeans->iCenterNum;++i) { pKmeans->aCluCenter[i].assign(pKmeans->iKeyNum,0); } //计算TF-IDF int iKeyIndex=0; for(map<string,int>::iterator iter=pKmeans->mKeyAprLines.begin();iter!=pKmeans->mKeyAprLines.end();++iter,++iKeyIndex) { for(int line=0;line<iLineNum;++line) { if(pKmeans->asAllLines[line].second.find(iter->first)==pKmeans->asAllLines[line].second.end()) { pKmeans->aaLinesTf[line][iKeyIndex]=0; } else { double TF=1.0*pKmeans->asAllLines[line].second[iter->first]/pKmeans->asAllLines[line].second.size(); double DF=log(1.0*pKmeans->iLineNum/iter->second); pKmeans->aaLinesTf[line][iKeyIndex]=TF*DF; } } } return 0;}void kMeansMainLoop(Kmeans *pKmeans,int iTimes,double iThreshold){ /* if(iTimes==0 && iThreshold==0) { return; //没有终止条件 } */ int iLeftTimes=iTimes; double lastJ=-1; vector<int> aPreLinesCenter; //之前的聚类 kMeansCentersRandomInit(pKmeans); while(true) { double J=0; pKmeans->aiLinesInCenter.assign(pKmeans->iCenterNum,0); aPreLinesCenter=pKmeans->aLinesCenter; //保存之前的聚类 //聚类 for(int i=0;i<pKmeans->iLineNum;++i) { int iCtrIndex=-1; double minDist=MAX_DISTANCE; for(int j=0;j<pKmeans->iCenterNum;++j) { double dist,centerSum=0,lineSum=0,crossSum=0; for(int k=0;k<pKmeans->iKeyNum;++k) { crossSum+=pKmeans->aaLinesTf[i][k]*pKmeans->aCluCenter[j][k]; centerSum+=pKmeans->aCluCenter[j][k]*pKmeans->aCluCenter[j][k]; lineSum+=pKmeans->aaLinesTf[i][k]*pKmeans->aaLinesTf[i][k]; } dist=crossSum/(sqrt(centerSum)*sqrt(lineSum)); dist=1-dist; if(dist<minDist) { iCtrIndex=j; minDist=dist; } } pKmeans->aLinesCenter[i]=iCtrIndex; pKmeans->aiLinesInCenter[iCtrIndex]++; J+=minDist*minDist; } int iCnt=0; for(int i=0;i<pKmeans->iLineNum;++i) { if(pKmeans->aLinesCenter[i]==aPreLinesCenter[i]) { iCnt++; } } if(iCnt==pKmeans->iLineNum) { break; } //重新计算各聚类中心点 for(int i=0;i<pKmeans->iCenterNum;++i) { for(int j=0;j<pKmeans->iKeyNum;++j) { pKmeans->aCluCenter[i][j]=0; } } for(int i=0;i<pKmeans->iLineNum;++i) { for(int j=0;j<pKmeans->iKeyNum;++j) { pKmeans->aCluCenter[pKmeans->aLinesCenter[i]][j]+=pKmeans->aaLinesTf[i][j]; } } //求均值,更新聚类中心 for(int i=0;i<pKmeans->iCenterNum;++i) { if(pKmeans->aLinesCenter[i]!=0) { for(int j=0;j<pKmeans->iKeyNum;++j) { pKmeans->aCluCenter[i][j]/=pKmeans->aiLinesInCenter[i]; } } } if(iTimes!=0 && --iLeftTimes==0) { break; } if(iThreshold!=0 && lastJ!=-1 && fabs(lastJ-J)<iThreshold) { break; } lastJ=J; }}int main(){ Kmeans test; string input[]= { "奥运 拳击 入场券 基本 分罄 邹市明 夺冠 对手 浮出 水面", "股民 要 清楚 自己 的 目的", "印花税 之 股民 四季", "杭州 股民 放 鞭炮 庆祝 印花税 下调", "残疾 女 青年 入围 奥运 游泳 比赛 创 奥运 历史 两 项 第一", "介绍 一 个 ASP.net MVC 系列 教程", "在 asp.net 中 实现 观察者 模式 ,或 有 更 好 的 方法 (续)", "输 大钱 的 股民 给 我们 启迪", "Asp.Net 页面 执行 流程 分析", "运动员 行李 将 “后 上 先 下” 奥运 相关 人员 行李 实名制", "asp.net 控件 开发 显示 控件 内容", "奥运 票务 网上 成功 订票 后 应 及时 到 银行 代售 网点 付款", "某 心理 健康 站 开张 后 首 个 咨询 者 是 位 新 股民", "ASP.NET 自定义 控件 复杂 属性 声明 持久性 浅析" };/* for(int i=0;i<14;++i) { stringToLower(input[i]); cout<<input[i]<<endl; }*/ vector<string> allLines(input,input+sizeof(input)/sizeof(string)); kMeansInit(&test,allLines,sizeof(input)/sizeof(string),3); kMeansMainLoop(&test,0,0); for(int i=0;i<test.iCenterNum;++i) { cout<<"Center "<<i<<" : "<<endl; for(int j=0;j<test.iLineNum;++j) { if(test.aLinesCenter[j]==i) { cout<<test.asAllLines[j].first<<endl; } } cout<<endl; } return 0;}
http://topic.csdn.net/u/20110906/11/89e01a81-923d-4cfb-b0ed-3dd295c1fd98.html
初始化
- 随机计算TFIDF作为权重,然后利用余弦距离进行聚类,用的是简单k-means算法。
- [python] 基于k-means和tfidf的文本聚类代码简单实现
- [python] 基于k-means和tfidf的文本聚类代码简单实现
- 基于k-means和tfidf的文本聚类代码简单实现
- 最大最小距离算法(K-MEANS K-medoids )聚类算法的结合运用
- 利用sklearn进行tfidf计算
- Numerical Example of K-Means Clustering(K-Means聚类算法的简单例子)
- K-means算法进行简单的图像"语义"分割,java
- C#实现简单的K-means聚类算法
- tfidf算法+余弦相似度算法计算文本相似度
- 基于距离的聚类方法--K-means
- K-Means聚类算法的实现
- Python :k-means聚类算法对数据进行分类
- K-Means聚类算法进行压缩图片
- 计算两篇文档的余弦相似度(tfidf)
- k-means聚类算法
- k-means聚类算法
- K-means聚类算法
- <jsp:include> 和 <iframe src=""...>的区别
- 断了你的后路,脚踏实地开创你的事业
- Learning Emacs
- soapUI 在Ubuntu11.04下没反应的解决方法
- ubuntu 下安装fetion
- 随机计算TFIDF作为权重,然后利用余弦距离进行聚类,用的是简单k-means算法。
- oracle shrink space的最佳实践
- PPI install-locate and notify-install method
- sed 命令使用大全
- 单实例 程序 例子 修改hosts
- SKB几个复制函数的区别
- EML与MBOX转换(.eml后缀的文件与.mbox后缀的文件之间的转换)
- PDB库调试Python程序
- 静态成员函数和静态成员变量