大部分聚类方法针对的是多维数据,现实场景中还有可能存在以为数据的情况,针对以为数组的聚类和多维的数据有很大的不同,今天就来实战演练下:

需求内容:分析订单的价格分布

常见方案:按照100为梯度,分析不同价格区间的订单量

存在缺陷:现实生活中,定价存在一些自然的价格分隔,如果按照步距划分可能存在一些偏差,比如airbnb的价格筛选显示出的房价分布:

解决上述缺陷最好的方式是对价格进行聚类,找出做合适的价格区间。

在学习聚类算法的过程中,学习到的聚类算法大部分都是针对n维的,针对一维数据的聚类方式较少,今天就来学习下如何给一维的数据进行聚类。

方案一:采用K-Means对一维数据聚类

Python代码如下:

from sklearn.cluster import KMeans

import numpy as np

x = np.random.random(10000)

y = x.reshape(-1,1)

km = KMeans()

km.fit(y)

km.cluster_centers_

核心的操作是y = x.reshape(-1,1),含义为将一维数据变成只有1列,行数不知道多少(-1代表根据剩下的维度计算出数组的另外一个shape属性值)。

方案二:采用一维聚类方法Jenks Natural Breaks

Jenks Natural Breaks(自然断点分类)。一般来说,分类的原则就是差不多的放在一起,分成若干类。统计上可以用方差来衡量,通过计算每类的方差,再计算这些方差之和,用方差和的大小来比较分类的好坏。因而需要计算各种分类的方差和,其值最小的就是最优的分类结果(但并不唯一)。这也是自然断点分类法的原理。另外,当你去看数据的分布时,可以比较明显的发现断裂之处,这些断裂之处和Jenks Natural Breaks方法算出来也是一致的。因而这种分类法很“自然”。

Jenks Natural Breaks和K Means在一维数据时,完全等价。它们的目标函数一样,但是算法的步骤不完全相同。K Means是先设定好K个初始随机点。而Jenks Breaks则是用遍历的方法,一个点一个点地移动,直到达到最小值。

Natural Breaks算法又有两种:

Jenks-Caspall algorithm(1971),是Jenks和Caspall发明的算法。原理就如前所述,实现的时候要将每种分类情况都计算一遍,找到方差和最小的那一种,计算量极大。n个数分成k类,就要从n-1个数中找k-1个组合,这个数目是很惊人的。数据量较大时,如果分类又多,以当时的计算机水平根本不能穷举各种可能性。

Fisher-Jenks algorithm(1977),Fisher(1958)发明了一种算法提高计算效率,不需要进行穷举。Jenks将这种方法引入到数据分类中。但后来者几乎只知道Jenks而不知Fisher了。

具体算法实现:

和K-Means一样,使用Jenks Natural Breaks需要先确定聚类数量K值。常见的方法是:GVF(The Goodness of Variance Fit)。GVF,翻译过来是“方差拟合优度”,公式如下:

$$SDCM=\sum_{i=1}^{k} \frac{1}{N_{i}} \sum_{i=1}^{N_{i}}(z_{i j}-\bar{z}_{j})^{2} $$

$$SDAM=\frac{1}{N} \sum_{i=1}^{N}\left(z_{i}-\bar{z}\right)^{2} $$

$$GVF=1-\frac{SDMC}{SDAM}$$

其中,SDAM是the Sum of squared Deviations from the Array Mean,即原始数据的方差;SDCM是the Sum of squared Deviations about Class Mean,即每一类方差的和。显然,SDAM是一个常数,而SDCM与分类数k有关。一定范围内,GVF越大,分类效果越好。SDCM越小,GVF越大,越接近于1。而SDCM随k的增大而大,当k等于n时,SDMC=0,GVF=1。

GVF用于判定不同分类数的分类效果好坏。以k和GVF做图可得:

随着k的增大,GVF曲线变得越来越平缓。特别是在红线处(k=5),曲线变得基本平坦(之前起伏较大,之后起伏较小),k(5)也不是很大,所以可以分为5类。一般来说,GVF>0.7就可以接受了,当然越高越好,但一定要考虑k不能太大。显然,这是一个经验公式,但总比没有好吧。

