Kmeans(0)

2017/03/01
这次是自己的第一次实践,就是算法是根据自己的理解来一步步书写,而不是使用现有的库(当然可以后来使用库对自己写的算法进行比较)
也算是一个简单的问题逐步解决吧。


1、最开始选的点是随机产生的
这个问题,其实会影响到最后的结果,不过我现在不好说结果


2、到底如何构建这个簇
我目前选定的中心点和其他的所有点都进行了计较,然后也算出了各个点之间的距离,但是我怎么来定义你这个距离就是比较小然后属于这个簇呢!?
不够,看《集体智慧》这本书的时候,感觉他这部分还是跟上一节的层次聚类一样。
解答:就是按照每次与中心点的距离,如果小于就进行修改。
而且,每次都把所有的点进行一次比较。
2017/03/02
这个计算的方法就是跟上面说的一样。只不过,你要绕过它!
层次聚类就像加一层一层的皮一样。
而这个方法是以点为中心。


3、最后的中间结果不对
就是因为纯粹看了别人的代码,缩进没有掌握好,导致计算出了错误的中心。


4、最后的结果
我不知道,就是我最后得到了一个点,得到了所谓的每个簇的中心。
我怎么判定测试的点就是这个簇的!看第5条。
:所以网上有说,这种算法比较适合那种圆形的方式。


5、结果判定
后来又看到一些文献。(kNN这种算法不知道到底属于那些范畴。)
既然,已经得到了一些点,我最后输入判定的点时,就判断他和哪个点更近,就判定他属于这个点。


6、结果展示
如果是可以在二维空间内展示的数据,我应该怎么画出这部分数据也是个问题。
所以这个算法,又回到了我最开始的疑惑,那就是如何可视化数据。

(我觉得,这种内容,可以靠多看别人的论文,多看别人的结果来增加经验。)


(这部分代码只作为最初版本,后期肯定还需要进一步改进)
(代码只随意定了几个点来做演示)
贴出代码如下:

#! /usr/local/bin/python
#coding:utf-8
#17/03/02
#Auther:VChao
'''
This py file is designed to show the k-means algorithm.
But honestly,the code is so simple.
There still a question remained.How to show the result!?
'''
import os
import matplotlib
matplotlib.use('Agg')

import matplotlib.pyplot as plt
import numpy as np
from sklearn import datasets

from math import sqrt
import random

def PlotMy(data):
    #Plot the Pic
    Filename = 'Myfig.png'
    plt.scatter(data[:,0],data[:,1],c=data[:,2],s=25,alpha=0.7)
    plt.savefig(Filename)
    os.system('sz '+Filename)
    os.system('rm -f '+Filename)

def RandPoint(data,k):
    #Get the k random point for the initial compution.
    PointMax = [max(data[:,0]),max(data[:,1])]
    PointMin = [min(data[:,0]),min(data[:,1])]

    Res = []
    for i in range(k):
        pointx = random.random()*(PointMax[0] - PointMin[0])+PointMin[0]
        pointy = random.random()*(PointMax[1] - PointMin[1])+PointMin[1]
        Res.append([pointx,pointy])
    return Res

def CalDis(point1,point2):
    #Calculate the distance of two points
    x1 = point1[0]
    y1 = point1[1]

    x2 = point2[0]
    y2 = point2[1]
    
    return sqrt(pow(x1-x2,2)+pow(y1-y2,2))

def kMeans(data):
    #To be honest, I don't know how to use the algorithm.
    #How to code!?
    k = 2

    datanum = len(data)
    cenLoc = RandPoint(data,k)
    lastMatches = None
    #Iteration times.
    for t in range(20):
        #Every iteration,there'll be a total new array to hold the match result.
        bestMatches = [[] for p in range(k)]
        print 'Iteration %d' %t
        #For every item in data,calculating the nearest point.
        for j in range(datanum):
            point = data[j]
            bestMatch = 0
            for i in range(k):
                d = CalDis(point,cenLoc[i])
                if d < CalDis(point,cenLoc[bestMatch]): bestMatch = i
            #Get it in to the matched Cluster.
            bestMatches[bestMatch].append(j)
        #下面这个句子,开始我感觉是有错误的,数组位置不同也是不相等.
        #但是如果你仔细想想,因为每次循环都是从零开始的,这就是关键点.
        if lastMatches == bestMatches: break
        lastMatches = bestMatches
        #Recalculate the centrol point.
        for i in range(k):
            avgs = [0.0]*len(data[0])
                        if len(bestMatches[i])>0:
                    for item in bestMatches[i]:
                        for m in range(len(data[item])):
                            avgs[m] += data[item][m]
                    for j in range(len(avgs)):
                        avgs[j]/=len(bestMatches[i])
                    cenLoc[i] = avgs
#   print cenLoc    
    return bestMatches  
if __name__ == "__main__":

    data = np.array(
        [[1.0,1.0],
        [2.0,1.0],
        [5.0,6.0],
        [6.0,6.0]]
        )
    target = np.array([
            [0],
            [0],
            [1],
            [1]]
            )
    #Make the array +v
    data = np.hstack((data,target))
    kMeans(data)        
    #PlotMy(data)

你可能感兴趣的:(Kmeans(0))