博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
聚类算法(kmeans)详解和python实现
阅读量:7118 次
发布时间:2019-06-28

本文共 5238 字,大约阅读时间需要 17 分钟。

聚类算法简介

kmeans算法是无监督学习算法,它的主要功能就是把相似的类别规到一类中,虽然它和knn算法都是以k开头,但是knn却是一种监督学习算法.

那我们怎样去区分样本间的相似性呢?其实计算相似性的方式有很多,其中最常用的是欧示距离。

聚类算法的实现原理

假设我们有N个样本点,这N个样本点有k个分类,首先我们随机选取k个样本点作为质心,

  1. 我们遍历N个样本点x_i,计算x_i与每个质心的距离,找x_i与哪一个质心的距离最小,那么x_i就是质心距离最小的那一个类别,最后我们就可以把所有的样本点都分成不同的类别。
  2. 当我们通过(1)分好所有类之后,我们重新选择质心。再重复(1)的过程,直到算法收敛。

由于kmeans算法比较简单,在这里不详细进行介绍,直接给出算法的实现过程和结果。

算法python实现

# coding=gbk'''Created on 2018年2月28日@author: sundarchen'''from numpy import *from mpmath.tests.test_elliptic import zeroimport matplotlib.pyplot as pltfrom _ast import If'''k-means分类模型@param dataSet: n*n维数组@param kValue:  分类类型'''def kmeans(dataSet, kValue):    '''构建n*(n + 1)维数组,用于存放离cluster的距离'''    currentClusters = randomSelectCluster(dataSet, kValue)        '''用于记录使用kmeans分后类的结果'''    kmeansResult = {}        totalRows = dataSet.shape[0]    while True:        '''重置分类后结果,后面会重新计算'''             kmeansResult.clear()                '''重新计算所有样本到cluster的距离'''        for currentRow in range(totalRows):            minCluster = -1            minDistance = 100000000            currentRowData = dataSet[currentRow:(currentRow + 1)]            '''计算当前的行与所有的cluster的距离,找出最小的距离'''            for clusterIndex in range(len(currentClusters)):                '''计算距离'''                innerDistance = calcuateDistance(currentRowData, currentClusters[clusterIndex])                '''记录最小距离'''                if minDistance > innerDistance:                    minCluster = clusterIndex                    minDistance = innerDistance            '''找出当前的行与哪个cluster的距离最小后,就把当前的行分配到相应的cluster下面进行分类'''            print("minCluster ====== " + str(minCluster))            if minCluster in kmeansResult:                resultArray = kmeansResult[minCluster]                resultArray.append(currentRowData)            else:                resultArray = []                resultArray.append(currentRowData)                kmeansResult[minCluster] = resultArray                            currentRow = 0        innerClusterArray = mat(zeros((kValue, 2)))        '''重新计算所有集合的cluster点'''        for key in kmeansResult:            resultArray = kmeansResult[key]            '''重新计算中点,即集合中所有的点与点之间的距离'''            minClusterValue = 0            minClusterIndex = -1            for outerIndex in range(len(resultArray)):                innterMinClusterValue = 0                for innerIndex in range(len(resultArray)):                    innterMinClusterValue += calcuateDistance(resultArray[outerIndex], resultArray[innerIndex])                if innterMinClusterValue < minClusterValue or minClusterValue == 0:                    minClusterIndex = outerIndex                    minClusterValue = innterMinClusterValue;            '''存放cluster点'''            innerClusterArray[currentRow, :] = resultArray[minClusterIndex]            currentRow += 1        '''算法收敛'''        if (currentClusters == innerClusterArray).all():            break        '''重新找到的cluster点'''        currentClusters = innerClusterArray    return currentClusters, kmeansResult'''随机选择k个中心点'''def randomSelectCluster(dataSet, kValue):    indexCache = []    indexValue = 0    centerSamples = mat(zeros((kValue, dataSet.shape[1])))    totalRows = dataSet.shape[0]    while indexValue < kValue:        index = random.randint(0, totalRows)        if index in indexCache:            continue        indexCache.append(index)        rowData = dataSet[index, :]         centerSamples[indexValue,:] = rowData        indexValue += 1    return centerSamples'''计算样本和中心点的距离'''def calcuateDistance(rowData, clusterData):    return math.sqrt((rowData - clusterData) * (rowData - clusterData).T)'''显示Kmeans结果集'''def showKmeans(currentClusters, kmeansResult):    x = []    y = []    marker = ["a", "b", "c", "d", "e"]    '''中心点'''    for kmeanRow in currentClusters:        x.append(kmeanRow[0, 0])        y.append(kmeanRow[0, 1])    plt.scatter(x,y, color='r', label=marker[0])        '''分类点'''    typeColor = ["m", "c", "b", "k"]    for kmeanRow in kmeansResult:        x1 = []        y1 = []        kmeansResultRow = kmeansResult[kmeanRow]        for innerRow in kmeansResultRow:            isFinded = False            '''判断当前的点必须为非中心点'''            for kmeanRow2 in currentClusters:                if kmeanRow2[0, 0] == innerRow[0, 0] and kmeanRow2[0, 1] == innerRow[0, 1]:                    isFinded = True            '''上面己经画出了中心点,这里只要画非中心点就可以'''            if not isFinded:                x1.append(innerRow[0, 0])                y1.append(innerRow[0, 1])        plt.scatter(x1, y1, color=typeColor[kmeanRow], label=marker[kmeanRow + 1])    plt.show()复制代码

以下给出测试代码

# coding=gbkimport randomimport kmeans2from numpy import *def createDataSet():    result = []    totalRows = 100    xAdder = 15    yAdder = 10    centerPoints = [[5, 10], [20, 10], [5, 0], [15, 0]]    for row in range(totalRows):        randomIndex = random.randint(0, len(centerPoints))        randomPoints = centerPoints[randomIndex]        randomX = random.randint(0, xAdder - 3)        randomY = random.randint(0, yAdder - 3)        result.append([randomPoints[0] + randomX, randomPoints[1] + randomY])    return resultdataSet = mat(createDataSet())currentClusters, kmeansResult = kmeans2.kmeans(dataSet, 4)'''显示kmeans数据'''kmeans2.showKmeans(currentClusters, kmeansResult)复制代码

运行结果

转载地址:http://fzbel.baihongyu.com/

你可能感兴趣的文章
标准W3C盒子模型和IE盒子模型CSS布局经典盒子模型
查看>>
开源USM-AlienVault OSSIM
查看>>
Linux系统单用户模式
查看>>
android 中MVC与MVP,MVVM模式使用介绍
查看>>
lol skl
查看>>
postgreSQL 9.1 的安装、基本配置、简单使用
查看>>
JavaScript日期时间对象的创建与使用(三)
查看>>
PHP编程效率的20个要点
查看>>
mysql主从数据不一致问题解决
查看>>
go 入门学习笔记之 条件判断 if switch (七)
查看>>
Linux下清空用户登录记录和命令历史的方法
查看>>
Visual Sudio 复制窗体文件
查看>>
实例变量并不安全(java)
查看>>
修改系统文件(cookie、桌面、我的文档)位置
查看>>
我的友情链接
查看>>
我的友情链接
查看>>
debian6 Redis+phpredis安装
查看>>
Google Auth+openssh
查看>>
NFS服务器配置及客户端挂载
查看>>
ELK(elasticsearch+logstash+kibana)开源日志分析平台搭建
查看>>