㈠ 急求:k-Means聚类算法实现
K-MEANS算法:
k-means 算法接受输入量 k ;然后将n个数据对象划分为 k个聚类以便使得所获得的聚类满足:同一聚类中的对象相似度较高;而不同聚类中的对象相似度较小。聚类相似度是利用各聚类中对象的均值所获得一个“中心对象”(引力中心)来进行计算的。
k-means 算法的工作过程说明如下:首先从n个数据对象任意选择 k 个对象作为初始聚类中心;而对于所剩下其它对象,则根据它们与这些聚类中心的相似度(距离),分别将它们分配给与其最相似的(聚类中心所代表的)聚类;然后再计算每个所获新聚类的聚类中心(该聚类中所有对象的均值);不断重复这一过程直到标准测度函数开始收敛为止。一般都采用均方差作为标准测度函数. k个聚类具有以下特点:各聚类本身尽可能的紧凑,而各聚类之间尽可能的分开。
具体如下:
输入:k, data[n];
(1) 选择k个初始中心点,例如c[0]=data[0],…c[k-1]=data[k-1];
(2) 对于data[0]….data[n], 分别与c[0]…c[n-1]比较,假定与c[i]差值最少,就标记为i;
(3) 对于所有标记为i点,重新计算c[i]={ 所有标记为i的data[j]之和}/标记为i的个数;
(4) 重复(2)(3),直到所有c[i]值的变化小于给定阈值。
算法实现起来应该很容易,就不帮你编写代码了。
㈡ 求一个用c语言写的基于K-means聚类的图像分割代码
基于Kmeans图像分割
..................\程序
..................\....\ChildFrm.cpp
..................\....\ChildFrm.h
..................\....\Debug
..................\....\Dib.cpp
..................\....\Dib.h
..................\....\MainFrm.cpp
..................\....\MainFrm.h
..................\....\ReadMe.txt
..................\....\res
..................\....\...\trace.rc2
..................\....\Resource.h
..................\....\StdAfx.cpp
..................\....\StdAfx.h
..................\....\trace.aps
..................\....\trace.clw
..................\....\trace.cpp
..................\....\trace.dsp
..................\....\trace.dsw
..................\....\trace.h
..................\....\trace.ncb
..................\....\trace.opt
..................\....\trace.plg
..................\....\trace.rc
..................\....\traceDoc.cpp
..................\....\traceDoc.h
..................\....\traceView.cpp
..................\....\traceView.h
㈢ 高分求一个C语言编写的聚类分析算法!!!
用c语言写?有点疯狂了,现在都用python写,你要的话我发给你,很多函数库,在c语言下不知道能不能找到呢
㈣ kmeans聚类算法是什么
K-means算法是最为经典的基于划分的聚类方法,是十大经典数据挖掘算法之一。K-means算法的基本思想是:以空间中k个点为中心进行聚类,对最靠近他们的对象归类。通过迭代的方法,逐次更新各聚类中心的值,直至得到最好的聚类结果。
聚类属于无监督学习,以往的回归、朴素贝叶斯、SVM等都是有类别标签y的,也就是说样例中已经给出了样例的分类。而聚类的样本中却没有给定y,只有特征x,比如假设宇宙中的星星可以表示成三维空间中的点集。
(4)kmeans算法c语言扩展阅读:
k个聚类以便使得所获得的聚类满足:同一聚类中的对象相似度较高;而不同聚类中的对象相似度较小。聚类相似度是利用各聚类中对象的均值所获得一个“中心对象”(引力中心)来进行计算的。
(1)适当选择c个类的初始中心;
(2)在第k次迭代中,对任意一个样本,求其到c个中心的距离,将该样本归到距离最短的中心所在的类;
(3)利用均值等方法更新该类的中心值;
(4)对于所有的c个聚类中心,如果利用(2)(3)的迭代法更新后,值保持不变,则迭代结束,否则继续迭代。
㈤ kmeans聚类算法是什么
kmeans聚类算法是将样本聚类成k个簇(cluster)。
K-Means算法的思想很简单,对于给定的样本集,按照样本之间的距离大小,将样本集划分为K个簇。让簇内的点尽量紧密的连在一起,而让簇间的距离尽量的大。在实际K-Mean算法中,我们一般会多次运行图c和图d,才能达到最终的比较优的类别。
用数据表达式表示
假设簇划分为$(C_1,C_2,...C_k)$,则我们的目标是最小化平方误差E:$$ E = sumlimits_{i=1}^ksumlimits_{x in C_i} ||x-mu_i||_2^2$$。
其中$mu_i$是簇$C_i$的均值向量,有时也称为质心,表达式为:$$mu_i = frac{1}{|C_i|}sumlimits_{x in C_i}x$$。
㈥ 急求用C#写的K-means算法的源程序 不懂的别来忽悠我
日 这都什么人? 一点共享精神也没有!!自己动手丰衣足食 ,自己来给大家分享 下(8个点聚成3个簇 输出不明显 有待改进)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text.RegularExpressions;
using System.Data.SqlClient;
using System.Windows.Forms;
namespace kmeans
{
public partial class Form1 : Form
{
public SqlConnection conn= new SqlConnection("server=localhost;uid=sa;pwd=123;database=Stu_info");
public Form1()
{
InitializeComponent();
}
private void button3_Click(object sender, EventArgs e)
{
/*float numCluster = float.Parse (textBox2.Text);
if (textBox2.Text == "")
{
MessageBox.Show("请输入期望簇的数目!");
return;
}
this.numCluster = float.Parse(numCluster);*/
int k = 3; //簇的数目
int n = 8;
List<points> lp=new List<points>(); //n条数据
lp.Add(new points(2, 10));
lp.Add(new points(5, 8));
lp.Add(new points(1, 2));
lp.Add(new points(2, 5));
lp.Add(new points(8, 4));
lp.Add(new points(7, 5));
lp.Add(new points(6, 4));
lp.Add(new points(4, 9));
/*lp.Add(new points(1,4 ));
lp.Add(new points(7,2));*/
string[] clusters = new string[k]; //k个簇,每个簇存储数据在points中的位置,数据之间用","分开
points[] centers = new points[k]; //k个簇的中心
points[] preCenters = new points[k];//前一次计算的簇中心
Regex r = new Regex(",");
for (int i = 0; i < k; i++) //取前k个对象作为初始的簇中心
{
centers[i] = new points(lp[i].X, lp[i].Y);
}
bool stop = false;
while (!stop)
{
for (int i = 0; i < clusters.Length; i++)//清空簇中的数据
{
clusters[i] = null;
}
for (int i = 0; i < n; i++)//搜索所有对象
{
double distance = points.DistanceBetween(lp[i], centers[0]);
double temp;
int num = 0;
for (int j = 0; j < k; j++)//搜索k个簇,比较对象与簇中心的距离,将与当前对象距离最小的簇的编号放入num
{
if ((temp = points.DistanceBetween(lp[i], centers[j])) < distance) { num = j; distance = temp; }
}
clusters[num] = clusters[num] + i + ",";
}
for (int i = 0; i < k; i++)
{
preCenters[i] = new points(centers[i].X, centers[i].Y);//保存先前的簇中心
}
for (int i = 0; i < k; i++)
{
centers[i].X = 0;
centers[i].Y = 0;
if (clusters[i] != null)
{
string[] pointsNum = r.Split(clusters[i]);
for (int j = 0; j < pointsNum.Length - 1; j++)
{
centers[i].X = centers[i].X + lp[Convert.ToInt32(pointsNum[j])].X;
centers[i].Y = centers[i].Y + lp[Convert.ToInt32(pointsNum[j])].Y;
}
centers[i].X = Convert.ToDouble(centers[i].X) / (pointsNum.Length - 1);
centers[i].Y = Convert.ToDouble(centers[i].Y) / (pointsNum.Length - 1);
}
}
stop = true;
for (int i = 0; i < k; i++)
{
if (preCenters[i].X != centers[i].X || preCenters[i].Y != centers[i].Y) stop = false;
}
}
listBox1.Items.Clear();
for (int i = 0; i < k; i++)//输出每个簇中数据所在的位置
{
string[] nums = r.Split(clusters[i]);
for (int j = 0; j < nums.Length - 1; j++)
{
//Console.Write("({0},{1}) ", lp[Convert.ToInt32(nums[j])].X, lp[Convert.ToInt32(nums[j])].Y);
listBox1.Items.Add(lp[Convert.ToInt32(nums[j])].X+","+lp[Convert.ToInt32(nums[j])].Y);
}
//Console.Write('\n');
}
//Console.Read();
}
private void button2_Click_1(object sender, EventArgs e)
{
this.Close();
}
private void button1_Click_1(object sender, EventArgs e)
{
OpenFileDialog dlg = new OpenFileDialog();
dlg.ShowDialog();
textBox1.Text = dlg.FileName;
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.Collections;
using System.Text.RegularExpressions;
using System.Data.Odbc;
namespace kmeans
{
public class points
{
private double x;
private double y;
public double X
{
get { return x; }
set { x = value; }
}
public double Y
{
get { return y; }
set { y = value; }
}
public points()
{
x = 0;
y = 0;
}
public points(double xx, double yy)
{
x = xx;
y = yy;
}
public void SetPoint(double xx, double yy)
{
x = xx;
y = yy;
}
public static double DistanceBetween(points p1,points p2)
{
double distance;
return distance=Math.Pow((p1.X - p2.X) * (p1.X - p2.X) + (p1.Y - p2.Y) * (p1.Y - p2.Y),1.0/2);
}
}
}
㈦ 大数据十大经典算法之k-means
大数据十大经典算法之k-means
k均值算法基本思想:
K均值算法是基于质心的技术。它以K为输入参数,把n个对象集合分为k个簇,使得簇内的相似度高,簇间的相似度低。
处理流程:
1、为每个聚类确定一个初始聚类中心,这样就有k个初始聚类中心;
2、将样本按照最小距离原则分配到最邻近聚类
3、使用每个聚类中的样本均值作为新的聚类中心
4、重复步骤2直到聚类中心不再变化
5、结束,得到K个聚类
划分聚类方法对数据集进行聚类时的要点:
1、选定某种距离作为数据样本间的相似性度量,通常选择欧氏距离。
2、选择平价聚类性能的准则函数
用误差平方和准则函数来评价聚类性能。
3、相似度的计算分局一个簇中对象的平均值来进行
K均值算法的优点:
如果变量很大,K均值比层次聚类的计算速度较快(如果K很小);
与层次聚类相比,K均值可以得到更紧密的簇,尤其是对于球状簇;
对于大数据集,是可伸缩和高效率的;
算法尝试找出使平方误差函数值最小的k个划分。当结果簇是密集的,而簇与簇之间区别明显的时候,效果较好。
K均值算法缺点:
最后结果受初始值的影响。解决办法是多次尝试取不同的初始值。
可能发生距离簇中心m最近的样本集为空的情况,因此m得不到更新。这是一个必须处理的问题,但我们忽略该问题。
不适合发现非凸面形状的簇,并对噪声和离群点数据较敏感,因为少量的这类数据能够对均值产生较大的影响。
K均值算法的改进:
样本预处理。计算样本对象量量之间的距离,筛掉与其他所有样本那的距离和最大的m个对象。
初始聚类中心的选择。选用簇中位置最靠近中心的对象,这样可以避免孤立点的影响。
K均值算法的变种:
K众数(k-modes)算法,针对分类属性的度量和更新质心的问题而改进。
EM(期望最大化)算法
k-prototype算法
这种算法不适合处理离散型属性,但是对于连续型具有较好的聚类效果。
k均值算法用途:
图像分割;
衡量足球队的水平;
下面给出代码:
#include <iostream>
#include <vector>
//auther archersc
//JLU
namespace CS_LIB
{
using namespace std;
class Kmean
{
public:
//输入格式
//数据数量N 维度D
//以下N行,每行D个数据
istream& loadData(istream& in);
//输出格式
//聚类的数量CN
//中心维度CD
//CN行,每行CD个数据
//数据数量DN
//数据维度DD
//以下DN组,每组的第一行两个数值DB, DDis
//第二行DD个数值
//DB表示改数据属于一类,DDis表示距离改类的中心的距离
ostream& saveData(ostream& out);
//设置中心的数量
void setCenterCount(const size_t count);
size_t getCenterCount() const;
//times最大迭代次数, maxE ,E(t)表示第t次迭代后的平方误差和,当|E(t+1) - E(t)| < maxE时终止
void clustering(size_t times, double maxE);
private:
double calDistance(vector<double>& v1, vector<double>& v2);
private:
vector< vector<double> > m_Data;
vector< vector<double> > m_Center;
vector<double> m_Distance;
vector<size_t> m_DataBelong;
vector<size_t> m_DataBelongCount;
};
}
#include "kmean.h"
#include <ctime>
#include <cmath>
#include <cstdlib>
//auther archersc
//JLU
namespace CS_LIB
{
template<class T>
void swap(T& a, T& b)
{
T c = a;
a = b;
b = c;
}
istream& Kmean::loadData(istream& in)
{
if (!in){
cout << "input error" << endl;
return in;
}
size_t dCount, dDim;
in >> dCount >> dDim;
m_Data.resize(dCount);
m_DataBelong.resize(dCount);
m_Distance.resize(dCount);
for (size_t i = 0; i < dCount; ++i){
m_Data[i].resize(dDim);
for (size_t j = 0; j < dDim; ++j){
in >> m_Data[i][j];
}
}
return in;
}
ostream& Kmean::saveData(ostream& out)
{
if (!out){
cout << "output error" << endl;
return out;
}
out << m_Center.size();
if (m_Center.size() > 0)
out << << m_Center[0].size();
else
out << << 0;
out << endl << endl;
for (size_t i = 0; i < m_Center.size(); ++i){
for (size_t j = 0; j < m_Center[i].size(); ++j){
out << m_Center[i][j] << ;
}
out << endl;
}
out << endl;
out << m_Data.size();
if (m_Data.size() > 0)
out << << m_Data[0].size();
else
out << << 0;
out << endl << endl;
for (size_t i = 0; i < m_Data.size(); ++i){
out << m_DataBelong[i] << << m_Distance[i] << endl;
for (size_t j = 0; j < m_Data[i].size(); ++j){
out << m_Data[i][j] << ;
}
out << endl << endl;
}
return out;
}
void Kmean::setCenterCount(const size_t count)
{
m_Center.resize(count);
m_DataBelongCount.resize(count);
}
size_t Kmean::getCenterCount() const
{
return m_Center.size();
}
void Kmean::clustering(size_t times, double maxE)
{
srand((unsigned int)time(NULL));
//随机从m_Data中选取m_Center.size()个不同的样本点作为初始中心。
size_t *pos = new size_t[m_Data.size()];
size_t i, j, t;
for (i = 0; i < m_Data.size(); ++i){
pos[i] = i;
}
for (i = 0; i < (m_Data.size() << 1); ++i){
size_t s1 = rand() % m_Data.size();
size_t s2 = rand() % m_Data.size();
swap(pos[s1], pos[s2]);
}
for (i = 0; i < m_Center.size(); ++i){
m_Center[i].resize(m_Data[pos[i]].size());
for (j = 0; j < m_Data[pos[i]].size(); ++j){
m_Center[i][j] = m_Data[pos[i]][j];
}
}
delete []pos;
double currE, lastE;
for (t = 0; t < times; ++t){
for (i = 0; i < m_Distance.size(); ++i)
m_Distance[i] = LONG_MAX;
for (i = 0; i < m_DataBelongCount.size(); ++i)
m_DataBelongCount[i] = 0;
currE = 0.0;
for (i = 0; i < m_Data.size(); ++i){
for (j = 0; j < m_Center.size(); ++j){
double dis = calDistance(m_Data[i], m_Center[j]);
if (dis < m_Distance[i]){
m_Distance[i] = dis;
m_DataBelong[i] = j;
}
}
currE += m_Distance[i];
m_DataBelongCount[m_DataBelong[i]]++;
}
cout << currE << endl;
if (t == 0 || fabs(currE - lastE) > maxE)
lastE = currE;
else
break;
for (i = 0; i < m_Center.size(); ++i){
for (j = 0; j < m_Center[i].size(); ++j)
m_Center[i][j] = 0.0;
}
for (i = 0; i < m_DataBelong.size(); ++i){
for (j = 0; j < m_Data[i].size(); ++j){
m_Center[m_DataBelong[i]][j] += m_Data[i][j] / m_DataBelongCount[m_DataBelong[i]];
}
}
}
}
double Kmean::calDistance(vector<double>& v1, vector<double>& v2)
{
double result = 0.0;
for (size_t i = 0; i < v1.size(); ++i){
result += (v1[i] - v2[i]) * (v1[i] - v2[i]);
}
return pow(result, 1.0 / v1.size());
//return sqrt(result);
}
}
#include <iostream>
#include <fstream>
#include "kmean.h"
using namespace std;
using namespace CS_LIB;
int main()
{
ifstream in("in.txt");
ofstream out("out.txt");
Kmean kmean;
kmean.loadData(in);
kmean.setCenterCount(4);
kmean.clustering(1000, 0.000001);
kmean.saveData(out);
return 0;
}
㈧ 使用K-Means 算法进行聚类分析程序
你这是四维数据,我这是一维数据kmeans,你试试吧
#include<iostream>
#include<math.h>
#include<stdlib.h>
#include<stdio.h>
using namespace std;
int N; //数据个数
int K; //集合个数
int *CenterIndex; //质心索引集合,即属于第几个参考点
double *Center; //质心集合
double *CenterCopy;
double *DataSet;
double **Cluster;
int *Top;
/*算法描述:
C-Fuzzy均值聚类算法采用的是给定类的个数K,将N个元素(对象)分配到K个类中去使得类内对象之间的相似性最大,而类之间的相似性最小 */
//函数声明部分
void InitData();
void InitCenter();
void CreateRandomArray(int n,int k,int *centerIndex);
void CopyCenter();
void UpdateCluster();
void UpdateCenter();
int GetIndex(double value,double *centerIndex);
void AddtoCluster(int index,double value);
void print();
bool IsEqual(double *center,double *center);
int main()
{
int Flag=1;
InitData();
while(Flag)//无限次循环
{
UpdateCluster();
UpdateCenter();
if(IsEqual(Center,CenterCopy))
{
Flag=0;
}
else
{
CopyCenter();
}
}
print();
getchar();
system("pause");
}
void InitData()
{
int i=0;
int a;
cout<<"请输入数据元素的个数: ";
cin>>N;
cout<<"请输入分类数: ";
cin>>K;
if(K>N)
{
return;
}
CenterIndex =new int [sizeof(int)];
Center =new double [sizeof(double)*K];
CenterCopy =new double [sizeof(double)*K];
DataSet =new double [sizeof(double)*N];
Cluster =new double* [sizeof(double*)*K];
Top =new int [sizeof(int)*K];
//初始化K个类的集合
for(i=0;i<K;i++)
{
Cluster[i]=new double [sizeof(double)*N];
Top[i]=0;
}
cout<<"请输入数据"<<endl;
for(i=0;i<N;i++)
{
cin>>a;
DataSet[i]=a;
}
//初始化质心集合
InitCenter();
UpdateCluster();
}
void InitCenter()//初始化中心点(参照点)
{
int i=0;
//产生随即的K个<N的不同的序列
CreateRandomArray(N,K,CenterIndex);
for(i=0;i<K;i++)
{
Center[i]=DataSet[CenterIndex[i]];
}
CopyCenter();
}
void CreateRandomArray(int n,int k,int *centerIndex)//产生可以随输出控制的 k与n (可舍弃)
{
int i=0,j=0;
for(i=0;i<K;i++)
{
int a=rand()%n;
for(j=0;j<i;j++)
{
if(centerIndex[j]==a)
break;
}
if(j>=i)
{
centerIndex[i]=a;
}
else
{
i--;
}
}
}
void CopyCenter()//将旧的中心点保留以作比较
{
int i=0;
for(i=0;i<K;i++)
{
CenterCopy[i]=Center[i];
}
}
void UpdateCluster()//
{
int i=0;
int tindex;
for(;i<K;i++)
{
Top[i]=0;
}
for(i=0;i<N;i++)
{
tindex=GetIndex(DataSet[i],Center);
AddtoCluster(tindex,DataSet[i]);
}
}
int GetIndex(double value,double *center)//判断属于哪个参照点
{
int i=0;
int index=i;
double min=fabs(value-center[i]);
for(i=0;i<K;i++)
{
if(fabs(value-center[i])<min)
{
index=i;
min=fabs(value-center[i]);
}
}
return index;
}
void AddtoCluster(int index,double value)//统计每组个数(用于均值法求新的参照点)
{
Cluster[index][Top[index]]=value;
Top[index]++;
}
void UpdateCenter()//更新参照点
{
int i=0,j=0;
double sum;
for(i=0;i<K;i++)
{
sum=0.0;
for(j=0;j<Top[i];j++)
{
sum+=Cluster[i][j];
}
if(Top[i]>0)
{
Center[i]=sum/Top[i];
}
}
}
bool IsEqual(double *center,double*center)//
{
int i;
for(i=0;i<K;i++)
{
if(fabs(center[i]!=center[i]))
return 0;
}
return 1;
}
void print()//
{
int i,j;
cout<<"===================================="<<endl;
for(i=0;i<K;i++)
{
cout<<"第"<<i<<"组:质心为:"<<Center[i]<<endl;
cout<<"数据元素为:\n";
for(j=0;j<Top[i];j++)
{
cout<<Cluster[i][j]<<'\t';
}
cout<<endl;
}
}