Bab*_*emi 5 python machine-learning dimensionality-reduction scikit-learn
我尝试使用scikit-learn 库中的线性判别分析,以便对具有 200 多个特征的数据执行降维。inverse_transform但我在LDA类中找不到该函数。
我只是想问,如何从LDA域中的一个点重建原始数据?
根据 @bogatron 和 @kazemakase 回答进行编辑:
我认为“原始数据”这个术语是错误的,我应该使用“原始坐标”或“原始空间”。我知道如果没有所有 PCA,我们就无法重建原始数据,但是当我们构建形状空间时,我们会在 PCA 的帮助下将数据投影到更低的维度。PCA 尝试仅用 2 或 3 个分量来解释数据,这些分量可以捕获数据的大部分方差,如果我们基于它们重建数据库,它应该向我们显示导致这种分离的形状部分。
我再次检查了 scikit-learn LDA 的源代码,我注意到特征向量存储在scalings_变量中。当我们使用svd求解器时,不可能反转特征向量 ( scalings_) 矩阵,但是当我尝试矩阵的伪逆时,我可以重建形状。
这里,有两个图像分别从 [ 4.28, 0.52] 和 [0, 0] 点重建:
我认为如果有人深入解释 LDA 逆变换的数学局限性那就太好了。
LDA 的逆不一定有意义,因为它丢失了很多信息。
为了进行比较,请考虑 PCA。这里我们得到一个用于变换数据的系数矩阵。我们可以通过从矩阵中剥离行来进行降维。为了获得逆变换,我们首先反转整个矩阵,然后删除与删除的行对应的列。
LDA 没有给我们一个完整的矩阵。我们只能得到一个不能直接求逆的简化矩阵。可以采用伪逆,但这比我们拥有完整矩阵的效率要低得多。
考虑一个简单的例子:
C = np.ones((3, 3)) + np.eye(3) # full transform matrix
U = C[:2, :] # dimensionality reduction matrix
V1 = np.linalg.inv(C)[:, :2] # PCA-style reconstruction matrix
print(V1)
#array([[ 0.75, -0.25],
# [-0.25, 0.75],
# [-0.25, -0.25]])
V2 = np.linalg.pinv(U) # LDA-style reconstruction matrix
print(V2)
#array([[ 0.63636364, -0.36363636],
# [-0.36363636, 0.63636364],
# [ 0.09090909, 0.09090909]])
Run Code Online (Sandbox Code Playgroud)
如果我们有完整的矩阵,我们会得到V1与简单反转变换 ( )不同的逆变换 ( ) V2。这是因为在第二种情况下,我们丢失了有关废弃组件的所有信息。
你被警告了。如果你仍然想进行 LDA 逆变换,这里有一个函数:
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.decomposition import PCA
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.utils.validation import check_is_fitted
from sklearn.utils import check_array, check_X_y
import numpy as np
def inverse_transform(lda, x):
if lda.solver == 'lsqr':
raise NotImplementedError("(inverse) transform not implemented for 'lsqr' "
"solver (use 'svd' or 'eigen').")
check_is_fitted(lda, ['xbar_', 'scalings_'], all_or_any=any)
inv = np.linalg.pinv(lda.scalings_)
x = check_array(x)
if lda.solver == 'svd':
x_back = np.dot(x, inv) + lda.xbar_
elif lda.solver == 'eigen':
x_back = np.dot(x, inv)
return x_back
iris = datasets.load_iris()
X = iris.data
y = iris.target
target_names = iris.target_names
lda = LinearDiscriminantAnalysis()
Z = lda.fit(X, y).transform(X)
Xr = inverse_transform(lda, Z)
# plot first two dimensions of original and reconstructed data
plt.plot(X[:, 0], X[:, 1], '.', label='original')
plt.plot(Xr[:, 0], Xr[:, 1], '.', label='reconstructed')
plt.legend()
Run Code Online (Sandbox Code Playgroud)
你看,逆变换的结果与原始数据没有太大关系(嗯,可以猜测投影的方向)。相当一部分的变化已经永远消失了。
| 归档时间: |
|
| 查看次数: |
4538 次 |
| 最近记录: |