一首繁、分析背景
電商平臺的發(fā)展取決于用戶坏为。電商平臺如何讓用戶點擊里面的內容,就是留住用戶的第一步爷怀。電商平臺的首頁往往會分成好幾個模塊阻肩,比如促銷活動廣告,而這些模塊都是代表了部分商品运授。如果平臺的活動廣告不是用戶喜歡的扫沼,那么這個活動就沒有意義蔫耽。準確判斷用戶是不是喜歡廣告中的商品,可以大大改善廣告點擊情況。
二侨糟、分析目的
現有阿里云天池(https://tianchi.aliyun.com/dataset/dataDetail?dataId=56)提供的淘寶用戶的廣告點擊數據。數據中包含了四張表同波,分別為用戶行為日志behavior_log(簡稱為bl)剃诅、原始樣本骨架raw_sample(簡稱為rs)、廣告基本信息表ad_feature(簡稱為af)纺讲、用戶基本信息表user_profile(簡稱為up)擂仍,具體字段說明如表1:
我們利用現有數據,使用用戶畫像分析和隨機森林熬甚,來查看用戶的廣告點擊偏好和預測raw_sample表中用戶是否點擊廣告逢渔。
三、分析方法
1. 用戶畫像分析
針對用戶的特征乡括,分析什么種類的用戶喜歡什么類型的廣告肃廓。
2. 隨機森林預測
使用數據挖掘方法智厌,將數據分為訓練集和測試集,通過訓練分類預測模型來預測用戶是否點擊廣告盲赊。
四铣鹏、數據準備——數據清洗
1. user_profile表
查看表結構:
up = pd.read_csv(r'E:\datafile\ad_clik\user_profile.csv',index_col='userid')
up.info()?
up.describe()
發(fā)現無重復值、異常值和格式錯誤值角钩,但cms_segid吝沫、cms_group_id、pvalue_level和new_user_class_level有缺失值递礼。
對于缺失值處理:① 刪除 ②增補
此次惨险,我們刪除了特征缺失很多的501條數據;對于僅城市層級缺失的數據脊髓,用隨機森林方法進行增補辫愉;其他缺失情況的數據,按照全非空數據的比例進行增補将硝。
2. ad_feature表
查看表結構恭朗,發(fā)現brand字段有缺失。通過adgroup_id字段連接raw_sample表依疼,增補對應的brand痰腮。但是發(fā)現同一個adgroup_id有兩個brand的情況,直接刪除律罢。
3. raw_sample表
無缺失值膀值、重復值、異常值和格式錯誤值误辑。
五沧踏、數據分析
1. up表中用戶特征的分布情況
1.1 性別、是否大學生
以性別為例:
gender = up['final_gender_code'].value_counts()
# print(gender)
# 女性用戶有684026人巾钉,男性用戶有377241人
plt.figure()
plt.grid(alpha=0.4)
gender.plot(kind='bar')
plt.title('up表的性別分布情況',fontproperties=my_font)
plt.xlabel('性別(1為男翘狱,2為女)',fontproperties=my_font)
plt.ylabel('人數',fontproperties=my_font)
plt.show()
結論:女性淘寶用戶占比很大,淘寶用戶主力是非大學生砰苍。
1.2 年齡層
結論:年齡層分布基本符合高斯分布潦匈。年齡層為3的用戶最多,最少的為6赚导。我們可以推測出年齡層為3的是在30歲左右的青年历等。
1.3 消費檔次
中檔消費用戶最多,其次為低檔辟癌,高檔的最少。
1.4 購物深度
淘寶深度用戶占絕大多數荐捻,說明淘寶的用戶忠誠度方面做得很好黍少,與現實相符寡夹。
1.5 城市層級
城市層級為2的用戶最多,最少的是層級為1的厂置∑刑停可以推測,層級為2的城市是二線城市昵济。而一線城市為何是最少的智绸?一個解釋就是一線城市數本身就比其他線城市少。
2. af表的廣告屬性分布情況
2.1 價格
首先我們將價格按照等距離分桶访忿,查看分桶后的分布情況瞧栗。
p = af['price']
bins = np.arange(0,600,10)
bins = pd.cut(p,bins)
bins = p.groupby(bins).count()
plt.figure(figsize=(30,8))
bins.plot(kind='bar')
plt.show()
我們可以發(fā)現,0-10海铆、90-100迹恐、190-200、290-300卧斟、390-400殴边、490-500是比周圍價格區(qū)間的廣告單元的數量都高。因為廣告商品的價格都很喜歡198,99,98等類型的價格珍语。至于價格在0-10的廣告數量很多锤岸,是因為淘寶中此類商品本身就特別多。
2.2 商品類目
我們查看商品類目出現的個數:
cate = af['cate_id'].value_counts()
bins = np.arange(0,200,10)
bins = pd.cut(cate,bins)
bin_counts = cate.groupby(bins).count()
plt.figure(figsize=(8,8))
bin_counts.plot(kind='pie')
plt.show()
#結果表明:在這個時間段板乙,打廣告的商品類目大都比較零散是偷,只有10個以內的廣告單元的cate_id占了將近一半。
2.3 廣告計劃
在這個時間段內亡驰,大多數廣告計劃各不相同晓猛。
2.4 廣告主
各個廣告對應的廣告主也各不相同。
2.5 廣告所屬品牌
廣告所屬品牌也很多凡辱,這也說明了淘寶中的商家并不存在壟斷情況戒职,市場還是良好的。
3. 用戶的廣告點擊偏好
3.1 不同用戶特征的商品類目偏好
在這里透乾,我們根據點擊量情況洪燥,查看不同類用戶最經常點擊的廣告商品類目。
df_clk = df[df['clk']==1]
u = ['final_gender_code','age_level','pvalue_level','shopping_level','occupation','new_user_class_level ']
c = [[1,2],[1,2,3,4,5,6],[1,2,3],[1,2,3],[0,1],[1,2,3,4]]
m = 0
for i in u:
? ? cate_clk = df_clk.groupby([i,'cate_id']).count()['clk'].reset_index()
? ? s = c[m]
? ? m += 1
? ? for n in s:
? ? ? ? print(cate_clk[cate_clk[i]==n].sort_values(by='clk',ascending=False).head(1))
print('ok')
我們發(fā)現乳乌,無論是哪種類型的用戶捧韵,點擊量最高的廣告商品類目都是6261。這需要區(qū)分清楚6261類廣告是真的受用戶偏愛汉操,還是它只是曝光量很高但點擊率不高再来。
我們先查看每個商品類目的點擊量和點擊率情況:
cate_y = df['cate_id'][df['clk']==1].value_counts().reset_index()
cate_y.columns = ['cate_id','clk']
# cate_n = df['cate_id'][df['clk']==0].value_counts().reset_index()
# cate_n.columns = ['cate_id','nclk']
cate_sum = df['cate_id'].value_counts().reset_index()
cate_sum.columns = ['cate_id','counts']
cate = pd.merge(cate_y,cate_sum,how='outer',on='cate_id')
cate = cate.fillna(0)
cate['clk_ratio'] = cate['clk']/cate['counts']
cate['clk_ratio'] = cate['clk_ratio'].map(lambda x:('%.4f')%x)
cate['clk_ratio'] = cate['clk_ratio'].astype(float)
cate.describe([0.1,0.3,0.5,0.7,0.8,0.9,0.95])
從點擊率的分布情況,可以看出平均點擊率為0.0476,大多數商品類目的點擊率都不是很高芒篷。
cate[cate['cate_id']==6261]
查看6261的點擊率為0.0605搜变,在分位點70%以上,這類商品不僅點擊量高而且點擊率也高针炉,說明它們的廣告還是很吸引用戶的挠他。
再進一步,在最偏好的商品類目中篡帕,查看最喜歡的品牌:
u = ['final_gender_code','age_level','pvalue_level','shopping_level','occupation','new_user_class_level ']
c = [[1,2],[1,2,3,4,5,6],[1,2,3],[1,2,3],[0,1],[1,2,3,4]]
m = 0
for i in u:
? ? cate_clk = df_clk[df_clk['cate_id']==6261].groupby([i,'brand']).count()['clk'].reset_index()
? ? s = c[m]
? ? m += 1
? ? for n in s:
? ? ? ? print(cate_clk[cate_clk[i]==n].sort_values(by='clk',ascending=False).head(1))
print('ok')
結果如下:
總體來看殖侵,品牌為234846、商品類目為6261的廣告最常被用戶點擊镰烧。只有年齡層為1和2拢军,以及大學生用戶最喜歡的品牌是82527。
同樣重復上面步驟拌滋,查看點擊率情況:
按品牌劃分的廣告點擊率平均為0.0412朴沿;品牌為234846的廣告點擊率為0.0608,在分位點75%左右败砂;品牌為82527的點擊率為0.0685赌渣,超過分為點80%。說明在商品類目為6261中昌犹,絕大多數用戶最常點擊品牌為234846的廣告坚芜;而對于低年齡層的用戶和大學生用戶來說,最喜歡品牌為82527的廣告斜姥,可以推測這個品牌很受年輕人喜愛鸿竖。
3.2 不同用戶特征的價格偏好
u = ['final_gender_code','age_level','pvalue_level','shopping_level','occupation','new_user_class_level ']
c = [[1,2],[1,2,3,4,5,6],[1,2,3],[1,2,3],[0,1],[1,2,3,4]]
m = 0
for i in u:
? ? cate_clk = df_clk.groupby([i,'price']).count()['clk'].reset_index()
? ? s = c[m]
? ? m += 1
? ? for n in s:
? ? ? ? print(cate_clk[cate_clk[i]==n].sort_values(by='clk',ascending=False).head(1))? ? ? ?
print('ok')
結果如下:
點擊的廣告價格分布情況:
結果表明:淘寶用戶經常點擊價格為198的廣告。而低年齡層用戶消費能力低一些铸敏,最喜歡點擊98缚忧、99左右價格的廣告。結合價格分布情況杈笔,側面驗證了大多數淘寶用戶的消費層次是中檔的闪水。
3.3?不同用戶特征的廣告活動計劃偏好
與上面代碼類目,得到以下結果:
其中蒙具,活動計劃為118601的廣告最吸引用戶球榆,尤其是女性用戶和深度用戶。
4. 用戶的廣告點擊情況預測
由于數據量太大禁筏,我們只選取三天的數據持钉,進行預測。
4.1 數據轉換
由于廣告屬性的cate_id篱昔、campaign_id每强、customer和brand無法直接進行建模,需要進行數據轉換。此處空执,按照廣告屬性的點擊量和點擊率情況窘茁,將它們進行等頻分桶,分成十個等級脆烟,轉換成8個新變量。
以cate_id為例:
# 先計算cate_id的點擊量和點擊率
cate_y = df['cate_id'][df['clk']==1].value_counts().reset_index()
cate_y.columns = ['cate_id','clk']
# cate_n = df['cate_id'][df['clk']==0].value_counts().reset_index()
# cate_n.columns = ['cate_id','nclk']
cate_sum = df['cate_id'].value_counts().reset_index()
cate_sum.columns = ['cate_id','counts']
cate = pd.merge(cate_y,cate_sum,how='outer',on='cate_id')
cate = cate.fillna(0)
cate['clk_ratio'] = cate['clk']/cate['counts']
cate['clk_ratio'] = cate['clk_ratio'].map(lambda x:('%.4f')%x)
cate['clk_ratio'] = cate['clk_ratio'].astype(float)
# 點擊量分桶
cate['cate_clk_bins'] = pd.qcut(cate['clk'],13,duplicates='drop',labels=[1,2,3,4,5,6,7,8,9,10])
cate['cate_clk_bins'] = cate['cate_clk_bins'].astype(int)
# cate['clk_bins'].unique().size
## 點擊率分桶
cate['cate_clk_ratio_bins'] = pd.qcut(cate['clk_ratio'],13,duplicates='drop',labels=[1,2,3,4,5,6,7,8,9,10])
cate['cate_clk_ratio_bins'] = cate['cate_clk_ratio_bins'].astype(int)
# cate['clk_ratio_bins'].unique().size
cate.drop(['clk','counts','clk_ratio'],axis=1,inplace=True)
4.2 相關分析和特征篩選
對于定類數據之間的相關分析房待,我們使用卡方檢驗邢羔;對于定類和定距數據,我們使用eta系數桑孩。
from sklearn.feature_selection import chi2,SelectKBest
train_x = df_012.drop('clk',axis=1).values
train_y = df_012['clk'].tolist()
selector = SelectKBest(chi2,k='all')
selector.fit(train_x, train_y)
scores = selector.scores_
print(scores)?
pvalues = selector.pvalues_
print(pvalues)? #p值都小于0.05
selector = SelectKBest(chi2,k=10)
v = selector.fit(train_x, train_y).get_support(indices=True)
print(v)
scores = selector.scores_
print(scores)?
根據特征得分拜鹤,只保留10個定類特征,刪除了'pid','clk','age_level','pvalue_level','shopping_level','occupation','new_user_class_level ','cate_clk_bins'這些特征流椒。
同時使用SPSS計算了eta系數敏簿,結果顯示它們相關。
4.2 訓練數據并預測
選擇使用隨機森林模型宣虾,進行用戶廣告點擊情況預測惯裕。
首先將三天的數據切分成訓練集和測試集:
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score,train_test_split
todrop = ['pid','clk','age_level','pvalue_level','shopping_level','occupation','new_user_class_level ','cate_clk_bins']
x = df_012.drop(todrop,axis=1).values
y = df_012['clk'].tolist()
train_X,test_X, train_y, test_y = train_test_split(x,y,test_size=1/5)
然后對訓練集進行交叉驗證訓練模型:
clf1 = RandomForestClassifier(n_estimators=10,max_depth=None,min_samples_split=2,random_state=0)
scores = cross_val_score(clf1,train_X,train_y,scoring='accuracy',cv=5)
clf1.fit(train_X,train_y)
print(scores.mean())
print(scores.std())?
以精確率為得分,訓練結果平均得分為0.9401836626955434绣硝,標準差為0.00010639743381447468蜻势。
模型訓練結束之后,使用預測集預測:
y_pred = clf1.predict(test_X)
最后鹉胖,做一個預測結果驗證握玛,計算準確率:
test = pd.DataFrame([y_pred,test_y],index=['y_pred','test_y'])
test = test.T
print('預測準確率:',test[(y_pred==test_y)]['y_pred'].size/test['y_pred'].size)? # 0.9404274614218243