diff --git a/pom.xml b/pom.xml index 8169ff7..fb772be 100644 --- a/pom.xml +++ b/pom.xml @@ -1,7 +1,6 @@ 4.0.0 - nearsoft.academy big-data 1.0-SNAPSHOT @@ -12,8 +11,9 @@ UTF-8 + 7 + 7 - org.apache.mahout @@ -26,5 +26,38 @@ 4.7 test + + org.slf4j + slf4j-api + 1.8.0-beta2 + + + + org.slf4j + slf4j-simple + 1.8.0-beta2 + test + + + + + maven-surefire-plugin + + + **/*_UT.java + **/*_FT.java + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 7 + 7 + + + + diff --git a/src/main/java/nearsoft/academy/bigdata/recommendation/MovieRecommender.java b/src/main/java/nearsoft/academy/bigdata/recommendation/MovieRecommender.java new file mode 100644 index 0000000..601d5d2 --- /dev/null +++ b/src/main/java/nearsoft/academy/bigdata/recommendation/MovieRecommender.java @@ -0,0 +1,161 @@ +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.net.URL; +import java.util.*; +import java.nio.file.Files; + +public class MovieRecommender { + + public File resource; + public File data; + private String pathToResources = "src/main/resources/data.txt"; + + public int totalReviews; + public long totalProducts; + public long totalUsers; + + private HashMap userHash = new HashMap(); + private HashMap productHash = new HashMap(); + private HashMap productHashStringId = new HashMap(); + + + public int getTotalReviews() { + return totalReviews; + } + + public void setTotalReviews(int totalReviews) { + this.totalReviews = totalReviews; + } + + public long getTotalProducts() { + return totalProducts; + } + + public void setTotalProducts(int totalProducts) { + this.totalProducts = totalProducts; + } + + public long getTotalUsers() { + return totalUsers; + } + + public void setTotalUsers(int totalUsers) { + this.totalUsers = totalUsers; + } + + + public List getRecommendationsForUser(String user) throws TasteException, IOException { + + DataModel model = new FileDataModel(data); + + UserSimilarity similarity = new PearsonCorrelationSimilarity(model); + + UserNeighborhood neighborhood = new ThresholdUserNeighborhood(0.1, similarity, model); + + UserBasedRecommender recommender = new GenericUserBasedRecommender(model,neighborhood,similarity); + + List recommendations = recommender.recommend(userHash.get(user), 3); + List recommendationIds = new ArrayList(); + + for (RecommendedItem recommendation : recommendations) { + long itemId = recommendation.getItemID(); + recommendationIds.add(productHashStringId.get(itemId)); + } + + return recommendationIds; + + } + + private URL getURL(String filename){ + ClassLoader classLoader = getClass().getClassLoader(); + URL url = classLoader.getResource(filename); + return url; + } + + private File getFileFromResources(String fileName) { + URL resource = getURL(fileName); + if (resource == null) { + throw new IllegalArgumentException("file is not found!"); + } else { + return new File(resource.getFile()); + } + } + + public void setInfo() throws IOException { + + if (resource != null) { + FileReader reader = new FileReader(resource); + BufferedReader br = new BufferedReader(reader); + + data = new File(pathToResources); + + Files.deleteIfExists(data.toPath()); + FileWriter fw = new FileWriter(data,true); + BufferedWriter nbr = new BufferedWriter(fw); + PrintWriter pw = new PrintWriter(nbr); + + String line; + + String userId = ""; + String productId = ""; + String score = ""; + + while ((line = br.readLine()) != null) { + + if (line.startsWith("product/productId")) { + totalReviews++; + productId = line.split(" ")[1]; + + if (!productHash.containsKey(productId)) { + totalProducts++; + productHash.put(productId, totalProducts); + productHashStringId.put(totalProducts,productId); + } + } + if (line.startsWith("review/userId")) { + userId = line.split(" ")[1]; + + if (!userHash.containsKey(userId)) { + totalUsers++; + userHash.put(userId, totalUsers); + } + } + if (line.startsWith("review/score:")) { + score = line.split(" ")[1]; + pw.println(userHash.get(userId) + "," + productHash.get(productId) + "," + score); + } + } + + totalProducts = productHash.size(); + totalUsers = userHash.size(); + br.close(); + pw.close(); + } + } + + public MovieRecommender(String path) throws IOException, TasteException { + this.resource = getFileFromResources(path); + setInfo(); + } + + public static void main (String [] args) throws IOException, TasteException { + MovieRecommender movie = new MovieRecommender("movies.txt"); + + System.out.println("REVIEWS " + movie.totalReviews); + System.out.println("PRODUCTS " + movie.totalProducts); + System.out.println("USERS " + movie.totalUsers); + + + } +}