章节2:Numpy库和线性代数有关的知识
在学习回归和分类问题前,我们先来学习下线代和微积分中一些重要的概念。这些基础有助于你理解接下来3章的理论知识,同时,我们也将介绍Numpy库。
Numpy库
我们将经常使用Numpy,它是一个Python库,增加了对大规模向量和矩阵以及对数据进行操作的一些重要数学函数快速有效计算的支持。Numpy是一个非常大的库,具有许多便利的函数。如果对这些函数进行全面介绍,则超出了本章的内容。我们会在以后的章节中,根据我们的需要介绍相关的Numpy库中的函数。在接下来的内容中,我们将简要学习一些最常用的操作。
首先,导入numpy库(常常以np作为缩写)
import numpy as np
Numpy库有许多方便的函数来产生一组数字,例如,生成0到10之间的一串整数
np.arange(0, 10)
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
numpy.linspace函数能在两个端点之间线性插入n个数
np.linspace(0, 10, 8)
array([ 0. , 1.42857143, 2.85714286, 4.28571429, 5.71428571,
7.14285714, 8.57142857, 10. ])
向量
向量可以用numpy.array来创建,如下向量v,np.array([2, 3, 1])
array([2, 3, 1])
当两个长度相同的向量相加时,对应元素相加,
a = np.array([2, 3, 1])
b = np.array([0, 2, -2])
c = a + b
print(c)
[ 2 5 -1]
向量中的元素能被一个数(标量)依次相乘,如下:
3 * np.array([2,3,1])
array([6, 9, 3])
向量点乘定义为两个长度相同的向量对应元素乘积之和。可以使用numpy.dot函数计算:
a = np.array([1,-2,2])
b = np.array([0,2,3])
c = np.dot(a, b)
print(c)
2
或者更简短的方法:
c = a.dot(b)
print(c)
2
矩阵
矩阵是一组数字的矩形排列,比如,下面是一个2x3的矩阵:注意,我们经常用行数x列数来表示矩阵的大小,所以,2x3表示矩阵有2行3列。
numpy能通过numpy.matrix函数把列表转成矩阵,比如:
np.matrix([[2,3,1],[0, 4,-2]])
matrix([[ 2, 3, 1],
[ 0, 4, -2]])
实例化一个元素都是0的矩阵:
np.zeros((3, 3))
array([[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]])
实例化一个元素都是1的矩阵:
np.ones((2, 2))
array([[1., 1.],
[1., 1.]])
在线性代数中,一个矩阵除了对角线上的元素都是1以外,其余元素都是0,该矩阵称为单位矩阵,比如:是一个3x3的单位矩阵,之所以叫做单位矩阵是因为一个矩阵乘以该矩阵,结果不变,就像乘了一个标量1。
实例化一个单位矩阵,可以使用numpy.eye方法,比如:
np.eye(3)
array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]])
注意,当一个矩阵和单位矩阵相乘后,结果还是原来那个矩阵,且与相乘的顺序无关。
M = np.matrix([[9,5,6],[-1,0,5],[-2,4,2]])
I = np.eye(3)
print("original matrix = \n", M)
M2 = I * M
print("I * M = \n", M2)
M3 = M * I
print("M * I = \n", M3)
original matrix =
[[ 9 5 6]
[-1 0 5]
[-2 4 2]]
I * M =
[[ 9. 5. 6.]
[-1. 0. 5.]
[-2. 4. 2.]]
M * I =
[[ 9. 5. 6.]
[-1. 0. 5.]
[-2. 4. 2.]]
实例化一个矩阵,且元素是随机生成的(0和1之间),可以用numpy.random方法:
A = np.random.random((2, 3))
print(A)
[[0.13425988 0.99250082 0.52730459]
[0.09945505 0.42777824 0.52474797]]
转置是反转矩阵的两个轴,所以矩阵i行j列的元素,转置后就位于j行i列。矩阵A的转置表示为A^T
A_transpose = np.transpose(A)
print(A_transpose)
[[0.13425988 0.09945505]
[0.99250082 0.42777824]
[0.52730459 0.52474797]]
也可以用缩写的方法.T:
A_transpose = A.T
print(A_transpose)
[[0.13425988 0.09945505]
[0.99250082 0.42777824]
[0.52730459 0.52474797]]
矩阵运算和性质
跟向量一样,矩阵也是对应元素相加,不过要求两个矩阵大小相同,举例来说:
a = np.matrix([[4, 3],[3,-1],[-2,1]])
b = np.matrix([[-2, 1],[5,3],[1,0]])
c = a + b
print(c)
[[ 2 4]
[ 8 2]
[-1 1]]
矩阵也可以跟向量一样,乘以一个标量,
a = np.matrix([[1,-2,0],[6,4,-2]])
-2 * a
matrix([[ -2, 4, 0],
[-12, -8, 4]])
两矩阵相乘,就是将第一个矩阵的行与第二个矩阵的列进行点乘,如下:矩阵A和B可相乘,必须满足A的列数与B的行数相同,例如:
a = np.matrix([[1,-2,0],[6,4,-2]])
b = np.matrix([[4,-1],[0,-2],[1,3]])
c = a * b
print(c)
[[ 4 3]
[ 22 -20]]
与一般的乘法不同,两矩阵的hadamard乘积是矩阵对应元素相乘,使用numpy计算hadamard乘积的话,用numpy.array而不是numpy.matrix方法来实例化矩阵,这样可以用numpy.multiply方法来实现:
a = np.array([[3,1],[0,5]])
b = np.array([[-2,4],[1,-2]])
np.multiply(a,b)
array([[ -6, 4],
[ 0, -10]])
函数
函数是一个等式,计算带有一个或多个变量的表达式的值,例如:所以在x=2处,f(2)=11,我们将经常遇到函数,一个神经网络就是一个很大的函数。
在机器学习中,经常会碰到变量和参数这两个词,变量是等式的一部分,是可变的,变量决定输出,所以上面这个函数取决于变量x。上式的系数(3,-5,9)有时候又叫做参数,因为他们决定函数的形状,并且是固定的。
def f(x):
return 3*(x**2)-5*x+9
f(2)
11
导数
函数f(x)的导数是指在给定点的斜率,表示为def f(x):
return -2*(x**3)
def f_deriv(x):
return -6*(x**2)
print(f(2))
print(f_deriv(2))
-16
-24
常数的导数为0,为什么呢?令:导数的性质
导数有交换律,和的导数就是导数的和,例如:链式法则
复合函数是多个函数的组合,例如:所以,对上式f(x)求导的结果为:
学习神经网络时,链式法则十分重要,因为由此可以计算网络代价函数的导数。
def h(x):
return 4*x-5
def g(x):
return x**3
def f(x):
return g(h(x))
def h_deriv(x):
return 4
def g_deriv(x):
return 3*(x**2)
def f_deriv(x):
return g_deriv(h(x)) * h_deriv(x)
f(4)
f_deriv(2)
1331
108
多元函数
一个函数可以有一个或多个变量,例如:梯度
函数的梯度是一个包含每个变量偏导数的向量,后面当我们在了解神经网络是如何训练时,会更深入了解梯度的作用。