推荐算法的Python实现(样例代码)

时间:2022-12-07 17:33:03
基于ItemCF算法
  1. #!/usr/sbin/env python
  2. # -*- coding:utf-8 -*-

  3. import math

  4. # ItemCF算法
  5. def ItemSimilarity(train):
  6.     C = dict()
  7.     N = dict()
  8.     for u,items in train.items():
  9.         for i in items.keys():
  10.             N[i] += 1
  11.             for j in items.keys():
  12.                 if i == j:
  13.                     continue
  14.                 C[i][j] += 1
  15.     W = dict()
  16.     for i,related_items in C.items():
  17.         for j,cij in related_items.items():
  18.             W[i][j] = cij / math.sqrt( N[i] * N[j])
  19.     return W

  20. # ItemCF-IUF算法
  21. def ItemSimilarity_v2(train):
  22.     C = dict()
  23.     N = dict()
  24.     for u,items in train.items():
  25.         for i in items.keys():
  26.             N[i] += 1
  27.             for j in items.keys():
  28.                 if i == j:
  29.                     continue
  30.                 C[i][j] += 1 / math.log(1+len(items)*1.0)
  31.     W = dict()
  32.     for i,related_items in C.items():
  33.         for j,cij in related_items.items():
  34.             W[i][j] = cij / math.sqrt( N[i] * N[j])
  35.     return W

  36. def Recommend(train,user_id,W,K):
  37.     rank = dict()
  38.     ru = train[user_id]
  39.     for i,pi in ru.items():
  40.         for j,wj in sorted(W[i].items,key=itemgetter(1),reverse=True)[0:K]:
  41.             if j in ru:
  42.                 continue
  43.             rank[j] += pi*wj
  44.     return rank
复制代码
基于UserCF算法
  1. #!/usr/sbin/env python
  2. # -*- coding:utf-8 -*-
  3. import math
  4. '''
  5. 基于UserCF的推荐算法
  6. '''
  7. # UserCF算法
  8. def UserSimilarity(train):
  9.     item_users = dict()
  10.     for u,items in train.items():
  11.         for i in items.keys():
  12.             if i not in item_users:
  13.                 item_users[i] = set()
  14.             item_users[i].add(u)
  15.     C = dict()
  16.     N = dict()
  17.     for i,users in item_users.items():
  18.         for u in users:
  19.             N[u] += 1
  20.             for v in users:
  21.                 if u == v:
  22.                     continue
  23.                 C[u][v] += 1
  24.     W = dict()
  25.     for u,related_users in C.items():
  26.         for v,cuv in related_users.items():
  27.             W[u][v] = cuv / math.sqrt(N[u] * N[v])
  28.     return W

  29. # User-IIF算法
  30. def UserSimilarity_v2(train):
  31.     item_users = dict()
  32.     for u,items in train.items():
  33.         for i in items.keys():
  34.             if i not in item_users:
  35.                 item_users[i] = set()
  36.             item_users[i].add(u)
  37.     C = dict()
  38.     N = dict()
  39.     for i,users in item_users.items():
  40.         for u in users:
  41.             N[u] += 1
  42.             for v in users:
  43.                 if u == v:
  44.                     continue
  45.                 C[u][v] += 1 / math.log(1+len(users))
  46.     W = dict()
  47.     for u,related_users in C.items():
  48.         for v,cuv in related_users.items():
  49.             W[u][v] = cuv / math.sqrt(N[u] * N[v])
  50.     return W

  51. def Recommend(user,train,W):
  52.     rank = dict()
  53.     interacted_items = train[user]
  54.     for v,wuv in sorted(W[u].items,key=itemgetter(1),reverse=True)[0:K]:
  55.         for i,rvi in train[v].items:
  56.             if i in interacted_items:
  57.                 continue
  58.             rank[i] += wuv*rvi
  59.     return rank
