QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 5258|回复: 3
打印 上一主题 下一主题

求协同过滤算法程序

[复制链接]
字体大小: 正常 放大
harveymao        

1

主题

10

听众

312

积分

升级  4%

  • TA的每日心情

    2014-12-6 00:46
  • 签到天数: 86 天

    [LV.6]常住居民II

    自我介绍
    数学建模的爱好者

    社区QQ达人

    群组第三届数模基础实训

    群组2014年地区赛数学建模

    群组数学建模培训课堂1

    跳转到指定楼层
    1#
    发表于 2014-7-18 23:21 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta
    本人在学校参加暑假培训,需要这个算法做题!求大神赐教,感激不尽, I1 i4 I7 m. u+ O' _! ~7 |
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信

    3503

    主题

    538

    听众

    5990

    积分

  • TA的每日心情
    开心
    2017-2-7 15:12
  • 签到天数: 691 天

    [LV.9]以坛为家II

    社区QQ达人 元老勋章 发帖功臣 新人进步奖 优秀斑竹奖 金点子奖 原创写作奖 最具活力勋章 助人为乐奖 风雨历程奖

    群组2013年国赛赛前培训

    群组2014年地区赛数学建模

    群组数学中国第二期SAS培训

    群组物联网工程师考试

    群组2013年美赛优秀论文解

    # -*- coding=utf-8 -*-
    & w: j, J: w3 {6 j
    8 q3 J& C+ L$ {& Z2 pimport math% q7 K7 [6 b: J4 ?' p- S
    import sys
    ( h3 @/ R/ f$ H, Z. U, [7 ffrom texttable import Texttable
    " S7 a9 O- D1 h! b3 g$ j: ~
    ' z8 h5 I3 h. @# C+ u: w
    4 H* `$ o0 b- U2 Y/ }#. q, o6 q. \: M! c1 l
    #   使用 |A&B|/sqrt(|A || B |)计算余弦距离
    9 j, c/ V7 x8 ~6 t) @' [#: z) V% I7 r5 [7 M- {6 ?; f
    #* w0 i  R. ^+ |3 x
    #* W. V% |* R9 ^( s
    def calcCosDistSpe(user1,user2):! k" }) a2 R1 a' i
        avg_x=0.0- v2 M& p! U1 z8 {
        avg_y=0.0
    4 o- `' [- U; u1 b    for key in user1:
    ! x) J4 n5 }( Q  c% T2 j        avg_x+=key[1]
    3 Y: M0 p1 I" q6 P: l* B    avg_x=avg_x/len(user1)* g2 ^+ B) X7 I% J3 N# e* `; K7 q
       
    " X1 \) _; ~  c5 C5 \    for key in user2:$ b7 V, u2 E+ |* C0 o' v
            avg_y+=key[1]
    5 N. y- A& ~9 }$ ?$ ~3 @2 z    avg_y=avg_y/len(user2)
    8 `- a2 y8 m5 T" F0 _    . s: z' a) S. w) D5 D
        u1_u2=0.0) o; n8 v1 l. A* ?8 F/ U
        for key1 in user1:2 \6 K6 x' [" H. R, K
            for key2 in user2:. d# }6 F' R* S. ^; e2 G
                if key1[1] > avg_x and key2[1]>avg_y and key1[0]==key2[0]:
    ) z, J0 B: \0 V; w  l5 c; `/ r8 w; c, U                u1_u2+=1- z- V( a7 e7 m
        u1u2=len(user1)*len(user2)*1.0( X' M! Q2 O, C! H2 _5 y. i5 e
        sx_sy=u1_u2/math.sqrt(u1u2)% O4 X! P3 m; A9 V- \0 S/ @7 z; Z
        return sx_sy
    : P% l9 ~4 ~, o! J2 [* j0 K4 Q9 R% `1 D+ x" C0 a
    1 e8 M4 V- `+ j. j+ x  J- V9 J
    #
    2 q1 g$ _( d: t! z1 H) W$ x#   计算余弦距离
    $ G. H) y& _9 N" i: q/ c! j  Y& d#; Q" b) D9 B4 C$ ]" l
    #
    * O' h9 k4 F( G& T. r$ hdef calcCosDist(user1,user2):
    5 C# s* r5 P" k0 F, N    sum_x=0.0' k- _0 y& [1 i  z( |5 @2 x: b; H
        sum_y=0.09 d# _2 q' @! p' l1 T
        sum_xy=0.0
    # @8 ]1 X4 e1 k" m9 J6 w" K    for key1 in user1:  [8 A0 `, ~3 K, r+ n. Y
            for key2 in user2:0 R- ?0 c: }  j8 \$ \
                if key1[0]==key2[0] :
    & g0 L4 \4 L' [; {                sum_xy+=key1[1]*key2[1]
    7 {1 [8 }' }1 D$ A! W" D1 q3 m7 o) W                sum_y+=key2[1]*key2[1]! }8 r  W/ g  q0 e$ C* Q. i! G& \( h/ Q
                    sum_x+=key1[1]*key1[1]
    , D& G" Q. I2 ]! y" t4 S   
    - V. H- b, ^' j# n. x    if sum_xy == 0.0 :$ E/ B& ^4 h7 ~$ T- c( ^0 V
            return 0/ f* C+ g2 u, x% J
        sx_sy=math.sqrt(sum_x*sum_y) # [3 H$ u  k4 Z1 D
        return sum_xy/sx_sy0 |6 J$ Y' ]7 @2 e
    # |* ?% U0 ]4 Y; i) F" {
    . x9 F4 E5 P$ ], A
    #
    " J) Q2 J3 o% C# p9 O& C#1 {/ t# I' a8 M
    #   相似余弦距离9 N0 b; P! g; y2 y& B3 t5 E; u7 I, P
    #5 R1 U) B8 _( g6 f2 S1 l
    #
    6 d9 m' ]8 a3 u9 ^#
    ! d" i3 M1 H! u9 ?7 Rdef calcSimlaryCosDist(user1,user2):
    ! y2 M& b/ y4 g7 A4 U  J8 ^7 c    sum_x=0.0
    8 G' k2 k* G6 Z+ h/ [5 M6 e    sum_y=0.0) \' s+ J, V8 n: \# g7 U7 G
        sum_xy=0.0
    6 B5 D4 \& M& ]% J6 v    avg_x=0.0
    0 I, M$ M, w. }/ r6 d1 I) A" b9 F    avg_y=0.0
    9 g, ]' S/ `1 ?  K) Y4 W% S    for key in user1:
      J. n' o$ _: K- w5 ^$ N+ Y& _$ r        avg_x+=key[1]2 s( Z. {4 V& U  O, X) X
        avg_x=avg_x/len(user1)
    ; m) K) `. F3 S9 o    ) v. m! J3 m. K% P. c
        for key in user2:% \- t& l9 K  `! }2 r
            avg_y+=key[1]. z3 g/ W3 H% {/ H! Z6 U( P) w$ C
        avg_y=avg_y/len(user2)
    6 W  ~$ o1 x' L0 k+ b( p1 W   
    # }3 u1 Z0 y. r+ n+ [7 v1 {    for key1 in user1:
    & \+ W% _4 [- ~9 u/ [        for key2 in user2:
    , D' X/ }2 j) p+ F" L9 a5 o! k: k9 f            if key1[0]==key2[0] :
    / X5 W3 ?1 H6 b8 {% p/ {                sum_xy+=(key1[1]-avg_x)*(key2[1]-avg_y)
    8 C! d! }% r' x1 F7 Z: n                sum_y+=(key2[1]-avg_y)*(key2[1]-avg_y)! H& E7 O+ W, A( u6 k: s
            sum_x+=(key1[1]-avg_x)*(key1[1]-avg_x)* u4 q% L1 s! m( L5 y2 D8 N
       
    ( N4 g8 r' _* \# O    if sum_xy == 0.0 :
    + h; y% V) t) t9 w. |: V2 W  l8 n        return 01 ]8 b2 r1 u; M
        sx_sy=math.sqrt(sum_x*sum_y) ; I+ [( F, V8 s4 H$ G9 B8 `
        return sum_xy/sx_sy/ N) }$ G! D  ~3 q- n" H
        3 R# q) U2 _8 n& {8 I6 K/ K
    2 f+ z6 W9 K- k8 |3 A
    #1 Z( ?$ {% ^4 M. T, h4 ~5 n  A. S
    #   读取文件" d1 V  U/ Q* F* Y! N% T* M5 d
    #
    * K6 s% Q) U/ C2 o#' Y8 {, b% J$ U2 P8 p
    def readFile(file_name):9 s, c: ~" t7 s% O& ]0 J
        contents_lines=[]9 [* F" }3 T# l! D* a' [+ u2 ~
        f=open(file_name,"r")
    0 k! K+ `2 \5 b# ?& i2 X5 v3 I    contents_lines=f.readlines()- s2 }- |7 P9 a! d4 S
        f.close()
    / q2 z8 W- U2 X# Z    return contents_lines
    / `8 H  ]7 H" I7 l
    ' t  B8 [- t; Y5 M; S
    8 e3 M/ m% X0 y; T( ^& E6 R
    + ?) l8 S$ O8 F/ |, i3 G7 d#4 f8 _+ v% r8 o! C4 Y0 b, Y
    #   解压rating信息,格式:用户id\t硬盘id\t用户rating\t时间' ~: s% A/ q0 ]7 t" u. f
    #   输入:数据集合# k. @$ `( ^4 A7 c+ k2 s
    #   输出:已经解压的排名信息( p7 l' k9 V& ~
    #3 Z6 P% A( @3 B. J
    def getRatingInformation(ratings):; d+ X/ b0 Z# ~# W5 V
        rates=[]
      }. D+ y1 B. B( n9 f# D    for line in ratings:
    4 T% \. G5 x% n( u% t, M9 \        rate=line.split("\t")
      P# X: E! p, ~# C/ B2 B% P6 `) @        rates.append([int(rate[0]),int(rate[1]),int(rate[2])])
    2 p2 V% @2 m( [! m# B4 m+ e    return rates
    ' \2 [1 Y( g8 \
    ' M* G0 n8 ^/ q* `4 w5 c4 `# L# u) j: S% R
    #0 b6 E+ k) O! M- U
    #   生成用户评分的数据结构
    ' B3 X/ y4 f! G: {& t2 f& y#   
    * }$ K1 ~* e: [- r% K3 ?* c3 O& T! S#   输入:所以数据 [[2,1,5],[2,4,2]...]
    . \# b2 b* T4 R; Y2 G8 }#   输出:1.用户打分字典 2.电影字典
    & l$ V3 E: h, o#   使用字典,key是用户id,value是用户对电影的评价,9 @) Q/ K& m, a! z, x9 Z, @/ w$ @3 n
    #   rate_dic[2]=[(1,5),(4,2)].... 表示用户2对电影1的评分是5,对电影4的评分是2! m! L, c+ E  E7 ~1 o, g
    #5 Z, O1 }9 s, O8 {; \# w3 [
    def createUserRankDic(rates):* O5 B0 w9 }8 X8 P0 G
        user_rate_dic={}' x; F3 V* C7 q& U% O
        item_to_user={}
    + D, R+ o2 P3 S( H* Q" Q. d8 d    for i in rates:
    ! w& l, ~( D$ {2 [' M. c        user_rank=(i[1],i[2])+ a+ j5 `; F5 k
            if i[0] in user_rate_dic:4 E/ p9 @/ A" p9 c' z% U& y  s3 V
                user_rate_dic[i[0]].append(user_rank)5 Z% R: \# `. [: {. a
            else:
    7 f  T4 p2 m; `" I$ @            user_rate_dic[i[0]]=[user_rank]0 u/ L0 C/ y: \& U( O* i+ j
                7 Z" x. K4 r7 u4 u4 p- z! B
            if i[1] in item_to_user:" z' w5 s$ U2 m( X8 P
                item_to_user[i[1]].append(i[0])
    ; X7 `' r7 y7 R4 y8 N, l. `        else:
    ) X) u. }8 L, n$ B' d3 s            item_to_user[i[1]]=[i[0]]
      T% b. H- D0 t" f. k            ! i# O, o" ]0 I8 Y" j
        return user_rate_dic,item_to_user/ U5 t* ~+ C+ s6 T
    / f7 W0 [( [/ p5 l, H

    , H5 }( v4 A8 g* e1 ~. I, W% E#
    ' }" s# B6 V' I2 T2 A& G8 `#   计算与指定用户最相近的邻居2 E$ w+ @8 [2 c& }% _
    #   输入:指定用户ID,所以用户数据,所以物品数据
    ( Q; E+ B. [! O9 x6 g) s: y% p. u#   输出:与指定用户最相邻的邻居列表2 ]8 g, q! `1 N/ O8 u
    #- A  o5 P. S  M& n$ D6 ^; h' p
    def calcNearestNeighbor(userid,users_dic,item_dic):0 W4 r) ?4 |" x
        neighbors=[]* q) ^; N8 j8 C; j
        #neighbors.append(userid)/ N. Y+ v: r( H6 }
        for item in users_dic[userid]:6 |. G1 z5 y/ ^+ T: P' O" J1 i
            for neighbor in item_dic[item[0]]:
    1 {; q" U' k0 h            if neighbor != userid and neighbor not in neighbors:
    8 c8 x2 Y, u" w( j                neighbors.append(neighbor)3 N# v+ O: I- Z' j
          
    $ y) s% L: u8 d9 q" m, k    neighbors_dist=[]
    2 B8 y8 e! M  A4 ~    for neighbor in neighbors:
    5 G# p+ y# W) }2 u; r; H" s" x2 r        dist=calcSimlaryCosDist(users_dic[userid],users_dic[neighbor])  #calcSimlaryCosDist  calcCosDist calcCosDistSpe% Z1 [. S; C5 A3 }2 q/ `
            neighbors_dist.append([dist,neighbor])0 S3 ]) x. {+ z. L
        neighbors_dist.sort(reverse=True)
    * O  I+ t) c1 o    #print neighbors_dist+ Z: n  X! c/ o
        return  neighbors_dist
    2 u$ k* S+ Z3 s5 j) W8 }% Q) h& H6 G& x

    + Y4 i1 y0 \# P5 D% b+ E  l6 b" O; V#8 \7 e/ {9 e6 x- y2 S
    #   使用UserFC进行推荐1 y! c- y$ c; W, x$ X) _: T
    #   输入:文件名,用户ID,邻居数量
    8 [9 H5 l# J4 m7 Y#   输出:推荐的电影ID,输入用户的电影列表,电影对应用户的反序表,邻居列表
    ; V; g* c% w0 `#
    ) b5 _: y7 J1 @4 a) B+ cdef recommendByUserFC(file_name,userid,k=5):
    6 Z4 Z/ B0 `+ p4 M: i    / a; S% t7 R& s4 W
        #读取文件数据
    - ]- t2 w) i1 ~: C1 l- j$ S1 c    test_contents=readFile(file_name)
    ' L7 o2 I. K" D/ A. h0 v   
    ' {" ^2 m: h$ u  L& H7 d! i    #文件数据格式化成二维数组 List[[用户id,电影id,电影评分]...]
    * M6 F3 f2 `% W1 t    test_rates=getRatingInformation(test_contents)$ |' k! S5 L% F3 `; _
       
    3 Z5 |9 L, I- L$ d% x% q- w    #格式化成字典数据
    # |7 x# ?0 n" k; P    #    1.用户字典:dic[用户id]=[(电影id,电影评分)...]
    ; O- G% G7 a' C  q- _8 {& q% b    #    2.电影字典:dic[电影id]=[用户id1,用户id2...]
    ' p; b2 n  c: F; m$ j1 G0 J    test_dic,test_item_to_user=createUserRankDic(test_rates)3 M2 l% N" A( G8 q" Q7 B  v
       
    ( g# Z+ Z! z( }5 r' z    #寻找邻居
    * Z& F  E# O6 S" S    neighbors=calcNearestNeighbor(userid,test_dic,test_item_to_user)[:k]
    2 _1 j3 f0 x* B' _2 U  `! t# C        
    ! {. B0 G  v$ s0 n    recommend_dic={}
      A- I. H+ O4 \5 u$ c4 Q  Z) T    for neighbor in neighbors:1 F0 R8 F  y: R) I# E: Z7 c- Z' P9 [
            neighbor_user_id=neighbor[1]* |5 G  k2 D5 i7 n- L$ p1 Z2 t# B
            movies=test_dic[neighbor_user_id]6 M( R: N8 t' z- h9 i- m) d
            for movie in movies:
    3 V" [4 ]/ y4 e: ~! y3 f            #print movie  j8 P# e1 u" O' o: }0 C, T
                if movie[0] not in recommend_dic:
    ' c. H" P! j/ s5 M8 N                recommend_dic[movie[0]]=neighbor[0]
    % T) K* L0 y5 w% I) n- y, q( w            else:
    & T: C1 |3 t: V4 Y- c7 t                recommend_dic[movie[0]]+=neighbor[0]* L0 r% u0 h6 K" U% q
        #print len(recommend_dic)
    ' e# |4 @) h, C# K    ( g* _/ l$ S+ O1 B" c/ Y9 R
        #建立推荐列表$ z. T+ k) k! e- c- j$ a/ r
        recommend_list=[]8 l2 R8 R# z0 ?
        for key in recommend_dic:+ L5 G- [* X) l) `1 a6 B3 N
            #print key
    % g" n7 t* V  B3 {5 n3 z8 a! h& b        recommend_list.append([recommend_dic[key],key])7 t! C% {  c, |9 q3 U
        8 n  A% g# [% J5 A  B# Y; [9 N
       
    & t) j6 H  L3 \4 R  @9 M* V    recommend_list.sort(reverse=True)! v4 p% |# R2 Z" m
        #print recommend_list" B: U# `$ i1 J/ l) v) F
        user_movies = [ i[0] for i in test_dic[userid]]8 G& @3 q( W' a' q0 L9 g
    : \, k: a/ i. @; J' z# j8 O8 u0 T
        return [i[1] for i in recommend_list],user_movies,test_item_to_user,neighbors
    : A/ C1 D, W, E' F   
    ! U! C- |, C! C    / \7 A4 Y: X( u1 q
    4 B; j+ j) e9 {2 o( @# E
    #6 k$ p5 O9 Y6 j1 s( y
    #: }1 w7 n  y; [, z+ Y) i  P6 I+ r' L( V
    #   获取电影的列表1 n* F2 Z' b9 z
    #3 d2 [3 [0 G1 w
    #
    ) J8 x' P/ E. N3 `/ D# b+ Q#
    , N: H  t$ s0 A# E6 ~def getMoviesList(file_name):
    # \: J$ M5 l/ F# e4 [# i) t    #print sys.getdefaultencoding()
    $ |# L7 l: I6 x! E9 l0 y( H6 p4 L    movies_contents=readFile(file_name)
    1 A: y5 F$ m: n+ E4 q5 O, ~    movies_info={}5 V9 ]/ E  w. z/ |+ G5 V3 K% ~
        for movie in movies_contents:6 [; F# Z: U; L; u& |! G/ e
            movie_info=movie.split("|")
    5 }' m3 b+ I5 h- y, s4 k  k. W        movies_info[int(movie_info[0])]=movie_info[1:]
    6 J3 v5 t: d* C% I8 z; K6 [# q! K+ m. q    return movies_info3 x+ K2 [/ c. m) g
        + q; Y/ D$ s! `" Y
        4 h- x' _* n4 y0 j, z0 g8 s1 ~
        2 `) ?  q2 B/ f# Z$ b) W1 N& T
    #主程序
    : o5 N( x4 {; l5 J: A/ W#输入 : 测试数据集合
    - H' P8 ]" {8 Jif __name__ == '__main__':
    $ n8 O+ U. l% b. D, r9 X' H    reload(sys)
    2 p) u. Y- Q: E, Z' S    sys.setdefaultencoding('utf-8')
      T7 k* D6 Z5 X9 j    movies=getMoviesList("/Users/wuyinghao/Downloads/ml-100k/u.item")6 V, w3 h0 O. T9 A2 M
        recommend_list,user_movie,items_movie,neighbors=recommendByUserFC("/Users/wuyinghao/Downloads/ml-100k/u.data",179,80)( b3 k( B% ^# I+ f! E( d
        neighbors_id=[ i[1] for i in neighbors]
    6 i  a  F, |1 l; V: e    table = Texttable()0 E2 R, N. l& C6 U
        table.set_deco(Texttable.HEADER)
      I# [7 M# m* R3 v    table.set_cols_dtype(['t',  # text & T5 f& {+ [( x' p% S, \
                              't',  # float (decimal)
    4 Z" V! e3 s3 Y/ M- d8 b) x7 @& _) ~                          't']) # automatic
      L) b1 ^* @* O* N, q    table.set_cols_align(["l", "l", "l"])) B9 B; |) D0 X8 Z, B
        rows=[]$ A- f" w! u( A
        rows.append([u"movie name",u"release", u"from userid"])
    * F2 c. [0 z/ y    for movie_id in recommend_list[:20]:
    6 S- N& [) N/ K; e: a$ O; ^        from_user=[]
    / @- w* M' n* j  X6 {" k        for user_id in items_movie[movie_id]:9 S* b7 @. T' k. |
                if user_id in neighbors_id:
    : Q9 z+ }( n+ ~4 }" `                from_user.append(user_id)
    ( Y3 y0 O" V( z. L' [        rows.append([movies[movie_id][0],movies[movie_id][1],""])* K9 m5 W0 O  Q3 [
        table.add_rows(rows)
    4 R1 L# m! N6 ~8 ?. y6 n    print table.draw()
    回复

    使用道具 举报

    mea_lsc        

    2

    主题

    10

    听众

    638

    积分

    升级  9.5%

  • TA的每日心情
    擦汗
    2016-4-14 14:41
  • 签到天数: 212 天

    [LV.7]常住居民III

    自我介绍
    数模新手

    社区QQ达人

    百年孤独 发表于 2014-7-19 09:22
    % w0 i" {* W% t- X5 d8 T0 o+ q0 l# -*- coding=utf-8 -*-4 c) A. K$ l2 j; s/ d, A- _+ L
    5 m, C. G9 C, ]/ ^- v
    import math

    : |6 c3 s& y( D这是什么语言的程序?9 K/ d# s% U) s) {& N- @
    回复

    使用道具 举报

    0

    主题

    4

    听众

    40

    积分

    升级  36.84%

  • TA的每日心情
    开心
    2019-8-30 15:45
  • 签到天数: 12 天

    [LV.3]偶尔看看II

    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

    关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

    手机版|Archiver| |繁體中文 手机客户端  

    蒙公网安备 15010502000194号

    Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

    GMT+8, 2026-4-17 15:11 , Processed in 0.455081 second(s), 68 queries .

    回顶部