基于 CFSFDP 聚类算法的电信客户价值分析

温馨提示:文末有 CSDN 平台官方提供的学长 QQ 名片 :) 

1. 项目背景

        电信行业是典型的数据密集型行业,只有正确地分析用户数据,发现更多商机,做出正确的决策,从而更好的向用户提供服务。电信行业的决策,在很大程度上依赖于客户的分类,针对不同类型的客户,实施相应的策略,从而获得客户的满意,征得客户的信任,把握真诚的客户群,最终是的企业自身获益。客户的分类依赖于客户价值的分析,本项目通过对客户价值的详细分析,并利用 CFSFDP 聚类算法,对客户进行类型的划分,可以获知客户价值的大小,客户价值的类型,从而得到客户的分类。

        从客户需求出发,了解客户需要什么,他们有怎么样的特征,电信运营商为客户设置不同的优惠套餐,以争取更多的用户:推出不同的优惠套餐,降低客户流失率、提高收入、增加 ARPU 值(average revenue per user 每个用户平均收益),实现精准的市场营销策略定制。

        B站详情与代码下载:基于CFFDP聚类算法的电信客户价值分析_哔哩哔哩_bilibili

基于CFFDP聚类算法的电信客户价值分析

2. 功能组成

        基于 CFSFDP 聚类算法的电信客户价值分析的功能主要包括:

3. 数据读取与预处理

custinfo = pd.read_csv('custinfo.csv')
custcall = pd.read_csv('custcall.csv')

# 数据聚合:--对整个DataFrame数值求平均值,删除最后一列【month】
custcall2 = custcall.groupby(custcall['Customer_ID']).mean()
custcall3 = custcall2.drop('month', 1)
# 数据合并
data = pd.merge(custinfo,custcall3,left_on='Customer_ID',right_index=True)
data.index = data['Customer_ID']
data = data.drop('Customer_ID',1) 
# 数据探索:(mean,std,min,max,25%,50%,75%)
data.describe()
ColumnsGenderAgeL_O_SPeak_callsPeak_minsOffPeak_callsOffPeak_minsWeekend_callsWeekend_minsInternational_minsNat_call_cost
count18550.00000018550.00000018550.00000018550.00000018550.00000018550.00000018550.00000018550.00000018550.00000018550.00000018550.000000
mean0.48210231.50625333.71003239.756397118.76876417.35651451.6039522.7908368.35694928.2925982.944807
std0.49969312.84847214.09397739.67767084.28997416.12024333.0039372.8368116.09782323.4885674.593809
min0.00000012.0000009.5333330.0000000.0000000.0000000.0000000.0000000.0000000.0018400.000000
25%0.00000022.00000021.33333310.33333352.6000004.66666724.5625000.6666673.60000010.9200830.000000
50%0.00000030.00000033.66666726.833333101.10000012.33333348.3500001.8333337.31666722.3974911.000000
75%1.00000039.00000045.86666756.333333169.30000025.83333373.8000004.00000012.20000039.3573744.333333
max1.00000082.00000058.200000287.500000483.600000105.666667191.00000020.66666733.700000169.13642233.000000

4. 数据探索式分析

4.1 性别分布情况

fig = plt.figure(figsize=(10, 5))
sns.countplot(data['Gender'])
plt.title('Gender')
plt.show()

4.2 Tariff 分布情况 

4.3 Handset 分布情况

4.4 其他类别特征密度分布图 

5. 特征工程

5.1 类别型的特征进行编码

encoder = LabelEncoder()
encoder = encoder.fit(data['Gender'])
data['Gender'] = encoder.transform(data['Gender'])
encoder = LabelEncoder()
encoder = encoder.fit(data['Tariff'])
data['Tariff'] = encoder.transform(data['Tariff'])
encoder = LabelEncoder()
encoder = encoder.fit(data['Handset'])
data['Handset'] = encoder.transform(data['Handset'])

5.2 数据标准化和数据降维

        由于这些数据的特征可能都不在一个数量级,这就很难使用一些聚类算法进行分析,因此,我们需要使用sklearn中有关数据处理的算法MinMaxScaler(),对数据进行标准化,将数据缩放到0~1之间,以便聚类分析。

# 引入第三方库
from sklearn.preprocessing import MinMaxScaler
# 初始化MinMaxScaler()
min_max_model = MinMaxScaler()
# 使用数据进行拟合并转化
data = min_max_model.fit_transform(data)

6. 基于 CFSFDP 算法的电信客户价值聚类

6.1 CFSDP 聚类算法算法原理及实现

聚类分析又称聚类,是把一个数据集合划分为多个集群(cluster)的过程,使得相同集群内的数据之间具有相似性,不同集群的数据之间具有差异性。聚类是数据挖掘、统计分析的主要任务之一,应用于机器学习、模式识别、图像处理、信息检索、生物信息、数据压缩和计算机图像等领域。(From 维基百科)

