QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 5067|回复: 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 a( t4 q$ ?  O- p8 m  d+ T
    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 -*-
    9 g  k3 f% R+ q% S+ t/ ?# m0 q1 m* p. x: ?* L
    import math
    $ |7 n. q" _/ limport sys6 @+ U  r  D( D( \1 ]
    from texttable import Texttable1 B1 x1 y% [( `1 L1 B

    6 S- ^! |) \& C# Z# u  h, e
    / Y9 U2 }( |# S& h. ]#
    # j7 W8 K3 Y- D#   使用 |A&B|/sqrt(|A || B |)计算余弦距离& m; p* o% B+ Q8 {. m
    #
    8 E* S1 v7 Y, ~#
    ) J5 i0 R: D2 h  ~3 l. Z#; Y6 T9 G4 a; Q/ V) C
    def calcCosDistSpe(user1,user2):
    " F! V# G1 L9 ?! \& h    avg_x=0.0
    % }: U" N5 W& s& B7 ~) f    avg_y=0.01 ^, B4 L% Y, T0 Q3 _6 _
        for key in user1:. c6 z! n3 }: w$ j9 s
            avg_x+=key[1]
      ?6 O! V/ V- e- s    avg_x=avg_x/len(user1)7 X% \8 E) V9 {
        ( n8 J6 r% o6 I3 M/ ~, }
        for key in user2:" |+ ^0 i! X- g- O" ?) x( n& W% g7 ^  Z  r
            avg_y+=key[1]
    2 Z8 A- W( f$ ]# u3 ~! r$ X% b    avg_y=avg_y/len(user2)
    - j; q* Y) W, G5 W8 Z   
    4 [/ F  [' A  w4 O% i6 P( ]    u1_u2=0.0
    4 D& ^' I5 N: o0 T3 l    for key1 in user1:& H( ^0 \- Q2 o* I. j$ [$ W
            for key2 in user2:
    8 R5 Y- h8 L  f; C8 {" Z3 k$ U            if key1[1] > avg_x and key2[1]>avg_y and key1[0]==key2[0]:' o9 R  [3 H% S0 B. w
                    u1_u2+=18 F6 Q* v5 L2 S  ^! Y
        u1u2=len(user1)*len(user2)*1.0' p0 z5 n, `. C" u1 J
        sx_sy=u1_u2/math.sqrt(u1u2)% @% T4 ?" `- I( o. U3 h! Q
        return sx_sy
    ( N0 R- _3 v2 ^" C& i0 j% R0 T2 ?) @+ F1 W
    5 }5 }6 v" }  Z+ r( s) F7 V9 m
    #
    3 U. {% R% p; V8 ]# d. k#   计算余弦距离
    4 O- L. \3 A+ W) H2 b) D+ w#
    ) R8 x% F) Q3 W#
    7 _- }& c+ H* Sdef calcCosDist(user1,user2):
    0 S8 r& [  E2 m* D    sum_x=0.0
    : q5 W2 }0 F& [    sum_y=0.0
    + Q/ {! k$ `; @) B% V4 a7 m% M    sum_xy=0.0+ ~: G" t! T4 T
        for key1 in user1:2 q+ {" r' y4 G5 I) P5 Z
            for key2 in user2:
    ' {1 }2 g' S( Z7 Z! I, S1 z" F            if key1[0]==key2[0] :$ J) T$ U" f% _# l9 A
                    sum_xy+=key1[1]*key2[1], m; U% F0 ]( L  o5 c4 z4 H! `3 h+ K
                    sum_y+=key2[1]*key2[1]
    , L. S' W; P9 `( D; |/ ]5 U                sum_x+=key1[1]*key1[1]
    7 S2 g: T3 N# i3 Z* W) D/ G    " ?9 v0 v% K7 z, \2 |. P& j
        if sum_xy == 0.0 :
    2 i' b& R+ U9 Q+ w1 Q. b- Y        return 0* V+ t/ K$ v) S' S, i7 b
        sx_sy=math.sqrt(sum_x*sum_y) 0 l" _) N8 J2 m
        return sum_xy/sx_sy
    4 t: m. A4 Q4 K5 v$ w
    ! C6 @9 K7 K% \& y/ {' C3 L( y
    / ]. U5 Y7 n' P" R. V#. ?5 `& A7 |# D' Q  _7 n+ H
    #
    1 F2 |! K8 M' T#   相似余弦距离' O2 v- _- \/ r3 O$ E0 K
    #9 j$ k" L! U- p1 C3 V7 }# y( A
    #
    7 n+ K1 O: u; j) G+ K#$ v; S9 r9 W( w" H; `9 [
    def calcSimlaryCosDist(user1,user2):7 ~8 Y6 g2 X- P
        sum_x=0.0" \2 M" `' H( @- _2 o# |
        sum_y=0.0. k1 E" S& u  _& o$ B
        sum_xy=0.0
    ! [# L& R2 J  H) j  l/ D: p    avg_x=0.0
    : q8 j* q4 k' R: }' o+ J% W9 |    avg_y=0.0
    2 |& ?- l$ \1 _$ I/ I6 l    for key in user1:2 y3 _$ G! l% Y6 B" M0 u4 ~. U
            avg_x+=key[1]
    ) l+ \1 k$ [4 o( F+ m( q3 \    avg_x=avg_x/len(user1)  u  u# `6 ?2 j$ [
        7 `. D  b# e$ y
        for key in user2:
    , o: g( T% K' v( l        avg_y+=key[1]- n, k6 |! t# w0 c/ x
        avg_y=avg_y/len(user2). S8 Y: d. }3 w0 C9 G- q
       
    0 R: C2 P' ]$ r: ~( N- X( k. R4 M    for key1 in user1:
      F. k3 k  ]& {3 M        for key2 in user2:* `, \! x( m4 n* Q3 \
                if key1[0]==key2[0] :' ?( T; N% N2 d
                    sum_xy+=(key1[1]-avg_x)*(key2[1]-avg_y)1 @: t% Z( F' S3 v
                    sum_y+=(key2[1]-avg_y)*(key2[1]-avg_y)
    " C% y% z! V4 K2 n* S        sum_x+=(key1[1]-avg_x)*(key1[1]-avg_x)" x% Z8 l+ T) u! H
        6 B* H* T3 D7 ?
        if sum_xy == 0.0 :
    2 h7 k5 w; R8 q. f) k' g+ l/ t        return 0
    ; L* g1 c& n. G! k- k; X5 o    sx_sy=math.sqrt(sum_x*sum_y)
    ! q2 o# `( H& W- Z    return sum_xy/sx_sy
    8 ?" ?+ x) d: o! K    ; Z8 n: Y9 g8 `

    ' @! q6 A) d7 S$ N& ^- |1 [9 ^( c#
    + d+ ^" o4 ]1 _( j1 n#   读取文件  x0 _" y$ H! p8 Z( D$ S
    #
    / ^- j1 p8 _* N% \# W#
    ! H' {" s! r4 ?3 a/ E) B; Jdef readFile(file_name):" z% d+ S" d: ^3 H2 q4 u
        contents_lines=[]
    + Z! j/ G2 \& Q$ `9 ~" V    f=open(file_name,"r")( C$ Q! w' V# Z$ J/ s0 G
        contents_lines=f.readlines()0 M; `$ ]2 a' i/ u+ F% I
        f.close()4 H3 h9 Z. t+ F6 ?6 U; ?
        return contents_lines" t' z3 y+ R, U) T7 c1 N

    * B! ]) W& r' d2 A  V" r
    . X) S! I' ?( C8 z$ S$ O/ y  x4 w* F* Q7 N
    #0 n1 u& W. ^* A& J; Q% _9 n2 j
    #   解压rating信息,格式:用户id\t硬盘id\t用户rating\t时间& b/ m0 N1 e  S# h4 r. [* F, b/ T
    #   输入:数据集合( T* x. A9 i* H$ U# k! V
    #   输出:已经解压的排名信息0 R4 p: s- O9 \* o4 P3 m4 g
    #
    2 K4 P( c; m! {def getRatingInformation(ratings):
    2 `6 I3 a# Y. S7 G" D5 @    rates=[]  l" j8 m, a4 R/ [5 g: I
        for line in ratings:( {' b: O& l! R9 `) j
            rate=line.split("\t")
    8 ]8 B7 P3 f1 D; q; C1 j, `+ Q        rates.append([int(rate[0]),int(rate[1]),int(rate[2])])0 ]7 J( R9 Y5 Q2 h; j6 P
        return rates+ X- i3 @# A* W5 M
    9 e/ K/ \. C5 B& E5 h

    ! O" o+ z& Y# {, J. p4 C#6 D$ f+ V8 c- y  H6 f
    #   生成用户评分的数据结构
    3 ~9 Q' U) G! A5 S/ [$ F, m# X2 v#   
    ! j) }% \2 J  _; o' O: U$ O. }#   输入:所以数据 [[2,1,5],[2,4,2]...]7 p0 N2 Q1 R; r
    #   输出:1.用户打分字典 2.电影字典) L) S/ I3 k+ G; o9 b" {
    #   使用字典,key是用户id,value是用户对电影的评价,) W$ f: m' \- u+ ~
    #   rate_dic[2]=[(1,5),(4,2)].... 表示用户2对电影1的评分是5,对电影4的评分是2+ {) [) M2 `/ I5 J1 M; l: S9 r
    #& S3 J9 c/ B5 K. S# X7 Q) @
    def createUserRankDic(rates):. ]( g( ^# C0 i" K  K, K8 r
        user_rate_dic={}
    * s# E+ u# [: i+ c, Z3 X4 D    item_to_user={}
    ' a( |6 @; T. ~; G    for i in rates:" q9 U2 g, d) i5 S
            user_rank=(i[1],i[2])
    # b9 S$ p. ~* a        if i[0] in user_rate_dic:
    + e* M' R; Z* P: |: _0 b  Y- a& |            user_rate_dic[i[0]].append(user_rank)* g: O. t* R, A" |
            else:
    : E; o8 s7 |( S* B, G( }; K            user_rate_dic[i[0]]=[user_rank]$ C, o0 o- t2 c4 n! A, |' Y
                
    $ T1 w% v/ x. u1 m, i        if i[1] in item_to_user:( ]9 x0 l& ]. J' b0 ]/ ^/ O1 F
                item_to_user[i[1]].append(i[0])' K+ O9 p; S& C5 L: k
            else:, e+ x2 \/ T# X/ m
                item_to_user[i[1]]=[i[0]]
    1 a+ H% u+ J1 H% {/ u* R            " J2 Q: q, C) A
        return user_rate_dic,item_to_user
    7 m6 u4 W( a0 a8 ?0 C/ p, y$ B4 g+ f" N  r# @7 \* Z4 R  w
    % H$ j, W1 P7 c4 M: l* N5 M
    #
    + f9 t3 [. s- t% n#   计算与指定用户最相近的邻居$ z+ G1 _% o6 a, W3 g, G
    #   输入:指定用户ID,所以用户数据,所以物品数据
    3 K* j8 u& i3 k9 M0 l0 ]5 \#   输出:与指定用户最相邻的邻居列表
    * \9 Q' _; ~- B- i2 ~7 H#& J6 g. U0 L4 J$ N
    def calcNearestNeighbor(userid,users_dic,item_dic):' c3 w2 E9 s; U4 J4 b- f- `' n! S
        neighbors=[]
    - E7 E3 W9 r( d1 @# _; Z    #neighbors.append(userid)! ?' Q* {& l9 x9 S' @7 K
        for item in users_dic[userid]:
    ( E# Q; |5 x9 ]0 _" ]7 a        for neighbor in item_dic[item[0]]:
    ' B5 R4 m. d& i* L3 q- u            if neighbor != userid and neighbor not in neighbors:
    + v* S& x" r1 B' F. n) O                neighbors.append(neighbor)
    3 {% B* V- f8 C4 |$ U+ p      ( T4 @7 t/ h9 i, F- l
        neighbors_dist=[]: }) b7 a  {" ^$ {9 H  {% Y# W
        for neighbor in neighbors:
    ( e9 G: h5 G, K0 q        dist=calcSimlaryCosDist(users_dic[userid],users_dic[neighbor])  #calcSimlaryCosDist  calcCosDist calcCosDistSpe
    9 b/ k5 F5 M" u( ^- Q- a: k        neighbors_dist.append([dist,neighbor])
    , r, |, V* I5 T6 W$ O7 J    neighbors_dist.sort(reverse=True)
    ! u8 b( [3 h* p  f* |2 ^' Q) V    #print neighbors_dist
    7 y1 m5 D" C9 K# N" m' H    return  neighbors_dist6 j; y) K+ r; j" \- a& o; w! t. B+ y( v2 R
    3 H7 y) m: |; V9 H/ r
    + S2 M- E0 G5 [& O% x0 W! B6 E' A
    #. a4 J8 @5 w0 o. x" o) U7 ~3 b
    #   使用UserFC进行推荐+ Q- W2 p1 a& k- r# s$ h! A
    #   输入:文件名,用户ID,邻居数量+ s& q& \$ g: F7 e: l- w
    #   输出:推荐的电影ID,输入用户的电影列表,电影对应用户的反序表,邻居列表7 A7 F. b1 U+ W! P' R) U
    #
    4 T) _8 E! i+ k+ e- Hdef recommendByUserFC(file_name,userid,k=5):
    9 K* z7 T: I  t: K" k   
    0 M( t& ~& A, [9 a7 y8 i# q+ E2 ?    #读取文件数据
    ' B6 b; n( K( ?& D    test_contents=readFile(file_name)
    9 l& E0 }) S8 c- {" E! w* z5 n    ) ?- y5 g+ L3 l
        #文件数据格式化成二维数组 List[[用户id,电影id,电影评分]...]
    # c  C' A1 Q5 }( [# ~/ c* M) g' j    test_rates=getRatingInformation(test_contents)
    ; D) H4 `2 h; K/ o6 |1 e$ N    : s& r3 {( ?! n! F. k
        #格式化成字典数据
    " e. I4 U, M7 u: a7 q    #    1.用户字典:dic[用户id]=[(电影id,电影评分)...]! O' k2 B& F7 j3 B) I" m
        #    2.电影字典:dic[电影id]=[用户id1,用户id2...]  p, @6 q% S; ]& e5 s
        test_dic,test_item_to_user=createUserRankDic(test_rates)% y* z0 ]/ o7 ~& W
       
    ; Y( p! M0 ]/ e. [" a2 R2 [# z# q* G    #寻找邻居' Q! k. Q$ T- f9 O" |
        neighbors=calcNearestNeighbor(userid,test_dic,test_item_to_user)[:k]( @: f) \$ M3 Q
            1 p( W% S3 e( ~1 a
        recommend_dic={}4 P4 t8 Y3 B) N, Z% Q
        for neighbor in neighbors:  r2 U- w2 I3 \0 s* b' l# }
            neighbor_user_id=neighbor[1]! X0 w; `5 D2 z8 o) f) _% r
            movies=test_dic[neighbor_user_id]4 P! m- v2 B  h5 V$ f" X
            for movie in movies:, G. C& C/ N; M5 m' e& }  j4 u! @
                #print movie
    3 ^! c: Z% \& r7 D7 B+ h4 R! }            if movie[0] not in recommend_dic:
    ) [: C5 h9 m/ S( e9 q                recommend_dic[movie[0]]=neighbor[0]. h& Y* x/ E- p  m
                else:
    + o6 s" E( l7 P6 e                recommend_dic[movie[0]]+=neighbor[0]
    $ s" k) b, s! Z    #print len(recommend_dic)8 i7 n' r  r# ^  Y& S1 d
        ; k7 D% r5 ]' `4 M: [" ?* y( I6 K" z
        #建立推荐列表
    7 J9 @& }1 r) S9 l    recommend_list=[]1 i6 ?! c) ~" u6 }, ^( K8 _$ s
        for key in recommend_dic:+ m) \/ m3 ~9 X  Q
            #print key' ?5 i, H/ H, }! r+ n" q2 z
            recommend_list.append([recommend_dic[key],key])
    % q  j, J" H0 A  V* n    + L" @. e% B* G/ i9 ^) s' _2 C
        5 O( o8 K, |$ A+ [0 p$ I% R
        recommend_list.sort(reverse=True)
    # y4 e  z9 e4 j8 s  X, X* K    #print recommend_list; c1 m( b8 \9 k
        user_movies = [ i[0] for i in test_dic[userid]]
    8 }0 k% x! M# e; k4 t4 |  ]: L% W5 h
    . @0 [4 |( S) N/ J6 ~    return [i[1] for i in recommend_list],user_movies,test_item_to_user,neighbors6 S' w2 M3 D7 L5 ^. W; C; Z& }
        & U# C" ^" a# `
        4 Q' U$ O) U3 n8 P; W6 ]7 T4 R8 f3 s

    3 `% R2 J2 ^( b  N' ?% Y#) m% I1 w- y5 @- l
    #9 G$ \3 X+ |- r. ~8 N2 A& S& z
    #   获取电影的列表
    , B# s5 v7 ]1 x+ G: a#
    : \8 I* W; S" S#$ e) X" Y( q7 G* o8 C( s
    ## h' d1 T9 F, c5 @
    def getMoviesList(file_name):
    % R) s) _- X2 O) C    #print sys.getdefaultencoding()! W$ @& B2 P1 D3 D3 i% T
        movies_contents=readFile(file_name)
    ! w/ s7 o/ O+ Z  o$ T! e    movies_info={}
    5 `% F2 U2 V& u0 [: i! k$ V    for movie in movies_contents:
    & B- @$ t; U( [, |& k9 j6 z% O) Q        movie_info=movie.split("|")+ W! k8 o5 @/ R0 j; {! W
            movies_info[int(movie_info[0])]=movie_info[1:]
    # N8 Q$ B  O: Y! a) \/ ^  I    return movies_info
    0 ?5 E2 W2 J$ H* m% @( |6 t   
    & f3 `7 q. ^: ~" J5 r6 F   
    9 n: ]4 w' o( B  ~$ c: {. j, H; g   
    % C' b0 o6 O4 w1 z9 g3 V& d% A#主程序, ~3 M- R6 n: k+ X7 r
    #输入 : 测试数据集合5 K6 q. ~9 {9 L! K, B8 q: R
    if __name__ == '__main__':
    * O! g! y- \% P% n! h    reload(sys)- ?0 \5 K% a0 v" Y: N0 ^0 [6 b7 U
        sys.setdefaultencoding('utf-8')
    7 o1 W9 [+ z1 o8 P# |2 T    movies=getMoviesList("/Users/wuyinghao/Downloads/ml-100k/u.item")! J$ {! W! t( p) X, ]0 U
        recommend_list,user_movie,items_movie,neighbors=recommendByUserFC("/Users/wuyinghao/Downloads/ml-100k/u.data",179,80)
    3 G" K2 s( V! Q4 R. w( S    neighbors_id=[ i[1] for i in neighbors]/ Y+ z; c# I0 i% z) n, q' [
        table = Texttable()
    & A8 f0 c) h- M! m$ N    table.set_deco(Texttable.HEADER)8 x0 h  W' t( H
        table.set_cols_dtype(['t',  # text # d. I! P- D, _
                              't',  # float (decimal)
    7 C+ ?8 e6 i8 q1 z* \  s  O/ P, L                          't']) # automatic
    : Q. ]. s4 y, z    table.set_cols_align(["l", "l", "l"])/ |0 s2 p; T; L1 j0 \; ?
        rows=[]1 c7 Z8 ^/ U$ N$ {. H
        rows.append([u"movie name",u"release", u"from userid"])
    / M4 ~5 C! l# f0 t5 J    for movie_id in recommend_list[:20]:
    " z% T) }( Z' ]        from_user=[]; H2 @* w) u% b1 j9 v2 E* t1 P
            for user_id in items_movie[movie_id]:) @8 E) N2 K$ B, ~9 d3 J
                if user_id in neighbors_id:
    7 z$ Q0 J/ d7 J  j                from_user.append(user_id)
    $ k# X$ V; J, X5 W' S6 {% M        rows.append([movies[movie_id][0],movies[movie_id][1],""])3 \. ?/ d' _1 ^0 g6 L# j
        table.add_rows(rows)
    0 x/ h3 H- `0 C9 b    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 5 u1 J$ G& t2 O. x, r+ ~3 B
    # -*- coding=utf-8 -*-6 ]/ t- l$ x% q. o9 j

    % @9 Q: J: P6 F' V# C, Y! w# T1 Z3 B: M9 N# dimport math

    / Z4 A6 Q  F. V/ \& [; V这是什么语言的程序?
    ) D8 ?' c. s. n. G: L, I
    回复

    使用道具 举报

    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-10-26 03:33 , Processed in 1.467464 second(s), 68 queries .

    回顶部