QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4998|回复: 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
    本人在学校参加暑假培训,需要这个算法做题!求大神赐教,感激不尽
    3 y0 D4 U; b) q. [- m& B& c
    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 -*-
    ' M0 z# M' A6 q9 _, J/ |0 ^% {
    % l$ g) |' L. W$ P  p1 S  m; v  M; _import math. [+ m$ o: B( Q# O
    import sys# v2 C1 a% H- W  j
    from texttable import Texttable
    . K+ {  S7 b, v6 E, S
    9 |# h6 A- C' W
    5 E( L* ^" ^$ k6 I( j, }8 s2 D. ]% y#1 s7 a$ Z9 @4 s& C# J" c9 ~$ \
    #   使用 |A&B|/sqrt(|A || B |)计算余弦距离
    ( c  h# u6 d1 q#. ?9 h; O0 h5 L  S8 d' s$ W6 B# N
    #5 E, A" C" l) e! g/ v# @
    #, Q, T7 T. P; N# J
    def calcCosDistSpe(user1,user2):0 R& g- |2 {8 }7 T
        avg_x=0.0
    4 j( k' X% J3 J2 I; ]( |( G    avg_y=0.0  z) G( R2 ~+ M' P  p5 n& }- ]$ [
        for key in user1:5 a3 K) ?* }1 e3 g" h3 t
            avg_x+=key[1]/ q% j, }7 y& I" I/ O
        avg_x=avg_x/len(user1)
    # u/ y9 `) D( K; c/ l& V+ A% o1 d   
    % r- V# Q. v; g5 d# {; V% }% B0 H, y    for key in user2:& o8 y1 C; ]$ `' ^$ B, N3 U3 h
            avg_y+=key[1]$ T6 B" s2 B4 o8 h4 c, i
        avg_y=avg_y/len(user2)
    $ B- {: l- r/ l* Y' w. a4 [    ' T3 B/ x  a9 G, c4 h
        u1_u2=0.0# \! n9 [- l% h; J' k$ e
        for key1 in user1:1 F; G/ q/ ]; T$ a3 |
            for key2 in user2:
    2 ~- R4 W, C& R' b            if key1[1] > avg_x and key2[1]>avg_y and key1[0]==key2[0]:
    ) |# M6 Z" t  i6 w+ y* N                u1_u2+=1
    " v( t" W* {' T# A, d    u1u2=len(user1)*len(user2)*1.0" j, d+ m& }( g: D5 r
        sx_sy=u1_u2/math.sqrt(u1u2)( B) T5 o# Y; a# b8 n
        return sx_sy1 u/ J/ ~& H  B+ ^7 A
    # ]. |3 t( ^& j. [9 C2 W! w. X

    ' ]( ~4 l9 ^4 \8 O#
    & b& e" e9 e5 M+ m#   计算余弦距离
    % A: n2 T& m- ~0 h: v#: x5 I/ \0 M6 \+ C, l) c' \( q
    #' |: X1 \) n" a" ^4 W6 z- h
    def calcCosDist(user1,user2):' L$ [. |% Y- n4 \6 L# E0 k9 t- n
        sum_x=0.0
    $ J# I/ F! h4 I9 ^+ Q* [    sum_y=0.0' v2 E( M" M  Q6 _- r" V% x
        sum_xy=0.0$ H# U2 ?+ P; {( G" N
        for key1 in user1:
    6 t  N; y7 Z! H! T  H        for key2 in user2:
    : `( y& d6 X  p2 A            if key1[0]==key2[0] :( O2 v) p( y( o, t& U; e
                    sum_xy+=key1[1]*key2[1], X* c0 n4 Z( `! |
                    sum_y+=key2[1]*key2[1]) F4 O2 T& r. O6 Z( l
                    sum_x+=key1[1]*key1[1]8 |2 L8 l7 t7 F
       
    % g4 }# |* ^8 O: y1 v% j9 Z, C9 o    if sum_xy == 0.0 :
    ; ]" d9 D8 ?/ w: o9 E' L- X6 E        return 02 S0 g9 P3 e4 U9 l  n* e* x! U6 G
        sx_sy=math.sqrt(sum_x*sum_y)
    : G1 N- x: M  D0 g' e& [% g    return sum_xy/sx_sy1 w5 G0 W- D- ]+ R
    : c/ V# ?# Y, J" z1 Q& ]  G2 h8 O
    ; `2 ?7 e# |  y: ^7 z$ U
    #
    + G0 U2 @0 G0 ~  R#
    : [( D5 @3 t: m/ k* g1 u#   相似余弦距离
    3 d, m1 D! x$ {. H% U6 w#1 c8 t; l4 ?2 ?; k2 r6 m' N; u4 ]1 f
    #
      L8 h6 g# q9 i#
    , k1 p6 Q7 t& r, `6 Wdef calcSimlaryCosDist(user1,user2):& ~6 G* Y5 K5 Z* p9 C+ I/ y3 _
        sum_x=0.03 a2 L# P4 `" U* j9 Y0 h/ r' G
        sum_y=0.0
    $ w; A8 u6 N5 q; n9 c6 D    sum_xy=0.0, w# \% S6 {, Q4 Z* {- L) @# c( S
        avg_x=0.0
    9 u/ {+ U1 n7 z5 `' O) j    avg_y=0.0" ^% W0 v' P" }5 Y5 z, H+ y
        for key in user1:
    8 Q! O* h, M, F2 a, V/ v        avg_x+=key[1]
    ) m5 y9 j6 {- s4 M    avg_x=avg_x/len(user1)
    ! r6 o- j8 g- X# O6 v( O   
    - d; g9 }2 A. ?# s$ x    for key in user2:1 K- ]+ n  s# |6 }0 G" r1 n4 y
            avg_y+=key[1]
    , I) S' y5 i( o8 \3 _5 n' ]    avg_y=avg_y/len(user2)
    5 {3 N% c- ^+ w, i2 {1 z& O' L   
    3 }/ O! A- ]$ n* i5 L* {% A5 T    for key1 in user1:
    - C& X6 I/ [- k  j6 s        for key2 in user2:
    5 o; H5 H  ~' L" U% w. \- L            if key1[0]==key2[0] :
    9 h) X' ~+ q8 k5 ~* P# N                sum_xy+=(key1[1]-avg_x)*(key2[1]-avg_y)
    * a9 A8 H% o. [, p2 s0 c2 }                sum_y+=(key2[1]-avg_y)*(key2[1]-avg_y)0 v) t* C$ W- _+ |) i2 ^" G' C
            sum_x+=(key1[1]-avg_x)*(key1[1]-avg_x)
    % M1 B) L3 G: g   
    5 v1 q( q+ @0 Y    if sum_xy == 0.0 :
    ' S3 k7 b2 t4 g9 m        return 0
    1 S! n/ {" }* \/ W- H: l3 T  O* @    sx_sy=math.sqrt(sum_x*sum_y) + q/ K( w( I% q8 s2 h2 L
        return sum_xy/sx_sy/ d/ {& a  D; f  ]' q. W/ C
          z8 k2 D" n) `0 c9 U

    0 ^' y: k, j1 R( m#4 Y4 p/ o0 T; f  l
    #   读取文件
    ; p" J- s( c+ b% n" E$ B#
    $ Y" l6 ?* Q9 x- _' M2 ~6 x  a#
    3 A  u4 F" O( L5 w7 S* G: u* Fdef readFile(file_name):, H) }* Z  t/ y4 W* x' p/ e% a
        contents_lines=[]: o7 S* G) _5 b* r5 g; L! s
        f=open(file_name,"r")- j  x0 @6 D& a3 V, P- \. `% ?, p/ {
        contents_lines=f.readlines()
    # A) [) r8 L) I    f.close()
    5 B8 H5 d5 r8 z, l* ~7 P6 ^9 T- i    return contents_lines$ k/ l; w5 M" C# ~& h: M

    8 Y0 @" E# E; B  v, D
    % W# \+ Z3 ~- e- ?1 E( r& Z! O  n% l
    3 g, B; m; \6 }) Y9 p#5 y5 B' k: m  |. ~- H! }
    #   解压rating信息,格式:用户id\t硬盘id\t用户rating\t时间
    8 Y, m! \0 B, o( E+ I8 @#   输入:数据集合
    # w5 w3 u  u7 f) T+ {6 p. t, R#   输出:已经解压的排名信息
    0 T4 E- N  j. Z+ @5 V' e6 `#
    ; Y" w# P/ S6 S$ P- s0 N4 Q1 mdef getRatingInformation(ratings):3 T, t2 l/ H3 X5 E- o: F" B
        rates=[]' X& X& C( Z& R$ W3 w
        for line in ratings:  s. o# V# d0 s5 G
            rate=line.split("\t")3 C2 C( T" {. p, z8 u
            rates.append([int(rate[0]),int(rate[1]),int(rate[2])])
    5 t2 Z' x% Q$ W2 m! ~8 l    return rates& F+ L* G) M0 _7 a) y3 |5 t
    6 K1 G8 d5 A( Y! t, |( n+ x+ i- b/ Q
    " E1 S+ B* Q5 m# r% s/ e) o8 d" l
    #: X0 H" S6 t% O) e/ _# \2 F
    #   生成用户评分的数据结构- I' X; j$ J/ n$ n6 @# D% C
    #   
    6 t; b3 R, |7 }#   输入:所以数据 [[2,1,5],[2,4,2]...]
    $ M1 Q6 H) y& c( i$ ~! q3 G#   输出:1.用户打分字典 2.电影字典* H1 l) x; u! i  i: b# p
    #   使用字典,key是用户id,value是用户对电影的评价,) u1 \6 ?) o, n, C0 {
    #   rate_dic[2]=[(1,5),(4,2)].... 表示用户2对电影1的评分是5,对电影4的评分是27 w  F$ n- U, g4 z
    #
    : D  F. h; E3 `- ldef createUserRankDic(rates):
    * Q% t& M9 Y# l    user_rate_dic={}
    . o7 U; K# z4 u3 o; d& a1 b    item_to_user={}7 e6 a+ s3 v3 `; N0 c1 E
        for i in rates:
    3 s* `  L1 ?9 o! b9 x3 z; F1 m- X: R        user_rank=(i[1],i[2])
    7 [: L  C7 _1 N        if i[0] in user_rate_dic:  z, }) I* f  \7 y/ b7 ]* R
                user_rate_dic[i[0]].append(user_rank); n5 X/ V5 e" I8 W, [" P
            else:
    + |, l# l3 F( q' a            user_rate_dic[i[0]]=[user_rank]! E5 M, _! d# R7 I# N6 s
                " e( g& `+ h% u8 ~* c/ G
            if i[1] in item_to_user:
    3 m6 v5 M7 Y% W% ^1 H9 l) m            item_to_user[i[1]].append(i[0])& i# F$ U2 E* B. O* x  {
            else:
    * ]5 Q% t" A, N! i: m9 E            item_to_user[i[1]]=[i[0]]
    + y2 p8 j8 h6 x6 J8 ~            5 ?3 q" G2 `. a( g" h
        return user_rate_dic,item_to_user
    ) I- g/ d- v% p! p  Z& t; x* R5 \: |) [8 Z
    3 Y! f1 c% X, I, V1 q
    #
    & N. @- {0 t( z7 s#   计算与指定用户最相近的邻居
    ' m' l" k0 e9 K- ^& A% O0 C#   输入:指定用户ID,所以用户数据,所以物品数据
    & d9 B0 G4 b1 h2 Y4 d% g# p2 c0 L#   输出:与指定用户最相邻的邻居列表' A1 a# f5 N0 X* E
    #
    6 b, V1 `. K8 Sdef calcNearestNeighbor(userid,users_dic,item_dic):6 [! Y! U! e: k! J  Q- a, q
        neighbors=[]
    ; `. p8 w# j' L, Y% t    #neighbors.append(userid)
    , a4 C- Y; M, Q7 w* O( \1 d; `0 v  o    for item in users_dic[userid]:
    6 N" z: D2 M" L& ]. w        for neighbor in item_dic[item[0]]:
    9 f9 g! z; g3 d, \8 \9 ]. Y            if neighbor != userid and neighbor not in neighbors:
    ) v- Y) r5 B1 D0 N' S- J; n                neighbors.append(neighbor)* [% A' U4 @$ W5 p/ y& M& `+ o. u2 S
          
    . Z( E2 v% s( {    neighbors_dist=[]
    5 V* m6 m! g( }1 N2 I1 v    for neighbor in neighbors:& P$ A7 [" o1 T( z6 s# D
            dist=calcSimlaryCosDist(users_dic[userid],users_dic[neighbor])  #calcSimlaryCosDist  calcCosDist calcCosDistSpe
    : J$ X+ X; J/ c8 G        neighbors_dist.append([dist,neighbor])
    7 F- v' J5 ]4 W8 t+ x    neighbors_dist.sort(reverse=True)3 s8 [, s$ q/ \' [
        #print neighbors_dist
    . @' G/ I3 Q, y7 k8 w    return  neighbors_dist
    + @, i7 o0 ~6 |  ]+ z7 j$ c8 @& v  N& E
    % D3 N4 t/ M! }  }
    #
    : @( H' F4 |. P3 S2 M#   使用UserFC进行推荐
    " i5 t+ P0 S! r% q4 j#   输入:文件名,用户ID,邻居数量
    0 q' H" ^; H) W) T! V#   输出:推荐的电影ID,输入用户的电影列表,电影对应用户的反序表,邻居列表: A. |0 b1 g# b- y8 X5 v
    #
      ~7 ]( g0 Y7 l5 K+ w' qdef recommendByUserFC(file_name,userid,k=5):* v  {% y, [& g: P5 \% G! G; _' ]7 ^
       
    8 c: C1 @0 V. f* J% R    #读取文件数据
      a  I4 _  }& \' h$ t% Z5 c6 `    test_contents=readFile(file_name)2 e: F# D  B/ _% T( Q
        7 L3 b$ |3 t% F  ?, ?0 i4 \/ g
        #文件数据格式化成二维数组 List[[用户id,电影id,电影评分]...] 4 k* K' _: E5 Z
        test_rates=getRatingInformation(test_contents)7 s" q. }6 z! z; q
        8 f# u% _1 w4 ^
        #格式化成字典数据 3 n; V- t$ C, a; c
        #    1.用户字典:dic[用户id]=[(电影id,电影评分)...]
    3 T( [7 h- X  `    #    2.电影字典:dic[电影id]=[用户id1,用户id2...]
    8 u) C, ?6 ]5 B5 R1 n1 b    test_dic,test_item_to_user=createUserRankDic(test_rates)
    # o: g  v, A3 l; R3 _- P3 @   
    + D6 [5 V$ s# U    #寻找邻居, i5 _% D/ c0 [! d
        neighbors=calcNearestNeighbor(userid,test_dic,test_item_to_user)[:k]
    + ]1 U' @% \) T: w' h8 J        
    2 O% i. x' l6 L  @$ e7 h/ b) {    recommend_dic={}4 `1 s) Y* i* Y, K
        for neighbor in neighbors:- g) X! K$ u1 T/ f4 \' w4 k. e
            neighbor_user_id=neighbor[1]* b/ x, E0 B2 l. {, e  l
            movies=test_dic[neighbor_user_id]
    " x+ T* S4 K( T7 C7 Q" V        for movie in movies:# I. U! g% U8 o/ Y- Y# P! k
                #print movie0 K7 @5 J: z& _9 U, m
                if movie[0] not in recommend_dic:2 V4 V" {& S% K$ I- T) K; K5 i
                    recommend_dic[movie[0]]=neighbor[0]
    0 V. Q( R# i+ j* a) X! }# t            else:, b' y* s% ]- h  l1 v
                    recommend_dic[movie[0]]+=neighbor[0]2 t5 l2 k0 t( ]( O) T: T/ {
        #print len(recommend_dic)
    / K) V+ Y) @& R9 h( K   
    * @) N' R2 ~8 O    #建立推荐列表  N4 ?9 v3 m8 d/ U
        recommend_list=[]  i' F  {6 S" M$ ~/ E
        for key in recommend_dic:: @& z9 M$ `6 {  r* l
            #print key2 ?5 K$ x; U5 P0 v7 n
            recommend_list.append([recommend_dic[key],key])) \: J+ @; W7 d& f& W
       
    ( c0 ~: A7 E3 R2 }$ w   
    + L$ k. l. l  n    recommend_list.sort(reverse=True)
    ( A0 ^4 ^! k' V. r1 K    #print recommend_list4 ^7 y* Q$ z9 b" B& D* E$ N- o5 V
        user_movies = [ i[0] for i in test_dic[userid]]' U) @" `% }: @. L2 G. T- F' D5 d7 ]
      |: _7 T7 f/ L1 s
        return [i[1] for i in recommend_list],user_movies,test_item_to_user,neighbors
    : [' V5 o% S5 Q1 k$ f   
    8 b  G* l% W# s, ?    & u; b: h' Y1 i' ^* I
    ( Q2 Z- l1 q- Z) }( k, n) j% A9 P
    #
    7 a4 l* O( Q1 v3 h; O  ]0 A#
    6 ~+ O5 l0 i" l, b5 r# q#   获取电影的列表
    7 y  c) f& n( O8 d- c, d#2 e3 M  w* Y- N0 P
    #) E  H' g7 o) a* H6 C& F
    #
    / {" x9 ]. c* c% U  V% R) \def getMoviesList(file_name):  j/ v1 i3 X9 ]
        #print sys.getdefaultencoding()! j, i& }7 j  ]  G0 I" I
        movies_contents=readFile(file_name)
    8 Y$ Z' Z1 U. R5 F6 p    movies_info={}! Q. p+ U  ~# b0 C
        for movie in movies_contents:
    $ v  W. b' Q& X        movie_info=movie.split("|")
    / C6 x1 {' l; y# G( n/ O' U        movies_info[int(movie_info[0])]=movie_info[1:]; h7 ]. x2 e5 n+ r
        return movies_info! ^, Q: {, C% {( D' H. D
        " K0 r2 a: r( m6 w5 D% n* e1 m
        $ P' p5 [! w9 A9 Q+ E- s( l
       
    & ?8 o" \) Q- q$ }#主程序+ [- N1 G2 t8 d. U& V
    #输入 : 测试数据集合
    ; I) |( ?( n0 w$ I- }; _" nif __name__ == '__main__':' R7 @0 Y2 C! f. S; w% g- q" Y
        reload(sys)
    ( I- J  K; D5 c1 l2 ], A( L( m    sys.setdefaultencoding('utf-8')& f7 i6 z6 K1 v( t( e
        movies=getMoviesList("/Users/wuyinghao/Downloads/ml-100k/u.item")& B" T5 L4 ^8 c
        recommend_list,user_movie,items_movie,neighbors=recommendByUserFC("/Users/wuyinghao/Downloads/ml-100k/u.data",179,80)
    8 B, D; p0 h* i8 q$ r9 q- ]2 Z- [9 t. P    neighbors_id=[ i[1] for i in neighbors]
    $ G- O2 S7 C4 S; S    table = Texttable(), S; [, q. O1 p/ X( v9 W2 j
        table.set_deco(Texttable.HEADER)
    $ N+ ?& l2 M- k% I, Y% H  K    table.set_cols_dtype(['t',  # text
    & Z" M7 C9 A# G/ R                          't',  # float (decimal)
    / f) G' E1 S0 ~5 J3 r, [                          't']) # automatic2 d  ]6 }" d' W* s, h+ V* p2 @  E
        table.set_cols_align(["l", "l", "l"])
    / d: Y) m, U6 m; O3 R/ G8 J    rows=[]
    ! {9 F% D2 g4 `% s    rows.append([u"movie name",u"release", u"from userid"])
    ( r6 i: o( N+ r* ~# r    for movie_id in recommend_list[:20]:
    ' H! g7 |; t. d- I" f8 j        from_user=[]
    + l( w1 S6 M9 d% J% @        for user_id in items_movie[movie_id]:
    0 }, |) A+ i0 K& h. ], a            if user_id in neighbors_id:: l" e6 g0 s! D: f
                    from_user.append(user_id)/ j# s" ~/ F+ @7 |3 N
            rows.append([movies[movie_id][0],movies[movie_id][1],""])
    ; P/ n5 h( `& p) Z* w3 I# _  U    table.add_rows(rows)
    % A3 l; H2 x( \8 `5 l  U    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 % R. j1 R8 f8 w# p  i/ [
    # -*- coding=utf-8 -*-# T& @1 M+ u9 X2 p- p9 C3 ]
    " D% X/ q- Q! o% L8 K0 j* D
    import math
    2 g; a/ G9 g* e; j4 A) i8 F
    这是什么语言的程序?
    & l0 m) R4 \' [, d2 h8 \2 {
    回复

    使用道具 举报

    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, 2025-8-20 06:52 , Processed in 0.407277 second(s), 67 queries .

    回顶部