基于上下文的推荐 -- 包括时间衰减算法和位置推荐算法(代码实现)

2023-11-02

基于时间特征的推荐

时间信息对用户兴趣的影响:

  1. 物品具有生命周期(例如春节档电影)
  2. 用户兴趣随时间变化
  3. 季节效应(冬奶茶夏圣代,吸溜)
    所以在给定时间信息后,对于推荐系统变成了一个时变的系统。

对于Delicious数据集(包括4部分–用户ID,日期,网页URL和标签)我们用不同的指标可以度量网站中物品的生命周期:

  • 物品评价在线天数
  • 相隔T天系统物品流行度向量的平均相似度(判断用户兴趣的转变)
    在这里插入图片描述
    可以看到成指数级下降,即我们推荐时要降低几天前的权重。
    实现实时性要求推荐算法:
  • 要求每个用户访问时,要根据用户当前时间点前的行为实时计算推荐列表。
  • 推荐算法要平衡考虑用户近期和长期行为(用户有长期的兴趣爱好)

对于现实中的推荐系统表现可以看出:对于推荐的书籍会在你搜索某本书籍时发生一两本的变化,但是整体还是稳定的,维持着用户长期兴趣的推荐。

通过对用户调查的实验观察得出:
在这里插入图片描述
对于没有用户行为时,实现时间多样性的方法:

  • 在生成结果时加入随机性
  • 记录用户每天看到的推荐结果,再次推荐时针对前几天看到很多次的推荐结果降权
    (若降权后,推荐的仍在列表前面则继续推荐)

时间衰减

在这里插入图片描述

基于时间衰减的ItemCF算法

算法核心两部分,都加入了时间衰减项

时间衰减函数:在这里插入图片描述
在这里插入图片描述

以movielens数据集实现ItemCF
import json
import pandas as pd
import math
import os
from operator import itemgetter
from sklearn.model_selection import train_test_split


class NewItemCF:
    def __init__(self,datafile,simfile):
        self.alpha = 0.5
        self.beta = 0.8
        #文件目录
        self.datafile = datafile
        #存放相似度矩阵的文件目录
        self.simfile=simfile
        #最大的时间
        self.max_time=self.get_maxtime()
        #获得训练集与测试集
        self.train, self.test = self.loadData()
        if os.path.exists(simfile):
            self.items_sim=json.load(open('data/items_sim.json', 'r'))
        else:
            self.items_sim = self.ItemSimilarityBest()
    def loadData(self):
        data = list()
        with open(self.datafile, 'r') as f:
            lines = f.readlines()
        for line in lines:

            userid, itemid, record, timestamp = line.split("::")
            data.append((userid, itemid, int(record), int(timestamp)))


        train_list, test_list = train_test_split(data, test_size=0.3,random_state=1)

        train_dict = self.transform(train_list)
        test_dict = self.transform(test_list)

        return train_dict, test_dict
    def get_maxtime(self):
        title = ['user', 'movie', 'rating', 'time']
        data = pd.read_csv(self.datafile, sep='::', names=title,engine = 'python')
        return data['time'].max()
    def transform(self,data):
        data_dict=dict()
        for userid,itemid,record,timestamp in data:
            data_dict.setdefault(userid,{})
            data_dict[userid].setdefault(itemid,{})
            data_dict[userid][itemid]['rate']=record
            data_dict[userid][itemid]['time']=timestamp
        return data_dict

    def ItemSimilarityBest(self):
        items_sim=dict()
        #统计每个物品的关联用户数
        item_user_count=dict()
        #两两物品相似度计算的分子部分
        C=dict()

        for user,items in self.train.items():
            for i in items.keys():
                item_user_count.setdefault(i,0)
                if self.train[user][i]['rate']>0:
                    item_user_count[i]+=1
                if i not in C.keys():
                    C[i]=dict()
                for j in items.keys():
                    if i==j:
                        continue
                    if j not in C[i].keys():
                        C[i][j]=0
                    if self.train[user][i]['rate']>0 and self.train[user][j]['rate']>0:
                        C[i][j]+=1/(1+self.alpha*abs(self.train[user][i]['time']-self.train[user][j]['time'])/(24*60*60))

        for i,related_items in C.items():
            items_sim.setdefault(i,dict())
            for j,cij in related_items.items():
                items_sim[i][j]=cij/math.sqrt(item_user_count[i]*item_user_count[j])

        json.dump(items_sim, open(self.simfile, 'w'))
        return items_sim

    def recommand(self,user,K=20,N=10):
        items_sim=self.items_sim
        rank=dict()

        ru=self.train.get(user,{})
        for i,rui in ru.items():
            for j,wij in sorted(items_sim[i].items(),key=itemgetter(1),reverse=True)[:K]:
                if j in ru.keys():
                    continue
                if j not in rank.keys():
                    rank[j]=0.0

                rank[j]+=rui['rate']*wij*(1/(1+self.beta*(self.max_time-rui['time'])/(24*60*60)))
        return sorted(rank.items(),key=itemgetter(1),reverse=True)[:N]

    def precision(self, K=20, N=10):
        hit = 0
        num=0
        for user in self.train.keys():
            tu = self.test.get(user, {})
            rank = self.recommand(user, K=K, N=N)
            for item, rate in rank:
                if item in tu:
                    hit += 1
            num += N
        precision=hit/num
        return precision

