揭秘Keras推薦系統如何建立模型 獲取使用者愛好

2021-09-23 08:58:15 字數 3669 閱讀 8711

你是否有過這樣的經歷?當你在亞馬遜**瀏覽一些書籍,或者購買過一些書籍後,你的偏好就會被系統學到,系統會基於一些假設為你推薦相關書目。為什麼系統會知道,在這背後又藏著哪些秘密呢?

推推薦系統可以從百萬甚至上億的內容或商品中把有用的東西高效地顯示給使用者,這樣可以為使用者節省很多自行查詢的時間,也可以提示使用者可能忽略的內容或商品,使使用者更有黏性,更願意花時間待在**上,從而使商家賺取更多的利潤,即使流量本身也會使商家從廣告中受益。

那麼推薦系統背後的魔術是什麼呢?其實任何推薦系統本質上都是在做排序。

矩陣分解可以認為是一種資訊壓縮。這裡有兩種理解。第一種理解,使用者和內容不是孤立的,使用者喜好有相似性,內容也有相似性。壓縮是把使用者和內容數量化,壓縮成 k 維的向量。把使用者向量維度進行壓縮,使得向量維度變小,本身就是資訊壓縮的一種形式;向量之間還可以進行各種計算,比如余弦(cosine)相似性,就可以數量化向量之間的距離、相似度等。第二種理解,從深度學習的角度,使用者表示輸入層(user representation)通常用 one hot編碼,這沒問題,但是通過第一層全連線神經網路就可以到達隱藏層,就是所謂的嵌入層(embedding layer),也就是我們之前提到的向量壓縮過程。緊接著這個隱藏層,再通過一層全連線網路就是最終輸入層,通常用來和實際標註資料進行比較,尋找差距,用來更新網路權重。從這個意義上講,完全可以把整個資料放進神經系統的框架中,通過淺層學習把權重求出來,就是我們要的向量集合了。經過這麼分析,矩陣分解在推薦系統中是如何應用的就顯而易見了。

這兩種情形都可以用矩陣分解來解決。假設資料庫裡m 個使用者和 n 部電影,那麼使用者電影矩陣的大小就是 m×n。每個單元 (i,j) 用r ij 表示使用者是否看了該電影,即0 或 1。我們把使用者和電影用類似 word2vec 的方法分別進行向量表示,把每個使用者 i 表示成 d 維向量 x i ,把每部電影 j 表示成 d 維向量 y j 。我們要尋找 x i 和 y j ,使得 x i ×y j和使用者電影矩陣 r ij 盡可能接近,如圖所示。這樣對於沒出現過的使用者電影對,通過 x i ×y j 的表示式可以**任意使用者對電影的評分值。

用數學表示式可以這麼寫:

注意:這裡d 是乙個遠小於m; n 的數。從機器學習的角度來說,模型是為了抓住資料的主要特徵,去掉雜訊。越複雜、越靈活的模型帶來的雜訊越多,降低維度則可以有效地避免過度擬合現象的出現。

下面展示高階版的深度模型。我們將建立多層深度學習模型,並且加入 dropout技術。

這個模型非常靈活。因為如果有除使用者、電影之外的資料,比如使用者年齡、地區、電影屬性、演員等外在變數,則統統可以加入模型中,用嵌入的思想把它們串在一起,作為輸入層,然後在上面搭建各種神經網路模型,最後一層可以用評分等作為輸出層,這樣的模型可以適用於很多場景。深度模型的的架構如下圖所示。

首先,做使用者和電影的嵌入層。

1 k = 128

2 model1 = sequential()

3 model1.add(embedding(n_users + 1, k, input_length = 1))

4 model1.add(reshape((k,)))

5 model2 = sequential()

6 model2.add(embedding(n_movies + 1, k, input_length = 1))

7 model2.add(reshape((k,)))

第三個小神經網路,在第

一、二個網路的基礎上把使用者和電影向量結合在一起。

1 model = sequential()

2 model.add(merge([model1, model2], mode = 'concat'))

然後加入dropout 和relu 這個非線性變換項,構造多層深度模型。

1 model.add(dropout(0.2))

2 model.add(dense(k, activation = 'relu'))

3 model.add(dropout(0.5))

4 model.add(dense(int(k/4), activation = 'relu'))

5 model.add(dropout(0.5))

6 model.add(dense(int(k/16), activation = 'relu'))

7 model.add(dropout(0.5))

因為是**連續變數評分,最後一層直接上線性變化。當然,讀者可以嘗試分類問

題,用softmax 去模擬每個評分類別的概率。

model.add(dense(1, activation = 'linear'))
將輸出層和最後的評分數進行對比,後向傳播去更新網路引數。

model.compile(loss = 'mse', optimizer = "adam")
接下來要給模型輸入訓練資料。

首先,收集使用者索引資料和電影索引資料。

1 users = ratings['user_id'].values

2 movies = ratings['movie_id'].values

收集評分資料。

label = ratings['rating'].values
構造訓練資料。

1 x_train = [users, movies]

2 y_train = label

然後,用小批量更新權重。

model.fit(x_train, y_train, batch_size = 100, epochs = 50)
模型訓練完以後,**未給的評分。

1 i,j = 10,99

2 pred = model.predict([np.array([users[i]]), np.array([movies[j]])])

最後,對訓練集進行誤差評估。

1 sum = 0

2 for i in range(ratings.shape[0]):

3 sum += (ratings['rating'][i] - model.predict([np.array([ratings['user_id'

][i]]), np.array([ratings['movie_id'][i]])])) ** 2

4 mse = math.sqrt(sum/ratings.shape[0])

5 print(mse)

訓練資料的誤差在0.8226 左右,大概乙個評分等級不到的誤差。

推薦系統系列3 推薦系統中如何解決冷啟動

使用者冷啟動主要解決如何給乙個新的使用者做個性化推薦。當乙個新使用者 新註冊的 到來時,我們沒有他的歷史行為資料,所以無法根據他的歷史行為去 他的興趣,從而無法去做個性化推薦。物品冷啟動 物品冷啟動主要解決如何將新的物品推薦給可能對其感興趣的使用者。系統冷啟動 利用使用者註冊提供的年齡性別等做粗粒度...

如何輕鬆實現個性化推薦系統

這裡採用的是.net的乙個引用nreco.recommender.dll,這是乙個國外電影 推薦系統衍生而來的,有興趣的可以到他們的官網看看。首先需要對資料庫進行設計,增加一張使用者的行為資料表,記錄使用者訪問 的行為,例如 的一般記錄瀏覽的商品和購買過的商品,根據你的業務邏輯進行設計。需要對商品的...

c 如何建立程式日誌系統

乙個好的軟體日誌系統的重要性 a.在軟體開發過程中,為了方便除錯,我們經常要輸出某些日誌,b.在單執行緒的時候,還可以直接看output視窗,但是多執行緒就要經常寫入日誌了。c.如果沒有日誌系統,在程式發布之後,出現問題了,就很難定位錯誤所在。所以,在乙個好的軟體,乙個好的程式,都會有自己的日誌系統...