From 21b77752da2793f2c14796508f21d019e6137886 Mon Sep 17 00:00:00 2001 From: Size43 Date: Tue, 19 May 2015 15:03:25 +0200 Subject: Fixed FeedSorter. --- .../main/java/org/rssin/neurons/FeedSorter.java | 180 ++++++++++++++------- app/src/main/java/org/rssin/neurons/Feedback.java | 9 ++ .../java/org/rssin/neurons/MultiNeuralNetwork.java | 2 +- .../neurons/MultiNeuralNetworkPrediction.java | 2 +- .../main/java/org/rssin/neurons/NeuralNetwork.java | 4 +- .../org/rssin/neurons/NeuralNetworkPrediction.java | 2 +- .../org/rssin/neurons/PredictionInterface.java | 2 +- 7 files changed, 141 insertions(+), 60 deletions(-) create mode 100755 app/src/main/java/org/rssin/neurons/Feedback.java (limited to 'app/src') diff --git a/app/src/main/java/org/rssin/neurons/FeedSorter.java b/app/src/main/java/org/rssin/neurons/FeedSorter.java index 43e26c0..5f24ac1 100755 --- a/app/src/main/java/org/rssin/neurons/FeedSorter.java +++ b/app/src/main/java/org/rssin/neurons/FeedSorter.java @@ -1,14 +1,26 @@ package org.rssin.neurons; +import android.gesture.Prediction; + +import org.rssin.rss.FeedItem; + import java.io.IOException; +import java.util.ArrayList; import java.util.Calendar; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; import java.util.Hashtable; +import java.util.List; import java.util.TimeZone; /** * Created by Jos on 14-5-2015. */ public class FeedSorter { + private final int SECONDS_IN_DAY = 24 * 60 * 60; + private MultiNeuralNetwork nn = new MultiNeuralNetwork(25, 50); private int[] isNthMonthInput = new int[12]; @@ -40,58 +52,118 @@ public class FeedSorter { isNight = nn.addInput(); } -// private PredictionInterface getPrediction(FeedItem item) { -// double[] inputs = new double[nn.getInputCount()]; -// -// //Initialize all inputs to -1 / false -// for(int i = 0; i < inputs.length; i++) -// { -// inputs[i] = -1; -// } -// -// //Set month -// Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); -// for(int i = 0; i < isNthMonthInput.length; i++) -// { -// if(cal.get(Calendar.MONTH) - cal.getMinimum(Calendar.MONTH) == i) -// { -// inputs[isNthMonthInput[i]] = 1; -// } -// } -// -// //Set weekday -// for(int i = 0; i < isNthWeekDayInput.length; i++) -// { -// if(cal.get(Calendar.DAY_OF_WEEK) - cal.getMinimum(Calendar.DAY_OF_WEEK) == i) -// { -// inputs[isNthMonthInput[i]] = 1; -// } -// } -// -// //Set day -// int hourOfDay = cal.get(Calendar.HOUR_OF_DAY); -// if(hourOfDay > 6 && hourOfDay < 12) -// { -// inputs[isMorning] = 1; -// }else if(hourOfDay >= 12 && hourOfDay <= 6) -// { -// inputs[isAfternoon] = 1; -// }else if(hourOfDay >= 6 && hourOfDay < 23) -// { -// inputs[isEvening] = 1; -// }else if(hourOfDay >= 23 || hourOfDay <= 6) -// { -// inputs[isNight] = 1; -// } -// -// //TODO: source, category, title, text, etc of FeedItems -// -// return nn.computeOutput(inputs); -// } - -// public List sortItems(List items) { -// // Sort list based on something like date + nn.computeOutput() * DAY. -// throw new NotImplementedException(); -// return items; -// } + private PredictionInterface getPrediction(FeedItem item) { + //Add new inputs for categories. + for(String category : item.getCategory()) + { + category = category.toLowerCase(); + if(!categoryInputs.containsKey(category)) + { + categoryInputs.put(category, nn.addInput()); + } + } + + double[] inputs = new double[nn.getInputCount()]; + + //Initialize all inputs to -1 / false + for(int i = 0; i < inputs.length; i++) + { + inputs[i] = -1; + } + + //Set month + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + for(int i = 0; i < isNthMonthInput.length; i++) + { + if(cal.get(Calendar.MONTH) - cal.getMinimum(Calendar.MONTH) == i) + { + inputs[isNthMonthInput[i]] = 1; + } + } + + //Set weekday + for(int i = 0; i < isNthWeekDayInput.length; i++) + { + if(cal.get(Calendar.DAY_OF_WEEK) - cal.getMinimum(Calendar.DAY_OF_WEEK) == i) + { + inputs[isNthMonthInput[i]] = 1; + } + } + + //Set day + int hourOfDay = cal.get(Calendar.HOUR_OF_DAY); + if(hourOfDay > 6 && hourOfDay < 12) + { + inputs[isMorning] = 1; + }else if(hourOfDay >= 12 && hourOfDay <= 6) + { + inputs[isAfternoon] = 1; + }else if(hourOfDay >= 6 && hourOfDay < 23) + { + inputs[isEvening] = 1; + }else if(hourOfDay >= 23 || hourOfDay <= 6) + { + inputs[isNight] = 1; + } + + for(String category : item.getCategory()) + { + inputs[categoryInputs.get(category.toLowerCase())] = 1; + } + + return nn.computeOutput(inputs); + } + + /** + * Provides feedback to the neural network. + * @param item The feeditem. + * @param feedback The feedback. Like will move these types of items up in the list, + * dislike will move them down. + */ + public void Feedback(FeedItem item, Feedback feedback) + { + PredictionInterface prediction = getPrediction(item); + switch(feedback) + { + case Like: + prediction.learn(1); + break; + case Dislike: + prediction.learn(-1); + break; + default: + throw new IllegalArgumentException("feedback"); + } + } + + /** + * Returns a sorted list of all the items in the List, according to the neural network. + * @param items The list of items. + * @return A new, sorted, list of items. The parameter items is not modified. + */ + public List sortItems(List items) { + // Sort list based on something like date + nn.computeOutput() * DAY. + List newItems = new ArrayList(items); + final Hashtable predictions = new Hashtable<>(); + + for(FeedItem feed : newItems) + { + predictions.put(feed, getPrediction(feed)); + } + + Collections.sort(newItems, new Comparator() { + @Override + public int compare(FeedItem lhs, FeedItem rhs) { + PredictionInterface lPrediction = predictions.get(lhs), + rPrediction = predictions.get(rhs); + + long lhsSeconds = (long)(lhs.getPubDate().getTime() / 1000 + lPrediction.getOutput() * SECONDS_IN_DAY); + long rhsSeconds = (long)(rhs.getPubDate().getTime() / 1000 + rPrediction.getOutput() * SECONDS_IN_DAY); + + return (int)Math.signum(lhsSeconds - rhsSeconds); + } + }); + + return newItems; + } } diff --git a/app/src/main/java/org/rssin/neurons/Feedback.java b/app/src/main/java/org/rssin/neurons/Feedback.java new file mode 100755 index 0000000..af5f1b3 --- /dev/null +++ b/app/src/main/java/org/rssin/neurons/Feedback.java @@ -0,0 +1,9 @@ +package org.rssin.neurons; + +/** + * Created by Jos on 19-5-2015. + */ +public enum Feedback { + Like, + Dislike +} diff --git a/app/src/main/java/org/rssin/neurons/MultiNeuralNetwork.java b/app/src/main/java/org/rssin/neurons/MultiNeuralNetwork.java index 492f67c..50fa707 100755 --- a/app/src/main/java/org/rssin/neurons/MultiNeuralNetwork.java +++ b/app/src/main/java/org/rssin/neurons/MultiNeuralNetwork.java @@ -3,7 +3,7 @@ package org.rssin.neurons; /** * Created by Jos on 14-5-2015. */ -public class MultiNeuralNetwork { +class MultiNeuralNetwork { private NeuralNetwork[] networks; public MultiNeuralNetwork(int numNetworks, int numHiddenNodes) { diff --git a/app/src/main/java/org/rssin/neurons/MultiNeuralNetworkPrediction.java b/app/src/main/java/org/rssin/neurons/MultiNeuralNetworkPrediction.java index 06164d0..8df99e5 100755 --- a/app/src/main/java/org/rssin/neurons/MultiNeuralNetworkPrediction.java +++ b/app/src/main/java/org/rssin/neurons/MultiNeuralNetworkPrediction.java @@ -3,7 +3,7 @@ package org.rssin.neurons; /** * Created by Jos on 14-5-2015. */ -public class MultiNeuralNetworkPrediction implements PredictionInterface { +class MultiNeuralNetworkPrediction implements PredictionInterface { private PredictionInterface[] predictions; MultiNeuralNetworkPrediction(PredictionInterface[] predictions) { diff --git a/app/src/main/java/org/rssin/neurons/NeuralNetwork.java b/app/src/main/java/org/rssin/neurons/NeuralNetwork.java index d761e35..7c2e447 100755 --- a/app/src/main/java/org/rssin/neurons/NeuralNetwork.java +++ b/app/src/main/java/org/rssin/neurons/NeuralNetwork.java @@ -3,7 +3,7 @@ package org.rssin.neurons; /** * Created by Jos on 14-5-2015. */ -public class NeuralNetwork { +class NeuralNetwork { private Neuron[] hiddenNodes; private Neuron outputNode; @@ -25,7 +25,7 @@ public class NeuralNetwork { public int addInput() { int result = 0; for (int i = 0; i < hiddenNodes.length; i++) { - result = hiddenNodes[i].AddWeight(); + result = hiddenNodes[i].addWeight(); } return result; diff --git a/app/src/main/java/org/rssin/neurons/NeuralNetworkPrediction.java b/app/src/main/java/org/rssin/neurons/NeuralNetworkPrediction.java index cd34c8e..162ba21 100755 --- a/app/src/main/java/org/rssin/neurons/NeuralNetworkPrediction.java +++ b/app/src/main/java/org/rssin/neurons/NeuralNetworkPrediction.java @@ -3,7 +3,7 @@ package org.rssin.neurons; /** * Created by Jos on 14-5-2015. */ -public class NeuralNetworkPrediction implements PredictionInterface { +class NeuralNetworkPrediction implements PredictionInterface { private double[] inputs; private double[] intermediateValues; private double output; diff --git a/app/src/main/java/org/rssin/neurons/PredictionInterface.java b/app/src/main/java/org/rssin/neurons/PredictionInterface.java index d2c04b9..e130f4d 100755 --- a/app/src/main/java/org/rssin/neurons/PredictionInterface.java +++ b/app/src/main/java/org/rssin/neurons/PredictionInterface.java @@ -3,7 +3,7 @@ package org.rssin.neurons; /** * Created by Jos on 14-5-2015. */ -public interface PredictionInterface { +interface PredictionInterface { public double getOutput(); public void learn(double expectedOutput); } -- cgit v1.2.3