推薦系統中的冷啟動問題

推薦系統中的冷啟動問題

什麼是冷啟動? 推薦系統主要是把物品推薦給喜歡的使用者,在使用的環境中,物品和使用者皆會持續的增長變化,也因此會持續面對有新物品和新使用者的情境;有新的物品和使用者使得無法做好的推薦就稱為冷啟動,我們要討論在這種情況下如何做合適的推薦。 基本的冷啟動可以分成三類: 使用者冷啟動:新用戶產生時沒有有任何瀏覽購買紀錄,如何推薦用品的問題。 物品冷啟動:新物品如何推薦給合適的用戶。 系統冷啟動:新系統上線時,物品、使用者、資料皆不足的推薦問題。 圖片來源:https://www.researchgate.net/figure/Illustration-of-Cold-Start-problem-in-recommender-systems-New-user-problem-left-and_fig2_332511384 接下來我們介紹幾個常見的解決方式 排行榜推薦 新物品的推薦 秉持著大家會喜新厭舊的心態,推薦新的物品給使用者;像是電影、影集等等就很適合,有新影片上線時,不管是新或舊的使用者都會想看。 熱門物品的推薦 推薦大家都喜歡的物品給使用者,這是非常常見的做法,簡單有效;也可以用作新演算法的AB test或benchmark,等到資料足夠後才做個性化推薦。 常用物品、必需品推薦 推薦生活必需品、常用物品給新使用者;這種情況適合一些居家用品、常用家電、廚房用具等等的情境。 標籤推薦 這種方式是針對前三項作更細微的推薦,像是ott 串流平台可以直接選擇喜劇、動作片、愛情片等等的推薦;但要注意標籤要先設計完整。 圖片來源:https://deepai.org/publication/addressing-the-cold-start-problem-in-outfit-recommendation-using-visual-preference-modelling 簡易的使用者推薦 簡易的使用者推薦 根據使用者簡易的年齡、性別等等資料分出人群進行推薦。 授權平台推薦 導入第三方社交平台facebook、google等等,根據這些平台的歷史數據進行推薦。 問答題推薦 目前有許多平台都是這種方式,註冊登入時會問幾個問題,了解你的喜好,根據你的反饋來推薦物品。 新物品的相似度推薦 新物品推薦系統在不同的平台有不同的重要程度,在新聞媒體等等時效性強的平台就特別重要,必須要快速的推薦出去,不然時間過了這個資訊、消息也就不重要了。 新物品跟用戶的相似度 計算新物品的特徵(標籤、cos相似度、TF-IDF、影像相似度等等)和使用者的行為特徵進行推薦。 新物品和舊物品的相似度 新物品進入平台後,根據平台的標籤、屬性資訊等等,計算出相似的物品,再推薦給喜歡此物品的使用者。 試探策略 這幾年短影片的流行,無論是純做短影片的網站,抑或是一般影音平台的短影片,皆是爆發性的成長;快速試探策略就很適合,快速、隨機推薦影片給使用者,再根據使用者觀看、點擊、滑動瀏覽網站、停留時間等等的行為,快速獲得使用者的資訊,再進行推薦。 結尾 上面是簡單介紹幾個常用的方式,還有許多做法可以解決遇到的冷啟動問題,主要必須先定義好問題,知道自己產品、平台的特徵、類型、使用者如何才會滿意等等的資訊,才能真正的對症下藥。 最後推薦幾篇論文,大家有興趣可以看看他們遇到的問題是什麼又是如何解決的。 Behavior-based popularity ranking on Amazon Video Billion-scale Commodity Embedding for E-commerce Recommendation in Alibaba Performance of recommender algorithms on top-N recommendation tasks ...

2021-11-29 · 1 min read · 69 words · KbWen · ZH
Deep Reinforcement learning

Deep Reinforcement learning

Reinforcement learning (RL) is a framework where agents learn to perform actions in an environment so as to maximize a reward. It’s actually training an AI to learn through every mistake and find the correct path without any label. The two main components are the environment and the agent. Deep Reinforcement learning (DRL) combined with deep learning technology is even more powerful. AlphaGo, is a typical application of deep reinforcement learning. ...

2020-10-26 · 2 min read · 356 words · KbWen · EN
Tensorflow2 -- MNIST

Tensorflow2 -- MNIST

