『科学计算』线性代数部分作业

最小二乘法求解垂足

from matplotlib import pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D

A=np.array([[1],[2],[3]])
B=np.array([[1],[1],[1]])

x=np.linspace(-0.5,1,10)

x.shape=(1,10)
xx=A.dot(x)

C=A.T.dot(B)
AA=np.linalg.inv(A.T.dot(A))

P=A.dot(AA).dot(C)
E=B-P

fig = plt.figure()
ax = fig.add_subplot(111,projection=‘3d‘)

ax.plot(xx[0,:],xx[1,:],xx[2,:],label="lineA")
ax.plot(A[0],A[1],A[2],‘ko‘,label="A")
ax.plot([0,B[0]],[0,B[1]],[0,B[2]],‘m-o‘,label="0B")
ax.plot([B[0][0],P[0][0]],[B[1][0],P[1][0]],[B[2][0],P[2][0]],‘r-o‘,label="BP")
ax.plot([0,E[0]],[0,E[1]],[0,E[2]],‘y-o‘,label="0E")

ax.legend()
ax.axis(‘equal‘)
plt.show()

因为是三维图么,所以扭了一下多截了一张(笑):

最小二乘法拟合函数

import numpy as np
import matplotlib.pyplot as plt
import copy

# 产生一个方波(x,y)
x = np.linspace(-10,10,300)
y=[]
for i in np.cos(x):
    if i>0:
        y.append(0)
    else:
        y.append(2)
y=np.array(y)

def projection(A,b):
    ####
    # return A*inv(AT*A)*AT*b
    ####
    AA = A.T.dot(A)
    w=np.linalg.inv(AA).dot(A.T).dot(b)
    print(w)
    return A.dot(w)

def fourier(x,y,N):
    A = []
    for i in x:
        A.append(copy.deepcopy([]))
        for j in range(N):
            A[-1].append(np.sin((j + 1) * i))
            A[-1].append(np.cos((j + 1) * i))
        A[-1].append(1)
    b = y.T
    yw = projection(np.array(A),b)
    return yw

# write Your code, Fourier function
plt.plot(x,y,color=‘g‘,label=‘origin‘)
plt.plot(x,fourier(x,y,3),color=‘r‘,label=‘3‘)
plt.plot(x,fourier(x,y,8),color=‘b‘,label=‘8‘)
plt.plot(x,fourier(x,y,23),color=‘k‘,label=‘23‘)

plt.legend()
plt.axis(‘equal‘)
plt.show()

从输出图可以直观看出来项数越多拟合效果越好:

使用动画模拟矩阵变换和特征值特征向量的关系

import numpy as np
import copy
import matplotlib.pyplot as plt
from matplotlib import animation

A=np.array([[3,1],[2,4]])/4.0

# write Your code
fig = plt.figure()
ax = fig.add_subplot(111)
line1, = ax.plot([],[],c=‘r‘)
line2, = ax.plot([],[],c=‘b‘)
ax.axis(‘equal‘)
ax.set_xlim(-2,2)
ax.set_ylim(-2,2)
ax.set_xticks(np.linspace(-2,2,5))
ax.set_yticks(np.linspace(-2,2,5))
ax.grid(True)

def data():
    point_num = 100
    x = np.cos(np.linspace(0,2 * np.pi,point_num))
    y = np.sin(np.linspace(0,2 * np.pi,point_num))
    rot_x,rot_y = copy.deepcopy([]),copy.deepcopy([])
    int_x,int_y = copy.deepcopy([]),copy.deepcopy([])
    for i in range(point_num):
        rot_x.append(A.dot([x[i],y[i]])[0])
        rot_y.append(A.dot([x[i],y[i]])[1])
        int_x.append(x[i])
        int_y.append(y[i])
        yield (rot_x,rot_y,int_x,int_y)

def update(data):
    line1.set_xdata(data[0])
    line1.set_ydata(data[1])
    line2.set_xdata(data[2])
    line2.set_ydata(data[3])
    return line1,line2

