标签:targe release tor efi name 来源 des 下标 tab
1. 聚类与分类的区别:
首先要来了解的一个概念就是聚类,简单地说就是把相似的东西分到一组,同 Classification (分类)不同,对于一个 classifier ,通常需要你告诉它“这个东西被分为某某类”这样一些例子,理想情况下,一个 classifier 会从它得到的训练集中进行“学习”,从而具备对未知数据进行分类的能力,这种提供训练数据的过程通常叫做 supervised learning (监督学习),而在聚类的时候,我们并不关心某一类是什么,我们需要实现的目标只是把相似的东西聚到一起,因此,一个聚类算法通常只需要知道如何计算相似 度就可以开始工作了,因此 clustering 通常并不需要使用训练数据进行学习,这在 Machine Learning 中被称作 unsupervised learning (无监督学习)。
我们经常接触到的聚类分析,一般都是数值聚类,一种常见的做法是同时提取 N 种特征,将它们放在一起组成一个 N 维向量,从而得到一个从原始数据集合到 N 维向量空间的映射——你总是需要显式地或者隐式地完成这样一个过程,然后基于某种规则进行分类,在该规则下,同组分类具有最大的相似性。
假设我们提取到原始数据的集合为(x1, x2, …, xn),并且每个xi为d维的向量,K-means聚类的目的就是,在给定分类组数k(k ≤ n)值的条件下,将原始数据分成k类
S = {S1, S2, …, Sk},在数值模型上,即对以下表达式求最小值:
这里μi 表示分类Si 的平均值。
说明:给定K,聚类完成后,对于每个类,对该类中的所有样本点到该类中心点的距离的平方求和,记为sum,对每个类都这样求和,然后把所有类的
sum加起来,总和记为SUM,聚类Kmeans算法就是要使得SUM最小。
那么在计算机编程中,其又是如何实现的呢?其算法步骤一般如下:
1、从D中随机取k个元素,作为k个簇的各自的中心。
2、分别计算剩下的元素到k个簇中心的相异度,将这些元素分别划归到相异度最低的簇。
3、根据聚类结果,重新计算k个簇各自的中心,计算方法是取簇中所有元素各自维度的算术平均数。
4、将D中全部元素按照新的中心重新聚类。
5、重复第4步,直到聚类结果不再变化。
6、将结果输出。
用数学表达式来说,
设我们一共有 N 个数据点需要分为 K 个 cluster ,k-means 要做的就是最小化
这个函数,其中 在数据点 n 被归类到 cluster k 的时候为 1 ,否则为 0 。即上面的J即为最上面的SUM,直接寻找 和 来最小化 并不容易,不过我们可以采取迭代的办法:先固定 ,选择最优的 ,很容易看出,只要将数据点归类到离他最近的那个中心就能保证 最小。下一步则固定 ,再求最优的 。将 对 求导并令导数等于零,很容易得到 最小的时候 应该满足:
其中 在数据点 n 被归类到 cluster k 的时候为 1,即上面的分母就是类cluster k中样本点数,而分子为该分类中所有样本点的和
亦即 的值应当是所有 cluster k 中的数据点的平均值。由于每一次迭代都是取到 的最小值,因此 只会不断地减小(或者不变),而不会增加,这保证了 k-means 最终会到达一个极小值。虽然 k-means 并不能保证总是能得到全局最优解,但是对于这样的问题,像 k-means 这种复杂度的算法,这样的结果已经是很不错的了。
2. 实现:
注:该实现用的是opencv中的一个函数:cvKMeans2函数
代码来源:http://www.cnblogs.com/moondark/archive/2012/03/08/2385870.html
- </pre><p></p><p style="margin:15px auto 10px; padding-top:0px; padding-bottom:0px; line-height:22px; text-align:justify"></p><pre code_snippet_id="500422" snippet_file_name="blog_20141029_2_1547356" name="code" class="cpp" style="font-family: ‘Lucida Grande‘, ‘Lucida Sans Unicode‘, Helvetica, Arial, Verdana, sans-serif; font-size: 14px; ">#ifdef _CH_
- #pragma package <opencv>
- #endif
-
- #define CV_NO_BACKWARD_COMPATIBILITY
-
- #include "opencv/cv.h"
- #include "opencv/highgui.h"
- #include <stdio.h>
-
- int main( int argc, char** argv )
- {
- #define MAX_CLUSTERS 5 //设置类别的颜色,个数(《=5)
- CvScalar color_tab[MAX_CLUSTERS];
- IplImage* img = cvCreateImage( cvSize( 500, 500 ), 8, 3 );
- CvRNG rng = cvRNG(-1);
- CvPoint ipt;
-
- color_tab[0] = CV_RGB(255,0,0);
- color_tab[1] = CV_RGB(0,255,0);
- color_tab[2] = CV_RGB(100,100,255);
- color_tab[3] = CV_RGB(255,0,255);
- color_tab[4] = CV_RGB(255,255,0);
-
- cvNamedWindow( "clusters", 1 );
-
- for(;;)
- {
- char key;
- int k, cluster_count = cvRandInt(&rng)%MAX_CLUSTERS + 1;
- int i, sample_count = cvRandInt(&rng)%1000 + 1;
- CvMat* points = cvCreateMat( sample_count, 1, CV_32FC2 );
- CvMat* clusters = cvCreateMat( sample_count, 1, CV_32SC1 );
- cluster_count = MIN(cluster_count, sample_count);
-
-
- for( k = 0; k < cluster_count; k++ )
- {
- CvPoint center;
- CvMat point_chunk;
- center.x = cvRandInt(&rng)%img->width;
- center.y = cvRandInt(&rng)%img->height;
-
- cvGetRows( points, &point_chunk, k*sample_count/cluster_count,
- k == cluster_count - 1 ? sample_count :
- (k+1)*sample_count/cluster_count, 1 );
-
-
- cvRandArr( &rng, &point_chunk, CV_RAND_NORMAL,
- cvScalar(center.x,center.y,0,0),
- cvScalar(img->width*0.1,img->height*0.1,0,0));
- }
-
-
- for( i = 0; i < sample_count/2; i++ )
- {
- CvPoint2D32f* pt1 = (CvPoint2D32f*)points->data.fl + cvRandInt(&rng)%sample_count;
- CvPoint2D32f* pt2 = (CvPoint2D32f*)points->data.fl + cvRandInt(&rng)%sample_count;
- CvPoint2D32f temp;
- CV_SWAP( *pt1, *pt2, temp );
- }
-
-
-
-
- printf( "iterations=%d\n", cvKMeans2( points, cluster_count, clusters,
- cvTermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 10, 1.0 ),
- 5, 0, 0, 0, 0 ));
- cvZero( img );
-
- for( i = 0; i < sample_count; i++ )
- {
- int cluster_idx = clusters->data.i[i];
- ipt.x = (int)points->data.fl[i*2];
- ipt.y = (int)points->data.fl[i*2+1];
- cvCircle( img, ipt, 2, color_tab[cluster_idx], CV_FILLED, CV_AA, 0 );
- }
-
- cvReleaseMat( &points );
- cvReleaseMat( &clusters );
-
- cvShowImage( "clusters", img );
-
- key = (char) cvWaitKey(0);
- if( key == 27 || key == ‘q‘ || key == ‘Q‘ )
- break;
- }
-
- cvDestroyWindow( "clusters" );
- return 0;
- }
效果如下:
转:http://blog.csdn.net/damotiansheng/article/details/40582211
【转】 聚类算法-Kmeans算法的简单实现
标签:targe release tor efi name 来源 des 下标 tab
原文地址:http://www.cnblogs.com/eleclsc/p/6569059.html