代码示例:

from jenkspy import jenks_breaks

import numpy as np

def goodness_of_variance_fit(array, classes):

# get the break points

classes = jenks_breaks(array, classes)

# do the actual classification

classified = np.array([classify(i, classes) for i in array])

# max value of zones

maxz = max(classified)

# nested list of zone indices

zone_indices = [[idx for idx, val in enumerate(classified) if zone + 1 == val] for zone in range(maxz)]

# sum of squared deviations from array mean

sdam = np.sum((array - array.mean()) ** 2)

# sorted polygon stats

array_sort = [np.array([array[index] for index in zone]) for zone in zone_indices]

# sum of squared deviations of class means

sdcm = sum([np.sum((classified - classified.mean()) ** 2) for classified in array_sort])

# goodness of variance fit

gvf = (sdam - sdcm) / sdam

return gvf

def classify(value, breaks):

for i in range(1, len(breaks)):

if value < breaks[i]:

return i

return len(breaks) - 1

if __name__ == '__main__':

gvf = 0.0

nclasses = 2

array = np.random.random(10000)

while gvf < .8:

gvf = goodness_of_variance_fit(array, nclasses)

print(nclasses, gvf)

nclasses += 1

参考链接:

方案三:核密度估计Kernel Density Estimation

所谓核密度估计,就是采用平滑的峰值函数(“核”)来拟合观察到的数据点,从而对真实的概率分布曲线进行模拟。核密度估计更多详细内容,可以参考先前的Mean Shift聚类中的相关说明。

使用示例:

import numpy as np

from scipy.signal import argrelextrema

import matplotlib.pyplot as plt

from sklearn.neighbors.kde import KernelDensity

a = np.array([10, 11, 9, 23, 21, 11, 45, 20, 11, 12]).reshape(-1, 1)

kde = KernelDensity(kernel='gaussian', bandwidth=3).fit(a)

s = np.linspace(0, 50)

e = kde.score_samples(s.reshape(-1, 1))

plt.plot(s, e)

plt.show()

mi, ma = argrelextrema(e, np.less)[0], argrelextrema(e, np.greater)[0]

print("Minima:", s[mi])

print("Maxima:", s[ma])

print(a[a < mi[0]], a[(a >= mi[0]) * (a <= mi[1])], a[a >= mi[1]])

plt.plot(s[:mi[0] + 1], e[:mi[0] + 1], 'r',

s[mi[0]:mi[1] + 1], e[mi[0]:mi[1] + 1], 'g',

s[mi[1]:], e[mi[1]:], 'b',

s[ma], e[ma], 'go',

s[mi], e[mi], 'ro')

plt.show()

输出内容:

Minima: [17.34693878 33.67346939]

Maxima: [10.20408163 21.42857143 44.89795918]

[10 11 9 11 11 12] [23 21 20] [45]

参考链接:

