前言:
目前朋友们对“kmeans算法的rfm”大体比较注意,兄弟们都想要知道一些“kmeans算法的rfm”的相关知识。那么小编在网摘上网罗了一些有关“kmeans算法的rfm””的相关内容,希望朋友们能喜欢,同学们一起来了解一下吧!有很多方法可以对客户进行分类并按组划分。但是由于这是讨论数据问题的地方,所以让我们使用数据方法来回答这个问题。
当您有数据时——比如客户列表和他们购买的产品——您需要使用这些数据创建具有类似特征的组,您需要一种聚类方法。聚类是无监督机器学习技术组的一部分。我们称它为无监督的,因为计算机之前没有关于如何对实体进行分组的信息。实际上,它将通过分析彼此之间的距离来尝试创建具有相似实体的聚类。
让我们开始讨论我们的研究案例。访问UCI并下载在线零售数据集()。该数据集由8个属性和541,909实例组成,显示了2010年12月1日至2011年12月9日英国在线零售发生的所有交易。据UCI介绍,公司主要销售独特的全天候礼品,很多客户都是批发商。
我们的主要目标是使用聚类技术将这些客户按客户细分进行分组。这里,我们将使用K-Means。但是,如何对这些客户进行分组呢?使用哪些变量?我们可以尝试使用RFM(最近一次消费,消费频率,消费金额)方法来分析客户。这种方法是用来评估客户价值的,我们稍后会详细讨论。
所以首先要做的是加载我们的库和数据并做一些探索性的数据分析。Python代码如下:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
data = pd.read_excel('data/retail.xlsx')
data.head()
稍后我们将详细讨论这些值。现在,我们已经查找了空值并删除了它们。让我们也花些时间研究数据集上的惟一值。您将看到,我们现在有来自37个国家的客户(我们删除了一些空条目——我们以前有38个国家)和4,372个惟一客户。Python代码如下:
data.isna().any()
data = data[pd.notnull(data['CustomerID'])]
data.isna().any()
data.nunique()
我们能做的就是describe()在数据集上提供的主要数字统计信息的帮助下进行检查。当你这样做时,注意一些有趣的事情:数量的最小值是负数。为什么?我老实说不知道。但是因为这个案例的负数没有任何意义,所以我们也将它们排除在外。
data.describe()
data = data[data.Quantity >= 0]
data.describe()
开始RFM
你还记得我说过我们将使用RFM来我们的客户吗?让我们现在开始。
根据维基百科,RFM代表三个维度:
Recency ——客户最近购买了什么?Frequency ——他们多久购买一次?Monetary Value ——他们花了多少钱?
对于RFM,我们可以做的一件事是为每个维度从1到5打分,这是我们最希望的行为。我们稍后再计算分数。我们首先需要创建一个由recency, the frequency 和the monetary value组成的新数据框架。
为了计算recency,我们将查看发票日期。因为我们最后一张发票的日期是2011-12-09,所以我们认为这是最近的一张。
为了计算Frequency ,我们将简单地计算每个客户的发票号码。对于Monetary Value,我们将单位价格乘以购买的数量,然后为每个客户求和。
Python实现如下:
import datetime as dt
print('Most recent invoice is from:')
print(data['InvoiceDate'].max())
lastDate = dt.datetime(2011,12,10)
data['InvoiceDate'] = pd.to_datetime(data['InvoiceDate'])
Most recent invoice is from:
2011-12-09 12:50:00
data['TotalPrice'] = data.UnitPrice * data.Quantity
rfmTable = data.groupby('CustomerID').agg({'InvoiceDate': lambda x: (lastDate - x.max()).days,
'InvoiceNo': lambda x: len(x),
'TotalPrice': lambda x: x.sum()})
rfmTable['InvoiceDate'] = rfmTable['InvoiceDate'].astype(int)
rfmTable.rename(columns={'InvoiceDate': 'recency',
'InvoiceNo': 'frequency',
'TotalPrice': 'monetary'}, inplace=True)
rfmTable.head()
现在,我们要计算分数。我们是这样做的:首先,我们在降序模式下按频率对数据进行排序。然后,我们将数据集上的客户数量除以5。我们为前面创建的每个段分配一个从5到1的数字。我们也来看看“monetary”和“recency”列。
注意:对于“recency”一栏,由于最近的订单更好,我们将按升序排序。
我将把分数添加到一个名为rfmTableScores的新数据集中 .Python代码如下:
# Create f_score
f_score = []
m_score = []
r_score = []
columns = ['frequency', 'monetary']
scores_str = ['f_score', 'm_score']
scores = [f_score, m_score]
for n in range(len(columns)):
# Order by column
rfmTable = rfmTable.sort_values(columns[n], ascending=False)
# Create new index
refs = np.arange(1,4340)
rfmTable['refs'] = refs
# Add score
for i, row in rfmTable.iterrows():
if row['refs'] <= 866:
scores[n].append(5)
elif row['refs'] > 866 and row['refs'] <= 866*2:
scores[n].append(4)
elif row['refs'] > 866*2 and row['refs'] <= 866*3:
scores[n].append(3)
elif row['refs'] > 866*3 and row['refs'] <= 866*4:
scores[n].append(2)
else:
scores[n].append(1)
# Create f_score column
rfmTable[scores_str[n]] = scores[n]
# For recency, we do the opposite: most recents are better, so we order as ascending
rfmTable = rfmTable.sort_values('recency', ascending=True)
# Recreate index
refs = np.arange(1,4340)
rfmTable['refs'] = refs
# Add score
for i, row in rfmTable.iterrows():
if row['refs'] <= 866:
r_score.append(5)
elif row['refs'] > 866 and row['refs'] <= 866*2:
r_score.append(4)
elif row['refs'] > 866*2 and row['refs'] <= 866*3:
r_score.append(3)
elif row['refs'] > 866*3 and row['refs'] <= 866*4:
r_score.append(2)
else:
r_score.append(1)
# Create f_score column
rfmTable['r_score'] = r_score
rfmTableScores = rfmTable.drop(['frequency', 'monetary', 'recency', 'refs'], axis=1)
rfmTableScores.head(5)
由于我们的分数在1到5之间,因此我们不需要缩放数字。
我们现在可以开始考虑这个机器学习模型了。K-Means模型只能对您在数据集上的信息进行聚类,但您必须选择所需的聚类数量。您可以使用K-Means模型本身做出此决定。为此,让我们创建聚类内的平方和(WCSS)以支持我们的决策。Python实现如下:
from sklearn.cluster import KMeans
wcss = []
for i in range(1,11):
kmeans = KMeans(n_clusters=i, init='k-means++', random_state=0)
kmeans.fit(rfmTableScores)
wcss.append(kmeans.inertia_)
plt.plot(range(1,11), wcss)
plt.title('Elbow graph')
plt.xlabel('Cluster number')
plt.ylabel('WCSS')
plt.show()
通过肘部法则生成的图显示最佳聚类数为4.这是线开始缓慢下降的点。现在,让我们构建机器学习模型。Python实现如下:
kmeans = KMeans(n_clusters=4, init='k-means++', random_state=0)
clusters = kmeans.fit_predict(rfmTableScores)
rfmTable['clusters'] = clusters
rfmTable.head()
我们已经完成了聚类过程。如您所见,由于R,F和M分数分析,聚类被分配给每个客户。
让我们绘制一个图表,显示聚类过程之前的数据点以及聚类过程之后的一些图表。所以你可以清楚地看到形成的聚类。Python代码如下:
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure(figsize=(15,10))
ax = fig.add_subplot(111, projection='3d')
ax.scatter(rfmTable.recency, rfmTable.frequency, rfmTable.monetary, s=50)
ax.set_xlabel('Recency')
ax.set_ylabel('Frequency')
ax.set_zlabel('Monetary')
fig = plt.figure(figsize=(15,10))
dx = fig.add_subplot(111, projection='3d')
colors = ['blue', 'yellow', 'green', 'red']
for i in range(0,4):
dx.scatter(rfmTable[rfmTable.clusters == i].recency,
rfmTable[rfmTable.clusters == i].frequency,
rfmTable[rfmTable.clusters == i].monetary,
c = colors[i],
label = 'Cluster ' + str(i+1),
s=50)
dx.set_title('Clusters of clients')
dx.set_xlabel('Recency')
dx.set_ylabel('Frequency')
dx.set_zlabel('Monetary')
dx.legend()
c1 = rfmTable[rfmTable.clusters == 0]
c2 = rfmTable[rfmTable.clusters == 1]
c3 = rfmTable[rfmTable.clusters == 2]
c4 = rfmTable[rfmTable.clusters == 3]
plt.scatter(c1.recency, c1.frequency, c = 'blue', label = 'Cluster 1')
plt.scatter(c2.recency, c2.frequency, c = 'yellow', label = 'Cluster 2')
plt.scatter(c3.recency, c3.frequency, c = 'green', label = 'Cluster 3')
plt.scatter(c4.recency, c4.frequency, c = 'red', label = 'Cluster 4')
plt.title('Clusters of clients')
plt.xlabel('Recency')
plt.ylabel('Frequency')
plt.legend()
c1 = rfmTable[rfmTable.clusters == 0]
c2 = rfmTable[rfmTable.clusters == 1]
c3 = rfmTable[rfmTable.clusters == 2]
c4 = rfmTable[rfmTable.clusters == 3]
plt.scatter(c1.frequency, c1.monetary, c = 'blue', label = 'Cluster 1')
plt.scatter(c2.frequency, c2.monetary, c = 'yellow', label = 'Cluster 2')
plt.scatter(c3.frequency, c3.monetary, c = 'green', label = 'Cluster 3')
plt.scatter(c4.frequency, c4.monetary, c = 'red', label = 'Cluster 4')
plt.title('Clusters of clients')
plt.xlabel('Frequency')
plt.ylabel('Monetary')
plt.legend()
c1 = rfmTable[rfmTable.clusters == 0]
c2 = rfmTable[rfmTable.clusters == 1]
c3 = rfmTable[rfmTable.clusters == 2]
c4 = rfmTable[rfmTable.clusters == 3]
plt.scatter(c1.recency, c1.monetary, c = 'blue', label = 'Cluster 1')
plt.scatter(c2.recency, c2.monetary, c = 'yellow', label = 'Cluster 2')
plt.scatter(c3.recency, c3.monetary, c = 'green', label = 'Cluster 3')
plt.scatter(c4.recency, c4.monetary, c = 'red', label = 'Cluster 4')
plt.title('Clusters of clients')
plt.xlabel('Recency')
plt.ylabel('Monetary')
plt.legend()
标签: #kmeans算法的rfm