【数学】主成分分析(PCA)的详细深度推导过程

news2024/11/19 5:25:59

本文基于Deep Learning (2017, MIT),推导过程补全了所涉及的知识及书中推导过程中跳跃和省略的部分。
blog

1 概述

现代数据集,如网络索引、高分辨率图像、气象学、实验测量等,通常包含高维特征,高纬度的数据可能不清晰、冗余,甚至具有误导性。数据可视化和解释变量之间的关系很困难,而使用这种高维数据训练的神经网络模型往往容易出现过拟合(维度诅咒)。
主成分分析(PCA)是一种简单而强大的无监督机器学习技术,用于数据降维。它旨在从大型变量集中提取一个较小的数据集,同时尽可能保留原始信息和特征(有损压缩)。PCA有助于识别数据集中最显著和有意义的特征,使数据易于可视化。应用场景包括:统计学、去噪和为机器学习算法预处理数据。

  • 主成分是什么?
    主成分是构建为原始变量的线性组合的新变量。这些新变量是不相关的,并且包含原始数据中大部分的信息。

2 背景数学知识

这些知识对下一节的推导很重要。

  • 正交向量和矩阵:
    • 如果两个向量垂直,则它们是正交的。即两个向量的点积为零。
    • 正交矩阵是一个方阵,其行和列是相互正交的单位向量;每两行和两列的点积为零,每一行和每一列的大小为1。
    • 如果 A T = A − 1 A^T=A^{-1} AT=A1 A A T = A T A = I AA^T=A^TA=I AAT=ATA=I,则 A A A是正交矩阵。
    • 在机器人学中,旋转矩阵通常是一个 3 × 3 3\times3 3×3的正交矩阵,在空间变换中它会旋转向量的方向但保持原始向量的大小。
  • 矩阵、向量乘法规则:
    • ( A B ) T = B T A T (AB)^T=B^TA^T (AB)T=BTAT,两个矩阵的乘积的转置。
    • a ⃗ T b ⃗ = b ⃗ T a ⃗ \vec{a}^T\vec{b}=\vec{b}^T\vec{a} a Tb =b Ta ,两个结果都是标量,标量的转置是相同的。
    • ( A + B ) C = A C + B C (A + B)C = AC + BC (A+B)C=AC+BC,乘法是可分配的。
    • A B ≠ B A AB \neq{} BA AB=BA,乘法一般不满足交换律。
    • A ( B C ) = ( A B ) C A(BC)=(AB)C A(BC)=(AB)C,乘法满足结合律。
  • 对称矩阵:
    • A = A T A=A^T A=AT A A A是对称矩阵。
    • X T X X^TX XTX是对称矩阵,因为 ( X T X ) T = X T X (X^TX)^T=X^TX (XTX)T=XTX
  • 向量导数规则( B B B是常量矩阵):
    • d ( x T B ) / d x = B d(x^TB)/dx=B d(xTB)/dx=B
    • d ( x T x ) / d x = 2 x d(x^Tx)/dx=2x d(xTx)/dx=2x
    • d ( x T B x ) / d x = 2 B x d(x^TBx)/dx=2Bx d(xTBx)/dx=2Bx
  • 矩阵迹规则:
    • T r ( A ) = T r ( A T ) Tr(A)=Tr(A^T) Tr(A)=Tr(AT)
    • T r ( A B ) = T r ( B A ) Tr(AB)=Tr(BA) Tr(AB)=Tr(BA)
    • T r ( A ) = ∑ i λ i Tr(A)=\sum_i{\lambda_i} Tr(A)=iλi,其中 λ \lambda λ A A A的特征值。
    • 迹在循环移位下不变: T r ( A B C D ) = T r ( B C D A ) = T r ( C D A B ) = T r ( D A B C ) Tr(ABCD)=Tr(BCDA)=Tr(CDAB)=Tr(DABC) Tr(ABCD)=Tr(BCDA)=Tr(CDAB)=Tr(DABC)
  • 向量和矩阵范数:
    • 向量的 L 2 L^2 L2范数,也称为欧几里得范数: ∣ ∣ x ∣ ∣ 2 = ∑ i ∣ x i ∣ 2 ||x||_2=\sqrt{\sum_i|x_i|^2} ∣∣x2=ixi2
    • 通常使用平方的 L 2 L^2 L2范数来衡量向量的大小,可以计算为 x T x x^Tx xTx
    • Frobenius范数用于衡量矩阵的大小: ∣ ∣ A ∣ ∣ F = ∑ i , j A i , j 2 ||A||_F=\sqrt{\sum_{i,j}A^2_{i,j}} ∣∣AF=i,jAi,j2
    • Frobenius范数是所有矩阵元素的绝对平方和的平方根。
    • Frobenius范数是矩阵版本的欧几里得范数。
  • 特征值分解和特征值:
    • 方阵 A A A的特征向量是一个非零向量 v v v,使得 A A A的乘法仅改变 v v v的比例: A v = λ v Av=\lambda v Av=λv λ \lambda λ是特征值, v v v是特征向量。
    • 假设矩阵 A A A n n n个线性无关的特征向量 v ( i ) v^{(i)} v(i),我们可以将所有特征向量连接起来形成一个矩阵 V = [ v ( 1 ) , … , v ( n ) ] V=[v^{(1)},\ldots,v^{(n)}] V=[v(1),,v(n)],并通过连接所有特征值 λ = [ λ 1 , … , λ n ] T \lambda=[\lambda_1,\ldots,\lambda_n]^T λ=[λ1,,λn]T形成一个向量,那么 A A A特征分解 A = V d i a g ( λ ) V − 1 A=Vdiag(\lambda)V^{-1} A=Vdiag(λ)V1
    • 每个实对称矩阵都可以分解为 A = Q Λ Q T A=Q\Lambda Q^T A=QΛQT,其中 Q Q Q是由 A A A的特征向量组成的正交矩阵, Λ \Lambda Λ(读作’lambda’)是一个对角矩阵。
  • 拉格朗日乘数法:
    • 拉格朗日乘数法是一种在方程约束下寻找函数局部最大值和最小值的策略。
    • 一般形式: L ( x , λ ) = f ( x ) + λ ⋅ g ( x ) \mathcal{L}(x,\lambda)=f(x)+\lambda\cdot g(x) L(x,λ)=f(x)+λg(x) λ \lambda λ称为拉格朗日乘子。

