Kmeans聚类算法python sklearn用户画像教程

 更新时间:2023年07月24日 11:06:23   作者:圆觉_  
这篇文章主要介绍了Kmeans聚类算法python sklearn用户画像教程,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

1、基本概念

聚类分析简称聚类(clustering),是一个把数据集划分成子集的过程,每一个子集是一个簇(cluster),使得簇中的样本彼此相似,但与其他簇中的样本不相似。

聚类分析不需要事先知道样本的类别,甚至不用知道类别个数,因此它是一种典型的无监督学习算法,一般用于数据探索,比如群组发现和离群点检测,还可以作为其他算法的预处理步骤。

在工作中遇到用户画像、群组划分问题,而kmeans聚类这一无监督学习算法,可以在无数据标注训练情况下,基于距离按将群组划分不同的簇。

主要的聚类算法一般可以划分为以下几类:

方法一般特点
划分方法1.发现球形互斥的簇 2.基于距离 3.可用均值或中心点代表簇中心 4.对中小规模数据有效
层次方法1.聚类是一个层次分解 2.不能纠正错误的合并或划分 3.可以集成其他技术
基于密度的方法1.可以发现任意形状的簇 2.簇是对象空间中被低密度区域分隔的稠密区域 3.簇密度 4.可能过滤离群点
基于网格的方法1.使用一种多分辨率网格数据结构 2.快速处理

2、Kmeans算法

Kmeans属于划分方法的经典聚类方法。

算法步骤如下:

选择K个点作为初始质心(随机产生或者从D中选取)  

  • repeat:将每个点分配到最近的质心,形成K个簇; 重新计算每个簇的质心  
  • until:簇不发生变化或达到最大迭代次数

2.1 k值选取

k的值是用户指定的,表示需要得到的簇的数目。

在运用Kmeans算法时,我们一般不知道数据的分布情况,不可能知道数据的集群数目,所以一般通过枚举来确定k的值。

另外,在实际应用中,由于Kmean一般作为数据预处理,或者用于辅助分类贴标签,所以k一般不会设置很大。

2.2 初始质心的选取

Kmeans算法对初始质心的选取比较敏感,选取不同的质心,往往会得到不同的结果。

初始质心的选取方法,常用以下两种的简单方法:一种是随机选取,一种是用户指定。

需要注意的是,无论是随机选取还是用户指定,质心都尽量不要超过原始数据的边界,即质心每一维度上的值要落在原始数据集每一维度的最小与最大值之间。

2.3 距离度量方法

距离度量方法(或者说相似性度量方法)有很多种,常用的有欧氏距离,余弦相似度,街区距离,汉明距离等等。

在Kmeans算法中,一般采用欧氏距离计算两个点的距离,欧氏距离如下:

distEclud(X,Y)=∑i=1n(Xi−Yi)2‾‾‾‾‾‾‾‾‾‾‾‾⎷

举个例子,X=(1000,0.1),Y=(900,0.2),那么它们的欧氏距离就是:

(1000−900)2+(0.1−0.2)2‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾√≈100 (1000−900)2+(0.1−0.2)2≈100

举这个例子是为了说明,当原始数据中各个维度的数量级不同时,它们对结果的影响也随之不同,那些数量级太小的维度,对于结果几乎没产生任何影响。

比如所举的例子中的第二个维度的0.1,0.2,与第一个维度1000的数量级相差了一万倍。

为了赋予数据每个维度同等的重要性,我们在运用欧氏距离时,必须先对数据进行规范化,比如将每个维度都缩放到[0,1]之间。

2.4 质心的计算

在Kmeans算法中,将簇中所有样本的均值作为该簇的质心。这也是Kmeans名字的由来吧。

2.5 算法停止条件

在两种情况下算法应该停止:一种是达到了指定的最大迭代次数,一种是算法已经收敛,即各个簇的质心不再发生变化。关于算法的收敛,在2.5部分讨论。

