hypertune
Version:
[Hypertune](https://www.hypertune.com/) is the most flexible platform for feature flags, A/B testing, analytics and app configuration. Built with full end-to-end type-safety, Git-style version control and local, synchronous, in-memory flag evaluation. Opt
68 lines • 2.58 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = calculateFrequentistMetrics;
function calculateZScore(conversionRateA, conversionRateB, standardError) {
return standardError
? (conversionRateB / conversionRateA - 1) / standardError
: 0;
}
function getZValueThreshold(confidence, oneSided) {
switch (oneSided) {
case false:
switch (confidence) {
case 0.9:
return 1.645;
case 0.95:
return 1.96;
case 0.99:
return 2.576;
default:
throw Error("Invalid confidence value");
}
default:
switch (confidence) {
case 0.9:
return 1.28;
case 0.95:
return 1.645;
case 0.99:
return 2.33;
default:
throw Error("Invalid confidence value");
}
}
}
// eslint-disable-next-line max-params
function calculateFrequentistMetrics(successes, visitors, controlIndex, confidence, oneSided) {
const armMetrics = {};
if (controlIndex < 0 ||
controlIndex >= successes.length ||
controlIndex >= visitors.length) {
return null;
}
successes.forEach((successB, i) => {
const successA = successes[controlIndex];
const visitorB = visitors[i];
const visitorA = visitors[controlIndex];
const conversionRateA = successA / visitorA;
const conversionRateB = successB / visitorB;
const standardErrorUplift = Math.sqrt((conversionRateA * (1 - conversionRateA)) / visitorA +
(conversionRateB * (1 - conversionRateB)) / visitorB) / conversionRateA;
const z = calculateZScore(conversionRateA, conversionRateB, standardErrorUplift);
const upLift = (conversionRateB - conversionRateA) / conversionRateA;
const isSignificant = oneSided
? z > getZValueThreshold(confidence, oneSided)
: Math.abs(z) > getZValueThreshold(confidence, oneSided);
const marginOfError = getZValueThreshold(confidence, oneSided) * standardErrorUplift;
const lowerBound = upLift - marginOfError;
const upperBound = upLift + marginOfError;
armMetrics[i] = {
upLift,
lowerBound,
upperBound,
isSignificant,
};
});
return armMetrics;
}
//# sourceMappingURL=calculateFrequentistMetrics.js.map