3 详细PCA推导

需求描述

我们有 m m m个点的输入数据,表示为 x ( 1 ) , . . . , x ( m ) {x^{(1)},...,x^{(m)}} x(1),...,x(m) R n \mathbb{R}^{n} Rn的实数集中。因此,每个点 x ( i ) x^{(i)} x(i)是一个列向量,具有 n n n维特征。

需要对输入数据进行有损压缩,将这些点编码以表示它们的较低维度版本。换句话说,我们想要找到编码向量 c ( i ) ∈ R l c^{(i)}\in \mathbb{R}^{l} c(i)Rl ( l < n ) (l<n) (l<n)来表示每个输入点 x ( i ) x^{(i)} x(i)。我们的目标是找到产生输入的编码向量的编码函数 f ( x ) = c f(x)=c f(x)=c,以及相应的重构(解码)函数 x ≈ g ( f ( x ) ) x\approx g(f(x)) xg(f(x)),根据编码向量 c c c计算原始输入。

解码的 g ( f ( x ) ) g(f(x)) g(f(x))是一组新的点(变量),因此它与原始 x x x是近似的。存储 c ( i ) c^{(i)} c(i)和解码函数比存储 x ( i ) x^{(i)} x(i)更节省空间,因为 c ( i ) c^{(i)} c(i)的维度较低。

解码矩阵

我们选择使用矩阵 D D D作为解码矩阵,将编码向量 c ( i ) c^{(i)} c(i)映射回 R n \mathbb{R}^{n} Rn,因此 g ( c ) = D c g(c)=Dc g(c)=Dc,其中 D ∈ R n × l D\in \mathbb{R}^{n\times l} DRn×l。为了简化编码问题,PCA将 D D D的列约束为彼此正交。

衡量重构的表现