Tensorflow2.X和1.X有多了很多差別和使用方式, 今天用tf2來實作MNIST分類問題 MNIST MNIST是一個很標準的手寫數字分類問題, 數據集下載有很多方式,這次直接使用tf API提供的 28 * 28 且只有黑白的數據 開發 在local 起 jupyter lab 先看看GPU是否啟用 %matplotlib widget import matplotlib.pyplot as plt import tensorflow as tf import numpy as np # check gpu tf.config.list_physical_devices('GPU') tf.test.is_built_with_cuda() # output True 方法一 繼承 tf.keras.model class MLP(tf.keras.Model): def __init__(self): super().__init__() self.flatten = tf.keras.layers.Flatten() self.dense1 = tf.keras.layers.Dense(units=100, activation=tf.nn.relu) self.dense2 = tf.keras.layers.Dense(units=20, activation=tf.nn.leaky_relu) self.dense3 = tf.keras.layers.Dense(units=10) @tf.function def call(self, inputs): # [batch_size, 28, 28, 1] flat1 = self.flatten(inputs) # [batch_size, 784] dens1 = self.dense1(flat1) # [batch_size, 100] dens2 = self.dense2(dens1) # [batch_size, 20] dens3 = self.dense3(dens2) # [batch_size, 10] output = tf.nn.softmax(dens3) return output 使用tf.GradientTape訓練 # @tf.function def one_batch_step(X, y, **kwargs): with tf.GradientTape() as tape: y_pred = model(X) loss = tf.keras.losses.sparse_categorical_crossentropy(y_true=y, y_pred=y_pred) loss = tf.reduce_mean(loss) tf.print(f"{batch_index} loss {loss}", [loss]) with summary_writer.as_default(): tf.summary.scalar("loss", loss, step=batch_index) grads = tape.gradient(loss, model.variables) optimizer.apply_gradients(grads_and_vars=zip(grads, model.variables)) for epoch_index in range(num_epochs): for batch_index in range(num_batches): X, y = data_loader.get_batch(batch_size) one_batch_step(X, y, batch_index=batch_index) with summary_writer.as_default(): tf.summary.trace_export(name="model_trace", step=0, profiler_outdir=log_dir) tf.saved_model.save(model, f"saved/{model_name}") 方法二 使用keras Pipeline來疊每一層要用的函數,彈性較低,但非常適合簡單的Model ...

2020-09-26 · 1 min read · 194 words · KbWen · ZH
Google NLP API parsing

Google NLP API parsing

使用google 提供的API做語意分析。 語意分析(syntactic analysis)能夠提取語言的訊息,把文章拆成句子,句子在拆成更小的每個分詞,做更進一步的分析,Goole NLP API 會給予每個字詞的詞性以及彼此的關係。 Analyzing syntax 進入GCP新增一個API Key 並確認NLP API狀態為enable;詳細的GCP申請操作步驟可以看官方文件。(或是以後有機會寫。) API Enabled 因為這次是介紹,所以使用google cloud shell;在平常使用下可以把某些步驟改成習慣的語言及IDE。 新增環境變數 export API_KEY=<YOUR_KEY> 確認輸入後,增加要丟進API的文字json檔 text.json { "document":{ "type":"PLAIN_TEXT", "content": "Beirut rescuers search the site for possible survivor 30 days after the explosion." }, "encodingType": "UTF8" } 標準的json檔輸入資訊:https://cloud.google.com/natural-language/docs 使用curl post資料 curl "https://language.googleapis.com/v1/documents:analyzeSyntax?key=${API_KEY}" \ -s -X POST -H "Content-Type: application/json" --data-binary @text.json 會得到解析出來的資訊 { "sentences": [ { "text": { "content": "Beirut rescuers search the site for possible survivor 30 days after the explosion.", "beginOffset": 0 } } ], "tokens": [ { "text": { "content": "Beirut", "beginOffset": 0 }, "partOfSpeech": { "tag": "NOUN", "aspect": "ASPECT_UNKNOWN", "case": "CASE_UNKNOWN", "form": "FORM_UNKNOWN", "gender": "GENDER_UNKNOWN", "mood": "MOOD_UNKNOWN", "number": "SINGULAR", "person": "PERSON_UNKNOWN", "proper": "PROPER", "reciprocity": "RECIPROCITY_UNKNOWN", "tense": "TENSE_UNKNOWN", "voice": "VOICE_UNKNOWN" }, "dependencyEdge": { "headTokenIndex": 1, "label": "NN" }, "lemma": "Beirut" }, { "text": { "content": "rescuers", "beginOffset": 7 }, "partOfSpeech": { "tag": "NOUN", "aspect": "ASPECT_UNKNOWN", "case": "CASE_UNKNOWN", "form": "FORM_UNKNOWN", "gender": "GENDER_UNKNOWN", "mood": "MOOD_UNKNOWN", "number": "PLURAL", "person": "PERSON_UNKNOWN", "proper": "PROPER_UNKNOWN", "reciprocity": "RECIPROCITY_UNKNOWN", "tense": "TENSE_UNKNOWN", "voice": "VOICE_UNKNOWN" }, "dependencyEdge": { "headTokenIndex": 2, "label": "NSUBJ" }, "lemma": "rescuer" }, { "text": { "content": "search", "beginOffset": 16 }, "partOfSpeech": { "tag": "VERB", "aspect": "ASPECT_UNKNOWN", "case": "CASE_UNKNOWN", "form": "FORM_UNKNOWN", "gender": "GENDER_UNKNOWN", "mood": "INDICATIVE", "number": "NUMBER_UNKNOWN", "person": "PERSON_UNKNOWN", "proper": "PROPER_UNKNOWN", "reciprocity": "RECIPROCITY_UNKNOWN", "tense": "PRESENT", "voice": "VOICE_UNKNOWN" } } ...... ], "language": "en" } 觀察一下上面的結果 ...

