# 机器学习笔记之K-means聚类

K-means聚类是聚类分析中比较基础的算法，属于典型的非监督学习算法。

1.创建K个点作为初始质心（通常是随机选择）
2.当任意一个点的簇分类结果发生改变时
2.1对数据的每一个点，计算每一个质心与该数据点的距离，将数据点分配到距其最近的簇
2.2对于每一个簇，计算簇中所有点的均值并将均值作为质心

K均值聚类算法原理简单易懂，聚类效果较好，但是其缺陷也较为明显：

1、对离群值比较敏感；
2、聚类个数的选择会影响最终聚类效果；
3、初始化聚类中心的选择会影响聚类效果。

## !/user/bin/env RStudio 1.1.423
## -*- coding: utf-8 -*-
## K-means Model

library("dplyr")
library('magrittr')
library('ggplot2')

rm(list = ls())
gc()


Data_Input <- function(file_path = "D:/R/File/iris.csv",p = .75){
data = read.csv(file_path,stringsAsFactors = FALSE,check.names = FALSE)
names(data) <- c('sepal_length','sepal_width','petal_length','petal_width','class')
data[,-ncol(data)] <- scale(data[,-ncol(data)])
x = data[,1:(ncol(data)-2)];y =  data$class_c return( list( data = data, train_data = x, train_target = y ) ) }  欧式距离计算： DistEclud <- function(vecA, vecB){ diff = rbind(vecA,vecB) euclidean = dist(diff) %>% as.numeric() return (euclidean) }  随机质心选择： RandCentre <- function(dataSet, k){ n = ncol(dataSet) Centres = matrix(nrow = k,ncol = n) for(j in 1:n){ minJ = min(dataSet[,j]) rangeJ = max(dataSet[,j]) - minJ Centres[,j] = (minJ + rangeJ * runif(k)) } return (Centres) }  K-means聚类构建： Kmeans_Cluster <- function(dataSet,k){ m = nrow(dataSet) ClusterAssment = rep(0,times = 2*m) %>% matrix(nrow = m,ncol = 2) Centres = RandCentre(dataSet,k) ClusterChanged = TRUE while(ClusterChanged){ ClusterChanged = FALSE for(i in 1:m){ minDist = Inf minIndex = 0 for(j in 1:k){ distJI = DistEclud(Centres[j,],dataSet[i,]) if (distJI < minDist){ minDist = distJI minIndex = j } } if(ClusterAssment[i,1] != minIndex){ ClusterChanged = TRUE ClusterAssment[i,] = c(minIndex,minDist^2) } } for(cent in 1:k){ index = grep(cent,ClusterAssment[,1]) ptsInClust = dataSet[index,] Centres[cent,] = apply(ptsInClust,2,mean) } print(Centres) } return ( list( Centres = Centres, ClusterAssment = ClusterAssment ) ) }  聚类模型执行与结果输出： Show_Result <- function(k){ data_source = Data_Input() dataSet = data_source$train_data
y = data_source$train_target result = Kmeans_Cluster(dataSet,k) centroids = result$Centres
clusterAssment = result\$ClusterAssment
ggplot() +
geom_point(data = NULL,aes(x = dataSet[,1],y = dataSet[,2],fill = factor(clusterAssment[,1])),shape = 21,colour = 'white',size = 4) +
geom_point(data = NULL,aes(x= centroids[,1],y = centroids[,2]),fill = 'Red',size = 10,shape = 23) +
scale_fill_brewer(palette = 'Set1') +
guides(fill=guide_legend(title=NULL)) +
theme_void()
}


#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import numpy  as np
import pandas as pd
from sklearn import preprocessing
from sklearn.metrics import confusion_matrix
from matplotlib import pyplot as plt


def DataInput():
data.columns = ['sepal_length','sepal_width','petal_length','petal_width','class']
data.iloc[:,0:-1] = preprocessing.scale(data.iloc[:,0:-1])
data['class_c'] =  pd.factorize(data['class'])[0]
return  data.iloc[:,0:-2],data.iloc[:,-1]


