-
Notifications
You must be signed in to change notification settings - Fork 57
POM, MovieRecommender #28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,145 @@ | ||
| package nearsoft.academy.bigdata.recommendation; | ||
|
|
||
|
|
||
| import org.apache.mahout.cf.taste.common.TasteException; | ||
| import org.apache.mahout.cf.taste.impl.model.file.FileDataModel; | ||
| import org.apache.mahout.cf.taste.impl.neighborhood.ThresholdUserNeighborhood; | ||
| import org.apache.mahout.cf.taste.impl.recommender.GenericUserBasedRecommender; | ||
| import org.apache.mahout.cf.taste.impl.similarity.PearsonCorrelationSimilarity; | ||
| import org.apache.mahout.cf.taste.model.DataModel; | ||
| import org.apache.mahout.cf.taste.neighborhood.UserNeighborhood; | ||
| import org.apache.mahout.cf.taste.recommender.RecommendedItem; | ||
| import org.apache.mahout.cf.taste.recommender.UserBasedRecommender; | ||
| import org.apache.mahout.cf.taste.similarity.UserSimilarity; | ||
|
|
||
|
|
||
| import java.io.*; | ||
| import java.util.ArrayList; | ||
| import java.util.HashMap; | ||
| import java.util.List; | ||
| import java.util.regex.Matcher; | ||
| import java.util.regex.Pattern; | ||
|
|
||
| public class MovieRecommender { | ||
| String path; | ||
| int repMovies,repUsers; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Declaration should go on single line |
||
| int user,product,review; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here, declaration should go on single lines |
||
| HashMap<String, Integer> userId = new HashMap<String, Integer>(); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Avoid using implementations, use an interface instead |
||
| HashMap<String, Integer> products = new HashMap<String, Integer>(); | ||
| HashMap<Integer,String> productId = new HashMap<Integer,String>(); | ||
|
|
||
| public MovieRecommender(String pathUrl) throws IOException { | ||
| this.path = pathUrl; | ||
| convert(); | ||
| } | ||
|
|
||
| public void convert() throws IOException { | ||
| this.user=0; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Initialization should be part of constructor. Also, default values of int attributes is zero |
||
| this.product=0; | ||
| this.review=0; | ||
| this.repMovies=0; | ||
| this.repUsers=0; | ||
| String idUser="",idProduct="", scoreReview=""; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Declaration should be single line |
||
|
|
||
| BufferedReader reader = new BufferedReader(new FileReader(path)); | ||
| String line; | ||
|
|
||
| String uRegex = "review\\/userId: ([\\D\\d]+)"; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These can be converted to class attributes |
||
| String pRegex = "product\\/productId: ([\\D\\d]+)"; | ||
| String rRegex = "review\\/score: ([\\D\\d]+)"; | ||
|
|
||
| Pattern userPattern = Pattern.compile(uRegex); | ||
| Pattern productPattern = Pattern.compile(pRegex); | ||
| Pattern reviewPattern = Pattern.compile(rRegex); | ||
|
|
||
|
|
||
| FileWriter csvWriter = new FileWriter("list.csv"); | ||
|
|
||
| Matcher matcher; | ||
|
|
||
| boolean match; | ||
|
|
||
| line= reader.readLine(); | ||
|
|
||
| while (line != null){ | ||
|
|
||
| matcher = productPattern.matcher(line); | ||
| match = matcher.matches(); | ||
|
|
||
| if (match){ | ||
| String[] parts = line.split(": ",2); | ||
| idProduct= parts[1]; | ||
| if(products.containsKey(idProduct)) | ||
| this.repMovies++; | ||
| else{ | ||
| this.product++; | ||
| products.put(idProduct,this.product); | ||
| productId.put(this.product,idProduct); | ||
| } | ||
|
|
||
| } | ||
|
|
||
| matcher = userPattern.matcher(line); | ||
| match = matcher.matches(); | ||
|
|
||
| if (match){ | ||
| String[] parts = line.split(": ",2); | ||
| idUser= parts[1]; | ||
| if(userId.containsKey(idUser)) | ||
| this.repUsers++; | ||
| else{ | ||
| this.user++; | ||
| userId.put(idUser,this.user); | ||
| } | ||
|
|
||
| } | ||
|
|
||
| matcher = reviewPattern.matcher(line); | ||
| match = matcher.matches(); | ||
|
|
||
| if (match){ | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see three different if statements for matches, does it mean that a single line can match with all three patterns at the same time? |
||
| String[] parts = line.split(": ",2); | ||
| scoreReview= parts[1]; | ||
| this.review++; | ||
| } | ||
|
|
||
| if(idProduct != "" && idUser != "" && scoreReview != "") { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use |
||
| csvWriter.append(userId.get(idUser).toString()); | ||
| csvWriter.append(","); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Avoid using string literals, you can use a static String or an enum |
||
| csvWriter.append(products.get(idProduct).toString()); | ||
| csvWriter.append(","); | ||
| csvWriter.append(scoreReview); | ||
| csvWriter.append("\n"); | ||
| idUser=""; | ||
| idProduct=""; | ||
| scoreReview=""; | ||
| } | ||
| line=reader.readLine(); | ||
|
|
||
| } | ||
| csvWriter.flush(); | ||
| csvWriter.close(); | ||
| reader.close(); | ||
|
|
||
| } | ||
|
|
||
| public int getTotalReviews(){ return this.review; } | ||
| public int getTotalProducts(){ return this.product; } | ||
| public int getTotalUsers(){ return this.user; } | ||
|
|
||
| public List <String> getRecommendationsForUser(String id) throws IOException, TasteException { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Where is this function being called? |
||
| DataModel model = new FileDataModel(new File("list.csv")); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Avoid hardcoding file names |
||
| UserSimilarity similarity = new PearsonCorrelationSimilarity(model); | ||
| UserNeighborhood neighborhood = new ThresholdUserNeighborhood(0.1, similarity, model); | ||
| UserBasedRecommender recommender = new GenericUserBasedRecommender(model, neighborhood, similarity); | ||
|
|
||
| List<String> recommendations = new ArrayList<String>(); | ||
|
|
||
| for (RecommendedItem recommendation : recommender.recommend(userId.get(id), 3)) { | ||
| recommendations.add(productId.get((int)(recommendation.getItemID()))); | ||
| } | ||
|
|
||
| return recommendations; | ||
| } | ||
|
|
||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Define right access modifier for class attributes