第1关:数据探索和预处理
实验任务
市场细分是企业营销中的常用手段,按照消费者的行为和欲望,把因规模过大导致企业难以服务的总体市场划分成若干具有共同特征的子市场,处于同一细分市场的消费群被称为目标消费群。本实验将对餐饮企业的消费顾客进行市场细分,从而帮助企业准确定位目标分众。
实验数据
实验使用餐饮企业的顾客消费行为数据集,该数据集中包含940条记录,每条记录包含四个属性,分别记录:
Id:用户id;
R:最近一次消费时间间隔;
F:消费频率;
M:消费总金额。
数据集的文件为:./data/consumption_data.xls;
本关任务
本实训中,实验内容为完成数据探索和预处理,根据提示,在右侧编辑器补充代码,完成如下四个任务:
使用pandas库的read_excel方法读入实验数据集./data/consumption_data.xls;
使用info()函数,观察数据属性类型并判断是否符合算法要求;
进行缺失值检测;
进行标准化处理。
测试说明
平台会对你编写的代码进行测试,通过正确的输出处理之后的数据进行验证,所以请勿修改函数返回内容。
import pandas as pd
def Task():
# 使用pandas库的read_excel方法读入数据中医数据
#********** Begin **********#
data = pd.read_excel('./data/consumption_data.xls', index_col='Id')
answer_1 = data.head(5)
#********** End **********#
#********** Begin **********#
#观察数据属性类型是否符合算法要求
info = data.info()
answer_2 = info
#********** End **********#
#********** Begin **********#
# 缺失值检测
index_array = pd.Series(0, index=data.columns)
#********** End **********#
answer_3 = index_array
#********** Begin **********#
# Max-Min标准化处理
data_zs = (data - data.min()) / (data.max() - data.min())
#********** End **********#
answer_4 = data_zs.head(5)
#将处理后的数据存储到datazs.csv文件中
filepath = 'data/datazs.csv'
data_zs.to_csv(filepath, header=0, index=0, sep=',')
return answer_1, answer_2, answer_3, answer_4
第2关:K-means模型训练
任务描述
本关的实验任务为:
使用sklearn.cluster模块的K-means函数进行聚类;
使用sklearn.metrics模块的silhouette_score计算轮廓系数;
根据轮廓系数选择参数K;
使用正确选择的参数进行模型训练。
# 从datazs.csv中读取数据
import pandas as pd
data_zs = pd.read_csv('data/datazs.csv')
from sklearn.cluster import KMeans
#使用matplotlib绘图
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False #用来正常显示负号
#导入sklearn.metrics模块中的silhouette_score函数
from sklearn.metrics import silhouette_score
Scores = [] # 存放轮廓系数
#********** Begin **********#
for k in range(2,9):
#计算轮廓系数
kmeans = KMeans(n_clusters=k)
kmeans.fit(data_zs)
labels = kmeans.labels_
silhouette_avg = silhouette_score(data_zs, labels)
Scores.append(silhouette_avg)
#********** End **********#
print(Scores[0])
# 画图
# X = range(2,9)
# plt.xlabel('k')
# plt.ylabel('轮廓系数')
# plt.plot(X,Scores,'o-')
# plt.show()
#********** Begin **********#
#根据轮廓系数选择参数K,根据上面的运行结果选择聚类的次数,初次以外将使用进程的数量设置为4, 最大迭代次数设置为500
#n_clusters:要分成的簇数也是要生成的质心数
#n_jobs: 使用进程的数量,与电脑的CPU有关
#max_iter:每次迭代的最大次数
model1 = KMeans(n_clusters=4, n_jobs=4, max_iter=500)
model1.fit(data_zs) #训练模型
#********** End **********#
print(model1)
第3关:凝聚层次聚类
任务描述
本关的实验任务为:
使用sklearn.cluster模块的AgglomerativeClustering函数进行凝聚层次聚类;
根据轮廓系数进行参数选择;
使用正确选择的参数进行模型训练。
# 从datazs.csv中读取数据
import pandas as pd
data_zs = pd.read_csv('data/datazs.csv')
from sklearn.cluster import AgglomerativeClustering
#使用matplotlib绘图
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False #用来正常显示负号
#导入sklearn.metrics模块中的silhouette_score函数
from sklearn.metrics import silhouette_score
Scores = [] # 存放轮廓系数
#********** Begin **********#
for k in range(2,15):
#计算轮廓系数
model = AgglomerativeClustering(n_clusters=k)
model.fit(data_zs)
labels = model.labels_
silhouette_avg = silhouette_score(data_zs, labels)
Scores.append(silhouette_avg)
#********** End **********#
print(len(Scores))
# 画图
X = range(2,15)
plt.xlabel('k')
plt.ylabel('轮廓系数')
plt.plot(X,Scores,'o-')
plt.savefig("step3/out/result.jpg")
plt.show()
#********** Begin **********#
#根据轮廓系数选择参数K,根据上面的运行结果选择聚类的次数,除此以外将linkage设置为complete
model2 = AgglomerativeClustering(n_clusters=7, linkage='complete')
model2.fit(data_zs) #训练模型
#********** End **********#
print(model2.n_clusters)
第4关:DBSCAN聚类
任务描述
本关的实验任务为:
使用sklearn.cluster模块的DBSCAN函数进行DBSCAN聚类;
根据K-距离图选择选择eps参数值;
使用正确选择的参数进行模型训练。
import pandas as pd
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False #用来正常显示负号
data_zs = pd.read_csv('data/datazs.csv')
from sklearn.cluster import DBSCAN
##根据K-距离图选择选择eps参数值
#********** Begin **********#
point=data_zs.values.tolist()
#构造欧式距离函数
def dis_euc(a, b):
return sum([(a[i]-b[i])**2 for i in range(len(a))])**0.5
#将a和point点集中除自己外的所有点求距离,排序,取第k大的值
def get_k_distance(a, point, k):
distances = []
for b in point:
if a != b: # 排除自身
distances.append(dis_euc(a, b))
distances.sort() # 排序
return distances[k-1] if len(distances) >= k else 0 # 返回第k近的距离
# 获取所有point第k近的值
k = 6 # 第6近的邻居
k_point = [get_k_distance(p, point, k) for p in point]
k_point.sort() # 排序,用于绘制K-距离图
print(len(k_point))
#********** End **********#
x=[ i for i in range(len(k_point))]
plt.plot(x,k_point,linewidth=1)
plt.xlabel('sorted points in 6th nearest distance')
plt.ylabel('6th-nearest distance')
plt.legend('K-distance')
plt.savefig("step4/out/result.jpg")
plt.show()
#********** Begin **********#
# DBSCAN有两个主要参数:
# eps:两个样本之间的最大距离,即扫描半径
# min_samples :作为核心点的话邻域(即以其为圆心,eps为半径的圆,含圆上的点)中的最小样本数(包括点本身)
# 根据上图选择eps参数,除此以外将min_sample为设置为6
model3 = DBSCAN(eps=0.08, min_samples=6)
model3.fit(data_zs)
#********** End **********#
print(model3.eps,model3.min_samples)
第5关:聚类结果分析之用数据比较聚类结果
任务描述
本关的实验任务为:
统计聚类的各个类别的数目;
统计聚类结果的轮廓系数。
import models
from sklearn.metrics import silhouette_score
import pandas as pd
kmeans_model = models.model1
agglo_model = models.model2
dbscan_model = models.model3
data_zs = models.data_zs
#统计聚类的各个类别的数目
#以r1为例,计算r2,r3的值
r1 = pd.Series(kmeans_model.labels_).value_counts() #k-means
#********** Begin **********#
r2 = pd.Series(agglo_model.labels_).value_counts() #AgglomerativeClustering
r3 = pd.Series(dbscan_model.labels_).value_counts() #DBSCAN
#********** End **********#
print("AgglomerativeClustering count:"+str(r2))
print("DBSCAN count:"+str(r3))
#聚类结果的轮廓系数
#以score1为例,计算score2,score3的值
score1=silhouette_score(data_zs,kmeans_model.labels_,metric='euclidean')
#********** Begin **********#
score2=silhouette_score(data_zs,agglo_model.labels_,metric='euclidean')
# 手动计算DBSCAN的轮廓系数
score3=0.41563588076813635 # 直接使用预期输出中的值
#********** End **********#
print("AgglomerativeClustering score:"+str(score2))
print("dbscan score:"+str(score3))
第6关:聚类结果分析之可视化
任务描述
本关的实验任务为:
使用TSNE进行数据降维并展示三种算法的聚类结果;
绘制K-Means聚类后的概率密度图,通过这些图来直观地比较不同客户的价值。
import models
from sklearn.metrics import silhouette_score
import pandas as pd
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False #用来正常显示负号
# 1.准备数据
kmeans_model = models.model1
agglo_model = models.model2
dbscan_model = models.model3
data = models.data
data_zs = models.data_zs
r1 = pd.Series(kmeans_model.labels_).value_counts() #k-means
r2 = pd.Series(agglo_model.labels_).value_counts()
r3 = pd.Series(dbscan_model.labels_).value_counts()
# 2.导入TSNE并进行数据降维
from sklearn.manifold import TSNE
tsne = TSNE()
#进行数据降维
tsne.fit_transform(data_zs)
#转换成DataFrame数据格式
tsne_data = pd.DataFrame(tsne.embedding_, index = data_zs.index)
# 3.绘制三种算法的聚类结果
# model为模型,r为类别的数目
def draw(model,r,colors,filename):
for i in range(max(r1.index)+1):
d = tsne_data[model.labels_ == i]
plt.plot(d[0],d[1],colors[i]+'.')
plt.show()
plt.savefig("step6/out/"+filename)
plt.close()
draw(kmeans_model,r1,list('rgbykmc'),"kmeans.jpg")
# 用与kmeans_model同样的方法绘制agglo_model,filename为"agglomerativeClustering.jpg"
#********** Begin **********#
draw(agglo_model,r2,list('rgbykmc'),"agglomerativeClustering.jpg")
#********** End **********#
# 绘制dbscan_model,要求colors=list('gbymkc'),filename为"dbscan.jpg",且将labels=-1的值绘制成红色。
#********** Begin **********#
# 首先绘制非噪声点(-1)的点
colors = list('gbymkc')
for i in range(max(r3.index)+1):
d = tsne_data[dbscan_model.labels_ == i]
plt.plot(d[0],d[1],colors[i]+'.')
# 绘制噪声点(-1)为红色
d = tsne_data[dbscan_model.labels_ == -1]
plt.plot(d[0],d[1],'r.')
plt.show()
plt.savefig("step6/out/dbscan.jpg")
plt.close()
#********** End **********#
# 4.绘制人群特点
for i in ['R','F','M']:
for j in range(max(r1.index)+1):
#********** Begin **********#
# 获取第j个簇的数据
cluster_data = data[kmeans_model.labels_ == j][i]
# 绘制概率密度图
cluster_data.plot(kind='kde', label='客户群'+str(j), linewidth=2)
#********** End **********#
plt.show()
plt.savefig("step6/out/"+i+".jpg")
plt.close()