在继续之前,我们需要弄清楚如何生成最优的编码点 c ∗ c^{*} c,我们可以测量输入点 x x x与其重构 g ( c ∗ ) g(c^*) g(c)之间的距离,使用 L 2 L^2 L2范数(或欧几里得范数): c ∗ = arg ⁡ min ⁡ c ∣ ∣ x − g ( c ) ∣ ∣ 2 c^{*}=\arg\min_c||x-g(c)||_2 c=argminc∣∣xg(c)2。由于 L 2 L^2 L2范数是非负的,并且平方操作是单调递增的,所以我们可以转而使用平方的 L 2 L^2 L2范数:
c ∗ = arg ⁡ min ⁡ c ∣ ∣ x − g ( c ) ∣ ∣ 2 2 c^{*}={\arg\min}_c||x-g(c)||_2^2 c=argminc∣∣xg(c)22 向量的 L 2 L^2 L2范数是其分量的平方和,它等于向量与自身的点积,例如 ∣ ∣ x ∣ ∣ 2 = ∑ ∣ x i ∣ 2 = x T x ||x||_2=\sqrt{\sum|x_i|^2}=\sqrt{x^Tx} ∣∣x2=xi2 =xTx ,因此平方的 L 2 L^2 L2范数可以写成以下形式:
∣ ∣ x − g ( c ) ∣ ∣ 2 2 = ( x − g ( c ) ) T ( x − g ( c ) ) ||x-g(c)||_2^2 = (x-g(c))^T(x-g(c)) ∣∣xg(c)22=(xg(c))T(xg(c)) 由分配率:
= ( x T − g ( c ) T ) ( x − g ( c ) ) = x T x − x T g ( c ) − g ( c ) T x + g ( c ) T g ( c ) =(x^T-g(c)^T)(x-g(c))=x^Tx-x^Tg(c)-g(c)^Tx+g(c)^Tg(c) =(xTg(c)T)(xg(c))=xTxxTg(c)g(c)Tx+g(c)Tg(c) 由于 x T g ( c ) x^Tg(c) xTg(c) g ( c ) T x g(c)^Tx g(c)Tx是标量,标量等于其转置, ( g ( c ) T x ) T = x T g ( c ) (g(c)^Tx)^T=x^Tg(c) (g(c)Tx)T=xTg(c),所以:
= x T x − 2 x T g ( c ) + g ( c ) T g ( c ) =x^Tx-2x^Tg(c)+g(c)^Tg(c) =xTx2xTg(c)+g(c)Tg(c) 为了找到使上述函数最小化的 c c c,第一项可以省略,因为它不依赖于 c c c,所以:
c ∗ = arg ⁡ min ⁡ c − 2 x T g ( c ) + g ( c ) T g ( c ) c^*={\arg\min}_c-2x^Tg(c)+g(c)^Tg(c) c=argminc2xTg(c)+g(c)Tg(c) 然后用 g ( c ) g(c) g(c)的定义 D c Dc Dc进行替换:
= arg ⁡ min ⁡ c − 2 x T D c + c T D T D c ={\arg\min}_c-2x^TDc+c^TD^TDc =argminc2xTDc+cTDTDc 由于 D D D的正交性和单位范数约束:
c ∗ = arg ⁡ min ⁡ c − 2 x T D c + c T I l c c^*={\arg\min}_c-2x^TDc+c^TI_lc c=argminc2xTDc+cTIlc = arg ⁡ min ⁡ c − 2 x T D c + c T c = {\arg\min}_c-2x^TDc+c^Tc =argminc2xTDc+cTc

目标函数

现在目标函数是 − 2 x T D c + c T c -2x^TDc+c^Tc 2xTDc+cTc,我们需要找到 c ∗ c^* c来最小化目标函数。使用向量微积分,并令其导数等于0:
∇ c ( − 2 x T D c + c T c ) = 0 \nabla_c(-2x^TDc+c^Tc)=0 c(2xTDc+cTc)=0 根据向量导数规则:
− 2 D T x + 2 c = 0 ⇒ c = D T x -2D^Tx+2c=0 \Rightarrow c=D^Tx 2DTx+2c=0c=DTx

找到编码矩阵 D D D

所以编码器函数是 f ( x ) = D T x f(x)=D^Tx f(x)=DTx。因此我们可以定义 PCA 重构操作为 r ( x ) = g ( f ( x ) ) = D ( D T x ) = D D T x r(x)=g(f(x))=D(D^Tx)=DD^Tx r(x)=g(f(x))=D(DTx)=DDTx

