Public
Edited
Nov 4, 2023
1 star
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
{
const plt = Plot.plot({
width: 600,
height: 600,
grid: true,
aspectRatio: 1.0,
x: { nice: true, axis: "top" },
y: { nice: true, reverse: true },
color: { legend: true, domain: [0, 1], scheme: "Inferno" },
marks: [
Plot.frame(),
Plot.contour(data, {
x: "pr",
y: "nr",
fill: select,
opacity: 1.0
}),
Plot.dot(data, {
x: "pr",
y: "nr",
fill: select,
tip: true,
opacity: 0.5
}),
segments > 20
? undefined
: Plot.text(data, {
x: "pr",
y: "nr",
text: (d) => d[select].toFixed(2),
fill: "white",
fontSize: 10
})
]
});

img.width = 450;
img.height = 450;

return htl.html`
<div style="display: flex; align-items: center">
${plt}
<div>
<h2>${select}</h2>
${img}
</div>
</div>
`;
}
Insert cell
img.width
Insert cell
Insert cell
Insert cell
data = mkData(numPositive, numNegative, segments)
Insert cell
data
Type Table, then Shift-Enter. Ctrl-space for more options.

Insert cell
exampleData = mkData(10, 10, 20)
Insert cell
mkData = (p, n, s) => {
const data = [],
pr = linspace(0.01, 0.99, s), //d3.range(0.01, 1, 0.1),
nr = linspace(0.01, 0.99, s); //d3.range(0.01, 1, 0.1);

pr.map((pr) => {
nr.map((nr) => {
const tp = pr * p,
fn = p - tp,
tn = nr * n,
fp = n - tn,
pp = tp + fp,
pn = fn + tn;

data.push({ p, n, pr, nr, tp, fn, fp, tn, pp, pn });
});
});

methods.map((method) => data.map(method));

return data;
}
Insert cell
linspace(0.01, 0.99, 50)
Insert cell
linspace = (start, stop, num) => {
const step = (stop - start) / num;

return d3.range(start, stop + step, step).filter((d) => d <= 1.0);
}
Insert cell
Insert cell
Insert cell
/**
* Make sure the methods are operated in-order
* The methods are described in https://en.wikipedia.org/wiki/Confusion_matrix
*/
methods = [
prevalence,
accuracy,
truePositiveRate,
falseNegativeRate,
falsePositiveRate,
trueNegativeRate,
informedness,
prevalenceThreshold,
balancedAccuracy,
positivePredictiveValue,
falseDiscoveryRate,
f1Score,
falseOmissionRate,
negativePredictiveValue,
fowlkesMallowsIndex,
positiveLikelihoodRatio,
negativeLikelihoodRatio,
markedness,
diagnosticOddsRatio,
matthewsCorrelationCoefficient,
criticalSuccessIndex
]
Insert cell
diagnosticOddsRatio = (obj) => {
const {lrp, lrn} = obj,
dor =lrp / lrn;

Object.assign(obj, {dor})
}
Insert cell
matthewsCorrelationCoefficient = (obj) => {
const {tpr, tnr, ppv, npv, fnr, fpr, for:_for, fdr} = obj,
mcc=Math.sqrt(tpr*tnr*ppv*npv) - Math.sqrt(fnr*fpr*_for*fdr);

Object.assign(obj, {mcc})
}
Insert cell
criticalSuccessIndex = (obj) => {
const { tp, fn, fp } = obj,
csi = tp / (tp + fn + fp);

Object.assign(obj, { csi });
}
Insert cell
markedness = (obj) => {
const { ppv, npv } = obj,
mk = ppv + npv - 1;

Object.assign(obj, { mk });
}
Insert cell
positiveLikelihoodRatio = (obj) => {
const {tpr, fpr} = obj,
lrp = tpr / fpr;

Object.assign(obj, {lrp})
}
Insert cell
negativeLikelihoodRatio = (obj) => {
const { fnr, tnr } = obj,
lrn = fnr / tnr;

Object.assign(obj, { lrn });
}
Insert cell
fowlkesMallowsIndex = (obj) => {
const { ppv, tpr } = obj,
fm = Math.sqrt(ppv * tpr);

Object.assign(obj, { fm });
}
Insert cell
falseOmissionRate = (obj) => {
const { fn, pn } = obj,
_for = fn / pn;

Object.assign(obj, { for: _for });
}
Insert cell
negativePredictiveValue = (obj) => {
const { tn, pn } = obj,
npv = tn / pn;

Object.assign(obj, { npv });
}
Insert cell
f1Score = (obj) => {
const { tp, fp, fn } = obj,
f1 = (2 * tp) / (2 * tp + fp + fn);

Object.assign(obj, { f1 });
}
Insert cell
falseDiscoveryRate = (obj) => {
const { fp, tp } = obj,
fdr = fp / (fp + tp);

Object.assign(obj, { fdr });
}
Insert cell
positivePredictiveValue = (obj) => {
const { tp, fp } = obj,
ppv = tp / (tp + fp);

Object.assign(obj, { ppv });
}
Insert cell
balancedAccuracy = (obj) => {
const { tpr, tnr } = obj,
ba = (tpr + tnr) / 2;

Object.assign(obj, { ba });
}
Insert cell
prevalenceThreshold = (obj) => {
const { tpr, fpr } = obj,
pt = (Math.sqrt(tpr * fpr) - fpr) / (tpr - fpr);

Object.assign(obj, { pt });
}
Insert cell
informedness = (obj) => {
const { tpr, tnr } = obj,
bm = tpr + tnr - 1;

Object.assign(obj, { bm });
}
Insert cell
trueNegativeRate = (obj) => {
const { tn, fp } = obj,
tnr = tn / (tn + fp);

Object.assign(obj, { tnr });
}
Insert cell
falsePositiveRate = (obj) => {
const { n, fp } = obj,
fpr = fp / n;

Object.assign(obj, { fpr });
}
Insert cell
falseNegativeRate = (obj) => {
const {p, fn} =obj,
fnr = fn / p;

Object.assign(obj, {fnr})
}
Insert cell
truePositiveRate = (obj) => {
const { p, tp } = obj,
tpr = tp / p;

Object.assign(obj, { tpr });
}
Insert cell
accuracy = (obj) => {
const { p, n, tp, tn } = obj,
accuracy = (tp + tn) / (p + n);

Object.assign(obj, { accuracy });
}
Insert cell
prevalence = (obj) => {
const {p, n } = obj,
prevalence = p / (p + n);

Object.assign(obj, { prevalence });
}
Insert cell
Insert cell
d3 = require("d3")
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more