-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathScript.R
More file actions
118 lines (94 loc) · 4.73 KB
/
Copy pathScript.R
File metadata and controls
118 lines (94 loc) · 4.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
options(digits=4)
# I am using only the data from Germany for simplicity
# but you can go ahead and use the entire dataset
#data <- read.csv(file="lastfm-data.csv")
data.germany <- read.csv(file="lastfm-matrix-germany.csv")
############################
# Item Based Similarity #
############################
# Drop the user column and make a new data frame
data.germany.ibs <- (data.germany[,!(names(data.germany) %in% c("user"))])
# Create a helper function to calculate the cosine between two vectors
getCosine <- function(x,y)
{
this.cosine <- sum(x*y) / (sqrt(sum(x*x)) * sqrt(sum(y*y)))
return(this.cosine)
}
# Create a placeholder dataframe listing item vs. item
holder <- matrix(NA, nrow=ncol(data.germany.ibs),ncol=ncol(data.germany.ibs),dimnames=list(colnames(data.germany.ibs),colnames(data.germany.ibs)))
data.germany.ibs.similarity <- as.data.frame(holder)
# Lets fill in those empty spaces with cosine similarities
for(i in 1:ncol(data.germany.ibs)) {
for(j in 1:ncol(data.germany.ibs)) {
data.germany.ibs.similarity[i,j]= getCosine(data.germany.ibs[i],data.germany.ibs[j])
}
}
# Output similarity results to a file
write.csv(data.germany.ibs.similarity,file="final-germany-similarity.csv")
# Get the top 10 neighbours for each
data.germany.neighbours <- matrix(NA, nrow=ncol(data.germany.ibs.similarity),ncol=11,dimnames=list(colnames(data.germany.ibs.similarity)))
for(i in 1:ncol(data.germany.ibs))
{
data.germany.neighbours[i,] <- (t(head(n=11,rownames(data.germany.ibs.similarity[order(data.germany.ibs.similarity[,i],decreasing=TRUE),][i]))))
}
# Output neighbour results to a file
write.csv(file="final-germany-item-neighbours.csv",x=data.germany.neighbours[,-1])
############################
# User Scores Matrix #
############################
# Process:
# Choose a product, see if the user purchased a product
# Get the similarities of that product's top 10 neighbours
# Get the purchase record of that user of the top 10 neighbours
# Do the formula: sumproduct(purchaseHistory, similarities)/sum(similarities)
# helper function to calculate the scores
getScore <- function(history, similarities)
{
x <- sum(history*similarities)/sum(similarities)
x
}
# A placeholder matrix
holder <- matrix(NA, nrow=nrow(data.germany),ncol=ncol(data.germany)-1,dimnames=list((data.germany$user),colnames(data.germany[-1])))
# Loop through the users (rows)
for(i in 1:nrow(holder))
{
# Loops through the products (columns)
for(j in 1:ncol(holder))
{
# Get the user's name and th product's name
# We do this not to conform with vectors sorted differently
user <- rownames(holder)[i]
product <- colnames(holder)[j]
# We do not want to recommend products you have already consumed
# If you have already consumed it, we store an empty string
if(as.integer(data.germany[data.germany$user==user,product]) == 1)
{
holder[i,j]<-""
} else {
# We first have to get a product's top 10 neighbours sorted by similarity
topN<-((head(n=11,(data.germany.ibs.similarity[order(data.germany.ibs.similarity[,product],decreasing=TRUE),][product]))))
topN.names <- as.character(rownames(topN))
topN.similarities <- as.numeric(topN[,1])
# Drop the first one because it will always be the same song
topN.similarities<-topN.similarities[-1]
topN.names<-topN.names[-1]
# We then get the user's purchase history for those 10 items
topN.purchases<- data.germany[,c("user",topN.names)]
topN.userPurchases<-topN.purchases[topN.purchases$user==user,]
topN.userPurchases <- as.numeric(topN.userPurchases[!(names(topN.userPurchases) %in% c("user"))])
# We then calculate the score for that product and that user
holder[i,j]<-getScore(similarities=topN.similarities,history=topN.userPurchases)
} # close else statement
} # end product for loop
} # end user for loop
# Output the results to a file
data.germany.user.scores <- holder
write.csv(file="final-user-scores.csv",data.germany.user.scores)
# Lets make our recommendations pretty
data.germany.user.scores.holder <- matrix(NA, nrow=nrow(data.germany.user.scores),ncol=100,dimnames=list(rownames(data.germany.user.scores)))
for(i in 1:nrow(data.germany.user.scores))
{
data.germany.user.scores.holder[i,] <- names(head(n=100,(data.germany.user.scores[,order(data.germany.user.scores[i,],decreasing=TRUE)])[i,]))
}
# Write output to file
write.csv(file="final-user-recommendations.csv",data.germany.user.scores.holder)