一.什么叫K-Means
K- Means是迭代动态聚类算法中的一种,其中K表示类别数,Means表示均值。K-Means是一种通过均值对数据点进行聚类的算法。K-Means算法通过预先设定的K值,根据每个类别的初始中心位置对点集进行划分,并通过划分后的均值更新中心位置,不断迭代优化得到聚类结果.
二.KNN的过程介绍
具体实现过程如下:
1.首先选取k个中心点,作为聚类的类别数,例如对如下点集,选取三个中心点
选取中心点
2.遍历所有点,将每个点划分到距离其最近的中心点上
划分点集
3.计算每个类别的中心(平均)坐标,并将其作为新的中心点
更新中心点
4.重复2.3过程,直到中心点收敛(或变化很小)的时候结束迭代
三.K值的选取
经验方法
经验选取
经验选取
肘方法(elbow method)
给定k>0,使用像K-均值这样的算法对数据集聚类,并计算簇内方差和var(k)。然后,绘制var关于k的曲线。曲线的第一个(或最显著的)拐点暗示“正确的”簇数。
交叉验证法
将数据分为m部分;用m-1部分获得聚类模型,余下部分评估聚类质量(测试样本与类中心的距离和);对k>0重复m次,比较总体质量,选择能获得最好聚类质量的k
四.K-Means算法的优缺点
优点;
原理简单,容易实现
缺点:
无法确定K的个数 (根据什么指标确定K)
对异常值敏感 (容易导致中心点偏移)
结果不稳定 (受输入顺序影响)
五.KNN和K-Means区别
KNN
分类算法,监督学习,数据集里有分类的标签,且已经是输入的正确标签
K-Means
无监督学习的聚类算法,数据集是无分类的标签的点集,杂乱的,经过迭代聚类才有序起来
六.K-Means算法的python实现
#-----------------------------------------------调用库-------------------------------------------#
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import math
#-----------------------------------------------导入数据----------------------------------------#
df = pd.read_csv("Kmeans实例.csv", index_col=None)
df.head(9) # 查看数据集的前9行
#----------------------------------------------查看点集-----------------------------------------#
#----随机设定中心点的位置和数量----#
k_means_dot=3#K值取3
k_means_x=[3,0,12]
k_means_y=[4,5,9]
def runplt():
plt.figure()
plt.title("")
plt.xlabel('x_position')
plt.ylabel('y_position')
plt.grid(True)
plt.xlim(0,15)
plt.ylim(0,10)
return plt
x = df.loc[:,'x'].values
y = df.loc[:,'y'].values
print(x)
print(y)
plt = runplt()
plt.plot(x, y, 'k.')
plt.scatter(k_means_x,k_means_y,color='r')
plt.show()
#--------------------------------------------数据设定--------------------------------------------#
train_epochs=20#最大训练轮次1000
#--------------------------------------------算法迭代--------------------------------------------#
for i in range(train_epochs):
label=[]
sum_1=0
sum_2=0
sum_3=0
sum_1_x=0
sum_1_y=0
sum_2_x=0
sum_2_y=0
sum_3_x=0
sum_3_y=0
#--------------------------------------------------------划分点集----------------------------#
for j in range(len(x)):
distance=[]
for k in range(k_means_dot):
derta_x=abs(k_means_x[k]-x[j])
derta_y=abs(k_means_y[k]-y[j])
distance.append(pow(pow(derta_x,2)+pow(derta_y,2),0.5))
label.append(np.argsort(distance)[0]+1)
#------------------------------------------------------中心点更新----------------------------#
for l in range(len(x)):
if label[l] == 1:
sum_1_x+=x[l]
sum_1_y+=y[l]
sum_1+=1
if label[l] == 2:
sum_2_x+=x[l]
sum_2_y+=y[l]
sum_2+=1
if label[l] == 3:
sum_3_x+=x[l]
sum_3_y+=y[l]
sum_3+=1
k_means_x[0]=sum_1_x/sum_1
k_means_y[0]=sum_1_y/sum_1
k_means_x[1]=sum_2_x/sum_2
k_means_y[1]=sum_2_y/sum_2
k_means_x[2]=sum_3_x/sum_3
k_means_y[2]=sum_3_y/sum_3
#--------------------------------------------聚类结果-----------------------------------------#
plt = runplt()
plt.plot(x, y, 'k.')
plt.scatter(k_means_x,k_means_y,color='r')
plt.show()
附实例分析时的数据集:
数据集