
3.3.3 特征值和特征向量
n×n的矩阵A可以看作n维空间中的线性变换。若x为n维空间中的一个向量,那么A与x的矩阵乘积就是对x进行线性变换之后的向量。如果x是线性变换的特征向量,那么经过这个线性变换之后,得到的新向量仍然与原来的x保持在同一方向上,但其长度也许会改变。特征向量的长度在该线性变换下缩放的比例称为其特征值。即特征向量x满足如下等式,λ的值可以是一个任意复数:
Ax =λx
下面以二维平面上的线性变换矩阵为例,演示特征值和特征变量的几何含义。通过linalg.eig(A)计算矩阵A的两个特征值evalues和特征向量evectors,在evectors中,每一列是一个特征向量。
A = np.array([[1, -0.3], [-0.1, 0.9]]) evalues, evectors = linalg.eig(A) evalues evectors ---------------------------------- ---------------------------- [ 1.13027756+0.j, 0.76972244+0.j] [[ 0.91724574, 0.79325185], [-0.3983218 , 0.60889368]]
图3-7显示了变换前后的向量。在图中,蓝色箭头为变换之前的向量,红色箭头为变换之后的向量。粗箭头为变换前后的特征向量。可以看出特征向量变换前后方向没有改变,只是长度发生了变化。长度的变化倍数由特征值决定:一个变为原来的1.13倍长,一个变为原来的0.77倍长。

图3-7 线性变换将蓝色箭头变换为红色箭头
numpy.linalg模块中也有eig( )函数,与之不同的是,scipy.linalg模块中的eig( )函数支持计算广义特征值和广义特征向量,它们满足如下等式,其中B是一个n×n的矩阵:
Ax =λBx
广义特征向量可以用于椭圆拟合,椭圆拟合的公式与原理可以参考下面的论文:
http://research.microsoft.com/pubs/67845/ellipse-pami.pdf
用广义特征向量计算椭圆拟合。
椭圆上的点满足如下方程,其中a,b,c,d,e,f为椭圆的参数,(x,y)为平面上的坐标点:
f(x,y)=ax2 +bxy+cy2 +dx+ey+f=0
所谓椭圆拟合,就是指给出一组平面上的点(xi ,yi ),找到一组椭圆参数,使得∑f(xi ,yi )2最小。显然这是一个最小化问题,可以使用上节介绍的优化算法optimize.leastsq( )求解。为了避免参数全为0的平凡解,需要一点小技巧,请读者自行演练一下。下面给出论文中用广义特征向量计算椭圆拟合的方法:
首先定义。D是一个n×6的矩阵,其中n为点的个数,D中的每一行与一个坐标点相对应。a为拟合椭圆的系数:a =[a,b,c,d,e,f]T。则a满足如下方程:
DT Da =λCa
其中C是一个6×6的矩阵:

显然上式符合广义特征向量的等式,因此可以用linalg.eig( )求解。下面首先使用椭圆的参数方程计算某个椭圆上随机的60个点,并引入一些随机噪声:

np.random.seed(42) t = np.random.uniform(0, 2* np.pi, 60) alpha = 0.4 a = 0.5 b = 1.0 x = 1.0 + a* np.cos(t)* np.cos(alpha) - b* np.sin(t)* np.sin(alpha) y = 1.0 + a* np.cos(t)* np.sin(alpha) - b* np.sin(t)* np.cos(alpha) x += np.random.normal(0, 0.05, size=len(x)) y += np.random.normal(0, 0.05, size=len(y))
❶当传递第二个参数时,eig( )计算广义特征值和向量。evectors中共有6个特征向量,❷将这6个特征向量代入椭圆方程中,计算平均误差,❸并挑选误差最小的特征向量作为椭圆的参数p。图3-8显示了参数p所表示的椭圆以及数据点。

图3-8 用广义特征向量计算的拟合椭圆
D = np.c_[x** 2, x* y, y** 2, x, y, np.ones_like(x)] A = np.dot(D.T, D) C = np.zeros((6, 6)) C[[0, 1, 2], [2, 1, 0]] = 2, -1, 2 evalues, evectors = linalg.eig(A, C) ❶ evectors = np.real(evectors) err = np.mean(np.dot(D, evectors)** 2, 0) ❷ p = evectors[:, np.argmin(err) ] ❸ print p [-0.55214278 0.5580915 -0.23809922 0.54584559 -0.08350449 -0.14852803]