K—Means算法实现

K—Means算法实现

算法简介

K-MEANS算法是聚类算法中比较简单的一种,他是输入聚类个数k,以及包含 n个数据对象的数据库,输出满足方差最小标准k个聚类的一种算法。k-means 算法接受输入量 k ;然后将n个数据对象划分为 k个聚类以便使得所获得的聚类满足:同一聚类中的对象相似度较高;而不同聚类中的对象相似度较小。

算法流程

输入:聚类个数k(这里的k=2),数据集。
输出:满足方差最小标准的k个聚类。
(1) 选择k个初始中心点;
(2) 对于每个对象,分别与每个中心点进行比较,假定与c差值最少,则该点为其中心点
(3) 对于所有标记为c点,重新计算c={ 所有标记为i的样本的每个特征的中心对象};
(4) 重复(2)(3),经过多次迭代,直到所有c值的变化小于给定阈值或者达到最大迭代次数。
在这里插入图片描述

代码实现

typedef struct
{
	float x;
	float y;
}Point;
int center[N];  ///  判断每个点属于哪个簇
Point p[N] = {
	{1.0, 11.0},
	{2.0, 56.0},
	{8.0, 52.0},
	{5.0, 20.0},
	{7.0, 35.0},
	{6.0, 24.0},
	{1.0, 22.0},
	{4.0, 39.0},
	{7.0, 53.0},
	{1.0, 43.0},
	{3.0, 79.0}
};
 
Point mean[K];  ///  保存每个簇的中心点
 
//获得两点间直线距离 
float getDistance(Point p1, Point p2)
{
	float d;
	d = sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));
	return d;
}
 
void getMean(int center[N])
{
	Point tep;
	int i, j, count = 0;
	for(i = 0; i < K; ++i)
	{
		count = 0;
		tep.x = 0.0;   /// 每算出一个簇的中心点值后清0
		tep.y = 0.0;
        for(j = 0; j < N; ++j)
		{
			if(i == center[j])
			{
				count++;
				tep.x += p[j].x;
				tep.y += p[j].y;
			}
		}
		tep.x /= count;
		tep.y /= count;
		mean[i] = tep;
	}
	for(i = 0; i < K; ++i)
    {
    	printf("The new center point of %d is : \t( %f, %f )\n", i+1, mean[i].x, mean[i].y);
    }
}
 
/// 计算平方误差函数(x1-x2)^2+(y1-y2)^2  计算当前各点与当前所属中心点间距离误差  
float getE()
{
	int i, j;
	float c = 0.0, sum = 0.0;
	for(i = 0; i < K; ++i)
	{
		for(j = 0; j < N; ++j)
		{
			if(i == center[j])
			{
				c = (p[j].x - mean[i].x) * (p[j].x - mean[i].x) + (p[j].y - mean[i].y) * (p[j].y - mean[i].y);
				sum += c;
			}
		}
	}
	return sum;
}
 
// 把N个点聚类
void clu()
{
	int i, j, q;
	float min;
	float distance[N][K];
	for(i = 0; i < N; ++i)
	{
		min = 100;		
		for(j = 0; j < K; ++j)//获得(point[i].x,point[i].y)的点到每个中心点的距离 
		{
			distance[i][j] = getDistance(p[i], mean[j]);
		}
		//计算每个点到三个中心点的距离,如果发现有直线距离更短的中心点,则将自己归入其中,放弃当前中心点 
		for(q = 0; q < K; ++q)
		{
			if(distance[i][q] < min)
			{
				min = distance[i][q];
        		center[i] = q;
			}
		}
		//输出这个过程中的该点及其归类 
		printf("( %.0f, %.0f )\t in -%d\n", p[i].x, p[i].y, center[i] + 1);
	}
	printf("-----------------------------\n");
}

在这里插入图片描述在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值