因此编码矩阵 D D D 也被重构过程使用。我们需要找到最优的 D D D 来最小化重构误差,即输入和重构之间所有维度特征的距离。这里使用 Frobenius 范数(矩阵范数)定义目标函数:
D ∗ = arg ⁡ min ⁡ D ∑ i , j ( x j ( i ) − r ( x i ) j ) 2 , D T D = I l D^*={\arg\min}_D\sqrt{\sum_{i,j}(x_j^{(i)}-r(x^{i})_j)^2},\quad D^TD=I_l D=argminDi,j(xj(i)r(xi)j)2 ,DTD=Il 从考虑 l = 1 l=1 l=1 的情况开始(这也是第一个主成分), D D D 是一个单一向量 d d d,并使用平方 L 2 L^2 L2 范数形式:
d ∗ = arg ⁡ min ⁡ d ∑ i ∣ ∣ ( x ( i ) − r ( x i ) ) ∣ ∣ 2 2 , ∣ ∣ d ∣ ∣ 2 = 1 d^*={\arg\min}_d{\sum_{i}||(x^{(i)}-r(x^{i}))}||_2^2, ||d||_2=1 d=argmindi∣∣(x(i)r(xi))22,∣∣d2=1 = arg ⁡ min ⁡ d ∑ i ∣ ∣ ( x ( i ) − d d T x ( i ) ) ∣ ∣ 2 2 , ∣ ∣ d ∣ ∣ 2 = 1 = {\arg\min}_d{\sum_{i}||(x^{(i)}-dd^Tx^{(i)})||_2^2}, ||d||_2=1 =argmindi∣∣(x(i)ddTx(i))22,∣∣d2=1 d T x ( i ) d^Tx^{(i)} dTx(i) 是一个标量:
= arg ⁡ min ⁡ d ∑ i ∣ ∣ ( x ( i ) − d T x ( i ) d ) ∣ ∣ 2 2 , ∣ ∣ d ∣ ∣ 2 = 1 = {\arg\min}_d{\sum_{i}||(x^{(i)}-d^Tx^{(i)}d)}||_2^2, ||d||_2=1 =argmindi∣∣(x(i)dTx(i)d)22,∣∣d2=1 标量等于其自身的转置:
d ∗ = arg ⁡ min ⁡ d ∑ i ∣ ∣ ( x ( i ) − x ( i ) T d d ) ∣ ∣ 2 2 , ∣ ∣ d ∣ ∣ 2 = 1 d^*= {\arg\min}_d{\sum_{i}||(x^{(i)}-x^{(i)T}dd)}||_2^2, ||d||_2=1 d=argmindi∣∣(x(i)x(i)Tdd)22,∣∣d2=1

使用矩阵形式表示

X ∈ R m × n X\in \mathbb{R}^{m\times n} XRm×n 表示所有描述点的向量堆叠,即 { x ( 1 ) T , x ( 2 ) T , … , x ( i ) T , … , x ( m ) T } \{x^{(1)^T}, x^{(2)^T}, \ldots, x^{(i)^T}, \ldots, x^{(m)^T}\} {x(1)T,x(2)T,,x(i)T,,x(m)T},使得 X i , : = x ( i ) T X_{i,:}=x^{(i)^T} Xi,:=x(i)T