2020-09-04 · 2 min read · 233 words · KbWen · ZH
OPENCV 人臉辨識

OPENCV 人臉辨識

人臉檢測 (Face Detection) 通常是人臉辨識流程的前置處理。這裡我們利用 Haar 特徵 來進行實作。 在訓練過程中,該演算法使用 AdaBoost,即利用多個「弱分類器」級聯 (Cascade) 來判別。每一步都會提取一個特徵值來判斷是否為人臉: 如果判斷為「是」,則進入下一個層級的強分類器。 如果判斷為「否」,則直接排除該區域。 廣義來看,這就像是讓所有弱分類器進行投票,並根據各自的準確率加權集成。其組成的分類器架構稱為 Cascade,形式上類似於簡單的多層決策樹。 實際應用與調整 在實際使用中,Haar Cascade 的挑戰主要在於參數的調優,尤其是 scaleFactor 和 minNeighbors: scaleFactor:控制影像縮放的比例。數值調大時,檢測的層數會變少,速度快但容易漏掉較小的目標。 minNeighbors:決定一個目標區域被聲明為「人臉」前,周圍必須也被檢測到的人臉鄰居數量。 由於不同圖片的解析度與場景差異,往往需要手動調整參數才能達到最佳效果,這在自動化處理上較為困難。未來我會嘗試使用深度學習等更強健的方式。 參考來源:Face Recognition with Python 下圖是檢測人臉與眼睛的結果,圖片來源為 USA Volleyball National Team 合照: My Github

2017-07-12 · 1 min read · 37 words · KbWen · ZH
Keras IMDb

Keras IMDb

IMDb 是一個電影相關的線上資料庫。這次要利用 IMDb 的影評文字,預測它屬於正面評價還是負面評價。 在深度學習模型中,輸入必須是數字。Keras 提供了 Tokenizer 模組,會依照英文單字出現頻率進行排序並編號:Keras Tokenizer 官方文件。 接著利用 Word Embedding 將編號清單轉換為向量清單,最後丟進 LSTM 模型進行學習。 Keras 封裝了許多方便的功能,讓文字轉數字與模型建立變得非常簡單。 這是我的 Model Summary。將數字序列轉換為 64 維的向量序列,並使用了三層隱藏層進行訓練。 準確率:0.8543 實際測試 造訪 IMDb 網站,抓取《蜘蛛人:返校日 (Spider-Man: Homecoming)》的評論進行檢驗。輸入正面評論後,模型正確辨識為正面(1 為正面,0 為負面)。 My Github 相關文章 Keras Cifar-10

2017-07-11 · 1 min read · 37 words · KbWen · ZH
Keras Cifar-10

Keras Cifar-10

