一、Python 矩阵基本运算
该部分在 Jupyter 中进行实验
1. Python 矩阵操作
解决线性代数的解方程问题
-
引入 numpy
import numpy as np
-
mat
▶ 创建一个 2 × 3 矩阵a=np.mat([[1,2,3],[4,5,6]]) a
点击运行结果如下
-
shape
▶ 获取矩阵大小a.shape
运行结果如下
-
T
▶ 转置矩阵a.T
运行结果如下
-
transpose
▶ 进行行列转换a.transpose
运行结果如下
-
使用二维数组代替矩阵
b=np.array([[1,2,1],[4,5,6]])
-
矩阵、数组加减法写法与普通加减法一样,但是列表不可以这样进行加减法
2. Python 矩阵乘法
-
使用二维数组创建矩阵如下
a=np.array([[1,2,1],[4,5,6]]) b=np.array([[1,2],[3,4],[5,6]])
-
*
▶ 矩阵与数相乘(符号*
不能用于矩阵相乘)2*a 2*b
-
dot
▶ 矩阵与矩阵相乘np.dot(a,b) np.dot(b,a)
-
创建二维数组
c
c=np.array([[1,2],[1,3]])
-
验证矩阵相乘结合性
(ab)c=a(bc)
np.dot(np.dot(a,b),c) np.dot(a,np.dot(b,c))
运算结果一样
-
验证矩阵加法分配性
(a+b)c=ac+bc
c(a+b)=ca+cb
d=b-1 np.dot(a,b+d) np.dot(a,b)+np.dot(a,d)
-
验证矩阵的数乘结合
2*(np.dot(a,b)) np.dot(a,2*b) np.dot(2*a,b) np.dot(a,2*b)
-
eye
▶ 创建单位矩阵I=np.eye(3)
-
使用一个矩阵
a
乘单位矩阵还是a
矩阵np.dot(a,I)
3. 矩阵的转置
-
创建矩阵
A
A=np.array([[1,2,3],[4,5,6]])
-
T
▶ 转置矩阵A.T
-
验证
(A')'=A
A.T.T
-
创建以下两个矩阵
B=np.array([[1,4],[2,5],[3,6]]) D=np.array([[0,3],[1,4],[2,5]])
-
验证转置第二性质
(A±B)'=A'±b'
(B+D).T B.T+D.T
-
验证矩阵转置第三性质
(KA)'=KA'
10*A.T (10*A.T)
-
验证矩阵转置第四性质
(A×B)'=B'×A'
np.dot(A,B).T np.dot(B.T,A.T)
4. Python 求方阵的迹
-
创建一个方阵
E
E=np.array([[1,2,3],[4,5,6],[7,8,9]])
-
trace
▶ 计算方阵的迹np.trace(E)
-
验证方阵的迹等于转置的迹
np.trace(E) np.trace(E.T)
-
创建另一个方阵
F
F=E-2 F
-
方阵乘积的迹
np.trace(np.dot(E,F)) np.trace(np.dot(F,E))
-
验证方阵的和的迹等于方阵的迹的和
np.trace(E+F) np.trace(E)+np.trace(F)
5. Python 方阵的行列式计算方法
-
创建以下两个方阵
E=np.array([[1,2,3],[4,5,6],[7,8,9]]) F=np.array([[-1,0,1],[2,3,4],[5,6,7]])
-
det
▶ 求方阵E
F
的行列式np.linalg.det(E) np.linalg.det(F)
6. Python 求逆矩阵/伴随矩阵
-
创建方阵
A
A=np.array([[1,-2,1],[0,2,-1],[1,1,-2]])
-
linalg.det
▶ 求A
的行列式A_abs=np.linalg.det(A) A_abs
-
linalg.inv
▶ 求A
的逆矩阵B=np.linalg.inv(A) B
-
A-1 = A"/|A| ==> A"=A-1|A|
A_abs=np.linalg.det(A) B=np.linalg.inv(A) A_bansui=B*A_abs
7. Python 解多元一次方程
-
创建方程组(矩阵与一维向量)
a=np.array([[1,2,1],[2,-1,3],[3,1,2]]) b=np.array([7,7,18])
-
linalg.solve
▶ 解方程x=np.linalg.solve(a,b)
-
验证解的正确性
np.dot(a,x)
二、梯度下降法
1. 微分
是指函数在某一点处(趋近于无穷小)的变化量,是一种变化的量。
2. 梯度
梯度的本意是一个向量(矢量),表示某一函数在该点处的方向导数沿着该方向取得最大值,即函数在该点处沿着该方向(此梯度的方向)变化最快,变化率最大(为该梯度的模)。
3. 梯度下降法
梯度下降法是一个一阶最优化算法。 要使用梯度下降法找到一个函数的局部极小值,必须向函数上当前点对应梯度(或者是近似梯度)的反方向的规定步长距离点进行迭代搜索
4. 梯度下降法的手工求解
求解以下函数的极小值点
5. Excle 中的梯度下降法
求解以下方程近似根
z = 2(x - 1)2 + y2
- 表格初始设置如下
- 设置
xi
yi
的初始值为(2, 1)
,i
为0
且逐行递增
- 函数设置
表格 | 函数 |
---|---|
ðz/ðx | 4 * (x - 1) |
ðz/ðy | 2 * y |
Δx | ŋ * (ðz / ðx) |
Δy | ŋ * (ðz / ðy) |
z | 2(x - 1)2 + y2 |
- 第三步为第一次迭代,用同样的方式继续迭代
当迭代到1000次的时候
yi
的值已经极小了,可近似看成0
,通过观察此时xi
与yi
的值可得其近似值为(1, 0)
三、Python 中实现梯度下降法求回归方程
1. 先使用最小二乘法解决,用于比较
-
代码
import numpy as np from scipy.optimize import leastsq from sklearn import linear_model #可以调用sklearn中的linear_model模块进行线性回归 import seaborn as sns # 定义数据集的大小 即20个数据点 m = 20 # x的坐标以及对应的矩阵 X0 = ones((m, 1)) # 生成一个m行1列的向量,其值全是1 X1 = arange(1, m+1).reshape(m, 1) # 生成一个m行1列的向量,也就是x1,从1到m X = hstack((X0, X1)) # 按照列堆叠形成数组,其实就是样本数据 # 对应的y坐标 Y = np.array([3, 4, 5, 5, 2, 4, 7, 8, 11, 8, 12,11, 13, 13, 16, 17, 18, 17, 19, 21]).reshape(m, 1) #进行线性回归的求解 model = linear_model.LinearRegression() model.fit(X1,Y) print("斜率=",model.coef_[0]) print("截距为=",model.intercept_) # 根据数据画出对应的图像 def plot(X, Y, theta): ax = plt.subplot(111) # 将画布分为1行1列,取第一个 ax.scatter(X, Y, s=30, c="blue", marker="s") plt.xlabel("X") plt.ylabel("Y") x = arange(0, 21, 0.2) # x的范围 y = model.intercept_+ model.coef_[0]*x ax.plot(x, y) plt.show() plot(X1, Y, model.coef_[0])
-
计算结果及绘图
2. 梯度下降法
-
代码
from numpy import * # 定义数据集的大小 即20个数据点 m = 20 # x的坐标以及对应的矩阵 X0 = ones((m, 1)) # 生成一个m行1列的向量,其值全是1 X1 = arange(1, m+1).reshape(m, 1) # 生成一个m行1列的向量,也就是x1,从1到m X = hstack((X0, X1)) # 按照列堆叠形成数组,其实就是样本数据 # 对应的y坐标 Y = np.array([ 3, 4, 5, 5, 2, 4, 7, 8, 11, 8, 12, 11, 13, 13, 16, 17, 18, 17, 19, 21 ]).reshape(m, 1) # 学习率 alpha = 0.01 import matplotlib.pyplot as plt #绘制出数据集 plt.scatter(X1,Y,color='red') plt.show() # 定义代价函数 #损失函数(loss function)或代价函数(cost function)是将随机事件或其有关随机变量的取值映射为非负实数以表示该随机事件的“风险”或“损失”的函数 def cost_function(theta, X, Y): diff = dot(X, theta) - Y # dot() 数组需要像矩阵那样相乘,就需要用到dot() return (1/(2*m)) * dot(diff.transpose(), diff) # 定义代价函数对应的梯度函数 def gradient_function(theta, X, Y): diff = dot(X, theta) - Y return (1/m) * dot(X.transpose(), diff) # 梯度下降迭代 def gradient_descent(X, Y, alpha): #将[1,1]变为2行1列的形式 theta = array([1, 1]).reshape(2, 1) #得到代价函数的初始梯度 gradient = gradient_function(theta, X, Y) #不断迭代的过程 while not all(abs(gradient) <= 1e-5): #更新迭代公式 theta = theta - alpha * gradient #更新迭代所用的梯度 gradient = gradient_function(theta, X, Y) return theta #梯度下降最终的结果 optimal = gradient_descent(X, Y, alpha) print('optimal:', optimal) print('cost function:', cost_function(optimal, X, Y)[0][0]) # 根据数据画出对应的图像 def plot(X, Y, theta): ax = plt.subplot(111) # 将画布分为1行1列,取第一个 ax.scatter(X, Y, s=30, c="red", marker="s") plt.xlabel("X") plt.ylabel("Y") x = arange(0, 21, 0.2) # x的范围 y = theta[0] + theta[1]*x ax.plot(x, y) plt.show() plot(X1, Y, optimal)
-
运算结果
3. 结果对比
对比项 | 最小二乘法 | 梯度法 |
---|---|---|
斜率 | 0.96992481 | 0.96992163 |
截距 | 0.51578947 | 0.51583286 |
由此可看其相差极小,可忽略
转载:https://blog.csdn.net/qq_44256264/article/details/115445630