Skip to content

Commit ac35503

Browse files
committed
More time series with EncogModel
1 parent c31f8ad commit ac35503

8 files changed

Lines changed: 219 additions & 31 deletions

File tree

src/main/java/org/encog/ml/data/versatile/NormalizationHelper.java

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -129,26 +129,14 @@ public int calculateNormalizedOutputCount() {
129129

130130
return normalizedOutputColumns;
131131
}
132-
133132
public MLData allocateInputVector() {
134-
return new BasicMLData(calculateNormalizedInputCount());
133+
return allocateInputVector(1);
135134
}
136-
public void normalizeInputVector(String[] line, MLData inputVector, boolean originalOrder) {
137-
int outputIndex=0;
138-
int i = 0;
139-
for(ColumnDefinition colDef: this.inputColumns) {
140-
int idx;
141-
142-
if( originalOrder ) {
143-
idx = this.sourceColumns.indexOf(colDef);
144-
} else {
145-
idx = i;
146-
}
147-
outputIndex = normalizeToVector(colDef, outputIndex, inputVector.getData(), false, line[idx]);
148-
i++;
149-
}
150-
135+
136+
public MLData allocateInputVector(int multiplier) {
137+
return new BasicMLData(calculateNormalizedInputCount()*multiplier);
151138
}
139+
152140
public String[] denormalizeOutputVectorToString(MLData output) {
153141
String[] result = new String[this.outputColumns.size()];
154142

@@ -222,6 +210,20 @@ public void defineMissingHandler(ColumnDefinition colDef, MissingHandler handler
222210
this.missingHandlers.put(colDef, handler);
223211
handler.init(this);
224212
}
225-
226-
213+
public void normalizeInputVector(String[] line, double[] data,
214+
boolean originalOrder) {
215+
int outputIndex=0;
216+
int i = 0;
217+
for(ColumnDefinition colDef: this.inputColumns) {
218+
int idx;
219+
220+
if( originalOrder ) {
221+
idx = this.sourceColumns.indexOf(colDef);
222+
} else {
223+
idx = i;
224+
}
225+
outputIndex = normalizeToVector(colDef, outputIndex, data, false, line[idx]);
226+
i++;
227+
}
228+
}
227229
}

src/main/java/org/encog/ml/data/versatile/PerformDataDivision.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,24 @@ public PerformDataDivision(boolean theShuffle, GenerateRandom theRandom) {
1313
this.rnd = theRandom;
1414
}
1515

16-
public void perform(List<DataDivision> dataDivisionList, double[][] data,
16+
public void perform(List<DataDivision> dataDivisionList, VersatileMLDataSet dataset,
1717
int inputCount, int idealCount) {
18-
generateCounts(dataDivisionList, data.length);
18+
generateCounts(dataDivisionList, dataset.getData().length);
1919
generateMasks(dataDivisionList);
2020
if (this.shuffle) {
21-
performShuffle(dataDivisionList, data.length);
21+
performShuffle(dataDivisionList, dataset.getData().length);
2222
}
23-
createDividedDatasets(dataDivisionList, data, inputCount, idealCount);
23+
createDividedDatasets(dataDivisionList, dataset, inputCount, idealCount);
2424

2525
}
2626

2727
private void createDividedDatasets(List<DataDivision> dataDivisionList,
28-
double[][] data, int inputCount, int idealCount) {
28+
VersatileMLDataSet parentDataset, int inputCount, int idealCount) {
2929
for (DataDivision division : dataDivisionList) {
30-
MatrixMLDataSet dataset = new MatrixMLDataSet(data, inputCount,
30+
MatrixMLDataSet dataset = new MatrixMLDataSet(parentDataset.getData(), inputCount,
3131
idealCount, division.getMask());
32+
dataset.setLagWindowSize(parentDataset.getLagWindowSize());
33+
dataset.setLeadWindowSize(parentDataset.getLeadWindowSize());
3234
division.setDataset(dataset);
3335
}
3436
}

src/main/java/org/encog/ml/data/versatile/VersatileMLDataSet.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ public void divide(List<DataDivision> dataDivisionList, boolean shuffle,
149149
}
150150

151151
PerformDataDivision divide = new PerformDataDivision(shuffle, rnd);
152-
divide.perform(dataDivisionList, getData(), getCalculatedInputSize(),
152+
divide.perform(dataDivisionList, this, getCalculatedInputSize(),
153153
getCalculatedIdealSize());
154154

155155
}

src/main/java/org/encog/ml/model/EncogModel.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -276,9 +276,4 @@ public StatusReportable getReport() {
276276
public void setReport(StatusReportable report) {
277277
this.report = report;
278278
}
279-
280-
281-
282-
283-
284279
}

src/main/java/org/encog/ml/train/strategy/end/SimpleEarlyStoppingStrategy.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@
2727
import org.encog.ml.data.MLDataSet;
2828
import org.encog.ml.train.MLTrain;
2929

30+
/**
31+
* A simple early stopping strategy that halts training when the validation set no longer improves.
32+
*/
3033
public class SimpleEarlyStoppingStrategy implements EndTrainingStrategy {
3134
/**
3235
* The validation set.
@@ -135,6 +138,9 @@ public double getTrainingError() {
135138
}
136139

137140

141+
/**
142+
* @return The validation error.
143+
*/
138144
public double getValidationError() {
139145
return this.lastValidationError;
140146
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package org.encog.util.arrayutil;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
6+
import org.encog.EncogError;
7+
import org.encog.util.EngineArray;
8+
9+
/**
10+
* Create a sliding window of double arrays. New vectors can be added to the
11+
* window. Once the required number of vectors have been added then the entire
12+
* window can be copied to an output vector large enough to hold it.
13+
*/
14+
public class VectorWindow {
15+
16+
/**
17+
* The window.
18+
*/
19+
private final List<double[]> window = new ArrayList<double[]>();
20+
21+
/**
22+
* The number of slices in a window.
23+
*/
24+
private final int sliceCount;
25+
26+
/**
27+
* Construct a sliding window.
28+
* @param theSliceCount The number of slices in a window.
29+
*/
30+
public VectorWindow(int theSliceCount) {
31+
this.sliceCount = theSliceCount;
32+
}
33+
34+
/**
35+
* Add a single vector to the window.
36+
* @param vec The vector to add to the window.
37+
*/
38+
public void add(double[] vec) {
39+
this.window.add(vec.clone());
40+
while (this.window.size() > this.sliceCount) {
41+
this.window.remove(0);
42+
}
43+
}
44+
45+
/**
46+
* @return True, if we've added enough slices for a complete window.
47+
*/
48+
public boolean isReady() {
49+
return this.window.size() >= this.sliceCount;
50+
}
51+
52+
/**
53+
* Copy the entire window to a complete vector.
54+
* @param output The vector to copy to.
55+
* @param startPos The starting position to write to.
56+
*/
57+
public void copyWindow(double[] output, int startPos) {
58+
if (!isReady()) {
59+
throw new EncogError("Can't produce a timeslice of size "
60+
+ this.sliceCount + ", there are only "
61+
+ this.window.size() + " vectors loaded.");
62+
}
63+
64+
int currentIndex = startPos;
65+
for (int i = 0; i < this.window.size(); i++) {
66+
double[] source = this.window.get(i);
67+
EngineArray.arrayCopy(source, 0, output, currentIndex,
68+
source.length);
69+
currentIndex += source.length;
70+
}
71+
}
72+
}

src/main/java/org/encog/util/simple/EncogUtility.java

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
import org.encog.ml.data.buffer.codec.CSVDataCODEC;
4848
import org.encog.ml.data.buffer.codec.DataSetCODEC;
4949
import org.encog.ml.data.specific.CSVNeuralDataSet;
50+
import org.encog.ml.data.versatile.MatrixMLDataSet;
5051
import org.encog.ml.svm.SVM;
5152
import org.encog.ml.svm.training.SVMTrain;
5253
import org.encog.ml.train.MLTrain;
@@ -462,4 +463,72 @@ public static void saveEGB(File f, MLDataSet data) {
462463
binary.load(data);
463464
data.close();
464465
}
466+
467+
public static void explainErrorMSE(MLRegression method,
468+
MatrixMLDataSet training) {
469+
StringBuilder line = new StringBuilder();
470+
double sum = 0;
471+
int count = 0;
472+
int itemNum = 0;
473+
474+
for (final MLDataPair pair : training) {
475+
final MLData output = method.compute(pair.getInput());
476+
double dsum = 0;
477+
for(int i=0;i<output.size();i++) {
478+
double diff = output.getData()[i] - pair.getIdeal().getData(i);
479+
dsum+=diff*diff;
480+
count++;
481+
}
482+
sum+=dsum;
483+
484+
line.setLength(0);
485+
line.append("Item #");
486+
line.append(itemNum++);
487+
line.append(", Actual=");
488+
line.append(EncogUtility.formatNeuralData(output));
489+
line.append(", Ideal=");
490+
line.append(EncogUtility.formatNeuralData(pair.getIdeal()));
491+
line.append(", Delta=");
492+
line.append(Format.formatDouble(dsum, 4));
493+
line.append(", Count=");
494+
line.append(count);
495+
line.append(", MSE=");
496+
line.append(Format.formatDouble(sum/count, 4));
497+
System.out.println(line.toString());
498+
}
499+
}
500+
501+
public static void explainErrorRMS(MLRegression method,
502+
MatrixMLDataSet training) {
503+
StringBuilder line = new StringBuilder();
504+
double sum = 0;
505+
int count = 0;
506+
int itemNum = 0;
507+
508+
for (final MLDataPair pair : training) {
509+
final MLData output = method.compute(pair.getInput());
510+
double dsum = 0;
511+
for(int i=0;i<output.size();i++) {
512+
double diff = output.getData()[i] - pair.getIdeal().getData(i);
513+
dsum+=diff*diff;
514+
count++;
515+
}
516+
sum+=dsum;
517+
518+
line.setLength(0);
519+
line.append("Item #");
520+
line.append(itemNum++);
521+
line.append(", Actual=");
522+
line.append(EncogUtility.formatNeuralData(output));
523+
line.append(", Ideal=");
524+
line.append(EncogUtility.formatNeuralData(pair.getIdeal()));
525+
line.append(", Delta=");
526+
line.append(Format.formatDouble(dsum, 4));
527+
line.append(", Count=");
528+
line.append(count);
529+
line.append(", RMS=");
530+
line.append(Format.formatDouble(Math.sqrt(sum/count), 4));
531+
System.out.println(line.toString());
532+
}
533+
}
465534
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package org.encog.util.arrayutil;
2+
3+
import org.encog.Encog;
4+
import org.encog.EncogError;
5+
import org.junit.Assert;
6+
import org.junit.Test;
7+
8+
public class TestVectorWindow {
9+
@Test(expected=EncogError.class)
10+
public void testIncomplete() {
11+
double[] o = new double[1];
12+
VectorWindow window = new VectorWindow(3);
13+
window.add(new double[] {1});
14+
window.copyWindow(o, 0);
15+
}
16+
17+
@Test
18+
public void testComplete() {
19+
final double[] expect = {1.0, 2.0, 3.0};
20+
double[] o = new double[3];
21+
VectorWindow window = new VectorWindow(3);
22+
window.add(new double[] {1});
23+
window.add(new double[] {2});
24+
window.add(new double[] {3});
25+
window.copyWindow(o, 0);
26+
Assert.assertArrayEquals(expect,o,Encog.DEFAULT_DOUBLE_EQUAL);
27+
}
28+
29+
@Test
30+
public void testCompleteScroll() {
31+
final double[] expect = {2.0, 3.0, 4.0};
32+
double[] o = new double[3];
33+
VectorWindow window = new VectorWindow(3);
34+
window.add(new double[] {1});
35+
window.add(new double[] {2});
36+
window.add(new double[] {3});
37+
window.add(new double[] {4});
38+
window.copyWindow(o, 0);
39+
Assert.assertArrayEquals(expect,o,Encog.DEFAULT_DOUBLE_EQUAL);
40+
}
41+
42+
}

0 commit comments

Comments
 (0)