#!/usr/bin/env python
"""Performs unweighted linear regression. Can be invoked from command line by
providing data pairs through stdin.
Nathan Baker, 2003"""
import math
from sys import stdin, stdout, stderr
""" Accepts list of x,y pairs as input. Returns dictionary of resuls """
def fit(data):
outdict = {}
# Get means
xmean = 0
ymean = 0
ndata = len(data)
for pair in data:
x = pair[0]
y = pair[1]
xmean = xmean + x
ymean = ymean + y
xmean = xmean/float(ndata)
ymean = ymean/float(ndata)
outdict["x mean"] = xmean
outdict["y mean"] = ymean
# Get variances
sxx = 0
syy = 0
sxy = 0
for pair in data:
x = pair[0]
y = pair[1]
sxx = sxx + (x-xmean)*(x-xmean)
syy = syy + (y-ymean)*(y-ymean)
sxy = sxy + (x-xmean)*(y-ymean)
covxx = sxx/float(ndata)
covyy = syy/float(ndata)
covxy = sxy/float(ndata)
outdict["xx covariance"] = covxx
outdict["xy covariance"] = covxy
outdict["yy covariance"] = covyy
# Slope
b = sxy/sxx
outdict["slope"] = b
# Intercept
a = ymean - b*xmean
outdict["intercept"] = a
# Correlation coefficient
r2 = sxy*sxy/sxx/syy
outdict["correlation coefficient (r^2)"] = r2
# Residual variance
s2 = (syy - b*sxy)/(float(ndata)-2)
s = math.sqrt(s2)
outdict["residual variance (s^2)"] = s2
# Slope error
eb = s/math.sqrt(sxx)
outdict["slope error"] = eb
# Intercept error
ea = s*math.sqrt((1/float(ndata)) + xmean*xmean/sxx)
outdict["intercept error"] = ea
return outdict
"""Main driver; reads from stdin"""
def main():
infile = stdin
stdout.write("Reading data from %s...\n" % infile.name)
data = []
while (1):
line = infile.readline()
if line == "":
break
line.strip()
words = line.split()
try:
pair1 = float(words[0])
pair2 = float(words[1])
data.append((pair1, pair2))
except Exception, str:
stderr.write("Ignoring unparseable line: %s\n" % line)
stdout.write("Read %d data points.\n" % len(data));
fitdict = fit(data);
keys = fitdict.keys()
keys.sort()
stdout.write("\nRESULTS:\n")
for key in keys:
stdout.write("%s: %g\n" % (key, fitdict[key]))
if __name__ == "__main__":
main()
|
|