if __name__ == '__main__':
    b=NewItemCF('ml-1m/ratings.dat','data/items_sim.json')
    print(b.precision())

基于时间衰减的UserCF算法

原理同上面的ItemCF算法,这里不再解释。

以movielens数据集实现UserCF
import json
import math
import pandas as pd
import os
from operator import itemgetter
from sklearn.model_selection import train_test_split


class NewUserCF:
    def __init__(self,datafile,simfile):
        self.alpha=0.5
        self.beta=0.8
        #文件目录
        self.datafile=datafile
        #存放相似度矩阵的文件
        self.simfile=simfile
        #获取最大的时间
        self.max_time=self.get_maxtime()
        #获取数据
        self.train,self.test=self.loadData()
        #用户之间相似度
        if os.path.exists('data/users_sim.json'):
            self.users_sim=json.load(open('data/users_sim.json','r'))
        else:
            self.users_sim=self.UsersSimilarity()
    def get_maxtime(self):
        title = ['user', 'movie', 'rating', 'time']
        data = pd.read_csv(self.datafile, sep='::', names=title, engine='python')
        return data['time'].max()

    def loadData(self):
        data=list()
        with open(self.datafile,'r') as f:
            lines=f.readlines()
        for line in lines:
            userid,itemid,record,timestamp=line.split("::")
            data.append([userid,itemid,int(record),int(timestamp)])
        train_data,test_data=train_test_split(data,test_size=0.3,random_state=1)
        train_data=self.transform(train_data)
        test_data=self.transform(test_data)
        return train_data,test_data

    def transform(self,data):
        data_dict=dict()
        for userid,itemid,record,timestamp in data:
            if userid not in data_dict.keys():
                data_dict[userid]={}
            if itemid not in data_dict[userid].keys():
                data_dict[userid][itemid]={}
            data_dict[userid][itemid]['rate']=record
            data_dict[userid][itemid]['time']=timestamp
        return data_dict

    def UsersSimilarity(self):


        #物品-用户倒查表
        item_users=dict()
        for u,items in self.train.items():
            for i in items.keys():
                item_users.setdefault(i,set())
                if self.train[u][i]['rate']>0:
                    item_users[i].add(u)
        #计算两两用户相似的分子部分
        C=dict()
        #统计每个用户评价过多少个电影
        N=dict()
        for user,item_dict in self.train.items():
            if user not in N.keys():
                N[user]=0

            items=[item for item in item_dict.keys() if item_dict[item]['rate']>0]
            N[user]=len(items)
        for item,users in item_users.items():
            for u in users:
                C.setdefault(u,dict())
                for v in users:
                    C[u].setdefault(v,0.0)
                    if v==u:
                        continue
                    C[u][v]+=(1/(1+self.alpha*abs(self.train[u][item]['time']-self.train[v][item]['time'])/(24*60*60)))*(1/math.log(1+len(users)))

        users_sim=dict()
        for u,related_users in C.items():
            users_sim.setdefault(u,dict())
            for v,wuv in related_users.items():
                if u==v:
                    continue
                users_sim[u][v]=wuv/math.sqrt(N[u]*N[v])
        json.dump(users_sim,open('data/users_sim.json','w'))
        return users_sim


    def recommand(self,user,K=20,N=10):
        """

        :param user: 用户id
        :param K: 取和user相似的前K的其他用户
        :param N: 推荐N个物品
        :return: 推荐列表及用户对其的兴趣的字典
        """
        rank=dict()
        related_items=self.train.get(user,{})
        for v,wuv in sorted(self.users_sim[user].items(),key=itemgetter(1),reverse=True)[:K]:
            for i,rvi in self.train[v].items():
                if i in related_items.keys():
                    continue
                if i not in rank.keys():
                    rank[i]=0.0
                else:
                    rank[i]+=wuv*rvi['rate']*(1/(1+self.beta*(self.max_time-rvi['time'])))
        return sorted(rank.items(),key=itemgetter(1),reverse=True)[:N]
    def precision(self,K=20,N=10):
        hit=0
        num=0

        for user in self.train.keys():
            tu=self.test.get(user,{})
            rank=self.recommand(user,K=K,N=N)
            for item,rate in rank:
                if item in tu:
                    hit+=1
            num+=N
        precision=hit/num
        return precision

