目的

本实验使用电信用户的通信行为数据集,进行用户信用分群和分析。由于是没有标注的训练样本,使用降维和聚类等无监督方法将用户进行分群,然后对不同群体数据进行人工分析,确定群体的信用行为特点。

数据

本实验中数据集来自开源的电信用户的通信行为数据集,共30000条数据,7个字段:入网时间、套餐价格、每月流量、每月话费、每月通话时长、欠费金额、欠费月份数。

实现代码

import pandas as pd
import numpy as np
import matplotlib.pylab as plt
%matplotlib inline
# 读取训练数据集
# 读取本地的数据信息部分
X = pd.read_csv('./telecom.csv', encoding='utf-8')
print(X.shape)
X.head()

执行结果:

# 数据预处理
# 数据标准化
from sklearn import preprocessing'''
preprocessing.scale()是按照列进行标准化计算,计算公式为:
(X_train[:,0]-X_train[:,0].mean())/X_train[:,0].std()
(X_train[:,0]-np.mean(X_train[:,0]))/np.std(X_train[:,0])//或者
'''
X_scaled = preprocessing.scale(X)  # scale操作之后的数据零均值,单位方差(方差为1)
X_scaled[0:5]

执行结果:

# 进行PCA数据降维
from sklearn.decomposition import PCA# 生成PCA实例
pca = PCA(n_components=3)  # 把维度降至3维
# 进行PCA降维
X_pca = pca.fit_transform(X_scaled)
# 生成降维后的dataframe
X_pca_frame = pd.DataFrame(X_pca, columns=['pca_1', 'pca_2', 'pca_3'])  # 原始数据由(30000, 7)降维至(30000, 3)
X_pca_frame.head()

执行结果:

# 训练简单模型
from sklearn.cluster import KMeans# KMeans算法实例化,将其设置为K=10
est = KMeans(n_clusters=10)# 作用到降维后的数据上
est.fit(X_pca)

执行结果:

KMeans(algorithm='auto', copy_x=True, init='k-means++', max_iter=300,n_clusters=10, n_init=10, n_jobs=None, precompute_distances='auto',random_state=None, tol=0.0001, verbose=0)

上述执行结果相关参数解释:

  • init='k-means++':初始簇中心的获取方法
  • max_iter=300:迭代300次停止
  • n_clusters=10:10簇
  • n_init=10:聚类从头随机10次
  • tol=0.0001:相邻两次聚类中心点距离小于0.0001停止
# 取出聚类后的标签
kmeans_clustering_labels = pd.DataFrame(est.labels_, columns=['cluster'])  # 0-9,一共10个标签# 生成有聚类后的dataframe
X_pca_frame = pd.concat([X_pca_frame, kmeans_clustering_labels], axis=1)X_pca_frame.head()

执行结果:

l

# 对不同的k值进行计算,筛选出最优的K值
from mpl_toolkits.mplot3d import Axes3D  # 绘制3D图形
from sklearn import metrics# KMeans算法实例化,将其设置为K=range(2, 14)
d = {}
fig_reduced_data = plt.figure(figsize=(12, 12))  #画图之前首先设置figure对象,此函数相当于设置一块自定义大小的画布,使得后面的图形输出在这块规定了大小的画布上,其中参数figsize设置画布大小
for k in range(2, 14):est = KMeans(n_clusters=k, random_state=111)# 作用到降维后的数据上y_pred = est.fit_predict(X_pca)# 评估不同k值聚类算法效果calinski_harabaz_score = metrics.calinski_harabasz_score(X_pca_frame, y_pred)  # X_pca_frame:表示要聚类的样本数据,一般形如(samples,features)的格式。y_pred:即聚类之后得到的label标签,形如(samples,)的格式d.update({k: calinski_harabaz_score})print('calinski_harabaz_score with k={0} is {1}'.format(k, calinski_harabaz_score))  # CH score的数值越大越好# 生成三维图形,每个样本点的坐标分别是三个主成分的值ax = plt.subplot(4, 3, k - 1, projection='3d') #将figure设置的画布大小分成几个部分,表示4(row)x3(colu),即将画布分成4x3,四行三列的12块区域,k-1表示选择图形输出的区域在第k-1块,图形输出区域参数必须在“行x列”范围ax.scatter(X_pca_frame.pca_1, X_pca_frame.pca_2, X_pca_frame.pca_3, c=y_pred)  # pca_1、pca_2、pca_3为输入数据,c表示颜色序列ax.set_xlabel('pca_1')ax.set_ylabel('pca_2')ax.set_zlabel('pca_3')

执行结果(每次的执行结果都不一样,每次的最优k值的取值也不相同,从侧面也反应了K-Means聚类很不稳定):

