## Wednesday, March 10, 2010

### Strang's Linear Algebra: least squares

Strang has an excellent section on least squares. I'm going to work through an example here as a way of building my understanding (homework). We take the simplest possible case of three time points equally spaced at t = 1, 2, 3. At these times we observe data y = 2, 2, 4 (to make it slightly different than his example). The three points are not co-linear, as you might guess and can see from the plot. The numpy function polyfit will fit a line to this data (that's what I plotted above), but we're going to find it ourselves.

The line that "best fits" the data has the equation y = C + Dt. We need to find C and D. We use calculus first, then linear algebra. The magnitude of the "error" at times 1, 2 and 3 is the difference between the value on the line and the value we actually observed.

 `e1 = C + 1D - 2e2 = C + 2D - 2e3 = C + 3D - 4`

We calculate the sum of the squares of the errors, which we wish to minimize. One reason for the square is that the minimization involves the derivative, and the derivative of the square function is a linear function.

 `SumSq = (C+D-2)2 + (C+2D-2)2 + (C+3D-4)2`

This is a function of two variables (C and D), so we need to take both partial derivatives and set them both equal to zero, (yielding two equations in two unknowns).

 `∂SumSq/∂C = 2(C+D-2) + 2(C+2D-2) + 2(C+3D-4) = 0∂SumSq/∂D = 2(C+D-2) + 2*2(C+2D-2) + 3*2(C+3D-4) = 0`

The factor of 2 in each term goes away. Notice that the first equation says that the sum of the errors is equal to zero.

Solve for C in the first eqn:

 `C + D - 2 + C + 2D - 2 + C + 3D - 43C + 6D = 83C = 8 - 6D`

Substitute C into the second equation:

 `C + D - 2 + 2C + 4D - 4 + 3C + 9D - 12 = 06C + 14D = 1814D = 18 - 6C 14D = 18 - 16 + 12D2D = 2D = 1C = 2/3`

In Bolstad (p. 237) the equation for the slope is given as:

 `B = mean(xy) - mean(x)*mean(y) / mean(x2) - mean(x)2mean(xy) = mean(1*2 + 2*2 + 3*4) = 18/3 = 6mean(x)*mean(y) = 2 * mean(2,2,4) = 16/3mean(x2) = mean(1,4,9) = 14/3mean(x)2 = 4B = 18/3 - 16/3 = 1 ----------- 14/3 - 12/3 `

and the intercept is

 `Ao = mean(y) - B*mean(x) = 8/3 - 2 = 2/3`

Looks good. Let's do some linear algebra! We go back to the equation for the line: C + Dt. We have one equation for each observation, which is written like so:

 `[ 1 1 ] [ C ] = [ 2 ][ 1 2 ] [ D ] [ 2 ][ 1 3 ] [ 4 ]`

Ax = b has no solution. We seek the projection of b onto A.

Using the formula from last time, (and Python to do the calculation, below) we obtain:

 `P = [ 5/6 1/3 -1/6 ] [ 1/3 1/3 1/3 ] [ -1/6 1/3 5/6 ]p = P b = [ 5/3 ] [ 8/3 ] [ 11/3 ]`

We can check that the error e = b - p

 `[ 2 ] - [ 5/3 ] = [ 1/3 ][ 2 ] - [ 8/3 ] = [ -2/3 ][ 4 ] - [ 11/3 ] = [ 1/3 ]`

is perpendicular to p:

 `e•p = 5/9 - 16/9 + 11/9 = 0`

 `import numpy as npimport matplotlib.pyplot as pltt = np.array([1,2,3])b = np.array([2,2,4])plt.scatter(t,b,s=300,color='r')ar,by = np.polyfit(t,b,1)def f(x): return by + ar*xT = np.arange(0,3.2,0.1)plt.plot(T,f(T),lw=4,color='k')plt.text(0.2,3.5,fontsize=24, s='y-intercept =' + str(round(by,3)))plt.text(0.2,3.0,fontsize=24, s='slope =' + str(round(ar,3)))ax = plt.axes()ax.set_xlim(0,3.2)ax.set_ylim(0,4.2)plt.savefig('example.png')col1 = np.array([1,1,1])t.shape = b.shape = col1.shape = (3,1)A = np.hstack([col1,t])print Adef project(A): AT = A.transpose() temp = np.linalg.inv(np.dot(AT,A)) return np.dot(A,np.dot(temp,AT))P = project(A)print Pprint bprint np.dot(P,P)print np.dot(P,b)`