# 原理:
假设数据集合为(x1, x2, …, xn),并且每个样本xi为d维的向量,K-means聚类目标,在给定分类组数k(k ≤ n)值的条件下,将原始数据分成k类:
S = {S1, S2, …, Sk}
在数值模型上,即对以下表达式求最小值
#数学表达式:
数学表达式:
n:样本数。
k:样本分为k类。
rnk:第n个样本点是否属于第k类,属于则rnk=1, 不属于则rnk=0。
μK:第k个中心点。
# 算法的实现:
(1)随机选取K个对象作为初始聚类中心;
(2)将数据样本集合中的样本按照最小距离原则分配到最邻近聚类;
(3)根据聚类的结果,重新计算K个聚类的中心,并作为新的聚类中心;
(4)重复步骤2.3直到聚类中心不再变化。
# 代码的实现`
import pandas as pd
import numpy as np
import random
import matplotlib.pyplot as plt
class Kmeans_clustering:
def __init__(self,data,k):
self.data=data
self.k = k
def distance(self,A,B):
'''用欧式距离公式计算两个向量之间的距离'''
return np.sqrt(sum(np.power(A-B,2)))
def chioce_center(self):
'''从数据集中随机选取k 个点作为聚类的中心'''
centroids=random.sample(self.data,self.k)
return centroids
def k_means(self):
'''将样本点,样本点距离聚点的最近距离,样本点的类型存放在DataFrame中
然后进行迭代的过程,计算样本点到聚点的最近距离,判断属于哪一类
重新计算每个类的质心
直到所有的样本点的类型不发生变化
'''
df=pd.DataFrame(self.data)
m=df.shape[1]
df["min_distance"]=[0]*len(self.data)
df["k类"]=[0]*len(self.data)
centroids=self.chioce_center()
K_changed=True
while K_changed:
K_changed = False
list_k = []#存放样本点的类型
min_distance =[]#存放样本点到各个聚点的最小距离
for j in range(len(self.data)):
dis_list=[]#存放一个样本点到各个聚点的距离
for i in range(self.k):
distance=self.distance(np.array(self.data[j]),np.array(centroids[i]))
dis_list.append(distance)
min_distance.append(min(dis_list))
list_k.append(dis_list.index(min(dis_list)))
if list(df["k类"])!=list_k:
K_changed=True
df["min_distance"] = min_distance
df["k类"] = list_k
for i in range(self.k):#重新计算每个类的质心
df1=df.groupby(df.columns[-1]).get_group(i)
centroids[i]=[np.mean(df1.iloc[:,0]),np.mean(df1.iloc[:,1])]
return df,centroids
data=[]
with open("text.txt","r",encoding="utf-8") as f:
for line in f.readlines():
line1 = line.strip().split()
line2 = list(map(float,line1))
data.append(line2)
a=Kmeans_clustering(data,4)
df,centroids=a.k_means()
print(df)
print(centroids)
for i in range(4):#将每个类的点显示出来
df2=df.groupby(df.columns[-1]).get_group(i)
plt.scatter(x=list(df2.iloc[:,0]),y=list(df2.iloc[:,1]))
结果:
0 1 min_distance k类
0 1.658985 4.285136 2.758587 1
1 -3.453687 3.424321 0.993410 2
2 4.838138 -1.151539 3.634463 1
3 -5.379713 -3.362104 1.251393 0
4 0.972564 2.924086 2.015117 1
5 -3.567919 1.531611 1.654707 2
6 0.450614 -3.302219 0.330917 3
7 -3.487105 -1.724432 1.251393 0
8 2.668759 1.594842 0.140032 1
9 -3.156485 3.191137 0.618302 2
10 3.165506 -3.999838 2.530735 3
11 -2.786837 -3.099354 1.737939 0
12 4.208187 2.984927 2.108910 1
13 -2.123337 2.943366 0.498210 2
14 0.704199 -0.479481 2.840816 1
15 -0.392370 -3.963704 1.147769 3
16 2.831667 1.574018 0.295199 1
17 -0.790153 3.343144 1.884279 2
18 2.943496 -3.357075 2.275142 3
[[-3.884551666666667, -2.7286300000000003], [2.554642714285714, 1.6759984285714287], [-2.6183161999999998, 2.8867158], [1.5418115000000001, -3.655709]]