#coding=utf-8
import math
import matplotlib.pyplot as plt
import numpy as np
'''
author
date 2013-12-20
description 分别用最小二乘法和梯度下降法求线性回归
'''
'''
梯度下降法
'''
def grediant(xset,yset,alpha,dgree):
theta_0 = 0;
theta_1 = 1;
length = len(xset)
jtheta = 0
total = 0
sum_total = 0
for index in range(0,length):
print index
total = total + theta_0 + theta_1 * xset[index] - yset[index]
tmp0 = theta_0 - alpha/length*(total)
tmp1 = theta_1 - alpha/length*(total)*xset[index]
theta_0 = tmp0
theta_1 = tmp1
sum_total = sum_total + theta_0 + theta_1 * xset[index] - yset[index]
jtheta_1 = 0.5 * length * math.pow(sum_total,2)
comp = math.fabs(jtheta_1 - jtheta)
print "%10.5f %10.5f %10.5f %10.5f" %(comp,jtheta * dgree,theta_0,theta_1)
if comp < jtheta * dgree:break
jtheta = jtheta_1
return theta_0,theta_1
'''
最小二乘法
'''
def linefit( x,y):
N = len(x)
sx,sy,sxx,syy,sxy=0,0,0,0,0
for i in range(0,N):
sx += x[i]
sy += y[i]
sxx += x[i]*x[i]
syy += y[i]*y[i]
sxy += x[i]*y[i]
a = (sy*sx/N -sxy)/( sx*sx/N -sxx)
b = (sy - a*sx)/N
r = abs(sy*sx/N-sxy)/math.sqrt( (sxx-sx*sx/N)*(syy-sy*sy/N))
return a,b,r
X=[1.5,2,1.5,2,3,3,3.5,3.5,4,4,5,5]
Y=[3,3.2,4,4.5,4,5,4.2,4.5,5,5.5,4.8,6.5]
#a,b = grediant(X,Y,0.0005,0.3)
a,b,r = linefit(X,Y)
print "y = %10.5fx + %10.5f" %(b,a)
x = np.linspace(0, 10, 10000)
#y = b * x + a
y = a * x + b
plt.plot(x,y)
plt.scatter(X, Y)
plt.show()