日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

个性化排序的神经协同过滤

發布時間:2023/11/28 生活经验 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 个性化排序的神经协同过滤 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

個性化排序的神經協同過濾

Neural Collaborative Filtering for Personalized Ranking

這一部分將超越顯式反饋,介紹神經協作過濾(NCF)框架,用于推薦具有隱式反饋。隱式反饋在推薦系統中普遍存在。諸如點擊、購買和觀看等行為都是常見的隱性反饋,這些反饋很容易收集并指示用戶的偏好。我們將介紹的模型名為NeuMF[He et al.,2017b],是神經矩陣分解的縮寫,旨在解決帶有隱式反饋的個性化排名任務。該模型利用神經網絡的靈活性和非線性,代替矩陣分解的點積,提高模型的表達能力。具體地說,該模型由廣義矩陣分解(GMF)和多層感知器(MLP)兩個子網絡構成,用兩條路徑來模擬相互作用,而不是簡單的內積。將這兩個網絡的輸出連接起來,以計算最終的預測分數。與AutoRec中的評分預測任務不同,該模型基于隱含反饋為每個用戶生成一個排名推薦列表。我們將使用最后一節介紹的個性化排名損失來訓練這個模型。

  1. The NeuMF model

如上所述,NeuMF融合了兩個子網。GMF是矩陣分解的一種神經網絡模型,輸入是用戶和項目潛在因素的元素乘積。它由兩個神經層組成:

這個模型的另一個組件是MLP。為了增加模型的靈活性,MLP子網不與GMF共享用戶和項嵌入。它使用用戶和項嵌入的連接作為輸入。通過復雜的連接和非線性變換,它能夠模擬用戶和物品之間的復雜交互。更準確地說,MLP子網定義為:


Fig. 1 Illustration of the NeuMF model

from d2l import mxnet as d2l

from mxnet import autograd, gluon, np, npx

from mxnet.gluon import nn

import mxnet as mx

import random

import sys

npx.set_np()

  1. Model
    Implementation

下面的代碼實現了NeuMF模型。它由一個廣義矩陣分解模型和一個具有不同用戶和項目嵌入向量的多層感知器組成。MLP的結構由參數nums_hiddens控制。ReLU用作默認激活功能。

class NeuMF(nn.Block):

def __init__(self, num_factors, num_users, num_items, nums_hiddens,**kwargs):super(NeuMF, self).__init__(**kwargs)self.P = nn.Embedding(num_users, num_factors)self.Q = nn.Embedding(num_items, num_factors)self.U = nn.Embedding(num_users, num_factors)self.V = nn.Embedding(num_items, num_factors)self.mlp = nn.Sequential()for num_hiddens in nums_hiddens:self.mlp.add(nn.Dense(num_hiddens, activation='relu',use_bias=True))def forward(self, user_id, item_id):p_mf = self.P(user_id)q_mf = self.Q(item_id)gmf = p_mf * q_mfp_mlp = self.U(user_id)q_mlp = self.V(item_id)mlp = self.mlp(np.concatenate([p_mlp, q_mlp], axis=1))con_res = np.concatenate([gmf, mlp], axis=1)return np.sum(con_res, axis=-1)
  1. Customized Dataset with Negative Sampling

對于成對排序損失,一個重要的步驟是負采樣。對于每個用戶,用戶未與之交互的項是候選項(未觀察到的條目)。下面的函數以用戶身份和候選項作為輸入,并從每個用戶的候選項集中隨機抽取負項。在訓練階段,該模型確保用戶喜歡的項目的排名高于其不喜歡或未與之交互的項目。

class PRDataset(gluon.data.Dataset):

def __init__(self, users, items, candidates, num_items):self.users = usersself.items = itemsself.cand = candidatesself.all = set([i for i in range(num_items)])def __len__(self):return len(self.users)def __getitem__(self, idx):neg_items = list(self.all - set(self.cand[int(self.users[idx])]))indices = random.randint(0, len(neg_items) - 1)return self.users[idx], self.items[idx], neg_items[indices]
  1. Evaluator

在這一部分中,我們采用按時間分割的策略來構造訓練集和測試集。給定截線命中率的兩個評價指標?? (Hit@?Hit@?) and area
under the ROC curve (AUC),用ROC曲線下面積(AUC)評價模型的有效性。給定位置命中率?,對于每個用戶,指示建議的項目是否包含在頂部?排行榜。正式定義如下:

#@save

def hit_and_auc(rankedlist, test_matrix, k):

hits_k = [(idx, val) for idx, val in enumerate(rankedlist[:k])if val in set(test_matrix)]hits_all = [(idx, val) for idx, val in enumerate(rankedlist)if val in set(test_matrix)]max = len(rankedlist) - 1auc = 1.0 * (max - hits_all[0][0]) / max if len(hits_all) > 0 else 0

return len(hits_k), auc

然后,總體命中率和AUC計算如下。

#@save