2.6 代价函数与算法收敛

Kmeans算法的代价函数比较简单,就是每个样本点与其所属质心的距离的平方和(误差平方和,Sum of Squared Error,简称SSE):

J(c,u)=∑i=1k||X(i)−uc(i)||2

与其他机器学习算法一样,我们要最小化这个代价函数,但这个函数没有解析解,所以只能通过迭代求解的方法来逼近最优解(这一点也和众多机器学习算法一样吧)。

所以你再看看算法步骤,其实就是一个迭代过程。

由于代价函数(SSE)是非凸函数,所以在运用Kmeans算法时,不能保证收敛到一个全局的最优解,我们得到的一般是一个局部的最优解。

因此,为了取得比较好的效果,一般会多跑几次算法(用不同的初始质心),得到多个局部最优解,比较它们的SSE,选取SSE最小的那个。

方法优点:

  • k-平均算法是解决聚类问题的一种经典算法,算法简单、快速。
  • 对处理大数据集,该算法是相对可伸缩的和高效率的,因为它的复杂度大约是O(nkt),其中n是所有对象的数目,k是簇的数目,t是迭代的次数。通常k<<n。这个算法经常以局部最优结束。
  • 算法尝试找出使平方误差函数值最小的k个划分。当簇是密集的、球状或团状的,而簇与簇之间区别明显时,它的聚类效果很好。

缺点:

  • K 是事先给定的,这个 K 值的选定是非常难以估计的;
  • 对初值敏感,对于不同的初始值,可能会导致不同的聚类结果。一旦初始值选择的不好,可能无法得到有效的聚类结果;
  • 该算法需要不断地进行样本分类调整,不断地计算调整后的新的聚类中心,因此当数据量非常大时,算法的时间开销是非常大的。
  • 不适合于发现非凸面形状的簇,或者大小差别很大的簇;
  • 对于”噪声”和孤立点数据敏感,少量的该类数据能够对平均值产生极大影响。

3、Kmeans算法实现

采用python实现,基于numpy、sklearn库,其中从sklearn.cluster中import KMeans。

为了可视化聚类效果,对二维数据进行聚类并用matplot画出数据不同簇的划分。

