• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
HaibaraAi
博客园    首页    新随笔    联系   管理    订阅  订阅

该来的还是要来,数据挖掘

k-means算法
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;
}
posted @ 2015-05-24 03:27  HaibaraAi  阅读(204)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3