【数据挖掘】推荐系统(二):基于内容的推荐

news2024/9/20 20:53:05

五、基于内容的系统

5.1 基本原理

        基于内容的系统根据用户偏好和配置文件生成建议。他们尝试将用户与他们以前喜欢的项目相匹配。项目之间的相似程度通常根据用户喜欢的项目的属性来确定。与大多数利用目标用户和其他用户之间的评级的协作过滤模型不同,基于内容的模型侧重于目标用户自己提供的评级。从本质上讲,基于内容的方法利用不同的数据源来生成建议。

        基于内容的系统的最简单形式需要以下数据源(这些要求可能会根据您尝试构建的系统的复杂性而增加):

  1. 项目级数据源 — 您需要与项目属性关联的强大数据源。对于我们的场景,我们有书价、num_pages、published_year等。您了解有关该项目的信息越多,它对您的系统就越有利。
  2. 用户级数据源 - 您需要根据您为其提供建议的项目提供某种用户反馈。此级别的反馈可以是隐式的,也可以是显式的。在我们的示例数据中,我们针对用户对他们阅读过的图书进行评分。您可以跟踪的用户反馈越多,对您的系统就越有利。

5.2 基于内容推荐的优缺点 

5.2.1 优势

当可用的评级数据量不足时,基于内容的模型对于推荐项目最有利。这是因为用户可能已对具有类似属性的其他项目进行了评级。因此,即使没有大量数据,模型也应该能够利用评级和项目属性来生成建议。

5.2.2弊端

基于内容的系统有两个主要缺点。

  1. 根据用户消费的项目/内容,提供的建议是“显而易见的”。这是一个缺点,因为如果用户从未与特定类型的项目交互,则永远不会向用户推荐该项目。例如,如果你从未读过神秘书籍,那么通过这种方法,您将永远不会被推荐神秘书籍。这是因为该模型是特定于用户的,并且没有利用来自类似用户的知识。这减少了建议的多样性,这对许多企业来说是一个负面的结果。
  2. 它们无法为新用户提供建议。构建模型时,您需要项目的显式/隐式用户级数据的历史记录。通常,拥有一个大型评级数据集,以便在不过度拟合的情况下进行可靠的预测,这一点很重要。

5.3  例子

        基于内容的系统的一些例子是:

  • 亚马逊产品 Feed(向您推荐的产品与您之前购买的产品相似)
  • Spotify 音樂推薦

        有许多优秀的基于内容的系统是用算法构建的,不依赖于基于模型的方法。例如,像Hacker Rank和Reddit这样的公司以前曾使用算法方法来向用户推荐其平台上的新帖子。为基于内容的推荐器构建算法方法的关键在于为您的业务定义一组可用于对项目进行排名的规则。就Reddit而言,他们的推荐受到发布时间,喜欢数量,不喜欢数量,评论数量等的限制。这可以考虑在公式中以生成帖子的分数,高分数将产生高推荐,反之亦然。

5.3.1 实现

  1. 从generate_data功能(上面提供的功能)导入数据或从此处下载CSV
  2. 规范化book_price、book_ratings num_pages
  3. 一个热编码publish_year、book_genre text_lang
  4. 给定一个book_id输入,计算余弦相似性并返回与输入相似的前 n 本书
import pandas as pd
import numpy as np
from numpy import dot
from numpy.linalg import norm 

def normalize(data):
    '''
    This function will normalize the input data to be between 0 and 1
    
    params:
        data (List) : The list of values you want to normalize
    
    returns:
        The input data normalized between 0 and 1
    '''
    min_val = min(data)
    if min_val < 0:
        data = [x + abs(min_val) for x in data]
    max_val = max(data)
    return [x/max_val for x in data]

