代码之家  ›  专栏  ›  技术社区  ›  edesz

Scikit Learn FunctionTransformer正在管道中,没有其他功能-不返回原始数据?

  •  1
  • edesz  · 技术社区  · 10 年前

    我正在尝试运行自定义变压器 FunctionTransformer() 在Python2.7中的Scikit-Learn管道中。我使用了文档中的示例 here 。此示例执行PCA,然后仅选择第二个变换的组件。即变换NumPy数组X并提取变换后的NumPy数组的第二列。

    我对官方文档中的代码所做的更改如下:

    1. 从管道中删除PCA()
    2. 添加2个打印语句以查看管道前的X和管道后的X
    3. 删除了列车测试拆分-这样我就用X训练,然后转换X
    4. 注释掉所有绘图代码

    以下是完整的工作代码:

    import matplotlib.pyplot as plt
    import numpy as np
    from sklearn.cross_validation import train_test_split
    from sklearn.decomposition import PCA
    from sklearn.pipeline import make_pipeline
    from sklearn.preprocessing import FunctionTransformer
    
    def _generate_vector(shift=0.5, noise=15):
        return np.arange(1000) + (np.random.rand(1000) - shift) * noise
    
    def generate_dataset():
        """
        This dataset is two lines with a slope ~ 1, where one has
        a y offset of ~100
        """
        return np.vstack((
            np.vstack((
                _generate_vector(),
                _generate_vector() + 100,
            )).T,
            np.vstack((
                _generate_vector(),
                _generate_vector(),
            )).T,
        )), np.hstack((np.zeros(1000), np.ones(1000)))
      
    def all_but_first_column(X):
        return X[:, 1:]
    
    def drop_first_component(X, y):
        """
        Create a pipeline with PCA and the column selector and use it to
        transform the dataset.
        """
        pipeline = make_pipeline(
            FunctionTransformer(all_but_first_column),
        )
        pipeline.fit(X,y)
        return pipeline.transform(X), y
    
    if __name__ == '__main__':
        X, y = generate_dataset()
        print X[:20,:]
        X_transformed, y_transformed = drop_first_component(*generate_dataset())
        print X_transformed[:20,:]
    

    运行此代码时,我得到以下输出:

    管道前:

    [[ -9.54109780e-01   1.00849257e+02]
     [ -6.44868525e+00   9.89713451e+01]
     [  6.00611903e+00   9.86368545e+01]
     [ -1.02307489e-01   9.91617270e+01]
     [  1.12423836e+01   1.04240711e+02]
     [  6.94957296e+00   1.09557543e+02]
     [  5.41042855e+00   1.09859950e+02]
     [  9.54984210e-01   1.03636786e+02]
     [  1.11194327e+01   1.06942524e+02]
     [  1.32146748e+01   1.16489221e+02]
     [  1.72316993e+01   1.16995924e+02]
     [  1.22797187e+01   1.08568249e+02]
     [  1.14360695e+01   1.06799741e+02]
     [  1.75291161e+01   1.13610682e+02]
     [  1.38768685e+01   1.07815267e+02]
     [  1.29773817e+01   1.12404830e+02]
     [  1.54218007e+01   1.11786074e+02]
     [  1.73923980e+01   1.19284226e+02]
     [  1.97373775e+01   1.16807048e+02]
     [  1.26896716e+01   1.26467393e+02]]
    

    管道之后:

    [[  94.35392453]
     [ 107.08036958]
     [  96.42404642]
     [  96.07304368]
     [ 109.33207232]
     [ 102.67435761]
     [ 106.34131846]
     [ 108.45857447]
     [ 105.33376831]
     [ 107.79576699]
     [ 110.71367112]
     [ 116.73589447]
     [ 117.74629814]
     [ 112.48947773]
     [ 109.7573836 ]
     [ 121.95472733]
     [ 119.62476775]
     [ 120.0264124 ]
     [ 115.00315794]
     [ 120.60368954]]
    

    来自这个Github post ,它提到 函数转换器() 可以用来做一些简单的事情。我希望在管道中只放置一列。

    管道前后的X不同。如果我只想让管道删除X的最后一列,那么这个管道应该在管道前后返回相同的X吗?

    其他信息(如有必要):

    在我的最后一个应用程序中,我需要使用变压器作为管道中的第一步,然后 PCA() 在第二站。因此,我在本文中首先测试的是管道,只有第一步- 函数转换器() .

    1 回复  |  直到 6 年前
        1
  •  1
  •   Anthony E    10 年前

    你打了两个电话给 generate_dataset() 因此,您的 drop_first_component 函数不是 X , y ,但一些新生成的数据。

    通过同样的测试 (X, y) 直接发送到 generate_dataset 修复了问题:

    if __name__ == '__main__':
      X, y = generate_dataset()
      print X[:20, :]
      X_transformed, y_transformed = drop_first_component(X, y)
      print X_transformed[:20, :]
    

    也就是说,我认为在这里使用流水线阶段完全是过火了。您要导入一些额外的库,包括几个额外的配置行和逻辑行,这些行分布在三个函数中——所有这些都是为了进行计算,只需简单的列选择 X[:, 1:] .