基於聚類(Kmeans)演算法實現客戶價值分析系統(電信運營商)
阿新 • • 發佈:2018-12-11
一、電信運營商–客戶價值分析
從客戶需求出發,瞭解客戶需要什麼,他們有怎麼樣的特徵, 電信運營商為客戶設定不同的優惠套餐
爭取更多的使用者:推出不同的優惠套餐 降低客戶流失率 提高收入 增加 ARPU 值(average revenue per user 每個使用者平均收益) 精準的市場營銷策略定製
二、使用聚類模型—分析專案需求
由於客戶多,消費行為複雜,很難人工對客戶打標籤,這種情況下: 採用無監督學習的聚類演算法更恰當 通過對客戶的特徵,日常消費行為進行分析,瞭解其偏好, 為降低客戶流失率和爭取新使用者提供個性化營銷依據 目標客戶: 公眾客戶 商業客戶 大客戶 初步目標 中高階使用者 中端使用者 離網趨勢使用者 其它需求使用者 通過聚類,將公眾客戶分為多個類別 聚類完成後,對分組資料的各方面做一個觀察,年齡、性別、消費情況
三、聚類模型的原理和方法
- 3.1 聚類(物以類聚,人以群分)
-
聚類(無監督) 分類(有監督,已經知道事務類別)
- 3.2 聚類效果評價標準(聚成幾個類比較合適)
-
層次聚類(
hierarchical clustering
) 是一種很直觀的演算法,一層一層地進行,把小的cluster 逐步聚攏(agglomerative clustering)),也可以將大的cluster逐步分割(divisive cluster)。逐步聚攏用的多 -
層次聚類的 dendrogram 樹
(親緣關係樹狀圖解)scipy.cluster.hierarchy.linkage
進行層次聚類的時候,可以使用scipy.cluster.hierarchy.dendrogram
-
如何切割 dendrogram 樹
四、程式碼:
4.1 資料感知
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from scipy.cluster.hierarchy import linkage,dendrogram
custinfo = pd.read_csv(r'.\\data\\custinfo.csv')
custcall = pd.read_csv(r'.\\data\\custcall.csv' )
custcall.head()
Customer_ID | Peak_calls | Peak_mins | OffPeak_calls | OffPeak_mins | Weekend_calls | Weekend_mins | International_mins | Nat_call_cost | month | |
---|---|---|---|---|---|---|---|---|---|---|
0 | K100130 | 12 | 10.587465 | 5 | 4.479312 | 0 | 0.000000 | 4.381410 | 0 | 4 |
1 | K100130 | 14 | 11.530076 | 7 | 4.878109 | 1 | 3.045756 | 4.771490 | 0 | 6 |
2 | K100130 | 10 | 9.109470 | 4 | 3.854007 | 0 | 0.000000 | 3.769771 | 0 | 1 |
3 | K100130 | 12 | 10.530956 | 5 | 4.455404 | 0 | 0.000000 | 4.358024 | 0 | 3 |
4 | K100130 | 11 | 9.507319 | 4 | 4.022327 | 0 | 0.000000 | 3.934413 | 0 | 2 |
4.2 資料預處理
# 資料聚合:--對整個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%)
desc = data.describe()
print(desc)
gender_cnt = pd.value_counts(data['Gender'])
print(gender_cnt)
tariff_cnt = pd.value_counts(data['Tariff'])
print(tariff_cnt)
handset_cnt = pd.value_counts(data['Handset'])
print(handset_cnt)
for col in data.columns:
if not col in [u'Gender',u'Tariff',u'Handset']:
fig = plt.figure()
ax=fig.add_subplot(1,1,1)
data[col].hist(bins=20)
ax.set_title(col)
fig.show()
4.3 模型建立
data_feature = data.drop('Age',1)
data_feature = data_feature.drop('Gender',1)
data_feature = data_feature.drop('Tariff',1)
data_feature = data_feature.drop('Handset',1)
data_zs = 1.0*(data_feature - data_feature.mean())/data_feature.std() #資料標準化
Z = linkage(data_zs, method = 'ward',
metric = 'euclidean') #譜系聚類圖(歐式距離)
P = dendrogram(Z, 0) #畫譜系聚類圖
plt.show()
k = 4 #聚類的類別
iteration = 500 #聚類最大迴圈次數
model = KMeans(n_clusters = k,
n_jobs = 1,
max_iter = iteration) #分為k類,併發數1,數值大系統卡死
model.fit(data_zs) #開始聚類
r1 = pd.Series(model.labels_).value_counts() #統計各個類別的數目
r2 = pd.DataFrame(model.cluster_centers_) #找出聚類中心
r = pd.concat([r2, r1], axis = 1) #橫向連線(0是縱向),得到聚類中心對應的類別下的數目
r.columns = list(data_zs.columns) + [u'class'] #重命名錶頭
print(r)
#類中心比較
# r[cols].plot(figsize=(10,10))
r2.columns = list(data_feature.columns)
r2.plot(figsize=(10,10))
plt.show()
#詳細輸出原始資料及其類別
res = pd.concat([data,
pd.Series(model.labels_, index = data.index)],
axis = 1) #詳細輸出每個樣本對應的類別
res.columns = list(data.columns) + [u'class'] #重命名錶頭
res.to_excel('.\\data\\result.xls') #儲存結果
pd.crosstab(res['Tariff'],res['class'])
pd.crosstab(res['Handset'],res['class'])
pd.crosstab(res['Gender'],res['class'])
res[[u'Age',u'class']].hist(by='class')
res[u'Age'].groupby(res['class']).mean()
4.4 概率密度圖
def density_plot(data): #自定義作圖函式
plt.rcParams['axes.unicode_minus'] = False #用來正常顯示負號
p = data.plot(kind='kde',
linewidth = 2,
subplots = True,
sharex = False,
figsize=(10,15) )
[p[i].set_ylabel(u'密度',fontproperties='SimHei') for i in range(k)]
plt.legend()
return plt
"""
看密度圖的話可以看到更多的細節,但是對比效果不明顯。
pd_: 概率密度圖檔名字首
"""
pic_output = '.\\data\\pd_'
for i in range(k):
density_plot(data[res[u'class']==i]).savefig(u'%s%s.png' %(pic_output, i))