• 【机器学习】python机器学习scikit-learn和pandas进行Pipeline处理工作:归一化和标准化及自定义转换器(二)


    数据准备:详见【机器学习】python机器学习借助scikit-learn进行数据预处理工作:缺失值填补,文本处理(一)
    一、自定义转换器:

    from sklearn.base import BaseEstimator, TransformerMixin
    #TransformerMixin可使方法自动获得fit_transform方法
    #BaseEstimator作为基类(并在构造函数中避免*args和**kargs),能额外获得两种非常有用的自动调整超参数的方法(get_params()和set_params())
    
    
    class CombinedAttributesAdder(BaseEstimator, TransformerMixin):
        def __init__(self): # no *args or **kargs
            #fit在不保存参数情况下仅返回自己
            pass
        def fit(self, X, y=None):
            return self  
        def transform(self, X):
            X=X.values
            totallOTherRooms = X[:, 3]-X[:, 4]
            return np.c_[X, totallOTherRooms]
        
    attr_adder = CombinedAttributesAdder()
    housing_extra_attribs = attr_adder.transform(housing_num)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    输出为ndarrary,可用如下代码恢复pd结构:

    housing_extra_attribs = pd.DataFrame(
        housing_extra_attribs,
        columns=list(housing_num.columns)+["otherrooms"],
        index=housing_num.index)
    housing_extra_attribs.head()
    
    • 1
    • 2
    • 3
    • 4
    • 5

    注:. values:对应的二维NumPy值数组
    np.c_ 用于连接两个矩阵
    np.c 中的c 是 column(列)的缩写,就是按列叠加两个矩阵,就是把两个矩阵左右组合,要求行数相等。

    二、数据归一化及标准化

    最小-最大缩放(又叫作归一化)很简单:将值重新缩放使其最终范围归于0~1之间。实现方法是将值减去最小值并除以最大值和最小值的差。对此,Scikit-Learn提供了一个名为MinMaxScaler的转换器。如果出于某种原因,你希望范围不是0~1,那么可以通过调整超参数feature_range进行更改。
    在这里插入图片描述

    list=[[-1, 2], [-0.5, 6], [0, 10], [1, 18]]
    from sklearn.preprocessing import MinMaxScaler,StandardScaler
    s=MinMaxScaler()
    s.fit_transform(list)
    
    • 1
    • 2
    • 3
    • 4

    array([[0. , 0. ],
    [0.25, 0.25],
    [0.5 , 0.5 ],
    [1. , 1. ]])

    标准化则完全不一样:首先减去平均值(所以标准化值的均值总是零),然后除以方差,从而使得结果的分布具备单位方差。不同于最小-最大缩放的是,标准化不将值绑定到特定范围,对某些算法而言,这可能是个问题(例如,神经网络期望的输入值范围通常是0~1)。但是标准化的方法受异常值的影响更小。例如,假设某个地区的平均收入为100(错误数据),最小-最大缩放会将所有其他值从0~15降到0~0.15,而标准化则不会受到很大影响。Scikit-Learn提供了一个标准化的转换器StandadScaler。
    在这里插入图片描述

    s=StandardScaler()
    s.fit_transform(list)
    
    • 1
    • 2

    array([[-1.18321596, -1.18321596],
    [-0.50709255, -0.50709255],
    [ 0.16903085, 0.16903085],
    [ 1.52127766, 1.52127766]])

    之后可用inverse_transform方法恢复原始数据。

    三、建立自动化的流水线
    Pipeline构造函数会通过一系列名称/估算器的配对来定义步骤序列。除了最后一个是估算器之外,前面都必须是转换器(也就是说,必须有fit_transform()方法)

    当调用流水线的fit()方法时,会在所有转换器上按照顺序依次调用fit_transform(),将一个调用的输出作为参数传递给下一个调用方法,直到传递到最终的估算器,则只会调用fit()方法。

    在对一个pandframe进行数据处理时,其中文本项要转为onehot,数值项要填补缺失,有两种方案,其一为:
    自定义一个pd列选择器,区分输入pd列:

    from sklearn.impute import SimpleImputer
    from sklearn.preprocessing import MinMaxScaler,StandardScaler,OneHotEncoder
    from sklearn.base import BaseEstimator, TransformerMixin
    
    
    # 选择器,位于第一个,从pandaframe中选择要处理的列并返回NUMPY
    class OldDataFrameSelector(BaseEstimator, TransformerMixin):
        def __init__(self, attribute_names):
            self.attribute_names = attribute_names
        def fit(self, X, y=None):
            return self
        def transform(self, X):
            return X[self.attribute_names].values
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    from sklearn.pipeline import Pipeline
    from sklearn.preprocessing import StandardScaler
    
    #备注:housing_num已去除文本列
    num_attribs = list(housing_num)
    cat_attribs = ["ocean_proximity"]
    
    old_num_pipeline = Pipeline([
            ('selector', OldDataFrameSelector(num_attribs)),
            ('imputer', SimpleImputer(strategy="median")),
            ('std_scaler', StandardScaler()),
        ])
    
    old_cat_pipeline = Pipeline([
            ('selector', OldDataFrameSelector(cat_attribs)),
            ('cat_encoder', OneHotEncoder(sparse=False)),
        ])
    from sklearn.pipeline import FeatureUnion
    
    old_full_pipeline = FeatureUnion(transformer_list=[
            ("num_pipeline", old_num_pipeline),
            ("cat_pipeline", old_cat_pipeline),
        ])
    #调用时输入的是原始pd:
    old_housing_prepared = old_full_pipeline.fit_transform(housing)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    其二是,在scikit0.20后的高级版本中,引入:

    #去掉带文字的指定列
    from sklearn.preprocessing import MinMaxScaler,StandardScaler,OneHotEncoder
    housing_num = housing.drop("ocean_proximity", axis=1)
    
    from sklearn.impute import SimpleImputer
    from sklearn.preprocessing import StandardScaler
    from sklearn.pipeline import Pipeline
    
    num_pipeline = Pipeline([
            ('imputer', SimpleImputer(strategy="median")),
            ('std_scaler', StandardScaler())
        ])
        
    from sklearn.compose import ColumnTransformer
    #返回所有列名
    num_attribs = list(housing_num)
    cat_attribs = ["ocean_proximity"]
    
    full_pipeline = ColumnTransformer([
            ("num", num_pipeline, num_attribs),
            ("cat", OneHotEncoder(), cat_attribs),
        ])
    
    housing_prepared = full_pipeline.fit_transform(housing)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
  • 相关阅读:
    Docker部署Zabbix
    设计一个简单HTML爵士音乐网页(HTML+CSS)
    智能变电站协议转换采集网关BA103
    又有新框架上线了,测试、AI 通通有「GitHub 热点速览」
    机器学习理论之(13):感知机 Perceptron;多层感知机(神经网络)
    SpringBoot2:web开发常用功能实现及原理解析-上传与下载
    【Linux】进程状态详解
    如何做好需求收集?方法和步骤
    JDK, JRE, 和 JVM 的解释
    Linux从入门到精通(十)——进程管理
  • 原文地址:https://blog.csdn.net/hh1357102/article/details/126331687