以下是线性代数 4 个核心概念的细分、它们的重要性、上下文解释和 Python 代码片段:
向量和矩阵是处理数据和参数的基础。运算(加法、乘法、转置)使算法计算能够以矢量化(高效)的方式进行。
import numpy as np
vector = np.array([2, 3])
matrix = np.array([[1, 2], [3, 4]])
sum_vector_matrix = vector + matrix[0] # Addition
print(sum_vector_matrix)
product = np.dot(matrix, vector) # Multiplication
print("product: ",product)
transpose = matrix.T # Transpose
print(transpose)
输出:
[3 5]
product: [ 8 18]
[[1 3]
[2 4]]
特征值和特征向量有助于深度学习模型中的降维、主成分分析和系统稳定性分析。
import numpy as np
import matplotlib.pyplot as plt
A = np.array([[4, 2], [1, 3]])
eigenvalues, eigenvectors = np.linalg.eig(A)
print(f'Eigenvalues: {eigenvalues}')
print(f'Eigenvectors: {eigenvectors}')
origin = [0], [0]
plt.quiver(*origin, eigenvectors[0,0], eigenvectors[1,0], color=['r'], scale=3, scale_units='xy', angles='xy')
plt.quiver(*origin, eigenvectors[0,1], eigenvectors[1,1], color=['b'], scale=3, scale_units='xy', angles='xy')
plt.xlim(-3, 3)
plt.ylim(-3, 3)
plt.title('Eigenvectors of A')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.grid()
plt.axhline(y=0, color='k')
plt.axvline(x=0, color='k')
plt.show()
输出:[^f1]
Eigenvalues: [5. 2.]
Eigenvectors: [[ 0.89442719 -0.70710678]
[ 0.4472136 0.70710678]]
线性变换(缩放、旋转)对于机器学习中的数据增强、标准化和数据转换至关重要。
import numpy as np
import matplotlib.pyplot as plt
matrix = np.array([[2, 3], [3, 4]])
scaling_matrix = np.array([[2, 0], [0, 2]])
transformed_matrix = np.dot(matrix, scaling_matrix)
plt.scatter(matrix[:,0], matrix[:,1], color="blue", label="Original")
plt.scatter(transformed_matrix[:,0], transformed_matrix[:,1], color="red", label="Transformed")
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.title('Linear Transformation: Scaling')
plt.grid(True)
plt.legend()
plt.axis('equal')
plt.show()
输出:
求解线性系统有助于找到权重、优化算法以及在机器学习模型中进行预测。
例如:
2
x
+
3
y
=
1
4
x
−
5
y
=
2
import numpy as np
A = np.array([[2, 3], [4, -5]])
B = np.array([1, 2])
x = np.linalg.solve(A, B)
print(f'Solution: x = {x[0]:.2f}, y = {x[1]:.2f}')
输出:
Solution: x = 0.50, y = 0.00
傅里叶分析是研究如何将一般函数分解为具有确定频率的三角函数或指数函数。 傅里叶展开有两种类型:
傅立叶分析在物理学中如此重要的原因是,控制物理系统的许多(尽管肯定不是全部)微分方程都是线性的,这意味着两个解的和又是一个解。 因此,由于傅立叶分析告诉我们任何函数都可以写成正弦函数,因此我们在求解微分方程时,可以将注意力限制在这些函数上。 然后我们可以从这些特殊的函数中构建任何其他函数。 这是一个非常有用的策略,因为处理正弦函数总是比处理一般函数更容易。
[^f2]傅立叶变换 (FT) 将信号的时域与其频域相关联,其中频域包含有关构成信号的正弦曲线(幅度、频率、相位)的信息。 由于FT是连续变换,离散傅立叶变换(DFT)成为数字世界中适用的变换,它将离散格式的信号信息保存为一组样本,其中采样定理是离散化的严格规则, 信号。 具有 N 个样本的信号 (xn) 的 DFT 由以下等式给出:
X
k
=
∑
n
=
0
N
−
1
x
n
⋅
e
−
i
2
π
k
n
/
N
=
∑
n
=
0
N
−
1
x
n
⋅
[
cos
(
2
π
k
n
/
N
)
−
i
sin
(
2
π
k
n
/
N
)
]
X_k=\sum_{n=0}^{N-1} x_n \cdot \mathrm{e}^{-\mathrm{i} 2 \pi k n / \mathrm{N}}=\sum_{n=0}^{N-1} x_n \cdot[\cos (2 \pi k n / N)-i \sin (2 \pi k n / N)]
Xk=n=0∑N−1xn⋅e−i2πkn/N=n=0∑N−1xn⋅[cos(2πkn/N)−isin(2πkn/N)]
其中:
DFT ( X k X_k Xk) 的输出是一个复数数组,其中包含频率分量的信息。 使用数学方程对信号应用 DFT 直接需要大量的计算复杂性。 幸运的是,快速傅立叶变换 (FFT) 的开发可以提供更快的 DFT 实现。 FFT 利用了 DFT 输出的对称性。
我们将开始简单地了解本文中使用的每种方法的输入和输出。 首先,我们将导入所需的包。 Numpy 用于处理矩阵和计算。 我们从 scipy.fft 模块(fft、rfft、fftfreq、rfftfreq)导入有助于我们进行傅立叶分析相关计算的方法。 最后,Plotly 和 matplotlib 用于可视化。
import numpy as np
from scipy.fft import fft, rfft
from scipy.fft import fftfreq, rfftfreq
import plotly.graph_objs as go
from plotly.subplots import make_subplots
import matplotlib.pyplot as plt
%matplotlib inline
我们需要信号来尝试我们的代码。 正弦曲线很棒并且适合我们的示例。 在接下来的代码中,我们使用名为 Signal 的类生成正弦信号,您可以按照此要点找到该类,以便随时使用。 我们将使用前一类生成的信号,包含三个正弦曲线 (1, 10, 20) Hz,幅度分别为 (3, 1, 0.5)。 采样率为 200,信号持续时间为 2 秒。
# Generate the three signals using Signal class and its method sine()
signal_1hz = Signal(amplitude=3, frequency=1, sampling_rate=200, duration=2)
sine_1hz = signal_1hz.sine()
signal_20hz = Signal(amplitude=1, frequency=20, sampling_rate=200, duration=2)
sine_20hz = signal_20hz.sine()
signal_10hz = Signal(amplitude=0.5, frequency=10, sampling_rate=200, duration=2)
sine_10hz = signal_10hz.sine()
# Sum the three signals to output the signal we want to analyze
signal = sine_1hz + sine_20hz + sine_10hz
# Plot the signal
plt.plot(signal_1hz.time_axis, signal, 'b')
plt.xlabel('Time [sec]')
plt.ylabel('Amplitude')
plt.title('Sum of three signals')
plt.show()
可以使用 scipy 包中的 (fft) 计算该信号的傅立叶变换,如下所示
# Apply the FFT on the signal
fourier = fft(signal)
# Plot the result (the spectrum |Xk|)
plt.plot(np.abs(fourier))
plt.show()
现在我们已经了解了傅立叶分析中使用的每种方法的输入和输出,让我们开始编写最终代码。 我们将建立一个类(Fourier),让我们对傅里叶变换的使用更加方便、更好用。