该来的还是要来,数据挖掘
2015-05-24 03:27
169 查看
k-means算法
n个对象聚簇成k个集合,选出k个质心
什么欧几里得距离,和余弦弧度相似度
大概先从n个中随机选k个作为质心,其实有点策略选会好点
然后求最近距离弄出k个集合,然后求方差,然后迭代到收敛
期间要不停换k个质心,通过求出的集合的均值作为新的质心,质心不一定要是原对象,坐标什么的可以随便取的
最后得到的k个集合和质心为所求,方差和均值和欧几里得距离这里只是一种方法,别的地方不一定是这些
但是最后要能收敛或在一定次数后终止循环迭代,另外注意空簇可能的bug
n个对象聚簇成k个集合,选出k个质心
什么欧几里得距离,和余弦弧度相似度
大概先从n个中随机选k个作为质心,其实有点策略选会好点
然后求最近距离弄出k个集合,然后求方差,然后迭代到收敛
期间要不停换k个质心,通过求出的集合的均值作为新的质心,质心不一定要是原对象,坐标什么的可以随便取的
最后得到的k个集合和质心为所求,方差和均值和欧几里得距离这里只是一种方法,别的地方不一定是这些
但是最后要能收敛或在一定次数后终止循环迭代,另外注意空簇可能的bug
#include <bits/stdc++.h> using namespace std; const int N = 200005; const int k=3; typedef vector<double> Tuple; int dataNum; int dimNum; double getDistXY(const Tuple &t1,const Tupble &t2){ double sum=0; for(int i=1;i<=dimNum;i++) sum+=(t1[i]-t2[i])*(t1[i]-t2[i]); return sqrt(sum); } int clusterOfTuple(Tuple means[],const Tuple &tuple){ double dist=getDistXY(means[0],tuple); double tmp; int lable=0; for(int i=1;i<k;i++){ tmp=getDistXY(means[i],tuple); if(tmp<dist){ dist=tmp; label=i; } } return label; } Tuple getMeans(const vector<Tuple> &cluster){ int num=cluster.size(); Tuple t(dimNu+1,0); for(int i=0;i<num;i++){ for(int j=1;j<=dimNum;j++) t[j]+=cluster[i][j]; } for(int j=1;j<=dimNum;j++) t[j]/=num; return t; } double getVar(vector<Tuple> clusters[],Tuple means[]){ double var=0; for(int i=0;i<k;i++){ vector<Tuple> t=clusters[i]; for(int j=0;j<t.size();j++) var+=getDistXY(t[j],means[i]); } return var; } void KMeans(vector<Tuple> &tuples){ vector<Tuple> clusters[k]; Tuple means[k]; int i=0; srand(time(nullptr)); for(i=0;i<k;i++){ int iToSelect=rand()%tuples.size(); if(means[i].size()==0){ for(int j=0;j<=dimNum;j++) means[i].push_back(tuples[iToSelect][j]); i++; } } int label=0; for(i=0;i!=tuples.size();i++){ label=clusterOfTuple(means,tuples[i]); clusters[label].push_back(tuples[i]); } double oldVar=-1; double newVar=getVar(clusters,means); int t=0; oldVar=newVar; while(abs(newVar-oldVar)>=1){ for(int i=0;i<k;i++){ means[i]=getMeans(clusters[i]); } newVar=getVar(clusters,means); for(int i=0;i<k;i++) clusters[i].clear(); for(int i=0;i!=tuples.size();i++){ label=clusterOfTuple(means,tuples[i]); clusters[label].push_back(tuples[i]); } oldVar=newVar; } } int main() { char fname[256]; cout<<"Please datafiles: "; cin>>fname; cout<<endl<<"Please input dim and number"<<endl; cin>>dimNum>>dataNum; ifstream infile(fname); if(!infile){ cout<<"can't open input file!"<<endl; return 0; } vector<Tuple>tuples; for(int i=0;i<dataNum&&!infile.eof();++i){ string str; getline(infile,str); istringstream istr(str); Tuple tuple(dimNum+1,0); tuple[0]=i+1; for(int j=1;j<=dimNum;j++){ istr>>tuple[j]; } tuples.push_back(tuple); } cout<<endl<<"start k-means clustor"<<endl; KMeans(tuples); return 0; }
相关文章推荐
- 数据挖掘 是“大忽悠”还是“懵懂少年”(转帖)
- 数据挖掘 是“大忽悠”还是“懵懂少年”
- 数据挖掘 是“大忽悠”还是“懵懂少年”
- 数据挖掘是科学还是宗教?
- 数据挖掘十大经典算法(4) The Apriori algorithm
- 用于数据挖掘的分类算法有哪些,各有何优劣?
- 【数据挖掘总结】
- 数据挖掘知识梳理脑图
- 最老程序员创业札记:全文检索、数据挖掘、推荐引擎应用24
- (学)无论是CallContext还是HttpContext,都不能自动实现数据的跨线程传递?
- 通过soap请求webservice时,返回的数据是XML类型,有时候也需要解析本地的xml数据等,苹果自带类NSXMLParser解析xml还是很方便的,简单轻便
- Weka介绍--使用Weka进行数据挖掘
- 数据挖掘回顾七:回归算法之 线性回归
- 数据挖掘之聚类
- Orange,RapidMiner,Weka,JHepWork,KNIM,五个免费开源的数据挖掘软件
- Python数据挖掘06--淘宝网数据处理
- 数据挖掘、数据分析的书籍推荐
- 机器学习和数据挖掘(9):线性模型
- 利用数据挖掘实现电信行业客户流失分析
- 数据挖掘经典算法复现:朴素贝叶斯