- 在线时间
- 2759 小时
- 最后登录
- 2017-9-15
- 注册时间
- 2011-4-3
- 听众数
- 538
- 收听数
- 4
- 能力
- 80 分
- 体力
- 1764 点
- 威望
- 27 点
- 阅读权限
- 150
- 积分
- 5990
- 相册
- 0
- 日志
- 0
- 记录
- 5
- 帖子
- 6675
- 主题
- 3503
- 精华
- 3
- 分享
- 6
- 好友
- 1721
TA的每日心情 | 开心 2017-2-7 15:12 |
|---|
签到天数: 691 天 [LV.9]以坛为家II
群组: 2013年国赛赛前培训 群组: 2014年地区赛数学建模 群组: 数学中国第二期SAS培训 群组: 物联网工程师考试 群组: 2013年美赛优秀论文解 |
# -*- coding=utf-8 -*-
8 J4 `+ o4 L" D* ?( y- B
7 W" l) q( ]1 m- S& j% \# rimport math5 n, e* F3 {8 J% u
import sys: U: P5 \+ q8 G8 s, K9 H# R# | _
from texttable import Texttable
/ L$ g, e& H& j; X3 s7 o/ S! Y; ?+ k5 b8 V, t% |' W
+ @% V( X; X7 O% C+ g
#5 Q6 z3 p3 n F0 N: Q7 i3 K
# 使用 |A&B|/sqrt(|A || B |)计算余弦距离
: k: V9 G( ^* M5 |#8 T, a( [( U2 Z' a7 G; f5 ]
#! d$ S0 a- Z0 o/ G
#
; F7 W) |- P- l6 E1 d& c1 ]" Q6 ndef calcCosDistSpe(user1,user2):# z2 S8 p+ z1 W% d
avg_x=0.05 \: {* _, @6 L2 s1 M1 o: D
avg_y=0.0
! [/ j. }3 d( u for key in user1:
) }0 h s5 }3 {% g% P& A9 s avg_x+=key[1]- I5 ]6 t1 m$ _/ L8 d
avg_x=avg_x/len(user1)
0 _& [( ] w) l. A5 W
V: D+ M8 k6 n, |6 q+ G for key in user2:9 f! d7 O4 ~! m$ `4 g
avg_y+=key[1]
, c0 z6 h- t6 u" C P8 A% i avg_y=avg_y/len(user2)+ |* B8 Y& H+ @
, o+ `1 O( {- }% ~- z9 n6 ] u1_u2=0.0- h0 R# b. v: u6 ^* P- b
for key1 in user1:' z2 l/ k6 r( b' O/ D8 m! i" V Y
for key2 in user2:, |5 ^2 J) r1 |% @# j% H5 i
if key1[1] > avg_x and key2[1]>avg_y and key1[0]==key2[0]:& M8 v5 q; y5 i
u1_u2+=15 `" M y0 \* X c( f
u1u2=len(user1)*len(user2)*1.0
) A8 s; u: b& N5 | sx_sy=u1_u2/math.sqrt(u1u2)
- T: p0 ]( g' o6 u# L; p8 ^ return sx_sy
8 l5 r" w$ C5 s; j$ `
$ W1 i$ @5 M2 C
9 r+ P5 `" D( p* p g#
+ p9 A2 U/ _0 S4 i5 }# 计算余弦距离- R* {3 s. b% g J+ n3 c
# e. e) |- H$ ?- z( N- S+ b& U
#
) d' m: {1 T$ I2 {4 w6 X; _def calcCosDist(user1,user2): D- W2 E1 s% E( J& P6 F
sum_x=0.0" | f. {) g; G8 N5 H! b
sum_y=0.0$ j$ r9 n4 M1 N" D
sum_xy=0.0
: ~% I6 P% \$ w for key1 in user1:% Q: w* N; X* ?. G8 o
for key2 in user2:9 _" g! R" c' w0 O
if key1[0]==key2[0] :5 q* F- y! `! e# j. L; V
sum_xy+=key1[1]*key2[1]
( K) [% R2 m$ ?, W! W% { sum_y+=key2[1]*key2[1]9 X5 Z* I! X& a" |
sum_x+=key1[1]*key1[1]5 A) e7 {; Y2 Y+ o) n2 [& o2 F
# ~/ |+ J6 }: z+ {2 F
if sum_xy == 0.0 :
3 J' ~; I' Y! o w7 V& l return 0
2 @: T, T8 J/ Z) ~ sx_sy=math.sqrt(sum_x*sum_y)
1 V8 Z P& {4 F" v return sum_xy/sx_sy! o+ T5 {+ U( e- O0 W5 V" B+ b
# _7 |4 P, s' p! u
[% O+ P* y, @( x#7 s! W0 Q% V6 M3 h
#
: K! D, n* k, j" b' R) K# 相似余弦距离
, P. u+ I& c( Z+ B#7 r# T* j2 B* K
#
: S. k, e" R# R1 k#
! v# Q. K4 t0 @; kdef calcSimlaryCosDist(user1,user2):
5 Z! E+ B: s3 Y sum_x=0.0; S3 R4 |! ]" V; D' `$ r7 h8 d o
sum_y=0.0
* {9 Y; \0 |% F5 w! j! p ] sum_xy=0.0
; |9 H/ E. F4 k( N: b avg_x=0.0
! Q6 X/ b6 q, ?. v i0 q" K avg_y=0.08 U) }% z3 L+ M
for key in user1:
# P+ i4 ?* \3 d avg_x+=key[1]* j s; w/ V: U* b. o$ h6 H
avg_x=avg_x/len(user1)
' Q, e# a3 U1 N7 y+ t) N% h4 o
$ M3 T- L( F0 v1 g' ~/ Q for key in user2:3 q3 D" ^" S, P
avg_y+=key[1]5 C) b W R; B
avg_y=avg_y/len(user2)+ [8 r% M. G) U2 ?% f e5 J% x
# m) |9 Z @2 j) Q$ J& o
for key1 in user1:
2 j$ l# E3 D5 T6 Y/ i+ t1 l: C for key2 in user2:
; Y+ A9 R' P: m, {& Q# \/ Y0 n if key1[0]==key2[0] :9 k* N+ L0 c4 T- [8 f
sum_xy+=(key1[1]-avg_x)*(key2[1]-avg_y)
2 Y2 R( d1 s" `. a6 Z sum_y+=(key2[1]-avg_y)*(key2[1]-avg_y); R! t9 I9 Q9 |8 l9 P
sum_x+=(key1[1]-avg_x)*(key1[1]-avg_x)9 f: b0 D5 D2 v1 N( K8 V* n
6 l" b! N! ]5 `1 V, L1 t( P2 ^ if sum_xy == 0.0 :7 w- R' g. ~' k. T
return 0$ j& O2 }0 B7 g4 F# B8 V/ a( B- p
sx_sy=math.sqrt(sum_x*sum_y)
8 S- d' p; r R7 b' ~ return sum_xy/sx_sy, z, k* f. F' X; x9 Z/ f
7 R9 [1 l" e7 d# z
p# Z E: h* d* F- V#
( l) c/ ?+ _* \: R0 Y# 读取文件
2 J- a# ~- w! d8 L#
' r( n% f7 a, [. f: Z3 O#: w" h! M" K: ~+ C! f0 Y4 t4 M. M% T
def readFile(file_name):: J# M; h9 Z3 B# Y u7 |4 h
contents_lines=[]
) W! e& p. u+ O6 y* U. V- H f=open(file_name,"r")) n" h7 q7 h N) ^
contents_lines=f.readlines() W) Q b) G" b* s/ @& U/ ~
f.close()
! H; {3 t; B$ j2 k return contents_lines; r7 w% z* W& f" u( `" \
/ X/ r& Q6 d* y' L
/ t$ ?# A+ M$ _' `+ z6 K2 u; y4 ?2 A6 o( R- ~6 h L4 K, Q" c; Z( w
#
" f* o/ t, K4 B7 |! }% ~' ?# 解压rating信息,格式:用户id\t硬盘id\t用户rating\t时间
7 [6 q" }: C( e5 o2 A8 p: N# 输入:数据集合8 w& w% c+ K/ k4 H3 V) V7 `7 v$ v
# 输出:已经解压的排名信息
( [' `, v" t# Y1 p8 O#
0 }' m( @4 P9 g7 F# p9 ]" X, Y" Cdef getRatingInformation(ratings):% e& Z$ N: U0 g! ] E) |. l
rates=[]
7 L l; ]' ?, ~ for line in ratings:6 H$ p5 S$ x8 _8 O% T* ]
rate=line.split("\t")
7 \; r# d; ?% H rates.append([int(rate[0]),int(rate[1]),int(rate[2])])2 y9 h% D& S- P9 x' h. U
return rates4 k2 O" W; z& @7 v! u
# e$ S, J" ]+ t+ Z% D6 J
/ p4 y$ l2 C8 t( V5 K
#
2 R: I1 o0 s$ a# 生成用户评分的数据结构
p; C6 k! u- _+ F0 z9 ^# 8 o$ W1 \- {3 h0 h0 y9 j6 E* k$ N% E
# 输入:所以数据 [[2,1,5],[2,4,2]...]( T/ x5 |: W. Z* s) j
# 输出:1.用户打分字典 2.电影字典# C: A. m t F7 ^: e
# 使用字典,key是用户id,value是用户对电影的评价,
' j5 h4 ?' V; w" o# rate_dic[2]=[(1,5),(4,2)].... 表示用户2对电影1的评分是5,对电影4的评分是2
' I" a$ t- u8 {9 v1 S* C; u9 ?#
$ ^, \9 v1 m0 ~. C! Pdef createUserRankDic(rates):' _" M- J4 @! w* Q
user_rate_dic={}" p( M0 L2 }3 L$ v7 E2 E& A/ q
item_to_user={}, I( `) Z* \- d
for i in rates:
6 c. F/ X/ k: W' q user_rank=(i[1],i[2]); p: [. G' S. J2 U7 S3 w0 e
if i[0] in user_rate_dic:
5 z, ~" }/ O2 G" J4 I1 a8 u1 H user_rate_dic[i[0]].append(user_rank)
; B) B- j% v$ y" ^- F5 | else:
% E4 @, L& i: f( m* [) g user_rate_dic[i[0]]=[user_rank]+ \1 v1 Q( L6 A4 `( G" r6 K
1 E" f2 y7 w k" K if i[1] in item_to_user:9 Q/ t6 u* h o6 B$ t* o6 v% I* B
item_to_user[i[1]].append(i[0])
# }' `( e) u) M& Y) `! ?: R! X else:2 ?% ]: v8 l% ~
item_to_user[i[1]]=[i[0]]
; \( A$ k) a, H: H ( i5 ?8 U* E/ G9 B5 z
return user_rate_dic,item_to_user ~" m+ w+ W8 ~. B' c- y- P+ K
5 P2 G8 T; x6 |: ^1 P1 b6 f4 {
& V( M5 ]* R9 A5 d
#" S2 F2 x( g. C8 F' Y
# 计算与指定用户最相近的邻居$ k$ Q; Q8 w/ _6 h' q: M
# 输入:指定用户ID,所以用户数据,所以物品数据
! `! _5 T. y( q4 W. Z6 F# 输出:与指定用户最相邻的邻居列表1 t: K }: z8 {, Z
#
2 E R. Z( ]5 i( j% z" ndef calcNearestNeighbor(userid,users_dic,item_dic):/ H' h3 w K7 I/ K; Y q/ ]
neighbors=[]
1 F6 H8 Y9 D W- T: G/ [4 m #neighbors.append(userid)
# ~ J* ?) j% U for item in users_dic[userid]:) Z: p- ^6 X# ?1 N2 h
for neighbor in item_dic[item[0]]:
6 v- N2 t/ \( x$ b6 |% Y if neighbor != userid and neighbor not in neighbors:
) x8 L- [5 ~3 G" L2 s W' Q neighbors.append(neighbor)
; f% v x5 f- w, E- c ) ]! W/ q T A2 M; \8 C2 R
neighbors_dist=[]9 Z7 \# \2 e# N7 {% l& J
for neighbor in neighbors:3 S% {7 Z" |( X& p
dist=calcSimlaryCosDist(users_dic[userid],users_dic[neighbor]) #calcSimlaryCosDist calcCosDist calcCosDistSpe) m4 g" B( |0 o+ D; ^; O" |
neighbors_dist.append([dist,neighbor]) R- k0 V+ k4 ?3 e) s' q
neighbors_dist.sort(reverse=True)! P) a* n {, n3 m) G. n
#print neighbors_dist
! w, ^) }7 E0 b8 q) J) o& U- s return neighbors_dist9 d2 q& Q, {% \: \/ ?, \
0 ^6 O+ \2 j8 S8 t+ W
s, u* e; ]4 g: f5 ]7 M#$ J g! I7 J1 [9 [; v3 D
# 使用UserFC进行推荐0 I( s. v7 {" Z, ?0 i9 P& I4 _
# 输入:文件名,用户ID,邻居数量
3 P5 g" }$ S" F% w: U. a I3 W# 输出:推荐的电影ID,输入用户的电影列表,电影对应用户的反序表,邻居列表
6 E* H, t9 l* Y J. }# z. k9 G#
7 X/ c5 }. k, y. d% h. J+ Xdef recommendByUserFC(file_name,userid,k=5):
" C. |7 M1 c% d1 j& P" C; O8 g8 K ( q/ q; P) F. ]- t
#读取文件数据/ Y/ q0 C/ O2 a5 `& }; Z. `
test_contents=readFile(file_name)& t5 L" J$ v/ @7 z, @
5 B6 J( E8 O( [8 T8 f6 I$ N
#文件数据格式化成二维数组 List[[用户id,电影id,电影评分]...] ; Q6 H4 u( e' t' y2 G; e
test_rates=getRatingInformation(test_contents)
+ E- w6 d5 l3 T6 i0 t
7 @* {8 v% L/ D0 w6 K6 m8 c #格式化成字典数据 & \& i5 d+ [) } E1 z0 a# p9 L) G; P
# 1.用户字典:dic[用户id]=[(电影id,电影评分)...]
9 L- r t6 }2 ?1 ~ # 2.电影字典:dic[电影id]=[用户id1,用户id2...]% p& H, w K1 Z( h
test_dic,test_item_to_user=createUserRankDic(test_rates)! ^9 v6 e& L: Y n) q
6 b3 {& r& W7 n4 \ Q
#寻找邻居' U! \3 h( Y6 B$ D: M) R# d, o
neighbors=calcNearestNeighbor(userid,test_dic,test_item_to_user)[:k]
/ q: ~: P1 g, d0 w/ L* m
' l. G* f3 w4 p* i c" z5 j2 _ recommend_dic={}7 s% l$ d1 F0 L) T( \
for neighbor in neighbors:
! |& q# ?3 B8 b7 p5 I' ` neighbor_user_id=neighbor[1]
! z9 y" }' S6 r- G, T" g movies=test_dic[neighbor_user_id]
/ d0 N, S& {: o/ V/ r for movie in movies:2 |. r! [: w4 [9 N5 E
#print movie8 `6 F, O% C+ D% Q0 u, O& L) u6 a
if movie[0] not in recommend_dic:
: R4 }- m+ x* @6 G; J3 ]# W recommend_dic[movie[0]]=neighbor[0]9 v. o; J: i8 l i
else:
3 O' A' s4 V' `$ r& y2 E7 T/ d recommend_dic[movie[0]]+=neighbor[0]
! S1 z% ]2 Q8 {) ]- U1 ^1 D #print len(recommend_dic)
% N4 W4 ?( L, F+ [
5 b9 u Z) e# [0 b7 x #建立推荐列表
% o, T' Q( X& N1 h" f recommend_list=[]* i. s# C, p- O6 U6 B1 C$ @: W
for key in recommend_dic:
/ K4 j8 s: X3 ]8 u9 h #print key
2 }" |5 j% F0 v" \# D recommend_list.append([recommend_dic[key],key])
4 a: K M6 R3 ~
7 S5 l3 s `% V- j4 a. i
) r1 h* @6 b' h8 S8 _3 n5 K% R recommend_list.sort(reverse=True)9 m5 r* e% z& }. z3 N6 |
#print recommend_list% ]0 E$ v2 P" P
user_movies = [ i[0] for i in test_dic[userid]]) n( v8 S, X8 j; Z1 \1 P
8 h! }& H# G' v9 I6 X t return [i[1] for i in recommend_list],user_movies,test_item_to_user,neighbors* o2 y$ J$ P. Y5 {
0 S* @. F% ?5 [( W1 ?6 l3 I ^
# i) ^' @- F+ d% u
; \$ V3 m+ ?- E( b9 u1 }
#
: f6 }7 X. Y% T1 @# m' u: M5 x#
: p' O- K R7 d1 O1 k4 a! Y2 r# 获取电影的列表# \, g+ A' l4 i3 B" W9 V0 n, x
#
& {4 _- J C8 F9 a2 h m#
$ r1 ~; p" v' }) c: `2 l5 Z# W$ l#3 ^1 S; Z7 o. L
def getMoviesList(file_name):& F3 g' F, ]2 x8 z- b8 l
#print sys.getdefaultencoding()
/ v! j; ?3 P2 N4 H+ m x movies_contents=readFile(file_name)
6 n$ f/ x& G2 H& L" J, ~ movies_info={}
8 z( B; n+ z8 b for movie in movies_contents:+ B9 q- P5 Z6 n* n9 {/ a
movie_info=movie.split("|")# t3 {) U3 v0 B
movies_info[int(movie_info[0])]=movie_info[1:]- |# a: k# v" `+ @4 T3 m, t+ U6 M: w: [
return movies_info
1 B# b3 v# X# g& @# S' u/ W# i 5 C- B/ Z; A, o' A# q( |; o: O
; ^8 U% N0 a$ h5 O
& ~7 f. F, R i% E$ |#主程序1 w6 x. @ N' @& b% m' H% h
#输入 : 测试数据集合+ h w* }: k: F0 W8 Y
if __name__ == '__main__':
2 a# g, A- q, ~4 K" H k% ]. ?0 s reload(sys)
3 B! X1 ~! I! K' x0 v- `0 U sys.setdefaultencoding('utf-8')
& u/ N2 o; W8 l5 i8 l8 ^: I movies=getMoviesList("/Users/wuyinghao/Downloads/ml-100k/u.item")
. ?$ t! ]/ h5 d! z2 l% } recommend_list,user_movie,items_movie,neighbors=recommendByUserFC("/Users/wuyinghao/Downloads/ml-100k/u.data",179,80)& U8 x4 M5 K& ]% E) |- q3 z
neighbors_id=[ i[1] for i in neighbors]
6 W! x: ~2 W' v _+ x table = Texttable() l- {+ w( G& J7 Q
table.set_deco(Texttable.HEADER)
( m8 ^! d. _% H8 u2 f$ ~$ g table.set_cols_dtype(['t', # text 3 l; Y: ?! Y8 H+ y
't', # float (decimal)
`* T3 I( P$ D 't']) # automatic
. Q+ w9 o' J6 f$ J6 l, r/ G3 D table.set_cols_align(["l", "l", "l"])+ h* \7 O% y, m& }
rows=[]
/ \' K: p% G9 Z8 }9 U% c7 C* Z rows.append([u"movie name",u"release", u"from userid"])
4 N) t# j5 i) O$ J( w0 r for movie_id in recommend_list[:20]:
' E* M: v% C& y/ e9 ?3 Z from_user=[]5 G( [6 T# Z" y0 P6 t% I5 P
for user_id in items_movie[movie_id]:# Z5 k! r$ `. p6 W5 R
if user_id in neighbors_id:# ?& n+ g1 ~# m8 B4 Z
from_user.append(user_id)
4 k" f- S: h8 a- @ rows.append([movies[movie_id][0],movies[movie_id][1],""])
4 X' p$ J" U* v6 R. L2 {) C table.add_rows(rows)
) ^( B* _' E! x8 Y6 U print table.draw() |
|