QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 5322|回复: 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
    本人在学校参加暑假培训,需要这个算法做题!求大神赐教,感激不尽
      S* Y5 ~( i9 ], G; I6 ^7 _" k. [
    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 -*-8 P) x3 d- L9 ~: b3 k+ [( n1 U' ]1 f
    2 g% C  Q* }8 }" M% T
    import math
    ) b0 X0 r4 e% M+ ^, q, q- G* Iimport sys
    7 P' X1 y! F$ B# e1 hfrom texttable import Texttable
    " I" z' ?  z2 m( s& c, G% J
    , ^% I, r9 a3 r7 p. k
    ! j  g0 B% l4 W% H#% v8 H3 A# {: D6 C, v$ U
    #   使用 |A&B|/sqrt(|A || B |)计算余弦距离
    / I- F2 Y+ l/ l5 |0 g% @#
    6 u. j+ s* Q- l% n) U$ v+ w#
    1 F# K  ]1 p* y# T. o$ X2 _! F#8 o- i+ b' `# U/ _) A7 y% ^
    def calcCosDistSpe(user1,user2):* ]& F& f, d& `7 a, t( `
        avg_x=0.0
    3 p, L6 [" d3 I/ D    avg_y=0.0
    % Q7 g* `& [9 _' y0 g6 G& k  ~    for key in user1:/ ^4 N" p) ^9 {- a+ c( {
            avg_x+=key[1]
    ! u. K8 T8 }4 [% f' T4 k    avg_x=avg_x/len(user1)
    8 H3 {1 H, Y  Q6 g& r2 g# o# c% c    " D# N8 j( {! g! `4 ?
        for key in user2:, M& s& Y/ G6 Q. f  i# B- c  [  ^( q
            avg_y+=key[1]. M- {4 B4 {. o; N7 X* H% W
        avg_y=avg_y/len(user2)
    6 A& K% ]- U$ t  w$ l8 X; U   
    4 S9 W" q7 S( B/ P( C* z8 ^    u1_u2=0.0
    $ n7 N8 I; ^1 @" R  u2 s% E+ i    for key1 in user1:9 b- X  u! o1 S( |8 V) N
            for key2 in user2:/ R' s: z' p6 k& A
                if key1[1] > avg_x and key2[1]>avg_y and key1[0]==key2[0]:
    2 I% x! e9 m9 R& x                u1_u2+=1. {' h6 Y& @+ I) w+ _% r4 D
        u1u2=len(user1)*len(user2)*1.06 @2 G* J4 Q( d& u
        sx_sy=u1_u2/math.sqrt(u1u2)
    1 V. R5 S2 p+ x, @. R, B! p7 w8 q' @    return sx_sy) v5 R8 W  @8 L% G% H/ S- P
    ; e- |+ J8 j9 k- a
    & I* D6 E' Q( g2 p' R+ K
    #
    1 h/ \6 k! ?) v9 s) A. S( X- l/ ]& [#   计算余弦距离
    ) K# \% D/ {# z- M#7 T6 `: V- Y/ ]! k) i7 u# b
    #- s7 j* X( Q  [$ F  f( T
    def calcCosDist(user1,user2):
    ) A* g& g% T# l2 Y7 w8 y$ X    sum_x=0.03 K1 C- p: K+ H2 k
        sum_y=0.0
    % @" u0 H( F2 o- i4 e  a    sum_xy=0.0: j# w/ ]$ l" z0 e! g
        for key1 in user1:
    9 f+ W# ]6 _: N* \: Y        for key2 in user2:+ L: q6 ~' A6 E& N+ v: |# L
                if key1[0]==key2[0] :
    ) ]/ q6 D8 M& J5 z! V4 v1 P                sum_xy+=key1[1]*key2[1]; }3 S  c* c3 ?1 i
                    sum_y+=key2[1]*key2[1]4 _6 k' G# r' ]$ [
                    sum_x+=key1[1]*key1[1]" s2 p" R6 d+ @) I$ v0 y
        : E. Z& |; Q; w; }& Y
        if sum_xy == 0.0 :: c2 z5 L. K* W/ a7 [- C, q. u& ^
            return 0
    % g0 E1 v0 X; P5 t( _    sx_sy=math.sqrt(sum_x*sum_y) 2 f- y# i, G. P( c7 Z7 ]: ]( P
        return sum_xy/sx_sy* w3 r. P2 ?1 r) h2 W/ d' g$ t6 g

    + V- V6 e$ F  \5 H1 i& _, M
    - ~$ \, w: R: |0 D4 t+ W; O  t#/ Q( u7 q; d, O3 }
    #
    $ \+ S; t# g" d5 |' v+ Y! h* D#   相似余弦距离' e3 ~1 G- a# |8 [& z7 O3 t/ n
    #
    , l- [* n. H" K( y. p0 a#
    6 M1 n. e2 ^' o0 x  e0 ~+ O/ x  d/ A#
    2 m7 ?. C" H" E; vdef calcSimlaryCosDist(user1,user2):
    , {1 V8 ?5 f3 {    sum_x=0.0! d' ^4 z6 w% c4 N
        sum_y=0.0
    - ~7 X1 v; K) ?$ S( C" Q    sum_xy=0.0) W$ f8 i# j; H( t5 b/ u
        avg_x=0.0
    ; A' H  ^3 p( j& i* j    avg_y=0.0/ I* S0 f  V1 x7 M
        for key in user1:
    ) f2 D+ n* \! r3 ?# T* ~* k        avg_x+=key[1]+ Q4 J6 P3 A" e8 ?. M1 z" i( a
        avg_x=avg_x/len(user1)! R3 |# e* k& T
        5 {" f% \; s- \; h' U& D2 h' V
        for key in user2:/ q( _: G2 t3 g$ e4 z! W8 t0 q
            avg_y+=key[1]4 d+ _) @1 |' M
        avg_y=avg_y/len(user2)7 p) ]9 n$ b& Y% B8 n3 Z# \
        + d# V: M9 O' R% _% H- U, n
        for key1 in user1:
    . K: q9 o" r+ C/ c        for key2 in user2:
    # J# B% r5 {& t, y6 H            if key1[0]==key2[0] :) |! K& O1 B2 C6 l2 y
                    sum_xy+=(key1[1]-avg_x)*(key2[1]-avg_y)- \. e1 y/ @9 U8 Q
                    sum_y+=(key2[1]-avg_y)*(key2[1]-avg_y)
    6 Q4 S& d" w/ }* M( A" B        sum_x+=(key1[1]-avg_x)*(key1[1]-avg_x)2 R, {% U) m1 C- x8 J0 \
       
    1 ^6 M- o! t0 N1 W2 Z* U/ |    if sum_xy == 0.0 :% f4 w# f6 A' K/ c2 n
            return 0
    + A: p/ o0 Q/ ]' E* M% s    sx_sy=math.sqrt(sum_x*sum_y)
    6 c( h& t" j% }) Z! V/ o! a    return sum_xy/sx_sy% u9 V! v+ y3 G, P( k# ], a4 B
        * j( J1 I, O  p5 M$ f% \
    # u6 `3 B+ G, p+ K% P& j0 A2 v! P
    #* S3 l/ X9 {; {( x, k: u1 Q
    #   读取文件
    3 d: s, W/ r% E. |3 F9 b5 T0 p#
    6 M# l. k$ ]* u  W5 f" K6 k/ x* T5 R#
    - {0 i9 i1 A- U8 @& Odef readFile(file_name):
    ! x. i. {( N4 _% Y% X, z( D    contents_lines=[]
    6 s0 m% Y. _( P! Q  W    f=open(file_name,"r")+ L0 l2 s! P; B9 E9 w4 Y- u* ?5 H
        contents_lines=f.readlines()
    ) z$ H/ a4 X* U" D& y+ u  E! P2 c    f.close()
    ) M" L8 Z+ R5 `    return contents_lines' h; e4 n! |& e6 Y/ Q+ @! |$ b8 k

    + P5 W2 L* F: f& `1 [8 |( ?7 I
    - ?( \5 b8 f6 v0 Z5 z9 u% W
    ) }* v. U, L& @/ }#
    0 z. s2 T9 Y) I/ O) k6 u0 p+ u) D#   解压rating信息,格式:用户id\t硬盘id\t用户rating\t时间
    4 E* o0 i. f/ _; ^6 u! p6 c#   输入:数据集合
    1 D5 H/ I0 a6 R) ]# w5 d- a1 k( N#   输出:已经解压的排名信息$ t# [$ W) P! p4 r% q
    #
    ( J2 u! c; [* g5 ^% o' J& \def getRatingInformation(ratings):
      t( H8 D* |5 H- n    rates=[]
    1 Z' R% Y: I+ ~( \3 v9 {    for line in ratings:$ J9 v' k* r+ ]. c, l3 [; ?
            rate=line.split("\t")
    : @( X/ j! i3 i+ O$ O+ S7 n: j5 t        rates.append([int(rate[0]),int(rate[1]),int(rate[2])])
    ( i' E7 a$ e8 Y1 n& Y8 J    return rates
    * M0 R& E' g+ B3 h" [- q. ?) a- {# \* M
    + Q: p1 T( e; U; g/ q
    #
    7 v. @8 a( ]5 ?' z* W# _' ]8 _+ @#   生成用户评分的数据结构
    5 Z. o2 ]  F9 `0 Y& R1 r. }, g; e#   6 ~: H! S7 C% ?. f" X9 X
    #   输入:所以数据 [[2,1,5],[2,4,2]...]
    6 F9 u* ?* H( i#   输出:1.用户打分字典 2.电影字典
    6 e3 F* B7 u% V3 `#   使用字典,key是用户id,value是用户对电影的评价,
    0 |6 K, W1 e& m* O! O- E#   rate_dic[2]=[(1,5),(4,2)].... 表示用户2对电影1的评分是5,对电影4的评分是2; ~* q8 v$ W: {! k& Y
    #
    ' k8 Q4 T3 N: A% ~def createUserRankDic(rates):
    ; x( |3 K* }/ I) j    user_rate_dic={}$ K+ Z0 ~# r" ~+ d6 n  n
        item_to_user={}
    ; A9 i4 }4 Q; y( w% b    for i in rates:
    ) i% w  ]+ P$ b0 {2 h  V        user_rank=(i[1],i[2])0 h5 V. O5 K% w; x3 ?: z9 ?2 V
            if i[0] in user_rate_dic:' E' u; ~  F7 j9 L( c; V1 u% \6 i
                user_rate_dic[i[0]].append(user_rank)" `5 K5 R4 m7 r' o7 p: h. L5 F# }
            else:0 l7 u" \! I/ t/ ~% t5 i5 ^
                user_rate_dic[i[0]]=[user_rank]
    - r$ Y# p9 ^1 l6 G) S6 u            ! b( t5 y" X/ s( p
            if i[1] in item_to_user:8 h# K% b- x2 y% _5 \& K; G
                item_to_user[i[1]].append(i[0])* M# Q  }; w" k4 G1 d
            else:
    % e3 p/ U/ C9 v- A3 S            item_to_user[i[1]]=[i[0]]
    7 N/ }2 u. k6 \/ W            
    6 V$ w7 s* v9 R$ b7 ?1 Z    return user_rate_dic,item_to_user
    2 Q% T* g5 j5 l" B
    1 x; A6 A2 T! A- |2 W! Y4 N3 p3 |& y6 i2 v" L
    #6 O, I) _: o, V( @/ q
    #   计算与指定用户最相近的邻居
    2 c$ ^; C) k% |#   输入:指定用户ID,所以用户数据,所以物品数据
    9 L* q! |2 A- G3 Z. s. S5 L#   输出:与指定用户最相邻的邻居列表, i$ y$ s8 T1 e7 D# e5 z; R4 ^5 o% P$ g
    #7 H( c. ^# K7 A6 S3 ]0 u! [
    def calcNearestNeighbor(userid,users_dic,item_dic):. L+ ]$ @9 q/ ]- g" R! X8 Y
        neighbors=[]
    3 J& v( d$ g% S# `4 W, \; j    #neighbors.append(userid)
      z- a2 S, k0 A4 ~% v) @* w3 S    for item in users_dic[userid]:
    * P2 A1 V) K1 S- C        for neighbor in item_dic[item[0]]:
    2 }* h/ {6 d) S/ D5 ]: Z4 o            if neighbor != userid and neighbor not in neighbors:
    5 O; W! {1 K# L6 i* Y                neighbors.append(neighbor); k' @/ E9 x) E, s. t
          
    ! m- I+ H  W5 [    neighbors_dist=[]
    : L  }# ?& K) M; q    for neighbor in neighbors:
    # z- t) ^. h& \$ j- ?7 w: n        dist=calcSimlaryCosDist(users_dic[userid],users_dic[neighbor])  #calcSimlaryCosDist  calcCosDist calcCosDistSpe
    . s0 e: W- P  `        neighbors_dist.append([dist,neighbor])
    " t" ?) e% i( X( Y4 E    neighbors_dist.sort(reverse=True)
    9 m) v2 {. B( ^5 y8 s    #print neighbors_dist3 Q7 @( T5 N% ?% G" q
        return  neighbors_dist7 z: R, Z( K' L% Z& }' x# E
    4 `# G. ]1 `$ ]5 v) H, b. T# V( z

    , P/ R* e/ @8 a. G% w7 H& \) s2 H#, d' W: e. v/ a
    #   使用UserFC进行推荐8 ^! b2 ^4 U7 l. A
    #   输入:文件名,用户ID,邻居数量* C! J! j/ p; m1 c& F
    #   输出:推荐的电影ID,输入用户的电影列表,电影对应用户的反序表,邻居列表, }- T! y9 F( K* [5 M
    #* u( @* s, z5 E8 U+ e
    def recommendByUserFC(file_name,userid,k=5):
    % K& u  c$ f* e1 g1 G* o    3 R2 z- t; A1 i" K  c
        #读取文件数据- O* q" a  v1 S
        test_contents=readFile(file_name)$ \; c$ p* N1 z6 m) s5 P5 [$ r
        & G& A7 [5 E; X4 e: s
        #文件数据格式化成二维数组 List[[用户id,电影id,电影评分]...] 2 Z; I) \: x; L; l& x
        test_rates=getRatingInformation(test_contents)
    4 F! Q3 x: J! h5 S0 S; `8 P+ e    4 _9 N/ S& p2 E
        #格式化成字典数据
    * p% X& A0 V, O1 r6 ^& u    #    1.用户字典:dic[用户id]=[(电影id,电影评分)...]/ x$ h. q1 r% ~
        #    2.电影字典:dic[电影id]=[用户id1,用户id2...]
    " R& ~0 ^  [; f    test_dic,test_item_to_user=createUserRankDic(test_rates)% \: G1 I: V; \) B
       
    # L) j# D; y3 r- ?- v    #寻找邻居) a! Z0 n, a( F9 l
        neighbors=calcNearestNeighbor(userid,test_dic,test_item_to_user)[:k]
      F/ y: K( w7 o1 s2 Z; B& ?: T        9 p$ E6 f* ^% h: ?! v. ]
        recommend_dic={}6 }9 B: f- r1 E# p* n8 [
        for neighbor in neighbors:8 a9 J' u% C$ u* N; L0 E
            neighbor_user_id=neighbor[1]
    . z- F6 P( {4 W5 m& S) B9 \% i9 X  \        movies=test_dic[neighbor_user_id]
    7 S( z: O- v1 O+ L& \, x( r# a        for movie in movies:; a6 B& @: l( p) K
                #print movie
    & s5 Q/ Q: P$ E4 V1 w7 `* U- O3 T            if movie[0] not in recommend_dic:
      @5 E+ b. t$ Z8 I+ j                recommend_dic[movie[0]]=neighbor[0]$ Z# D8 P9 q# c( A
                else:$ y% [2 f- Q6 t  o
                    recommend_dic[movie[0]]+=neighbor[0]5 K  s0 r" ^" @: `1 L  |
        #print len(recommend_dic)9 f1 r- \) x) y- J( u! Y0 \
        1 H! }6 X9 d7 r/ H6 J
        #建立推荐列表) w+ C# N" T) w* s
        recommend_list=[]& r+ I* C( X" F6 f7 M9 l
        for key in recommend_dic:
    # [, e8 m8 k9 C        #print key. H1 @* v' A( n+ I3 V5 C3 Z; B
            recommend_list.append([recommend_dic[key],key])
    0 T0 \1 i. x/ [6 K( C& W2 G1 n    # p$ ]; f8 T( _# j3 {0 M' m5 l4 u4 T
          }- Y" B+ @  @
        recommend_list.sort(reverse=True)
    3 g+ a8 |. Q4 W# D% K3 f    #print recommend_list4 Q6 D+ x  w9 k
        user_movies = [ i[0] for i in test_dic[userid]]
    ) w6 p3 V& K( h1 i3 E0 ^5 V1 `7 r# \$ |% u8 j( C* ?( F7 s
        return [i[1] for i in recommend_list],user_movies,test_item_to_user,neighbors
    ! D$ Z0 R/ d# Y6 `   
    & z: A  R# M/ x3 H' Z5 i' Z    / W( P6 H4 s: H' c. R2 }8 I$ ^1 B

    - B9 r# _. \. y5 m: Y2 ]#% h0 S" C3 b, O& ?0 x
    #- ]8 P% D' e+ X
    #   获取电影的列表% d+ s4 v3 E% C8 \7 @8 e3 `# c
    #
    2 t' D: O* Y7 p) P2 [. g#* N/ `9 ~& k9 o4 p
    #
    ) i) `# f4 \; X. `# ]' udef getMoviesList(file_name):
    , f1 N' k# h# M+ ^4 w    #print sys.getdefaultencoding()
    - W4 H% O; p* N0 H* W7 m    movies_contents=readFile(file_name)
    * @' k6 `4 `1 Z- j1 a. F5 W0 X    movies_info={}& {, x/ ?8 |- l# l: x
        for movie in movies_contents:# g$ _) N! j- ^& ~7 F
            movie_info=movie.split("|")0 q; X1 z! N7 W. _& ]( e2 V: w
            movies_info[int(movie_info[0])]=movie_info[1:]
    8 y9 _! o8 k" Z0 N5 \7 G! \. |    return movies_info
    ( k4 u. M0 s, E% u   
    - _" ?! R! T. w3 X0 g, Y# _   
    ' T# y; M% g, G2 {    ( ]% N1 X1 |8 m8 A0 q
    #主程序
    0 Q9 s) s/ F# g) k2 n6 J#输入 : 测试数据集合
    ( Y! V( m. b6 [- ?# [if __name__ == '__main__':$ o0 J/ O3 R+ j4 t( x! r7 ?5 w* `7 _# M
        reload(sys)  q5 @" b$ g( [6 O
        sys.setdefaultencoding('utf-8')9 b# ~- n0 ?9 O; y; u
        movies=getMoviesList("/Users/wuyinghao/Downloads/ml-100k/u.item")
    , \! {; R" c+ C! ?( b3 S    recommend_list,user_movie,items_movie,neighbors=recommendByUserFC("/Users/wuyinghao/Downloads/ml-100k/u.data",179,80)
    + y- g+ U$ {' n" y: v9 A3 A1 a    neighbors_id=[ i[1] for i in neighbors]
    3 m+ o2 k; v" w    table = Texttable()
    0 W4 R! H- O+ y: U- l# u* O) G: y    table.set_deco(Texttable.HEADER)
    + y& O7 q7 w$ C    table.set_cols_dtype(['t',  # text " G: {. }. f; r) W" ~. e
                              't',  # float (decimal)- V; W3 r# P' _, s  a2 V
                              't']) # automatic4 @$ t% Z0 I+ z8 g
        table.set_cols_align(["l", "l", "l"])/ ~# k1 M. a9 {7 }% t3 |
        rows=[]1 l1 r* C! n5 r9 u
        rows.append([u"movie name",u"release", u"from userid"])' }2 |% y, F8 |5 b
        for movie_id in recommend_list[:20]:
    ; G6 O4 N; |* \/ e        from_user=[]- \( f0 w# P/ y6 C, A3 T+ O6 B7 ]8 {
            for user_id in items_movie[movie_id]:  ~. L* R* a# N2 Q1 V: A3 b2 a# u" V/ ~
                if user_id in neighbors_id:; {3 I% a2 Q4 K5 e5 R
                    from_user.append(user_id)" Y/ G2 A2 T# E
            rows.append([movies[movie_id][0],movies[movie_id][1],""])
    7 [5 |3 x' D8 O4 V6 c9 v    table.add_rows(rows)  D0 w: G) T% U) Q# M$ `
        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 + l$ @9 V. I& T8 i" U5 W9 W; O
    # -*- coding=utf-8 -*-; p: H* G/ L5 N" e

    ' ^2 U- `7 X$ u1 \' @; G4 fimport math

    / l& s, E7 N4 ^0 G这是什么语言的程序?& x, W8 ?6 y7 {! z4 v' i( x* e& Y
    回复

    使用道具 举报

    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-7-20 03:21 , Processed in 0.707779 second(s), 67 queries .

    回顶部