def ohe(df, enc_col):
    '''
    This function will one hot encode the specified column and add it back
    onto the input dataframe
    
    params:
        df (DataFrame) : The dataframe you wish for the results to be appended to
        enc_col (String) : The column you want to OHE
    
    returns:
        The OHE columns added onto the input dataframe
    '''
    
    ohe_df = pd.get_dummies(df[enc_col])
    ohe_df.reset_index(drop = True, inplace = True)
    return pd.concat([df, ohe_df], axis = 1)

class CBRecommend():
    def __init__(self, df):
        self.df = df
        
    def cosine_sim(self, v1,v2):
        '''
        This function will calculate the cosine similarity between two vectors
        '''
        return sum(dot(v1,v2)/(norm(v1)*norm(v2)))
    
    def recommend(self, book_id, n_rec):
        """
        df (dataframe): The dataframe
        song_id (string): Representing the song name
        n_rec (int): amount of rec user wants
        """
        
        # calculate similarity of input book_id vector w.r.t all other vectors
        inputVec = self.df.loc[book_id].values
        self.df['sim']= self.df.apply(lambda x: self.cosine_sim(inputVec, x.values), axis=1)

        # returns top n user specified books
        return self.df.nlargest(columns='sim',n=n_rec)

if __name__ == '__main__':
    # constants
    PATH = '../data/data.csv'

    # import data
    df = pd.read_csv(PATH)

    # normalize the num_pages, ratings, price columns
    df['num_pages_norm'] = normalize(df['num_pages'].values)
    df['book_rating_norm'] = normalize(df['book_rating'].values)
    df['book_price_norm'] = normalize(df['book_price'].values)
    
    # OHE on publish_year and genre
    df = ohe(df = df, enc_col = 'publish_year')
    df = ohe(df = df, enc_col = 'book_genre')
    df = ohe(df = df, enc_col = 'text_lang')
    
    # drop redundant columns
    cols = ['publish_year', 'book_genre', 'num_pages', 'book_rating', 'book_price', 'text_lang']
    df.drop(columns = cols, inplace = True)
    df.set_index('book_id', inplace = True)
    
    # ran on a sample as an example
    t = df.copy()
    cbr = CBRecommend(df = t)
    print(cbr.recommend(book_id = t.index[0], n_rec = 5))

六、混合推荐系统

6.1 原理和直觉

        推荐系统的各种方法都有其自身的优点和缺陷。通常,其中许多方法在单独使用时可能看起来很严格,尤其是当有多个数据源可用于该问题时。混合推荐系统旨在使用不同的可用数据源来生成可靠的推理。

        混合推荐系统有两种主要设计,并行和顺序。并行设计为多个推荐系统提供输入,每个推荐组合在一起生成一个输出。顺序设计将输入参数提供给单个推荐引擎,输出按顺序传递给下一个推荐器。有关两种设计的可视化表示,请参阅下图。

        并行和顺序推荐系统架构。图片由C.C. Aggarwal提供,推荐系统:教科书

6.2 系统优缺点

6.2.1 优势

        混合系统结合了不同的模型,以克服一种模型与另一种模型的缺点。这总体上减少了使用单个模型的弱点,并有助于生成更可靠的建议。这为用户提供了更强大和个性化的建议。

6.2.2 弊端

        这些类型的模型通常具有很高的计算复杂性,并且需要包含评级和其他属性的大型数据库才能保持最新状态。如果没有最新的指标(用户参与度、评级等),就很难重新训练并提供来自不同用户的更新项目和评级的新建议。

6.3  案例

        Netflix 是一家使用混合推荐系统的公司,他们根据相似用户的观看和搜索风格(协同过滤)以及具有相似特征的电影(基于内容)向用户生成推荐。

6.3.1 实现

  1. 从generate_data功能(上面提供的功能)导入数据或从此处下载CSV
  2. 使用基于内容的模型 (cosine_similarity) 计算 50 本最相似的书籍
  3. 使用协作
    过滤模型 (SVD) 计算用户可能为这 50 本书提供的预测评分
  4. 返回预测评分最高的前 n 本图书
import pandas as pd
import numpy as np