X = [ x ( 1 ) T x ( 2 ) T … x ( m ) T ] ⇒ X d = [ x ( 1 ) T d x ( 2 ) T d … x ( m ) T d ] X = \begin{bmatrix} x^{(1)^T}\\ x^{(2)^T}\\ \ldots\\ x^{(m)^T} \end{bmatrix} \Rightarrow Xd = \begin{bmatrix} x^{(1)^T}d\\ x^{(2)^T}d\\ \ldots\\ x^{(m)^T}d \end{bmatrix} X= x(1)Tx(2)Tx(m)T Xd= x(1)Tdx(2)Tdx(m)Td ⇒ X d d T = [ x ( 1 ) T d d T x ( 2 ) T d d T … x ( m ) T d d T ] \Rightarrow Xdd^T = \begin{bmatrix} x^{(1)^T}dd^T\\ x^{(2)^T}dd^T\\ \ldots\\ x^{(m)^T}dd^T\\ \end{bmatrix} XddT= x(1)TddTx(2)TddTx(m)TddT ⇒ X − X d d T = [ x ( 1 ) T − x ( 1 ) T d d T x ( 2 ) T − x ( 2 ) T d d T … x ( m ) T − x ( m ) T d d T ] \Rightarrow X-Xdd^T = \begin{bmatrix} x^{(1)^T}-x^{(1)^T}dd^T\\ x^{(2)^T}-x^{(2)^T}dd^T\\ \ldots\\ x^{(m)^T}-x^{(m)^T}dd^T\\ \end{bmatrix} XXddT= x(1)Tx(1)TddTx(2)Tx(2)TddTx(m)Tx(m)TddT 矩阵中的一行的转置:
( x ( i ) T − x ( i ) T d d T ) T = x ( i ) − d d T x ( i ) (x^{(i)^T}-x^{(i)^T}dd^T)^T=x^{(i)}-dd^Tx^{(i)} (x(i)Tx(i)TddT)T=x(i)ddTx(i) 由于 d T x ( i ) d^Tx^{(i)} dTx(i) 是标量:
= x ( i ) − d T x ( i ) d = x ( i ) − x ( i ) T d d =x^{(i)}-d^Tx^{(i)}d=x^{(i)}-x^{(i)^T}dd =x(i)dTx(i)d=x(i)x(i)Tdd 所以我们知道 X X X 的第 i i i 行的 L 2 L^2 L2 范数与原始形式相同,因此我们可以使用矩阵重写问题,并省略求和符号:
d ∗ = arg ⁡ min ⁡ d ∣ ∣ X − X d d T ∣ ∣ F 2 , d T d = 1 d^*={\arg\min}_{d}||X-Xdd^T||_F^2, \quad d^Td=1 d=argmind∣∣XXddTF2,dTd=1 利用矩阵迹规则简化 Frobenius 范数部分如下:
arg ⁡ min ⁡ d ∣ ∣ X − X d d T ∣ ∣ F 2 {\arg\min}_{d}||X-Xdd^T||_F^2 argmind∣∣XXddTF2 = arg ⁡ min ⁡ d T r ( ( X − X d d T ) T ( X − X d d T ) ) ={\arg\min}_{d}Tr((X-Xdd^T)^T(X-Xdd^T)) =argmindTr((XXddT)T(XXddT)) = arg ⁡ min ⁡ d − T r ( X T X d d T ) − T r ( d d T X T X ) + T r ( d d T X T X d d T ) ={\arg\min}_{d}-Tr(X^TXdd^T)-Tr(dd^TX^TX)+Tr(dd^TX^TXdd^T) =argmindTr(XTXddT)Tr(ddTXTX)+Tr(ddTXTXddT) = arg ⁡ min ⁡ d − 2 T r ( X T X d d T ) + T r ( X T X d d T d d T ) ={\arg\min}_{d}-2Tr(X^TXdd^T)+Tr(X^TXdd^Tdd^T) =argmind2Tr(XTXddT)+Tr(XTXddTddT) 由于 d T d = 1 d^Td=1 dTd=1
= arg ⁡ min ⁡ d − 2 T r ( X T X d d T ) + T r ( X T X d d T ) ={\arg\min}_{d}-2Tr(X^TXdd^T)+Tr(X^TXdd^T) =argmind2Tr(XTXddT)+Tr(XTXddT) = arg ⁡ min ⁡ d − T r ( X T X d d T ) ={\arg\min}_{d}-Tr(X^TXdd^T) =argmindTr(XTXddT) = arg ⁡ max ⁡ d T r ( X T X d d T ) ={\arg\max}_{d}Tr(X^TXdd^T) =argmaxdTr(XTXddT) 由于迹是循环置换不变的,将方程重写为:
d ∗ = arg ⁡ max ⁡ d T r ( d T X T X d ) , d T d = 1 d^*={\arg\max}_{d}Tr(d^TX^TXd), \quad d^Td=1 d=argmaxdTr(dTXTXd),dTd=1 由于 d T X T X d d^TX^TXd dTXTXd 是实数,因此迹符号可以省略:
d ∗ = arg ⁡ max ⁡ d d T X T X d , d T d = 1 d^*={\arg\max}_{d}d^TX^TXd,\quad d^Td=1 d=argmaxddTXTXd,dTd=1

