个性化推荐算法系统(1):基于邻域的个性化召回算法LFM(MovieLens数据集电影推荐)

目录

一、LFM理论

二、LFM实战

2.1 数据处理:read.py

1、得到电影信息

2、得到每部电影平均得分

3、准备LFM数据

2.2 LFM主体函数编写:LFM.py

1、初始化向量

2、计算模型预测出用户向量和电影向量之前的距离,欧氏距离

3、得到lfm模型的用户向量和电影向量

4、使用lfm得到的推荐结果,和得分

5、启动函数

6、分析推荐结果的好坏(只是打印出来)

7、go


代码、数据集下载:https://download.csdn.net/download/qq_35883464/11225488

LFM(latent factor model)隐语义模型核心思想是通过隐含特征联系用户兴趣和物品。 

相比USerCF算法(基于类似用户进行推荐)和ItemCF(基于类似物品进行推荐)算法;

我们还可以直接对物品和用户的兴趣分类。对应某个用户先得到他的兴趣分类,确定他喜欢哪一类的物品,再在这个类里挑选他可能喜欢的物品。

对于LFM(latent factor model)的数学原理网络上很多博客都有提及,这里不再细讲,只是和代码一起讲解

 

一、LFM理论

 

建模公式:

公式解释:如果user(用户)点击了item(物品)p(u,i)则为1,反之则为0.模型的最终输出为user的向量(pu)、item向量(qi)  相乘是一个数字,通过梯度下降迭代。

loss function:

上面的公式中前面项是真实值,后面一项为预测值

loss function加入正则项:

就可以,求得:

具体用代码讲解

 

二、LFM实战

电影推荐实战

先看看数据集movies:(电影ID、电影名、类型)

 

数据集movies:(用户ID、用户打分的电影ID、分数、时间戳)

 

2.1 数据处理:read.py

 

  • 1、得到电影信息

def get_item_info(input_file):
    '''
    get item info :[title, gemre]
    :param item
    :return: a dict: key item_id, value:[title, genre]
    '''

    if not os.path.exists(input_file):
        return {}
    linenum = 0
    item_info = {}
    fp = open(input_file, encoding='UTF-8')
    for line in fp:
        if linenum == 0:   # 第一行数据不需要
            linenum += 1
            continue
        item = line.strip().split(',')
        if len(item) < 3:
            continue
        elif len(item) == 3:
            itemid, title, genre = item[0], item[1], item[2]
        elif len(item) > 3:
            itemid = item[0]
            genre = item[-1]
            title = ','.join(item[1:-1])
        item_info[itemid] = [title, genre]
    fp.close()
    return item_info

 

  • 2、得到每部电影平均得分

def get_ave_score(input_file):
    '''
    get item ave roting score
    :param input_file: user rating file
    :return: dict,key:itemid,value:sve_score
    '''

    if not os.path.exists(input_file):
        return {}
    linenum = 0
    record_dict = {}
    score_dict = {}
    tp = open(input_file, encoding='UTF-8')
    for line in tp:
        if linenum == 0:
            linenum += 1
            continue
        item = line.strip().split(',')
        if len(item) < 4:
            continue
        userid,itemid,rating = item[0],item[1],float(item[2])
        if itemid not in record_dict:
            record_dict[itemid] = [0,0]
        record_dict[itemid][0] += 1
        record_dict[itemid][1] += rating
    tp.close()
    for itemid in record_dict:
        score_dict[itemid] = round(record_dict[itemid][1]/record_dict[itemid][0],3)
        return score_dict

 

  • 3、准备LFM数据

def get_train_data(input_file):
    '''
    get train data for LFM model train
    :param input_file:user item rating file
    :return:a list: [(userid,itemid,label),(userid1,itemid,label)]
    '''
    if not os.path.exists(input_file):
        return {}
    score_dict = get_ave_score(input_file)
    neg_dic = {}
    pos_dic = {}
    train_data = []
    linenum = 0
    with open(input_file, encoding='UTF-8') as fp:
        for line in fp:
            if linenum == 0:
                linenum += 1
                continue
            item = line.strip().split(',')
            if len(item) < 4:
                continue
            userid,item,rating = item[0],item[1],float(item[2])
            if userid not in pos_dic:
                pos_dic[userid] = []
            if userid not in neg_dic:
                neg_dic[userid] = []

            if rating >= 4.0:
                pos_dic[userid].append((item, 1))
            else:
                score = score_dict.get(item, 0)
                neg_dic[userid].append((item,score))

    for userid in pos_dic:
        data_num = min(len(pos_dic[userid]), len(neg_dic.get(userid,[])))
        if data_num > 0:
            train_data += [(userid,zuhe[0],zuhe[1]) for zuhe in pos_dic[userid]][:data_num]
        else:
            continue

        sorted_neg_list = sorted(neg_dic[userid], key=lambda element : element[1], reverse=True)
        train_data += [(userid,zuhe[0],0) for zuhe in sorted_neg_list]
    return train_data

 

2.2 LFM主体函数编写:LFM.py

 

  • 1、初始化向量

def init_model(vector_len):
    '''

    :param vector_len: the len of vector
    :return: ndarray
    '''
    return np.random.randn(vector_len)

 

  • 2、计算模型预测出用户向量和电影向量之前的距离,欧氏距离

