QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 5364|回复: 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
    本人在学校参加暑假培训,需要这个算法做题!求大神赐教,感激不尽
    8 K+ g' d. n1 I' w) F, Q
    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 -*-
    , z- t) N- x( D5 C- o! ~# d5 k3 [) _6 E, W/ z8 ]% v
    import math
    ) A& t1 `) _" G' U$ P/ C5 Aimport sys
    : b# ~! P0 A9 }3 G2 Ofrom texttable import Texttable0 u. [+ ?/ _' ?5 S' i4 n

    : q. V) N3 K8 {+ C: E' M
    8 M) {9 u- H0 ]7 a' e; Q! v, r- c2 |; t#
    " H% f4 O; b. x; _#   使用 |A&B|/sqrt(|A || B |)计算余弦距离
    ' s7 O' U5 l3 f0 B% _. F#' R; J/ C7 t6 ^6 R
    #( V$ B2 P' ]  V/ \( A9 Q
    #
    , G' T# ^$ r; }4 b  s( p9 B; Ydef calcCosDistSpe(user1,user2):. w) p* S$ }6 g5 q+ N( @4 H) s
        avg_x=0.03 {8 l8 m- k* ~
        avg_y=0.0! L5 H& l. n" n$ l
        for key in user1:2 {" f  G; R3 V* Q6 v% M
            avg_x+=key[1]8 |% q4 z' C* Z7 B% k' s
        avg_x=avg_x/len(user1)/ D$ t" r5 {; b1 L' k
        / i1 W$ y5 _/ [" R$ ?  l
        for key in user2:
    , }: j, z6 i* s% B9 T        avg_y+=key[1]
    % m4 \. d4 e) s; b- h) o    avg_y=avg_y/len(user2)( c7 W9 }1 [+ P2 C: L0 m5 q) B
        0 |- @8 ~3 t$ N$ M
        u1_u2=0.03 e! x. q- J+ a8 l; P
        for key1 in user1:0 m* ?4 {  D5 |  z- S. p6 L+ ]* i
            for key2 in user2:4 S; o5 i, W$ ^* b
                if key1[1] > avg_x and key2[1]>avg_y and key1[0]==key2[0]:
    . J6 o2 D0 f6 t( j! ^9 {                u1_u2+=1' h8 X  [" }+ E& ]' O  I" ~
        u1u2=len(user1)*len(user2)*1.0& v% m% r* _0 s: G4 K
        sx_sy=u1_u2/math.sqrt(u1u2)
    0 H& ?3 X# t  G% u" A) I    return sx_sy" z$ j# R9 ^9 ^) Q9 s

    % H# }  n' y! N% j# C$ ]- S/ Q$ A
    #
    ! j3 \0 [" L" \0 }' ~* H6 k, S#   计算余弦距离0 G9 M& [+ ^1 N; g! ~
    #
    * Z; M0 \2 f5 S% O% @: P4 H#
    4 |1 S% t6 S; J! a5 b3 M2 R# Bdef calcCosDist(user1,user2):* a4 V5 x7 m6 `: L; i1 W' C; h4 E0 G
        sum_x=0.0/ R% @: |2 G* y+ F7 N% f' T
        sum_y=0.0
    : s- a/ m, t( O/ S. n% q  _    sum_xy=0.0# S# l/ }8 h* o$ ]# |" `8 O, n' Z
        for key1 in user1:1 |& L  b* x8 G
            for key2 in user2:6 U$ L( L$ B0 f+ f1 t& B
                if key1[0]==key2[0] :* E' n( h0 w1 k  K3 h( z4 C
                    sum_xy+=key1[1]*key2[1]/ Z. ?* b# x- u, a
                    sum_y+=key2[1]*key2[1]
    ( ?  s& X" f2 x7 Q! A# L! F                sum_x+=key1[1]*key1[1]
    . [8 P/ f2 H* w/ `  w    / [4 R, I7 i7 w
        if sum_xy == 0.0 :* \. L; K& M2 i1 i% a9 F2 ]
            return 0
    7 M9 g8 ?0 h0 O; e& H' R    sx_sy=math.sqrt(sum_x*sum_y) 8 n& I* d9 |7 H# N3 K
        return sum_xy/sx_sy( u( ~0 h2 R  @0 u

    ! z1 r$ o% z# ~& s
    - {1 ~0 N0 n& L4 ~) m0 ]#( @! X5 u1 g: B5 a% H" T
    #
    ) y4 @; A1 C5 Q#   相似余弦距离
    % p% p# s' `  i#
    ! {+ {; x1 `7 @: h% `#
    - z) {6 v5 h8 Z' m) Q0 I2 K#( w4 G& F  w& d  ]2 z" \
    def calcSimlaryCosDist(user1,user2):! ^) Y& K3 x: e" ]
        sum_x=0.06 Q0 _0 [' A, L1 l0 t2 w* N
        sum_y=0.06 A, I+ d  Y; }# q  U  S
        sum_xy=0.00 ?) s( V; A" d2 b  z/ X
        avg_x=0.0
    4 T4 R9 o9 n7 {0 b: x    avg_y=0.0
    0 [: k4 R3 I8 P- ?9 ~    for key in user1:- X- P, ~# {. v6 k0 K- t( P7 h% }- ~" b
            avg_x+=key[1]
    9 [8 ^9 O) R1 u5 i8 e5 D, g; y    avg_x=avg_x/len(user1)
    % j2 X4 |$ H: n( t: P   
    5 I4 u2 o5 j9 w    for key in user2:
    $ m/ f+ E* A7 x$ L        avg_y+=key[1]
    + N. q! x8 A9 Y# k% P    avg_y=avg_y/len(user2)
    / ?3 P) o; a+ |% d* e; z  F4 N    ! b; l2 O5 F6 s  Z
        for key1 in user1:3 _/ ?0 X  x8 I: r6 Q/ M/ S' h
            for key2 in user2:, N0 x8 U& L+ a$ C, d4 E1 u! Z4 Z8 S
                if key1[0]==key2[0] :- c7 W; X8 w5 D9 Z( ?
                    sum_xy+=(key1[1]-avg_x)*(key2[1]-avg_y)
      y1 `. d  h- h( R1 S4 q                sum_y+=(key2[1]-avg_y)*(key2[1]-avg_y)
    . S( {; S5 D, q) I0 N        sum_x+=(key1[1]-avg_x)*(key1[1]-avg_x)5 n" J5 l/ |9 |! m, h0 R
        2 a+ u, `! N+ p
        if sum_xy == 0.0 :* W, t6 R- j) x8 Q$ s
            return 0
    6 {) H) ^# y, S* B    sx_sy=math.sqrt(sum_x*sum_y) 9 @! a7 u# t& X7 Y" _; n
        return sum_xy/sx_sy9 ?' p& P4 S8 f( w# a+ L, s
       
    7 ~. r# A. ]6 J4 i2 L
      m2 X& K: z# z) N: I' w#
    ! k1 p3 {1 r$ m( x#   读取文件
    : E+ T  V' ^. u9 B' g1 ?3 B#; j/ {1 |: e! P5 ^, e
    #
    , V' [0 Z$ t- O( hdef readFile(file_name):
    . w# I, d- X- ]( `    contents_lines=[]
    " ?9 x) _  S& ^+ h) x, o# a    f=open(file_name,"r")8 T  t6 _  |( n/ X1 v5 m4 S
        contents_lines=f.readlines()
    0 ~' U% G% }+ b8 f, Q- q2 q& P/ A* D    f.close()) s+ O: d! \* i$ ]" i0 I
        return contents_lines; @4 V3 w% ?' t* N5 M' y& Y

    6 B! y0 I1 Z" A5 M: |$ U* i
    ( x: v2 }) k; n: b) `0 ]9 w1 Z( Z) {( \( k: l$ X
    #
    3 K8 }# J  @' T% k! r#   解压rating信息,格式:用户id\t硬盘id\t用户rating\t时间
    $ f. _5 q8 |7 i. S) p8 H4 m#   输入:数据集合
    9 V; I3 }% a1 b" y1 N% P#   输出:已经解压的排名信息5 g  B5 j+ C( H: d7 r3 w7 }
    #
    ; |2 s! F% _) N/ u/ o( T& J( Z9 {def getRatingInformation(ratings):0 @4 M0 ]5 \, P- Q, f
        rates=[]0 d: {% v# L6 h; S
        for line in ratings:8 f( M& k" X: h/ V6 T/ ?
            rate=line.split("\t")
    4 ?0 ~# V7 o! B( N* z        rates.append([int(rate[0]),int(rate[1]),int(rate[2])])
    " y7 ?) E, ~: I& P: A3 ^6 O    return rates
    8 K8 f5 y4 v) G5 t* o/ M  v& |! c; X# j1 L4 `
    % ]8 J5 U6 i. y9 E# e& D9 L
    #. ^) Y+ g% K/ P4 N. e; S2 t
    #   生成用户评分的数据结构
      A' E1 t9 S) A) v; x- b$ {#   
    * O8 P2 }$ P# Q% @0 R#   输入:所以数据 [[2,1,5],[2,4,2]...]
    + n9 v) Z% ?' V#   输出:1.用户打分字典 2.电影字典7 c8 g- z" M" T" m! {  p1 }
    #   使用字典,key是用户id,value是用户对电影的评价,
    ) y* f8 s( C5 `- C6 I2 b6 Z$ l#   rate_dic[2]=[(1,5),(4,2)].... 表示用户2对电影1的评分是5,对电影4的评分是2# Y5 T1 h6 ]8 `. o
    #9 T3 C$ o+ P* E) ^8 X( q
    def createUserRankDic(rates):2 `# ~7 z) Q: n  w  }( F% E! l
        user_rate_dic={}
    6 r* R2 O6 L+ w2 t    item_to_user={}# _1 c7 g/ O- W! k- Y+ x" d
        for i in rates:
    3 o& x9 n9 R4 {" `, F        user_rank=(i[1],i[2])
    6 U$ ^- C( p4 H        if i[0] in user_rate_dic:. {0 U1 O1 {1 ^! F: |1 l
                user_rate_dic[i[0]].append(user_rank)+ n3 f! h+ r: b* a6 ~
            else:
    : g9 g) q1 \7 ~* A1 L; Z            user_rate_dic[i[0]]=[user_rank]
    * p8 l. _9 z$ \5 V/ M  v            7 d7 D& {4 Y: [$ E6 ]
            if i[1] in item_to_user:
    / X; y& e. {" j  V% K7 Z" g/ q            item_to_user[i[1]].append(i[0])
    6 U$ q% q5 Z* n6 F3 ^        else:- Q7 i0 f( v3 C, Z. u0 Y, B* A
                item_to_user[i[1]]=[i[0]]* H' z: L  X/ \- G3 \
                
    / {2 S+ |* H, D0 i  Q# D' B" V+ G    return user_rate_dic,item_to_user
    1 L( X. A8 [9 e) h' M% d3 \, ~- }7 V+ S! ^' I6 c( }

    0 g/ c7 E: _  D- i4 ^$ n# \, }/ t#
    $ m3 f) i+ A  p#   计算与指定用户最相近的邻居
    $ x+ e' c* \1 ]* m. p2 r2 r; t#   输入:指定用户ID,所以用户数据,所以物品数据
    : d. l" e( B+ I1 t$ E9 s#   输出:与指定用户最相邻的邻居列表
    $ a' S% _2 A4 H0 x5 p#6 B2 Y' d4 n& k* Q. |
    def calcNearestNeighbor(userid,users_dic,item_dic):" P9 }$ X# G2 `7 o! Z- U) h
        neighbors=[]  c0 ^0 r4 l  e2 U9 j: e1 G3 ?
        #neighbors.append(userid)( b6 l, g/ H1 {; B* F7 C4 q
        for item in users_dic[userid]:
    % T' D, }  w( [6 z        for neighbor in item_dic[item[0]]:
    8 B) F+ t* ^5 j+ [            if neighbor != userid and neighbor not in neighbors:
    0 T9 c, [( I* @3 x2 R& E                neighbors.append(neighbor)! \6 q/ v. F, Q8 x# t
          
    . |0 S. F: N$ i    neighbors_dist=[]
    . B; i# K  w2 n$ b1 B& X. m' {    for neighbor in neighbors:
    5 e5 `9 P7 y+ D1 b& n- B        dist=calcSimlaryCosDist(users_dic[userid],users_dic[neighbor])  #calcSimlaryCosDist  calcCosDist calcCosDistSpe2 M0 \' O$ g2 x, |4 \  z
            neighbors_dist.append([dist,neighbor])0 p8 N/ ^2 C( k
        neighbors_dist.sort(reverse=True)
    8 n2 R4 O' N. B2 C) Q9 x    #print neighbors_dist
    $ f+ L: X7 ]! K; R2 _: Y$ c( t! w    return  neighbors_dist
    0 `: v$ H8 l7 C! K: _" w9 t6 f2 O2 T  P
    ( |* [3 r$ r9 k; T. q  A% j
    #
    5 c& y, K9 [, K# q  C9 Q- p#   使用UserFC进行推荐
    ) r5 ], q; W; {2 h( M#   输入:文件名,用户ID,邻居数量
    0 V' J3 i6 Z1 u( V/ W#   输出:推荐的电影ID,输入用户的电影列表,电影对应用户的反序表,邻居列表
    + B6 |2 Y- ?: n% n- Q, h. G( B#5 A: e# g/ f% a+ A( I7 v" Y
    def recommendByUserFC(file_name,userid,k=5):
    " A% R0 B! P9 Y# {- x& Y    . x( R* P8 ~5 Z! s0 c& e4 M) `, C
        #读取文件数据' m0 V6 E# w9 j% H/ w
        test_contents=readFile(file_name)! ]/ \0 p1 _: o6 ?6 Y# N9 H  ~
        5 R9 V, z$ D4 D7 X
        #文件数据格式化成二维数组 List[[用户id,电影id,电影评分]...]
      [' X& E9 F6 }+ X- M8 I7 k  T    test_rates=getRatingInformation(test_contents)( l8 F) j- E" c: H% e8 M3 x
        & i: \+ o: a* s5 ]+ G" D+ t
        #格式化成字典数据 ) @( B5 w/ n- o
        #    1.用户字典:dic[用户id]=[(电影id,电影评分)...]
    3 X2 c( E; A. u0 n) x3 V! I- d0 m    #    2.电影字典:dic[电影id]=[用户id1,用户id2...]+ V* G2 A2 R) D* J- K
        test_dic,test_item_to_user=createUserRankDic(test_rates)' K3 j9 b0 }0 K/ H& r
       
    3 q; d" z9 x) c6 w, }! }    #寻找邻居- J! D6 G7 n" R# C5 v2 i) y0 F* n
        neighbors=calcNearestNeighbor(userid,test_dic,test_item_to_user)[:k]
    ( m  |% O  w, Y+ H/ _        
    ' b$ v) k& K+ }) p1 J; p$ _" J    recommend_dic={}1 \9 }) k( U: c  y: _+ b) L: ~
        for neighbor in neighbors:- q2 d/ T: A' R% c: g; G% u
            neighbor_user_id=neighbor[1]
    ( d- y; G* q3 H0 o# B        movies=test_dic[neighbor_user_id]
      y/ Q- E( B3 C9 [8 ]( X        for movie in movies:! D( M" J1 M9 @# e# v# C2 y; Z
                #print movie+ y3 R2 x8 H0 `# K" @% w
                if movie[0] not in recommend_dic:
    ( o7 x& L* t# c4 z2 x9 L6 g                recommend_dic[movie[0]]=neighbor[0]& c1 _( W( g0 l9 P5 L; t7 y
                else:
    ) u( K% `$ g- Z                recommend_dic[movie[0]]+=neighbor[0]7 u1 V) X& V1 P5 G! n, L* e2 E% w
        #print len(recommend_dic)
    8 H: Y/ Y* C7 i" _' u2 B, E( H    & c) b  S: J  U2 }) ~9 p
        #建立推荐列表
    6 t. ~8 K2 q# F0 c, [# R8 s) }/ w    recommend_list=[]
    : x6 K. @" r# j" d% N+ z    for key in recommend_dic:# N# Y* P7 o% B5 T
            #print key
    # j: U- T' u0 B! o# w( S        recommend_list.append([recommend_dic[key],key])8 K. E3 D0 r- \$ m, b
       
    . \5 S8 P$ I0 R3 E0 w1 K: U   
      v. k5 b; C, Z& B- z& l% W    recommend_list.sort(reverse=True)* L/ e: b: [$ a3 ?* |) G8 N
        #print recommend_list
    ; Y2 Z9 m* v$ I6 b    user_movies = [ i[0] for i in test_dic[userid]]% n" ~# C. ?. U  W5 c! z
    ; Z' J1 G. q$ q% ^/ I. D
        return [i[1] for i in recommend_list],user_movies,test_item_to_user,neighbors' r/ H( M& t; X+ }1 t6 n$ L2 ]
        0 T& M4 m  c& C& }$ y6 v; B* g( |
        , A4 I- W6 l$ J6 H$ N7 c
    1 [2 y6 S& A6 s& F$ d  Y1 ]# s
    #$ ^4 n$ i4 B. \: X
    #* j1 J) d) |+ Q6 Q( D2 \
    #   获取电影的列表
    $ x( t; c, o# c  Y2 ?6 O#
    0 g" D' _, p. f( w  W  d#
    5 o; |* b1 {2 K( ^# K9 T% v#
    ' @% m- E4 @5 D6 ydef getMoviesList(file_name):! L" p( S' k( s7 S2 E2 Q2 B
        #print sys.getdefaultencoding()
    ! s# [* x8 m4 B+ ~' ^0 G" |    movies_contents=readFile(file_name); ]* {% r& d6 S! \1 P/ b3 e
        movies_info={}$ e6 `  L0 Z  C. p- C9 N
        for movie in movies_contents:/ j, m) p6 g% G& K8 O# ~
            movie_info=movie.split("|")
    5 t8 U" M# U4 |" g  k) ^, o  m        movies_info[int(movie_info[0])]=movie_info[1:]% d: @8 Y5 O% J% ^0 K
        return movies_info
    4 A1 R+ o+ U: X) n$ g4 t* z1 a    # M: _% J9 P% i  q) c' u) p
       
    . L. n& M- H. K# ~    0 p2 ~" K4 h: A5 {9 P/ }9 f& ~
    #主程序
    8 p# S0 o- M" o8 C- G0 _$ k/ F#输入 : 测试数据集合. M% a8 l2 ~: I+ D4 B  h2 X" Y, |% U
    if __name__ == '__main__':
    7 d4 X" w" V1 _; L6 [! ]* X. M9 i    reload(sys)
    8 @% B$ p1 _" I& h2 D7 {4 i    sys.setdefaultencoding('utf-8')
    ; K5 m! `1 k; b! h) w    movies=getMoviesList("/Users/wuyinghao/Downloads/ml-100k/u.item")7 l; C2 ]$ t% j  q9 |% r/ N, g( x
        recommend_list,user_movie,items_movie,neighbors=recommendByUserFC("/Users/wuyinghao/Downloads/ml-100k/u.data",179,80)
    : V# j: p3 `$ w& S$ a+ m    neighbors_id=[ i[1] for i in neighbors]$ i5 T. i* u: R# R; N
        table = Texttable()
    4 A* I7 c% {$ ], v    table.set_deco(Texttable.HEADER)
    ) C3 S2 n* g( d    table.set_cols_dtype(['t',  # text
    2 L, Z* i" G- Z1 ]: `" e; G                          't',  # float (decimal)* T; p  y' b& ^) }
                              't']) # automatic
    7 N% v/ c1 x" R9 a* L    table.set_cols_align(["l", "l", "l"])
    4 T$ j& g  S8 v4 Q, K, l    rows=[]
    8 V: _# _$ J0 L& Q    rows.append([u"movie name",u"release", u"from userid"])' X8 O" J' ~' j; i- t% l# ~7 @6 Q
        for movie_id in recommend_list[:20]:
    ) t2 Z7 e5 v. A# S' W        from_user=[]" f3 F6 C' E8 _& `4 I3 X; E( W
            for user_id in items_movie[movie_id]:4 I) @; f/ D- Q+ [+ w1 U8 Q9 E
                if user_id in neighbors_id:
    " F3 ]" U' ^' A% K7 h$ |                from_user.append(user_id)
    * t$ s! B; W/ G0 `1 {. u        rows.append([movies[movie_id][0],movies[movie_id][1],""])
    . }$ J" ]9 q5 P. q, O3 i    table.add_rows(rows)
    - L. ]# E* Q/ D    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
    . F% ]# N; L* B9 H. [5 [3 @0 [# -*- coding=utf-8 -*-
    . G) `# F7 w8 Y1 g" j  W9 [3 V0 b: Y! w, z3 E! h
    import math

      K7 K+ c6 y" ~, U* l这是什么语言的程序?
    " u3 N$ @/ h( j3 c( l& e
    回复

    使用道具 举报

    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-9-3 10:04 , Processed in 0.422710 second(s), 68 queries .

    回顶部