Notebooks 2.0 is here.

Published
Edited
Oct 12, 2021
Fork of Simple D3
Insert cell
Insert cell
function entropy(data) {
// track data length (used a couple times)
const n = data.length;
// empty data has entropy of zero
if (n <= 1) {
return 0
};
// init counter
const counts = {}
// count occurrences of elements in data
for (const d of data) {
counts[d] = counts[d] ? counts[d] + 1 : 1;
}
// start entropy at 0
let entropyValue = 0;
// loop through data and calculate entropy
Object.keys(counts).forEach(c => {
// get relative frequency of item
const prob = counts[c] / n;
// if > 0, tally entropy
if (prob > 0) {
entropyValue -= prob * Math.log2(prob)
}
});
return entropyValue
}
Insert cell
function prob(data, positiveClass) {
// track data length (used a couple times)
const n = data.length;
// empty data has entropy of zero
if (n <= 1) {
return 0
};
// init counter
const counts = {}
// count occurrences of elements in data
for (const d of data) {
counts[d] = counts[d] ? counts[d] + 1 : 1;
}
// ensure value for class so no NaN
counts[positiveClass] = counts[positiveClass] ? counts[positiveClass] : 0;
return counts[positiveClass] / n
}
Insert cell
Insert cell
prob(['negative', 'negative'], 'positive')
Insert cell
entropy(['positive', 'positive', 'positive', 'positive'])
Insert cell
entropy(['positive', 'positive', 'positive', 'positive', 'negative'])
Insert cell
entropy(['positive', 'positive', 'negative', 'negative'])
Insert cell
Insert cell
{
// loop and create permutations of samples for nSamples
let permutations = [];
let data = [];

for (let i = 0; i <= nSamples; ++i) {
let j = nSamples - i;
// add i positive cases
let positiveSamples = new Array(i).fill('positive')
// append j negative cases
let negativeSamples = new Array(j).fill('negative')

let permutation = positiveSamples.concat(negativeSamples)
// append to permutations array
permutations.push(permutation)
// create data for plot
data.push({
perm: permutation,
entropy: entropy(permutation),
x: prob(permutation, 'positive')
})
}

console.log('data', data)

// Create entropy plot
const padding = 50;
const svg = d3.create("svg")
.attr("width", width)
.attr("height", height)
.style('outline', '1px solid black');


const areaGradient = svg.append("defs")
.append("linearGradient")
.attr("id","areaGradient")
.attr("x1", "0%").attr("y1", "0%")
.attr("x2", "0%").attr("y2", "100%");

areaGradient.append("stop")
.attr("offset", "0%")
.attr("stop-color", "coral")
.attr("stop-opacity", 0.76);
areaGradient.append("stop")
.attr("offset", "100%")
.attr("stop-color", "white")
.attr("stop-opacity", 0);

const xScale = d3.scaleLinear()
.domain([0, 1])
.range([padding, width - padding])

const yScale = d3.scaleLinear()
.domain([0, 1])
.range([height - padding, padding])

// add axes
// x
svg.append("g")
.attr('transform', `translate(${0}, ${height - padding})`)
.call(d3.axisBottom(xScale));
// y
svg.append("g")
.attr('transform', `translate(${padding}, 0)`)
.call(d3.axisLeft(yScale));
// draw line
svg.append('path')
.datum(data)
.style("fill", "url(#areaGradient)")
.attr("stroke", "coral")
.attr("stroke-width", 6)
.attr("d", d3.line()
.x(d => xScale(d.x))
.y(d => yScale(d.entropy))
)

// add title
svg.append('text')
.text(`Entropy Distribution for ${nSamples} Samples of Binary Class`)
.attr('x', width / 2)
.attr('y', 20)
.attr('text-anchor', 'middle')
.style('font-weight', 'bold')
.style('font-size', '1.2rem')

// add title
svg.append('text')
.text(`P(Positive Class)`)
.attr('x', width / 2)
.attr('y', height - padding/4)
.attr('text-anchor', 'middle')

svg.append('text')
.text(`Entropy`)
.attr('x', 60)
.attr('y', 50)
// .attr('text-anchor', 'middle')

return svg.node()
}
Insert cell
html`
<style>@import url("https://fonts.googleapis.com/css?family=Comfortaa");
* {
font-family: Comfortaa;
}
</style>`
Insert cell
height = 450
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