• Machine Learning(1)——kmeans算法


    在OpenCV Maching Learning部分,实现了一些经典的机器学习算法,并且每个算法都有相应的例子,所以我觉得可以从这里开始学习机器学习算法。

    K-means算法应该是比较简单的机器学习算法,就先从这个开始学习。

    K-means 算法是很典型的基于距离的聚类算法 。从二维图像的例子来看,图像上有很多个点,为了将这些点按他们相近的距离分成一簇一簇的,假设要分成k簇,k-means算法步骤如下,

    a.  随机地选取k个点作为中心,

    b.  计算每个点到这些中心的距离,将这个点归属于离它最近的中心,这样就得到了k个簇。因为是随机选取的中心,会有一些点分配到错误的中心上。

    c.  根据得到的簇重新计算出它的中心,那么属于某个簇的点到它中心的距离就比较平均。

    d.  重复b~c,直到收敛。

    上图中可以看到,一开始随机选取的中心,有可能使一些点错误地放到其它簇。但在迭代过程中,它会改变它所属的簇,最后归属到正确的簇。

    下面是OpenCV里面的代码,相较于learning OpenCV上的代码,添加了cluster个数和sample个数的输出,修复了按esc键不能退出的bug。

     

    View Code
    // example in book leanring OpenCV, machine learning, k-means algorithn
    
    // good site for OpenCV examples, http://nashruddin.com/OpenCV_Examples_Part_2
    
    #include "cxcore.h"
    #include "highgui.h"
    
    #include <cstdio>
    
    int main(int argc, char** argv)
    {
        #define MAX_CLUSTER 5
        CvScalar color_tab[MAX_CLUSTER];
        IplImage* img = cvCreateImage(cvSize(500,500),8,3);
        CvRNG rng = cvRNG(0xffffffff);
        
        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);
    
        for(;;)
        {
            int k, cluster_count = cvRandInt(&rng)%MAX_CLUSTER+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);
            
            /* generate random samples */
            /* gaussian distribution */
            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);
                cvRandArr(&rng,&point_chunk,CV_RAND_NORMAL,
                        cvScalar(center.x,center.y,0,0),
                        cvScalar(img->width/6,img->height/6,0,0));
            }
    
            /* shuffle samples */
            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("cluster_count: %d\nsample_count:%d\n\n",cluster_count,sample_count);    
    
            cvKMeans2(points,cluster_count,clusters,
                    cvTermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER,100,0.01));
            cvZero(img);
            for(i=0;i<sample_count;i++)
            {
                CvPoint2D32f pt = ((CvPoint2D32f*)points->data.fl)[i];
                int cluster_idx = clusters->data.i[i];
                cvCircle(img,cvPointFrom32f(pt),2,
                        color_tab[cluster_idx],CV_FILLED);
            }
            cvReleaseMat(&points);
            cvReleaseMat(&clusters);
        
            cvShowImage("clusters",img);
    
            int key = cvWaitKey(0);
            key = key&0x000000FF;
            //printf("the key pressed:%d\n",key);
            if(key==27)
                break;
        }
    
        return 0;
    }
    
     

    效果图如下,

    恩,先就这样。

  • 相关阅读:
    Python:文件操作技巧(File operation)
    使用多域名实现并行下载
    win7 + cygwin + nodejs很详细的安装步骤【推荐】
    gzip压缩
    C#中一些常用的方法使用
    C#中的@符号的使用
    Sql中partition by的使用
    C#中使用WCF一些常见问题及解决方案
    C# MVC中直接执行Js
    MVC路由规则进一步了解
  • 原文地址:https://www.cnblogs.com/Frandy/p/machine_learning_kmeans.html
Copyright © 2020-2023  润新知