1.归类
聚类(clustering)属于非监督学习(unsupervised learning)
无类别标记 (class label)
2.K-means算法
1)Clustering中的经典算法,数据挖掘十大经典算法之一;
2)算法接受参数K,然后将事先输入的n个数据对象划分为k个聚类以便使得所获得的聚类满足:
同一聚类中的对象相似度较高,而不同聚类中的对象相似度较小
3)算法思想:
以空间中k个点为中心进行聚类,对最近它们的对象归类,通过迭代的方法,逐次更新各聚类中心的值,直到得到最好的聚类结果;
4)算法描述:
(1)适当选择c个类的初始中心;
(2)在第k次迭代中,对任意一个样本,求其到c各中心的距离,将该样本归到距离最短的中心所在类;
(3)利用均值等方法更新该类的中心值;
(4)对于c个聚类中心,如果利用(2)(3)的迭代法更新后,值保持不变,则迭代结束,否则继续;
算法结束条件:(1)分类不在变化(2)上一次分类变化小于本次(3)给定迭代次数
5)算法流程
6)实例
7)优缺点
优点:速度快,简单
缺点:最终结果跟初始点选择有关,容易陷入局部最优,需直到k值
3.实践
1)代码
# -*- coding: utf-8 -*-
import numpy as np
#数据:
#X值--Y值--分类结果
# 1 1 -1
# 2 1 -1
# 4 3 -2
# 5 4 -2
def kmeans(X,k,maxIt):
#数据点的个数(行)和列(维度)
numPoints,numDim = X.shape
#多增加一列作为结果
dataSet = np.zeros((numPoints,numDim+1))
#去掉分类结果
dataSet[:,:-1] = X
#随机选取k行
centroids = dataSet[np.random.randint(numPoints,size=k),:]
#centroids = dataSet[0:2,:]
#对各行进行分类
centroids[:,-1] = range(1,k+1)
#循环次数
iteration = 0
#旧的中心点
oldCentroids = None
while not showIdShop(oldCentroids,centroids,iteration,maxIt):
print("iteration:",iteration)
print("dataSet:",dataSet)
print("centroids:",centroids)
#它们为两个变量,在下边需要更新
oldCentroids = np.copy(centroids)
iteration+=1
#根据数据集合中心点对每个点重新分类
updateLabels(dataSet,centroids)
#重新计算中心点
centroids = getCentroids(dataSet,k)
return dataSet
def showIdShop(oldCentroids,centroids,iteration,maxIt):
if(iteration>maxIt):
return True
#比较两次的中心点是否变化(比较二者的值)
return np.array_equal(oldCentroids,centroids)
def updateLabels(dataSet,centroids):
numPoints,numDim = dataSet.shape
for i in range(0,numPoints):
dataSet[i,-1] = getLabelFromClosestCentroid(dataSet[i,:-1],centroids)
def getLabelFromClosestCentroid(dataSetRow,centroids):
label = centroids[0,-1]
minDist = np.linalg.norm(dataSetRow-centroids[0,:-1])
for i in range(1,centroids.shape[0]):
#距离计算
dist = np.linalg.norm(dataSetRow-centroids[i,:-1])
if(dist<minDist):
minDist = dist
label = centroids[i,-1]
print("minDist",minDist)
return label
def getCentroids(dataSet,k):
result = np.zeros((k,dataSet.shape[1]))
for i in range(1,k+1):
oneCluster = dataSet[dataSet[:,-1]==i,:-1]
result[i-1,:-1] = np.mean(oneCluster,axis=0)
result[i-1,-1] = i
return result
x1 = np.array([1,1])
x2 = np.array([2,1])
x3 = np.array([4,3])
x4 = np.array([5,4])
#把数组纵向组成大矩阵
testX = np.vstack((x1,x2,x3,x4))
result = kmeans(testX,2,10)
print("result",result)
2)结果
iteration: 1
dataSet: [[ 1. 1. 1.]
[ 2. 1. 1.]
[ 4. 3. 2.]
[ 5. 4. 2.]]
centroids: [[ 1.5 1. 1. ]
[ 4.5 3.5 2. ]]
minDist 0.5
minDist 0.5
minDist 0.707106781187
minDist 0.707106781187
result [[ 1. 1. 1.]
[ 2. 1. 1.]
[ 4. 3. 2.]
[ 5. 4. 2.]]