python中的逆局部线性嵌入LLE

Posted

技术标签:

【中文标题】python中的逆局部线性嵌入LLE【英文标题】:Inverse locally linear embedding LLE in python 【发布时间】:2021-11-06 10:52:51 【问题描述】:

如何使用 sklearn 或其他 python 包执行逆局部线性嵌入 (LLE)?

我想对一些表格数据 X 执行分类机器学习算法(SVM、神经网络...),其中 y 是目标类变量。

像往常一样,程序如下:

将 X 和 y 拆分为 X_train、y_train、X_test、y_test。由于我有大量参数(列)。我可以使用 X_train 上的 LLE 减少参数数量以获得 X_train_lle。 y 是一个目标变量,它不进行任何转换。之后,我可以简单地在 X_train_lle 上训练一个模型。当我想在 y_test 上使用经过训练的模型时,就会出现问题。如果在 X_test 和 X_train 上执行 LLE,则会引入数据泄漏。此外,如果 LLE 仅在 X_test 上执行,则新的 X_test_lle 可能会完全不同,因为该算法使用 k 个最近邻。我想正确的过程应该是在 X_test 上使用 X_train 上获得的参数执行逆 LLE,然后在 X_test_lle 上使用分类模型。

我查看了一些参考资料,第 2.4.1 节处理的是逆 LLE。 https://arxiv.org/pdf/2011.10925.pdf

如何用python(最好是sklearn)做逆LLE?

这是一个代码示例:

import numpy as np

from sklearn import preprocessing
from sklearn import svm, datasets
from sklearn.manifold import LocallyLinearEmbedding


### Generating dummy data
n_row = 10000 # these numbers are much bigger for the real problem
n_col = 50 #
X = np.random.random(n_row, n_col)
y = np.random.randint(5, size=n_row) # five different classes labeled from 0 to 4

### Preprocessing ###
X_train, X_test, y_train, y_test = model_selection.train_test_split(X, y, test_size = 0.5, random_state = 1)
#standardization using StandardScaler applied to X_train and then scaling X_train and X_test
scaler = preprocessing.StandardScaler()
scaler.fit(X_train)
X_train = scaler.transform(X_train)
X_test = scaler.transform(X_test)

### Here is the part with LLE ###
# We reduce the parameter space to 10 with 15 nearest neighbours
X_train_lle = LocallyLinearEmbedding(n_neighbors=15, n_components=10, method='modified', eigen_solver='dense')

### Here is the training part ###
# we want to apply SVM to transformed data X_train_lle
#Create a svm Classifier
clf = svm.SVC(kernel='linear') # Linear Kernel

#Train the model using the training sets
clf.fit(X_train_lle, y_train)


# Here should go the code to do inverse LLE on X_test 
#i.e. where do values of X_test_lle fit in the manufold X_train_lle


### After the previous part of the code was successfully solved by *** community :)
#Predict the response for test dataset
y_pred = clf.predict(X_test_lle)

【问题讨论】:

您可以先查看这个 scikit-learn 课程:scikit-learn.org/stable/modules/generated/… 如果您有更具体的问题,查看代码示例会有所帮助。跨度> 你说得对,我会放一些代码以便更好地理解问题 请避免与问题无关的导入墙(已编辑)。 【参考方案1】:

就像任何 scikit-learn 转换器一样,从类 from sklearn.manifold import LocallyLinearEmbedding 创建的对象实现了 .fit().transform() 方法。 (在您的示例中,StandardScaler 是变压器的另一个示例)。因此,要使用 X_train 中的数据找到嵌入空间,您可以这样做:

embedding = LocallyLinearEmbedding(n_neighbors=15, n_components=10, method='modified', eigen_solver='dense')
embedding.fit(X_train)

# Transform X_train using LLE fit above
X_train_lle = embedding.transform(X_train)

# transform X_test, using LLE fit on X_train:
X_test_lle = embedding.transform(X_test)

print('train: ', X_train.shape, X_train_lle.shape)
print('test: ', X_test.shape, X_test_lle.shape)

【讨论】:

【参考方案2】:

可以使用您提到的论文(Ghojogh et al. (2020) - Sec. 2.4.1)和其他论文(例如,Franz et al. (2014) - Sec. 4.1)中的方法进行逆变换。这个想法是您在嵌入空间中找到 k 最近邻,然后将每个点表示为嵌入空间中其邻居的线性组合。然后保持获得的权重,并使用相同的权重将原始点中的每个点表示为其k近邻的组合。显然,应该使用与原始前向 LLE 相同数量的邻居。

使用barycenter_kneighbor_graph 函数的代码如下所示:

from sklearn.manifold._locally_linear import barycenter_kneighbors_graph
# calculate the weights for expressing each point in the embedded space as a linear combination of its neighbors
W = barycenter_kneighbors_graph(Y, n_neighbors = k, reg = 1e-3)
# reconstruct the data points in the high dimensional space from its neighbors using the weights calculated based on the embedded space
X_reconstructed = W @ X

其中 Y 是原始 LLE 嵌入的结果(这是您的代码 sn-p 中的 X_train_lle),X 是原始数据矩阵,k 是最近邻的数量。

【讨论】:

以上是关于python中的逆局部线性嵌入LLE的主要内容,如果未能解决你的问题,请参考以下文章

用scikit-learn研究局部线性嵌入(LLE)

局部线性嵌入(LLE)原理总结

局部线性嵌入(LLE)原理总结

流行学习流形学习家族局部线性嵌入LLE随机投影(Random Projection)t-SNE降维及可视化

机器学习——降维(主成分分析PCA线性判别分析LDA奇异值分解SVD局部线性嵌入LLE)

降维LLE与其他降维技术