if __name__ == '__main__':
    a=NewUserCF('ml-1m/ratings.dat','data/users_sim.json')
    print(a.precision())


基于地点和热度推荐

原理(包含三种数据集)

在这里插入图片描述

以home-less数据集为例实现代码

# 这里用了老师给的代码 
# 这个数据集与上面三种数据集采用的思想不一样
import pandas as pd

class RecBasedAh:
    def __init__(self,path=None,Addr='朝阳区',type='score',k=10):
        self.path=path
        self.Addr=Addr
        self.type=type
        self.k=k

        self.data=self.load_mess()
    def load_mess(self):
      # 这个函数筛选出用户位置周围的数据
        data=pd.read_csv(self.path,header=0,sep=',',encoding='GBK')
        return data[data['addr']==self.Addr]

    def recommand(self):
      # 判断推荐所依据的原因 
      # else 中是综合原因 对于评分 评论条数 开业时间 装修时间分别做了加权 
      # 可以自己设计自己的要求 比如对于开业时间等不做考虑
        if self.type in ['score','comment_num','lowest_price','decoration_time','open_time']:
            data=self.data.sort_values(by=[self.type,'lowest_price'],ascending=False)[:self.k]
            return dict(data.filter(items=['name',self.type]).values)
        elif self.type=='combine':
            data=self.data.filter(items=['name','score','comment_num','lowest_price','decoration_time','open_time'])
            #装修时间越近越好
            data['decoration_time']=data['decoration_time'].apply(lambda x:int(x)-2017)
            #开业时间越早越好
            data['open_time']=data['open_time'].apply(lambda x:2017-int(x))

            for col in data.keys():
                if col!='name':
                    data[col]=(data[col]-data[col].min())/(data[col].max())


            data[self.type]=1*data['score']+2*data['comment_num']+1.5*data['lowest_price']+0.5*data['decoration_time']+0.5*data['open_time']
            data=data.sort_values(by=self.type,ascending=False)[:self.k]
            return dict(data.filter(items=['name',self.type]).values)


