Bulletproof statistical functions
This commit is contained in:
parent
f8c0d2d0c6
commit
1a65165015
2 changed files with 31 additions and 13 deletions
|
@ -2,7 +2,7 @@
|
|||
|
||||
(defsystem "dev.metalisp.survey"
|
||||
:description "A simple survey"
|
||||
:version "0.4.6"
|
||||
:version "0.4.7"
|
||||
:author "Marcus Kammer <marcus.kammer@metalisp.dev>"
|
||||
:source-control "git@git.sr.ht:~marcuskammer/dev.metalisp.survey"
|
||||
:licence "MIT"
|
||||
|
|
|
@ -10,6 +10,9 @@
|
|||
|
||||
(in-package #:ml-survey/stats)
|
||||
|
||||
(define-condition stats-error (error)
|
||||
((message :initarg :message :reader error-message)))
|
||||
|
||||
(defun preprocess-and-transpose (data)
|
||||
(apply #'mapcar #'list (mapcar #'cdr data)))
|
||||
|
||||
|
@ -21,19 +24,34 @@
|
|||
(reduce #'max numbers)))
|
||||
|
||||
(defun standard-deviation (numbers)
|
||||
(let* ((avg (mean numbers))
|
||||
(variance (/ (reduce #'+ (mapcar (lambda (x) (expt (- x avg) 2)) numbers))
|
||||
(1- (length numbers)))))
|
||||
(sqrt variance)))
|
||||
(handler-case
|
||||
(let ((len (length numbers)))
|
||||
(if (< len 2)
|
||||
(error 'stats-error :message "Need at least two numbers for standard deviation")
|
||||
(let ((avg (mean numbers)))
|
||||
(sqrt (/ (reduce #'+ (mapcar (lambda (x) (expt (- x avg) 2)) numbers))
|
||||
(1- len))))))
|
||||
(type-error ()
|
||||
(error 'stats-error :message "Invalid input for standard deviation calculation"))))
|
||||
|
||||
(defun mean (numbers)
|
||||
(handler-case
|
||||
(if (null numbers)
|
||||
(error 'stats-error :message "Cannot calculate mean of an empty list")
|
||||
(/ (reduce #'+ numbers) (length numbers)))
|
||||
(division-by-zero ()
|
||||
(error 'stats-error :message "Division by zero in mean calculation"))))
|
||||
|
||||
(defun median (numbers)
|
||||
(handler-case
|
||||
(let ((sorted (sort (copy-seq numbers) #'<))
|
||||
(count (length numbers)))
|
||||
(if (oddp count)
|
||||
(nth (floor count 2) sorted)
|
||||
(/ (+ (nth (1- (/ count 2)) sorted)
|
||||
(nth (/ count 2) sorted))
|
||||
2.0))))
|
||||
(len (length numbers)))
|
||||
(if (zerop len)
|
||||
(error 'stats-error :message "Cannot calculate median of an empty list")
|
||||
(if (oddp len)
|
||||
(nth (floor len 2) sorted)
|
||||
(/ (+ (nth (1- (/ len 2)) sorted)
|
||||
(nth (/ len 2) sorted))
|
||||
2))))
|
||||
(type-error ()
|
||||
(error 'stats-error :message "Invalid input for median calculation"))))
|
||||
|
|
Loading…
Add table
Reference in a new issue