• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

编写KMeanspython

武飞扬头像
D.ziyu
帮助1

KMeans

一种聚类算法,是无监督学习,即没有类标签。
所用数据集就是几个点,点的分布和算的过程 见文末参考博客。

思想:

1. 数据
2. 随机选k个中心点
循环
3. 遍历所有点,算该点 和k点的距离,属于最小的 一类
4. 重新选中心点。新中心点 为该类所有点平均值
5. 结束条件:新中心和 旧中心差值 《 阈值(自己设置)

代码:

import random
def createDataSet():
    dataSet = [[1,4],
            [1,5],
            [2,4],
            [2,5],
            [2,6],
            [4,1],
            [4,2],
            [5,1],
            [5,2],
            [6,2]]
    return dataSet

# 两点间欧氏距离, 参数形式如:pointA = [x, y]
def getDistance(pointA, pointB):
    res = 0
    for i in range(len(pointA)):
        res  = (pointA[i] - pointB[i]) ** 2
    print(f'{pointA}和{pointB}两点距离', res ** 0.5)
    return res ** 0.5

# 第一次随机选k个点为 k类中心点
def randomChoice(dataSet, K):
    centerPoint = []# 中心点 
    lastRanIndex = -1
    rList = []
    for i in range(K): # 选k个随机数
        randomIndex = random.randint(0, len(dataSet)-1)
        print('randomIndex =',randomIndex)
        if(randomIndex == lastRanIndex): # 两次随机数取值相同
            i -= 1
            continue
        lastRanIndex = randomIndex
        rList.append(randomIndex)
    rList = sorted(rList) # 下标递增 好一点
    #print(rList)
    for r in rList:
        centerPoint.append(dataSet[r])
    return centerPoint

def KMeans(dataSet):
    typeList = []
    [typeList.append(0) for i in range(len(dataSet))]
    # 默认K为2,两类
    K = 2
    centerPoint = randomChoice(dataSet, K) # 随机选K个中心点
    print('初次随机中心点 =', centerPoint)
    
    flag = 1
    while(flag == 1):
        # 遍历所有点,算该点 和k点的距离,属于最小的 一类
        for i in range(len(dataSet)):# 
            distList = []
            for k in range(K):
                dist = getDistance(dataSet[i], centerPoint[k]) # 第i点和第k中心点距离
                #print('两点距离 =', dist)
                distList.append(dist)
            print(distList)
            for j in range(K):
                if distList[j] == min(distList): # 找到最小的吗,就是类别
                    typeList[i] = j   1 # j 1为类型
            print(typeList)
            
        # 计算新中心点
        newCenterPoint = renewCenterPoint(typeList, dataSet, K)
        print('新中心点 =', newCenterPoint)
        cntK = 0                # 统计k个中心点合格的个数
        for k in range(K):
            distChange = getDistance(centerPoint[k], newCenterPoint[k]) # 新旧中心点欧式距离
            print(f'第{k}个中心移动了 =', distChange)
            if distChange < 1:  # 中心点改变很小,不用再改变的中心点  1
                cntK  = 1
            if cntK == K:       #k个中心点全部合格才能结束
                flag = 0
                break
        centerPoint = newCenterPoint # 别忘了,更新中心点 
    return typeList

# 重新计算中心点
def renewCenterPoint(typeList, dataSet, K):
    centerPoint = []
    for k in range(K):
        X = Y = cnt = 0
        for j in range(len(typeList)):
            if typeList[j] == k   1:
                X  = dataSet[j][0]
                Y  = dataSet[j][1]
                cnt  = 1
        print(f'X和值{X}, Y和值{Y}, 该类有{cnt}个')
        centerPoint.append([X/cnt, Y/cnt])
    #print(centerPoint)
    return centerPoint
    
if __name__ == '__main__':
    dataSet = createDataSet()
    print(dataSet)
    typeList = KMeans(dataSet)# 最后结果
    print(typeList)
学新通

结果

[[1, 4], [1, 5], [2, 4], [2, 5], [2, 6], [4, 1], [4, 2], [5, 1], [5, 2], [6, 2]]
randomIndex = 0
randomIndex = 7
初次随机中心点 = [[1, 4], [5, 1]]
[1, 4]和[1, 4]两点距离 0.0
[1, 4]和[5, 1]两点距离 5.0
[0.0, 5.0]
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
......
新中心点 = [[1.6, 4.8], [4.8, 1.6]]
[1, 4]和[1.6, 4.8]两点距离 0.9999999999999999
第0个中心移动了 = 0.9999999999999999
[5, 1]和[4.8, 1.6]两点距离 0.632455532033676
第1个中心移动了 = 0.632455532033676
[1, 1, 1, 1, 1, 2, 2, 2, 2, 2]

参考文章

后序可能用plt画kmeans,更直观一点

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgcfckb
系列文章
更多 icon
同类精品
更多 icon
继续加载