机器学习--物以类聚(k-means算法)

k-means算法是无监督学习算法,没有标签值,通过自身分析自身的数据,自己进行分类。

此次实现参考了其他博客的实现。

k-means中k的意思表示的是分类数目。

数据集下载地址:链接:http://pan.baidu.com/s/1cfhvAY 密码:7nk8

思想:

1.将数据集中的每条数据视为空间中的一个点

2.随机选取k条作为基准的数据

3.遍历数据集,分别计算每条数据转化为数据点后到每条k中记录的距离,选取距离最短的k作为该条数据的类别

4.遍历完所有数据集后,对所有属于对应的k中的类别的数据进行重新选择中心点操作,可以通过x=(x1+x2+x3+...+xn)/n来计算中心点

5.重复对数据集进行遍历操作,重复步骤3和步骤4,直到中心点不再发生变化为止,此时停止操作。

6.最后数据集所属的类别和各个中心点即为最终分类的结果


算法实现步骤:

1.设计一个方法:导入数据,对数据进行切割,转化为矩阵

2.设计一个方法:计算两个点的距离

3.设计一个方法:随机生成k条作为基准的数据集

4.设计一个方法:遍历所有数据集,对所有数据进行判别类型操作

5.设计一个方法:对最后的中心点、数据集所属的类型、数据集进行数据图展示


python实现:

# coding = utf-8
import numpy
import matplotlib.pyplot as plt

#导入文件,转化为矩阵返回
def getdatamat(file):
    file = open(file)
    lines = file.readlines()
    arr = []
    for line in lines:
        temp = line.split("\t")
        arr.append([float(temp[0]), float(temp[1])])
    dataset = numpy.mat(arr)
    return dataset

#计算两个数据点之间的距离,返回距离
def getdis(pointA, pointB):
    return numpy.sqrt(numpy.sum(numpy.power(pointA - pointB, 2)))

#获取k条随机的基准数据并返回
def getinitpoints(dataset, k):
    length, width = dataset.shape
    points = numpy.zeros((k, width))
    for i in range(k):
        index = int(numpy.random.uniform(0, length))
        points[i:, ] = dataset[index]
    return points

#对数据进行分类操作,直到中心点不再变化为止
def kmeans(dataset, k):
    time = 0
    initpoints = getinitpoints(dataset, k)
    print initpoints
    length, width = dataset.shape
    labels = numpy.mat(numpy.zeros((length, 2)))
    isChanged = True
    while isChanged:
        isChanged = False
        for i in xrange(length):
            pointA = dataset[i, :]
            distance = 1000
            index = -1
            for j in range(k):
                pointB = initpoints[j, :]
                resultDis = getdis(pointB, pointA)
                if distance > resultDis:
                    distance = resultDis
                    index = j
            if labels[i, 0] != index:
                isChanged = True
            labels[i, 0] = index
        for i in range(k):
            temp = dataset[numpy.nonzero(labels[:, 0].A==i)[0]]
            initpoints[i, :] = numpy.mean(temp, axis=0)
        time += 1
        print time
        if time>100:
            return initpoints, labels
    return initpoints, labels

#通过matplotlib展示最后的结果。
def show(dataSet, k, centroids, clusterAssment):
    numSamples, dim = dataSet.shape
    mark = ['or', 'ob', 'og', 'ok', '^r', '+r', 'sr', 'dr', '<r', 'pr']
    for i in xrange(numSamples):
        markIndex = int(clusterAssment[i, 0])
        plt.plot(dataSet[i, 0], dataSet[i, 1], mark[markIndex])
    mark = ['Dr', 'Db', 'Dg', 'Dk', '^b', '+b', 'sb', 'db', '<b', 'pb']
    for i in range(k):
        plt.plot(centroids[i, 0], centroids[i, 1], mark[i], markersize = 12)
    plt.show()

if __name__ == '__main__':
    k = 4
    dataset = getdatamat("test.txt")
    initpoints, labels = kmeans(dataset, k)
    show(dataset, k, initpoints, labels)

k为4的时的结果图:

机器学习--物以类聚(k-means算法)

机器学习--物以类聚(k-means算法)

机器学习--物以类聚(k-means算法)

k为3的时的结果图:

机器学习--物以类聚(k-means算法)

机器学习--物以类聚(k-means算法)

机器学习--物以类聚(k-means算法)

k为2的时的结果图(与初始基准点选取有关):

机器学习--物以类聚(k-means算法)

机器学习--物以类聚(k-means算法)

机器学习--物以类聚(k-means算法)

机器学习--物以类聚(k-means算法)