xy-scale 1.4.31 → 1.4.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/xy-scale.min.js +1 -1
- package/package.json +1 -1
- package/src/datasets.js +164 -90
- package/src/utilities.js +1 -20
- package/test/test.js +2 -2
package/dist/xy-scale.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var XY_Scale;(()=>{"use strict";var e={d:(t,r)=>{for(var n in r)e.o(r,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:r[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};e.r(t),e.d(t,{arrayToTimesteps:()=>
|
|
1
|
+
var XY_Scale;(()=>{"use strict";var e={d:(t,r)=>{for(var n in r)e.o(r,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:r[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};e.r(t),e.d(t,{arrayToTimesteps:()=>i,parseProductionX:()=>s,parseTrainingXY:()=>a});const r=e=>null==e||!Number.isFinite(e),n=e=>{const t=[...e];for(let e=t.length-1;e>0;e--){const r=Math.floor(Math.random()*(e+1));[t[e],t[r]]=[t[r],t[e]]}return t},o=(e,{min:t=-1/0,max:r=1/0},n)=>{if(!Array.isArray(e))throw new Error(`Invalid property. "${n}" expected an array.`);if(e.length<t)throw new Error(`Invalid property value. Array "${n}" expected at least ${r} items.`);if(e.length>r)throw new Error(`Invalid property value. Array "${n}" expected at max ${r} items.`);return!0},l=e=>{for(const[t,r]of Object.entries(e)){if("number"==typeof r&&Number.isNaN(r))throw new Error(`Invalid value at index 0 property "${t}": value is "${r}". Expected a numeric value.`);if(null===r)throw new Error(`Invalid value at index 0 property "${t}": value is "${r}".`)}return!0},a=({arrObj:e=[],trainingSplit:t=.8,yCallbackFunc:a=e=>e,xCallbackFunc:s=e=>e,validateRows:i=()=>!0,shuffle:c=!1,balancing:u="",state:h={}})=>{let f=[],p=[];const y=[];o(e,{min:5},"parseTrainingXY"),l(e[0]);for(let t=0;t<e.length;t++){if(!i({objRow:e,index:t,state:h}))continue;const r=s({objRow:e,index:t,state:h}),n=a({objRow:e,index:t,state:h});null!=r&&null!=n&&(f.push(r),p.push(n),y.push(t))}if(c){const e=new Array(f.length);for(let t=0;t<f.length;t++)e[t]={x:f[t],y:p[t],sourceIndex:y[t]};const t=n(e);f=new Array(t.length),p=new Array(t.length);for(let e=0;e<t.length;e++)f[e]=t[e].x,p[e]=t[e].y,y[e]=t[e].sourceIndex}const d=f.length,g=p.length,w=d?Object.keys(f[0]).filter((e=>"tempIdx"!==e)):[],b=g?Object.keys(p[0]).filter((e=>"tempIdx"!==e)):[],m=new Array(d),x=new Array(g),v={keyNames:w},j={keyNames:b};for(let e=0;e<d;e++){const t=f[e],n=y[e],o=new Array(w.length);for(let e=0;e<w.length;e++){const l=w[e],a=t[l];if(r(a))throw new Error(`Invalid property value (${a}) returned from "xCallbackFunc" on index "${n}" property "${l}".`);o[e]=a}m[e]=o}for(let e=0;e<g;e++){const t=p[e],r=new Array(b.length);for(let e=0;e<b.length;e++)r[e]=t[b[e]];x[e]=r}const A=Math.floor(m.length*t);let O=m.slice(0,A),X=x.slice(0,A),$=m.slice(A),E=x.slice(A);if(u){let e;if("oversample"===u)e=((e,t)=>{const r={},n={};t.forEach(((o,l)=>{r[o]||(r[o]=0,n[o]=[]),r[o]++,n[o].push([e[l],t[l]])}));const o=Math.max(...Object.values(r)),l=[],a=[];return Object.keys(n).forEach((e=>{const t=n[e],r=t.length;for(let e=0;e<o;e++){const n=t[e%r];l.push(n[0]),a.push(n[1])}})),{X:l,Y:a}})(O,X),O=e.X,X=e.Y;else{if("undersample"!==u)throw Error('balancing argument only accepts "", "oversample" and "undersample". Defaults to "".');e=((e,t)=>{const r={},n={};t.forEach(((o,l)=>{r[o]||(r[o]=0,n[o]=[]),r[o]++,n[o].push([e[l],t[l]])}));const o=Math.min(...Object.values(r)),l=[],a=[];return Object.keys(n).forEach((e=>{const t=n[e];for(let e=0;e<o;e++){const r=t[e];l.push(r[0]),a.push(r[1])}})),{X:l,Y:a}})(O,X),O=e.X,X=e.Y}}return{trainX:O,trainY:X,testX:$,testY:E,configX:v,configY:j}},s=({arrObj:e=[],xCallbackFunc:t=e=>e,validateRows:a=()=>!0,shuffle:s=!1,state:i={}})=>{let c=[],u=[];o(e,{min:5},"parseProductionX"),l(e[0]);for(let r=0;r<e.length;r++){if(!a({objRow:e,index:r,state:i}))continue;const n=t({objRow:e,index:r,state:i});null!=n&&!1!==n&&(c.push(n),u.push(r))}if(s){const e=new Array(c.length);for(let t=0;t<c.length;t++)e[t]={x:c[t],sourceIndex:u[t]};const t=n(e);c=new Array(t.length),u=new Array(t.length);for(let e=0;e<t.length;e++)c[e]=t[e].x,u[e]=t[e].sourceIndex}const h=c.length,f=h?Object.keys(c[0]).filter((e=>"tempIdx"!==e)):[],p=new Array(h),y={keyNames:f};for(let e=0;e<h;e++){const t=c[e],n=u[e],o=new Array(f.length);for(let e=0;e<f.length;e++){const l=f[e],a=t[l];if(r(a))throw new Error(`Invalid property value (${a}) returned from "xCallbackFunc" on index "${n}" property "${l}".`);o[e]=a}p[e]=o}return{X:p,configX:y}},i=(e,t)=>{if(0===t)return e;if(t<0)throw new Error("timeSteps must be greater than 0");const r=[];for(let n=0;n<=e.length-t;n++)r.push(e.slice(n,n+t));return r};XY_Scale=t})();
|
package/package.json
CHANGED
package/src/datasets.js
CHANGED
|
@@ -1,99 +1,140 @@
|
|
|
1
|
-
import { arrayShuffle,
|
|
1
|
+
import { arrayShuffle, isBadNumber } from "./utilities.js";
|
|
2
2
|
import { oversampleXY, undersampleXY } from "./balancing.js";
|
|
3
3
|
import { validateFirstRow, validateArray } from "./validators.js";
|
|
4
4
|
|
|
5
|
-
//ADD A PARAM max correlation that will measure the correlation between variables if defined
|
|
6
|
-
|
|
7
|
-
export const parseTrainingXY = ({
|
|
8
|
-
arrObj = [], //array of objects
|
|
9
|
-
trainingSplit = 0.8, //
|
|
10
|
-
yCallbackFunc = row => row, //accepted callback functions
|
|
11
|
-
xCallbackFunc = row => row, //accepted callback functions
|
|
12
|
-
validateRows = () => true
|
|
13
|
-
shuffle = false
|
|
14
|
-
balancing = ''
|
|
15
|
-
state = {}, //accepted object or classes
|
|
5
|
+
// ADD A PARAM max correlation that will measure the correlation between variables if defined
|
|
6
|
+
|
|
7
|
+
export const parseTrainingXY = ({
|
|
8
|
+
arrObj = [], // array of objects
|
|
9
|
+
trainingSplit = 0.8, // numeric float between 0.01 and 0.99
|
|
10
|
+
yCallbackFunc = row => row, // accepted callback functions
|
|
11
|
+
xCallbackFunc = row => row, // accepted callback functions
|
|
12
|
+
validateRows = () => true, // accepted callback functions
|
|
13
|
+
shuffle = false, // only booleans
|
|
14
|
+
balancing = '', // accepted '', 'oversample' or 'undersample'
|
|
15
|
+
state = {}, // accepted object or classes
|
|
16
16
|
}) => {
|
|
17
17
|
let X = [];
|
|
18
18
|
let Y = [];
|
|
19
|
+
const sourceIndexes = [];
|
|
19
20
|
|
|
20
|
-
validateArray(arrObj, {min: 5}, 'parseTrainingXY')
|
|
21
|
-
validateFirstRow(arrObj[0])
|
|
21
|
+
validateArray(arrObj, { min: 5 }, 'parseTrainingXY');
|
|
22
|
+
validateFirstRow(arrObj[0]);
|
|
22
23
|
|
|
23
|
-
//if parsedX
|
|
24
|
+
// if parsedX or parsedY is undefined/null the current row will be excluded from training
|
|
24
25
|
for (let x = 0; x < arrObj.length; x++) {
|
|
26
|
+
if (!validateRows({ objRow: arrObj, index: x, state })) continue;
|
|
27
|
+
|
|
28
|
+
const parsedX = xCallbackFunc({ objRow: arrObj, index: x, state });
|
|
29
|
+
const parsedY = yCallbackFunc({ objRow: arrObj, index: x, state });
|
|
30
|
+
|
|
31
|
+
if (
|
|
32
|
+
typeof parsedX !== 'undefined' &&
|
|
33
|
+
parsedX !== null &&
|
|
34
|
+
typeof parsedY !== 'undefined' &&
|
|
35
|
+
parsedY !== null
|
|
36
|
+
) {
|
|
37
|
+
X.push(parsedX);
|
|
38
|
+
Y.push(parsedY);
|
|
39
|
+
sourceIndexes.push(x);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
25
42
|
|
|
26
|
-
|
|
43
|
+
if (shuffle) {
|
|
44
|
+
const merged = new Array(X.length);
|
|
27
45
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
46
|
+
for (let i = 0; i < X.length; i++) {
|
|
47
|
+
merged[i] = {
|
|
48
|
+
x: X[i],
|
|
49
|
+
y: Y[i],
|
|
50
|
+
sourceIndex: sourceIndexes[i],
|
|
51
|
+
};
|
|
34
52
|
}
|
|
35
|
-
}
|
|
36
53
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
54
|
+
const shuffled = arrayShuffle(merged);
|
|
55
|
+
|
|
56
|
+
X = new Array(shuffled.length);
|
|
57
|
+
Y = new Array(shuffled.length);
|
|
58
|
+
|
|
59
|
+
for (let i = 0; i < shuffled.length; i++) {
|
|
60
|
+
X[i] = shuffled[i].x;
|
|
61
|
+
Y[i] = shuffled[i].y;
|
|
62
|
+
sourceIndexes[i] = shuffled[i].sourceIndex;
|
|
63
|
+
}
|
|
42
64
|
}
|
|
43
65
|
|
|
44
|
-
const xLen = X.length
|
|
45
|
-
const yLen = Y.length
|
|
46
|
-
|
|
47
|
-
const
|
|
66
|
+
const xLen = X.length;
|
|
67
|
+
const yLen = Y.length;
|
|
68
|
+
|
|
69
|
+
const xKeys = xLen ? Object.keys(X[0]).filter(key => key !== 'tempIdx') : [];
|
|
70
|
+
const yKeys = yLen ? Object.keys(Y[0]).filter(key => key !== 'tempIdx') : [];
|
|
71
|
+
|
|
72
|
+
const flatX = new Array(xLen);
|
|
73
|
+
const flatY = new Array(yLen);
|
|
74
|
+
|
|
48
75
|
const configX = {
|
|
49
|
-
keyNames:
|
|
50
|
-
}
|
|
76
|
+
keyNames: xKeys,
|
|
77
|
+
};
|
|
78
|
+
|
|
51
79
|
const configY = {
|
|
52
|
-
keyNames:
|
|
53
|
-
}
|
|
80
|
+
keyNames: yKeys,
|
|
81
|
+
};
|
|
54
82
|
|
|
55
|
-
for(let idx = 0; idx < xLen; idx++)
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
83
|
+
for (let idx = 0; idx < xLen; idx++) {
|
|
84
|
+
const rowObj = X[idx];
|
|
85
|
+
const sourceIndex = sourceIndexes[idx];
|
|
86
|
+
const flatRow = new Array(xKeys.length);
|
|
59
87
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}
|
|
88
|
+
for (let j = 0; j < xKeys.length; j++) {
|
|
89
|
+
const key = xKeys[j];
|
|
90
|
+
const value = rowObj[key];
|
|
64
91
|
|
|
65
|
-
|
|
92
|
+
if (isBadNumber(value)) {
|
|
93
|
+
throw new Error(
|
|
94
|
+
`Invalid property value (${value}) returned from "xCallbackFunc" on index "${sourceIndex}" property "${key}".`
|
|
95
|
+
);
|
|
96
|
+
}
|
|
66
97
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
let testX = flatX.slice(splitIndex)
|
|
70
|
-
let testY = flatY.slice(splitIndex)
|
|
98
|
+
flatRow[j] = value;
|
|
99
|
+
}
|
|
71
100
|
|
|
101
|
+
flatX[idx] = flatRow;
|
|
102
|
+
}
|
|
72
103
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
104
|
+
for (let idx = 0; idx < yLen; idx++) {
|
|
105
|
+
const rowObj = Y[idx];
|
|
106
|
+
const flatRow = new Array(yKeys.length);
|
|
76
107
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
balance = oversampleXY(trainX, trainY)
|
|
80
|
-
trainX = balance.X
|
|
81
|
-
trainY = balance.Y
|
|
82
|
-
}
|
|
83
|
-
else if(balancing === 'undersample')
|
|
84
|
-
{
|
|
85
|
-
balance = undersampleXY(trainX, trainY)
|
|
86
|
-
trainX = balance.X
|
|
87
|
-
trainY = balance.Y
|
|
88
|
-
}
|
|
89
|
-
else
|
|
90
|
-
{
|
|
91
|
-
throw Error('balancing argument only accepts "false", "oversample" and "undersample". Defaults to "false".')
|
|
108
|
+
for (let j = 0; j < yKeys.length; j++) {
|
|
109
|
+
flatRow[j] = rowObj[yKeys[j]];
|
|
92
110
|
}
|
|
111
|
+
|
|
112
|
+
flatY[idx] = flatRow;
|
|
93
113
|
}
|
|
94
114
|
|
|
115
|
+
const splitIndex = Math.floor(flatX.length * trainingSplit);
|
|
116
|
+
|
|
117
|
+
let trainX = flatX.slice(0, splitIndex);
|
|
118
|
+
let trainY = flatY.slice(0, splitIndex);
|
|
119
|
+
let testX = flatX.slice(splitIndex);
|
|
120
|
+
let testY = flatY.slice(splitIndex);
|
|
121
|
+
|
|
122
|
+
if (balancing) {
|
|
123
|
+
let balance;
|
|
124
|
+
|
|
125
|
+
if (balancing === 'oversample') {
|
|
126
|
+
balance = oversampleXY(trainX, trainY);
|
|
127
|
+
trainX = balance.X;
|
|
128
|
+
trainY = balance.Y;
|
|
129
|
+
} else if (balancing === 'undersample') {
|
|
130
|
+
balance = undersampleXY(trainX, trainY);
|
|
131
|
+
trainX = balance.X;
|
|
132
|
+
trainY = balance.Y;
|
|
133
|
+
} else {
|
|
134
|
+
throw Error('balancing argument only accepts "", "oversample" and "undersample". Defaults to "".');
|
|
135
|
+
}
|
|
136
|
+
}
|
|
95
137
|
|
|
96
|
-
// Split into training and testing sets
|
|
97
138
|
return {
|
|
98
139
|
trainX,
|
|
99
140
|
trainY,
|
|
@@ -104,49 +145,82 @@ export const parseTrainingXY = ({
|
|
|
104
145
|
};
|
|
105
146
|
};
|
|
106
147
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
arrObj = [],
|
|
148
|
+
export const parseProductionX = ({
|
|
149
|
+
arrObj = [],
|
|
110
150
|
xCallbackFunc = row => row,
|
|
111
151
|
validateRows = () => true,
|
|
112
152
|
shuffle = false,
|
|
113
153
|
state = {},
|
|
114
154
|
}) => {
|
|
115
155
|
let X = [];
|
|
156
|
+
let sourceIndexes = [];
|
|
116
157
|
|
|
117
|
-
validateArray(arrObj, {min: 5}, 'parseProductionX')
|
|
118
|
-
validateFirstRow(arrObj[0])
|
|
158
|
+
validateArray(arrObj, { min: 5 }, 'parseProductionX');
|
|
159
|
+
validateFirstRow(arrObj[0]);
|
|
119
160
|
|
|
120
161
|
for (let x = 0; x < arrObj.length; x++) {
|
|
162
|
+
if (!validateRows({ objRow: arrObj, index: x, state })) continue;
|
|
121
163
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
const parsedX = xCallbackFunc({ objRow: arrObj, index: x, state})
|
|
164
|
+
const parsedX = xCallbackFunc({ objRow: arrObj, index: x, state });
|
|
125
165
|
|
|
126
166
|
if (typeof parsedX !== 'undefined' && parsedX !== null && parsedX !== false) {
|
|
127
|
-
X.push(parsedX)
|
|
167
|
+
X.push(parsedX);
|
|
168
|
+
sourceIndexes.push(x);
|
|
128
169
|
}
|
|
129
170
|
}
|
|
130
171
|
|
|
131
|
-
if(shuffle)
|
|
132
|
-
|
|
133
|
-
|
|
172
|
+
if (shuffle) {
|
|
173
|
+
const merged = new Array(X.length);
|
|
174
|
+
|
|
175
|
+
for (let i = 0; i < X.length; i++) {
|
|
176
|
+
merged[i] = {
|
|
177
|
+
x: X[i],
|
|
178
|
+
sourceIndex: sourceIndexes[i],
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const shuffled = arrayShuffle(merged);
|
|
183
|
+
|
|
184
|
+
X = new Array(shuffled.length);
|
|
185
|
+
sourceIndexes = new Array(shuffled.length);
|
|
186
|
+
|
|
187
|
+
for (let i = 0; i < shuffled.length; i++) {
|
|
188
|
+
X[i] = shuffled[i].x;
|
|
189
|
+
sourceIndexes[i] = shuffled[i].sourceIndex;
|
|
190
|
+
}
|
|
134
191
|
}
|
|
135
192
|
|
|
136
|
-
const xLen = X.length
|
|
137
|
-
const
|
|
193
|
+
const xLen = X.length;
|
|
194
|
+
const xKeys = xLen ? Object.keys(X[0]).filter(key => key !== 'tempIdx') : [];
|
|
195
|
+
const flatX = new Array(xLen);
|
|
196
|
+
|
|
138
197
|
const configX = {
|
|
139
|
-
keyNames:
|
|
140
|
-
}
|
|
198
|
+
keyNames: xKeys,
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
for (let idx = 0; idx < xLen; idx++) {
|
|
202
|
+
const rowObj = X[idx];
|
|
203
|
+
const sourceIndex = sourceIndexes[idx];
|
|
204
|
+
const flatRow = new Array(xKeys.length);
|
|
205
|
+
|
|
206
|
+
for (let j = 0; j < xKeys.length; j++) {
|
|
207
|
+
const key = xKeys[j];
|
|
208
|
+
const value = rowObj[key];
|
|
209
|
+
|
|
210
|
+
if (isBadNumber(value)) {
|
|
211
|
+
throw new Error(
|
|
212
|
+
`Invalid property value (${value}) returned from "xCallbackFunc" on index "${sourceIndex}" property "${key}".`
|
|
213
|
+
);
|
|
214
|
+
}
|
|
141
215
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
216
|
+
flatRow[j] = value;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
flatX[idx] = flatRow;
|
|
145
220
|
}
|
|
146
221
|
|
|
147
|
-
// Split into training and testing sets
|
|
148
222
|
return {
|
|
149
223
|
X: flatX,
|
|
150
224
|
configX,
|
|
151
|
-
}
|
|
152
|
-
};
|
|
225
|
+
};
|
|
226
|
+
};
|
package/src/utilities.js
CHANGED
|
@@ -1,23 +1,4 @@
|
|
|
1
|
-
export const
|
|
2
|
-
if (X.length !== Y.length) {
|
|
3
|
-
throw new Error("X and Y arrays must have the same length");
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
// Create an array of indices based on the length of X or Y
|
|
7
|
-
const indices = Array.from({ length: X.length }, (_, i) => i);
|
|
8
|
-
|
|
9
|
-
// Shuffle the indices using Fisher-Yates shuffle algorithm
|
|
10
|
-
for (let i = indices.length - 1; i > 0; i--) {
|
|
11
|
-
const j = Math.floor(Math.random() * (i + 1));
|
|
12
|
-
[indices[i], indices[j]] = [indices[j], indices[i]];
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
// Use the shuffled indices to rearrange X and Y
|
|
16
|
-
const shuffledX = indices.map(i => X[i]);
|
|
17
|
-
const shuffledY = indices.map(i => Y[i]);
|
|
18
|
-
|
|
19
|
-
return { shuffledX, shuffledY };
|
|
20
|
-
}
|
|
1
|
+
export const isBadNumber = (v) => v == null || !Number.isFinite(v)
|
|
21
2
|
|
|
22
3
|
export const arrayShuffle = X => {
|
|
23
4
|
// Make a copy of the array to avoid mutating the original
|
package/test/test.js
CHANGED
|
@@ -52,7 +52,7 @@ const test = async () => {
|
|
|
52
52
|
|
|
53
53
|
return false
|
|
54
54
|
},
|
|
55
|
-
shuffle:
|
|
55
|
+
shuffle: false,
|
|
56
56
|
balancing: null,
|
|
57
57
|
});
|
|
58
58
|
|
|
@@ -86,7 +86,7 @@ const yCallbackFunc = ({ objRow, index }) => {
|
|
|
86
86
|
if (typeof next === 'undefined') return null
|
|
87
87
|
|
|
88
88
|
return {
|
|
89
|
-
result: Number(next.close > next.open)
|
|
89
|
+
result: Number(next.close > next.open) //the output shoud must be an array to preserve the key->value order
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
92
|
|