[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)多种,但同类的数据条的标签都是一样的
按照标签对数据分类整理,把数据放到包含对应各个标签的小列表的大列表中
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