欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

[Python数据挖掘] sklearn-KMeans聚类

程序员文章站 2022-07-14 11:49:47
...

[问题背景]

假定有这样的数据集,txt格式,ANSI编码:

YZN,133,108,76
ZHY,96,145,101
WYZ,132,107,60
DHY,100,102,120
CYH,139,99,93
LHY,73,149,81
ZHY,85,148,93
TQP,39,138,85
ZZL,145,112,71
HJC,101,116,118
XZY,99,98,117

每行第一列是学生姓名,第二列是语文成绩,第三列是数学成绩,第四列是英语成绩。

目标是利用KMeans对学生进行聚类,例如聚成3类。

[问题分析]

数据预处理:

def loadData(filePath):
    fr = open(filePath, 'r+')
    lines = fr.readlines()
    retName = []
    retData = []
    for line in lines:
        items = line.strip().split(',')
        retName.append(items[0])
        retData.append([float(items[i]) for i in range(1,len(items))])
    return retName, retData

 编写loadData()函数,作用是传入grade.txt,传出两个列表:

Name = ['YZN', 'ZHY', 'WYZ', 'DHY', 'CYH', 'LHY', 'ZHY', 'TQP', 'ZZL', 'HJC', 'XZY']
Data = [[133.0, 108.0, 76.0], [96.0, 145.0, 101.0], [132.0, 107.0, 60.0], [100.0, 102.0, 120.0], [139.0, 99.0, 93.0], [73.0, 149.0, 81.0], [85.0, 148.0, 93.0], [39.0, 138.0, 85.0], [145.0, 112.0, 71.0], [101.0, 116.0, 118.0], [99.0, 98.0, 117.0]]

这样就完成了数据预处理工作。这部分代码的编写思想请参考 [Python数据处理] 怎样用Python预处理txt文档提取数据

应用KMeans聚类器:

数据预处理grade.txt(需要和该py代码处于同一目录下)

if __name__ == '__main__':
    Name, Data = loadData('grade.txt')

设置聚类数目为3:

clusters_cnt = 3

用KMeans()方法设置生成一个3类聚类器km

km = KMeans(n_clusters=clusters_cnt)

将Data传入km分类器的fit_predict()接口,传出label标签

label是一个存放标签值的列表,顺序与Data相同

label = km.fit_predict(Data)

此时label的内容为

[1 2 1 0 1 2 2 2 1 0 0]

每次运行生成的标签值不尽相同,因为贴标签的方式可能是(0 1 2), (0 2 1), (1 0 2), (1 2 0), (2 0 1), (2 1 0)多种,但同类的数据条的标签都是一样的

[Python数据挖掘] sklearn-KMeans聚类
传入Data数据 经过fit_predict接口 传出label标签示意图

 

按照标签对数据分类整理,把数据放到包含对应各个标签的小列表的大列表中

    outputName = []
    for i in range(clusters_cnt):
        outputName.append([])
    for i in range(len(Name)):
        outputName[label[i]].append(Name[i])
    print(outputName)

最后输出聚类结果:

[['DHY', 'HJC', 'XZY'], ['YZN', 'WYZ', 'CYH', 'ZZL'], ['ZHY', 'LHY', 'ZHY', 'TQP']]

可以看出,KMeans聚类器将

英语较好的DHY, HJC, XZY聚在一起;

语文较好的YZN, WYZ, CYH, ZZL聚在一起;

数学较好的ZHY, LHY, ZHY, TQP聚在一起。

读者可看grade.txt内容验证以上聚类结果。

YZN,133,108,76
ZHY,96,145,101
WYZ,132,107,60
DHY,100,102,120
CYH,139,99,93
LHY,73,149,81
ZHY,85,148,93
TQP,39,138,85
ZZL,145,112,71
HJC,101,116,118
XZY,99,98,117

 最后附上完整代码:

import numpy as np
from sklearn.cluster import KMeans

def loadData(filePath):
    fr = open(filePath, 'r+')
    lines = fr.readlines()
    retName = []
    retData = []
    for line in lines:
        items = line.strip().split(',')
        retName.append(items[0])
        retData.append([float(items[i]) for i in range(1,len(items))])
    return retName, retData

if __name__ == '__main__':
    Name, Data = loadData('grade.txt')
    
    clusters_cnt = 3
    km = KMeans(n_clusters=clusters_cnt)
    label = km.fit_predict(Data)

    outputName = []
    for i in range(clusters_cnt):
        outputName.append([])
    for i in range(len(Name)):
        outputName[label[i]].append(Name[i])
    print(outputName)

[注]numpy和sklearn库可通过pip命令或其他管理工具安装;字符串形式的分数在预处理时需要强转成float