Эх сурвалжийг харах

Compute real metrics so scaling works right

Kirk Trombley 3 жил өмнө
parent
commit
0bc530c606
1 өөрчлөгдсөн 14 нэмэгдсэн , 15 устгасан
  1. 14 15
      nearest.js

+ 14 - 15
nearest.js

@@ -121,8 +121,8 @@ const state = {
 };
 
 // Metrics
-const getBestKMean = (stats, q) => argMin(stats.kMeans.map((z, i) => vectorSqDist(z.vector, q.vector) / stats.kWeights[i]));
-const getWorstKMean = (stats, q) => argMax(stats.kMeans.map((z, i) => vectorSqDist(z.vector, q.vector) / stats.kWeights[i]));
+const getBestKMean = (stats, q) => argMin(stats.kMeans.map((z, i) => vectorDist(z.vector, q.vector) / stats.kWeights[i]));
+const getWorstKMean = (stats, q) => argMax(stats.kMeans.map((z, i) => vectorDist(z.vector, q.vector) / stats.kWeights[i]));
 
 const getScale = weight => state.includeScale ? (1 / weight) : 1;
 
@@ -147,6 +147,8 @@ const summarySelectors = [
 
 const selectedSummary = (stats, q) => summarySelectors[state.clusterChoice](stats, q);
 
+// TODO unfortunately the addition of the scaling factor means we have to compute *real*
+// metrics instead of cheaper approximations. would be nice to fix this
 const metrics = [
   // RMS
   (stats, q) => { 
@@ -156,14 +158,13 @@ const metrics = [
   // mean angle
   (stats, q) => {
     const [ mean, scale ] = selectedSummary(stats, q);
-    // divide by scale since we're negative
-    return -vectorDot(mean.unit, q.unit) / scale
+    return rad2deg * Math.acos(vectorDot(mean.unit, q.unit)) * scale;
   },
   // mean dist
   (stats, q) => {
     const [ mean, scale ] = selectedSummary(stats, q);
     // TODO I know there's some way to avoid recalculation here but I'm just too lazy right now
-    return vectorSqDist(mean.vector, q.vector) * scale;
+    return vectorDist(mean.vector, q.vector) * scale;
   },
   // hue angle
   (stats, q) => {
@@ -173,8 +174,7 @@ const metrics = [
   // max inertia
   (stats, q) => {
     const [ , scale ] = selectedSummary(stats, q);
-    // divide by scale since we're negative
-    return -stats.inertia / scale;
+    return -stats.inertia * scale;
   },
   // custom
   (stats, q) => {
@@ -238,19 +238,18 @@ const mathDefinitions = {
   `,
 };
 
-const includeScaleFactor = () => state.clusterChoice > 0 && state.includeScale
+const includeScaleFactor = muArg => state.clusterChoice > 0 && state.includeScale ? String.raw`\frac{\left|P\right|}{\left|${muArg}\right|}` : ""
 
 const metricText = [
   muArg => String.raw`
     ${mathArgBest("min", "P")}\left[
-      ${includeScaleFactor() ? String.raw`\frac{\left|P\right|}{\left|${muArg}\right|}\left(` : ""}
-      I\left(P\right) - 2\vec{q}\cdot \vec{\mu}\left(${muArg}\right)
-      ${includeScaleFactor() ? String.raw`\right)` : ""}
+      ${includeScaleFactor(muArg)}I\left(P\right) 
+      - 2\vec{q}\cdot ${includeScaleFactor(muArg)}\vec{\mu}\left(${muArg}\right)
     \right]`,
-  muArg => String.raw`${mathArgBest("min", "P")}\left[-${includeScaleFactor() ? String.raw`\frac{\left|${muArg}\right|}{\left|P\right|}` : ""}\cos\left(\angle \left(\vec{q}, \vec{\mu}\left(${muArg}\right)\right)\right)\right]`,
-  muArg => String.raw`${mathArgBest("min", "P")}\left[${includeScaleFactor() ? String.raw`\frac{\left|P\right|}{\left|${muArg}\right|}` : ""}\left|\left| \vec{q} - \vec{\mu}\left(${muArg}\right) \right|\right|^2\right]`,
-  muArg => String.raw`${mathArgBest("min", "P")}\left[${includeScaleFactor() ? String.raw`\frac{\left|P\right|}{\left|${muArg}\right|}` : ""}\angle \left(\vec{q}_{\perp}, \vec{\mu}\left(${muArg}\right)_{\perp} \right)\right]`,
-  muArg => String.raw`${mathArgBest("min", "P")}\left[-${includeScaleFactor() ? String.raw`\frac{\left|${muArg}\right|}{\left|P\right|}` : ""}I\left(P\right)\right]`,
+  muArg => String.raw`${mathArgBest("min", "P")}\left[${includeScaleFactor(muArg)}\angle \left(\vec{q}, \vec{\mu}\left(${muArg}\right)\right)\right]`,
+  muArg => String.raw`${mathArgBest("min", "P")}\left[${includeScaleFactor(muArg)}\left|\left|\vec{q} - \vec{\mu}\left(${muArg}\right) \right|\right|\right]`,
+  muArg => String.raw`${mathArgBest("min", "P")}\left[${includeScaleFactor(muArg)}\angle \left(\vec{q}_{\perp}, \vec{\mu}\left(${muArg}\right)_{\perp}\right)\right]`,
+  muArg => String.raw`${mathArgBest("min", "P")}\left[-${includeScaleFactor(muArg)}I\left(P\right)\right]`,
 ].map(s => muArg => TeXZilla.toMathML(s(muArg)));
 
 const muArgs = [