def init():
    line1.set_data([],[])
    line2.set_data([],[])
    return line1,line2

ani = animation.FuncAnimation(fig,update,data,init_func=init,interval=100,repeat=False)
plt.show()

这是个动画,所以我截了两张图来表示,可以看到同一变换矩阵对不同方向的单位向量放缩长度并不相同,是个椭圆形:

使用矩阵求解差分方程(发散情况)

import numpy as np
import matplotlib.pyplot as plt  

import time
def time_cost(f):
    def _f(*arg, **kwarg):
        start = time.clock()
        a=f(*arg,**kwarg)
        end = time.clock()
        print(f.__name__,"run cost time is ",end-start)
        return a
    return _f

@time_cost
def fib_opt_seq(seq):
    return [fib_opt(i) for i in seq]

def fib_opt(n):
    a,b,i=0,1,0

    while i<n:
        a,b=b,a+b
        i+=1
    else:
        #print(b)
        return b    

import random
#seq = [random.randint(800,1000) for i in xrange(1000)]
seq = range(1000)
a=fib_opt_seq(seq)

# write Your code fib_eig_seq function
A = np.array([[1,1],[1,0]])
eigval,eigvect = np.linalg.eig(A)
S_inv = np.linalg.inv(eigvect)

@time_cost
def fib_eig_seq(seq):
    return [fib_eig(i) for i in seq]

def fib_eig(n):
    af = (np.diag(eigval)**(n+1)).dot(S_inv)
    #print((eigvect.dot(af)).dot(np.array([[1],[0]]))[1])
    return (eigvect.dot(af)).dot(np.array([[1],[0]]))[1]

b=fib_eig_seq(seq)

Python 3.5.2 |Anaconda 4.2.0 (64-bit)| (default, Jul  5 2016, 11:41:13) [MSC v.1900 64 bit (AMD64)]
Type "copyright", "credits" or "license" for more information.
IPython 5.1.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython‘s features.
%quickref -> Quick reference.
help      -> Python‘s own help system.
object?   -> Details about ‘object‘, use ‘object??‘ for extra details.
PyDev console: using IPython 5.1.0

fib_opt_seq run cost time is  0.08637829184750435
fib_eig_seq run cost time is  0.01634134003747284

上面对比了传统的递归方式生成斐波那契数列方式,一般来说随着数量的上升,使用矩阵速度更快。

使用矩阵求解差分方程(收敛情况)

import numpy as np

A = np.array([[ 0.8 ,  0.1],
              [ 0.2 ,  0.9]])

N_year = 1000

x=np.array([3200,
            4000])

def hw_3_5(a,x,n):
    eigval, eigvact = np.linalg.eig(a)
    res = (eigvact.dot((np.diag(eigval)**n).dot(np.linalg.inv(eigvact)).dot(x.T)))
    print(res)
    return res

hw_3_5(A,x,N_year)

IPython 5.1.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython‘s features.
%quickref -> Quick reference.
help      -> Python‘s own help system.
object?   -> Details about ‘object‘, use ‘object??‘ for extra details.
PyDev console: using IPython 5.1.0
Running C:/Projects/python3_5/homework/hw_3-5_demo.py
[ 2400.  4800.]

虽然求解都类似,但是这是个收敛的差分方程,把100年换成1000年结果还是2400和4800。

实践:使用PCA给Mnist图片降维

再写程序的时候发现作业资料给的数据载入包并不能用(也许是python版本的问题),对debug不是很感兴趣,所以索性使用了tensorflow中提供的Mnist数据集调用方法了。

思路有一点偏差,我看了答案,其原意是把N幅数据组成N*(28*28)的二维矩阵,对这个矩阵进行降维,然后在绘图时还原整个矩阵,再在矩阵中进行子图分割;我理解成把每幅小图独自降维保存了,不过除了使我的程序麻烦了一点之外没什么其他影响:

import os
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.examples.tutorials.mnist import input_data