這次使用 Keras 建立 CNN 疊代模型,來辨識 CIFAR-10 影像資料。 CIFAR-10 是 32*32 的 RGB 彩色圖形,包含飛機、狗、貓等 10 個類別,可以視為 MNIST 的進階挑戰版。 在數據預處理 (Preprocess) 階段,流程與 MNIST 類似,包括標準化與 One-hot encoding。 模型架構: 卷積層 (Convolution):兩層,選用 3*3 Kernel,Same padding。 池化層 (Max-pooling):2*2 大小。 全連接層 (Dense):由 4096 降至 1024,最後輸出 10 個類別。 可以觀察 Keras 與 TensorFlow 在參數表現與語法上的些微差异。 利用 pandas 建立混淆矩陣 (Confusion Matrix),分析模型是否在特定類別間產生混淆。 從矩陣中可以看出: 第 3 類 (cat) 與第 5 類 (dog) 較容易混淆。 動物類與交通工具類之間區分得相當清楚。 兩層 CNN 準確率:0.732 My Github 相關文章 Keras IMDb

2017-07-06 · 1 min read · 69 words · KbWen · ZH
ML KNN

ML KNN

k-th nearest neighbor (k-NN) k-NN 是監督式學習 (Supervised learning) 的一種,名稱非常簡明扼要,就是尋找「K 個最相近的鄰居」。 這個演算法在實作時,會找到附近 K 個最近的點,根據鄰居的類別來判斷自己要歸在哪一類。雖然它是監督式學習,但其實並不需要訓練模型參數,而是將所有訓練資料儲存起來進行即時對比。 我們可以藉由調整 K 的數值來增加演算法的 Noise Margin。然而,此演算法存在著儲存空間需求大(空間複雜度高)的問題,且容易受到數據不平衡的影響。 在實作上,核心在於計算點與點之間的距離。我使用了 Scipy 的函數來實作,為了方便觀察,先取 K=1,並將結果與 sklearn 的 KNN 進行比較。 實作思路是利用 for 迴圈計算每個測試資料與所有訓練資料的距離,並取最近者的類別作為預測結果。 準確率比較: sklearn knn : 0.9733 手刻 knn : 0.9467 My Github

2017-06-30 · 1 min read · 40 words · KbWen · ZH
LSTM

LSTM

原文網址:Understanding LSTMs 想像人在思考或閱讀文章時,並不是從零開始,而是會保留過去的記憶。RNN 就是為了解決這方面的問題而設計的。 每次訓練時,網路會保留過去的訊息並持續傳遞。而 LSTM 則是一種特殊的 RNN 形式。 The Problem of Long-Term Dependencies 在許多情況下,我們需要更多的上下文訊息,但這些關鍵資訊可能距離當前時間點非常遙遠。一般的 RNN 在處理這種長距離依賴時,容易產生梯度消失或梯度爆炸的問題。 LSTM LSTM 稱為「長短期記憶網絡」(Long Short Term Memory networks),是一種特殊的 RNN 架構。 不同於傳統 RNN 在每個 Cell 裡只包含一個 tanh 層,LSTM 增加了: input gate (輸入門) output gate (輸出門) forget gate (遺忘門) 這些閘門都是用來精準控制資料的操作。使用 sigmoid 激活函數可以看做是控制記憶與讀取資料量的多寡:0 代表不通過,1 代表全部通過。 詳細的數學推導可以參考原文。文中也介紹了 GRU——一種更為簡煉高效的 LSTM 變體。值得注意的是,現今我們從 RNN 領域獲得的優異成果,幾乎指的都是 LSTM 的應用。 在 TensorFlow 中,LSTM 已經封裝完善,呼叫即可使用。 下圖是用 LSTM (紅虛線) 去學習黑線 (x*sin(x)) 的擬合結果:

2017-06-29 · 1 min read · 66 words · KbWen · ZH
Kaggle PM2.5 Prediction

Kaggle PM2.5 Prediction

嘗試用 sklearn 進行分析。 使用豐原站的觀測記錄,將資料分為訓練集 (train set) 與測試集 (test set): train.csv:每個月前 20 天的所有觀測資料。 test_X.csv:從每個月剩下的 10 天中取樣。每筆資料包含連續 10 小時,以前九小時的所有觀測數據作為 Feature,預測第十小時的 PM2.5 濃度。一共取出 240 筆不重複的測試資料。 sklearn 在使用上非常直接。目前的策略是採用最基礎的方式:取出所有前九小時的值作為 Feature,不進行額外的特徵工程或化簡,直接觀察結果。 在 Private 排名約在中間,略高於 Baseline。 因為使用的是 Linear Regression,對 Gradient Descent 而言:計算一次斜率,直接就能找到解。 My Github 相關文章 Kaggle Digit Recognizer Kaggle Titanic

2017-06-13 · 1 min read · 43 words · KbWen · ZH