已知当前所研究的问题的类别数目及各类特征,将一些未知类别的个体正确地归属于其中某一类。
例如,在大学,学校根据院系、专业,将学员分类不同的类别,有学计算机的,有学金融,有学数学等,这个过程就是分类,一开始就知道类别数目、类别特征
事先不知道所研究的问题应分为几类,也不知道观测到的个体的具体分类情况,需要按照性质上的亲疏程度在没有先验知识的情况下进行自动分类,产生分类结果
例如,在大学,同学之间根据兴趣爱好、性格、家乡等,自发地聚集成不同的圈子,这个过程就是聚类,一开始不知道类别数目及细节
多数情况:对样品进行分类(Q型聚类)
少数情况:对指标进行分类(R型聚类)
样品间距离:
欧式距离,平方欧式距离,切比雪夫距离,块距离等
数据的变换方法:
标准化变换,对数变换,极差变换标准化等
1.系统聚类法:… …
2.K-均值法:
1.把样本粗略分为K类;
2.把样品逐个分派到最近的类中;
3.重复第二步,直到各类无元素进出为止
R:最近一次消费(Recency)
F:消费频率(Frquency)
M:消费金额(Monetary)
以R、F、M三个核心指标为维度进行聚类分析,利用K-means聚类分析将用户分成8个类别,即哪些是重要价值客户,哪些是重要保持客户,哪些是重要发展客户,哪些是流失客户等
1.数据源
用户id
首投资时间
最近一次投资时间
总计投资金额
投标总次数
提数日:2016/7/20
2.RFM指标计算
R:求出最近一次投资时间距提数日天数
F:月均投资次数
M:月均投资金额
3.聚类分析
3.1.数据标准化,这里采用取对数,即log10进行标准化
3.2.利用K-means聚类将用户分为8个类别
3.3.根据这8个类别的R、F、M指标,对用户进行标注,哪些是重要价值客户,哪些是重要保持客户,哪些是重要发展客户,哪些是流失客户等
import warnings
warnings.filterwarnings("ignore")
import pandas as pd
data=pd.read_excel('RFM聚类分析【样本数据】.xlsx',index_col='用户编码')
data.head()
#提数日 2016/7/20
import datetime
exdata_date=datetime.datetime(2016,7,20)#将字符串转化为datetime类型
print(exdata_date)
#R最近一次投资时间距提数日天数
last_date=pd.to_datetime(data['最近一次投资时间']) #转化为datetime类型
diff_R=exdata_date-last_date
diff_R #timedelta
R=[]
for i in diff_R:
R.append(i.days)
R[:10]
'''
用户在投时长(月)
python中没有直接获取月份差的方法,只能获取天数差
1.用户在投时长(天)
2.月=天数/30,向上取整,ceil函数
'''
from math import ceil
first_date=pd.to_datetime(data['首次投资时间'])
diff=exdata_date-first_date
diff
diff_months=[]
for i in diff: #i是天数
diff_months.append(ceil(i.days/30))
diff_months[:10]
'''
type((data['总计投标总次数']/diff_months)) #Series
type((data['总计投标总次数']/diff_months).values) #ndarray
'''
#F 月均投资次数
F=(data['总计投标总次数']/diff_months).values #ndarray,有索引和值
F[:10]
#M 月均投资金额
M=(data['总计投资总金额']/diff_months).values
M[:10]
#选取R,F,M三个指标作为聚类分析的指标
import pandas as pd
cdata=pd.DataFrame([R,list(F),list(M)]).T #一定是列表,F、M都是数组
cdata
#指定cdata的index和columns
cdata.index=data.index
cdata.columns=['R-最近一次投资时间距提数日的天数','F-月均投资次数','M-月均投资金额']
cdata.head()
K-meas 聚类分析
#标准化:
# cdata-cdata.mean()#对每列进行操作
zcdata=(cdata-cdata.mean())/cdata.std()
zcdata.head()
from sklearn.cluster import KMeans
kmodel=KMeans(n_clusters=4,n_jobs=4,max_iter=100,random_state=0)
kmodel.fit(zcdata) #拟合
#分几类,分配资源,最大迭代次数,随机数种子(使得结果可以重现,每次运行结果可以固定下来)
kmodel.labels_ #ndarray
#统计每个分类的频率
pd.Series(kmodel.labels_).value_counts()
'''
需求:将kmodel.labels_追加到cdata的最后一列
方法一:将kmodel.labels_有ndarray转化为Series,然后insert到cdata中
Category=pd.Series(kmodel.labels_,index=cdata.index)
cdata.insert(3,'类别',Category)
cdata
方法二:将kmodel.labels_有ndarray转化为Series,然后用concat函数
Category=pd.Series(kmodel.labels_,index=cdata.index)
cdata_res=pd.concat([cdata,Category],axis=1)#axis=1表示横向合并
cdata_res.rename(columns={0:'类别'},inplace = True) #0不能加引号,因为DataFrame中的0不是字符串
cdata_res
'''
#把类别标签赋回原来的数据
#kmodel.labels_是一个数组,没有用户编码那个字段
cdata_res=pd.concat([cdata,pd.Series(kmodel.labels_,index=cdata.index)],axis=1)#axis=1表示横向合并
cdata_res.rename(columns={0:'类别'},inplace = True) #0不能加引号,因为DataFrame中的0不是字符串
# cdata_res.columns=list[cdata.columns]+['类别'] 这也是重命名的一种方法
cdata_res.head()
cdata_res.groupby(cdata_res['类别']).mean().T
#每个类别那三种指标的均值
'''
结论:
-类别3:R,F,M都比较高,超级用户
-类别2:,,,
-类别1:M很高,F还行,R不高,重要保持客户
-类别0:低价值客户
'''
增加列:在投时长【提数日-首次投资时间】不足一个月按一个月计算
=DATEDIF(B2,$F$1,"m")+1
标准化:
(样本-均值)/标准差
R_std:【F_std、M_std同理】
=(H2-AVERAGE(H:H))/STDEV.S(H:H)
#####进入SPSS分析:
分析变量
R_std、F_std、M_std
会生成新一列(表示每个用户属于哪个类别)
averageifs:计算每个类别均值