calinski_harabaz_score with k=2 is 5746.929406409248
calinski_harabaz_score with k=3 is 4829.511605316234
calinski_harabaz_score with k=4 is 4621.231417506531
calinski_harabaz_score with k=5 is 3932.911635328698
calinski_harabaz_score with k=6 is 3717.604661006179
calinski_harabaz_score with k=7 is 11821.594238659907
calinski_harabaz_score with k=8 is 10914.61377491437
calinski_harabaz_score with k=9 is 12799.380920854697
calinski_harabaz_score with k=10 is 10213.95953059057
calinski_harabaz_score with k=11 is 9366.264946192307
calinski_harabaz_score with k=12 is 13275.064831949414
calinski_harabaz_score with k=13 is 12613.521688107054

# 绘制不同k值对应的score,找到最优的k值
x = []
y = []
for k, score in d.items():x.append(k)y.append(score)plt.plot(x, y)
plt.xlabel('k value')
plt.ylabel('calinski_harabaz_score')

执行结果:

X.index = X_pca_frame.index  # 返回:RangeIndex(start=0, stop=30000, step=1)# 合并原数据和三个主成分的数据
X_full = pd.concat([X, X_pca_frame], axis=1)
X_full.head()

执行结果(数据合并):

使用箱形图去除异常点原理(有点类似3sigma原理):

# 按每个聚类分组
grouped = X_full.groupby('cluster')result_data = pd.DataFrame()
# 对分组做循环,分别对每组进行去除异常值处理
for name, group in grouped:# 每组去除异常值前的个数print('Group:{0}, Samples before:{1}'.format(name, group['pca_1'].count()))'''Group:0, Samples before:2628pca_1        pca_2        pca_3count  2628.000000  2628.000000  2628.000000mean      0.576172    -0.351355     0.845832std       0.570799     0.439029     0.685016min      -0.385017    -1.401124    -0.43584725%       0.136194    -0.608690     0.31977850%       0.431924    -0.462852     0.76305575%       0.908006    -0.288401     1.308205max       2.770590     1.784875     3.463926Group:0, Samples after:2240Group:1, Samples before:6684pca_1        pca_2        pca_3count  6684.000000  6684.000000  6684.000000mean     -0.814651    -0.355528     0.507371std       0.348469     0.211944     0.399592min      -1.623047    -0.856733    -0.08878725%      -1.112743    -0.454713     0.19476250%      -0.869354    -0.391802     0.40622975%      -0.540702    -0.327447     0.715365max       0.043140     0.998287     1.954580Group:1, Samples after:6009'''desp = group[['pca_1', 'pca_2', 'pca_3']].describe() # 返回每组的数量、均值、标准差、最小值、最大值等数据for att in ['pca_1', 'pca_2', 'pca_3']:# 去异常值:箱形图lower25 = desp.loc['25%', att]upper75 = desp.loc['75%', att]IQR = upper75 - lower25min_value = lower25 - 1.5 * IQRmax_value = upper75 + 1.5 * IQR# 使用统计中的1.5*IQR法则,删除每个聚类中的噪音和异常点group = group[(group[att] > min_value) & (group[att] < max_value)]result_data = pd.concat([result_data, group], axis=0)# 每组去除异常值后的个数print('Group:{0}, Samples after:{1}'.format(name, group['pca_1'].count()))
print('Remain sample:', result_data['pca_1'].count())

执行结果:

Group:0, Samples before:2628
Group:0, Samples after:2240
Group:1, Samples before:6684
Group:1, Samples after:6009
Group:2, Samples before:2919
Group:2, Samples after:2314
Group:3, Samples before:369
Group:3, Samples after:297
Group:4, Samples before:1932
Group:4, Samples after:1595
Group:5, Samples before:9179
Group:5, Samples after:7848
Group:6, Samples before:3456
Group:6, Samples after:2756
Group:7, Samples before:1194
Group:7, Samples after:1084
Group:8, Samples before:47
Group:8, Samples after:30
Group:9, Samples before:1592
Group:9, Samples after:1128
Remain sample: 25301
# 原始数据降维后的可视化
from mpl_toolkits.mplot3d import Axes3D# 生成三维图形,每个样本点的坐标分别是三个主成分的值
fig_reduced_data = plt.figure()
ax_reduced_data = plt.subplot(111, projection='3d')
ax_reduced_data.scatter(X_pca_frame.pca_1.values, X_pca_frame.pca_2.values, X_pca_frame.pca_3.values)
ax_reduced_data.set_xlabel('Component_1')
ax_reduced_data.set_ylabel('Component_2')
ax_reduced_data.set_zlabel('Component_3')

执行结果:

