diff options
Diffstat (limited to 'app/src/main')
7 files changed, 351 insertions, 0 deletions
diff --git a/app/src/main/java/org/rssin/neurons/FeedSorter.java b/app/src/main/java/org/rssin/neurons/FeedSorter.java new file mode 100755 index 0000000..fee6f4d --- /dev/null +++ b/app/src/main/java/org/rssin/neurons/FeedSorter.java @@ -0,0 +1,95 @@ +package org.rssin.neurons;
+
+import java.util.Calendar;
+import java.util.TimeZone;
+
+/**
+ * Created by Jos on 14-5-2015.
+ */
+public class FeedSorter {
+ private MultiNeuralNetwork nn = new MultiNeuralNetwork(25, 50);
+
+ private int[] isNthMonthInput = new int[12];
+ private int[] isNthWeekDayInput = new int[7];
+ private int isMorning, isAfternoon, isEvening, isNight;
+ private Hashtable<String, int> categoryInputs = new Hashtable<String, int>();
+ private Hashtable<String, int> wordInputs = new Hashtable<String, int>();
+ private Hashtable<String, int> feedSourceInputs = new Hashtable<String, int>();
+
+ public FeedSorter() {
+ //TODO: Load Neural Network
+ createNewNetwork();
+ }
+
+ private void createNewNetwork() {
+ for(int i = 0; i < 12; i++)
+ {
+ isNthMonthInput[i] = nn.addInput();
+ }
+
+ for(int i = 0; i < 7; i++)
+ {
+ isNthWeekDayInput[i] = nn.addInput();
+ }
+
+ isMorning = nn.addInput();
+ isAfternoon = nn.addInput();
+ isEvening = nn.addInput();
+ 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<FeedItem> sortItems(List<FeedItem> items) {
+ // Sort list based on something like date + nn.computeOutput() * DAY.
+ throw new NotImplementedException();
+ return items;
+ }
+}
diff --git a/app/src/main/java/org/rssin/neurons/MultiNeuralNetwork.java b/app/src/main/java/org/rssin/neurons/MultiNeuralNetwork.java new file mode 100755 index 0000000..492f67c --- /dev/null +++ b/app/src/main/java/org/rssin/neurons/MultiNeuralNetwork.java @@ -0,0 +1,38 @@ +package org.rssin.neurons;
+
+/**
+ * Created by Jos on 14-5-2015.
+ */
+public class MultiNeuralNetwork {
+ private NeuralNetwork[] networks;
+
+ public MultiNeuralNetwork(int numNetworks, int numHiddenNodes) {
+ networks = new NeuralNetwork[numNetworks];
+ for (int i = 0; i < networks.length; i++) {
+ networks[i] = new NeuralNetwork(numHiddenNodes);
+ }
+ }
+
+ public int addInput() {
+ int id = 0;
+ for (NeuralNetwork network : networks) {
+ id = network.addInput();
+ }
+
+ return id;
+ }
+
+ public PredictionInterface computeOutput(double[] inputs) {
+ PredictionInterface[] predictions = new PredictionInterface[networks.length];
+ for(int i = 0; i < predictions.length; i++)
+ {
+ predictions[i] = networks[i].computeOutput(inputs);
+ }
+
+ return new MultiNeuralNetworkPrediction(predictions);
+ }
+
+ public int getInputCount() {
+ return networks[0].getInputCount();
+ }
+}
diff --git a/app/src/main/java/org/rssin/neurons/MultiNeuralNetworkPrediction.java b/app/src/main/java/org/rssin/neurons/MultiNeuralNetworkPrediction.java new file mode 100755 index 0000000..06164d0 --- /dev/null +++ b/app/src/main/java/org/rssin/neurons/MultiNeuralNetworkPrediction.java @@ -0,0 +1,30 @@ +package org.rssin.neurons;
+
+/**
+ * Created by Jos on 14-5-2015.
+ */
+public class MultiNeuralNetworkPrediction implements PredictionInterface {
+ private PredictionInterface[] predictions;
+ MultiNeuralNetworkPrediction(PredictionInterface[] predictions)
+ {
+ this.predictions = predictions;
+ }
+
+ public double getOutput()
+ {
+ double average = 0;
+ for (PredictionInterface prediction : predictions) {
+ average += prediction.getOutput();
+ }
+
+ return average / (double) predictions.length;
+ }
+
+ public void learn(double expectedOutput)
+ {
+ for(PredictionInterface prediction : predictions)
+ {
+ prediction.learn(expectedOutput);
+ }
+ }
+}
diff --git a/app/src/main/java/org/rssin/neurons/NeuralNetwork.java b/app/src/main/java/org/rssin/neurons/NeuralNetwork.java new file mode 100755 index 0000000..d761e35 --- /dev/null +++ b/app/src/main/java/org/rssin/neurons/NeuralNetwork.java @@ -0,0 +1,105 @@ +package org.rssin.neurons;
+
+/**
+ * Created by Jos on 14-5-2015.
+ */
+public class NeuralNetwork {
+ private Neuron[] hiddenNodes;
+ private Neuron outputNode;
+
+ public NeuralNetwork(int numHiddenNodes) {
+ if(numHiddenNodes < 1)
+ {
+ throw new IllegalArgumentException("numHiddenNodes must be > 0");
+ }
+
+ hiddenNodes = new Neuron[numHiddenNodes];
+
+ for (int i = 0; i < hiddenNodes.length; i++) {
+ hiddenNodes[i] = new Neuron();
+ }
+
+ outputNode = new Neuron(numHiddenNodes + 1);
+ }
+
+ public int addInput() {
+ int result = 0;
+ for (int i = 0; i < hiddenNodes.length; i++) {
+ result = hiddenNodes[i].AddWeight();
+ }
+
+ return result;
+ }
+
+ public PredictionInterface computeOutput(double[] inputs) {
+ double[] intermediateValues = new double[outputNode.getWeightCount()];
+
+ for (int neuronNum = 0; neuronNum < hiddenNodes.length; neuronNum++) {
+ Neuron n = hiddenNodes[neuronNum];
+
+ double neuronOutput = 0;
+ for (int i = 0; i < n.getWeightCount(); i++) {
+ neuronOutput += n.getWeight(i) * inputs[i];
+ }
+
+ intermediateValues[neuronNum] = HyperTan(neuronOutput);
+ }
+
+ double result = 0;
+ for (int neuronNum = 0; neuronNum < intermediateValues.length; neuronNum++) {
+ result += intermediateValues[neuronNum] * outputNode.getWeight(neuronNum);
+ }
+
+ return new NeuralNetworkPrediction(this, inputs, intermediateValues, HyperTan(result));
+ }
+
+ void learn(NeuralNetworkPrediction p, double expectedOutput) {
+ double actualOutput = p.getOutput();
+ double[] intermediateValues = p.getIntermediateValues();
+ double[] inputs = p.getInputs();
+
+ double[] hiddenGradients = new double[hiddenNodes.length];
+
+ //Calculate output gradients
+ double outputDerivative = (1 - actualOutput) * (1 + actualOutput);
+
+ //Derivative of HyperTan function
+ double outputGradient = outputDerivative * (expectedOutput - actualOutput);
+
+ //Calulate hidden gradients
+ for (int i = 0; i < hiddenGradients.length; i++) {
+ //Derivative of HyperTan function
+ double hiddenDerivative = (1 - intermediateValues[i]) * (1 + intermediateValues[i]);
+ hiddenGradients[i] = hiddenDerivative * outputGradient * outputNode.getWeight(i);
+ }
+
+ //Update input => hidden weights.
+ final double learningRate = 0.3;
+ for (int neuronNum = 0; neuronNum < hiddenNodes.length; neuronNum++) {
+ Neuron n = hiddenNodes[neuronNum];
+
+ for (int i = 0; i < n.getWeightCount(); i++) {
+ //Calulate & apply delta
+ double delta = learningRate * hiddenGradients[neuronNum] * inputs[i];
+ n.adjustWeight(i, delta);
+ }
+ }
+
+ //Update hidden => output weights.
+ for (int i = 0; i < outputNode.getWeightCount(); i++) {
+ //Calulate & apply delta
+ double delta = learningRate * outputGradient * intermediateValues[i];
+ outputNode.adjustWeight(i, delta);
+ }
+ }
+
+ private static double HyperTan(double x) {
+ if (x < -10.0) return -1.0;
+ else if (x > 10.0) return 1.0;
+ else return Math.tanh(x);
+ }
+
+ public int getInputCount() {
+ return hiddenNodes[0].getWeightCount();
+ }
+}
diff --git a/app/src/main/java/org/rssin/neurons/NeuralNetworkPrediction.java b/app/src/main/java/org/rssin/neurons/NeuralNetworkPrediction.java new file mode 100755 index 0000000..cd34c8e --- /dev/null +++ b/app/src/main/java/org/rssin/neurons/NeuralNetworkPrediction.java @@ -0,0 +1,34 @@ +package org.rssin.neurons;
+
+/**
+ * Created by Jos on 14-5-2015.
+ */
+public class NeuralNetworkPrediction implements PredictionInterface {
+ private double[] inputs;
+ private double[] intermediateValues;
+ private double output;
+ private NeuralNetwork nn;
+
+ NeuralNetworkPrediction(NeuralNetwork nn, double[] inputs, double[] intermediateValues, double output) {
+ this.inputs = inputs;
+ this.intermediateValues = intermediateValues;
+ this.output = output;
+ this.nn = nn;
+ }
+
+ double[] getInputs() {
+ return inputs;
+ }
+
+ double[] getIntermediateValues() {
+ return intermediateValues;
+ }
+
+ public double getOutput() {
+ return output;
+ }
+
+ public void learn(double expectedOutput) {
+ nn.learn(this, expectedOutput);
+ }
+}
diff --git a/app/src/main/java/org/rssin/neurons/Neuron.java b/app/src/main/java/org/rssin/neurons/Neuron.java new file mode 100755 index 0000000..5df9d47 --- /dev/null +++ b/app/src/main/java/org/rssin/neurons/Neuron.java @@ -0,0 +1,40 @@ +package org.rssin.neurons;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+/**
+ * Created by Jos on 14-5-2015.
+ */
+class Neuron {
+ private static Random r = new Random();
+
+ private List<Double> weights = new ArrayList<Double>();
+
+ public Neuron() {
+ }
+
+ public Neuron(int numWeights) {
+ for (int i = 0; i < numWeights; i++) {
+ addWeight();
+ }
+ }
+
+ public int addWeight() {
+ weights.add(r.nextDouble() * 2 - 1);
+ return weights.size() - 1;
+ }
+
+ public double getWeight(int i) {
+ return weights.get(i);
+ }
+
+ public void adjustWeight(int i, double delta) {
+ weights.set(i, weights.get(i) + delta);
+ }
+
+ public int getWeightCount() {
+ return weights.size();
+ }
+}
diff --git a/app/src/main/java/org/rssin/neurons/PredictionInterface.java b/app/src/main/java/org/rssin/neurons/PredictionInterface.java new file mode 100755 index 0000000..d2c04b9 --- /dev/null +++ b/app/src/main/java/org/rssin/neurons/PredictionInterface.java @@ -0,0 +1,9 @@ +package org.rssin.neurons;
+
+/**
+ * Created by Jos on 14-5-2015.
+ */
+public interface PredictionInterface {
+ public double getOutput();
+ public void learn(double expectedOutput);
+}
|