參考場景:行為分析和預測

文中涉及的「數據目錄」和「源代碼目錄」見雲盤:pan.baidu.com/s/1slJntR

雖然個體的行為具有一定的隨機性和隱蔽性,但是很多時候在數據層面又可能呈現出一定的規律和現象。比如,據說有公司嘗試過分析員工的行為來預測哪些員工未來離職的可能性比較大,發現到了下班時候不再回復工作郵件、請假次數變多、和同事的郵件交流和社交媒體交流減少等現象往往預示著一個即將離職員工的出現;當然,前面信用評分的案例中也清晰地體現了,如果用戶近期有信用卡逾期行為的,未來逾期的風險也會急劇增加。因此,在很多場景下,對數據進行分析可能可以幫助我們見微知著地了解一些事態的走向。

這裡我們有一份新浪微博在 2015年2月1日到 2015年7月31日這半年內抽樣部分用戶的所有微博在發表一周以後的轉發、評論、贊的數據(數據目錄下的 weibo.zip 文件),讓我們根據這個數據來建立一個模型,能夠預測每個用戶在當時再發表一篇微博,一周後這條微博的轉發、評論和贊的數量。

這個例子中的程序可見源代碼目錄下 weibo.py

1、探索性分析

打開數據瀏覽一下,馬上就會看到有很多的微博的轉發、評論、贊的數量均為 0 。恐怕這樣的用戶為數不少。那我們就先看一下不同用戶的轉發、評論、贊的分布到底是什麼樣的。

先將數據按照總共大約 3.7 萬多個用戶ID進行分組:

groupby_user = data.groupby(uid)groupby_user.median().to_csv(weibo_groupby_user.csv)

得到效果如下圖,從圖中可以看到,每個用戶的轉發、評論、贊的中位數,基本都呈現非常明顯的長尾分布。也就是說,在微博上,用戶在活躍程度上有著非常大的區別,大量的用戶可能是幾乎沒有什麼交互的小透明或者殭屍號。

下面先將數據以 2015年7月1日為分界線,將數據劃分為訓練集和測試集。經過統計,在所有 37263 個用戶中,有 36426 個曾經出現在訓練集中,另外還有 837 個過去從來沒出現過,這些用戶的行為沒有歷史可以參考,預測會存在較大的不確定性。

2、交互行為的時間特點

我們再來考察一下用戶發表微博的時間對後續的評論、轉發和贊有沒有影響。如下圖所示,對訓練集中的所有數據進行統計就可以發現,如果發微博的時間實在凌晨 1 點到 8點之間,那麼這些微博引發的評論、轉發和贊都明顯處於較低的水平。也就是說,半夜發的微博較容易被忽視掉。

而對於發微博是周幾來說,對評論和轉發基本沒有影響,但是周五和周六發出的微博贊相對會更多一些。

3、構建特徵

顯然,用戶是否活躍(粉絲數量多少、與粉絲互動多少)是影響一個用戶發微博產生的評論、轉發、贊的決定性因素。因此,我們首先需要通過構造可以儘可能反映用戶活躍程度的特徵,來反映用戶的活躍程度。

我們可以構建如下的一些用戶特徵:

  • 用戶的微博產生的評論、轉發、贊的中位數 user_comment_n、user_forward_n、user_like_n
  • 用戶的微博產生的評論、轉發、贊的標準差 user_comment_std、user_forward_std、user_like_std
  • 用戶總共發表的微博數量 user_post_count

注意,以上這些用戶特徵都是在用戶存在評論、轉發、贊的前提下構建的,如果用戶過去的微博都沒有任何互動,那麼我們可以認為未來存在互動的可能性也很小。

下面是構造用戶特徵的大致過程:

# 將數據按時間分為訓練集和測試集time_split = time.strptime(2015-07-01 00:00:00, %Y-%m-%d %H:%M:%S)data_train = data[data.time < time_split]data_test = data[data.time >= time_split]# 提取訓練集中的用戶groupby_user_train = data_train.groupby(uid)# 計算中位數特徵user_train_median_1 = groupby_user_train.median()[(groupby_user_train.median()[comment_n]>0) | (groupby_user_train.median()[forward_n]>0) | (groupby_user_train.median()[like_n]>0)]user_train_median_1[uid] = user_train_median_1.indexuser_train_median_1 = user_train_median_1.rename(columns={comment_n:user_comment_n, forward_n:user_forward_n, like_n:user_like_n})# 計算標準差特徵user_train_std_1 = groupby_user_train.std()[(groupby_user_train.median()[comment_n]>0) | (groupby_user_train.median()[forward_n]>0) | (groupby_user_train.median()[like_n]>0)]user_train_std_1[uid] = user_train_std_1.indexuser_train_std_1 = user_train_std_1.rename(columns={comment_n:user_comment_std, forward_n:user_forward_std, like_n:user_like_std})user_train_1 = pd.merge(user_train_median_1, user_train_std_1, on=uid, how=left)# 計算微博數量特徵user_train_count_1 = groupby_user_train.count()[(groupby_user_train.median()[comment_n]>0) | (groupby_user_train.median()[forward_n]>0) | (groupby_user_train.median()[like_n]>0)][[mid]]user_train_count_1[uid] = user_train_count_1.indexuser_train_count_1 = user_train_count_1.rename(columns={mid:user_post_count})user_train_1 = pd.merge(user_train_1, user_train_count_1, on=uid, how=left)

另外,一條微博的特點也會影響評論、轉發、贊的數量,上面的探索性的分析中看到,包括微博的發表時間等屬性都可能對交互產生影響。那麼,我們可以對微博構造如下特徵:

  • 微博發表的時間 post_day post_hour
  • 微博的長度 post_len
  • 微博的文本特徵向量 post_0、……、post_n