复制代码
基于时间上下文的个性化推荐
  1. #!/usr/sbin/env python
  2. # -*- coding:utf-8 -*-

  3. import math


  4. def RecentPopularity(records,alpha,T):
  5.     ret = dict()
  6.     for user,item,tm in records:
  7.         if tm >= T:
  8.             continue
  9.         addToDict(ret,item,1/(1.0+alpha*(T-tm)))
  10.     return ret

  11. def addToDict(dicts,item,value):
  12.     pass

  13. def ItemSimilarity(train,alpha):
  14.     C = dict()
  15.     N = dict()
  16.     for u,items in train.items():
  17.         for i,tui in items.items():
  18.             N[i] += 1
  19.             for j,tuj in items.items():
  20.                 if i == j:
  21.                     continue
  22.                 C[i][j] += 1 / (1+alpha*abs(tui-tuj))
  23.     W = dict()
  24.     for i,related_items in C.items():
  25.         for j,cij in related_items.items():
  26.             W[i][j] = cij / math.sqrt(N[i] * N[j])
  27.     return W

  28. def RecommendItemCF(train,user_id,W,K,t0):
  29.     rank = dict()
  30.     ru = train[user_id]
  31.     for i,pi in ru.items():
  32.         for j,wj in sorted(W[i].items(),\
  33.                 key=itemgetter(1),reverse=True)[0:K]:
  34.             if j,tuj in ru.items():
  35.                 continue
  36.             rank[j] += pi * wj / (1 + alpha * (t0 - tuj))
  37.     return rank


  38. def UserSimilarity(train):
  39.     item_users = dict()
  40.     for u,items in train.items():
  41.         for i,tui in items.items():
  42.             if i not in item_users:
  43.                 item_users[i] = dict()
  44.             item_users[i][u] = tui

  45.     C = dict()
  46.     N = dict()
  47.     for i,users in item_users.items():
  48.         for u,tui in users.items():
  49.             N[u] += 1
  50.             for v,tvi in users.items():
  51.                 if u == v:
  52.                     continue
  53.                 C[u][v] += 1 / (1 + alpha * abs(tui - tvi))
  54.     W = dict()
  55.     for u,related_users in C.items():
  56.         for v,cuv in related_users.items():
  57.             W[u][v] = cuv / math.sqrt(N[u] * N[v])
  58.     return W

  59. def RecommendUserCF(user,T,train,W):
  60.     rank = dict()
  61.     interacted_items = train[user]
  62.     for v,wuv in sorted(W[u].items,key=itemgetter(1),\
  63.             reverse=True)[0:K]:
  64.         for i,tvi in train[v].items:
  65.             if i in interacted_items:
  66.                 continue
  67.             rank[i] += wuv / (1 + alpha * (T - tvi))
  68.     return rank