python函一维聚类_聚类实战:一维数组数据聚类相关推荐

  1. python实现线性回归预测_机器学习实战笔记(Python实现)-08-线性回归

    --------------------------------------------------------------------------------------- 本系列文章为<机器 ...

  2. python视频网站项目_[项目实战] Python Flask构建微电影视频网站

    注:本站源码仅做学术研究,自娱自乐使用,不得用于任何的非法商业用途 由于版权原因.本站将无限期停止微擎模块资源下载如果有任何侵犯您权益的内容请联系小站删除哦.小站一定会积极配合的. 课程目录: (下载 ...

  3. python 赚钱 知乎_爬虫实战:抓取知乎问题 “大学生如何赚到一万元”

    最近对赚钱的话题很感兴趣,在知乎上关注了很多"赚钱"相关的问题,高质量的有不少,但是夹杂着私货的也不少.不过知乎的数据比较全,我们完全可以用来做文本分析. 爬虫的原理我就不细讲了, ...

  4. python做bi系统_可视化实战!Python+BI,手把手教你做炫酷的NBA可视化分析

    之前手痒做了一次NBA可视化分析,好多人追着我问教程,这两天终于闲下来了,花时间整理这篇NBA可视化分析教程,手把手教大家做一次炫酷的数据可视化分析! 先部分展示本次教程的作品: 数据获取 本次可视化 ...

  5. python京东自动签到_爬虫实战【10】利用Selenium自动登陆京东签到领金币

    今天我们来讲一下如何通过python来实现自动登陆京东,以及签到领取金币. 如何自动登陆京东? 我们先来看一下京东的登陆页面,如下图所示: [插入图片,登陆页面] 登陆框就是右面这一个框框了,但是目前 ...

  6. python手机号码正确编程_【实战案例】用python批量生成真实的手机号码

    前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理.1目 标 场 景 平时在工作过程中,偶尔会需要大量的 手机号码,去测试一些具体 ...

  7. 爬虫python代码网易云_爬虫实战(二) 用Python爬取网易云歌单

    最近,博主喜欢上了听歌,但是又苦于找不到好音乐,于是就打算到网易云的歌单中逛逛 本着 "用技术改变生活" 的想法,于是便想着写一个爬虫爬取网易云的歌单,并按播放量自动进行排序 这篇 ...

  8. python 数据模型好学吗_没有工程能力的数据分析师也是扯淡,到底要不要精通python!...

    背景 你们好 很早之前提到一个观点:一个优秀的数据人应该是思维.业务.分析和工程能力的综合体,谈思维.业务等能力可能大家觉得飘在空中. 确实,在我一开始入门数据行业的时候,我也有这样的感觉,为什么那些 ...

  9. python 矩阵元素赋值_对numpy中数组元素的统一赋值实例

    Numpy中的数组整体处理赋值操作一直让我有点迷糊,很多时候理解的不深入.今天单独列写相关的知识点,进行总结一下. 先看两个代码片小例子: 例子1: In [2]: arr =np.empty((8, ...

最新文章

  1. composer自动载入的四种方式
  2. oracle11gr2查看数据库状态,Oracle 11gR2数据库文件丢失后的恢复测试
  3. HTTP_REFERER的获取情况
  4. C语言常用宏定义(#define)使用方法
  5. 特征图大小_新手向快速了解图神经网络
  6. 微信小程序云开发教程-WXSS入门-基本语法
  7. 190615每日一句;每个学生都不能错过的9个人生忠告; 什么样心态的人,才能取得最终的成功
  8. hadoop namenode启动不了_hadoop全分布式是个什么鬼?!动手搭建Hadoop(4)
  9. STC89C51单片机串口程序下载失败总结
  10. c51串行通信汇编语言,51单片机双机串行通信汇编语言程序+Proteus仿真
  11. linux展示文件最尾部内容 最新,LINUX tailf命令-显示文件的末尾若干行内容
  12. [附源码]java毕业设计疫情防控期间人员档案追寻系统设计与实现论文
  13. Python点击Pycharm按钮Run的时候出现Type ‘manage.py help <subcommand>‘ for help on a specific subcommand.
  14. 姓名学中萍字无根 怎么解释_无根Buildah的工作原理:在非特权环境中构建容器
  15. T-S模糊模型与状态反馈控制及Matlab仿真 (附代码)
  16. 怎样提高英语思维能力?
  17. 直流无刷电机和霍尔传感器
  18. JAVA实现把PPT转PDF的方法
  19. Arduino极速入门教程——两篇文章让你会用Arduino(下)
  20. php上传文件到三方,文件上传服务器_PHP文件上传实现上传到另一台服务器

热门文章

  1. 用JSP创建一个表格模板
  2. linu之软件包管理
  3. js日期加一天或者减一天
  4. 干掉联想电脑管家LAVservice进程
  5. 一步一步教你装kata-container
  6. AI修复后的王祖贤和林青霞,真的是人间绝色啊
  7. 飞腾CPU相关寄存器描述(持续更新)
  8. 免费舆情监控工具有哪些,TOOM加强舆情监控提高应对能力
  9. 京瓷3501i,原稿台复印纸张识别故障
  10. 老子《道德经》第五十二章