目錄python
window8.1,python3.7,Tableau2019.1網絡
該項目的數據集來源於天池,是由阿里巴巴提供的一個淘寶用戶行爲數據集,其中包含了2017年11月25日至2017年12月3日之間,一百萬個隨機用戶的全部用戶行爲(行爲包括點擊、購買、加購、收藏)數據,有關每一個字段的介紹以下所示:
其中,用戶行爲類型共有四種,具體的說明見下表:
app
--分析思路:從what、why和how這三個角度對用戶行爲進行分析,即什麼是用戶行爲分析?爲何進行用戶行爲分析?如何進行用戶行爲分析?而其中的why做爲咱們的重點解釋對象。
--分析目的:經過對淘寶用戶的點擊、加購、收藏、購買行爲進行深刻研究,讓企業或者店鋪更好地瞭解用戶行爲習慣,爲網絡營銷提供指導意義,也爲取得新成績打下堅實的基礎。echarts
用戶行爲分析,能夠看作是分析用戶行爲,而用戶行爲包括5w2h,即時間、地點、人物、原由、通過、結果和金錢,也就是說分析用戶行爲則是分析這7個要素產生的數據,基於這些數據進行統計、分析,從中發現用戶使用產品的規律,並將這些規律與產品、渠道、價格和促銷等相結合,從而發現當前所存在的問題,併爲後續進一步改進和優化提供依據,這將有助於企業提升平臺轉化率,進而提高企業的收益。ide
從時間的維度來看,經過對用戶行爲路徑的分析能夠幫助企業發現:用戶從哪裏來?用戶作了什麼操做?用戶從哪裏流失的?用戶爲何流失?
從空間的維度來看,根據用戶的行爲特徵構建用戶畫像,進而實現精準營銷和提高用戶體驗,達到提高企業盈利的目的。學習
此環節正是咱們此次項目的重中之重,咱們主要經過如下三種模型進行用戶行爲分析:
優化
數據總容量爲1億多,我這裏選擇了500萬來進行分析.excel
import pandas as pd df = pd.read_csv(r'D:\Data\UserBehavior.csv', nrows=5000000, header=None, names=['用戶ID','商品ID','商品類目ID','行爲類型','時間戳'])
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 5000000 entries, 0 to 4999999
Data columns (total 5 columns):
用戶ID int64
商品ID int64
商品類目ID int64
行爲類型 object
時間戳 int64
dtypes: int64(4), object(1)
memory usage: 190.7+ MB
數據維度500萬×5,1個字符串類型和4個64位整型數據,500萬數據大小190.7MBcode
df.describe() df.describe(include=['O'])
因爲該數據集中會出現一個用戶ID屢次瀏覽的狀況,所以這裏「用戶ID」的count數和max值不表明用戶數量,「商品ID「和「商品類目ID「相似
用戶行爲類型分爲4種,其中瀏覽量pv最多,達到4475232次orm
對於重複值,直接採用刪除的方式處理。
df.drop_duplicates(keep='last',inplace=True)
在處理缺失值以前,先查看有多少缺失值
df.isnull().sum()
用戶ID 0
商品ID 0
商品類目ID 0
行爲類型 0
時間戳 0
dtype: int64
能夠看到沒有缺失值,所以也就不用處理了
根據數據介紹,可知道數據的日期包含在2017年11月25日至2017年12月3日之間,所以可根據這條規則對數據進行異常處理
import time start_time = time.mktime(time.strptime("2017-11-25 00:00:00",'%Y-%m-%d %H:%M:%S')) end_time = time.mktime(time.strptime("2017-12-03 23:59:59",'%Y-%m-%d %H:%M:%S')) df = df[(df.時間戳 >=int(start_time)) & (df.時間戳<= int(end_time))]
將時間戳轉換爲datetime格式
df['時間戳'] = df.時間戳.apply(lambda x: datetime.datetime.fromtimestamp(x))
提取出日期和時間
df['日期'] = df.時間戳.dt.date df['時間'] = df.時間戳.dt.time df['小時'] = df.時間戳.dt.hour
截止目前,咱們的數據預處理工做就完成了,可查看處理結果
df.head()
1.日pv、日人均pv和日uv
import numpy as np from pyecharts import Line, Overlap pv_day = df[df.行爲類型 == 'pv'].groupby('日期')['行爲類型'].count() uv_day = df[df.行爲類型 == 'pv'].drop_duplicates(['用戶ID','日期']).groupby('日期')['用戶ID'].count() attr = pv_day.index v1 = pv_day.values v2 = uv_day.values line1 = Line('日pv、日人均pv和日uv對比圖') line1.add('日pv(單位:萬次)', attr, np.around(v1/10000,decimals=2), mark_point=["max", "min"], mark_line=['average'], legend_pos='right') line1.add('日人均pv(單位:次)', attr, np.around(v1/v2, decimals=2), mark_point=['max','min'], mark_line=['average'], yaxis_max=100, yaxis_name='pv', yaxis_name_pos='end', yaxis_name_gap=15, legend_pos='right', legend_top='3%') line2 = Line() line2.add('日uv(單位:萬人)', attr, np.around(v2/10000, decimals=2), mark_point=["max",'min'], mark_line=['average'], yaxis_name='uv', yaxis_name_pos='end', yaxis_name_gap=15) overlap = Overlap() overlap.add(line1) overlap.add(line2, is_add_yaxis=True, yaxis_index=1) overlap.render()
--日pv和日uv二者走勢相相似,也進一步說明日人均pv波動較平緩,其平均水平爲13.34;
--日pv和日uv均呈現上升趨勢,且均在12月2日忽然升高至九日內最高水平,而12月2日是週六,但11月25日也是週六,所以可能不是週末的緣由,又因爲12月2日距離雙十一較近且多數人會在雙十一購買近期所需物品,所以初步推測12月2日~3日的忽然升高是由於商家進行促銷、宣傳推廣等活動。
2.日新增uv和日新增uv的pv
from pyecharts import Bar, Line, Overlap from copy import deepcopy import datetime df_pv = df[df.行爲類型 == 'pv'] s = set() days = [] nums = [] add_pv = [] for date in df_pv['日期'].unique(): num1 = len(s) s1 = deepcopy(s) ids = df_pv[df_pv.日期 == date]['用戶ID'].values.tolist() for i in ids: s.add(i) add_users = s - s1 add_users_pvs = df[(df.用戶ID.isin(add_users)) & (df.行爲類型 == 'pv')].groupby('日期', as_index=False)['行爲類型'].count() add_users_pv = int(add_users_pvs[add_users_pvs.日期 == date]['行爲類型'].values) num2 = len(s) add_pv.append(add_users_pv) days.append(date) nums.append(num2-num1) df_new_uv = pd.DataFrame({'日期': days, '新增訪客數': nums, '新增訪客的瀏覽量': add_pv}) attr = df_new_uv.日期 v = df_new_uv.新增訪客數 w = df_new_uv.新增訪客的瀏覽量 bar = Bar('日新增uv和日新增uv的pv對比圖') bar.add('日新增uv', attr, v, is_label_show=True, yaxis_formatter=" 人", legend_pos='right', legend_top='3%', label_pos='outside') line = Line() line.add('日新增uv的pv', attr, w, yaxis_formatter=" 次",is_label_show=True, yaxis_max=700000, label_pos='inside') overlap = Overlap() overlap.add(bar) overlap.add(line, is_add_yaxis=True, yaxis_index=1) overlap.render()
日新增uv和日新增uv的pv均呈現明顯降低趨勢,且在12月2日新增uv的人均pv爲627/62=10.11(低於日人均pv的平均水平),說明日pv的忽然升高不是由12月2日當日新增的uv帶來的,而是由老uv帶來的,另外,12月2日新增uv爲62人,環比增加-0.44,從側面反映了這次活動的目的可能不是拉新。
1.時活躍用戶數
hour_active = df.drop_duplicates(['用戶ID', '小時']).groupby('小時')['用戶ID'].count() line = Line('時活躍用戶折線圖') line.add('', hour_active.index, hour_active.values, mark_point=['max', 'min'], mark_line=['average'], yaxis_formatter=' 人') line.render()
19時~22時爲用戶活躍高峯期, 而2時~5時則爲用戶活躍低峯期,可在用戶活躍高峯期加大活動宣傳力度。
2.日活躍用戶數
day_active = df.drop_duplicates(['用戶ID', '日期']).groupby('日期')['用戶ID'].count() day_active line = Line('日活躍用戶折線圖') line.add('', day_active.index, day_active.values, is_label_show=True, yaxis_formatter=' 人') line.render()
日活躍用戶數呈現明顯的增加趨勢,且在12月2日取得最大值,說明這次活動的目的多是促活。
from datetime import timedelta def get_nday_retention_rate(df, n): users2 = set() days = [] nday_retentions = [] dates = df.日期.unique()[:-n] for date in dates: users1 = deepcopy(users2) ids = df[df.日期 == date].用戶ID.values.tolist() for i in ids: users2.add(i) users = users2 - users1 nday_users = df[df.日期 == date + timedelta(days=n)].用戶ID.unique() counts = 0 for nday_user in nday_users: if nday_user in users: counts += 1 nday_retention_rate = counts / len(users) nday_retentions.append(nday_retention_rate) days.append(date) df_retention_rate = pd.DataFrame({'日期': days, 'n日留存率': nday_retentions}) return df_retention_rate retention_rate1 = get_nday_retention_rate(df, 1) retention_rate2 = get_nday_retention_rate(df, 2) retention_rate3 = get_nday_retention_rate(df, 3) retention_rate4 = get_nday_retention_rate(df, 4) retention_rate5 = get_nday_retention_rate(df, 5) retention_rate6 = get_nday_retention_rate(df, 6) retention_rate7 = get_nday_retention_rate(df, 7) line = Line('留存率對比分析圖') line.add('7日留存', retention_rate7.日期, retention_rate7.n日留存率) line.add('6日留存', retention_rate6.日期, retention_rate6.n日留存率) line.add('5日留存', retention_rate5.日期, retention_rate5.n日留存率) line.add('4日留存', retention_rate4.日期, retention_rate4.n日留存率) line.add('3日留存', retention_rate3.日期, retention_rate3.n日留存率) line.add('2日留存', retention_rate2.日期, retention_rate2.n日留存率) line.add('第二天留存', retention_rate1.日期, retention_rate1.n日留存率, legend_pos='right') line.render()
--就時間窗口來講,第二天留存和3日留存均表現出先減後增的趨勢,而7日留存則相比以前略有減小;
--就某一天來講,11月25日新增的活躍用戶3日留存<第二天留存<7日留存,11月26日新增的活躍用戶第二天留存<3日留存<7日留存,且其餘日期3日留存均大於第二天留存。
整體來講,留存呈現增加的趨勢,反映出用戶粘性在上升。
1.時購買行爲
hour_buy_user_num = df[df.行爲類型 == 'buy'].drop_duplicates(['用戶ID', '小時']).groupby('小時')['用戶ID'].count() hour_active_user_num = df.drop_duplicates(['用戶ID', '小時']).groupby('小時')['用戶ID'].count() hour_buy_rate = hour_buy_user_num / hour_active_user_num attr = hour_buy_user_num.index v1 = hour_buy_user_num.values v2 = hour_buy_rate.values line1 = Line('時購買行爲分析') line1.add('購買人數', attr, v1, mark_point=['max', 'min'], yaxis_formatter=' 人') line2 = Line() line2.add('購買率', attr, np.around(v2, 3), mark_point=['max', 'min']) overlap = Overlap() overlap.add(line1) overlap.add(line2, is_add_yaxis=True, yaxis_index=1) overlap.render()
購買人數和購買率的走勢大體類似,且均呈現明顯的雙峯走勢,其中21時購買人數最多,而10時購買率最高,應當繼續保持10時的活動,加大21時的活動力度。
2.日購買行爲
day_buy_user_num = df[df.行爲類型 == 'buy'].drop_duplicates(['用戶ID', '日期']).groupby('日期')['用戶ID'].count() day_active_user_num = df.drop_duplicates(['用戶ID', '日期']).groupby('日期')['用戶ID'].count() day_buy_rate = day_buy_user_num / day_active_user_num attr = day_buy_user_num.index v1 = day_buy_user_num.values v2 = day_buy_rate.values line1 = Line('日購買行爲分析') line1.add('購買人數', attr, v1, mark_point=['max', 'min'], yaxis_formatter=' 人') line2 = Line() line2.add('購買率', attr, np.around(v2, 3), mark_point=['max', 'min']) overlap = Overlap() overlap.add(line1) overlap.add(line2, is_add_yaxis=True, yaxis_index=1) overlap.render()
在12月1日以前,購買人數和購買率走勢相相似,而在12月1日以後購買人數有所增長,但與以前相比購買率卻在減小,商家應當優化產品自己並加大宣傳推廣。
3.九日復購率
df_rebuy = df[df.行爲類型 == 'buy'].drop_duplicates(['用戶ID', '時間戳']).groupby('用戶ID')['時間戳'].count() df_rebuy[df_rebuy >= 2].count() / df_rebuy.count()
0.6323078771856036
若是以0.6做爲合格標準的話,說明用戶忠誠度表現通常,有大幅增加空間。
4.三日復購率和回購率
#計算復購率 for m, n in zip(range(1, 10), df.日期.unique()): if m % 3 == 0: df.loc[(df.日期 + timedelta(days=0) <= n) & (df.日期 + timedelta(days=2) >= n), '日期1'] = n df.日期1.unique() df_rebuy = df[df.行爲類型 == 'buy'].drop_duplicates(['用戶ID', '時間戳']).groupby(['日期1', '用戶ID'], as_index=False)['行爲類型'].count() df_rebuy_rate = df_rebuy[df_rebuy.行爲類型 >= 2].groupby('日期1')['用戶ID'].count() / df_rebuy.groupby('日期1')['用戶ID'].count() #計算回購率 days = [] back_buy_rates = [] for i in range(0, 2): df_buy_users = df[df.行爲類型 == 'buy'].drop_duplicates(['用戶ID', '時間戳']).groupby(['日期1'])['用戶ID'].unique() users_id = df_buy_users[i] counts = 0 for user in users_id: if user in df_buy_users[i+1]: counts += 1 df_back_buy_rate = counts / len(df_buy_users[i]) back_buy_rates.append(df_back_buy_rate) days.append(df_buy_users.index[i]) df_back_buy = pd.DataFrame({'日期': days, '回購率': back_buy_rates}) #繪製折線圖 line = Line('用戶每三日復購和回購行爲分析') line.add('回購率', df_back_buy.日期, np.around(df_back_buy.回購率, 3), is_label_show=True) line.add('復購率', df_rebuy_rate.index, np.around(df_rebuy_rate.values, 3), is_label_show=True) line.render()
--用戶回購率總體高於復購率,其波動性也明顯強於復購率;
--用戶復購率呈現先減後增的趨勢,而用戶回購率則是增長趨勢 , 即第二週期購買用戶的忠誠度較第一期高,總體說明用戶忠誠度在增長。
from pyecharts import Funnel pv_users = df[df.行爲類型 == 'pv']['用戶ID'].count() fav_users = df[df.行爲類型 == 'fav']['用戶ID'].count() cart_users = df[df.行爲類型 == 'cart']['用戶ID'].count() buy_users = df[df.行爲類型 == 'buy']['用戶ID'].count() attr = ['點擊', '加入購物車', '收藏', '購買'] values = [np.around((pv_users / pv_users * 100), 2), np.around((cart_users / pv_users * 100), 2), np.around((fav_users / pv_users * 100), 2), np.around((buy_users / pv_users * 100), 2)] funnel = Funnel("用戶行爲轉化漏斗", title_pos='center')#width=600, height=400, funnel.add( "", attr, values, is_label_show=True, label_formatter = '{b} {c}%', label_pos="outside", is_legend_show = False, ) funnel.render()
--總的點擊量中,有6.25%加入購物車,有3.24%收藏,而到最後只有2.24%購買,總體來看,購買的轉化率最低,有很大的增加空間;
--就顏色來看,紅色部分的變化最大,即「點擊-加入購物車「這一環節的轉化率最低,按照「點擊-加入購物車-收藏-購買」這一用戶行爲路徑,咱們可經過優化「點擊-加入購物車」這一環節進而提高購買的轉化率。
R:Recency(最近一次消費),F:Frequency(消費頻次),M:Monetary(消費金額)
因爲咱們的數據集中沒有消費金額相關數據,所以這裏就R和F對客戶價值進行分析
from datetime import date nowdate = date(2017, 12, 5) recent_buy_date = df[df.行爲類型 == 'buy'].groupby('用戶ID')['日期'].apply(lambda x: x.sort_values().iloc[-1]) recent_buy_time = (nowdate - recent_buy_date).map(lambda x: x.days) fre_buy = df[df.行爲類型 == 'buy'].drop_duplicates(['用戶ID', '時間戳']).groupby('用戶ID')['日期'].count() rf_module = pd.DataFrame({'用戶ID': recent_buy_time.index, 'recency': recent_buy_time.values, 'frequency': fre_buy.values}) rf_module['recency_avg'] = rf_module.recency.mean() rf_module['frequency_avg'] = rf_module.frequency.mean() rf_module.to_excel(r'E:\Data\data2.xlsx')
保存至Excel文件,而後經過Tableau繪製波士頓矩陣以下所示:
--第一象限(重要價值用戶):該象限用戶消費頻次高、最近一次消費近,應當繼續保持並給予支持;
--第二象限(重點保持用戶):該象限用戶消費頻次高、最近一次消費遠,可經過電話、短信等方式主動聯繫促進最近消費;
--第三象限(重點挽留用戶):該象限用戶消費頻次低、最近一次消費遠,可經過贈送禮品、加大折扣等方式進行挽回;
--第四象限(重點發展用戶):該象限用戶消費頻次低、最近一次消費近,可經過發放優惠券、捆綁銷售等方式增長用戶購買頻次。
對比12月2日~12月3日與上一個週末的日pv、日uv和日活躍用戶數,均發現有明顯的上升趨勢,且上升均是由老用戶帶來的,反映出老用戶忠誠度表現不錯,同時也說明了這兩天的促活活動產生了效果;
在天天的19時~22時爲用戶活躍高峯期,購買人數也最多,購買率略低;而在10時用戶活躍度較低,購買人數也略低,但用戶購買率卻最高,所以就購買率來講,10時活躍用戶產生的價值較高,應當對10時活躍用戶的活動力度繼續保持並給予支持,重點發展19~22時的活躍用戶。
在「點擊-加入購物車-收藏-購買」轉化漏斗中:就總體來講,購買轉化率爲2.24%表現最差,有很大的增加空間;就各環節來講,「點擊-加入購物車」環節的轉化率爲6.25%表現最低,能夠經過優化這一環節的轉化率,來提高總體的購買轉化率。
商家可根據RF模型的分析結果,對不一樣羣體的用戶進行精準營銷,達到利益最大化。
聲明:本文僅用於學習交流,未經容許禁止轉載!