数据挖掘实战之K-Means算法python实现
数据挖掘实战之K-Means算法python实现
概念:
在“无监督”学习当中,训练样本的标记信息是未知的,目标是通过对无标记训练样本的学习来揭示数据的内在性质及规律,为进一步的数据分析提供基础。此类学习任务中研究最多、应用最广的是“聚类”,而我们此次所实现的K-Means算法则是其中代表性之一。
tips K-Means算法可以看作高斯混合聚类在混合成分方差相等、且每个样本仅指派给一个混合成分时的特例,聚类簇数k通常需要用户提供,有一些启发式用于自动确定k,但常用的仍是基于不同k值多次运行后选取最佳结果。
import numpy as np
import matplotlib.pyplot as plt
# 定义方法用来计算两点距离
def distance(e1, e2):
return np.sqrt((e1[0]-e2[0])**2+(e1[1]-e2[1])**2)
# 定义方法用来标记类别中心
def means(arr):
return np.array([np.mean([e[0] for e in arr]), np.mean([e[1] for e in arr])])
# arr中距离a最远的元素,用于初始化聚类中心
def farthest(k_arr, arr):
f = [0, 0]
max_d = 0
for e in arr:
d = 0
for i in range(k_arr.__len__()):
d = d + np.sqrt(distance(k_arr[i], e))
if d > max_d:
max_d = d
f = e
return f
# arr中距离a最近的元素,用于聚类
def closest(a, arr):
c = arr[1]
min_d = distance(a, arr[1])
arr = arr[1:]
for e in arr:
d = distance(a, e)
if d < min_d:
min_d = d
c = e
return c
if __name__ == "__main__":
# 定义一个变量用来存储读取进来的数据
arr = []
# 读入数据
# 此处路径设置为自身数据所保存的路径
with open("C:/iris.txt") as fp:
for line in fp.readlines():
# 这里可以读取每一行
list = line.split(",")
# 获取x
first = float(list[0])
# 获取y
second = float(list[1])
arr.append([first,second])
# print(type(arr))
# print(arr)
## 初始化聚类中心和聚类容器
# 本次实验数据集当中类别有三个,则定义变量为3
m = 3
r = np.random.randint(arr.__len__() - 1)
k_arr = np.array([arr[r]])
cla_arr = [[]]
for i in range(m-1):
k = farthest(k_arr, arr)
k_arr = np.concatenate([k_arr, np.array([k])])
cla_arr.append([])
## 迭代聚类
n = 20
cla_temp = cla_arr
for i in range(n): # 迭代n次
for e in arr: # 把集合里每一个元素聚到最近的类
ki = 0 # 假定距离第一个中心最近
min_d = distance(e, k_arr[ki])
for j in range(1, k_arr.__len__()):
if distance(e, k_arr[j]) < min_d: # 找到更近的聚类中心
min_d = distance(e, k_arr[j])
ki = j
cla_temp[ki].append(e)
# 迭代更新聚类中心
for k in range(k_arr.__len__()):
if n - 1 == i:
break
k_arr[k] = means(cla_temp[k])
cla_temp[k] = []
## 对所得结果进行可视化展示
col = [HotPink, Aqua, Chartreuse]
col2 = [blue,green,black]
for i in range(m):
# 数据点
plt.scatter([e[0] for e in cla_temp[i]], [e[1] for e in cla_temp[i]], color=col[i])
# 各类别中心
plt.scatter(k_arr[i][0], k_arr[i][1], linewidth=5, color=col2[i])
plt.show()
上图即为最终分类结果。
注意事项:
为避免运行时间过长,通常设置一个最大运行轮数或者最小调整幅度阈值,若达到最大轮数或调整幅度小于阈值,则停止运行。
下一章节我们将采用高斯混合聚类(Mixture-of-Gaussian)方法,对iris数据集进行分类。
上一篇:
通过多线程提高代码的执行效率例子
下一篇:
Java 微信支付APP V3示例思路
