1 | #!/usr/bin/env ts-node
|
2 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
3 | return new (P || (P = Promise))(function (resolve, reject) {
|
4 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
5 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
6 | function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
7 | step((generator = generator.apply(thisArg, _arguments || [])).next());
|
8 | });
|
9 | };
|
10 | import { ChineseWhispers } from './chinese-whispers';
|
11 | const t = require('tap');
|
12 | const jsnx = require('jsnetworkx');
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 | t.test('Cluster', (t) => __awaiter(this, void 0, void 0, function* () {
|
29 | const NUMBER_LIST = [
|
30 | 10, 13, 15,
|
31 | 150, 155, 160,
|
32 | 260, 270, 280,
|
33 | ];
|
34 | const EXPECTED_NO_THRESHOLD_CLUSTER = {
|
35 | 0: [
|
36 | 10, 13, 15,
|
37 | ],
|
38 | 1: [
|
39 | 150, 155, 160,
|
40 | ],
|
41 | 2: [
|
42 | 260, 270, 280,
|
43 | ],
|
44 | };
|
45 | const EXPECTED_THRESHOLD_1_6_CLUSTER = {
|
46 | 0: [
|
47 | 10, 13, 15,
|
48 | ],
|
49 | 1: [
|
50 | 150, 155, 160,
|
51 | ],
|
52 | 2: [
|
53 | 260,
|
54 | ],
|
55 | 3: [
|
56 | 270,
|
57 | ],
|
58 | 4: [
|
59 | 280,
|
60 | ],
|
61 | };
|
62 | t.test('no threshold', (t) => __awaiter(this, void 0, void 0, function* () {
|
63 | const cw = new ChineseWhispers({
|
64 | weightFunc,
|
65 | });
|
66 | const clusterIndicesList = cw.cluster(NUMBER_LIST);
|
67 |
|
68 | t.equal(clusterIndicesList.length, Object.keys(EXPECTED_NO_THRESHOLD_CLUSTER).length, 'should get expect number of clusters');
|
69 | for (const i of Object.keys(EXPECTED_NO_THRESHOLD_CLUSTER)) {
|
70 | t.deepEqual(clusterIndicesList[parseInt(i, 10)].map(idx => NUMBER_LIST[idx]), EXPECTED_NO_THRESHOLD_CLUSTER[i], 'should get expected items for cluster ' + i);
|
71 | }
|
72 | }));
|
73 | t.test('threshold 1/6', (t) => __awaiter(this, void 0, void 0, function* () {
|
74 | const cw = new ChineseWhispers({
|
75 | threshold: 1 / 6,
|
76 | weightFunc,
|
77 | });
|
78 | const clusterIndicesList = cw.cluster(NUMBER_LIST);
|
79 | t.equal(clusterIndicesList.length, Object.keys(EXPECTED_THRESHOLD_1_6_CLUSTER).length, 'should get expect number of clusters');
|
80 | for (const i of Object.keys(EXPECTED_THRESHOLD_1_6_CLUSTER)) {
|
81 | t.deepEqual(clusterIndicesList[parseInt(i, 10)].map(idx => NUMBER_LIST[idx]), EXPECTED_THRESHOLD_1_6_CLUSTER[i], 'should get expected items for cluster ' + i);
|
82 | }
|
83 | }));
|
84 | }));
|
85 | t.test('buildNetwork()', (t) => __awaiter(this, void 0, void 0, function* () {
|
86 | const DATA = [
|
87 | 1, 2, 3,
|
88 | 10, 20, 30,
|
89 | 100, 200, 300,
|
90 | 1000, 2000, 3000,
|
91 | ];
|
92 | const cw = new ChineseWhispers({
|
93 | weightFunc,
|
94 | });
|
95 | t.test('weight threshold none', (t) => __awaiter(this, void 0, void 0, function* () {
|
96 | const G = cw.buildNetwork(DATA, weightFunc);
|
97 | const nodeList = G.nodes();
|
98 | const edgeList = G.edges();
|
99 | t.equal(nodeList.length, DATA.length, 'should turn data to nodes');
|
100 | const edgeNum = DATA.length * (DATA.length - 1) / 2;
|
101 | t.equal(edgeList.length, edgeNum, 'should turn data to C(n, 2) edges');
|
102 | }));
|
103 | t.test('weight threshold 1/5', (t) => __awaiter(this, void 0, void 0, function* () {
|
104 | const G = cw.buildNetwork(DATA, weightFunc, 1 / 5);
|
105 | const edgeList = G.edges();
|
106 | t.equal(edgeList.length, 3, 'should turn data to 3 edges for threshold 1/5');
|
107 | }));
|
108 | t.test('weight threshold 1/50', (t) => __awaiter(this, void 0, void 0, function* () {
|
109 | const G = cw.buildNetwork(DATA, weightFunc, 1 / 50);
|
110 | const edgeList = G.edges();
|
111 | t.equal(edgeList.length, 15, 'should turn data to 15 edges for threshold 1/50');
|
112 | }));
|
113 | t.test('weight threshold 1/500', (t) => __awaiter(this, void 0, void 0, function* () {
|
114 | const G = cw.buildNetwork(DATA, weightFunc, 1 / 500);
|
115 | const edgeList = G.edges();
|
116 | t.equal(edgeList.length, 36, 'should turn data to 36 edges for threshold 1/500');
|
117 | }));
|
118 | }));
|
119 | t.test('buildClusterList()', (t) => __awaiter(this, void 0, void 0, function* () {
|
120 | const NODE_LIST = [
|
121 | [1, { label: 'a' }],
|
122 | [2, { label: 'b' }],
|
123 | [3, { label: 'a' }],
|
124 | [4, { label: 'b' }],
|
125 | [5, { label: 'a' }],
|
126 | ];
|
127 | const G = new jsnx.Graph();
|
128 | G.addNodesFrom(NODE_LIST);
|
129 | const cw = new ChineseWhispers({
|
130 | weightFunc,
|
131 | });
|
132 | const clusterList = cw.buildClusterList(G);
|
133 | t.equal(clusterList.length, 2, 'should get 2 cluster');
|
134 | t.deepEqual(clusterList[0], [1, 3, 5], 'should get cluster for a');
|
135 | t.deepEqual(clusterList[1], [2, 4], 'should get cluster for b');
|
136 | }));
|
137 | function weightFunc(a, b) {
|
138 | const dist = Math.abs(a - b);
|
139 | return 1 / dist;
|
140 | }
|
141 |
|
\ | No newline at end of file |