机器学习作业k均值算法终于让我再开始学python
第一篇文章,主要给自己做笔记用,python入门水平的小白
k均值算法原理
一种原型聚类,属于无监督学习,将没有标记的样本划分成不同的簇。针对划分最小化平方误差E,E越小,代表簇内样本围绕均值向量越紧密。
利用了贪心策略,若某次迭代后划分结果保持不变就认为得到了最优解。
一、用到的一些模块(都没用过呢555,太小白了)
- matplotlib.pyplot是一个有命令风格的函数集合,它看起来和MATLAB的绘图很相似。plt.scatter()用于绘制散点图。
- NumPy(Numerical Python) 是 Python 语言的一个扩展程序库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。
NumPy 通常与 SciPy(Scientific Python)和 Matplotlib(绘图库)一起使用, 这种组合广泛用于替代 MatLab
- pandas 是基于NumPy 的一种工具,该工具是为解决数据分析任务而创建的。Pandas 纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的工具
pandas.read_excel()的作用:将Excel文件读取到pandas DataFrame中。直接使用pd.read_excel(r"文件路径"),默认读取第一个sheet的全部数据
二、mycode
import pandas as pd
import numpy as np
import random
import matplotlib.pyplot as plt
#首先从数据集中读入数据
midu = []
hantanglv = []
df = pd.read_excel('C:\\Users\\xinyue liu\\Desktop\\西瓜数据集4.0.xlsx')
for i in df.index.values:#i in range(0,30)
midu.append(df.values[i][0])
hantanglv.append(df.values[i][1])
m = len(midu)
'''
print(df.values[0])
print(df.values[0][0])
print(df.values[0][1])
'''
def distance(x1, y1, x2, y2):
#计算两个样本点的距离
return ((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))**0.5
def kMeans(x):#计算新的均值向量
m = 0
h = 0
for i in x:
m = m + i[0]
h = h + i[1]
return m/len(x), h/len(x)
#按照书上所讲,将聚类簇数定义为3
k = 3
#用flag表示均值向量有没有更新
flag = k
#选择k个样本作为均值向量,U为均值向量列表
u = random.sample(range(0, m), k)
U = []
for i in u:
U.append((midu[i], hantanglv[i]))
#开始迭代
while flag==k:
C = []#C为样本簇列表,应包含k个样本簇
flag=0
for i in range(k):
C.append([])
for i in range(m):
everyDistance = [distance(midu[i], hantanglv[i], j[0], j[1]) for j in U]
#计算样本xi与各均值向量的距离
C[everyDistance.index(min(everyDistance))].append((midu[i], hantanglv[i]))
#根据距离最近的均值向量确定xi的簇标记,并将样本划入相应的簇
for i in range(k):
mk, hk = kMeans(C[i])#计算新的均值向量
if U[i][0] != mk or U[i][1] != hk:
U[i] = (mk, hk)#如果新均值向量不同于之前就替代,并且flag加一
flag = flag + 1
#将聚类结果可视化出来
color = ['r', 'g', 'b', 'm']
for i in range(k):
mm = [a[0] for a in C[i]]
hh = [a[1] for a in C[i]]
plt.scatter(mm, hh, color=color[i%len(color)])
plt.scatter(U[i][0], U[i][1], marker='x')
plt.show()
#原文链接:https://blog.csdn.net/wave2587/article/details/100655607
列一下读代码过程中学到的知识点 :
#everyDistance.index(min(everyDistance)):list的index()方法返回列表中某个元素的序号
#everyDistance = [distance(midu[i], hantanglv[i], j[0], j[1]) for j in U]这算是构造列表的一个方法了吧