def model_predict(user_vector, item_vector):
    '''

    :param user_vector: model produce user distance
    :param item_vector: model produce item distance
    :return:   a num
    '''
    res = np.dot(user_vector,item_vector)/(np.linalg.norm(user_vector)*np.linalg.norm(item_vector))
    return res

 

  • 3、得到lfm模型的用户向量和电影向量

ef lfm_train(train_data,F,alpha,beta,step):
    '''
    得到lfm模型的用户向量和电影向量
    train_data:train_data for lfm
    F:user_vector len,item_vector len
    alpha: regularization factor
    beta:learning rate
    step:iteration num
    :return:
        dic:key itemid,value:ndarray
        dic:key userid,value:ndarray
    '''
    user_vec ={}
    item_vec ={}

    for step_index in range(step):
        for data_instance in train_data:
            userid,itemid,label = data_instance
            if userid not in user_vec:
                user_vec[userid] = init_model(F)
            if itemid not in item_vec:
                item_vec[userid] = init_model(F)
        delta = label - model_predict(user_vec[userid], item_vec[itemid])
        for index in range(F):    # 在这里和公式不一样,是实际工程的应用,没有2倍
            user_vec[userid][index] = user_vec[userid][index] - beta*(-delta*item_vec[itemid][index] + alpha*user_vec[userid][index])
            item_vec[itemid][index] = item_vec[itemid][index] - beta*(-delta*user_vec[userid][index] + alpha*item_vec[itemid][index])
        beta = beta*0.9
    return user_vec, item_vec

 

  • 4、使用lfm得到的推荐结果,和得分

def give_recom_result(user_vec, item_vec, userid):
    '''
    user lfm model result give fix userid recom result
    :param user_vec: lfm model result
    :param item_vec: lfm model result
    :param userid: fix userid
    :return:list : [(itemid,score), (itemid1,score1)]
    '''
    if userid not in user_vec:
        return []
    record = {}
    recom_list = []
    fix_num = 5
    user_vecor = user_vec[userid]
    for itemid in item_vec:
        item_vector = item_vec[itemid]
        res = np.dot(user_vecor,item_vector)/(np.linalg.norm((user_vecor)*np.linalg.norm(item_vector)))
        record[itemid] = res                    # record={'itemid':'res'}
        record_list = list(record.items())      # record.items()=[(itemid,res),(itemid,res)]   在此用list转换格式是Python3的不兼容问题
    for zuhe in sorted(record.items(), key=lambda rec: record_list[1], reverse=True)[:fix_num]:
        itemid = zuhe[0]
        score = round(zuhe[1],3)
        recom_list.append((itemid,score))
    return recom_list

 

  • 5、启动函数

def model_train_process():
    '''
    test lfm model train
    :return:
    '''
    train_data = read.get_train_data('ratings.csv')
    user_vec,item_vec = lfm_train(train_data,50,0.01,0.1,50)

    recom_result = give_recom_result(user_vec, item_vec, '11')
    ana_recom_result(train_data, '11', recom_result)

这里lfm的参数是随便设置的,大家可以cv来调参。最后2行是显示例子

 

  • 6、分析推荐结果的好坏(只是打印出来)

def ana_recom_result(train_data,userid,recom_list):
    '''
    :param train_data: 之前用户对哪些电影打分高
    :param userid: 分析的用户
    :param recom_list:模型给出的推荐结果
    '''
    item_info = read.get_item_info('movies.csv')
    for data_instance in train_data:
        userid1,itemid,label = data_instance
        if userid1 == userid and label == 1:
            print(item_info[itemid])
    print('返回结果:')
    for zuhe in recom_list:
        print(item_info[zuhe[0]])

 

  • 7、go

if __name__ == '__main__':
    model_train_process()

 

 

 

 

 

 

  • 5
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
基于深度学习的个性化学习资源自适应推荐系统的设计如下: 1. 数据集准备:收集用户的个人信息、历史行为数据、学习目标等信息,同时收集学习资源的描述、关键词、类别等信息,将其转化为向量表示。 2. 深度学习模型设计:设计深度学习模型,可以使用卷积神经网络(CNN)、循环神经网络(RNN)或者注意力机制(Attention)等模型,对用户和学习资源进行建模,同时考虑它们之间的交互。例如,可以设计一个基于RNN的模型,将用户的历史行为序列和学习资源的描述序列作为输入,输出用户对学习资源的兴趣程度。 3. 模型训练:使用训练集对深度学习模型进行训练,目标是最小化预测评分与真实评分之间的误差。可以使用交叉熵损失函数等常见的损失函数。 4. 模型推荐:对于每个用户,根据其历史行为和兴趣,选取与其兴趣最接近的学习资源进行推荐推荐过程可以使用基于邻域的方法、基于矩阵分解的方法等。 5. 模型评估:使用评估指标,例如准确率、召回率、F1值等对模型进行评估,从而确定模型的性能和优化方向。 6. 模型优化:根据模型评估结果,对模型进行优化。可以考虑增加更多的特征、调整模型结构、调整超参数等方法。 以上是基于深度学习的个性化学习资源自适应推荐系统的设计,具体实现可以根据需求进行调整和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值