复制代码
基于LFM算法的个性化推荐
  1. #!/usr/bin/env python
  2. import random

  3. '''
  4. items => {'12':'PHP','1203':'Storm','123':'Ubuntu'}
  5. items_pool => [12,32,121,324,532,123,53,1203,429,2932]
  6. user_items => {'1010':[12,1203,123,429]}
  7. '''
  8. def RandomSelectNagativeSample(items):
  9.     ret = dict()
  10.     for i in items.keys():
  11.         ret[i] = 1
  12.     n = 0
  13.     for i in range(0,len(items)*3):
  14.         item = items_pool[random.randint(0,len(items_pool)-1)]
  15.         if item in ret:
  16.             continue
  17.         ret[item] = 0
  18.         n += 1
  19.         if n > len(items):
  20.             break
  21.     return ret


  22. def InitModel(user_items,F):
  23.     P = dict()
  24.     Q = dict()
  25.     for u in user_items.keys():
  26.         if u not in P:
  27.             P[u] = {}
  28.         for f in range(0,F):
  29.             P[u][f] = 1

  30.     items = user_items.values()
  31.     itemLen = len(items[0])
  32.     i = 0
  33.     while i< itemLen:
  34.         ii = items[0][i]
  35.         if ii not in Q:
  36.             Q[ii] = {}
  37.         for f in range(0,F):
  38.             Q[ii][f] = 1
  39.         i += 1
  40.     return [P,Q]


  41. def LatentFactorModel(user_items,F,N,alpha,lambda1):
  42.     [P,Q] = InitModel(user_items,F)
  43.     for setup in range(0,N):
  44.         for user,items in user_items.items():
  45.             samples = RandomSelectNagativeSample(items)
  46.             for item,rui in samples.items():
  47.                 eui = rui - Predict(user,item)
  48.                 for f in range(0,F):
  49.                     P[user][f] += alpha * (eui * Q[item][f] - lambda1 * P[user][f])
  50.                     Q[item][f] += alpha * (eui * P[user][f] - lambda1 * Q[item][f])
  51.         alpha *= 0.9
  52.     return [P,Q]


  53. def Recommend(user,P,Q):
  54.     rank = dict()
  55.     for f,puf in P[user].items():
  56.         for i,pfi in Q[f].items():
  57.             if i not in rank:
  58.                 rank[i] += puf * qfi
  59.     return rank



  60. def PersonalRank(G,alpha,root,maxsetup):
  61.     rank = dict()
  62.     #rank = {x:0 for x in G.keys()}
  63.     rank = rank.fromkeys(G.keys(),0)
  64.     rank[root] = 1
  65.     for k in range(maxsetup):
  66.         tmp = dict()
  67.         #tmp = {x:0 for x in G.keys()}
  68.         tmp = tmp.fromkeys(G.keys(),0)
  69.         for i,ri in G.items():
  70.             for j,wij in ri.items():
  71.                 if j not in tmp:
  72.                     tmp[j] = 0
  73.                 tmp[j] += alpha * rank[i]/(1.0*len(ri))
  74.                 if j == root:
  75.                     tmp[j] += 1 - alpha
  76.         rank = tmp

  77.         print 'iter:' + str(k) + "\t",
  78.         for key,value in rank.items():
  79.             print "%s:%.3f,\t" % (key,value),
  80.         print
  81.     return rank

  82. if __name__ == '__main__':
  83.     G = {'A':{'a':1,'c':1},
  84.      'B':{'a':1,'b':1,'c':1,'d':1},
  85.      'C':{'c':1,'d':1},
  86.      'a':{'A':1,'B':1},
  87.      'b':{'B':1},
  88.      'c':{'A':1,'B':1,'C':1},
  89.      'd':{'B':1,'C':1}}
  90.     PersonalRank(G,0.85,'A',20)

  91. '''

  92. #items_pool = {'12':'PHP','32':'Nginx','121':'Apache','324':'Erlang','532':'Linux','123':'Ubuntu','53':'Java','1203':'Storm','429':'Kafka','2932':'Flume'}
  93. items_pool = [12,32,121,324,532,123,53,1203,429,2932]
  94. items = {'12':'PHP','1203':'Storm','123':'Ubuntu'}
  95. user_items = {'1010':[12,1203,123,429]}


  96. #print RandomSelectNagativeSample(items)
  97. print InitModel(user_items,4)
  98. '''
复制代码
基于图的推荐算法
  1. #!/usr/sbin/env python
  2. # -*- coding:utf-8 -*-
  3. '''
  4.     基于图的推荐算法,二分图
  5. '''


  6. def PersonalRank(G,alpha,root,maxsetup):
  7.     rank = dict()
  8.     #rank = {x:0 for x in G.keys()}
  9.     rank = rank.fromkeys(G.keys(),0)
  10.     rank[root] = 1
  11.     for k in range(maxsetup):
  12.         tmp = dict()
  13.         #tmp = {x:0 for x in G.keys()}
  14.         tmp = tmp.fromkeys(G.keys(),0)
  15.         for i,ri in G.items():
  16.             for j,wij in ri.items():
  17.                 if j not in tmp:
  18.                     tmp[j] = 0
  19.                 tmp[j] += alpha * rank[i]/(1.0*len(ri))
  20.                 if j == root:
  21.                     tmp[j] += 1 - alpha
  22.         rank = tmp

  23.         print 'iter:' + str(k) + "\t",
  24.         for key,value in rank.items():
  25.             print "%s:%.3f,\t" % (key,value),
  26.         print
  27.     return rank

  28. if __name__ == '__main__':
  29.     G = {'A':{'a':1,'c':1},
  30.      'B':{'a':1,'b':1,'c':1,'d':1},
  31.      'C':{'c':1,'d':1},
  32.      'a':{'A':1,'B':1},
  33.      'b':{'B':1},
  34.      'c':{'A':1,'B':1,'C':1},
  35.      'd':{'B':1,'C':1}}
  36.     PersonalRank(G,0.85,'C',20)