if __name__ == '__main__':
    path='hotel-mess/hotel-mess.csv'

    hotel_rec=RecBasedAh(path,Addr='朝阳区',type='combine',k=10,sort=False)
    print(hotel_rec.recommand())
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于上下文的推荐 -- 包括时间衰减算法和位置推荐算法(代码实现) 的相关文章

  • Apriori算法是什么?适用于什么情境?

    Apriori适用于什么场景 Apriori算法是常用的用于挖掘出数据关联规则的算法 它用来找出数据值中频繁出现的数据集合 找出这些集合的模式有助于我们做一些决策 例如什么商品集合顾客会在同一次购物中购买 最著名的例子莫过于啤酒与尿布的故事
  • 当推荐系统邂逅深度学习

    前言 这是一篇关于讲述推荐系统邂逅深度学习故事的文章 推荐系统之于用户的角色 有时更像是无微不至的男朋友 你口渴时递给你符合口味的饮料 你饥饿时还你以常吃的披萨 你无聊时帮你推荐有趣的音乐亦或带你欣赏感兴趣的电影 但男友也会有手足无措 不知
  • 推荐系统遇上深度学习(十一)--神经协同过滤NCF原理及实战

    原创 文文 小小挖掘机 2018 06 02 笔者是一个痴迷于挖掘数据中的价值的学习人 希望在平日的工作学习中 挖掘数据的价值 找寻数据的秘密 笔者认为 数据的价值不仅仅只体现在企业中 个人也可以体会到数据的魅力 用技术力量探索行为密码 让
  • 推荐系统系列——推荐算法评价指标

    文章目录 同步读书之 菜根谭 9 静坐观心 真妄毕现 10 得意早回头 拂心莫停手 推荐算法评价指标 1 评分预测指标 1 1 符号定义 1 2 平均绝对误差 1 3 均方根误差 1 4 覆盖率 2 集合推荐指标 2 1 混淆矩阵 2 2
  • # Python推荐系统学习笔记(3)------基于协同过滤的个性化推荐算法实战---隐语义模型

    Python推荐系统学习笔记 3 基于协同过滤的个性化推荐算法实战 隐语义模型 一 概念性理解 传统的推荐方法 UserCF 首先需要找到和他们看了同样书的其他用户 然后给他们推荐那些用户喜欢的其他书 ItemCF 需要给他们推荐和他们已经
  • Surprise库使用总结

    文章目录 Surprise库 1 加载数据模块 2 模型训练前的数据划分模块 2 1 交叉验证数据划分 2 2 训练集测试集划分 3 构建算法模块 3 1 记号说明 3 2 基于统计的算法 3 3 基于近邻 协同过滤 的方法 3 3 1 相
  • 特征选择 (feature_selection)

    当数据预处理完成后 我们需要选择有意义的特征输入机器学习的算法和模型进行训练 通常来说 从两个方面考虑来选择特征 特征是否发散 如果一个特征不发散 例如方差接近于0 也就是说样本在这个特征上基本上没有差异 这个特征对于样本的区分并没有什么用
  • 推荐系统:Wide & Deep模型解析

    1 Wide Deep模型介绍 经典推荐深度模型 Wide Deep 对应的论文 Wide Deep Learning for Recommender Systems 链接 arxiv Wide Deep的模型架构如下图所示 可以看到Wid
  • 机器学习之电子商务网站用户行为分析及服务推荐案例

    项目概述 本项目案例根据某法律咨询服务网站的用户浏览记录 把用户划分为训练集的用户和测试集的用户 再根据找出相应用户的浏览记录划分为训练集数据和测试集数据 训练集用于后续构建用户物品矩阵 再根据用户物品矩阵构建物品相似度矩阵 根据杰卡德相似
  • 推荐系统实践(一)----基于用户的协同过滤算法(UserCF)

    随着信息技术和互联网的发展 人们逐渐从信息匮乏的时代走入了信息过载的时代 在这个时代 无论是信息消费者还是信息生产者都遇到了很大的挑战 如何从大量信息中找到自己感兴趣的信息是一件非常困难的事情 这个时候就需要推荐系统 推荐系统不需要用户提供
  • 注意力机制与兴趣演化在推荐系统当中的应用

    什么是 注意力机制 注意力机制 来源于人类天生的 选择性注意 的习惯 最典型的例子是用户在浏览网页时 会有选择性地注意页面的特定区域 而忽视其他区域 比如下图是 Google 对大量用户进行眼球追踪实验后 得出的页面注意力热度图 我们可以看
  • 深度学习系列:阿里DIN模型的原理和代码实现

    一 前言 今天介绍阿里巴巴的DIN网络 不得不说 阿里妈妈的大佬是真的多 经常都会更新非常多的创造性的东西 比如DIN中使用的自适应正则化技术以及Dice激活函数以及注意力机制的使用 并且值得注意的是DIN网络中使用的注意力机制还挺多的 哈
  • 关联分析算法(一)——Apriori(先验算法)

    算法思路简介 Apriori根据原始的销售表 第一步 列出所有元素 所有元素独立组成一个集合 计算每个集合的支持度 然后根据最小支持度的阈值剔除掉小的支持度的集合 第二步 每个集合都增加一个与原有集合中没有的元素 构成多个新的集合 计算每个
  • 开源的推荐系统简介TOP 10

    最近这两年推荐系统特别火 本文搜集整理了一些比较好的开源推荐系统 即有轻量级的适用于做研究的SVDFeature LibMF LibFM等 也有重 量级的适用于工业系统的 Mahout Oryx EasyRecd等 供大家参考 PS 这里的
  • 【程序开发经验分享2024】计算机毕业设计吊打导师Python+Spark知识图谱课程推荐系统 课程预测系统 mooc慕课课程爬虫 课程大数据 课程数据分析大屏 大数据毕业设计 大数据毕设

    开发技术 前端 vue js 后端 springboot mybatis plus 数据库 mysql neo4j 算法 机器学习 深度学习 协同过滤算法 基于用户 基于物品全部实现 神经网络混合CF推荐算法 MLP深度学习算法 SVD深度
  • 【推荐算法】FM模型:Factorization Machines

    1 线性回归 在介绍FM之前 我们先简单回顾以下线性回归 回归分析是一种预测性的建模技术 它研究的是因变量 目标 和自变量 预测器 之间的关系 这种技术通常用于预测分析 时间序列模型以及发现变量之间的因果关系 通常使用曲线 直线来拟合数据点
  • Sequential Recommendation with Graph Neural Networks

    Sequential Recommendation with Graph Neural Networks 文章目录 1 背景 2 模型 2 1 Interest Graph Construction 2 1 1 Raw graph cons
  • 推荐系统实践(八)----评分预测

    目前为止都是在讨论 T o p N TopN TopN 推荐 即给定一个用户 如何给他生成一个长度为 N N
  • 浅谈矩阵分解在推荐系统中的应用

    推荐系统是当下越来越热的一个研究问题 无论在学术界还是在工业界都有很多优秀的人才参与其中 近几年举办的推荐系统比赛更是一次又一次地把推荐系统的研究推向了高潮 比如几年前的Neflix百万大奖赛 KDD CUP 2011的音乐推荐比赛 去年的
  • 直播预告

    点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入 6月9日晚7 30 9 00 AI TIME特别邀请了三位优秀的讲者跟大家共同开启ICLR专场六 哔哩哔哩直播通道 扫码关注AITIME哔哩哔哩官方账号 观看直播 链接 http