#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
@author: liuweima
"""
from sklearn.cluster import KMeans
from sklearn.externals import joblib
import numpy
import time
import matplotlib.pyplot as plt
import sys
reload(sys)
sys.setdefaultencoding('utf8')
if __name__ == '__main__':
    ## step 1: 加载数据
    print "step 1: load data..."
    dataSet = []
    loss = []
    fileIn = open('path')
    for line in fileIn.readlines():
        lineArr = line.strip('\xef\xbb\xbf')      # '\xef\xbb\xbf'是BOM,标识读入的文件是UTF-8编码,需strip()切掉
        lineArr = lineArr.strip().split('\t')      #注意自己文件中每行数据中是用什么对列数据做分割  建议先用Word 规范一下要打开的文件
        dataSet.append([float(lineArr[0])/1.99759326,(float(lineArr[1])-100)/192230])   #数据规范化【0,1】
    print dataSet
    #设定不同k值以运算
    for k in range(2,10):
        clf = KMeans(n_clusters=k) #设定k  !!!!!!!!!!这里就是调用KMeans算法
        s = clf.fit(dataSet) #加载数据集合
        numSamples = len(dataSet)
        centroids = clf.labels_
        print centroids,type(centroids) #显示中心点
        print clf.inertia_  #显示聚类效果
        mark1 = ['or', 'ob', 'og', 'ok', '^r', '+r', 'sr', 'dr', '<r', 'pr']
        #画出所有样例点 属于同一分类的绘制同样的颜色
        for i in xrange(numSamples):
            #markIndex = int(clusterAssment[i, 0])
            plt.plot(dataSet[i][0], dataSet[i][1], mark1[clf.labels_[i]]) #mark[markIndex])
        mark2 = ['Dr', 'Db', 'Dg', 'Dk', '^b', '+b', 'sb', 'db', '<b', 'pb']
        # 画出质点,用特殊图型
        centroids =  clf.cluster_centers_
        for i in range(k):
            plt.plot(centroids[i][0], centroids[i][1], mark2[i], markersize = 12)
            #print centroids[i, 0], centroids[i, 1]
        plt.show()
        loss.append(clf.inertia_)
    for m in range(8):  #因为k 取值是2-9 (!不包括10) m取值是0-7
        plt.plot(m,loss[m],'bo')
    plt.show()

质心的初始化、最大迭代次数都为默认值。

其中读取文件一些坑已经做了备注。整个kmeans算法不是很耗时,主要在画图上花费时间。以我跑十万级别的数据来看,画图很费时间。

聚类结果图 ,涉及业务,就不贴出了。

贴出,k取range(2,30)时,kmeans的误差平方和(SSE)曲线图。

为了弥补经典kmeans聚类算法的不足,出现了一些改进型kmeans

比如二分Kmeans算法(bisectingKmeans)是为了克服Kmeans算法收敛于局部最小值的问题而提出的。

该算法首先将所有点作为一个簇,然后将该簇一分为二。之后选择其中一个簇继续划分,选择哪一个簇进行划分

取决于对其划分是否可以最大程度降低SSE的值,上述过程不断迭代,直到得到用户指定的簇数目为止。

或者先使用MeanShift算法自动生成k值删除游离点。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 基于PyQt5制作一个PDF文件合并器

    基于PyQt5制作一个PDF文件合并器

    PDF文件合并工具是非常好用可以把多个pdf文件合并成一个,本文将利用Python中的PyQT5模块,制作一个简易的PDF文件合并器,感兴趣的可以了解一下
    2022-03-03
  • pandas如何获取某个数据的行号

    pandas如何获取某个数据的行号

    这篇文章主要介绍了pandas如何获取某个数据的行号问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-02-02
  • python  Matplotlib绘图直线,折线,曲线

    python  Matplotlib绘图直线,折线,曲线

    这篇文章主要介绍了python  Matplotlib绘图直线,折线,曲线,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-09-09
  • Python中出现IndentationError:unindent does not match any outer indentation level错误的解决方法

    Python中出现IndentationError:unindent does not match any outer

    今天在网上copy的一段代码,代码很简单,每行看起来该缩进的都缩进了,运行的时候出现了如下错误,IndentationError: unindent does not match any outer indentation level,如果看起来缩进正常所有tab与空格混用就会出现这个问题
    2019-01-01
  • 基于Python实现自动关机小工具

    基于Python实现自动关机小工具

    上班族经常会遇到这样情况,着急下班结果将关机误点成重启,或者临近下班又通知开会,开完会已经迟了还要去给电脑关机。今天使用PyQt5做了个自动关机的小工具,设置好关机时间然后直接提交即可,需要的可以参考一下
    2022-10-10
  • 详解Python之可迭代对象,迭代器和生成器

    详解Python之可迭代对象,迭代器和生成器

    这篇文章主要为大家介绍了Python之可迭代对象,迭代器和生成器,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2021-12-12
  • Tensor和NumPy相互转换的方法

    Tensor和NumPy相互转换的方法

    本文主要介绍了Tensor和NumPy相互转换的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-03-03
  • Django如何将URL映射到视图

    Django如何将URL映射到视图

    这篇文章主要介绍了Django如何将URL映射到视图,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-07-07
  • 解决python3.6 右键没有 Edit with IDLE的问题

    解决python3.6 右键没有 Edit with IDLE的问题

    这篇文章主要介绍了解决python3.6 右键没有 Edit with IDLE的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-03-03
  • Django文件存储 自己定制存储系统解析

    Django文件存储 自己定制存储系统解析

    这篇文章主要介绍了Django文件存储 自己定制存储系统解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-08-08

最新评论