def evaluate_ranking(net, test_input, seq, candidates, num_users, num_items,

                 ctx):ranked_list, ranked_items, hit_rate, auc = {}, {}, [], []all_items = set([i for i in range(num_users)])for u in range(num_users):neg_items = list(all_items - set(candidates[int(u)]))user_ids, item_ids, x, scores = [], [], [], [][item_ids.append(i) for i in neg_items][user_ids.append(u) for _ in neg_items]x.extend([np.array(user_ids)])if seq is not None:x.append(seq[user_ids, :])x.extend([np.array(item_ids)])test_data_iter = gluon.data.DataLoader(gluon.data.ArrayDataset(*x),shuffle=False,last_batch="keep",batch_size=1024)for index, values in enumerate(test_data_iter):x = [gluon.utils.split_and_load(v, ctx, even_split=False)for v in values]scores.extend([list(net(*t).asnumpy()) for t in zip(*x)])scores = [item for sublist in scores for item in sublist]item_scores = list(zip(item_ids, scores))ranked_list[u] = sorted(item_scores, key=lambda t: t[1], reverse=True)ranked_items[u] = [r[0] for r in ranked_list[u]]temp = hit_and_auc(ranked_items[u], test_input[u], 50)hit_rate.append(temp[0])auc.append(temp[1])return np.mean(np.array(hit_rate)), np.mean(np.array(auc))
  1. Training and Evaluating the Model

培訓功能定義如下。我們以成對的方式訓練模型。

#@save

def train_ranking(net, train_iter, test_iter, loss, trainer, test_seq_iter,

              num_users, num_items, num_epochs, ctx_list, evaluator,candidates, eval_step=1):timer, hit_rate, auc = d2l.Timer(), 0, 0animator = d2l.Animator(xlabel='epoch', xlim=[1, num_epochs], ylim=[0, 1],legend=['test hit rate', 'test AUC'])for epoch in range(num_epochs):metric, l = d2l.Accumulator(3), 0.for i, values in enumerate(train_iter):input_data = []for v in values:input_data.append(gluon.utils.split_and_load(v, ctx_list))with autograd.record():p_pos = [net(*t) for t in zip(*input_data[0:-1])]p_neg = [net(*t) for t in zip(*input_data[0:-2],input_data[-1])]ls = [loss(p, n) for p, n in zip(p_pos, p_neg)][l.backward(retain_graph=False) for l in ls]

l += sum([l.asnumpy() for l in ls]).mean()/len(ctx_list)

        trainer.step(values[0].shape[0])metric.add(l, values[0].shape[0], values[0].size)timer.stop()with autograd.predict_mode():if (epoch + 1) % eval_step == 0:hit_rate, auc = evaluator(net, test_iter, test_seq_iter,candidates, num_users, num_items,ctx_list)animator.add(epoch + 1, (hit_rate, auc))print('train loss %.3f, test hit rate %.3f, test AUC %.3f'% (metric[0] / metric[1], hit_rate, auc))print('%.1f examples/sec on %s'% (metric[2] * num_epochs / timer.sum(), ctx_list))

現在,我們可以加載MovieLens
100k數據集并訓練模型。由于在MovieLens數據集中只有評級,但準確性會有所下降,因此我們將這些評級進行二值化,即0和1。如果一個用戶對一個項目進行評分,我們認為隱含反饋為1,否則為零。給一個項目評分的行為可以看作是一種提供隱性反饋的形式。在這里,我們在seq感知模式下分割數據集,在這種模式下,用戶的最新交互項被排除在外進行測試。

batch_size = 1024

df, num_users, num_items = d2l.read_data_ml100k()

train_data, test_data = d2l.split_data_ml100k(df, num_users, num_items,

                                          'seq-aware')

users_train, items_train, ratings_train, candidates = d2l.load_data_ml100k(

train_data, num_users, num_items, feedback="implicit")

users_test, items_test, ratings_test, test_iter = d2l.load_data_ml100k(

test_data, num_users, num_items, feedback="implicit")

num_workers = 0 if sys.platform.startswith(“win”) else 4

train_iter = gluon.data.DataLoader(PRDataset(users_train, items_train,

                                         candidates, num_items ),batch_size, True,last_batch="rollover",num_workers=num_workers)

然后我們創建并初始化模型。我們使用一個三層MLP,隱藏大小恒定為10。

ctx = d2l.try_all_gpus()

net = NeuMF(10, num_users, num_items, nums_hiddens=[10, 10, 10])

net.initialize(ctx=ctx, force_reinit=True, init=mx.init.Normal(0.01))

下面的代碼訓練模型。

The following code trains the model.

lr, num_epochs, wd, optimizer = 0.01, 10, 1e-5, ‘adam’

loss = d2l.BPRLoss()

trainer = gluon.Trainer(net.collect_params(), optimizer,

                    {"learning_rate": lr, 'wd': wd})

train_ranking(net, train_iter, test_iter, loss, trainer, None, num_users,

          num_items, num_epochs, ctx, evaluate_ranking, candidates)

train loss 4.030, test hit rate 0.322, test AUC 0.736

13.1 examples/sec on [gpu(0), gpu(1)]

6. Summary

· Adding nonlinearity to matrix factorization model is beneficial for improving the model capability and effectiveness.

· NeuMF is a combination of matrix factorization and Multilayer perceptron. The multilayer perceptron takes the concatenation of user and item embeddings as the input.

總結

以上是生活随笔為你收集整理的个性化排序的神经协同过滤的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。