随机推荐

  • 多态案例三-电脑组装

    案例描述 电脑主要组成部件为 CPU 用于计算 显卡 用于显示 内存条 用于存储 将每个零件封装出抽象基类 并且提供不同的厂商生产不同的零件 例如Intel厂商和Lenovo厂商创建电脑类提供让电脑工作的函数 并且调用每个零件工作的接口测试
  • finetune一个GPT3模型

    过程其实挺简单的 首先得注册一个账号获取token 我是叫在美国的朋友注册了一个 注册好账号后 有18美金的试用额度 基本可以完成好几次模型训练了 除了模型训练需要收费之外 大概1000个token的费用是0 02美金 设置好OPENAI
  • 浮动窗口代码(带关闭按钮+全屏漂浮)

    div div
  • Linux安装anaconda与环境变量的配置

    Linux安装anaconda的步骤 下载anaconda的安装包 后缀名为 sh 然后在root用户下执行bash XXX sh Linux配置anaconda环境变量 1 命令的路径在 usr local anaconda3 bin 2
  • 解决VM虚拟机启动后假死

    一 开机后黑屏假死 管理员cmd 输入netsh winsock reset 回车 重启系统 二 启动后假死 关闭本机防火墙
  • 数字孪生技术在各个领域得到广泛应用

    数字孪生是指将物理实体 如产品 设备 建筑 城市等 与其数字模型进行连接 通过实时数据交换和仿真模拟等技术手段 将实际的运行状态 性能 行为模式等信息反映到数字模型中 实现对其进行监测 分析 优化和预测等 实际的物理实体和数字模型之间通过感
  • 一、Docker入门

    最小安装centos7之后无法联网 无法查看ip的解决方法 cd etc sysconfig network scripts 查看目录下的文件 修改ifcfg ens33文件 ONBOOT yes 修改之后执行 service networ
  • Sprin boot 加载位置顺序

    配置文件的加载位置 Spring boot 启动会扫描一下位置的application properties或者application yml文件作为Spring boot的默认配置文件 file config 项目根目录下的config文
  • 【数据集制作】VOC2007格式数据集制作和处理教程(Faster-RCNN模型标准输入)

    说明 此次案例是制作VOC2007数据集的制作教程 用于目标检测 此次数据集处理可用于Faster RCNN YOLOv3等网络进行目标检测模型的标准输入 VOC2007数据集结构 VOC2007数据集结构如下 VOC2007 Annota
  • 灵魂拷问!GPT-4来了!人类自媒体博主存在的意义是什么?

    大家有没有想过一个问题 当某某领域大v 的文章或者视频都是GPT 4创作出来的时候 那么我们这些低产能的人类自媒体博主存在的意义又是什么呢 拿什么跟GPT 4进行竞争呢 想到这个问题是不是会有些伤感 GPT 4 VS 人类博主 首先我们先比
  • 左神提升6:暴力递归改动态规划

    内容 讲述暴力递归和动态规划的关系 去重的过程 记忆化搜索 傻缓存 动态规划都可以由暴力递归改进过来 解决动态规划的套路 常见的尝试模型 设计尝试过程的原则 本节是暴力递归到动态规划的总纲 很重要 后续的课都是在讲述这一系列的套路 1 尝试
  • Python多进程写日志ConcurrentLogHandler

    文档 https pypi org project ConcurrentLogHandler 0 9 1 这个类库是通过文件锁实现写日志进程安全的 但是只能通过文件大小控制切割 不能通过时间分割文件 demo import time imp
  • 2023年数据要素交易指数研究报告

    报告紧扣数据要素市场化发展主线 深入分析数据要素交易现状 从构建规范高效的数据交易场所入手 坚持理论指导导向 实践需求导向 共性特征导向 发展趋势导向 围绕数据场内交易需要 分析构建了数据要素交易指数指标体系 并在此基础上提出数据要素交易指
  • zabbix客户端错误:no active checks on server [192.168.1.107:10051]: host [ ] not found

    查看zabbix agentd log时出现下列错误 root www tail var log zabbix zabbix agentd log 10526 20170506 154012 832 no active checks on
  • 解决Maven:com.oracle:ojdbc7-12.1.0.2.jar在pom文件中无法下载问题

    一 pom文件中有ojdbc依赖 但是一直无法下载 导致打包出错 二 解决方法 1 配置Maven的环境变量 此处省略 检查maven配置成功 win R 在doc窗口输入mvn v 如下则说明Maven 的环境变量配置成功 2 自行下载o
  • 【原创】QString 函数 replace()indexOf()、 lastindexOf()

    1 替换函数 示例 QString x Say yes QString y no x replace 4 3 y x Say no 应用 将 002 jpg 7位 替换为 s save002 jpg 1 13位 QString x1 fil
  • swc-loader Segmentation fault “$NODE_EXE“ “$NPM_CLI_JS“ “$@“

    webpack swc swc还不是很稳定 在swcrc 中有配置plugins 时 swc 转换 node modules 会报错 环境 swc cor 1 3 62 swc loader 0 2 3 swc plugin vue jsx
  • python+opencv实现文字颜色识别与标定

    最近接了一个比较简单的图像处理的单子 花了一点时间随便写了一下 数据集客户没有是自己随便创建的 程序如下 Code creation time September 11 2021 Author PanBo Realize function
  • Spring学习心得(6)-- spring DI(依赖注入)

    DI的定义 给配置文件中的bean的属性赋值 方式 一种是利用其属性的setter方法 另外一种是利用构造函数 我们先来讨论第一种 利用属性的setter方法赋值 首先 先创建好类 并且配置到配置文件中 public class Perso
  • 基于上下文的推荐 -- 包括时间衰减算法和位置推荐算法(代码实现)

    基于上下文的推荐 基于时间特征的推荐 时间衰减 基于时间衰减的ItemCF算法 算法核心两部分 都加入了时间衰减项 以movielens数据集实现ItemCF 基于时间衰减的UserCF算法 以movielens数据集实现UserCF 基于