Skip to content

Instantly share code, notes, and snippets.

@pedrobertao
Created March 3, 2025 12:51
Show Gist options
  • Save pedrobertao/b78bde1001b55840a927716568eff5af to your computer and use it in GitHub Desktop.
Save pedrobertao/b78bde1001b55840a927716568eff5af to your computer and use it in GitHub Desktop.
Modified Z-Score by Claude.ai
package main
import (
"fmt"
"math"
"sort"
)
// RemoveOutliersSmallDataset removes outliers from a small dataset using the Modified Z-score method
// threshold is typically 3.5 (more conservative) to 3.0 (more aggressive)
func RemoveOutliersSmallDataset(prices []float64, threshold float64) []float64 {
if len(prices) <= 3 {
return prices // Not enough data to determine outliers
}
// Calculate the median
sortedCopy := make([]float64, len(prices))
copy(sortedCopy, prices)
sort.Float64s(sortedCopy)
var median float64
n := len(sortedCopy)
if n%2 == 0 {
median = (sortedCopy[n/2-1] + sortedCopy[n/2]) / 2
} else {
median = sortedCopy[n/2]
}
// Calculate the Median Absolute Deviation (MAD)
deviations := make([]float64, len(prices))
for i, price := range prices {
deviations[i] = math.Abs(price - median)
}
sort.Float64s(deviations)
var mad float64
if n%2 == 0 {
mad = (deviations[n/2-1] + deviations[n/2]) / 2
} else {
mad = deviations[n/2]
}
// Constant factor for normal distribution
const c = 0.6745
// Handle the case where MAD is zero (can happen with repeated values)
if mad == 0 {
// Alternative approach when MAD is zero - use a small epsilon or
// simply return the original data since there's no variation
return prices
}
// Filter based on Modified Z-scores
result := []float64{}
for _, price := range prices {
modifiedZScore := math.Abs((price - median) / (mad * c))
if modifiedZScore <= threshold {
result = append(result, price)
}
}
return result
}
// Usage example
func main() {
prices := []float64{10.2, 14.1, 14.4, 14.4, 14.4, 14.5, 14.5, 14.6, 14.7, 15.0, 45.0}
filteredPrices := RemoveOutliersSmallDataset(prices, 3.5)
fmt.Println("Unfiltered", prices)
// Unfiltered [10.2 14.1 14.4 14.4 14.4 14.5 14.5 14.6 14.7 15 45]
fmt.Println("Filtered", filteredPrices)
// Filtered [14.4 14.4 14.4 14.5 14.5 14.6 14.7]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment