Project 4:用户画像的建立
用戶畫像
目標:通過用戶給商品的打標簽記錄,建立用戶畫像(顯示打標簽、亦可為隱式評分:點擊率等)
# 使用SimpleTagBased、NormTagBased、TagBased-TFIDF算法對Delicious2K數據進行推薦 # 原始數據集:https://grouplens.org/datasets/hetrec-2011/ # 數據格式:userID bookmarkID tagID timestamp用戶畫像的準則
用戶標簽的建立
一、數據初步分析層(一級標簽):
首先,需要將用戶的數據進行分類,打上一級標簽,這涉及到四個維度:
八字原則:用戶消費行為分析
(User Behavior可以分成Explicit Behavior顯式行為和Implicit Behavior隱式行為)
二、算法層(二級標簽):
在初步分析基礎上,對用戶進行聚類分析、標簽算法、關聯算法的分析,為用戶打上二級標簽:
用戶畫像建立、Item特性、產品購買偏好、用戶關聯關系、熱門商品、熱門話題支付行為偏好、優惠偏好
三、預測算法層(三級標簽):
基于上述兩層標簽的預測標簽:如購買某項產品的預測,用戶流失預測等。
標簽賦能
為用戶建立用戶畫像后,標簽的賦能(對業務的指導)分為用戶生命周期(LTV)的三個階段:獲客、粘客、留客。
1 .商品維度:對本產品中的熱門商品(已完善的商品體系)、特色商品(新開發的商品體系)進行廣告推薦;
基于商品特色,針對性的向潛在用戶群體投放廣告,將用戶的廣告點擊行為打上新的標簽。
2.用戶維度:基于用戶已有的標簽,推薦相應適合的商品,并根據其點擊行為等更新其標簽。
SimpleTagBased算法
Score(u,i)=∑tuser?tags[u,t]?item?tags[t,i]Score(u, i) = \sum_t{user-tags[u,t] \cdot item-tags[t,i]}Score(u,i)=t∑?user?tags[u,t]?item?tags[t,i]
(user?tags[u,t])(user-tags[u,t])(user?tags[u,t]) 用戶 uuu 使用過標簽 ttt 的次數
item?tags[t,i]item-tags[t,i]item?tags[t,i]商品 iii 被打上標簽 ttt 的次數
數據結構定義:
用戶打標簽記錄:records[i] = {user, item, tag}
用戶 u 打過標簽 t 的數量:user_tags[u][t]
用戶 u 給商品 i 打過的標簽數量:user_items[u][i]
打上 tag 標簽的商品的數量:tag_items[t][i]
tag 標簽使用過的用戶數量:tag_users[t][u]
數據加載
import pandas as pd import random from collections import defaultdict#直接傳入會出錯 def defaultdict_list():return defaultdict(list) #創建一個默認字典 records = defaultdict(defaultdict_list)#加載數據 def load_data():#如何加載 dat 格式文件data = pd.read_csv('user_taggedbookmarks-timestamps.dat', sep = '\t')for i in range(data.shape[0]):records[data.iloc[i, 0]][data.iloc[i, 1]].append(data.iloc[i, 2])print('共加載{}條數據'.format(data.shape[0]))print('總計{}人'.format(len(records)))%time load_data()數據切分
由于random的生成是均勻分布,因此大樣本情況下,滿足均勻分布特性。
# 將數據集拆分為訓練集和測試集 test_data = {} train_data = {}def train_test_split(ratio, seed=100):count = 0random.seed(seed)for u in records.keys():for i in records[u].keys():# ratio比例設置為測試集if random.random()<ratio:test_data.setdefault(u,{})test_data[u].setdefault(i,[])for t in records[u][i]:test_data[u][i].append(t)count += 1else:train_data.setdefault(u,{})train_data[u].setdefault(i,[])for t in records[u][i]:train_data[u][i].append(t) print('切分比例:{}'.format(count / 437593)) print("訓練集用戶數 {}, 測試集用戶數 {}" .format(len(train_data),len(test_data)))train_test_split(0.2)數據結構 “user_tags; user_items; tag_items; tag_users” 初始化
#初始化users-items;users-tags;items-tags矩陣 # 設置矩陣 mat[index, item] = 1 user_tags = {} user_items = {} tag_items = {} tag_users = {} def addValueToMat(mat, index, item, value=1):if index not in mat:mat.setdefault(index,{})mat[index].setdefault(item,value)else:if item not in mat[index]:mat[index][item] = valueelse:mat[index][item] += value# 使用訓練集,初始化user_tags, tag_items, user_items def initStat():records=train_datafor u,items in records.items():for i,tags in items.items():for tag in tags:#print tag# 用戶和tag的關系addValueToMat(user_tags, u, tag, 1)# tag和item的關系addValueToMat(tag_items, tag, i, 1)# 用戶和item的關系addValueToMat(user_items, u, i, 1)#標簽和用戶的關系addValueToMat(tag_users, tag, u, 1)print("user_tags, tag_items, user_items, tag_users初始化完成.")print("user_tags大小 %d, tag_items大小 %d, user_items大小 %d, tag_users大小 %d" % (len(user_tags), len(tag_items), len(user_items), len(tag_users)))initStat()基于SimpleTagBased算法的TOP-N推薦
import operator # 對用戶user推薦Top-N def simple_recommend(user, N):recommend_items = dict()# 對Item進行打分,分數為所有的(用戶對某標簽使用的次數 wut, 乘以 商品被打上相同標簽的次數 wti)之和tagged_items = user_items[user]for tag, wut in user_tags[user].items():#print(self.user_tags[user].items())for item, wti in tag_items[tag].items():#用戶標記過的商品不需要再計算分數if item in tagged_items:continue#print('wut = %s, wti = %s' %(wut, wti))if item not in recommend_items:recommend_items[item] = wut * wtielse:recommend_items[item] = recommend_items[item] + wut * wtireturn sorted(recommend_items.items(), key = operator.itemgetter(1), reverse=True)[0:N] # 使用測試集,計算準確率和召回率 def simple_precisionAndRecall(N):hit = 0h_recall = 0h_precision = 0for user,items in test_data.items():#沒有標簽的用戶無法推薦if user not in train_data:continue# 獲取Top-N推薦列表rank = simple_recommend(user, N) # print(rank)for item,rui in rank:if item in items:hit = hit + 1h_recall = h_recall + len(items)h_precision = h_precision + N#print('一共命中 %d 個, 一共推薦 %d 個, 用戶設置tag總數 %d 個' %(hit, h_precision, h_recall))# 返回準確率 和 召回率return (hit/(h_precision*1.0)), (hit/(h_recall*1.0))# 使用測試集,對推薦結果進行評估 def simple_testRecommend():print("推薦結果評估")print("%3s %10s %10s" % ('N',"精確率",'召回率'))for n in [5,10,20,40,60,80,100]:precision,recall = simple_precisionAndRecall(n)print("%3d %10.3f%% %10.3f%%" % (n, precision * 100, recall * 100))改進:基于NormTagBased算法與 TF-IDFBased算法 的TOP-N推薦
由于 SimpleTagBased 使用的方法
因此使用 NormTagsBased 做標準化處理:
Score(u,i)=∑tuser?tags[u,t]?item?tags[t,i]user?tags[user]?tag?users[tag]Score(u, i) =\sum_t \frac{user-tags[u,t] \cdot item-tags[t,i]}{user-tags[user] \cdot tag-users[tag]} Score(u,i)=t∑?user?tags[user]?tag?users[tag]user?tags[u,t]?item?tags[t,i]?
user?tags[user]user-tags[user]user?tags[user] 表示一個用戶使用的標簽總類別數量;
tag?users[tag]tag-users[tag]tag?users[tag] 表示一個標簽 tag 總的用戶個數。
由于 user?tags[u,t]user-tags[u,t]user?tags[u,t] 表示一個用戶使用某 tag 的數量,若該標簽熱門,那么可能使用的數量就會越多,因此借助TF-IDF的思想,使用:
log(1+(user?tags[user]))log(1 + (user-tags[user]))log(1+(user?tags[user])) 對公式進行處理。
Score(u,i)=∑tuser?tags[u,t]?item?tags[t,i]log(1+(user?tags[user]))Score(u, i) =\sum_t \frac{user-tags[u,t] \cdot item-tags[t,i]}{log(1 + (user-tags[user]))} Score(u,i)=t∑?log(1+(user?tags[user]))user?tags[u,t]?item?tags[t,i]?
通過對用戶畫像:user_tags; user_items 的建立,對用戶進行個性化推薦。可以看到標準化后的結果有著顯著的提高。
總結
以上是生活随笔為你收集整理的Project 4:用户画像的建立的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: volatile关键字和AtomicIn
- 下一篇: Spark-Streaming基础