from sklearn.metrics.pairwise import cosine_similarity
from surprise import SVD, Reader, Dataset, accuracy
from surprise.model_selection import train_test_split

def hybrid(reader_id, book_id, n_recs, df, cosine_sim, svd_model):
    '''
    This function represents a hybrid recommendation system, it will have the following flow:
        1. Use a content-based model (cosine_similarity) to compute the 50 most similar books
        2. Compute the predicted ratings that the user might give these 50 books using a collaborative
           filtering model (SVD)
        3. Return the top n books with the highest predicted rating
        
    params:
        reader_id (Integer) : The reader_id 
        book_id (Integer) : The book_id 
        n_recs (Integer) : The number of recommendations you want
        df (DataFrame) : Original dataframe with all book information 
        cosine_sim (DataFrame) : The cosine similarity dataframe
        svd_model (Model) : SVD model
    '''
    
    # sort similarity values in decreasing order and take top 50 results
    sim = list(enumerate(cosine_sim[int(book_id)]))
    sim = sorted(sim, key=lambda x: x[1], reverse=True)
    sim = sim[1:50]
    
    # get book metadata
    book_idx = [i[0] for i in sim]
    books = df.iloc[book_idx][['book_id', 'book_rating', 'num_pages', 'publish_year', 'book_price', 'reader_id']]
    
    # predict using the svd_model
    books['est'] = books.apply(lambda x: svd_model.predict(reader_id, x['book_id'], x['book_rating']).est, axis = 1)
    
    # sort predictions in decreasing order and return top n_recs
    books = books.sort_values('est', ascending=False)
    return books.head(n_recs)
  
if __name__ == '__main__':
    # constants
    PATH = '../data/data.csv'

    # import data
    df = pd.read_csv(PATH)

    # content based
    rmat = df.pivot_table(
        columns = 'book_id',
        index = 'reader_id',
        values = 'book_rating'
    ).fillna(0)

    #Compute the cosine similarity matrix 
    cosine_sim = cosine_similarity(rmat, rmat)
    cosine_sim = pd.DataFrame(cosine_sim, index=rmat.index, columns=rmat.index)

    # collaborative filtering
    reader = Reader()
    data = Dataset.load_from_df(df[['reader_id', 'book_id', 'book_rating']], reader)

    # split data into train test
    trainset, testset = train_test_split(data, test_size=0.3,random_state=10)

    # train
    svd = SVD()
    svd.fit(trainset)

    # run the trained model against the testset
    test_pred = svd.test(testset)

    # get RMSE
    accuracy.rmse(test_pred, verbose=True)
    
    # generate recommendations
    r_id = df['reader_id'].values[0]
    b_id = df['book_id'].values[0]
    n_recs = 5
    print(hybrid(r_id, b_id, n_recs, df, cosine_sim, svd))

 如果你想要一个关于如何以上面未显示的不同方式实现混合推荐系统的分步指南,你可以参考我的文章 使用 Node2Vec 构建链接预测推荐引擎。

七、结束语

        请注意,这只是对推荐引擎的介绍。还有更多类型和方法来构建强大的推荐引擎,本文未涵盖这些内容。一些值得注意的是通过链接预测、算法方法、贝叶斯模型、马尔可夫模型等生成建议......

        本文的目的是直观地理解和实现用于推荐系统(协同过滤、基于内容和混合)的基本方法。协同过滤是通过识别来自许多用户的偏好和信息来预测用户兴趣的过程,而基于内容的系统根据用户的偏好和配置文件生成建议。混合系统通常是许多推荐系统的组合。

        我将在下面列出一些值得思考的内容,以评估建议的质量。这些问题在本文中没有回答,但在构建良好的推荐系统时是必不可少的。

  • 如何跟踪推荐的流失率、响应能力、参与度和新颖性?
  • 在知道用户 X 时间未与前一个推荐交互后,何时应向用户显示新推荐?
  • 当用户对新产品进行评分或互动时,它会立即或稍后影响您的推荐系统?
  • 随着用户与平台互动的增加,推荐会如何变化?
  • 您如何知道您的建议不会将用户限制在业务的次要部分?

        我特意尝试实现每种推荐系统的不同版本,以便更广泛地了解它们的实现。可以在此处查看用于生成这些结果的所有代码和数据。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/729664.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

