# K-Means

## 先来看看相似度/距离的计算方法

dist(X,Y)=(i=1nxiyip)1p d i s t ( X , Y ) = ( ∑ i = 1 n | x i − y i | p ) 1 p

J(a,b)=ABAB J ( a , b ) = A ∩ B A ∪ B

cos(θ)=aTb|a||b| cos ⁡ ( θ ) = a T b | a | | b |

Pearson相似系数

ρXY=cov(X,Y))σxσY=E[(XμX)(YμY)]σxσY=ni=1(XμX)(XμY)ni=1(XμX)2ni=1(XμX)2 ρ X Y = c o v ( X , Y ) ) σ x σ Y = E [ ( X − μ X ) ( Y − μ Y ) ] σ x σ Y = ∑ i = 1 n ( X − μ X ) ( X − μ Y ) ∑ i = 1 n ( X − μ X ) 2 ∑ i = 1 n ( X − μ X ) 2

D(p||q)=xp(x)logp(x)q(x)=Ep(x)logp(x)q(x) D ( p | | q ) = ∑ x p ( x ) l o g p ( x ) q ( x ) = E p ( x ) l o g p ( x ) q ( x )

## K-Means算法详解

K-Means算法，即k-均值算法，是一种广泛使用的聚类算法。

创建k个点作为起始质心（经常是随机选择）

对数据集中的每个数据点
对每个质心
计算质心与数据点之间的距离
将数据点分配到距离最近的簇
对每一个簇，计算簇中所有点的均值作为质心

python代码实现

from numpy import *
import random
from matplotlib import pyplot as plt

data = []
with open(fileName) as fr:
lines = line.strip().split('\t')
L = list(map(float, lines)) #注意与书中的不同
data.append(L)

return mat(data)

# 欧式距离计算
def distEclud(vecA,vecB):
return sqrt(sum(square(vecA-vecB)))

# 构建随机质心
def randCent(data,k):
m,n = shape(data)
centroids = mat(zeros((k,n)))
for i in range(k):
for j in range(n):
minJ = min(data[:, j])  # 找出每列中最小的值
rangeJ = float(max(data[:, j]) - minJ)  # 找出每一列的范围值
centroids[(i,j)] = mat(minJ + rangeJ * random.random())
return centroids

def k_Means(data,k):
m,n = shape(data) # 每一行为一个simple，共有n个样本
# 初始化一个矩阵来存储每个点的簇分配结果 #
# 一列记录簇索引值,第二列存储误差(误差是指当前点到簇质心的距离,后面会使用该误差来评价聚类的效果)
clusterAssemt = mat(zeros((m,2)))
centroids = randCent(data,k)
clusterChanged = True
while clusterChanged:
clusterChanged = False
for i in range(m):
minDist = inf
minIndex = 0

for j in range(k):
distJI = distEclud(centroids[j,:],data[i,:]) #采用欧式距离
if distJI < minDist:
minDist = distJI
minIndex = j
# 找到每个样本最近距离的质点

if clusterAssemt[i,0] != minIndex:
clusterChanged = True

clusterAssemt[i,:] = minIndex, minDist **2
for cent in range(k):
ptsInClust = data[nonzero(clusterAssemt[:,0].A == cent)[0]]
centroids[cent,:] = mean(ptsInClust,axis=0)
return centroids,clusterAssemt

if __name__ == '__main__':
fig = plt.figure()
p1 = plt.scatter(data[:, 0].flatten().A[0], data[:, 1].flatten().A[0], marker='o')

myCentroids, clustAssing = k_Means(data,3)

print(myCentroids)
print(clustAssing)
p2 = plt.scatter(myCentroids[:,0].flatten().A[0],myCentroids[:,1].flatten().A[0], marker='x', edgecolors='r')
plt.show()

## K-Means算法实现总结：

1、python版本的差异

2、计算欧式距离时，无法使用pow(x,2)函数，报错为数据维数不符合。而改用直接用是sqart（）

3、random.rand(k,1)这个也是无法使用。报错为：
random中无rand模块。我dir了一下，python3中确实没有。不知道是不是2和3的差异。要想在3中使用，只能用numpy模块中的rand模块了。

4、使用数据预测时，出现了数据类型不符合的情况~

5、使用matplotlib画图时，总算明白了flatten()的奥妙之处~散点画图能力加强了~

• 点赞
• 评论
• 分享
x

海报分享

扫一扫，分享海报

• 收藏
• 手机看

分享到微信朋友圈

x

扫一扫，手机阅读

• 打赏

打赏

huixinbuding

你的鼓励将是我创作的最大动力

C币 余额
2C币 4C币 6C币 10C币 20C币 50C币
• 一键三连

点赞Mark关注该博主, 随时了解TA的最新博文
05-29 1861
08-24 5902

04-23 3万+
08-31 5749
12-18
07-02 2万+
03-18 5731
05-31 1210