Skip to content

Commit 5c32c1c

Browse files
authored
Add tests (#91)
1 parent 61e69c6 commit 5c32c1c

File tree

10 files changed

+376
-63
lines changed

10 files changed

+376
-63
lines changed

tests/gui/data/functional.test.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import puppeteer from 'puppeteer'
2+
3+
/** @type {puppeteer.Browser} */
4+
let browser
5+
beforeAll(async () => {
6+
browser = await puppeteer.launch({ args: ['--no-sandbox'] })
7+
})
8+
9+
afterAll(async () => {
10+
await browser.close()
11+
})
12+
13+
describe('classification', () => {
14+
/** @type {puppeteer.Page} */
15+
let page
16+
beforeEach(async () => {
17+
page = await browser.newPage()
18+
await page.goto(`http://${process.env.SERVER_HOST}/`)
19+
page.on('console', message => console.log(`${message.type().substring(0, 3).toUpperCase()} ${message.text()}`))
20+
.on('pageerror', ({ message }) => console.log(message))
21+
.on('requestfailed', request => console.log(`${request.failure().errorText} ${request.url()}`))
22+
await page.waitForSelector('#data_menu > *')
23+
}, 10000)
24+
25+
test('initialize', async () => {
26+
const dataSelectBox = await page.waitForSelector('#ml_selector dl:first-child dd:nth-child(2) select')
27+
dataSelectBox.select('functional')
28+
29+
const dataMenu = await page.waitForSelector('#ml_selector #data_menu')
30+
const dimensionTextBox = await dataMenu.waitForSelector('input[name=dim]')
31+
const dimension = await (await dimensionTextBox.getProperty('value')).jsonValue()
32+
expect(dimension).toBe('1')
33+
}, 10000)
34+
})

tests/lib/model/diffusion_map.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { jest } from '@jest/globals'
2-
jest.retryTimes(5)
2+
jest.retryTimes(10)
33

44
import Matrix from '../../../lib/util/matrix.js'
55
import DiffusionMap from '../../../lib/model/diffusion_map.js'
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import Matrix from '../../../lib/util/matrix.js'
2+
import GrowingCellStructures from '../../../lib/model/growing_cell_structures.js'
3+
4+
test('clustering', () => {
5+
const model = new GrowingCellStructures()
6+
const n = 50
7+
const x = Matrix.concat(Matrix.randn(n, 2, 0, 0.1), Matrix.randn(n, 2, 5, 0.1)).toArray()
8+
9+
for (let i = 0; i < 100; i++) {
10+
model.fit(x)
11+
}
12+
const y = model.predict(x)
13+
expect(y).toHaveLength(x.length)
14+
})

tests/lib/model/kernel_density_estimator.test.js

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,30 @@ import KernelDensityEstimator from '../../../lib/model/kernel_density_estimator.
66

77
import { correlation } from '../../../lib/evaluate/regression.js'
88

9-
test('density estimation', () => {
10-
const model = new KernelDensityEstimator()
9+
test.each([undefined, 'gaussian', 'triangular', 'epanechnikov', 'biweight', 'triweight'])(
10+
'density estimation %s',
11+
kernel => {
12+
const model = new KernelDensityEstimator(kernel)
13+
const n = 500
14+
const x = Matrix.concat(Matrix.randn(n, 2, 0, 0.1), Matrix.randn(n, 2, 5, 0.1)).toArray()
15+
16+
model.fit(x)
17+
const y = model.predict(x)
18+
expect(y).toHaveLength(x.length)
19+
20+
const p = []
21+
for (let i = 0; i < x.length; i++) {
22+
const p1 = Math.exp(-x[i].reduce((s, v) => s + v ** 2, 0) / (2 * 0.1)) / (2 * Math.PI * 0.1)
23+
const p2 = Math.exp(-x[i].reduce((s, v) => s + (v - 5) ** 2, 0) / (2 * 0.1)) / (2 * Math.PI * 0.1)
24+
p[i] = (p1 + p2) / 2
25+
}
26+
const corr = correlation(y, p)
27+
expect(corr).toBeGreaterThan(0.9)
28+
}
29+
)
30+
31+
test.each(['rectangular'])('density estimation %s', kernel => {
32+
const model = new KernelDensityEstimator(kernel)
1133
const n = 500
1234
const x = Matrix.concat(Matrix.randn(n, 2, 0, 0.1), Matrix.randn(n, 2, 5, 0.1)).toArray()
1335

@@ -22,5 +44,5 @@ test('density estimation', () => {
2244
p[i] = (p1 + p2) / 2
2345
}
2446
const corr = correlation(y, p)
25-
expect(corr).toBeGreaterThan(0.9)
47+
expect(corr).toBeGreaterThan(0.8)
2648
})

tests/lib/model/maxabs.test.js

Lines changed: 77 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,90 @@
11
import Matrix from '../../../lib/util/matrix.js'
22
import MaxAbsScaler from '../../../lib/model/maxabs.js'
33

4-
test('fit', () => {
4+
test('mat mat', () => {
55
const model = new MaxAbsScaler()
66
const x = Matrix.randn(50, 2, 1, 0.2)
77
const xabsmax = Matrix.map(x, Math.abs).max(0).value
88
model.fit(x.toArray())
9-
const y = model.predict(x.toArray())
10-
11-
const min = Array(2).fill(Infinity)
12-
const max = Array(2).fill(-Infinity)
13-
const absmax = Array(2).fill(0)
14-
for (let i = 0; i < x.rows; i++) {
15-
for (let k = 0; k < x.cols; k++) {
16-
expect(y[i][k]).toBeCloseTo(x.at(i, k) / xabsmax[k])
17-
min[k] = Math.min(min[k], y[i][k])
18-
max[k] = Math.max(max[k], y[i][k])
19-
absmax[k] = Math.max(max[k], Math.abs(y[i][k]))
9+
10+
const x1 = Matrix.randn(50, 2, 0, 0.2)
11+
const y = model.predict(x1.toArray())
12+
13+
for (let i = 0; i < x1.rows; i++) {
14+
for (let j = 0; j < x1.cols; j++) {
15+
expect(y[i][j]).toBeCloseTo(x1.at(i, j) / xabsmax[j])
2016
}
2117
}
22-
for (let k = 0; k < min.length; k++) {
23-
expect(min[k]).toBeGreaterThanOrEqual(-1)
18+
})
19+
20+
test('mat arr', () => {
21+
const model = new MaxAbsScaler()
22+
const x = Matrix.randn(50, 2, 1, 0.2)
23+
const xabsmax = Matrix.map(x, Math.abs).max(0).value
24+
model.fit(x.toArray())
25+
26+
const x1 = Matrix.randn(50, 1, 0, 0.2)
27+
const y = model.predict(x1.value)
28+
29+
for (let i = 0; i < x1.rows; i++) {
30+
expect(y[i]).toBeCloseTo(x1.at(i, 0) / xabsmax[0])
2431
}
25-
for (let k = 0; k < max.length; k++) {
26-
expect(max[k]).toBeLessThanOrEqual(1)
32+
})
33+
34+
test('mat 0', () => {
35+
const model = new MaxAbsScaler()
36+
const x = Matrix.zeros(50, 2)
37+
model.fit(x.toArray())
38+
39+
const x1 = Matrix.randn(50, 2, 0, 0.2)
40+
const y = model.predict(x1.toArray())
41+
42+
for (let i = 0; i < x1.rows; i++) {
43+
for (let j = 0; j < x1.cols; j++) {
44+
expect(y[i][j]).toBeCloseTo(x1.at(i, j))
45+
}
2746
}
28-
for (let k = 0; k < absmax.length; k++) {
29-
expect(absmax[k]).toBeCloseTo(1)
47+
})
48+
49+
test('arr mat', () => {
50+
const model = new MaxAbsScaler()
51+
const x = Matrix.randn(50, 1, 1, 0.2)
52+
const xabsmax = Matrix.map(x, Math.abs).max()
53+
model.fit(x.value)
54+
55+
const x1 = Matrix.randn(50, 2, 0, 0.2)
56+
const y = model.predict(x1.toArray())
57+
58+
for (let i = 0; i < x1.rows; i++) {
59+
for (let j = 0; j < x1.cols; j++) {
60+
expect(y[i][j]).toBeCloseTo(x1.at(i, j) / xabsmax)
61+
}
62+
}
63+
})
64+
65+
test('arr arr', () => {
66+
const model = new MaxAbsScaler()
67+
const x = Matrix.randn(50, 1, 1, 0.2)
68+
const xabsmax = Matrix.map(x, Math.abs).max()
69+
model.fit(x.value)
70+
71+
const x1 = Matrix.randn(50, 1, 0, 0.2)
72+
const y = model.predict(x1.value)
73+
74+
for (let i = 0; i < x1.rows; i++) {
75+
expect(y[i]).toBeCloseTo(x1.at(i, 0) / xabsmax)
76+
}
77+
})
78+
79+
test('arr 0', () => {
80+
const model = new MaxAbsScaler()
81+
const x = Matrix.zeros(50, 1, 1, 0.2)
82+
model.fit(x.value)
83+
84+
const x1 = Matrix.randn(50, 1, 0, 0.2)
85+
const y = model.predict(x1.value)
86+
87+
for (let i = 0; i < x1.rows; i++) {
88+
expect(y[i]).toBeCloseTo(x1.at(i, 0))
3089
}
3190
})

tests/lib/model/minmax.test.js

Lines changed: 82 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,96 @@
11
import Matrix from '../../../lib/util/matrix.js'
22
import MinmaxNormalization from '../../../lib/model/minmax.js'
33

4-
test('fit', () => {
4+
test('mat mat', () => {
55
const model = new MinmaxNormalization()
66
const x = Matrix.randn(50, 2, 1, 0.2)
77
model.fit(x.toArray())
8-
const y = model.predict(x.toArray())
8+
9+
const x1 = Matrix.randn(50, 2, 0, 0.2)
10+
const y = model.predict(x1.toArray())
11+
12+
const xmin = x.min(0).value
13+
const xmax = x.max(0).value
14+
for (let i = 0; i < x1.rows; i++) {
15+
for (let k = 0; k < x1.cols; k++) {
16+
expect(y[i][k]).toBeCloseTo((x1.at(i, k) - xmin[k]) / (xmax[k] - xmin[k]))
17+
}
18+
}
19+
})
20+
21+
test('mat arr', () => {
22+
const model = new MinmaxNormalization()
23+
const x = Matrix.randn(50, 2, 1, 0.2)
24+
model.fit(x.toArray())
25+
26+
const x1 = Matrix.randn(50, 1, 0, 0.2)
27+
const y = model.predict(x1.value)
928

1029
const xmin = x.min(0).value
1130
const xmax = x.max(0).value
12-
const min = Array(2).fill(Infinity)
13-
const max = Array(2).fill(-Infinity)
14-
for (let i = 0; i < x.rows; i++) {
15-
for (let k = 0; k < x.cols; k++) {
16-
expect(y[i][k]).toBeCloseTo((x.at(i, k) - xmin[k]) / (xmax[k] - xmin[k]))
17-
min[k] = Math.min(min[k], y[i][k])
18-
max[k] = Math.max(max[k], y[i][k])
31+
for (let i = 0; i < x1.rows; i++) {
32+
expect(y[i]).toBeCloseTo((x1.at(i, 0) - xmin[0]) / (xmax[0] - xmin[0]))
33+
}
34+
})
35+
36+
test('mat same', () => {
37+
const model = new MinmaxNormalization()
38+
const r = Math.random()
39+
const x = new Matrix(50, 2, r)
40+
model.fit(x.toArray())
41+
42+
const x1 = Matrix.randn(50, 2, 0, 0.2)
43+
const y = model.predict(x1.toArray())
44+
45+
for (let i = 0; i < x1.rows; i++) {
46+
for (let k = 0; k < x1.cols; k++) {
47+
expect(y[i][k]).toBeCloseTo(x1.at(i, k) - r)
1948
}
2049
}
21-
for (let k = 0; k < min.length; k++) {
22-
expect(min[k]).toBeCloseTo(0)
50+
})
51+
52+
test('arr mat', () => {
53+
const model = new MinmaxNormalization()
54+
const x = Matrix.randn(50, 1, 1, 0.2)
55+
model.fit(x.value)
56+
57+
const x1 = Matrix.randn(50, 2, 0, 0.2)
58+
const y = model.predict(x1.toArray())
59+
60+
const xmin = x.min()
61+
const xmax = x.max()
62+
for (let i = 0; i < x1.rows; i++) {
63+
for (let k = 0; k < x1.cols; k++) {
64+
expect(y[i][k]).toBeCloseTo((x1.at(i, k) - xmin) / (xmax - xmin))
65+
}
66+
}
67+
})
68+
69+
test('arr arr', () => {
70+
const model = new MinmaxNormalization()
71+
const x = Matrix.randn(50, 1, 1, 0.2)
72+
model.fit(x.value)
73+
74+
const x1 = Matrix.randn(50, 1, 0, 0.2)
75+
const y = model.predict(x1.value)
76+
77+
const xmin = x.min()
78+
const xmax = x.max()
79+
for (let i = 0; i < x1.rows; i++) {
80+
expect(y[i]).toBeCloseTo((x1.at(i, 0) - xmin) / (xmax - xmin))
2381
}
24-
for (let k = 0; k < max.length; k++) {
25-
expect(max[k]).toBeCloseTo(1)
82+
})
83+
84+
test('arr same', () => {
85+
const model = new MinmaxNormalization()
86+
const r = Math.random()
87+
const x = new Matrix(50, 1, r)
88+
model.fit(x.value)
89+
90+
const x1 = Matrix.randn(50, 1, 0, 0.2)
91+
const y = model.predict(x1.value)
92+
93+
for (let i = 0; i < x1.rows; i++) {
94+
expect(y[i]).toBeCloseTo(x1.at(i, 0) - r)
2695
}
2796
})
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import NeuralNetwork from '../../../../lib/model/neuralnetwork.js'
2+
import Matrix from '../../../../lib/util/matrix.js'
3+
4+
describe('nn', () => {
5+
test.each(['sgd', 'momentum', 'rmsprop', 'adam'])('%s', optimizer => {
6+
const net = NeuralNetwork.fromObject(
7+
[
8+
{ type: 'input', name: 'in' },
9+
{ type: 'full', out_size: 5, activation: 'sigmoid' },
10+
{ type: 'full', out_size: 3 },
11+
],
12+
'mse',
13+
optimizer
14+
)
15+
const x = Matrix.randn(1, 10)
16+
const t = Matrix.randn(1, 3)
17+
18+
for (let i = 0; i < 1000; i++) {
19+
const loss = net.fit(x, t, 1000, 0.01)
20+
if (loss[0] < 1.0e-8) {
21+
break
22+
}
23+
}
24+
25+
const y = net.calc(x)
26+
for (let i = 0; i < 3; i++) {
27+
expect(y.at(0, i)).toBeCloseTo(t.at(0, i))
28+
}
29+
})
30+
})

0 commit comments

Comments
 (0)