设计模式之模板方法实现抽奖功能

1.项目背景 接到一个需求&#xff0c;实现电商营销模块的圆盘抽奖功能。如果大家有关注市面上的抽奖&#xff0c;大致也是圆盘抽奖、九宫格抽奖&#xff0c;随机抽球等等。尤其是电商行业&#xff0c;会有各种各样的活动&#xff0c;因此也会出现各式各样的抽奖&#xff0c;那…

【InnoDB 存储引擎】15.7.1 InnoDB Locking(锁实验,重要)

文章目录 1 关于 Record Lock 的实验1.1 实验 1&#xff1a;没有主键时的如何锁定1.2 实验 1&#xff08;续&#xff09;&#xff1a;带着问题继续实验1.3 实验 2&#xff1a;有主键时如何锁定 2 关于 Next-Key Lock 的实验2.1 实验 3&#xff1a;如何确定算法的锁定范围2.2 实…

HTML期末作业-精仿故宫模板(HTML+CSS+JavaScript)

期末作业完成&#xff01;我仿了故宫官网&#xff0c;老师给了90分。现在分享给大家&#xff01; 首页包含功能&#xff1a; 轮播图&#xff1a;在首页顶部设置一个可自动轮播的图片展示区域&#xff0c;展示多张宣传图片或产品图片&#xff0c;提升页面的视觉效果和吸引力。…

从0训练一个神经网络分类器

从0训练一个神经网络分类器 0. 关于数据&#xff1f; 训练一个图像分类器1. 使用torchvision可以非常容易地加载CIFAR10。2. 定义一个卷积神经网络3. 定义损失函数和优化器4. 训练网路5. 在测试集上测试网络6. 检测网络在整个测试集上的结果如何。7. 在识别哪一个类的时候好&am…

MySQL基操例题

Ⅰ创建数据库使用create语句&#xff1a; create database 数据库名&#xff1b; Ⅱ创建表同理&#xff1a; create table if not exists 表名 &#xff08; 字段名 数据类型 主键 约束&#xff0c; 字段名 数据类型 主键 约束&#xff09; 设置存储引擎和字符集&#xff1b; …

Text-Augmented Open Knowledge Graph Completion viaPre-Trained Language Models

摘要 开放知识图谱(KG)完成的任务是从已知的事实中得出新的发现。增加KG完成度的现有工作需要(1)事实三元组来扩大图推理空间,或(2)手动设计提示从预训练的语言模型(PLM)中提取知识,表现出有限的性能,需要专家付出昂贵的努力。为此,我们提出了TAGREAL,它自动生成高质量的…

【youcans动手学模型】SENet 模型及 PyTorch 实现

欢迎关注『youcans动手学模型』系列 本专栏内容和资源同步到 GitHub/youcans 【youcans动手学模型】SENet 模型 【经典模型】SENet 模型-Cifar10图像分类1. SENet 卷积神经网络模型1.1 模型简介1.2 论文介绍1.3 分析与讨论 2. 在 PyTorch 中定义 SENet 模型类2.1 定义 SE Block…

STL好难(5):stack的使用

目录 1.stack的介绍和使用&#xff1a; 2.stack的使用 3.有关stack的练习题&#xff1a; &#x1f349;最小栈 &#x1f349;栈的压入、弹出序列 4.stack的模拟实现&#xff1a; 1.stack的介绍和使用&#xff1a; 点击查看stack的文档介绍 1. stack是一种容器适配器&#…

(vue)element-ui表格中插入switch开关

