K-means进行用户分层
RFM作为经典的用户分层模型,做用户分层确实非常合适,但是我看到大部分的文章仅仅只是介绍如何使用RFM做用户分层,却没有介绍最重要的一点,如何划分分界点,这里使用聚类算法对RFM指标进行分类。
源数据格式
uid,R,F,M
一、K-Means算法
K-Means 是一种非监督学习,解决的是聚类问题。 K 代表的是 K 类,Means 代表的是中心,主要计算过程就是通过计算点之间的距离确定K类之间的中心点,确定了中心点之后,也就完成了聚类。
二、K-Means 的工作原理
选取 K 个点作为初始的类中心点,这些点一般都是从数据集中随机抽取的;
将每个点分配到最近的类中心点,这样就形成了 K 个类,然后重新计算每个类的中心
点;重复第二步,直到类不发生变化,或者你也可以设置最大迭代次数,这样即使类中心点
发生变化,但是只要达到最大迭代次数就会结束。
三、案例1:给亚洲球队做聚类
数据源格式如下:

针对以上数据源,按照以下步骤进行聚类计算
1、数据规范化
数据变换是数据准备的重要环节,它通过数据平滑、数据聚集、数据概化和规范化等方式将数据转换成适用于数据挖掘的形式。
- 数据平滑:去除数据中的噪声,将连续数据离散化。这里可以采用分箱、聚类和回归的
方式进行数据平滑,我会在后面给你讲解聚类和回归这两个算法;- 数据聚集:对数据进行汇总,在 SQL 中有一些聚集函数可以供我们操作,比如 Max()
反馈某个字段的数值最大值,Sum() 返回某个字段的数值总和;- 数据概化:将数据由较低的概念抽象成为较高的概念,减少数据复杂度,即用更高的概
念替代更低的概念。比如说上海、杭州、深圳、北京可以概化为中国。- 数据规范化:使属性数据按比例缩放,这样就将原来的数值映射到一个新的特定区域
中。常用的方法有最小—最大规范化、Z—score 规范化、按小数定标规范化等,我会
在后面给你讲到这些方法的使用;- 属性构造:构造出新的属性并添加到属性集中。这里会用到特征工程的知识,因为通过
属性与属性的连接构造新的属性,其实就是特征工程。比如说,数据表中统计每个人的
英语、语文和数学成绩,你可以构造一个“总和”这个属性,来作为新属性。这样“总
和”这个属性就可以用到后续的数据挖掘计算中。
数据规范化的几种方法:
- Min-max 规范化
Min-max 规范化方法是将原始数据变换到 [0,1] 的空间中。用公式表示就是:
新数值 =(原数值 - 极小值)/(极大值 - 极小值)。- Z-Score 规范化
假设 A 与 B 的考试成绩都为 80 分,A 的考卷满分是 100 分(及格 60 分),B 的考卷满
分是 500 分(及格 300 分)。虽然两个人都考了 80 分,但是 A 的 80 分与 B 的 80 分代
表完全不同的含义。
那么如何用相同的标准来比较 A 与 B 的成绩呢?Z-Score 就是用来可以解决这一问题的。
我们定义:新数值 =(原数值 - 均值)/ 标准差。
假设 A 所在的班级平均分为 80,标准差为 10。B 所在的班级平均分为 400,标准差为
100。那么 A 的新数值 =(80-80)/10=0,B 的新数值 =(80-400)/100=-3.2。
那么在 Z-Score 标准下,A 的成绩会比 B 的成绩好。
我们能看到 Z-Score 的优点是算法简单,不受数据量级影响,结果易于比较。不足在于,
它需要数据整体的平均值和方差,而且结果没有实际意义,只是用于比较。- 小数定标规范化
小数定标规范化就是通过移动小数点的位置来进行规范化。小数点移动多少位取决于属性
A 的取值中的最大绝对值。
举个例子,比如属性 A 的取值范围是 -999 到 88,那么最大绝对值为 999,小数点就会移
动 3 位,即新数值 = 原数值 /1000。那么 A 的取值范围就被规范化为 -0.999 到 0.088。
上面这三种是数值规范化中常用的几种方式。
这里采用Min-max 规范化,使用 新数值 =(原数值 - 极小值)/(极大值 - 极小值) 公式计算:
1 | from sklearn import preprocessing |

2、确定 K 类及 K 类的中心点
此处确定3个类,K-Means算法随机指派初始中心点,通过后续不断的迭代获取最终的中心点。
这里随机选择中国、日本、韩国为三个类的中心点。
3、计算其余球队到该三个中心点的距离
欧氏距离、曼哈顿距离、切比雪夫距离、余弦距离四种有关距离的计算,欧氏距离是最常用的距离计算方式,这里选用该方式

计算过程
1 | # 将随机选择的三个初始k点的值取出 |
最后输出

4、重新计算这三个类的中心点
最简单的方式就是取平均值,然后根据新的中心点按照距离远近重新分配球队的分类,再根据球队的分类更新中心点的位置。
1 | # 重新计算这三个类的中心点,取这些点的平均值 |
5、重复迭代以上过程
迭代到分类结果不再发生变化,可以得到以下的分类结果:
1 | # 第二次循环,对三列分别计算到array21、22、23的欧式距离 |

这里存在疑问,划分4和划分5两个分类结果一直交替,不知道为什么会出现这种结果,这里暂且认为从划分4之后数据分类就不再变化。
从以上划分4的结果可以看到,中国、伊拉克、阿联酋、乌兹别克断坦是属于同一个类的。
6、使用sklearn种的k-means算法
sklearn 是 Python 的机器学习工具库,如果从功能上来划分,sklearn 可以实现分类、聚类、回归、降维、模型选择和预处理等功能。这里我们使用的是 sklearn 的聚类函数库,因此需要引用工具包:
1 | n_clusters: 即 K 值,一般需要多试一些 K 值来保证更好的聚类效果。你可以随机设置 |
最常用的是 fit 和 predict 这个两个函数。你可以单独使用 fit 函数和 predict 函数,也可以合并使用 fit_predict 函数。其中fit(data) 可以对 data 数据进行 k-Means 聚类。 predict(data) 可以针对 data 中的每个样本,计算最近的类。
1 | # coding: utf-8 |

结果和我们之前计算的结果一致。
四、使用k-means对rmf指标进行分类
1、生成数据并计算
1 | # coding: utf-8 |

2、分类之后的数据如何使用?
核心问题:分类之后需要依据分类结果划分值,怎么划分?
这里通过计算各群体特征的概率密度函数来看各个类中的分布情况:
研究一个随机变量,不只是要看它能取哪些值,更重要的是它取各种值的概率如何!
PDF的取值本身不是概率,它是一种趋势(密度)只有对连续随机变量的取值进行积分后才是概率,也就是说对于连续值确定它在某一点的概率是没有意义的;
rfm模型是连续型随机变量,所以这里使用概率密度函数来表示各个分类的结果分布,不写循环了,多写几遍代码了:
1 | import scipy.stats as st |

对以上分组数据进行解读即可。
最后
本文并未涉及对K值的选取,故有疑问,自行搜索。
附上源文件地址: