本例中,使用用戶註冊時間(註冊天數reg_length)、活躍(最近活躍間隔天數rec_act_length、近7日活躍天數act_days)和變現(近7日日均廣告點擊量ad_pd、近7日日均閱讀量read_pd)三個維度進行聚類。

庫導入

在這裡用到了os用來處理路徑,numpy、pandas都是數據分析處理的常用庫,matplotlib作簡單的圖形看指標分佈,重頭戲就是sklearn啦,用來完成我們的聚類建模。

import os
import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import KMeans
?
mpl.rcParams[font.sans-serif] = [simhei] #指定默認字體
mpl.rcParams[axes.unicode_minus] = False # 解決保存圖像是負號-顯示為方塊的問題
?
%matplotlib inline #開啟matplotlib圖形顯示

數據導入

首先載入原數據,pandas為我們提供了多種方案,不論是csv、excel或是使用sql從資料庫中提取,都並不困難,本例中從csv讀入。

#使用pandas讀取csv生成DataFrame
data = pd.read_csv(user_value_source_data.csv)
[[reg_length,rec_act_length,act_days,ad_pd,read_pd]]

數據觀察

數據觀察是非常重要的一個步驟,通過數據觀察發現數據中的臟數據、缺失,或是不合理的異常數據,都能夠幫助我們提高數據質量,更好的實現接下來的聚類工作。

本例中的數據源共63W條用戶數據,對於這樣量級的數據,我們肯定不能逐個進行檢查和查看,要藉助於描述性統計工具和分佈圖來查看。本例中數據取自公司資料庫,較為規整,全部為數值形式,相對來說觀察和處理均處理較為簡單。

欄位屬性及描述性統計

#查看欄位相關信息,包括欄位名,數據條數,是否存在空值,欄位類型等
data.info()
?
#<class pandas.core.frame.DataFrame>
#Int64Index: 623202 entries, 0 to 732007
#Data columns (total 5 columns):
#reg_length 623202 non-null float64
#rec_act_length 623202 non-null int64
#act_days 623202 non-null int64
#ad_pd 623202 non-null float64
#read_pd 623202 non-null float64
#dtypes: float64(3), int64(2)
#memory usage: 28.5 MB
?
#查看各個欄位的描述性統計結果
data.describe()
?
# reg_length rec_act_length act_days ad_pd read_pd
# count 623202.000000 623202.000000 623202.000000 623202.000000 623202.000000
# mean 690.140974 1.756763 5.183326 0.765262 3.048918
# std 481.744966 1.562748 2.343711 1.716068 5.806001
# min 1.000000 1.000000 1.000000 0.000000 0.000000
# 25% 219.000000 1.000000 3.000000 0.000000 0.000000
# 50% 677.000000 1.000000 7.000000 0.143000 0.286000
# 75% 1119.000000 2.000000 7.000000 0.714000 3.000000
# max 1537.000000 7.000000 7.000000 14.857000 29.857000

查看數值分佈

以日均廣告點擊量欄位為例,作出數據分佈直方圖,可以看到數據偏態分佈,聚集於靠近0的位置。發現各個欄位基本都存在這種情況,因此可以考慮對數據進行對數處理,使得分佈更加均勻。

#作出該欄位的分佈直方圖
ad_pd = data[ad_pd]
plt.figure()
ad_pd.plot.hist(bins=2000,figsize=(10,6),xlim=[0,100])

數據處理

缺失值處理

當前數據並不存在缺失,可以省略這步驟,當只存在少量缺失數據時,可以直接剔除數據,對聚類的影響較小,若欄位為類型變數,有時缺失本身可以作為一類,具有一定業務含義。

此外,有時缺失值並不一定為空值,也可能以特定字元串形式出現,如NULL,空,或某一特定數值,如-1,999等,在做數據處理時要記得查看是否有類似形式數據,或某一單一數值分佈異常多。對於這種情況,可以使用replace()方法將缺失值統一成我們希望的形式。

#dropna方法,詳細方法可查看pandas文檔
data.dropna()
?
#將NULL替換為空值
data.replace(NULL,)

異常值處理

前文數據觀察中,我們看了各欄位數據的分佈,根據業務邏輯,若欄位中存在異常大的數值,則我們應考慮剔除,避免影響聚類結果。

#寫一個篩選條件即可
filter_ = ( data[ad_pd] < 100 ) &( data[read_pd] < 200 )
data = data[filter_]

數據標準化

本例中數據偏態分佈,可先做對數處理,再使用Z-Score進行標準化。

def standardize(df):
data_log = df.apply(lambda x: np.log(x+1))
Zdata = data_log.apply(lambda x: round((x-x.mean())/x.std(),4))
return Zdata

推薦閱讀:

相關文章