寻找最优的 d d d

现在的问题是找到最优的 d d d 来最大化 d T X T X d d^TX^TXd dTXTXd,并且有约束条件 d T d = 1 d^Td=1 dTd=1

使用拉格朗日乘子法来将问题描述为关于 d d d 的形式:
L ( d , λ ) = d T X T X d + λ ( d T d − 1 ) \mathcal{L}(d,\lambda)=d^TX^TXd+\lambda(d^Td-1) L(d,λ)=dTXTXd+λ(dTd1) d d d 求导数(向量导数规则):
∇ d L ( d , λ ) = 2 X T X d + 2 λ d \nabla_d\mathcal{L}(d,\lambda)=2X^TXd+2\lambda d dL(d,λ)=2XTXd+2λd 令导数等于0, d d d 将是最优的:
2 X T X d + 2 λ d = 0 2X^TXd+2\lambda d=0 2XTXd+2λd=0 X T X d = − λ d X^TXd=-\lambda d XTXd=λd X T X d = λ ′ d , ( λ ′ = − λ ) X^TXd=\lambda' d,\quad(\lambda'=-\lambda) XTXd=λd,(λ=λ) 这个方程是典型的矩阵特征值分解形式, d d d 是矩阵 X T X X^TX XTX 的特征向量, λ ′ \lambda' λ 是对应的特征值。

利用上述结果,让我们重新审视原方程:
d ∗ = arg ⁡ max ⁡ d d T X T X d , d T d = 1 d^*={\arg\max}_{d}d^TX^TXd, \quad d^Td=1 d=argmaxddTXTXd,dTd=1 = arg ⁡ max ⁡ d d T λ ′ d ={\arg\max}_{d}d^T\lambda' d =argmaxddTλd = arg ⁡ max ⁡ d λ ′ d T d ={\arg\max}_{d}\lambda'd^T d =argmaxdλdTd = arg ⁡ max ⁡ d λ ′ ={\arg\max}_{d}\lambda' =argmaxdλ 现在问题已经变的非常清楚了, X T X X^TX XTX 的最大特征值会最大化原方程的结果,因此最优的 d d d 是矩阵 X T X X^TX XTX 对应最大特征值的特征向量。

这个推导是针对 l = 1 l=1 l=1 的情况,只包含第一个主成分。当 l > 1 l>1 l>1 时, D = [ d 1 , d 2 , … ] D=[d_1, d_2, \ldots] D=[d1,d2,],第一个主成分 d 1 d_1 d1 是矩阵 X T X X^TX XTX 对应最大特征值的特征向量,第二个主成分 d 2 d_2 d2 是对应第二大特征值的特征向量,以此类推。


4 总结

我们有一个数据集,包含 m m m 个点,记为 x ( 1 ) , . . . , x ( m ) {x^{(1)},...,x^{(m)}} x(1),...,x(m)
X ∈ R m × n X\in \mathbb{R}^{m\times n} XRm×n 为将所有这些点堆叠而成的矩阵: [ x ( 1 ) T , x ( 2 ) T , … , x ( i ) T , … , x ( m ) T ] [x^{(1)^T}, x^{(2)^T}, \ldots, x^{(i)^T}, \ldots, x^{(m)^T}] [x(1)T,x(2)T,,x(i)T,,x(m)T]

主成分分析(PCA)编码函数表示为 f ( x ) = D T x f(x)=D^Tx f(x)=DTx,重构函数表示为 x ≈ g ( c ) = D c x\approx g(c)=Dc xg(c)=Dc,其中 D = [ d 1 , d 2 , … ] D=[d_1, d_2, \ldots] D=[d1,d2,] 的列是 X T X X^TX XTX 的特征向量,特征向量对应的特征值大小为降序排列。 D T x D^Tx DTx即是降维度之后的数据。


呼~
后续恢复元气后会分析一些PCA的应用案例。

