K-means.js 1.87 KB
  const getDataRanges = (extremes) => {
    var ranges = [];

    for (var dimension in extremes) {
      ranges[dimension] = extremes[dimension].max - extremes[dimension].min;
    }

    return ranges;
  }

  const getDataExtremes = (data)=> {
    var extremes = [];

    for (var i in data) {
      var point = data[i];

      for (var dimension in point) {
        if (!extremes[dimension]) {
          extremes[dimension] = { min: 1000, max: 0 };
        }

        if (point[dimension] < extremes[dimension].min) {
          extremes[dimension].min = point[dimension];
        }

        if (point[dimension] > extremes[dimension].max) {
          extremes[dimension].max = point[dimension];
        }
      }
    }

    return extremes;
  }

  const initMeans = (k, dataExtremes, dataRange) => {
    if (!k) {
      k = 3;
    }
    const means = [];
    while (k--) {
      var mean = [];
      for (var dimension in dataExtremes) {
        mean[dimension] = dataExtremes[dimension].min + Math.random() * dataRange[dimension];
      }

      means.push(mean);
    }

    return means;
  }

  const makeAssignments = (means, data) => {
    const assignments = {};
    for (var i in data) {
      var point = data[i];
      var distances = [];
      for (var j in means) {
        var mean = means[j];
        var sum = 0;

        for (var dimension in point) {
          var difference = point[dimension] - mean[dimension];
          difference *= difference;
          sum += difference;
        }

        distances[j] = Math.sqrt(sum);
      }
      assignments[i] = distances.indexOf(Math.min.apply(null, distances));
    }
    return assignments;
  }
const setup = (data) => {
    const dataExtremes = getDataExtremes(data);
    const dataRange = getDataRanges(dataExtremes);
    const means = initMeans(3, dataExtremes, dataRange);

    return makeAssignments(means, data);
  }

export default setup;