Skip to content

Commit 4671e01

Browse files
committedNov 8, 2017
Fix bugs, add recommender interface, recommendation runner class
1 parent 28cd05c commit 4671e01

15 files changed

+569
-111
lines changed
 

‎EfficientRater.class

164 Bytes
Binary file not shown.

‎EfficientRater.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ public int numRatings() {
4747

4848
public ArrayList<String> getItemsRated() {
4949
ArrayList<String> list = new ArrayList<String>();
50-
for(int k=0; k < myRatings.size(); k++){
51-
list.add(myRatings.get(k).getItem());
50+
for(String key : myRatings.keySet()){
51+
list.add(myRatings.get(key).getItem());
5252
}
5353
return list;
5454
}

‎FourthRatings.class

1.87 KB
Binary file not shown.

‎FourthRatings.ctxt

+3-1
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,6 @@ comment7.params=id
1616
comment7.target=java.util.ArrayList\ getSimilarities(java.lang.String)
1717
comment8.params=id\ numSimilarRaters\ minimalRaters
1818
comment8.target=java.util.ArrayList\ getSimilarRatings(java.lang.String,\ int,\ int)
19-
numComments=9
19+
comment9.params=id\ numSimilarRaters\ minimalRaters\ filterCriteria
20+
comment9.target=java.util.ArrayList\ getSimilarRatingsByFilter(java.lang.String,\ int,\ int,\ Filter)
21+
numComments=10

‎FourthRatings.java

+50-10
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@ public FourthRatings() {
1313
this("ratings.csv");
1414
}
1515

16-
public FourthRatings(String ratingsfile) {
17-
FirstRatings fr = new FirstRatings();
16+
public FourthRatings(String ratingsfile) {;
1817
RaterDatabase.addRatings("data/" + ratingsfile);
1918
}
2019

@@ -52,10 +51,10 @@ public ArrayList<Rating> getAverageRatingsByFilter(int minimalRaters,
5251
ArrayList<String> movies = MovieDatabase.filterBy(filterCriteria);
5352

5453
for (String movieID : movies){
55-
double rating = getAverageByID(movieID, minimalRaters);
56-
Rating movieAvgRate = new Rating(movieID, rating);
54+
double avgRating = getAverageByID(movieID, minimalRaters);
5755

58-
if(rating != 0){
56+
if(avgRating != 0){
57+
Rating movieAvgRate = new Rating(movieID, avgRating);
5958
avgRatingsByFilter.add(movieAvgRate);
6059
}
6160
}
@@ -79,13 +78,16 @@ private double dotProduct(Rater me, Rater r){
7978
}
8079

8180
private ArrayList<Rating> getSimilarities(String id) {
82-
81+
8382
ArrayList<Rating> list = new ArrayList<Rating>();
8483
Rater me = RaterDatabase.getRater(id);
84+
8585
for (Rater r : RaterDatabase.getRaters()){
86-
if (id != r.getID()) {
87-
Rating rater = new Rating(r.getID(), dotProduct(me, r));
88-
list.add(rater);
86+
if (!r.equals(me)) {
87+
double dotProd = dotProduct(me, r);
88+
if (dotProd > 0) {
89+
list.add(new Rating(r.getID(), dotProd));
90+
}
8991
}
9092
}
9193
Collections.sort(list, Collections.reverseOrder());
@@ -108,17 +110,55 @@ public ArrayList<Rating> getSimilarRatings( String id,
108110
double weight = r.getValue();
109111
String raterID = r.getItem();
110112
Rater myRater = RaterDatabase.getRater(raterID);
113+
111114
if(myRater.hasRating(movieID)) {
112115
countRaters ++;
113116
sum += weight * myRater.getRating(movieID);
114117
}
115118
}
119+
116120
if (countRaters >= minimalRaters){
117121
weightedAverage = sum / countRaters;
118122
ret.add(new Rating(movieID, weightedAverage));
119123
}
120-
}
124+
}
125+
126+
Collections.sort(ret, Collections.reverseOrder());
127+
return ret;
128+
}
129+
130+
public ArrayList<Rating> getSimilarRatingsByFilter( String id, int numSimilarRaters,
131+
int minimalRaters, Filter filterCriteria ) {
132+
133+
ArrayList<Rating> ret = new ArrayList<Rating>();
134+
ArrayList<Rating> list = getSimilarities(id);
135+
ArrayList<String> movies = MovieDatabase.filterBy(filterCriteria);
136+
137+
for (String movieID : movies){
138+
double weightedAverage = 0;
139+
double sum = 0;
140+
int countRaters = 0;
141+
142+
for(int k=0; k < numSimilarRaters; k++){
143+
Rating r = list.get(k);
144+
double weight = r.getValue();
145+
String raterID = r.getItem();
146+
Rater myRater = RaterDatabase.getRater(raterID);
147+
148+
if(myRater.hasRating(movieID)) {
149+
countRaters ++;
150+
sum += weight * myRater.getRating(movieID);
151+
}
152+
}
153+
154+
if (countRaters >= minimalRaters){
155+
weightedAverage = sum / countRaters;
156+
ret.add(new Rating(movieID, weightedAverage));
157+
}
158+
}
159+
121160
Collections.sort(ret, Collections.reverseOrder());
122161
return ret;
162+
123163
}
124164
}

‎MovieRunnerSimilarRatings.class

3.39 KB
Binary file not shown.

‎MovieRunnerSimilarRatings.ctxt

+11-1
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,14 @@ comment1.params=
44
comment1.target=void\ printAverageRatings()
55
comment2.params=
66
comment2.target=void\ printAverageRatingsByYearAfterAndGenre()
7-
numComments=3
7+
comment3.params=
8+
comment3.target=void\ printSimilarRatings()
9+
comment4.params=
10+
comment4.target=void\ printSimilarRatingsByGenre()
11+
comment5.params=
12+
comment5.target=void\ printSimilarRatingsByDirector()
13+
comment6.params=
14+
comment6.target=void\ printSimilarRatingsByGenreAndMinutes()
15+
comment7.params=
16+
comment7.target=void\ printSimilarRatingsByYearAfterAndMinutes()
17+
numComments=8

‎MovieRunnerSimilarRatings.java

+124-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public void printAverageRatings(){
1515
// ratings.csv
1616
// ratedmoviesfull.csv
1717

18-
FourthRatings tr = new FourthRatings("data/ratings.csv");
18+
FourthRatings tr = new FourthRatings("ratings.csv");
1919
MovieDatabase.initialize(moviefile);
2020
ArrayList<Rating> ratedMovieList = tr.getAverageRatings(35);
2121
Collections.sort(ratedMovieList);
@@ -62,5 +62,128 @@ public void printAverageRatingsByYearAfterAndGenre(){
6262
}
6363
}
6464

65+
public void printSimilarRatings(){
66+
String movieFile = "ratedmoviesfull.csv";
67+
String ratingsFile = "ratings.csv";
68+
String id = "71";
69+
int minimalRaters = 5;
70+
int similarRaters = 20;
71+
72+
FourthRatings fr = new FourthRatings(ratingsFile);
73+
MovieDatabase.initialize(movieFile);
74+
ArrayList<Rating> ratings = fr.getSimilarRatings(id, similarRaters, minimalRaters);
75+
76+
System.out.println("read data for " + RaterDatabase.size() + " raters");
77+
System.out.println("read data for " + MovieDatabase.size() + " movies");
78+
System.out.println(ratings.size() + " movie(s) matched");
79+
80+
for (int i = 0; i < ratings.size(); i++) {
81+
System.out.println(ratings.get(i).getValue() + " " + MovieDatabase.getTitle(ratings.get(i).getItem()));
82+
}
83+
}
84+
85+
public void printSimilarRatingsByGenre(){
86+
String movieFile = "ratedmoviesfull.csv";
87+
String ratingsFile = "ratings.csv";
88+
String id = "964";
89+
int minimalRaters = 5;
90+
int similarRaters = 20;
91+
GenreFilter genreFilter =
92+
new GenreFilter("Mystery");
93+
94+
FourthRatings fr = new FourthRatings(ratingsFile);
95+
MovieDatabase.initialize(movieFile);
96+
97+
ArrayList<Rating> ratings = fr.getSimilarRatingsByFilter(id, similarRaters,
98+
minimalRaters, genreFilter);
99+
100+
System.out.println("read data for " + RaterDatabase.size() + " raters");
101+
System.out.println("read data for " + MovieDatabase.size() + " movies");
102+
System.out.println(ratings.size() + " movie(s) matched");
103+
104+
for (int i = 0; i < ratings.size(); i++) {
105+
System.out.println(ratings.get(i).getValue() + " " + MovieDatabase.getTitle(ratings.get(i).getItem()));
106+
}
107+
}
108+
109+
public void printSimilarRatingsByDirector(){
110+
String movieFile = "ratedmoviesfull.csv";
111+
String ratingsFile = "ratings.csv";
112+
String id = "120";
113+
int minimalRaters = 2;
114+
int similarRaters = 10;
115+
DirectorsFilter directorFilter =
116+
new DirectorsFilter("Clint Eastwood,J.J. Abrams,Alfred Hitchcock,Sydney Pollack,David Cronenberg,Oliver Stone,Mike Leigh");
117+
118+
FourthRatings fr = new FourthRatings(ratingsFile);
119+
MovieDatabase.initialize(movieFile);
120+
121+
ArrayList<Rating> ratings = fr.getSimilarRatingsByFilter(id, similarRaters,
122+
minimalRaters, directorFilter);
123+
124+
System.out.println("read data for " + RaterDatabase.size() + " raters");
125+
System.out.println("read data for " + MovieDatabase.size() + " movies");
126+
System.out.println(ratings.size() + " movie(s) matched");
127+
128+
for (int i = 0; i < ratings.size(); i++) {
129+
System.out.println(ratings.get(i).getValue() + " " + MovieDatabase.getTitle(ratings.get(i).getItem()));
130+
}
131+
}
132+
133+
public void printSimilarRatingsByGenreAndMinutes(){
134+
String movieFile = "ratedmoviesfull.csv";
135+
String ratingsFile = "ratings.csv";
136+
String id = "168";
137+
int minimalRaters = 3;
138+
int similarRaters = 10;
139+
140+
GenreFilter genreFilter = new GenreFilter("Drama");
141+
MinutesFilter minutesFilter = new MinutesFilter(80, 160);
142+
AllFilters genreAndMinutesFilters = new AllFilters();
143+
genreAndMinutesFilters.addFilter(genreFilter);
144+
genreAndMinutesFilters.addFilter(minutesFilter);
145+
146+
FourthRatings fr = new FourthRatings(ratingsFile);
147+
MovieDatabase.initialize(movieFile);
148+
149+
ArrayList<Rating> ratings = fr.getSimilarRatingsByFilter(id, similarRaters,
150+
minimalRaters, genreAndMinutesFilters);
151+
152+
System.out.println("read data for " + RaterDatabase.size() + " raters");
153+
System.out.println("read data for " + MovieDatabase.size() + " movies");
154+
System.out.println(ratings.size() + " movie(s) matched");
155+
156+
for (int i = 0; i < ratings.size(); i++) {
157+
System.out.println(ratings.get(i).getValue() + " " + MovieDatabase.getTitle(ratings.get(i).getItem()));
158+
}
159+
160+
}
65161

162+
public void printSimilarRatingsByYearAfterAndMinutes(){
163+
String movieFile = "ratedmoviesfull.csv";
164+
String ratingsFile = "ratings.csv";
165+
String id = "314";
166+
int minimalRaters = 5;
167+
int similarRaters = 10;
168+
169+
YearAfterFilter yearAfterFilter = new YearAfterFilter(1975);
170+
MinutesFilter minutesFilter = new MinutesFilter(70, 200);
171+
AllFilters yearAndMinutesFilters = new AllFilters();
172+
yearAndMinutesFilters.addFilter(yearAfterFilter);
173+
yearAndMinutesFilters.addFilter(minutesFilter);
174+
175+
FourthRatings fr = new FourthRatings(ratingsFile);
176+
MovieDatabase.initialize(movieFile);
177+
178+
ArrayList<Rating> ratings = fr.getSimilarRatingsByFilter(id, similarRaters,
179+
minimalRaters, yearAndMinutesFilters);
180+
181+
System.out.println("read data for " + RaterDatabase.size() + " raters");
182+
System.out.println("read data for " + MovieDatabase.size() + " movies");
183+
System.out.println(ratings.size() + " movie(s) matched");
184+
185+
for (int i = 0; i < ratings.size(); i++) {
186+
System.out.println(ratings.get(i).getValue() + " " + MovieDatabase.getTitle(ratings.get(i).getItem()));
187+
}
188+
}
66189
}

‎RecommendationRunner.class

4.14 KB
Binary file not shown.

‎RecommendationRunner.ctxt

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#BlueJ class context
2+
comment0.target=RecommendationRunner
3+
comment1.params=
4+
comment1.target=java.util.ArrayList\ getItemsToRate()
5+
comment2.params=webRaterID
6+
comment2.target=void\ printRecommendationsFor(java.lang.String)
7+
numComments=3

‎RecommendationRunner.java

+104
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
2+
/**
3+
* Write a description of class RecommendationRunner here.
4+
*
5+
* @author (your name)
6+
* @version (a version number or a date)
7+
*/
8+
9+
import java.util.*;
10+
11+
public class RecommendationRunner implements Recommender
12+
{
13+
public ArrayList<String> getItemsToRate (){
14+
15+
ArrayList<String> res = new ArrayList<String>();
16+
int numToDisplay = 10;
17+
int minimalRaters = 5;
18+
ArrayList<String> movies = MovieDatabase.filterBy(new TrueFilter());
19+
Random rand = new Random();
20+
21+
for(int i = 0; i < numToDisplay; i++){
22+
int r = rand.nextInt(movies.size());
23+
String title = movies.get(r);
24+
if (!res.contains(title)) {
25+
res.add(title);
26+
}
27+
}
28+
return res;
29+
}
30+
public void printRecommendationsFor (String webRaterID){
31+
32+
FourthRatings fr = new FourthRatings();
33+
ArrayList<Rating> ratings = fr.getSimilarRatings(webRaterID,1,1);
34+
int length = 10;
35+
36+
if(ratings.size()<10){
37+
length = ratings.size();
38+
}
39+
40+
if(ratings.size() == 0){
41+
int index = 0;
42+
ArrayList<String> movies = MovieDatabase.filterBy(new TrueFilter());
43+
Random rand = new Random();
44+
HashSet <String> titles = new HashSet <String>();
45+
for(int i =0; i < 10; i++){
46+
int r = rand.nextInt(movies.size());
47+
String title = movies.get(r);
48+
if (ratings.size()!=0 && !titles.contains(title)) {
49+
ratings.add(new Rating(title, 5.00));
50+
titles.add(title);
51+
index++;
52+
}
53+
if(index > 10){
54+
break;
55+
}
56+
}
57+
}
58+
59+
System.out.println
60+
(
61+
"<style>" +
62+
" body { background-color: #1d1f20; }" +
63+
" h2.error { background-color: #ffd700; color: #dc143c; margin: 5; }" +
64+
" #customers, h2 { font-family: \"Trebuchet MS\", Arial, Helvetica, sans-serif;" +
65+
" border-collapse: collapse; width: 100%;text-align: center;}" +
66+
" #custmers td, #customers th, h2 { border: 1px solid #3e3a3a; padding: 8px;}" +
67+
" #customers tr { background-color: #343537; color: #efefef; }" +
68+
" #customers tr:nth-child(even) { background-color: #686666; }" +
69+
" #customers tr:hover { background-color: #ff4444; }" +
70+
" #customers th { padding-top: 12px; padding-bottom: 12px; text-align: center;" +
71+
" background-color: #ef040a; color: white; }" +
72+
" #customers img { height: 50%; }" +
73+
" h2 { background-color: #ef040a; }" +
74+
"</style>" +
75+
"<div class=\"content\">" +
76+
" <div class=\"ui-widget\">" +
77+
" <html>" +
78+
"<h2>BGT Flix - These are some movies you may like</h2>" +
79+
"<table id=\"customers\">" +
80+
" <tr>" +
81+
" <th>#</th>" +
82+
" <th>Poster</th>" +
83+
" <th>Title</th>" +
84+
" <th>Genre</th>" +
85+
" <th>Year</th>" +
86+
" <th>Time</th>" +
87+
" </tr>" +
88+
" <tr>"
89+
);
90+
91+
for(int i=0; i< length; i++) {
92+
int num = i+1;
93+
System.out.println(" <td>"+num+"</td>");
94+
System.out.println(" <td><img src=");
95+
System.out.println( "\""+MovieDatabase.getPoster(ratings.get(i).getItem())+"\"");
96+
System.out.println(" /> </td>");
97+
System.out.println(" <td>"+MovieDatabase.getTitle(ratings.get(i).getItem())+"</td>");
98+
System.out.println(" <td>"+MovieDatabase.getCountry(ratings.get(i).getItem())+"</td>");
99+
System.out.println(" <td>"+MovieDatabase.getYear(ratings.get(i).getItem())+"</td>");
100+
System.out.println(" <td>"+MovieDatabase.getMinutes(ratings.get(i).getItem())+" Minutes"+"</td>");
101+
System.out.println(" </tr>");
102+
}
103+
}
104+
}

‎Recommender.class

278 Bytes
Binary file not shown.

‎Recommender.ctxt

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#BlueJ class context
2+
comment0.target=Recommender
3+
comment0.text=\n\ Implement\ this\ interface\ to\ allow\ your\ code\ to\ be\ integrated\ with\ our\n\ web\ site.\n\ \n\ When\ users\ first\ visit\ the\ recommender\ website,\ our\ code\ will\ call\ the\n\ method\ <code>getItemsToRate()</code>\ to\ get\ a\ list\ of\ movies\ to\ display\n\ on\ the\ web\ page\ for\ users\ to\ rate.\n\ \n\ When\ a\ user\ submits\ their\ ratings,\ our\ code\ will\ call\ the\ method\ <code>\n\ printRecommendationsFor</code>\ to\ get\ your\ recommendations\ based\ on\ the\n\ user's\ ratings.\ \ The\ ID\ given\ to\ this\ method\ is\ for\ a\ new\ Rater\ that\ we\ \n\ have\ already\ added\ to\ the\ RaterDatabase\ with\ ratings\ for\ the\ movies\ \n\ returned\ by\ the\ first\ method.\ \ Whatever\ is\ printed\ from\ that\ method\ will\ \n\ be\ displayed\ on\ the\ web\ page\:\ HTML,\ plain\ text,\ or\ debugging\ information.\n\ \n
4+
comment1.params=
5+
comment1.target=java.util.ArrayList\ getItemsToRate()
6+
comment1.text=\n\ This\ method\ returns\ a\ list\ of\ movie\ IDs\ that\ will\ be\ used\ to\ look\ up\ \n\ the\ movies\ in\ the\ MovieDatabase\ and\ present\ them\ to\ users\ to\ rate.\ \n\ \ \n\ The\ movies\ returned\ in\ the\ list\ will\ be\ displayed\ on\ a\ web\ page,\ so\n\ the\ number\ you\ choose\ may\ affect\ how\ long\ the\ page\ takes\ to\ load\ and\n\ how\ willing\ users\ are\ to\ rate\ the\ movies.\ \ For\ example,\ 10-20\ should\n\ be\ fine,\ 50\ or\ more\ would\ be\ too\ many.\n\ \n\ There\ are\ no\ restrictions\ on\ the\ method\ you\ use\ to\ generate\ this\ list\n\ of\ movies\:\ the\ most\ recent\ movies,\ movies\ from\ a\ specific\ genre,\ \n\ randomly\ chosen\ movies,\ or\ simply\ your\ favorite\ movies.\n\ \n\ The\ ratings\ for\ these\ movies\ will\ make\ the\ profile\ for\ a\ new\ Rater\ \n\ that\ will\ be\ used\ to\ compare\ to\ for\ finding\ recommendations.\n
7+
comment2.params=webRaterID
8+
comment2.target=void\ printRecommendationsFor(java.lang.String)
9+
comment2.text=\n\ This\ method\ returns\ nothing,\ but\ prints\ out\ an\ HTML\ table\ of\ the\ \n\ movies\ recommended\ for\ the\ given\ rater.\n\ \n\ The\ HTML\ printed\ will\ be\ displayed\ on\ a\ web\ page,\ so\ the\ number\ you\n\ choose\ to\ display\ may\ affect\ how\ long\ the\ page\ takes\ to\ load.\ \ For\ \n\ example,\ you\ may\ want\ to\ limit\ the\ number\ printed\ to\ only\ the\ top\ \n\ 20-50\ movies\ recommended\ or\ to\ movies\ not\ rater\ by\ the\ given\ rater.\n\ \n\ You\ may\ also\ include\ CSS\ styling\ for\ your\ table\ using\ the\ &lt;style&gt;\n\ tag\ before\ you\ print\ the\ table.\ \ There\ are\ no\ restrictions\ on\ which\ \n\ movies\ you\ print,\ what\ order\ you\ print\ them\ in,\ or\ what\ information\n\ you\ include\ about\ each\ movie.\ \n\ \n\ @param\ webRaterID\ the\ ID\ of\ a\ new\ Rater\ that\ has\ been\ already\ added\ to\ \n\ \ \ \ \ \ \ \ the\ RaterDatabase\ with\ ratings\ for\ the\ movies\ returned\ by\ the\ \n\ \ \ \ \ \ \ \ method\ getItemsToRate\n
10+
numComments=3

‎Recommender.java

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
2+
import java.util.*;
3+
4+
5+
/**
6+
* Implement this interface to allow your code to be integrated with our
7+
* web site.
8+
*
9+
* When users first visit the recommender website, our code will call the
10+
* method <code>getItemsToRate()</code> to get a list of movies to display
11+
* on the web page for users to rate.
12+
*
13+
* When a user submits their ratings, our code will call the method <code>
14+
* printRecommendationsFor</code> to get your recommendations based on the
15+
* user's ratings. The ID given to this method is for a new Rater that we
16+
* have already added to the RaterDatabase with ratings for the movies
17+
* returned by the first method. Whatever is printed from that method will
18+
* be displayed on the web page: HTML, plain text, or debugging information.
19+
*
20+
*/
21+
public interface Recommender {
22+
/**
23+
* This method returns a list of movie IDs that will be used to look up
24+
* the movies in the MovieDatabase and present them to users to rate.
25+
*
26+
* The movies returned in the list will be displayed on a web page, so
27+
* the number you choose may affect how long the page takes to load and
28+
* how willing users are to rate the movies. For example, 10-20 should
29+
* be fine, 50 or more would be too many.
30+
*
31+
* There are no restrictions on the method you use to generate this list
32+
* of movies: the most recent movies, movies from a specific genre,
33+
* randomly chosen movies, or simply your favorite movies.
34+
*
35+
* The ratings for these movies will make the profile for a new Rater
36+
* that will be used to compare to for finding recommendations.
37+
*/
38+
public ArrayList<String> getItemsToRate ();
39+
40+
/**
41+
* This method returns nothing, but prints out an HTML table of the
42+
* movies recommended for the given rater.
43+
*
44+
* The HTML printed will be displayed on a web page, so the number you
45+
* choose to display may affect how long the page takes to load. For
46+
* example, you may want to limit the number printed to only the top
47+
* 20-50 movies recommended or to movies not rater by the given rater.
48+
*
49+
* You may also include CSS styling for your table using the &lt;style&gt;
50+
* tag before you print the table. There are no restrictions on which
51+
* movies you print, what order you print them in, or what information
52+
* you include about each movie.
53+
*
54+
* @param webRaterID the ID of a new Rater that has been already added to
55+
* the RaterDatabase with ratings for the movies returned by the
56+
* method getItemsToRate
57+
*/
58+
public void printRecommendationsFor (String webRaterID);
59+
}

‎package.bluej

+199-96
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)
Please sign in to comment.