-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.js
191 lines (160 loc) · 6.64 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
let data = require("./data/finalUser.json");
const { kmean, silhouette } = require("./algorithm/index.js");
const _ = require("lodash");
const fs = require('fs');
const { distance } = require("./algorithm/utils");
function describeOneClass(arrayItem, attributes) {
let obj = {};
let data = []
for (let i = 0; i < attributes.length; i++) {
let max = _.maxBy(arrayItem, function (o) {
return o[attributes[i]];
});
let min = _.minBy(arrayItem, function (o) {
return o[attributes[i]];
});
let mean = _.meanBy(arrayItem, function (o) {
return o[attributes[i]];
});
let nullValue = arrayItem.reduce((accumulator, currentValue) => {
if(currentValue[attributes[i]] === null) {
accumulator = accumulator + 1
}
return accumulator
}, 0)
data = arrayItem.map(item => item[attributes[i]])
obj[attributes[i]] = {
max: max[attributes[i]],
min: min[attributes[i]],
mean: mean,
null: nullValue,
data
};
}
return obj;
}
function describe(data) {
let result = describeOneClass(data, [
"visitScore",
"spendingRank"
])
return result
}
function mainProcess(k) {
data = data.map(item => {
return ({
"userID": item.userID,
"visitScore": parseInt(item.visitScore),
"spendingRank": parseFloat(item.spendingRank)
})
})
// console.log(data.length)
// tính toán min, max, mean, null của dataset
let descriptData = describe(data)
// đếm số lượng dữ liệu ban đầu
let countItemOriginal = data.length
// chúng ta sẽ xử lý dữ liệu đầu vào
trainData = _.uniqWith(data, function(arr, other) {
return arr.visitScore === other.visitScore && arr.spendingRank === other.spendingRank
})
trainData = trainData.filter(item => {
return item.visitScore >= 0 && item.visitScore <= 100 && item.spendingRank >= 0 && item.spendingRank <= 100
})
// console.log(trainData)
// console.log('unique data', trainData.length)
// tính giá trị distortion và inertia của k từ 1 cho đến 10
let distortions = []
let inertias = []
for(let i = 1; i <= 10; i++) {
let r = kmean(trainData, i, [
"userID",
// "visitScore",
// "spendingRank"
]);
distortions.push({
k: i,
distortion: r.distortion
})
inertias.push({
k: i,
inertia: r.inertia
})
}
// sau khi có k xong chúng ta thực hiện dùng k đó để thực hiện phân cụm
result = kmean(trainData, k, [
"userID",
// "visitScore",
// "spendingRank"
])
// tính toán lại silhoutte của giá trị k
let silhoutteResult = silhouette(result.groupArray)
fs.writeFileSync('./data/train.json', JSON.stringify(trainData))
// tính toán tổng số data point trong dữ liệu
let countItemKmeanData = trainData.length
// lưu vào file
fs.writeFileSync('./data/original.json', JSON.stringify({
countItemOriginal,
countItemKmeanData,
descriptData,
data
}), { flag: 'w' })
// lưu tất cả kết quả của kmean
fs.writeFileSync('./data/initialKmean.json', JSON.stringify({
distortions,
inertias,
silhoutteResult
}), { flag: 'w' })
fs.writeFileSync('./data/kmean.json', JSON.stringify({
groupArray: result.groupArray,
arrayCentroid: result.arrayCentroid,
distortion: result.distortion,
}), { flag: 'w' })
}
let r = mainProcess(5)
console.log('Done')
function demoSmallData() {
let arrayPoint = [
{ x: 3, y: 5 },
{ x: 1, y: 4 },
{ x: 1, y: 5 },
{ x: 2, y: 6 },
{ x: 8, y: 8 },
{ x: 7, y: 6 },
{ x: 6, y: 7 },
{ x: 5, y: 6 }
]
// let xC = 6.5
// let yC = 6.75
// arrayPoint.forEach(item=>{
// console.log(item)
// console.log(Math.sqrt(Math.pow(item.x - xC, 2) + Math.pow(item.y - yC, 2)))
// })
console.log("Tập dữ liệu ban đầu")
console.log(arrayPoint)
let result = kmean(arrayPoint, 2, [])
console.log(result.arrayCentroid)
console.log('inertia', result.inertia)
console.log("Tập dữ liệu sau khi dùng kmean")
console.log(result.groupArray)
let sum = 0
for(let i = 0 ; i < result.groupArray[0].length; i++) {
sum += Math.pow(distance(result.groupArray[0][i], result.arrayCentroid[0], []), 2)
// sum += distance(result.groupArray[0][i], result.arrayCentroid[0], [])
}
console.log(sum)
sum = 0
for(let i = 0 ; i < result.groupArray[1].length; i++) {
sum += Math.pow(distance(result.groupArray[1][i], result.arrayCentroid[1], []), 2)
// sum += distance(result.groupArray[1][i], result.arrayCentroid[1], [])
}
console.log(sum)
console.log(result.distortion)
}
// demoSmallData()
// • Bước 1: Chỉ định ra số lượng K clsuters
// • Bước 2: Khởi tạo các điểm centroid bằng việc trộn tất cả dataset và lấy ngẫu nhiên ra K điểm data points làm centroid.
// • Bước 3: Tính khoảng cách giữa centroid và datapoint. Sau đó, gán data point với cluster gần nhất (centroid).
// • Bước 4: Tính toán lại tất cả centroid bằng việc tính trung bình cộng của tất cả data point mà những điểm thuộc mỗi cluster.
// • Bước 5: Lặp cho đến khi không có sự thay đổi giữa các centroid (những điểm data point được gán tới clusters không bị thay đổi)
// • Bước 6: Nếu phần tử của bất kì clusters nào đó không bị đổi thì dừng thuật toán, nếu không thì tiếp tục bước 3.
// • Bước 7: Tính trung bình của bình phương khoảng cách giữa datapoints và centroid – Distortion (Có nghĩa là trước hết với một cụm, tính tổng bình phương khoảng cách từ centroid với các điểm thuộc về centroid đó, làm tương tự với những cluster khác, cuối cùng thì chúng ta sẽ chia cho tổng số lượng tất cả datapoint. Một cluster sẽ có 1 centroid và nhiều datapoint của cluster đó, chọn 2C1 để tính khoảng cách thì sẽ có n trường hợp. Ví dụ: cluster1 (n1 trường hợp), cluster 2 (n2 trường hợp), cluster 3 (n3 trường hợp) thì cuối cùng cũng bằng với tổng số lượng datapoints).