移动公司客户价值分析

        大数据课程设计,搜了半天没搜到,希望以后能帮助其他人。        

移动公司价值分析:

过程:

  1. 读入数据并进行数据预处理,处理数据集中的缺失值、重复值及无效值,对数据做量化处理
  2. 对数据进行特征提取和标准化处理
  3. 根据第二部计算的特征使用K-Means聚类算法对客户进行聚类分析
  4. 对聚类结果和相关数据进行数据可视化和数据分析

下面代码里面,关于n_jobs不能使用,我就没有写,原因是在版本0.23以后的sklearn.cluster里没有n_jobs,我不会解决这个问题所以没写,但是不影响数据。

代码能跑起来,中间会有些警告,新版本python对于一些书写方式的建议,也不影响数据。

 下面是数据集:

链接:https://pan.baidu.com/s/1gmRMjPyp2XNVevq7eT9VVw 
提取码:wppu 

话不多说,直接上代码,过程基本在代码里都有太多了我就不用手敲了,jupyter写的,python3版本。

先读入数据:

import pandas as pd
import math
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from datetime import datetime
import numpy as np
import matplotlib as mpl
data = pd.read_excel('D:\数据集.xlsx')
data.head(10)

剩下的看代码段里的注解就行了

#从数据中可以看出数据虽然没有缺失值但是  有些行的数据中存在0值的数据
#查看行列数的统计
print(data.shape)
#从上述数据来看  数据总共有301行,每行数据有着12列属性
#查看整体描述信息
print(data.info)
#统计数据缺失值
data.isnull().sum()
#统计存在0值的数据列
(data == 0).any()
#从缺失值和0值来看,没有但是只有3列不存在0值
#检测过滤异常值  遍历data的每一列 统计每一列0数据的个数
for col in data.columns:
    count = 0  #count为统计的个数
    count = [count + 1 for x in data[col] if x == 0]
    print(col+': '+str(sum(count)))
gender1 = 0  
gender2 = 0 
gender1 =   [gender1 + 1 for x in data['gender'] if x == 1]
print(sum(gender1))
gender2 =   [gender2 + 1 for x in data['gender'] if x == 2]
print(sum(gender2))
#gender pay_num pay_times age 0值少,可能是不正常统计造成的,下面寻找脏数据
index1 = (data["gender"] == 0) |(data["age"]==0)
data[index1]
#从以上数据来看  gender  and  age  这两列数据都是0的行数为9行  感觉为脏数据

index2 = (data["pay_num"] == 0) | (data["pay_times"]==0)
data[index2]
#以上也为脏数据  
#将两种脏数据合并并删除
# data = data.drop(data[index1].index)
# data = data.drop(data[index2].index)
# data.shape
#这里一个警告 ,用了个笨办法解决了
index3 = ((data["pay_num"] == 0) | (data["pay_times"]==0)) | ((data["gender"] == 0) |(data["age"]==0))
data = data.drop(data[index3].index)
data.shape
#统计重复值
data.duplicated().sum()
#看12列数据名称  用户id是唯一值  检查id是否有重复值
data.duplicated(['user_id']).sum()
#删除重复id
data = data.drop_duplicates(['user_id'])
data.shape
#删除重复id
data = data.drop_duplicates(['user_id'])
data.shape
#数据分析  从12列数据属性来看,可以针对客户的年龄和性别分析客户的使用习惯
gender = pd.value_counts(data['gender'])
age = pd.value_counts(data['age'])
#筛选属性列 
data_select = data[['user_id','pay_num','pay_times','last_pay_time']]
data_select.head()
data_select.columns = ['用户id','消费金额','消费次数','最后一次消费时间']
data_select.head()
#生成起始日期和提数日日期
exdata_date = datetime(2016,7,20)
start_date = datetime(2016,6,1)
print(exdata_date)
print(start_date)
#转化为可以计算的日期数据类型
data_select['最后一次消费时间'] = pd.to_datetime(data_select['最后一次消费时间'])
#计算R
#不加dt.days  输出的日期的后面会带days  
# 带了days后面数学计算将无法进行  ,所以先去除days
data_select['R(最后一次消费距提数日时间)'] = (exdata_date - data_select['最后一次消费时间']).dt.days
print(data_select['R(最后一次消费距提数日时间)'])
#计算最后一次消费时间和起始日期差几天
period_day = data_select['最后一次消费时间'] - start_date
#创建空列表统计月数
period_month = []
#遍历天数,向上取整生成月数
for i in period_day:
    period_month.append(math.ceil(i.days/30))
#第一次输出月数统计
print(period_month)
#清除月份为0的值  将其赋值为1
for i in range(0,len(period_month)):
    if period_month[i] == 0:
        period_month[i] = 1
print(period_month)
#计算 F M
data_select['F(月均消费次数)'] = data_select['消费次数']/period_month