复制代码
基于标签的推荐算法
  1. #!/usr/sbin/env python
  2. # -*- coding:utf-8 -*-

  3. import math

  4. #标签流行度算法
  5. def TagPopularity(records):
  6.     tagfreq = dict()
  7.     for user,item,tag in records:
  8.         if tag not in tagfreq:
  9.             tagfreq[tag] = 1
  10.         else:
  11.             tagfreq[tag] += 1
  12.     return tagfreq

  13. #物品相似度余弦算法
  14. def CosineSim(item_tags,i,j):
  15.     ret  = 0
  16.     for b,wib in item_tags[i].items():
  17.         if b in item_tags[j]:
  18.             ret += wib * item_tags[j][b]
  19.     ni = 0
  20.     nj = 0
  21.     for b,w in item_tags[i].items():
  22.         ni += w * w
  23.     for b,w in item_tags[j].items():
  24.         nj += w * w
  25.     if ret == 0:
  26.         return 0
  27.     return ret / math.sqrt(ni * nj)

  28. #推荐物品的多样性算法
  29. def Diversity(item_tags,recommend_items):
  30.     ret = 0
  31.     n = 0
  32.     for i in recommend_items.keys():
  33.         for j in recommend_items.keys():
  34.             if i == j:
  35.                 continue
  36.             ret += CosineSim(item_tags,i,j)
  37.             n += 1
  38.     return ret / (n * 1.0)


  39. def addValueToMat(dicts,index,k,v):
  40.     if index not in dicts:
  41.         dicts[index] = dict()
  42.         dicts[index][k] = v
  43.     else:
  44.         if k not in dicts[index]:
  45.             dicts[index][k] = v
  46.         else:
  47.             dicts[index][k] += v

  48. def InitStat(records):
  49.     user_tags = dict() #存储 user_tags[u][b] = n(u,b)
  50.     tag_items = dict() # tag_items[b][i] = n(b,i)
  51.     user_items = dict()
  52.     for user,item,tag in records.items():
  53.         addValueToMat(user_tags,user,tag,1)
  54.         addValueToMat(tag_items,tag,item,1)
  55.         addValueToMat(user_items,user,item,1)


  56. def Recommend(user):
  57.     recommend_items = dict()
  58.     tagged_items = user_items[user]
  59.     for tag,wut in user_tags[user].items():
  60.         # wut = wut*1.0/math.log(1+len(tag_users[tag])) #TagBasedTFIDF and TagBasedTFIDF++
  61.         for item,wti in tag_items[tag].items():
  62.             # wti = wti*1.0/math.log(1+len(user_items[user])) #TagBasedTFIDF++
  63.             if item in tagged_items:
  64.                 continue
  65.             if item not in recommend_items:
  66.                 recommend_items[item] = wut * wti
  67.             else:
  68.                 recommend_items[item] += wut * wti
  69.     return recommend_items


  70. if __name__ == "main":
  71.     user_tags = dict()
  72.     user_items = dict()
  73.     tag_items = dict()

  74.     records = dict()
  75.     user = '1220';

  76.     InitStat(records)
  77.     rec_items = Recommend(user)
复制代码