Skip to content
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

Codigo para las funciones del test. #69

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package nearsoft.academy.bigdata.recommendation;

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.*;
LMBarrera marked this conversation as resolved.
Show resolved Hide resolved
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class MovieRecommender {

private int reviews;
private long users;
private int products;
public UserBasedRecommender recommender;
private HashMap<String, Integer> productTable = new HashMap();
private HashMap<String, Long> userTable = new HashMap();
private HashMap<Integer, String> iProductsTable = new HashMap();
Comment on lines +20 to +26

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need all of these as global variables?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not all of them, but I decided to leave all of them like that instead of a few regarding the aesthetics. I'll consider not doing this again on a future case.


public MovieRecommender(String txt) throws Exception {
readReviewsFile(txt);
}

private void readReviewsFile(String txt) throws Exception {
DataModel model;
UserSimilarity similarity;
UserNeighborhood neighborhood;

File file = new File(txt);
BufferedReader br = new BufferedReader(new FileReader(file));
FileWriter writer = new FileWriter("data.csv");
BufferedWriter bw = new BufferedWriter(writer);
String csv = "";

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why string? Did you consider a string builder?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't consider the inefficiency of string vs. stringBuilder in this case. I'll keep it in mind for the next occasion I do something similar.


for (String line = br.readLine(); line != null; line = br.readLine()) {
if (line.startsWith("product/productId")) {
LMBarrera marked this conversation as resolved.
Show resolved Hide resolved
String productId = line.split(" ")[1];
this.reviews++;
if (this.productTable.containsKey(productId)) {
csv = this.productTable.get(productId) + ",";
} else {
this.productTable.put(productId, this.products);
this.iProductsTable.put(this.products, productId);
csv = this.products + ",";
this.products++;
}
} else if (line.startsWith("review/userId")) {
String userId = line.split(" ")[1];
if (this.userTable.containsKey(userId)) {
csv = this.userTable.get(userId) + "," + csv;
} else {
this.userTable.put(userId, this.users);
csv = this.users + "," + csv;
this.users++;
}
} else if (line.startsWith("review/score")) {
String reviewScore = line.split(" ")[1];
csv += reviewScore + "\n";
bw.write(csv);
}
}
bw.close();
model = new FileDataModel(new File("data.csv"));
similarity = new PearsonCorrelationSimilarity(model);
neighborhood = new ThresholdUserNeighborhood(0.1, similarity, model);
this.recommender = new GenericUserBasedRecommender(model, neighborhood, similarity);
}

public int getTotalReviews() {
return this.reviews;
}

public int getTotalProducts() {
return this.products;
}

public long getTotalUsers() {
return this.users;
}

public List<String> getRecommendationsForUser(String user) throws Exception {
List<String> results = new ArrayList();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why ArrayList and not LinkedList?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because the list consisted only of three elements and the order wasn't an issue. Also no removal or rearrangement was needed, so I thought an arrayList was more fitting for this specific case.


long id = userTable.get(user);
List<RecommendedItem> recommendations = recommender.recommend(id, 3);

for (RecommendedItem recommendation : recommendations) {
results.add(iProductsTable.get((int) recommendation.getItemID()));
}

return results;
}
}