【代码解析(1)】Secure Federated Matrix Factorization

该Python脚本实现了一个分布式矩阵分解算法,用于更新用户和物品向量。在用户和物品的交互数据上,它迭代地执行用户更新和服务器更新过程,通过最小化误差来优化模型。当物品向量的更新达到预设收敛条件时,算法停止。
摘要由CSDN通过智能技术生成

DistributeMF_Full.py

import time
import copy
import numpy as np

from load_data import ratings_dict, item_id_list, user_id_list
from shared_parameter import *

# print(ratings_dict)


def user_update(single_user_vector, user_rating_list, item_vector):
    """
    :param single_user_vector:
    :param user_rating_list:
    :param item_vector:
    :return:
    函数的作用: 更新user_vector和gradient
    """
    gradient = np.zeros([len(item_vector), len(single_user_vector)])
    # gradient矩阵初始化,行为item数,列为user数、
    # too many values to unpack (expected 2)
    for item_id, rate, _ in user_rating_list:
        error = rate - np.dot(single_user_vector, item_vector[item_id])
        # 对于用户user,一个交互记录就更新一次向量
        single_user_vector = single_user_vector - lr * (-2 * error * item_vector[item_id] + 2 * reg_u * single_user_vector)
        gradient[item_id] = error * single_user_vector
    # print(single_user_vector)
    # print('00000000000')
    # print(gradient)

    return single_user_vector, gradient


def loss():
    loss = []
    # User updates
    for i in range(len(user_id_list)):
        # user_id_list: ['1', '4', '5', '6', '7', '8', '10']
        for r in range(len(ratings_dict[user_id_list[i]])):
            # len(ratings_dict[user_id_list[i]])表示有几个交互记录
            # too many values to unpack (expected 2)
            # 因为后面一句返回三个值,前面只有两个变量接收,所以要加一个'_'
            item_id, rate, _ = ratings_dict[user_id_list[i]][r]

            error = (rate - np.dot(user_vector[i], item_vector[item_id])) ** 2
            loss.append(error)
    return np.mean(loss)


if __name__ == '__main__':

    # Init process
    # 初始化用户矩阵和item矩阵
    # np.random.normal()从正态高斯分布中抽取随机样本作为矩阵的填充值。
    user_vector = np.random.normal(size=[len(user_id_list), hidden_dim])
    # print(user_vector)
    item_vector = np.random.normal(size=[len(item_id_list), hidden_dim])

    start_time = time.time()

    for iteration in range(max_iteration):

        print('###################')
        t = time.time()

        # Step 2 User updates
        gradient_from_user = []
        for i in range(len(user_id_list)):
            """
                更新用户矩阵的每一个用户行
                以及gradient矩阵,gradient的行为item,列为user
            """
            user_vector[i], gradient = user_update(user_vector[i], ratings_dict[user_id_list[i]], item_vector)
            """
                遍历完一个用户的所有交互记录将最终的gradient存入gradient_from_user
            """
            gradient_from_user.append(gradient)
        # print(gradient_from_user) 列表

        '''
            item的更新源于g的值
            g的值是User update来的
            妙啊!!
        '''
        # Step 3 Server update
        tmp_item_vector = copy.deepcopy(item_vector)
        # print(item_vector)
        # tmp_item_vector存储一下item_vector更新之前的值
        for g in gradient_from_user:
            item_vector = item_vector - lr * (-2 * g + 2 * reg_u * item_vector)

        # 拟合条件,更新后的矩阵与原始矩阵(每个矩阵,每一行值都是不一样的因为这次是正态分布值)的差值的平均小于0.0004

        if np.mean(np.abs(item_vector - tmp_item_vector)) < 1e-4:
            print('Converged')
            break

        print('Time', time.time() - t, 's')

        print('loss', loss())

    print('Converged using', time.time() - start_time)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
>