Public
Edited
Mar 19, 2023
Insert cell
Insert cell
Insert cell
toc()
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
md`
Q: Can you give me an example of why this would be useful?

A: Yes! Imagine you want to use data leverage against LargeCo. You have a limited budget (of money, your time, etc.), so need to decide if you want to focus on helping people join a data strike or engage in CDC. If you can find a rough estimate for the scaling laws of the tech you hope to impact, you can use the power laws to reason about how much a data strike might hurt LargeCo and how much CDC will help SmallCo. If the system has a large scaling coefficient (${tex `\alpha`}), CDC may be extra valuable. Conversely, if the system has a a small scaling coefficient, data strikes may be extra effective. The exact best choice will come down to the specific costs required to get participants. Even relying on rough estimates of the scaling coefficient, the number of people involved, the costs involved, etc., we hypothesize that this approach for thinking about data leverage effectiveness can still be a useful tool.
`
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
viewof rightLabel = Text({value: 'Loss'});
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
configs
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
md`
## Tabular Summary of Power Laws in Prior Work (WIP)
`
Insert cell
viewof RW = Table(priorWork)
Insert cell
configs = priorWork.reduce(function(map, obj) {
map[obj.Paper + obj.Task] = {
alpha: obj.alpha, D_min: obj.D_min, D_max: obj.D_max, L_0: obj.L_0, loss: obj.loss, SPP: obj.SPP
}
return map;
}, {});
Insert cell
Insert cell
Insert cell
Insert cell
function transform(x) {
if (x > 0.85){
return 1 + x
} else{
return 0.5 + x
}
}
Insert cell
function helper(d){
return {size: d.size, value: transform(d.value)}
}
Insert cell
utilityData = data.map(helper)
Insert cell
utilities = utilityData.map(d => d.value)
Insert cell
{
// Create an empty SVG with specified width and height.
const svg2 = d3.select(DOM.svg(width, height));
//create background
svg2.append("rect")
.attr("width", "100%")
.attr("height", "100%")
.attr("class", "svgBackground");
// Draw the x and y axes.
svg2.append('g').call(xAxis)
svg2.append('g').call(utilityAxis);
svg2.append('path')
.datum(utilityData)
.attr('d', utilityLine);
return svg2.node();
}
Insert cell
Insert cell
md`
We'll use 1000 fractional sizes from 0.001 to 1.000 with step size 0.001.
`
Insert cell
fracs = [...Array(999).keys()].map(x => (x+1)/1000)
Insert cell
mode = Object({
true: 'strike',
false: 'cdc'
})[invert]
Insert cell
sizes = fracs.map(x => x * maxObs);
Insert cell
Insert cell
calcLoss = D => C * (D ** -k) + bayesError
Insert cell
losses = Object({
strike: sizes.map(x=> calcLoss(maxObs-x)),
cdc: sizes.map(calcLoss)
})[mode]
Insert cell
minLoss = Math.min(...losses)
Insert cell
maxLoss = Math.max(...losses)
Insert cell
lossRange = maxLoss - minLoss
Insert cell
dlpFunction = Object({
strike: loss => (loss - minLoss) / (maxLoss - minLoss),
cdc: loss => (loss - maxLoss) / (minLoss - maxLoss)
})
Insert cell
scaleLoss = dlpFunction[mode]
Insert cell
scaledLosses = losses.map(scaleLoss)
Insert cell
scaledSizes = sizes.map(x=>x/ Math.max(...sizes))
Insert cell
function formatData (x, i) {
return {size: x, value: scaledLosses[i]}
}
Insert cell
data = scaledSizes.map(formatData)
Insert cell
percent = i * 100
Insert cell
chosenFrac = percent / 100
Insert cell
curScore = Object({
strike: scaleLoss(calcLoss((1-chosenFrac) * maxObs)),
cdc: scaleLoss(calcLoss(chosenFrac * maxObs))
})[mode]

Insert cell
complementScore = 1 - curScore;
Insert cell
curUsers = (chosenFrac * maxUsers).toFixed(0);
Insert cell
md`
### Figure 1 Annotations
`
Insert cell
leftAnnotation = Object({ //for cdc, left annotation is cdc
cdc: `CDC by ${percent.toFixed(0)}% (${curUsers} people) brings performance from 0 to ${(curScore).toFixed(2)}`,
strike: `Data strike by ${(percent).toFixed(0)}% (${curUsers} people) decreases perfomance by ${(curScore).toFixed(2)} to ${(complementScore).toFixed(2)}`,
})[mode]
Insert cell
rightAnnotation = Object({ // for strike, right annotation is cdc
strike: `CDC by ${100-percent.toFixed(0)}%(${maxUsers - curUsers} people) brings performance from 0 to ${(complementScore).toFixed(2)}`,
cdc: `Data strike by ${(100 - percent).toFixed(0)}% (${maxUsers - curUsers} people) decreases perfomance by ${(complementScore).toFixed(2)} to ${(curScore).toFixed(2)}`,
})[mode]
Insert cell
niceStr = Object({
cdc: 'Contribution',
strike: 'Strike',
})[mode]
Insert cell
function flip() {
set(viewof i, 1 - i)
set(viewof invert, !invert)
}
Insert cell
viewof invert = Toggle({label: "Show Strike Perspective", value:false})
Insert cell
md`
### Figure 1 Crosshairs
`
Insert cell
Insert cell
Insert cell
Insert cell
height = 500
Insert cell
Insert cell
md`
### Misc Code: Defining d3 scale and d3 axis elements
`
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
forLossScale = Object({
strike: [d3.min(losses), d3.max(losses)],
cdc: [d3.max(losses), d3.min(losses)]
})[mode]
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
line = d3.line()
.defined(d => !isNaN(d.value))
.x(d => xScale(d.size))
.y(d => yScale(d.value))
Insert cell
utilityLine = d3.line()
.defined(d => !isNaN(d.value))
.x(d => xScale(d.size))
.y(d => utilityScale(d.value))
Insert cell
md`
## Import Statements
`
Insert cell
import {Button, Checkbox, Toggle, Range, Select, Table, Text, html} from "@observablehq/inputs"
Insert cell
import {Scrubber} from "@mbostock/scrubber"
Insert cell
html`
<style>
path {
fill: none;
stroke: steelblue;
stroke-width: 1.5;
stroke-linejoin: round;
stroke-linecap: round;
}
button {
background-color: #4B0082;
border: none;
color: white;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
}

input[type=range] {
font-size: 16px;
}
.svgBackground {fill: #fffbeb;}
.annotateBackground {background: brown;}

</style>`
Insert cell
d3 = require("d3@6")
Insert cell
function set(input, value) {
input.value = value;
input.dispatchEvent(new Event("input"));
}
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more