UNPKG

@visactor/vmind

Version:

<div align="center"> <a href="https://github.com/VisActor#gh-light-mode-only" target="_blank"> <img alt="VisActor Logo" width="200" src="https://github.com/VisActor/.github/blob/main/profile/logo_500_200_light.svg"/> </a> <a href="https://githu

71 lines (65 loc) 2.79 kB
"use strict"; function jaccardSimilarity(columnA, columnB) { if (columnA.length !== columnB.length) throw new Error("Columns must be of the same length"); let intersection = 0, union = 0; for (let i = 0; i < columnA.length; i++) 1 !== columnA[i] && 1 !== columnB[i] || (union++, 1 === columnA[i] && 1 === columnB[i] && intersection++); return intersection / union; } function calculateClusterDistance(clusterA, clusterB) { let sumDistance = 0; for (const itemA of clusterA.children) for (const itemB of clusterB.children) { sumDistance += 1 - jaccardSimilarity(itemA.value, itemB.value); } return sumDistance / (clusterA.children.length * clusterB.children.length); } function calculateDistanceMatrix(data) { const n = data.length, distanceMatrix = Array.from({ length: n }, (() => Array(n).fill(0))); let minDistance = 1; const distancePair = [ 0, 0 ]; for (let i = 0; i < n; i++) for (let j = i + 1; j < n; j++) { const distance = calculateClusterDistance(data[i], data[j]); distanceMatrix[i][j] = distance, distanceMatrix[j][i] = distance, distance < minDistance && (minDistance = distance, distancePair[0] = i, distancePair[1] = j); } return { distanceMatrix: distanceMatrix, minDistance: minDistance, distancePair: distancePair }; } Object.defineProperty(exports, "__esModule", { value: !0 }), exports.agglomerativeHierarchicalClustering = exports.calculateDistanceMatrix = exports.jaccardSimilarity = void 0, exports.jaccardSimilarity = jaccardSimilarity, exports.calculateDistanceMatrix = calculateDistanceMatrix; const agglomerativeHierarchicalClustering = (data, threshold = .4) => { const clusters = data.map(((v, i) => ({ id: i, children: [ v ] }))), clusterMap = new Map; let hasMerged = !0; for (;hasMerged && clusters.length > 1; ) { hasMerged = !1; const {minDistance: minDistance, distancePair: distancePair} = calculateDistanceMatrix(clusters); if (minDistance <= threshold) { const mergedCluster = { id: clusters.length, children: [ ...clusters[distancePair[0]].children, ...clusters[distancePair[1]].children ] }; clusters.splice(distancePair[0], 1), clusters.splice(distancePair[1] - 1, 1), clusters.push(mergedCluster), hasMerged = !0; } } return clusters.forEach(((v, i) => { v.children.forEach((item => { clusterMap.set(item.id, i); })); })), { clusters: clusters, clusterMap: clusterMap }; }; exports.agglomerativeHierarchicalClustering = agglomerativeHierarchicalClustering; //# sourceMappingURL=cluster.js.map