Я пытаюсь написать функцию k-mean в javascript. И вот мой код.Почему я получаю NaN, когда переключаю петлю?
function kmeans(arrayToProcess,cluster_n){
var pointDimension = arrayToProcess[0].length;
var ClusterResult = new Array();
var ClusterCenter = new Array();
var oldClusterCenter = new Array();
var changed=false;
for(var i = 0;i<cluster_n;i++)
ClusterCenter.push(arrayToProcess[randomInt(arrayToProcess.length-1)]);
console.log(ClusterCenter);
// do{
for(var k=0;k<50;k++){//loop
for(var i = 0; i<cluster_n; i++){
ClusterResult[i] = new Array();
}
for(var i = 0; i<arrayToProcess.length; i++){
//for every point element
var oldDistance=-1;
var newClusterNumber = 0;
for(var j = 0; j<cluster_n; j++){
//for every cluster
var distance = Math.abs(computeDistanceBetween(arrayToProcess[i], ClusterCenter[j]));
if (oldDistance == -1){
oldDistance = distance;
newClusterNumber = j;
}else if (distance <= oldDistance){
newClusterNumber = j;
oldDistance = distance;
}
}
ClusterResult[newClusterNumber].push(arrayToProcess[i]);
}
oldClusterCenter = ClusterCenter;
//compute new centroid
for(var i = 0; i<cluster_n; i++){
newCentroid = pinit(pointDimension);
for(var j = 0; j<ClusterResult[i].length; j++){
newCentroid = padd(ClusterResult[i][j], newCentroid);
}
ClusterCenter[i] = pdivide(newCentroid, ClusterResult[i].length);
}
changed=false;
for(var i = 0; i<cluster_n; i++){
if(!pequal(ClusterCenter[i],oldClusterCenter[i]))
changed = true;
}
}//while (changed == true);
return ClusterResult;
}
function computeDistanceBetween(a,b){
var result = 0;
for(var i = 0; i<a.length;i++) result += a[i] * b[i];
return result;
}
function pinit(n){
var result = new Array(n);
for(var i=0;i<n;i++) result[i] = 0;
return result;
}
function padd(a,b){
var result = new Array(a.length);
for(var i = 0; i<a.length;i++) result[i] = a[i] + b[i];
return result;
}
function pdivide(a,d){
var result = new Array(a.length);
for(var i = 0; i<a.length;i++) result[i] = a[i]/d;
return result;
}
function pequal(a,b){
for(var i = 0; i<a.length;i++)
if(a[i] != b[i]) return false;
return true;
}
function randomInt(max){
return randomIntBetween(0,max);
}
function randomIntBetween(min,max){
return Math.floor(Math.random() * (max - min + 1)) + min;
}
Если я остановить для петли (к < 0), консоль дает правильный ответ. Но если я запустил for-loop (k < 1), массив ClusterCenter всегда будет иметь некоторые элементы NaN. Как доза NaN появляется?
Редактировать: Дальнейшее объяснение: если цикл for в 14-й строке был выполнен, ClusterCenter выше предоставит некоторые пункты NaN. Почему?
Пример входных данных
var testArray = new Array();
for(var i=0; i<100; i++) testArray.push([randomInt(-150,150),randomInt(-150,150)]);
kmeans(testArray,4);
FYI NaN = не число, JS возвращает это, когда вы кладете некоторые «не цифры 'в середине математических операций. – enapupe
Можете ли вы воспользоваться некоторыми примерами ввода? Кроме того, что означает «*, если я останавливаю цикл *» и «*, если я начинаю цикл» означает, что только варианты кода не работают? – Bergi
@Bergi Спасибо за ваш ответ. Я добавил «Дальнейшее объяснение» и «Пример ввода». – cusr