在这里插入图片描述

“Remember, Red, hope is a good thing, maybe the best of things, and no good thing ever dies.
I will be hoping that this letter finds you, and finds you well.”

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1594340.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

QQ农场-phpYeFarm添加数据教程

前置知识 plugin\qqfarm\core\data D:\study-project\testweb\upload\source\plugin\qqfarm\core\data 也就是plugin\qqfarm\core\data是一个缓存文件,如果更新农场数据后,必须要删除才可以 解决种子限制(必须要做才可以添加成功) 你不更改加入了id大于2000直接删除种子 D…

Bridge 桥接

意图 将抽象部分与其显示部分分离&#xff0c;使他们都可以独立地变化。 结构 其中&#xff1a; Abstraction定义抽象类的接口&#xff0c;维护一个指向Implementer类型对象的指针。RefinedAbstraction扩展由Abstraction定义的接口。Implementor定义实现类的接口&#xff0c…

2024年DTC的回顾与思考

刚结束了2024的数据库技术嘉年华 这是我从2017年开始就参加的技术大会。中途因为疫情的耽误。正常来说我是连续的。知道我的朋友都知道我习惯炫耀一下。 按照惯例&#xff0c;此时此刻群友都在写大会回顾。只是有几个不讲武德的人已经发送了。下面有主观和客观的分析。 主观上…

亚马逊云科技CTO带你学习云计算降本增效秘诀

2023亚马逊云科技一年一度的重磅春晚--Re:invent上有诸多不同话题的主题Keynote&#xff0c;这次小李哥带大家复盘来自亚马逊CTO: Wener博士的主题演讲: 云架构节俭之道1️⃣节俭对于云计算为什么重要&#xff1f; ▶️企业基础设施投入大&#xff0c;利用好降本策略可以减少巨…

记录linux从0部署java项目(宝塔)

目录 一、安装宝塔可视化界面 二、部署前端 三、部署后端 1、配置并连接Mysql数据库 2、配置并连接redis 3、安装jdk 这里先记录一个安装后遇到的问题 安装openJDK 四、检查 一、安装宝塔可视化界面 宝塔面板下载&#xff0c;免费全能的服务器运维软件 运行安装脚本 安…

步骤大全:网站建设3个基本流程详解

一.领取一个免费域名和SSL证书&#xff0c;和CDN 1.打开网站链接&#xff1a;https://www.rainyun.com/z22_ 2.在网站主页上&#xff0c;您会看到一个"登陆/注册"的选项。 3.点击"登陆/注册"&#xff0c;然后选择"微信登录"选项。 4.使用您的…

时间序列模型:lag-Llama

项目地址&#xff1a;GitHub - time-series-foundation-models/lag-llama: Lag-Llama: Towards Foundation Models for Probabilistic Time Series Forecasting 论文地址&#xff1a;https://arxiv.org/pdf/2310.08278.pdf hugging-face镜像&#xff1a;https://hf-mirror.c…

C++11 设计模式2. 简单工厂模式

简单工厂&#xff08;Simple Factory&#xff09;模式 我们从实际例子出发&#xff0c;来看在什么情况下&#xff0c;应用简单工厂模式。 还是以一个游戏举例 //策划&#xff1a;亡灵类怪物&#xff0c;元素类怪物&#xff0c;机械类怪物&#xff1a;都有生命值&#xff0…

【一刷《剑指Offer》】面试题 3:二维数组中的查找

力扣对应题目链接&#xff1a;240. 搜索二维矩阵 II - 力扣&#xff08;LeetCode&#xff09; 核心考点&#xff1a;数组相关&#xff0c;特性观察&#xff0c;时间复杂度把握。 一、《剑指Offer》对应内容 二、分析题目 正常查找的过程本质就是排除的过程&#xff0c;谁排除…

傲基科技冲刺上市:依赖单一产品,元气未恢复,有股东提前退出

近日&#xff0c;傲基科技股份有限公司&#xff08;下称“傲基科技”&#xff09;递交招股书&#xff0c;准备在港交所主板上市&#xff0c;华泰证券为其独家保荐人。 据招股书介绍&#xff0c;傲基科技是一家提供家具家居类产品的品牌运营商及出口物流服务商。傲基科技在招股…

