协同过滤(collaborative filtering)是一种在推选系统中常常使用的时间。该时间通过分析用户或者事物之间的相似性porn ai换脸,来揣摸用户可能感敬爱的内容并将此内容推选给用户。
这里的相似性不错是东说念主口特征的相似性,也不错是历史浏览内容的相似性,还不错是个东说念主通过一定机制继承某个事物的回答。比如,A和B是无话不谈的好一又友,何况皆心爱看电影,那么协同过滤会以为A和B的相似度很高,会将A心爱关联词B没联系注的电影推选给B,反之也是。
协同过滤推选分为3种类型:
基于用户(user-based)的协同过滤(UserCF)基于物品(item-based)的协同过滤(ItemCF算法)基于模子(model-based)的协同过滤 (ModelCF算法)时间升迁时间要学会共享、交流,不建议闭门觅句。一个东说念主走的很快、一堆东说念主不错走的更远。
著述中的完好源码、贵寓、数据、时间交流升迁, 均可加常识星球交流群获得,群友已跳跃2000东说念主,添加时切记的备注风物为:着手+敬爱地方,便捷找到志同说念合的一又友vb.net教程C#教程python教程。
算法旨趣ItemCF算法是目下业界使用最常常的算法之一,亚马逊、Netflix、YouTube的推选算法的基础皆是基于ItemCF。
不知说念全球平时在网上购物的时候有莫得这样的体验,比如你在网上商城下单了一个手机,在订单完成的界面,网页会给你推选同款手机的手机壳,你此时很可能就会点进去浏览一下,趁便买一个手机壳。
其实这便是ItemCF算法在背后默然使命。ItemCF算法给用户推选那些和他们之前心爱的物品相似的物品。因为你之前买了手机,ItemCF算法缱绻出来手机壳与手机之间的相似度较大,是以给你推选了一个手机壳,这便是它的使命旨趣。
看起来是不是跟UserCF算法很相似是不是?只不外此次不再是缱绻用户之间的相似度,而是换成了缱绻物品之间的相似度。
由上述刻画不错知说念ItemCF算法的主要关节如下:
缱绻物品之间的相似度凭证物品的相似度和用户的历史活动给用户生成推选列表那么摆在咱们眼前的第一个问题便是奈何缱绻物品之间的相似度,这里尤其要十分留神一下:
ItemCF算法并不是径直凭证物品自己的属性来缱绻相似度,而是通过分析用户的活动来缱绻物品之间的相似度。
什么预见呢?比如手机和手机壳,除了时势相似除外莫得什么其它的相似点,径直缱绻相似度似乎也无从下手。关联词换个角度来探究这个问题,如若有好多个用户在买了手机的同期,又买了手机壳,那是不是不错以为手机和手机壳相比相似呢vb.net教程C#教程python教程?由此引出物品相似度的缱绻公式:
图片
图片
图片
图片
图片
图片
临了将筛选出来的物品按照用户对其感敬爱进度逆序排序,取全体列表或者列表前K个物品推选给用户,至此ItemCF算法完成。
算法使命经过接下来咱们用一个或者例子演示一下ItemCF的具体使命经过。
下表是一个绵薄的原始数据集,也称之为User-Item表,即用户-物品列表,纪录了每个用户醉心的物品,数据表格如下:
图片
图片
图片
用户A的共现矩阵
上图是用户A的共现矩阵C,C[i][j]代表的含义是同期心爱物品i和物品j的用户数目。举个例子,C[a][b]=1代表的含义便是同期心爱物品a和物品b的用户有一个,便是用户A。由于同期心爱物品i和物品j的东说念主与同期心爱物品j和物品i的东说念主数是一样的,是以这是一个对称矩阵。相同的敬爱,其他用户也皆有一张近似的表格。因为不同的用户的醉心物品列表不一致,会导致每个用户酿成的共现矩阵大小不一,这里为了结伴起见,将矩阵大小执行到nxn,其中n是所有效户心爱物品列表的并集的大小。
底下用一张图来刻画奈何构建完好的共现矩阵:
图片
通过对不同用户的醉心物品聚拢组成的共现矩阵进行累加,最终得到了上图中的矩阵C,这其实便是相似度公式中的分子部分。
这里只是为了演示奈何缱绻物品举座共现矩阵,本色在代码中咱们并不会采取分袂为每个用户建立一个共现矩阵再累加的风物。为了加速成果和简略空间,不错使用python的dict来杀青,具体不错参考代码杀青章节。
接下来咱们缱绻最终的物品相似度矩阵,以物品a和物品b的相似度缱绻为例,通过上头缱绻的缱绻可知C[a][b]=1,即同期心爱物品a和物品b的用户有一位。凭证User-Item表不错统计出N(a)=2,N(b)=3,那么物品a和物品b的相似度缱绻如下:
图片
有了物品相似度矩阵W之后,咱们对用户进行物品推选了,底下以给用户C推选物品为例,展示一下缱绻过程:不错看到用户C心爱的物品列表为{c,d},通过查物品相似度矩阵可知,与物品c相似的有{b,d,e},同理与物品d相似的物品有{a,b,c},故最终给用户C推选的物品列表为{a,b,e}(留神这里并不是{a,b,c,d,e},因为要去掉用户C心爱的物品,驻防重叠推选)。接下来分袂缱绻用户C对这些物品的感敬爱进度。
P(C,a) = W[d][a] = 0.71P(C,b) = W[c][b] + W[d][b]= 0.67 + 0.58 = 1.25P(C,e) = W[c][e] = 0.58
故给用户C的推选列表是{b,a,e}。
相似度算法更动从前边的参议不错看到,在协同过滤中两个物品产生相似度是因为它们共同出当今好多用户的敬爱列表中。换句话说,每个用户的敬爱列表皆对物品的相似度产生孝敬。那么是不是每个用户的孝敬皆疏导呢?
假定有这样一个用户,他是开书店的,何况买了当当网上80%的书准备用来我方卖。那么他的购物车里包含当当网80%的书。假定当当网有100万本书,也便是说他买了80万本。从前边对ItemCF的参议不错看到,这意味着因为存在这样一个用户,有80万本书两两之间就产生了相似 度,也便是说,内存里行将出生一个80万乘80万的广宽矩阵。
快乐风男 勾引John S. Breese在论文1中提议了一个称为IUF(Inverse User Frequence),即用户活跃度对数的 倒数的参数,他也以为活跃用户对物品相似度的孝敬应该小于不活跃的用户,他提议应该增多IUF 参数来修正物品相似度的缱绻公式:
图片
上述公式对活跃用户作念了一种软性的刑事累赘,关联词关于好多过于活跃的用户,比如上头那位买了当当网80%史籍的用户,为了幸免相似度矩阵过于广宽,咱们在本色缱绻中一般径直忽略他的敬爱列表,而不将其纳入到相似度缱绻的数据辘集。
相似度矩阵归一化惩办Karypis在策动中发现如若将ItemCF的相似度矩阵按最大值归一化,不错提高推选的准确率。其策动标明,如若照旧得到了物品相似度矩阵w,那么不错用如下公式得到归一化之后的相似度矩阵w’:
图片
实验标明,归一化的克己不单是在于增强推选的准确度,还不错提高推选的遮盖率和万般性。
代码践诺凭证之前的先容,可知所有这个词算法经过分为两个阶段:
考研阶段推选阶段关于考研阶段,可分为以下几步:
数据预惩办,建立User-Item表建立物品举座共现矩阵建立物品相似度矩阵关于推选阶段,可分为以下几步:
寻找与被推选用户醉心物品集最相似的N个物品缱绻用户对这N个物品的感敬爱程序列表并逆序陈列考研阶段数据预惩办,建立User-Item表咱们采取MovieLens数据辘集的ratings.dat文献,因为这内部包含了用户对电影的评分数据,留神咱们忽略掉评分那一栏,将其简化成用户心爱或者不心爱。惟有效户有参与过评分的电影,不管分值奈何,咱们皆以为这部电影是用户心爱的。
留神,ratings.dat内部包含了100多万条评价数据,为了减少考研时间,不错只读取部分数据,本文读取了前29415条数据,即前200个用户的评价数据。ratings.dat原始数据每行包含了4列,本文中只取了’UserID'、’MovieID'这两列。
接下来使用以下代码来读取数据并建立User-Item表:
import random import pandas as pd def LoadMovieLensData(filepath, train_rate): ratings = pd.read_table(filepath, sep="::", header=None, names=["UserID", "MovieID", "Rating", "TimeStamp"], engine='python') ratings = ratings[['UserID','MovieID']] train = [] test = [] random.seed(3) for idx, row in ratings.iterrows(): user = int(row['UserID']) item = int(row['MovieID']) if random.random() < train_rate: train.append([user, item]) else: test.append([user, item]) return PreProcessData(train), PreProcessData(test) def PreProcessData(originData): """ 建立User-Item表,结构如下: {"User1": {MovieID1, MoveID2, MoveID3,...} "User2": {MovieID12, MoveID5, MoveID8,...} ... } """ trainData = dict() for user, item in originData: trainData.setdefault(user, set()) trainData[user].add(item) return trainData
建立物品举座共现矩阵这里并莫得采取对每个用户皆建立共现矩阵再累加的风物,而是径直采取了两重dict来杀青一个Matrix,然后在此基础上径直建立共现矩阵。
def ItemMatrix(trainData, similarity): """ 建立物品共现矩阵 :param trainData: User-Item表 :param similarity: 相似度缱绻函数聘任 :return: """ N = defaultdict(int) # 纪录每个物品的醉心东说念主数 itemSimMatrix = defaultdict(int) # 共现矩阵 for user, items in trainData.items(): for i in items: itemSimMatrix.setdefault(i, dict()) N[i] += 1 for j in items: if i == j: continue itemSimMatrix[i].setdefault(j, 0) if similarity == "cosine": itemSimMatrix[i][j] += 1 elif similarity == "iuf": itemSimMatrix[i][j] += 1. / math.log1p(len(items) * 1.) return itemSimMatrix
建立物品相似度矩阵这一步是是径直在物品共现矩阵的基础上除以两个物品各自醉心东说念主数的乘积,何况包含了数据归一化的惩办。
def ItemSimilarityMatrix(ItemMatrix, N, isNorm): """ 缱绻物品相似度矩阵 :param ItemMatrix: :param N: :param isNorm: :return: """ itemSimMatrix = dict() for i, related_items in ItemMatrix.items(): for j, cij in related_items.items(): # 缱绻相似度 itemSimMatrix[i][j] = cij / math.sqrt(N[i] * N[j]) # 是否要圭臬化物品相似度矩阵 if isNorm: for i, relations in itemSimMatrix.items(): max_num = relations[max(relations, key=relations.get)] # 对字典进行归一化操作之后复返新的字典 itemSimMatrix[i] = {k: v / max_num for k, v in relations.items()} return itemSimMatrix
推选阶段
def recommend(trainData, itemSimMatrix, user, N, K): """ :param trainData: User-Item表 :param itemSimMatrix: 物品相似度矩阵 :param user: 被推选的用户user :param N: 推选的商品个数 :param K: 查找的最相似的用户个数 :return: 按照user对推选物品的感敬爱进度排序的N个商品 """ recommends = dict() # 先获得user的醉心物品列表 items = trainData[user] for item in items: # 对每个用户醉心物品在物品相似矩阵中找到与其最相似的K个 for i, sim in sorted(itemSimMatrix[item].items(), key=itemgetter(1), reverse=True)[:K]: if i in items: continue # 如若与user醉心的物品重叠了,则径直跳过 recommends.setdefault(i, 0.) recommends[i] += sim # 凭证被推选物品的相似度逆序陈列,然后推选前N个物品给到用户 return dict(sorted(recommends.items(), key=itemgetter(1), reverse=True)[:N])
中枢代码底下的代码杀青了完好的功能,修改“ratings.dat"文献的旅途之后,不错径直开动。
import math import random import pandas as pd from collections import defaultdict from operator import itemgetter def LoadMovieLensData(filepath, train_rate): ratings = pd.read_table(filepath, sep="::", header=None, names=["UserID", "MovieID", "Rating", "TimeStamp"], engine='python') ratings = ratings[['UserID','MovieID']] train = [] test = [] random.seed(3) for idx, row in ratings.iterrows(): user = int(row['UserID']) item = int(row['MovieID']) if random.random() < train_rate: train.append([user, item]) else: test.append([user, item]) return PreProcessData(train), PreProcessData(test) def PreProcessData(originData): """ 建立User-Item表,结构如下: {"User1": {MovieID1, MoveID2, MoveID3,...} "User2": {MovieID12, MoveID5, MoveID8,...} ... } """ trainData = dict() for user, item in originData: trainData.setdefault(user, set()) trainData[user].add(item) return trainData class ItemCF(object): """ Item based Collaborative Filtering Algorithm Implementation""" def __init__(self, trainData, similarity="cosine", norm=True): self._trainData = trainData def similarity(self): N = defaultdict(int) #纪录每个物品的醉心东说念主数 for user, items in self._trainData.items(): for i in items: self._itemSimMatrix.setdefault(i, dict()) N[i] += 1 for j in items: if i == j: continue self._itemSimMatrix[i].setdefault(j, 0) if self._similarity == "cosine": self._itemSimMatrix[i][j] += 1 elif self._similarity == "iuf": self._itemSimMatrix[i][j] += 1. / math.log1p(len(items) * 1.) for i, related_items in self._itemSimMatrix.items(): for j, cij in related_items.items(): self._itemSimMatrix[i][j] = cij / math.sqrt(N[i]*N[j]) # 是否要圭臬化物品相似度矩阵 if self._isNorm: for i, relations in self._itemSimMatrix.items(): max_num = relations[max(relations, key=relations.get)] # 对字典进行归一化操作之后复返新的字典 self._itemSimMatrix[i] = {k : v/max_num for k, v in relations.items()} def recommend(self, user, N, K): """ :param user: 被推选的用户user :param N: 推选的商品个数 :param K: 查找的最相似的用户个数 :return: 按照user对推选物品的感敬爱进度排序的N个商品 """ recommends = dict() # 先获得user的醉心物品列表 items = self._trainData[user] for item in items: # 对每个用户醉心物品在物品相似矩阵中找到与其最相似的K个 for i, sim in sorted(self._itemSimMatrix[item].items(), key=itemgetter(1), reverse=True)[:K]: if i in items: continue # 如若与user醉心的物品重叠了,则径直跳过 recommends.setdefault(i, 0.) recommends[i] += sim # 凭证被推选物品的相似度逆序陈列,然后推选前N个物品给到用户 return dict(sorted(recommends.items(), key=itemgetter(1), reverse=True)[:N]) if __name__ == "__main__": train, test = LoadMovieLensData("../Data/ml-1m/ratings.dat", 0.8) print("train data size: %d, test data size: %d" % (len(train), len(test))) ItemCF = ItemCF(train, similarity='iuf', norm=True) ItemCF.train() # 分袂对以下4个用户进行物品推选 print(ItemCF.recommend(1, 5, 80))
上述代码对测试辘集前4个用户进行了电影推选,对每个用户而言,从与他们醉心电摄影似的80部电影中挑选出5部推选。
输出截止是一个dict,内部包含了给用户推选的电影以及用户对每部电影的感敬爱进度,按照逆序陈列。
截止如下:
图片
版权声明:本文为博主原创著述,谨守 CC 4.0 BY-SA 版权条约,转载请附上原文出处连气儿和本声明。
原文连气儿:https://blog.csdn.net/m0_59596990/article/details/130459464porn ai换脸
本站仅提供存储职业,所有内容均由用户发布,如发现存害或侵权内容,请点击举报。