# 设置每个簇对应的颜色
cluster_2_color = {0: 'red', 1: 'green', 2: 'blue', 3: 'yellow', 4: 'cyan', 5: 'black', 6: 'magenta', 7: '#fff0f5',8: '#ffdab9', 9: '#ffa500'}colors_clustered_data = X_pca_frame.cluster.map(cluster_2_color)  # 簇名和颜色映射
fig_reduced_data = plt.figure()
ax_clustered_data = plt.subplot(111, projection='3d')# 聚类算法之后的不同簇数据的映射为不同颜色
ax_clustered_data.scatter(X_pca_frame.pca_1.values, X_pca_frame.pca_2.values, X_pca_frame.pca_3.values,c=colors_clustered_data)
ax_clustered_data.set_xlabel('Component_1')
ax_clustered_data.set_ylabel('Component_2')
ax_clustered_data.set_zlabel('Component_3')

执行结果:

# 筛选后的数据聚类可视化
colors_filtered_data = result_data.cluster.map(cluster_2_color)
fig = plt.figure()
ax = plt.subplot(111, projection='3d')
ax.scatter(result_data.pca_1.values, result_data.pca_2.values, result_data.pca_3.values, c=colors_filtered_data)
ax.set_xlabel('Component_1')
ax.set_ylabel('Component_2')
ax.set_zlabel('Component_3')

执行结果:

# 查看各族中的每月话费情况
monthly_Fare = result_data.groupby('cluster').describe().loc[:, u'每月话费']
monthly_Fare

执行结果:

# mean:均值;std:标准差
monthly_Fare[['mean', 'std']].plot(kind='bar', rot=0, legend=True)  # rot可以控制轴标签的旋转度数。legend是否在图上显示图例

执行结果:

# 查看各族中的入网时间情况
access_time = result_data.groupby('cluster').describe().loc[:, u'入网时间']
access_time

执行结果:

access_time[['mean', 'std']].plot(kind='bar', rot=0, legend=True, title='Access Time')

执行结果:

# 查看各族中的欠费金额情况
arrearage = result_data.groupby('cluster').describe().loc[:, u'欠费金额']
arrearage[['mean', 'std']].plot(kind='bar', rot=0, legend=True, title='Arrearage')

执行结果:

# 综合描述
new_column = ['Access_time', u'套餐价格', u'每月流量', 'Monthly_Fare', u'每月通话时长', 'Arrearage', u'欠费月份数', u'pca_1', u'pca_2',u'pca_3', u'cluster']
result_data.columns = new_column
result_data.groupby('cluster')[['Monthly_Fare', 'Access_time', 'Arrearage']].mean().plot(kind='bar')  # 每个簇的Monthly_Fare、Access_time、Arrearag的均值放在一块比较

执行结果:

数据分析结果

在对聚类结果进行分析时,需要将各种图结合起来看,做综合的分析,然后给各组打上标签。

  1. 簇‘2’、‘9’中的用户,为高消费且少欠费的用户,用户质量高,属于黄金用户;
  2. 簇‘8’的用户,虽然其消费高,但是用户欠费也最多,属于风险较大的用户群;
  3. 簇‘3’、‘4’中的用户,属于消费少、欠费多的性质,需要重点关注;
  4. 簇‘0’、‘1’、‘5’、‘6’、‘7’的用户,需要加大其的优惠力度;
  5. 在网时间的长短和消费能力的大小并不成正比;

由于聚类算法本身的局限性,在了解具体的业务后,才能做好聚类,否则很难做好。

参考

  1. https://www.jianshu.com/p/f4e4f0351f5e    --sklearn.preprocessing.scale介绍
  2. https://www.cnblogs.com/keye/p/8194539.html    --sklearn preprocessing对数据预处理
  3. https://baike.baidu.com/item/%E6%95%B0%E6%8D%AE%E6%A0%87%E5%87%86%E5%8C%96/4132085?fr=aladdin    --数据标准化定义
  4. https://blog.csdn.net/lilong117194/article/details/78561013    --数据的中心化和标准化
  5. https://www.cnblogs.com/laoniubile/p/5893286.html    --matplotlib画图
  6. https://www.6sq.net/question/545416    --箱形图
  7. https://wenku.baidu.com/view/7d6c5325cc175527072208b6.html     --3sigma