进程与线程的区别?

并发和并行 在聊进程和线程的概念之前&#xff0c;首先了解一下操作系统相关概念&#xff0c;大部分操作系统&#xff08;如Windos、Linux&#xff09;的任务调度是采用时间片轮转的抢占式调度方式&#xff0c;也就是一个任务执行一小段时间后强制暂停去执行下一个任务&#x…

音频变速python版

音频变速 如何能在不改变音频其他特点的情况下&#xff0c;只改变语速呢&#xff1f; 有几个python的库可以实现该功能&#xff0c;下面一一介绍。 pydub库 首先&#xff0c;确保安装了pydub和ffmpeg。 下面是一个简单的Python脚本&#xff0c;展示如何改变音频的播放速度&a…

通讯录的实现(顺序表版本)

我们知道通讯录是基于顺序表的前提下&#xff0c;要写好通讯录我们就要深入了解好顺序表。我们先来看看什么是顺序表。&#xff08;注意今天代码量有点多&#xff0c;坚持一下&#xff09;。冲啊&#xff01;兄弟们&#xff01; 顺序表的简单理解 对于顺序表&#xff0c;我们首…

地球上的七大洲介绍

地球上的七大洲示意图&#xff1a; 1. 亚洲&#xff08;Asia&#xff09;&#xff1a;世界上最大的洲&#xff0c;面积约为44579000平方公里。亚洲地域辽阔&#xff0c;包括从北极圈到赤道的各种气候和地形。它拥有世界上最多的人口&#xff0c;也是世界上一些最古老文明的发源…

2024年腾讯云最新优惠活动及领券入口整理分享

随着云计算技术的快速发展&#xff0c;越来越多的企业和个人选择将业务部署在云端。腾讯云作为国内知名的云计算服务提供商&#xff0c;为用户提供了丰富的云产品和服务。为了帮助用户降低成本&#xff0c;腾讯云定期推出各种优惠活动。本文将为大家整理分享2024年腾讯云的最新…

1.MMD模型动作场景镜头的导入及视频导出

界面介绍 MIKUMIKUDANCE926版本 MMD的工具栏模型骨骼帧的窗口&#xff0c;在不同时间做不同动作&#xff0c;可以在这里打帧操作时间曲线操作窗口&#xff0c;控制模型两个动作之间的过渡模型操作窗口&#xff0c;导入模型选择模型相机操作&#xff0c;控制相机远近&#xf…

JS/TS笔记学习2

周末总得学点什么吧~ 奥利给! 设计模式: 事件订阅派发模式 简单说就是:事件调度中心,负责接收事件发布者的消息&#xff0c;并将这些消息分发给所有订阅了该事件的订阅者 为什么用它&#xff0c;在构建大型、复杂或交互性强的应用程序时&#xff0c;用该模式非常方便&#xff0…

至少需要[XXXXMB]内存才能安装(宝塔导入数据库提示)

①我的2g内存腾讯云服务器想安装mysql8.0 ②宝塔提示“至少需要[3700MB]内存才能安装” 将数据库部署到宝塔上的时候提示-----》至少需要[XXXXMB]内存才能安装&#xff0c;解决的方法其实也很简单。 首先&#xff0c;进入文件夹/www/server/panel/class&#xff0c;找到找到…

OpenSSH 安全漏洞(CVE-2023-51385) 升级v9.7

漏洞编号&#xff1a;OpenSSH 安全漏洞(CVE-2023-51385) openssh9.7文件获取 https://f.ws59.cn/f/dtv9atef3io 复制链接到浏览器打开 处理方式 ##注释掉的根据实际情况处理 #查询原openssh9.4p1是否有安装openssh-askpass&#xff0c;若有需先删除 rpm -qa | grep openss…

解决Xshell登录云服务器的免密码和云服务器生成子用户问题

Xshell登录云服务器的免密码问题 前言一、Xshell登录云服务器的免密码操作实践 二、centos创建用户创建用户实操删除用户更改用户密码直接删除子用户 前言 Xshell登录云服务器免密码问题的解决方案通常涉及使用SSH密钥对。用户生成一对密钥&#xff08;公钥和私钥&#xff09;…