print(os.getcwd())
os.environ[‘TF_CPP_MIN_LOG_LEVEL‘] = ‘3‘

batch_size = 10
mnist = input_data.read_data_sets(‘../../Mnist_data/‘, one_hot=True)
batch_xs,batch_ys = mnist.train.next_batch(batch_size)
print(batch_xs.shape)

# write Your code
def pca(data,k=0.5):
    # data 原始的图片
    # k是保留特征值的百分比
    # return 返回降维后重建的图片
    res = np.empty_like(data).reshape(batch_size, 28, 28)
    rec = np.empty_like(res)
    data = data.reshape(batch_size, 28, 28)
    for i in range(batch_size):
        cov = np.cov(data[i])
        eigVal, eigVact = np.linalg.eig(cov)
        print(cov.shape, eigVal.shape, eigVact.shape)
        for j in range(len(eigVal) - 1):
            # print(sum(eigVal[:j]),sum(eigVal[:]),sum(eigVal[:j])/sum(eigVal[:]))
            if sum(eigVal[:j])/sum(eigVal[:]) > k:
                print(‘提取前面‘,j, ‘个特征‘)
                break
        # res[i] = eigVact[:,:j].T.dot(data[i].T)# np.dot(eigVact[:j],data[i].T)
        a = eigVact#[:,:j]
        b = data[i]
        print(a.shape,b.shape)
        res[i] = np.dot(b, a)
        rec[i] = np.dot(res[i],a.T)
    f,a = plt.subplots(2,batch_size,figsize=(10,2))
    for i in range(batch_size):
        a[0][i].imshow(data[i],‘gray‘)
        a[0][i].set_xticks([])
        a[0][i].set_yticks([])
        a[1][i].imshow(rec[i].reshape(28,28),‘gray‘)
        a[1][i].set_xticks([])
        a[1][i].set_yticks([])

# N = 20
recon_data = pca(batch_xs)
# show_pic(data[:N,:],recon_data[:N,:])

保留占比50%的特征值后压缩(上行是原图,下行是压缩后的图片):

保留占比90%的特征值后压缩(上行是原图,下行是压缩后的图片):

直观来看90%对50%似乎提升不大,不过查看90%和50%保留的特征个数就卡以发现,其实两者的特征数目相差不大,基本上都在5个以下(总数应该是28个左右),也就是说PCA压缩是有道理的——实际上图片的大量信息被保存在极少的几个特征上了。

时间: 2024-11-10 05:24:37

『科学计算』线性代数部分作业的相关文章

『科学计算』通过代码理解SoftMax多分类

SoftMax实际上是Logistic的推广,当分类数为2的时候会退化为Logistic分类 其计算公式和损失函数如下, 梯度如下, 1{条件} 表示True为1,False为0,在下图中亦即对于每个样本只有正确的分类才取1,对于损失函数实际上只有m个表达式(m个样本每个有一个正确的分类)相加, 对于梯度实际上是把我们以前的最后一层和分类层合并了: 第一步则和之前的求法类似,1-概率 & 0-概率组成向量,作为分类层的梯度,对batch数据实现的话就是建立一个(m,k)的01矩阵,直接点乘控制开

『科学计算』层次聚类实现

层次聚类理论自行百度,这里是一个按照我的理解的简单实现, 我们先看看数据, 啤酒名 热量 钠含量 酒精 价格Budweiser 144.00 19.00 4.70 .43Schlitz 181.00 19.00 4.90 .43Ionenbrau 157.00 15.00 4.90 .48Kronensourc 170.00 7.00 5.20 .73Heineken 152.00 11.00 5.00 .77Old-milnaukee 145.00 23.00 4.60 .26Aucsberg

『科学计算_理论』优化算法:梯度下降法&amp;牛顿法