【sklearn】K-Means聚类与PCA降维实践 - 用户信用分群和分析相关推荐

  1. OpenCV的k - means聚类 -对图片进行颜色量化

    OpenCV的k - means聚类 目标 学习使用cv2.kmeans()数据聚类函数OpenCV 理解参数 输入参数 样品:它应该的np.float32数据类型,每个特性应该被放在一个单独的列. ...

  2. OpenCV官方文档 理解k - means聚类

    理解k - means聚类 目标 在这一章中,我们将了解k - means聚类的概念,它是如何工作等. 理论 我们将这个处理是常用的一个例子. t恤尺寸问题 考虑一个公司要发布一个新模型的t恤. 显然 ...

  3. 机器学习公开课笔记(8):k-means聚类和PCA降维

    K-Means算法 非监督式学习对一组无标签的数据试图发现其内在的结构,主要用途包括: 市场划分(Market Segmentation) 社交网络分析(Social Network Analysis ...

  4. python机器学习库sklearn——k均值聚类

    全栈工程师开发手册 (作者:栾鹏) python数据挖掘系列教程 k均值聚类的相关的知识内容可以参考 http://blog.csdn.net/luanpeng825485697/article/de ...

  5. K-means高维聚类与PCA降维

    K-means高维与PCA降维 K-means高维聚类 PCA 查了很多博客,发现网上给出的K-means都是二维数据,没有高维示例,所以笔者将抄来的二维模板稍修改了一下,把Python实现的K-me ...

  6. 【吴恩达】机器学习作业ex7--(k-means聚类)与(PCA降维)Python

    一.前言 此次还是分为俩个部分,第一部分是利用k-means算法进行聚类,第一部分分为俩小步骤,第一步为给好的数据集进行分类(ex7data2),第二步是利用k-means算法来对图片进行压缩,然后第 ...

  7. k means聚类算法_K-Means 聚类算法 20210108

    说到聚类,应先理解聚类和分类的区别 聚类和分类最大的不同在于:分类的目标是事先已知的,而聚类则不一样,聚类事先不知道目标变量是什么,类别没有像分类那样被预先定义出来. K-Means 聚类算法有很多种 ...

  8. k means聚类算法_一文读懂K-means聚类算法

    1.引言 什么是聚类?我们通常说,机器学习任务可以分为两类,一类是监督学习,一类是无监督学习.监督学习:训练集有明确标签,监督学习就是寻找问题(又称输入.特征.自变量)与标签(又称输出.目标.因变量) ...

  9. 特征工程之PCA降维(主成分分析)总结

    目录 1.PCA是什么 2. 算法思路 详细推算 特征值分解 优缺点 参考链接: 1.PCA是什么 PCA是什么? PCA(Principal Component Analysis)是一种常用的数据分 ...

  10. 机器学习(十四):K均值聚类(kmeans)

    k均值聚类方法是一种无监督机器学习技术,用于识别数据集中的数据对象集群.有许多不同类型的聚类方法,但k -means是最古老和最平易近人的方法之一.这些特性使得在 Python 中实现k -means ...

最新文章

  1. vue 给组件绑定原生事件
  2. Unsafe工具类的一些实用技巧,通往JVM底层的钥匙
  3. 创建cordova项目
  4. Cryptohack-RSA writeups
  5. IDA插件uEmu模拟执行
  6. 前端学习(95):ps基本操作与图片格式
  7. 面试软件测试所需要掌握的7个技能
  8. android一格一格向上的进度条,如何 使用 ProgressBar 进度条
  9. Java架构师面试题系列之Mybatis面试专题(36题,含详细答案解析)
  10. 2019支持c99吗_德国LYNX携手北京十方融科科技有限公司成功中标2019年中国联通北京市分公司4K超高清视频信号传输设备购置项目...
  11. Java字符串格式化记录
  12. 实战NSURLProtocol 拦截 APP网络请求NSURLConnection, NSURLSession, Alamofire
  13. ArrayList源码简单剖析 及与linkedlist vector 区别
  14. 在MacOS下为2K显示器开启HiDPI
  15. 推荐一款护眼的软件——f.lux。它可以随着时间,自己调节色温
  16. 19个免费的UI界面设计工具及资源
  17. 解决CesiumForUnreal加入CesiumSunSky并调整设置后场景仍然纯白的问题
  18. JAVA中的protected的访问权限只有在本类同包类和子类吗?
  19. 展望计算机未来发展趋势,计算机的未来展望
  20. HX711称重模块的使用

热门文章

  1. IIS 访问页面出现500 – 内部服务器错误的解决方案
  2. Extraneous non-emits event listeners (onJump) were passed to component but could not be automaticall
  3. ubuntu 安装chrome并禁止提示更新
  4. 20200726 T3 树高【ETT(dfs序splay)维护同色边连通块】
  5. 云盼智能快递柜提供第三方便民服务平台,解决快递业终端服务困境
  6. android 两张电信_双卡双待双核2.3 电信机皇摩托XT882评测
  7. 酷狗小程开发,项目创建(Vue)
  8. Google大数据论文GFS(Google File System)介绍
  9. 【R语言数据科学】:(三)数据基础处理(mutate、filter、select等)
  10. 微前端框架 之 qiankun