【手撕机器学习系列】kmeans算法

  • Post author:
  • Post category:其他


重温《机器学习实战》,对其中的经典算法重新学习,发现又是另一种感受;才发现自己以前并没有真正理解,在数据结构算法的理解基础上,再来看机器学习算法,发现有一种异曲同工之妙,这才有了《手撕机器学习系列》的想法,让我们一起走进算法,在理解中认识算法,而不是简单的调包。

【手撕机器学习系列】kmeans算法

原理:(资源太多,这里不再赘述)

手撕代码:

import math
import random

'''
Author:kevinelstri
Date:2021/04/22
Desc:手撕机器学习系列
'''

# 读取数据
def load_data(filename):
    dataSet = []
    for line in open(filename).readlines():
        dataLines = [float(i) for i in line.strip().split('\t')]
        dataSet.append(dataLines)
    return dataSet

# 计算距离(欧式距离)
def dist(vec1,vec2):
    return math.sqrt(pow(vec1[0]-vec2[0],2)+pow(vec1[1]-vec2[1],2))

# 计算平均值例子
def mean():
    L = [[1.658985, 4.285136], [-3.453687, 3.424321], [4.838138, -1.151539]]
    sum_list = [sum(i) for i in zip(*L)]
    avg_list = [sum(i)/len(L) for i in zip(*L)]
    return sum_list,avg_list

# 随机获取k个聚类中心
def randomCenter(dataSet,k):
    dataLength = len(dataSet)
    if k > dataLength:
        return
    randomCenter = []
    for i in range(k):
        randomNum = random.randomInt(1,dataLength-1) # 获取随机数
        randomCenter.append(dataSet[randomNum])
    return randomCenter

# 聚类算法
def kmeans(dataSet,k,randomCenter):
    clusterCenterBegin = randomCenter
    clusterCenterEnd = []
    dataLength = len(dataSet)
    cluster = [[] for i in range(k)]
    for i in range(dataLength):
		distList = []
        for j in range(k):
            distList.append(dist(dataSet[i],dataSet[j]))
        cluster[distList.index(min(distList))].append(dataSet[i])  # 计算最小距离,进行分类,每个类别就是一个list
        
    # 计算类别平均值
    for i in range(k):
        tmp = cluster[i]
        avg = [sum(i)/len(tmp) for i in zip(*tmp)]  # 计算平均值
        randomCenterEnd[i] = avg
    
    # 递归算法
    if clusterCenterBegin != clusterCenterEnd:
        kmeans(dataSet,k,clusterCenterEnd)
    return cluster,clusterCenterEnd

# 主函数调用
if __name__ == '__main__':
    # 读取数据
    filename = 'testSet.txt'
    dataSet = load_data(filename)
    print('数据据:',dataSet)
    
    # 随机获取k个聚类中心
    k = 3
    randonCenter = randomCenter(dataSet,k)
    print(f'随机{k}个聚类中心{randomCenter}')
    
    # 聚类算法
    cluster,clusterCenter = kmeans(dataSet,k,randomCenter)
    
    # 打印聚类结果
    for i in range(k):
        print(f'第{i+1}个聚类结果',cluster[i])
        print(f'第{i+1}个聚类中心'clusterCenter[i])

代码解析:

本次代码使用 “递归” 的方式来实现 kmeans 算法,对于无监督算法而言,最终的目标就是求解最优化结果,使用递归算法可以不断进行迭代,来获取最终结果。

代码链接:

https://github.com/kevinelstri/Hander-Marchine-Learning-Series/tree/main/K-means

《百面机器学习》

链接:https://pan.baidu.com/s/13DrUAaNc40-5AUlXrNCjyQ

提取码:pbh6



版权声明:本文为kevinelstri原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。