题目描述:
现在有部分餐饮客户的消费数据存于数据文件:consumption.xls
其中R表示最近一次消费时间间隔,F表示消费频率,M表示消费总金额
编程实现K-Means聚类算法,将客户分类成3类客户群,并评价这些客户群的价值
数据集如下:
解题思路:
这是一个使用 K-Means 聚类算法的 Python 程序。
简单来说,K-Means 算法是一种聚类算法,它的目的是将数据集划分成 K 个聚类,使得每个聚类内的数据点尽可能地相似。
在这个程序中,首先使用 pandas 库读取了一个 Excel 文件中的数据,然后使用 K-Means 算法将数据分为 3 个聚类。然后,程序计算了每个聚类的平均消费频率和平均消费总金额,并使用这些信息计算出了每个聚类的价值。最后,程序使用 matplotlib 库绘制了每个聚类的价值的折线图。
其中,绘制出的价值曲线,x轴标识分出的客户群,y轴标识价值。客户群的价值是通过计算每个客户群的平均消费频率和平均消费总金额,然后相乘得到的。
具体来说,代码中使用了两个字典avg_freq和avg_m分别表示每个客户群的平均消费频率和平均消费总金额,然后使用一个字典cluster_value将它们相乘得到每个客户群的价值。
实验的主要函数的功能:
euclidean_distance函数:用于计算两个点之间的欧几里得距离。这个函数用于K-Means聚类算法中用于计算每个数据点与各个聚类中心的距离。
kmeans函数实现了K-Means聚类算法的过程。它接受两个参数:X表示待聚类的数据,K表示要聚成几类。函数返回两个值:clusters表示每个数据点所属的客户群编号,centers表示聚类后的聚类中心。
每次迭代的聚类中心:
得到的三个客户群的价值:
得到的折线图:
python实现代码:
from collections import defaultdict
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
def euclidean_distance(x, y):
return np.sqrt(np.sum((x - y) ** 2))
def kmeans(X, K):
N = len(X)
clusters = np.zeros(N)
centers = X[np.random.choice(N, K, replace=False)]
while True:
for i in range(N):
distances = [euclidean_distance(X[i], c) for c in centers]
clusters[i] = np.argmin(distances)
new_centers = np.zeros((K, 3))
for k in range(K):
new_centers[k] = np.mean(X[clusters == k], axis=0)
print(new_centers) # 输出新的中心点
if np.allclose(centers, new_centers):
break
centers = new_centers
return clusters, centers
data = pd.read_excel('/Users/mac/Desktop/上课内容/数据挖掘/实验三/1.xlsx', engine='openpyxl')
X = data[['R', 'F', 'M']].values
clusters, centers = kmeans(X, 3)
# 计算每个客户群的平均消费频率和平均消费总金额
cluster_freq = defaultdict(list)
for i, cluster in enumerate(clusters):
cluster_freq[cluster].append(X[i, 1])
avg_freq = {c: sum(f) / len(f) for c, f in cluster_freq.items()}
cluster_m = defaultdict(list)
for i, cluster in enumerate(clusters):
cluster_m[cluster].append(X[i, 2])
avg_m = {c: sum(m) / len(m) for c, m in cluster_m.items()}
# 评估每个客户群的价值
cluster_value = {c: avg_freq[c] * avg_m[c] for c in avg_freq}
print(cluster_value)
x = list(range(len(cluster_value)))
y = list(cluster_value.values())
plt.plot(x, y)
plt.show()