我正在尝试为TSNE制作一个自定义函数,以便它可以在Sklearn make_pipeline函数中使用。
一般来说,对于PCA,我会做以下操作:
make_pipeline(PCA(),
LinearRegression())
然而,当我尝试这个:
make_pipeline(TSNE(),
LinearRegression())
我会得到一个错误,说它没有transform()方法,也不能使用fit_transform()方法。所以,现在我正尝试使用以下方法创建一个自定义transform()方法:
class TSNE_wrapper(TSNE):
def transform(X):
return TSNE().fit_transform(X)
但我得到了这个错误:
transform() takes 1 positional argument but 2 were given
您的修复是对的,但不应该这样做!
主成分分析
PCA通过找到最大化方差的轴来创建嵌入:给定训练集,您可以找到数据变化很大的方向(轴(x、y、z等)的线性组合)。拟合PCA的结果是k个方向(轴的k个线性组合)(这是sklearn中的.components属性)。然后,您可以通过将线性组合应用于测试点来转换测试数据。
TSNE
另一方面,TSNE创建了低维嵌入,试图(在一定程度上)尊重真实维度中的点之间的距离。TSNE不考虑点在高维空间中的位置,它只关注该点与其邻居之间的距离。并尽量在昏暗的空间里尊重这些关系
这就是为什么Sklearn没有用于该类的转换函数,您不能使用TSNE转换数据:TSNE转换函数需要首先适应数据。
- 如果你想了解更多信息,请查看这篇非常好的文章:http://mlexplained.com/2018/09/14/paper-dissected-visualizing-data-using-t-sne-explained/
回到你的问题
如果您使用带有训练/测试拆分的管道,TSNE对象将在测试时使用测试数据进行重新训练!并且没有理由认为嵌入看起来与训练数据拟合的嵌入相同(同样,因为嵌入取决于训练期间给出的点)。ML模型的性能应该很差!
如果你真的想使用TSNE,然后使用机器学习,你必须对整个数据集进行拟合转换训练和测试:但请记住,你的机器学习功能将毫无用处,因为你泄露了测试数据!