《机器学习实战》第11章——利用K-均值聚类算法对未标注的数据分组完全解读

本章介绍

本章将介绍如何利用K-均值算法进行聚类。在进行聚类之后,分析如何通过后处理手段来提高聚类性能。探讨二分K-均值是如何克服局部最小值问题。最后将使用地理坐标在地图上进行聚类。

K-均值算法

在讲K-均值算法前,我们需要对无监督学习的概念有所了解。无监督学习的特点是训练样本点标记信息未知,目标是通过对无标记样本数据的学习,解释数据的内在性质与规律。聚类是无监督学习算法中的一大分支。聚类将数据集中的样本划分为若干个子集(通常不想交),每个子集称为一个簇。簇的中心被称为质心。

K-均值算法则是一个经典的聚类算法,它对未标注的数据进行聚类,并生成K个类别(簇心)的算法。

K-均值的伪码表示如下:

创建k个点作为起始的质心(通常是随机选择)
当任意一个点的簇分配结果发生改变的时候:
    对数据集中的每个数据点
        对每个质心
            计算很质心到数据点之间的距离
        将数据点分配到距离其最近的簇
    对每个簇,计算簇中所有点的均值并将均值作为质心

下面来看一下具体的实现

import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans

def loadDataSet(fileName):
    '''
    函数功能:
        从文本中读取数据,并返回处理好的数据
    参数:
        fileName__文件名
    返回值:
        数据矩阵
    '''
    #创建一个列表存储从文件读取的数据
    dataMat = []
    #打开文件
    fr = open(fileName)
    #对文件的数据进行行遍历
    for line in fr.readlines():
        #由于一行有多个数据,所以要创建一个temp保存
        temp = []
        #将这一行数据按\t切分
        curLine = line.strip().split('\t')
        #fltLine = map(float, curLine)这行代码会导致数据类型变为map object,影响可视化,所以对代码进行改写
        #得到当前行数据的数量
        lenOfcurLine = len(curLine)
        #遍历当前行所有数据
        for i in range(lenOfcurLine):
            #将数据转为float型存入temp
            temp.append(float(curLine[i]))
        #将temp放进dataMat里
        dataMat.append(temp)
    #返回从文件中读取到的并处理好的数据
    return np.mat(dataMat)

def randCent(dataSet,k):
    '''
    函数功能:
        根据数据的规模与K值随机生成中心点
    参数:
        dataSet__数据集
        k__随机生成中心点的数量
    返回值:
        k个中心点组成的矩阵
    '''
    #shape是指数据的维度(m,n).m指数据集的数量,n指数据集的维度.
    n = np.shape(dataSet)[1]
    #生成一个维度为(k,n)的零矩阵
    centroids = np.mat(np.zeros((k,n)))
    #对所有列进行遍历
    for j in range(n):
        #找出第n列中最小值
        minJ = np.min(dataSet[:,j])
        #一列中最大值减去一列中最小值得到一个区间
        rangeJ = float(np.max(dataSet[:,j]) - minJ)
        #最小值+区间×随机系数.这样生成的中心点在整个数据集的边界之内
        centroids[:,j] = minJ + rangeJ * np.random.rand(k,1)
    #返回随机生成的中心点
    return centroids

def distEclud(vecA ,vecB):
    '''
    函数功能:
        计算两个点之间的欧氏距离
    参数:
        vecA__A点的坐标
        VecB__B点的坐标
    返回值:
        两点之间的欧氏距离
    '''
    return np.sqrt(np.sum(np.power(vecA - vecB,2)))

def KMeans(dataSet, k, distMeas=distEclud, createCent=randCent):
    '''
    函数功能:
        对数据集进行K-均值聚类
    参数:
        dataSet__结构化、数值型的数据集
        k__中心点个数
    返回值:
        聚类中心矩阵、聚类结果
    '''
    #数据集的行数
    m = np.shape(dataSet)[0]
    #数据集的列数
    n = np.shape(dataSet)[1]
    #创建一个大小为(m,2)的零矩阵,第0列是聚类的结果,第1列是该点到簇中心的距离
    clusterAssment = np.mat(np.zeros((m,2)))
    #利用函数createCent随机生成中心点完成初始化
    centroids = createCent(dataSet, k)
    #标记
    clusterChanged = True
    #如果所有在一轮聚类之后,所有点的分配都不发生改变,为False,结束聚类,否则为True,继续进行聚类
    while clusterChanged:
        #假定所有点分配都不发生改变,标记为False
        clusterChanged = False
        #遍历整个样本
        for i in range(m):
            #无穷大,用来记录点到簇的最小距离
            minDist = np.inf
            #默认值-1
            minIndex = -1
            #遍历所有的簇心
            for j in range(k):
                #计算每个样本与每个簇的距离
                distJI = distMeas(centroids[j,:] ,dataSet[i,:
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值