data_select['M(月均消费金额)'] = data_select['消费金额']/period_month
data_select
data_select.head(20)
#提取R  F  M
cdata = data_select[['R(最后一次消费距提数日时间)','F(月均消费次数)','M(月均消费金额)']]
cdata.index = data_select['用户id']
cdata.head()
#标准化处理
z_data = (cdata - cdata.mean())/cdata.std()
z_data.columns = ['R(标准化)','F(标准化)','M(标准化)']
z_data.head()
#SSE记录每次聚类后样本到中心的欧式距离
SSE = []
#分别聚类为9个类别
for k in range (1,9):
    estimator = KMeans(n_clusters = k)
    estimator.fit(z_data)
    #样本到最近聚类中信的距离平方之和
    SSE.append(estimator.inertia_)
#设置x轴的数据
X = range(1,9)
#雅黑字体
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
plt.plot(X,SSE,'o-')
plt.xlabel('k值')
plt.ylabel('SSE')
plt.title("肘部图")
plt.show()
kmodel = KMeans(n_clusters = 4 , max_iter = 100,random_state = 0)
kmodel.fit(z_data)
kmodel.labels_
kmodel.cluster_centers_
#统计所属各个类别的数据个数
r1 = pd.Series(kmodel.labels_).value_counts()
#聚类中心

r2 = pd.DataFrame(kmodel.cluster_centers_)
#链接后得到了聚类中心对应类别下的数目
result = pd.concat([r2,r1],axis = 1)
result.columns = ['R','F','M'] + ['各类别人数']
result1  = result['各类别人数']
result
KM_data = pd.concat([z_data,pd.Series(kmodel.labels_ ,index = z_data.index)],axis = 1)
data1 = pd.concat([data_select, pd.Series(kmodel.labels_ , index = data.index)], axis = 1)
data1.columns = list(data_select.columns) + ['类别']
KM_data.columns = ['R','F','M'] + ['类别']
KM_data.head()
data1.head()
centers = kmodel.cluster_centers_
#雷达图
# 1、创建画布
plt.figure()
# 支持中文,支持负号:
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False
# 2、绘图及修饰
# 绘制雷达图
datalength = centers.shape[1]
# 构建角度----从0-2π生成5个元素的等差数组
angle = np.linspace(0, 2 * np.pi, datalength, endpoint=False)
# 闭合角度
angle = np.concatenate((angle, [angle[0]]), axis=0)
# 闭合数据
centers = np.concatenate((centers, centers[:, 0:1]), axis=1)
# 绘制雷达图
for i in range(centers.shape[0]):
    plt.polar(angle, centers[i, :])
# 添加标题
plt.title('移动公司客户聚类结果')
# 修改刻度
plt.xticks(angle[:-1], [ 'R', 'F', 'M'])
# 添加图例
plt.legend(['第0类', '第1类', '第2类','第3类'], loc=0)
# 3、展示
plt.show()
# 柱状图
x_data = ["男","女"]
y_data = [sum(gender1) ,sum(gender2)]
# 正确显示中文和负号
plt.rcParams["font.sans-serif"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False

# 画图,plt.bar()可以画柱状图
for i in range(len(x_data)):
	plt.bar(x_data[i], y_data[i])
# 设置图片名称
plt.title("性别-人数分析")
# 设置x轴标签名
plt.xlabel("性别")
# 设置y轴标签名
plt.ylabel("人数")
# 显示
plt.show()
#折线图
L = list(range(100))
x = range(0, 100)
for col in range(100):
    count = 0  #count为统计的个数
    count = [count + 1 for x in data['age'] if x == col]
    L[col] = sum(count)  
plt.plot(x,L)
plt.title('年龄-人数统计图')
plt.xlabel('年龄')
plt.ylabel('人数')
plt.show()

# 准备数据
x_data = ["第0类","第1类","第2类","第3类"]

y_data = result1
# 正确显示中文和负号
plt.rcParams["font.sans-serif"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False

# 画图,plt.bar()可以画柱状图
for i in range(len(x_data)):
	plt.bar(x_data[i], y_data[i])
# 设置图片名称
plt.title("性别-人数分析")
# 设置x轴标签名
plt.xlabel("性别")
# 设置y轴标签名
plt.ylabel("人数")
# 显示
plt.show()

r2.columns = ['R','F','M']
# 中文和正负号设置
mpl.rcParams["font.sans-serif"] = ["SimHei"]
mpl.rcParams["axes.unicode_minus"] = False
tick_label = ["第0类","第1类","第2类","第3类"]
x = np.arange(len(tick_label))
y = [1,2,3,4]
bar_width = 0.3

plt.figure(figsize=(13,7))
# 柱状
plt.bar(x,r2['R'], bar_width, align="center", color="#2bb179", label='R', alpha=0.5)
plt.bar(x+bar_width, r2['F'], bar_width, color="b", align="center", label="F", alpha=0.5)
plt.bar(x+bar_width*2, r2['M'], bar_width, color="orange", align="center", label="M", alpha=0.5)

plt.xticks(x+bar_width, tick_label,fontsize=18)
plt.yticks(fontsize=18)
plt.xlabel("类别",fontsize=20)
plt.ylabel("三个指标均值",fontsize=20)
plt.legend(fontsize=16)
plt.grid()

本人python比较差,基本柱状图、雷达图什么的是看着人家的学来的所以有很多不规范的地方,代码能跑就行,欢迎大佬指点。

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值