常用的聚类算法包括:
(1)启发式分割算法:起始确定K个中心点,用距离公式来判断数据点归属,用代价函数(如最小化平方和)评价聚类结果,迭代直至最优,例如:K-Means,K-Medoids。
(2)基于模型的算法:起始随机确定若干个模型中心,用基于概率的方法判断数据点归属,通过迭代的方法找寻适合各个类的模型,例如:Gaussian Mixture Model。
(3)降维的方法:通过降维,找寻数据间的特征,再完成聚类,例如:Spectral Clustering,Normalised-Cut。
(4)基于密度的方法:定义数据点密度,从少数对象开始拓展得到集群,例如:DBSCAN,CFSFDP。

        CFSFDP算法即为Clustering by fast search and find of density peaks,这是由Alex Rodriguez 和Alessandro Laio于2014年发表在《Science》期刊的聚类算法。该算法的基本假设有两个,一是聚类中心附近的数据点具有较低的密度,二是数据点与其他密度更大的中心距离较远。

在这里插入图片描述

# 计算任意两点之间的欧氏距离,并存储为矩阵
def caldistance(v):
    distance = np.zeros(shape=(len(v), len(v)))
    for i in range(len(v)):
        for j in range(len(v)):
            if i > j:
                distance[i][j] = distance[j][i]
            elif i < j:
                distance[i][j] = np.sqrt(np.sum(np.power(v[i] - v[j], 2)))
    return distance

......


#  通过数距离小于dc的点的个数来衡量一个点的密度(离散型)**
def count_density(distance, dc):
    density = np.zeros(shape=len(distance))
    for index, node in enumerate(distance):
        density[index] = len(node[node < dc])
    return density


#  通过公式np.sum(np.exp(-(node / dc) ** 2))衡量一个店的密度(连续型)**
#node=dij
def continous_density(distance, dc):
    density = np.zeros(shape=len(distance))
    for index, node in enumerate(distance):
        density[index] = np.sum(np.exp(-(node / dc) ** 2))
    return density


# 计算密度大于自身的点中距离自己最近的距离以及该点的直属上级
def node_detal(density, distance):
    detal_ls = np.zeros(shape=len(distance))
    closest_leader = np.zeros(shape=len(distance), dtype=np.int32)
    for index, node in enumerate(distance):
        #  点密度大于当前点的点集合(一维数组)
        density_larger_than_node = np.squeeze(np.argwhere(density > density[index]))
        #  存在密度大于自己的点
        if density_larger_than_node.size != 0:
            ......
    return detal_ls, closest_leader


......

# 确定每点的最终分类
def clustering(closest_leader, chose_list):
    for i in range(len(closest_leader)):
            while closest_leader[i] not in chose_list:
                j = closest_leader[i]
                closest_leader[i] = closest_leader[j]
    new_class = closest_leader[:]
    return new_class  # new_class[i]表示第i点所属最终分类

6.2 聚类结果可视化

def show_result(new_class, norm_data, chose_list):
    colors = [
        '#FF0000', '#FFA500', '#FFFF00', '#00FF00', '#228B22',
        '#0000FF', '#FF1493', '#EE82EE', '#000000', '#FFA500',
        '#00FF00', '#006400', '#00FFFF', '#0000FF', '#FFFACD',
        '#770077', '#008866', '#000088', '#9F88FF','#3A0088',
        '#660077', '#FF00FF','#0066FF', '#00FF00', '#7744FF',
        '#33FFDD', '#CC6600', '#886600', '#227700', '#008888',
        '#FFFF77', '#D1BBFF'
              ]
    # 画最终聚类效果图
    leader_color = {}
    main_leaders = dict(collections.Counter(new_class)).keys()
    for index, i in enumerate(main_leaders):
        leader_color[i] = index
    plt.figure(num=3, figsize=(15, 15))
    for node, class_ in enumerate(new_class):
        #  标出每一类的聚类中心点
        if node in chose_list:
            plt.scatter(x=norm_data[node, 0], y=norm_data[node, 1], marker='*', s=500, c='black',alpha=1)
        else:
            plt.scatter(x=norm_data[node, 0], y=norm_data[node, 1], c=colors[leader_color[class_]], s=100, marker='o',alpha=1)
    plt.title('The Result Of Cluster')
    plt.show()


# 画detal图和原始数据图
def show_optionmal(den, det, v):
    plt.figure(num=1, figsize=(15, 9))
    ax1 = plt.subplot(121)
    for i in range(len(v)):
        plt.scatter(x=den[i], y=det[i], c='k', marker='o', s=15)
    plt.xlabel('Density')
    plt.ylabel('Detal')
    plt.title('Chose Leader')
    plt.sca(ax1)

    ax2 = plt.subplot(122)
    for j in range(len(v)):
        plt.scatter(x=v[j, 0], y=v[j, 1], marker='o', c='k', s=15)
    plt.xlabel('axis_x')
    plt.ylabel('axis_y')
    plt.title('Dataset')
    plt.sca(ax2)
    plt.show()

7. 总结

        本项目通过对客户价值的详细分析,并利用 CFSFDP 聚类算法,对客户进行类型的划分,可以获知客户价值的大小,客户价值的类型,从而得到客户的分类。从客户需求出发,了解客户需要什么,他们有怎么样的特征,电信运营商为客户设置不同的优惠套餐,以争取更多的用户:推出不同的优惠套餐,降低客户流失率、提高收入、增加 ARPU 值(average revenue per user 每个用户平均收益),实现精准的市场营销策略定制。

欢迎大家点赞、收藏、关注、评论啦 ,由于篇幅有限,只展示了部分核心代码。

精彩专栏推荐订阅:

1. Python 毕设精品实战案例
2. 自然语言处理 NLP 精品实战案例
3. 计算机视觉 CV 精品实战案例

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Python极客之家

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值