def DistEclud(vecA, vecB)
return np.sqrt(np.sum(np.power(vecA - vecB, 2)))
#随机质心选择函数：

def RandCentre(dataSet, k):
n = dataSet.shape[1]
Centres = np.mat(np.zeros((k,n)))
for j in range(n):
minJ = np.min(dataSet.iloc[:,j])
rangeJ = np.float(np.max(dataSet.iloc[:,j]) - minJ)
Centres[:,j] = np.mat(minJ + rangeJ * np.random.rand(k,1))
return Centres


def kMeans(dataSet,k):
m = dataSet.shape[0]
ClusterAssment = np.mat(np.zeros((m,2)))
Centres = RandCentre(dataSet,k)
ClusterChanged = True
while ClusterChanged:
ClusterChanged = False
for i in range(m):
minDist = np.inf;minIndex = -1
for j in range(k):
distJI = DistEclud(Centres[j,:],dataSet.iloc[i,:].values)
if distJI < minDist:
minDist = distJI
minIndex = j
if ClusterAssment[i,0] != minIndex:
ClusterChanged = True
ClusterAssment[i,:] = minIndex,minDist**2
print(Centres)
for cent in range(k):
index = np.nonzero(ClusterAssment[:,0].A== cent)[0].tolist()
ptsInClust = dataSet.iloc[index,:]
Centres[cent,:] = np.mean(ptsInClust,axis=0).values
return Centres,ClusterAssment


def show(k):
dataSet,y = DataInput()
centroids, clusterAssment = kMeans(dataSet,k)
m,n = dataSet.shape
mark  = ['or', 'ob', 'og']
for i in range(m):
markIndex = np.int(clusterAssment[i,0])
plt.plot(dataSet.iloc[i,0], dataSet.iloc[i,1],mark[markIndex])
for i in range(k):
plt.plot(centroids[i,0], centroids[i,1], mark[i], markersize = 12)
plt.show()
return centroids,clusterAssment

show(k=3)


|
12天前
|

【机器学习】K-means算法与PCA算法之间有什么联系？
【5月更文挑战第15天】【机器学习】K-means算法与PCA算法之间有什么联系？
41 1
|
12天前
|

【机器学习】维度灾难问题会如何影响K-means算法？
【5月更文挑战第15天】【机器学习】维度灾难问题会如何影响K-means算法？
29 0
|
13天前
|

【机器学习】聚类算法中，如何判断数据是否被“充分”地聚类，以便算法产生有意义的结果？
【5月更文挑战第14天】【机器学习】聚类算法中，如何判断数据是否被“充分”地聚类，以便算法产生有意义的结果？
41 1
|
13天前
|

【机器学习】可以利用K-means算法找到数据中的离群值吗？
【5月更文挑战第14天】【机器学习】可以利用K-means算法找到数据中的离群值吗？
37 0
|
14天前
|

【机器学习】怎样在非常大的数据集上执行K-means算法？
【5月更文挑战第13天】【机器学习】怎样在非常大的数据集上执行K-means算法？
29 0
|
14天前
|

【机器学习】列举几种情况，在这些情况下K-means算法难以取得较好效果
【5月更文挑战第13天】【机器学习】列举几种情况，在这些情况下K-means算法难以取得较好效果
19 0
|
14天前
|

【机器学习】在聚类算法中，使用曼哈顿距离和使用欧式距离有什么区别？
【5月更文挑战第12天】【机器学习】在聚类算法中，使用曼哈顿距离和使用欧式距离有什么区别？
35 4
|
14天前
|

【机器学习】在使用K-means算法之前，如何预处理数据？
【5月更文挑战第12天】【机器学习】在使用K-means算法之前，如何预处理数据？
65 3
|
14天前
|

【机器学习】比较分层聚类（Hierarchical Clustering）和K-means聚类算法
【5月更文挑战第12天】【机器学习】比较分层聚类（Hierarchical Clustering）和K-means聚类算法
35 2
|
14天前
|

【机器学习】在使用K-means聚类算法时，如何选择K的值？
【5月更文挑战第11天】【机器学习】在使用K-means聚类算法时，如何选择K的值？
112 9