(vue)element-ui表格中插入switch开关 效果&#xff1a; <el-table-column property"enabled" label"启用/禁用" width"150"><template slot-scope"scope"> <el-switchv-model"scope.row.enabled"active-co…

动态规划之746 使用最小花费爬楼梯(第3道)

题目&#xff1a; 给你一个整数数组 cost &#xff0c;其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用&#xff0c;即可选择向上爬一个或者两个台阶。 你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。 请你计算并返回达到楼梯顶部的最低花费…

差分学习笔记

1.前言 同步于 c n b l o g s cnblogs cnblogs 发布。 前置芝士&#xff1a; 基本树上操作&#xff0c;lca。&#xff08;用于树上差分。&#xff09; 如有错误&#xff0c;欢迎各位大佬指出。&#xff08;顺便复习一下远古算法。&#xff09; 2.什么是差分 我们先给定一…

AR增强现实技术解决企业远程协作需求

随着科技的不断发展&#xff0c;AR(增强现实)远程协同系统已经成为了一种新型的工作方式。这种系统利用AR技术将虚拟信息叠加到现实世界中&#xff0c;从而实现异地高效协作。 由广州华锐互动开发的AR远程协同系统&#xff0c;广泛应用于各个行业的远程协作场景中&#xff0c;…

44. 通配符匹配(从暴力递归到动态规划)

题目链接&#xff1a;力扣 所有的动态规划都可以使用暴力递归求解&#xff0c;如果推导dp方程比较困难&#xff0c;可以先使用暴力递归进行尝试&#xff0c;然后将从递归改为动态规划&#xff0c;这种方式在dp方程求解困难的情况下非常有效&#xff0c;而且从递归修改为动态规划…

计算机网络?

那么这样能通过审核吗&#xff1f;

二次元古代美女【InsCode Stable Diffusion美图活动一期】

二次元古代美女【InsCode Stable Diffusion美图活动一期】 一、前言二、初识 InsCode三、 试玩 Stable Diffusion 模型1.阅读Stable Diffusion 模型在线引导说明2.实际体验 Stable Diffusion 模型 四、模型相关版本和参数配置&#xff1a;五、图片生成提示词与反向提示词六、种…

游戏术语英语

王者荣耀英文术语大全&#xff01;玩这么久你都听懂了吗&#xff1f; 王者荣耀AP、AD、ADC、AOE等专业术语大全_乐游网 Operating System win2003, winXP, win7, win10 MacOS Game Platform 游戏平台 TGP&#xff08;Tencent Game Platform &#xff09; PC &#xff08;Per…

Linux上部署docker与docker-compose的步骤

Centos上部署docker与docker-compose的步骤 linux系统版本为Centos7.2 第一步-检查前置条件是否符合部署docker 64-bit 系统 kernel 3.10 使用uname -r 检查内核版本&#xff0c;返回的值大于3.10即可。 Centos 7.2的kernel是&#xff1a;3.10.0-327&#xff0c;刚好满足条件…

【算法与数据结构】225、LeetCode用队列实现栈

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析&#xff1a;第一种解法是利用两个队列&#xff0c;一个用作输出队列&#xff0c;一个用作备份队列。主要难点在于p…

<Java导出Excel> 4.0 Java实现Excel动态模板字段增删改查

思路&#xff1a; 主要是同时操作两张表&#xff1a;一张存储数据的表&#xff0c;一张存储模板字段的表&#xff1b; 查询&#xff1a;只查询模板字段的表&#xff1b; 新增&#xff0c;修改&#xff0c;删除&#xff1a;需要同时操作两张表中的字段 如果两张表字段不一致&…

51单片机--点亮LED灯和流水灯

文章目录 前言LED模块的原理点亮一个LED灯LED灯的闪烁LED流水灯 前言 大家好&#xff0c;这里是诡异森林。我使用的是普中科技的A2的51开发板&#xff0c;适合新手入门。用到的应用是Keil5和Stc-isp&#xff0c;第一个软件主要用来写代码的&#xff0c;第二个是将代码程序输送…