梯度下降法 梯度下降法用来求解目标函数的极值.这个极值是给定模型给定数据之后在参数空间中搜索找到的.迭代过程为: 可以看出,梯度下降法更新参数的方式为目标函数在当前参数取值下的梯度值,前面再加上一个步长控制参数alpha.梯度下降法通常用一个三维图来展示,迭代过程就好像在不断地下坡,最终到达坡底.为了更形象地理解,也为了和牛顿法比较,这里我用一个二维图来表示: 懒得画图了直接用这个展示一下.在二维图中,梯度就相当于凸函数切线的斜率,横坐标就是每次迭代的参数,纵坐标是目标函数的取值.每次迭代的过程

『科学计算_理论』最大似然估计

概述 通俗来讲,最大似然估计,就是利用已知的样本结果,反推最有可能(最大概率)导致这样结果的参数值. 重要的假设是所有采样满足独立同分布. 求解模型参数过程 假如我们有一组连续变量的采样值(x1,x2,-,xn),我们知道这组数据服从正态分布,标准差已知.请问这个正态分布的期望值为多少时,产生这个已有数据的概率最大? P(Data | M) = ? 根据公式 可得: 对μ求导可得 ,则最大似然估计的结果为μ=(x1+x2+-+xn)/n 由上可知最大似然估计的一般求解过程: (1) 写出似然函数

python科学计算_numpy_线性代数/掩码数组/内存映射数组

1. 线性代数 numpy对于多维数组的运算在默认情况下并不使用矩阵运算,进行矩阵运算可以通过matrix对象或者矩阵函数来进行: matrix对象由matrix类创建,其四则运算都默认采用矩阵运算,和matlab十>分相似: a = np.matrix([[1,2,3],[4,5,6],[7,8,9]]) matrix([[1, 2, 3],[4, 5, 6],[7, 8, 9]]) a * a matrix([[ 30, 36, 42],[ 66, 81, 96],[102, 126, 15

『Python』Numpy学习指南第十章_高端科学计算库scipy入门(系列完结)

简介: scipy包包含致力于科学计算中常见问题的各个工具箱.它的不同子模块相应于不同的应用.像插值,积分,优化,图像处理,,特殊函数等等. scipy可以与其它标准科学计算程序库进行比较,比如GSL(GNU C或C++科学计算库),或者Matlab工具箱.scipy是Python中科学计算程序的核心包;它用于有效地计算numpy矩阵,来让numpy和scipy协同工作. 在实现一个程序之前,值得检查下所需的数据处理方式是否已经在scipy中存在了.作为非专业程序员,科学家总是喜欢重新发明造轮子

在.NET上进行线性代数等科学计算 (转)

link: http://www.cnblogs.com/redmoon/archive/2011/03/29/1999242.html 对于工程类.图形等专业软件,需要大量的数学计算,而用的最多的就是线性代数的计算. 那么,在.NET之上,尤其.NET 4.0和VS2010之上要如何完成相关的线性代数计算呢?我想有如下几种方式: 一,自己动手.丰衣足食:根据自己软件的需要,增量式地逐步开发一些函数库.这种方式最大的问题是——重新制作轮子,所以大部分一般不宜采用这种方式. 二,使用开源(或免费的

1.5 Scipy:高级科学计算

医药统计项目可联系 QQ:231469242 http://www.kancloud.cn/wizardforcel/scipy-lecture-notes/129867 作者:Adrien Chauve, Andre Espaze, Emmanuelle Gouillart, Ga?l Varoquaux, Ralf Gommers Scipy scipy包包含许多专注于科学计算中的常见问题的工具箱.它的子模块对应于不同的应用,比如插值.积分.优化.图像处理.统计和特殊功能等. scipy可以

Python学习_科学计算

Python科学计算 包含Numpy.Matplotlib.Scipy.Pandas和scikit-learn 一.Numpy 1.Numpy特征和导入 (1)用于多维数组的第三方Python包 (2)更接近于底层和硬件 (高效) (3)专注于科学计算 (方便) (4)导入包:import numpy as np 2.list转为数组 (1)a = np.array([0,1,2,3]) (2)输出为:[0 1 2 3] (3)数据类型:<type 'numpy.ndarray'> 3.一维数