@@ -25,11 +25,11 @@ class NeuralNetworkData {
25
25
// methods
26
26
// summarize data
27
27
this . createMetadata = this . createMetadata . bind ( this ) ;
28
- this . getDataStats = this . getDataStats . bind ( this ) ;
28
+ this . setDataStats = this . setDataStats . bind ( this ) ;
29
29
this . getInputMetaStats = this . getInputMetaStats . bind ( this ) ;
30
- this . getDataUnits = this . getDataUnits . bind ( this ) ;
31
- this . getInputMetaUnits = this . getInputMetaUnits . bind ( this ) ;
32
- this . getDTypesFromData = this . getDTypesFromData . bind ( this ) ;
30
+ this . setDataUnits = this . setDataUnits . bind ( this ) ;
31
+ this . setInputMetaUnits = this . setInputMetaUnits . bind ( this ) ;
32
+ this . setDTypesFromData = this . setDTypesFromData . bind ( this ) ;
33
33
// add data
34
34
this . addData = this . addData . bind ( this ) ;
35
35
// data conversion
@@ -41,7 +41,7 @@ class NeuralNetworkData {
41
41
this . unnormalizeArray = this . unnormalizeArray . bind ( this ) ;
42
42
// one hot
43
43
this . applyOneHotEncodingsToDataRaw = this . applyOneHotEncodingsToDataRaw . bind ( this ) ;
44
- this . getDataOneHot = this . getDataOneHot . bind ( this ) ;
44
+ this . setDataOneHot = this . setDataOneHot . bind ( this ) ;
45
45
this . getInputMetaOneHot = this . getInputMetaOneHot . bind ( this ) ;
46
46
this . createOneHotEncodings = this . createOneHotEncodings . bind ( this ) ;
47
47
// Saving / loading data
@@ -66,25 +66,22 @@ class NeuralNetworkData {
66
66
* 2. getting the min and max from the data
67
67
* 3. getting the oneHot encoded values
68
68
* 4. getting the inputShape and outputUnits from the data
69
- * @param {* } dataRaw
70
- * @param {* } inputShape
71
- * TODO: don't need to pass around dataRaw as an argument
69
+ * @param {number[] } [inputShape]
72
70
*/
73
- createMetadata ( dataRaw , inputShape = null ) {
74
- if ( ! dataRaw . length ) {
71
+ createMetadata ( inputShape = null ) {
72
+ if ( ! this . data . raw . length ) {
75
73
throw new Error ( 'Cannot create metadata because no data has been added.' ) ;
76
74
}
77
75
// get the data type for each property
78
- this . getDTypesFromData ( dataRaw ) ;
76
+ this . setDTypesFromData ( ) ;
79
77
// get the stats - min, max
80
- this . getDataStats ( dataRaw ) ;
78
+ this . setDataStats ( ) ;
81
79
// onehot encode
82
- this . getDataOneHot ( dataRaw ) ;
80
+ this . setDataOneHot ( ) ;
83
81
// calculate the input units from the data
84
- this . getDataUnits ( dataRaw , inputShape ) ;
82
+ this . setDataUnits ( inputShape ) ;
85
83
86
84
this . isMetadataReady = true ;
87
- return { ...this . meta } ;
88
85
}
89
86
90
87
/*
@@ -94,47 +91,35 @@ class NeuralNetworkData {
94
91
*/
95
92
96
93
/**
94
+ * @private
97
95
* get stats about the data
98
- * @param {* } dataRaw
99
96
*/
100
- getDataStats ( dataRaw ) {
101
- const meta = Object . assign ( { } , this . meta ) ;
102
-
103
- const inputMeta = this . getInputMetaStats ( dataRaw , meta . inputs , 'xs' ) ;
104
- const outputMeta = this . getInputMetaStats ( dataRaw , meta . outputs , 'ys' ) ;
105
-
106
- meta . inputs = inputMeta ;
107
- meta . outputs = outputMeta ;
108
-
109
- this . meta = {
110
- ...this . meta ,
111
- ...meta ,
112
- } ;
113
-
114
- return meta ;
97
+ setDataStats ( ) {
98
+ // TODO: I don't like that this overwrites the existing value -Linda
99
+ this . meta . inputs = this . getInputMetaStats ( this . meta . inputs , 'xs' ) ;
100
+ this . meta . outputs = this . getInputMetaStats ( this . meta . outputs , 'ys' ) ;
115
101
}
116
102
117
103
/**
104
+ * @private
118
105
* getRawStats
119
106
* get back the min and max of each label
120
- * @param {* } dataRaw
121
107
* @param {* } inputOrOutputMeta
122
108
* @param {* } xsOrYs
123
109
*/
124
- // eslint-disable-next-line no-unused-vars, class-methods-use-this
125
- getInputMetaStats ( dataRaw , inputOrOutputMeta , xsOrYs ) {
110
+ getInputMetaStats ( inputOrOutputMeta , xsOrYs ) {
126
111
const inputMeta = Object . assign ( { } , inputOrOutputMeta ) ;
127
112
128
113
Object . keys ( inputMeta ) . forEach ( k => {
129
114
if ( inputMeta [ k ] . dtype === 'string' ) {
130
115
inputMeta [ k ] . min = 0 ;
131
116
inputMeta [ k ] . max = 1 ;
132
117
} else if ( inputMeta [ k ] . dtype === 'number' ) {
133
- const dataAsArray = dataRaw . map ( item => item [ xsOrYs ] [ k ] ) ;
118
+ const dataAsArray = this . data . raw . map ( item => item [ xsOrYs ] [ k ] ) ;
134
119
inputMeta [ k ] . min = nnUtils . getMin ( dataAsArray ) ;
135
120
inputMeta [ k ] . max = nnUtils . getMax ( dataAsArray ) ;
136
121
} else if ( inputMeta [ k ] . dtype === 'array' ) {
137
- const dataAsArray = dataRaw . map ( item => item [ xsOrYs ] [ k ] ) . flat ( ) ;
122
+ const dataAsArray = this . data . raw . map ( item => item [ xsOrYs ] [ k ] ) . flat ( ) ;
138
123
inputMeta [ k ] . min = nnUtils . getMin ( dataAsArray ) ;
139
124
inputMeta [ k ] . max = nnUtils . getMax ( dataAsArray ) ;
140
125
}
@@ -144,41 +129,23 @@ class NeuralNetworkData {
144
129
}
145
130
146
131
/**
132
+ * @private
147
133
* get the data units, inputshape and output units
148
- * @param {* } dataRaw
134
+ * @param {* } arrayShape
149
135
*/
150
- getDataUnits ( dataRaw , _arrayShape = null ) {
151
- const arrayShape = _arrayShape !== null ? _arrayShape : undefined ;
152
- const meta = Object . assign ( { } , this . meta ) ;
153
-
136
+ setDataUnits ( arrayShape ) {
154
137
// if the data has a shape pass it in
155
- let inputShape ;
156
- if ( arrayShape ) {
157
- inputShape = arrayShape ;
158
- } else {
159
- inputShape = [ this . getInputMetaUnits ( dataRaw , meta . inputs ) ] . flat ( ) ;
160
- }
161
-
162
- const outputShape = this . getInputMetaUnits ( dataRaw , meta . outputs ) ;
163
-
164
- meta . inputUnits = inputShape ;
165
- meta . outputUnits = outputShape ;
166
-
167
- this . meta = {
168
- ...this . meta ,
169
- ...meta ,
170
- } ;
171
-
172
- return meta ;
138
+ this . meta . inputUnits = arrayShape ?? [ this . setInputMetaUnits ( this . meta . inputs ) ] . flat ( ) ;
139
+ this . meta . outputUnits = this . setInputMetaUnits ( this . meta . outputs ) ;
173
140
}
174
141
175
142
/**
143
+ * @private
176
144
* get input
177
145
* @param {* } _inputsMeta
178
- * @param {* } _dataRaw
179
146
*/
180
- // eslint-disable-next-line class-methods-use-this, no-unused-vars
181
- getInputMetaUnits ( _dataRaw , _inputsMeta ) {
147
+ // eslint-disable-next-line class-methods-use-this
148
+ setInputMetaUnits ( _inputsMeta ) {
182
149
let units = 0 ;
183
150
const inputsMeta = Object . assign ( { } , _inputsMeta ) ;
184
151
@@ -202,18 +169,19 @@ class NeuralNetworkData {
202
169
}
203
170
204
171
/**
205
- * getDTypesFromData
172
+ * @private
173
+ * setDTypesFromData
206
174
* gets the data types of the data we're using
207
175
* important for handling oneHot
208
176
*/
209
- getDTypesFromData ( _dataRaw ) {
177
+ setDTypesFromData ( ) {
210
178
const meta = {
211
179
...this . meta ,
212
180
inputs : { } ,
213
181
outputs : { } ,
214
182
} ;
215
183
216
- const sample = _dataRaw [ 0 ] ;
184
+ const sample = this . data . raw [ 0 ] ;
217
185
const xs = Object . keys ( sample . xs ) ;
218
186
const ys = Object . keys ( sample . ys ) ;
219
187
@@ -233,8 +201,6 @@ class NeuralNetworkData {
233
201
// otherwise throw an error
234
202
235
203
this . meta = meta ;
236
-
237
- return meta ;
238
204
}
239
205
240
206
/**
@@ -244,6 +210,7 @@ class NeuralNetworkData {
244
210
*/
245
211
246
212
/**
213
+ * @public - used by nn
247
214
* Add Data
248
215
* @param {object } xInputObj, {key: value}, key must be the name of the property value must be a String, Number, or Array
249
216
* @param {* } yInputObj, {key: value}, key must be the name of the property value must be a String, Number, or Array
@@ -262,12 +229,13 @@ class NeuralNetworkData {
262
229
*/
263
230
264
231
/**
232
+ * @public - used by nn
265
233
* convertRawToTensors
266
234
* converts array of {xs, ys} to tensors
267
235
* @param {* } _dataRaw
268
236
* @param {* } meta
237
+ * TODO: requires the nn to pass in the training data as an argument -- why?
269
238
*/
270
- // eslint-disable-next-line class-methods-use-this, no-unused-vars
271
239
convertRawToTensors ( dataRaw ) {
272
240
const meta = Object . assign ( { } , this . meta ) ;
273
241
const dataLength = dataRaw . length ;
@@ -313,30 +281,24 @@ class NeuralNetworkData {
313
281
*/
314
282
315
283
/**
284
+ * @public - used by nn
316
285
* normalize the dataRaw input
317
- * @param {* } dataRaw
318
286
*/
319
- normalizeDataRaw ( dataRaw ) {
320
- const meta = Object . assign ( { } , this . meta ) ;
321
-
322
- const normXs = this . normalizeInputData ( dataRaw , meta . inputs , 'xs' ) ;
323
- const normYs = this . normalizeInputData ( dataRaw , meta . outputs , 'ys' ) ;
324
-
325
- const normalizedData = nnUtils . zipArrays ( normXs , normYs ) ;
287
+ normalizeDataRaw ( ) {
288
+ const normXs = this . normalizeInputData ( this . meta . inputs , 'xs' ) ;
289
+ const normYs = this . normalizeInputData ( this . meta . outputs , 'ys' ) ;
326
290
327
- return normalizedData ;
291
+ return nnUtils . zipArrays ( normXs , normYs ) ;
328
292
}
329
293
330
294
/**
331
- * normalizeRaws
332
- * @param {* } dataRaw
295
+ * @private
333
296
* @param {* } inputOrOutputMeta
334
297
* @param {* } xsOrYs
335
298
*/
336
- // eslint-disable-next-line no-unused-vars, class-methods-use-this
337
- normalizeInputData ( dataRaw , inputOrOutputMeta , xsOrYs ) {
299
+ normalizeInputData ( inputOrOutputMeta , xsOrYs ) {
338
300
// the data length
339
- const dataLength = dataRaw . length ;
301
+ const dataLength = this . data . raw . length ;
340
302
// the copy of the inputs.meta[inputOrOutput]
341
303
const inputMeta = Object . assign ( { } , inputOrOutputMeta ) ;
342
304
@@ -349,7 +311,7 @@ class NeuralNetworkData {
349
311
max : inputMeta [ k ] . max ,
350
312
} ;
351
313
352
- const dataAsArray = dataRaw . map ( item => item [ xsOrYs ] [ k ] ) ;
314
+ const dataAsArray = this . data . raw . map ( item => item [ xsOrYs ] [ k ] ) ;
353
315
// depending on the input type, normalize accordingly
354
316
if ( inputMeta [ k ] . dtype === 'string' ) {
355
317
options . legend = inputMeta [ k ] . legend ;
@@ -378,7 +340,7 @@ class NeuralNetworkData {
378
340
}
379
341
380
342
/**
381
- * normalizeArray
343
+ * @public - used by nn
382
344
* @param {* } _input
383
345
* @param {* } _options
384
346
*/
@@ -408,7 +370,7 @@ class NeuralNetworkData {
408
370
}
409
371
410
372
/**
411
- * unNormalizeArray
373
+ * @public but not used anywhere
412
374
* @param {* } _input
413
375
* @param {* } _options
414
376
*/
@@ -451,16 +413,17 @@ class NeuralNetworkData {
451
413
*/
452
414
453
415
/**
416
+ * @public - used by nn
454
417
* applyOneHotEncodingsToDataRaw
455
418
* does not set this.data.raws
456
419
* but rather returns them
457
420
* @param {* } _dataRaw
458
421
* @param {* } _meta
459
422
*/
460
- applyOneHotEncodingsToDataRaw ( dataRaw ) {
423
+ applyOneHotEncodingsToDataRaw ( ) {
461
424
const meta = Object . assign ( { } , this . meta ) ;
462
425
463
- const output = dataRaw . map ( row => {
426
+ const output = this . data . raw . map ( row => {
464
427
const xs = {
465
428
...row . xs ,
466
429
} ;
@@ -490,35 +453,21 @@ class NeuralNetworkData {
490
453
}
491
454
492
455
/**
493
- * getDataOneHot
456
+ * @private
494
457
* creates onehot encodings for the input and outputs
495
458
* and adds them to the meta info
496
- * @param {* } dataRaw
497
459
*/
498
- getDataOneHot ( dataRaw ) {
499
- const meta = Object . assign ( { } , this . meta ) ;
500
-
501
- const inputMeta = this . getInputMetaOneHot ( dataRaw , meta . inputs , 'xs' ) ;
502
- const outputMeta = this . getInputMetaOneHot ( dataRaw , meta . outputs , 'ys' ) ;
503
-
504
- meta . inputs = inputMeta ;
505
- meta . outputs = outputMeta ;
506
-
507
- this . meta = {
508
- ...this . meta ,
509
- ...meta ,
510
- } ;
511
-
512
- return meta ;
460
+ setDataOneHot ( ) {
461
+ this . meta . inputs = this . getInputMetaOneHot ( this . meta . inputs , 'xs' ) ;
462
+ this . meta . outputs = this . getInputMetaOneHot ( this . meta . outputs , 'ys' ) ;
513
463
}
514
464
515
465
/**
516
- * getOneHotMeta
466
+ * @private
517
467
* @param {* } _inputsMeta
518
- * @param {* } _dataRaw
519
468
* @param {* } xsOrYs
520
469
*/
521
- getInputMetaOneHot ( _dataRaw , _inputsMeta , xsOrYs ) {
470
+ getInputMetaOneHot ( _inputsMeta , xsOrYs ) {
522
471
const inputsMeta = Object . assign ( { } , _inputsMeta ) ;
523
472
524
473
Object . entries ( inputsMeta ) . forEach ( arr => {
@@ -528,7 +477,7 @@ class NeuralNetworkData {
528
477
const { dtype } = arr [ 1 ] ;
529
478
530
479
if ( dtype === 'string' ) {
531
- const uniqueVals = [ ...new Set ( _dataRaw . map ( obj => obj [ xsOrYs ] [ key ] ) ) ] ;
480
+ const uniqueVals = [ ...new Set ( this . data . raw . map ( obj => obj [ xsOrYs ] [ key ] ) ) ] ;
532
481
const oneHotMeta = this . createOneHotEncodings ( uniqueVals ) ;
533
482
inputsMeta [ key ] = {
534
483
...inputsMeta [ key ] ,
@@ -587,7 +536,7 @@ class NeuralNetworkData {
587
536
*/
588
537
async loadData ( filesOrPath , inputLabels , outputLabels ) {
589
538
const dataArray = await loadData ( filesOrPath ) ;
590
- this . data . raw = this . formatRawData ( dataArray , inputLabels , outputLabels ) ;
539
+ this . formatRawData ( dataArray , inputLabels , outputLabels ) ;
591
540
}
592
541
593
542
/**
@@ -704,7 +653,8 @@ class NeuralNetworkData {
704
653
}
705
654
706
655
// create an array of json objects [{xs,ys}]
707
- const result = dataArray . map ( ( item , idx ) => {
656
+ // set this.data.raw
657
+ this . data . raw = dataArray . map ( ( item , idx ) => {
708
658
const output = {
709
659
xs : { } ,
710
660
ys : { } ,
@@ -728,11 +678,6 @@ class NeuralNetworkData {
728
678
729
679
return output ;
730
680
} ) ;
731
-
732
- // set this.data.raw
733
- this . data . raw = result ;
734
-
735
- return result ;
736
681
}
737
682
738
683
/**
0 commit comments