下面是構造微博特徵的大致過程:

# 微博相關的特徵data[post_hour] = data[time].apply(lambda time : str(time.tm_hour))data[post_day] = data[time].apply(lambda time : str(time.tm_wday))data[post_len] = data[content].apply(lambda content : len(content))# 微博內容的文本特徵向量def tokenizer(text): try: cuts = jieba.lcut(text) return [c for c in cuts if c.strip() != ] except Exception as e: return [] data[words] = data[content].apply(tokenizer)query_docs = [] for i, row in data.iterrows(): doc = TaggedDocument(row[words], tags=[i]) query_docs.append(doc) vec_class_count = 48d2v = Doc2Vec(query_docs, min_count=1, window=3, size=vec_class_count, workers=4) d2v.train(query_docs, total_examples=d2v.corpus_count, epochs=5)print(Doc2Vec train done, time.strftime(%Y-%m-%d %H:%M:%S, time.localtime(time.time())))data[words_vec] = data[words].apply(d2v.infer_vector)print(Infer vector done, time.strftime(%Y-%m-%d %H:%M:%S, time.localtime(time.time())))for i in range(vec_class_count): data[post_+str(i)] = data[words_vec].apply(lambda vec : vec[i])print(Extract vector done, time.strftime(%Y-%m-%d %H:%M:%S, time.localtime(time.time())))

4、訓練與預測

上面我們已經把用戶分成了沒有任何活動的部分和有一定活躍的部分,對於沒有歷史活動的用戶,未來的評論、轉發、贊都可以直接預測為 0。關鍵是對於有一定活躍用戶的預測,要儘可能準確一些。顯然,我們可以考慮使用集成方法進行計算。

# 分別尋找評論、轉發、贊的較優模型參數for target in [comment, forward, like]: best_bst = None best_auc = 0 best_max_depth = 0 for max_depth in range(2, 10): train_data = lgb.Dataset(dtrain_1[feature_names], label=dtrain_1[target + _n], feature_name=feature_names) test_data = lgb.Dataset(dtest_1[feature_names], label=dtest_1[target + _n], feature_name=feature_names) param = {max_depth: max_depth, learning_rate: 0.1, objective:regression, metric: {auc}, } num_round = 1000 bst = lgb.train(param, train_data, num_round, valid_sets=[test_data], early_stopping_rounds=int(num_round/50)) auc = bst.best_score[valid_0][auc] if auc > best_auc: best_auc = auc best_max_depth = max_depth best_bst = bst print(time.strftime(%Y-%m-%d %H:%M:%S, time.localtime(time.time())), target, auc={:.4f}.format(auc)) print(target, best_max_depth={:.0f} best_auc={:.4f}.format(best_max_depth, best_auc)) lgb.plot_importance(best_bst, title=target, figsize=(20, 20), height=0.4)

這個模型運行下來,評論的 AUC 指標可以達到 0.76,轉發的 AUC 指標可以達到 0.78,贊的 AUC 指標可以達到 0.73 。下面是各個指標的特徵重要性排序圖中,最重要的部分特徵:

從特徵重要性中可以看到,和未來評論、轉發、贊的數量關係最大的,還是這個用戶歷史微博的評論、轉發、贊的情況,另外,微博的長度也是一個比較重要的因素。微博內容的文本特徵向量也能反映一定的趨勢,但是這些特徵不存在太多的可解釋性。而在探索性分析中判斷可能有影響的時間因素,在模型中的重要性較低,從統計上看時間對社交行為有影響,但是對於每個用戶的每條微博這個個體來說,時間的影響遠沒有其它特徵重要。

5、思考

既然和一條微博未來可能產生交互的情況最相關的信息,存在於這個用戶的特徵中,那麼如果可以豐富這個用戶的畫像,應該可以提升預測的準確性。現有的這個數據中和用戶相關的只有歷史微博的評論、轉發、贊的數量,如果能夠獲取這個用戶的其它信息,比如粉絲的數量等,就應該能夠更加直接地反應這個用戶的活躍和社交網路的廣度,這將更加有助於描述某個用戶的社交特徵。

另外,微博的特徵是不是可以做得更加細緻一點。從常識我們知道,如果我們轉發一條熱門的微博,那麼可能這條微博的評論轉發也會多一點,也就是我們應該想辦法提取微博更多的特徵,而不僅僅是文本內容特徵。比如轉發的原始微博的作者本身的粉絲數量、微博是不是用 # 符號標記了熱門話題等等,這些信息的提取應該也能幫助我們做更加準確的預測。

6、練習

數據目錄下有一個 news_app.zip 文件,其中包含了某新聞資訊類 APP 的一些用戶的行為,其中 users.txt 中記錄了這些用戶的 ID,news.csv 中記錄了新聞的 ID 和 分類,user_actions.csv 中記錄了這些用戶和這些新聞發生的交互行為,包括點擊、完整閱讀、評論、收藏、分享等。

嘗試從這些數據中構建一個模型,用來給每個用戶推薦三條最適合 TA 的新聞。


推薦閱讀:

老爸要換途安L,我給他推薦了GL6,他看完為什麼立馬放棄了途安?
法師甄姬的出裝銘文推薦有哪些呢?
不錯的室內設計師必看網站
痘肌混油皮有什麼水乳推薦?
有什麼理由為觀眾推薦《看不見的客人》這部豆瓣好評電影?

TAG:預測 | 行為分析 | 推薦 |