Last active
June 15, 2025 13:06
-
-
Save Ddhuet/100a885758cbb224322ee6e0168e0d56 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Claude Index Normalization Function | |
* | |
* This module provides functions to normalize rating data, particularly useful for: | |
* - Teacher/evaluator ratings that suffer from central tendency bias | |
* - Ratings where evaluators use different parts of the scale | |
* - Compressed or shifted rating distributions | |
* | |
* The core function blends original ratings with normalized scores based on | |
* a configurable alpha parameter, with automatic adjustment for compression. | |
*/ | |
/** | |
* Calculate the mean of an array of numbers | |
* @param {number[]} arr - Array of numeric values | |
* @return {number} - The arithmetic mean | |
*/ | |
function mean(arr) { | |
return arr.reduce((sum, val) => sum + val, 0) / arr.length; | |
} | |
/** | |
* Calculate the standard deviation of an array of numbers | |
* @param {number[]} arr - Array of numeric values | |
* @return {number} - The standard deviation | |
*/ | |
function stdDev(arr) { | |
const avg = mean(arr); | |
const squareDiffs = arr.map(value => Math.pow(value - avg, 2)); | |
return Math.sqrt(squareDiffs.reduce((sum, val) => sum + val, 0) / arr.length); | |
} | |
/** | |
* Calculate z-scores for an array of values | |
* @param {number[]} arr - Array of numeric values | |
* @return {number[]} - Array of z-scores | |
*/ | |
function zScores(arr) { | |
const avg = mean(arr); | |
const sd = stdDev(arr); | |
return sd !== 0 | |
? arr.map(val => (val - avg) / sd) | |
: arr.map(() => 0); // Handle case where all values are the same | |
} | |
/** | |
* The Claude Index Normalization Function | |
* | |
* Normalizes ratings using a blended approach that respects both | |
* the absolute values and relative rankings within the distribution. | |
* | |
* @param {number[]} ratings - Original ratings array | |
* @param {number} targetMean - Desired mean for normalized distribution (default: 5.5) | |
* @param {number} targetStdDev - Desired standard deviation (default: 1.5) | |
* @param {number} alpha - Blending factor between original and normalized scores (default: 0.3) | |
* 0 = completely normalized, 1 = original scores | |
* @param {number} compressionThreshold - SD threshold for detecting compressed ratings (default: 0.5) | |
* @return {number[]} - Array of normalized scores | |
*/ | |
function claudeIndexNormalize( | |
ratings, | |
targetMean = 5.5, | |
targetStdDev = 1.5, | |
alpha = 0.3, | |
compressionThreshold = 0.5 | |
) { | |
// Calculate original distribution statistics | |
const originalMean = mean(ratings); | |
const originalStdDev = stdDev(ratings); | |
// Calculate z-scores (how many standard deviations from the mean) | |
const zScoreValues = zScores(ratings); | |
// Detect compression in the ratings distribution | |
// If ratings are tightly compressed, we want to rely more on the normalized distribution | |
const compressionFactor = Math.min(1, originalStdDev / compressionThreshold); | |
// Adjust alpha based on compression (compressed ratings get lower effective alpha) | |
const effectiveAlpha = alpha * compressionFactor; | |
// Generate normalized values using blended approach | |
return ratings.map((rating, i) => { | |
// Transform to target distribution | |
const normalizedScore = targetMean + (zScoreValues[i] * targetStdDev); | |
// Blend between original and normalized score based on effective alpha | |
return (effectiveAlpha * rating) + ((1 - effectiveAlpha) * normalizedScore); | |
}); | |
} | |
/** | |
* Batch normalize multiple evaluators' ratings | |
* | |
* @param {Object[]} evaluators - Array of evaluator objects | |
* @param {string} evaluators[].id - Unique identifier for the evaluator | |
* @param {number[]} evaluators[].ratings - Array of ratings from this evaluator | |
* @param {Object} options - Normalization options | |
* @return {Object[]} - Array of evaluator objects with normalized ratings added | |
*/ | |
function batchNormalize(evaluators, options = {}) { | |
const { | |
targetMean = 5.5, | |
targetStdDev = 1.5, | |
alpha = 0.3, | |
compressionThreshold = 0.5 | |
} = options; | |
return evaluators.map(evaluator => { | |
const normalizedRatings = claudeIndexNormalize( | |
evaluator.ratings, | |
targetMean, | |
targetStdDev, | |
alpha, | |
compressionThreshold | |
); | |
return { | |
...evaluator, | |
normalizedRatings, | |
stats: { | |
originalMean: mean(evaluator.ratings), | |
originalStdDev: stdDev(evaluator.ratings), | |
normalizedMean: mean(normalizedRatings), | |
normalizedStdDev: stdDev(normalizedRatings) | |
} | |
}; | |
}); | |
} | |
// Export the functions | |
module.exports = { | |
claudeIndexNormalize, | |
batchNormalize, | |
mean, | |
stdDev, | |
zScores | |
}; | |
/* Example import and usage | |
const { claudeIndexNormalize } = require('./claude-index'); | |
// Example teacher ratings | |
const teacherRatings = [7, 7.5, 8, 8.5, 9]; | |
// Apply normalization | |
const normalizedScores = claudeIndexNormalize(teacherRatings); | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment