上篇博客說到繪制用戶畫像時根據用戶行為計算標簽權重很重要,計算標簽權重最常用的算法是TF-IDF標簽權重算法,但是如何計算並沒有詳細介紹,那么這篇博客咱們就來詳細說說基於TF-IDF算法計算用戶標簽權重。
TF-IDF算法用以評估一個字詞對於一個文件集或一個語料庫中的其中一份文件的重要程度,常用於計算標簽的重要程度,一個標簽的重要程度隨着它在一篇文章出現的次數成正比,隨着它在整個文檔集中出現的次數成反比。
我們用W(P,T)
表示一個標簽T被用於標記商品P的次數,用TF(P,T)
表示這個標簽在商品P所有標簽中所占的比重。
TF為詞頻即詞條在某文檔中出現的頻率,TF(P,T)=W(P,T)/ΣW(P,Ti),即TF=該標簽標記該商品的次數 / 該商品全部標簽個數
IDF為逆向文件頻率即標簽T在全部標簽中的稀缺程度,IDF(P,T)=ΣW(Pi,Ti) / ΣW(Pi,T),即IDF=全部商品個數 / 包含T標簽的商品數
實例
標簽A:商品1 商品2 商品4 商品6
商品1:標簽A 標簽C 標簽D
商品2:標簽B 標簽C 標簽E
商品3:標簽A 標簽D
對於標簽A,TF(1,A)=1/3,IDF(1,A)=3/2,則該標簽對於該商品的重要程度即該標簽的權重值=TF*IDF=1/3 * 3/2= 1/2
用戶行為表結構
user_id:用戶id
tag_id:標簽id
tag_name:標簽名稱,用戶某一行為與該標簽聯系
tag_type:標簽類型
action_name:用戶行為名稱,如搜索,點擊,收藏等
action_count:用戶該行為的次數
action_time:用戶該行為的時間,某年某月某日
weight:該標簽的權重
行為類型權重
用戶瀏覽、搜索、收藏、取消收藏等不同行為反映用戶對商品的喜愛程度,不同行為的權重也不同,權重值的設置該應根據具體應用場景來設置其值。比如瀏覽、搜索、收藏代表用戶喜歡商品,應設為正值,但是收藏>搜索>瀏覽,取消收藏代表用戶不喜歡該類商品,其權重應設為負值。
時間衰減
一般考慮時間,用戶的行為會隨着時間的過去,歷史行為和當前的相關性不斷減弱,例如去年發生的行為和今年發生的行為應該是有衰減邏輯在里面的,在建立與時間衰減相關的函數時,我們可套用牛頓冷卻定律數學模型。如果周期小或業務場景穩定,也可以選擇忽略這個因素。
行為次數
記錄用戶在同一天中,同一行為的次數。
標簽重要度
代碼實現
package recommender; import java.util.Arrays; import java.util.List; /** * Created by bee on 2020/2/5. */ public class test { /** *calculate the tag frequency */ public double tf(List<String> product, String term) { double termFrequency = 0; for (String str : product) { if (str.equalsIgnoreCase(term)) { termFrequency++; } } return termFrequency / product.size(); } /** *calculate the document frequency */ public int df(List<List<String>> tags, String term) { int count = 0; if (term != null && term != "") { for (List<String> product : tags) { for (String tag : product) { if (term.equalsIgnoreCase(tag)) { count++; break; } } } } else { System.out.println("要計算的tag不能為空"); } return count; } /** *calculate the inverse document frequency */ public double idf(List<List<String>> tags, String term) { return Math.log(tags.size()/(double)df(tags,term)); } /** * calculate tf-idf */ public double tfIdf(List<String> product, List<List<String>> tags, String term) { return tf(product, term) * idf(tags, term); } public static void main(String[] args) { List<String> product1 = Arrays.asList("男鞋", "潮流", "秋季", "皮鞋", "英倫","簡約"); List<String> product2 = Arrays.asList("簡約", "秋季", "運動鞋", "男鞋", "休閑", "時尚"); List<String> product3 = Arrays.asList("女鞋", "日韓", "可愛", "娃娃鞋", "甜美", "名媛風"); List<List<String>> tags = Arrays.asList(product1, product2, product3); test calculator = new test(); double tfidf = calculator.tfIdf(product1, tags, "簡約"); System.out.println("TF-IDF (簡約) = " + tfidf); double count = (1.0/6) * Math.log(3.0/2); System.out.println(count); } }
運行結果