文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Python数据分析真的不难学,实战来了:大佬级别数据预处理方式

2024-12-11 19:58

关注

说到预处理,一般就是需要:

在做数据处理以及机器学习的过程中,最后你会发现每个项目似乎都存在“套路”。所有的项目处理过程都会存在一个“套路”:

对于预处理,其实也是一个套路,不过我们不用pipeline 函数,而是另一个FeatureUnion函数。

当然一个函数也不能解决所有问题,我们通过实战来看看哪些函数以及编码风格能让我们的代码看起来很有条理并且“大(zhuang)佬(bi)”风格十足。

导入数据开启实战

今天我们分析的titanic 数据,数据我已经下载,并且放在项目路径下的data 文件中。

  1. import pandas as pd 
  2. file = 'data/titanic_train.csv' 
  3. raw_df = pd.read_csv(file) 

接下来就是标准套路:预览info以及预览head。

  1. print(raw_df.info()) 
  2. print(raw_df.head()) 

我们对数据集的名称进行简单的回顾:

按数据类型来划分:

int64 :

object:

float64:

  1. RangeIndex: 891 entries, 0 to 890 
  2. Data columns (total 12 columns): 
  3.  #   Column       Non-Null Count  Dtype   
  4. ---  ------       --------------  -----   
  5.  0   PassengerId  891 non-null    int64   
  6.  1   Survived     891 non-null    int64   
  7.  2   Pclass       891 non-null    int64   
  8.  3   Name         891 non-null    object  
  9.  4   Sex          891 non-null    object  
  10.  5   Age          714 non-null    float64 
  11.  6   SibSp        891 non-null    int64   
  12.  7   Parch        891 non-null    int64   
  13.  8   Ticket       891 non-null    object  
  14.  9   Fare         891 non-null    float64 
  15.  10  Cabin        204 non-null    object  
  16.  11  Embarked     889 non-null    object  
  17. dtypes: float64(2), int64(5), object(5) 
  18. memory usage: 83.7+ KB 

一般的机器学习都不会预处理缺失值以及类别型数据,因此我们至少要对这两种情形做预处理。

首先我们查看缺失值,其实上文中的info已经有这样的信息。这里我们更显式的展示缺失信息。

  1. # get null count for each columns 
  2. nulls_per_column = raw_df.isnull().sum() 
  3. print(nulls_per_column) 

结果如下:

  1. PassengerId       0 
  2. Survived             0 
  3. Pclass                 0 
  4. Name                 0 
  5. Sex                     0 
  6. Age                177 
  7. SibSp                  0 
  8. Parch                  0 
  9. Ticket                 0 
  10. Fare                    0 
  11. Cabin             687 
  12. Embarked          2 
  13. dtype: int64 

可以看到Age 有缺失,Age是float64 类型数据,Cabin 有缺失,Cabin 为object 类型,Embarked 有缺失,Embarked 也是object 类型。

主角登场(策略与函数)

上述我们可以看到缺失的列有哪些,对于有些情况,比如快速清理数据,我们仅仅会制定如下策略:

对于float类型,我们一般就是用均值或者中位数来代替 对于object 类型,如果ordinal 类型,也就是严格类别之分,比如(男,女),比如(高,中,低)等,一般就用众数来替代 对于object 类型,如果nominal类型,也就是没有等级/严格类别关系,比如ID,我们就用常值来替代。本文中用到的是sklearn的preprocessing 模块,pipeline模块,以及一个第三方“新秀”sklearn_pandas 库。

这里我们简单的介绍这个函数的用途。

  1. StandardScaler: 用于对数字类型做标准化处理 
  2. LabelBinarizer: 顾名思义,将类型类型,先label 化(变成数字),再Binarize (变成二进制)。相当于onehot 编码,不过LabelBinarizer只是针对一列进行处理 
  3. FeatureUnion:用于将不同特征预处理过程(函数)重新合并,但是需要注意的是它的输入不是数据而是transformer,也就是预处理的方法。 
  4. SimpleImputer:sklearn 自带了类似于fillna的预处理函数 
  5. CategoricalImputer: 来自于sklearn_pandas 的补充,因为sklearn 中并没有针对类别类型数据的预处理。 
  6. DataFrameMapper: 相当于构建针对dataframe的不同的列构建不同的transformer。 
  7. from sklearn.preprocessing import StandardScaler 
  8. from sklearn.preprocessing import LabelBinarizer 
  9. from sklearn.pipeline import FeatureUnion 
  10. from sklearn_pandas import CategoricalImputer 
  11. from sklearn_pandas import DataFrameMapper 
  12. from sklearn.impute import SimpleImputer 

按照我们策略,我们需要将列分为数字型和类别型。思路就是看一列数据是否为object类型。

  1. # split categorical columns and numerical columns 
  2. categorical_mask = (raw_df.dtypes == object) 
  3. categorical_cols = raw_df.columns[categorical_mask].tolist() 
  4. numeric_cols = raw_df.columns[~categorical_mask].tolist() 
  5. numeric_cols.remove('Survived'
  6. print(f'categorical_cols are {categorical_cols}' ) 
  7. print(f'numeric_cols are {numeric_cols}' ) 

print:

  1. categorical_cols are ['Name''Sex''Ticket''Cabin''Embarked'
  2. numeric_cols are ['PassengerId''Pclass''Age''SibSp''Parch''Fare'

数值型数据预处理

对数值型数据进行预处理,这里我们采用DataFrameMapper来创建这个transformer 对象,对所有的numeric_cols 进行填写中值。

  1. numeric_fillna_mapper=DataFrameMapper([([col], SimpleImputer(strategy="median")) for col in numeric_cols], 
  2.                                             input_df=True
  3.                                             df_out=True 
  4.                                            ) 

我们可以测试代码,看一下变换后的数据是什么样。这里需要调用fit_transform 方法。

  1. transformed = numeric_fillna_mapper.fit_transform(raw_df) 
  2. print(transformed.info()) 

结果如下,可以看到变换后的数据只包含我们处理的列,并且可以看到non-null 个数已经为891,表明没有缺失。

  1. #   Column       Non-Null Count  Dtype   
  2. --  ------       --------------  -----   
  3. 0   PassengerId  891 non-null    float64 
  4. 1   Pclass       891 non-null    float64 
  5. 2   Age          891 non-null    float64 
  6. 3   SibSp        891 non-null    float64 
  7. 4   Parch        891 non-null    float64 
  8. 5   Fare         891 non-null    float64 

如果我们需要对数值型特征,先进行缺失值填充,然后再进行标准化。这样我们只需要将上面的函数重新修改,增加一个transformer list。这个transformer list包含SimpleImputer 和StandardScaler 两步。

  1. # fill nan with mean 
  2. and then standardize cols 
  3. numeric_fillna_standardize_mapper=DataFrameMapper([([col], [SimpleImputer(strategy="median"), 
  4.                                                 StandardScaler()]) for col in numeric_cols], 
  5.                                             input_df=True
  6.                                             df_out=True 
  7.                                            ) 
  8. fillna_standardized = numeric_fillna_standardize_mapper.fit_transform(raw_df) 
  9.  
  10. print(fillna_standardized.head()) 

预览变换后的结果:

  1.    PassengerId       Pclass          Age        SibSp        Parch          Fare 
  2. 0    -1.730108  0.827377 -0.565736  0.432793 -0.473674 -0.502445 
  3. 1    -1.726220 -1.566107  0.663861  0.432793 -0.473674  0.786845 
  4. 2    -1.722332  0.827377 -0.258337 -0.474545 -0.473674 -0.488854 
  5. 3    -1.718444 -1.566107  0.433312  0.432793 -0.473674  0.420730 
  6. 4    -1.714556  0.827377  0.433312 -0.474545 -0.473674 -0.486337 

这样我们就完成了数值型数据的预处理。类似的我们可以针对类别型数据进行预处理。

类别型数据预处理

本例中,Cabin 有缺失,Embarked 有缺失,因为这两者都是有有限类别个数的,我们可以用出现最高频次的数据进行填充,假如是Name 缺失呢?一般Name都没有重名的,而且即便有个别重名,用最高频次的数据进行填充也没有意义。所以我们会选择用常数值填充,比如“unknown”等。

作为一个模板,这里我们的处理方法要涵盖两种情况。

['Name','Cabin','Ticket'] 其实都类似于ID,几乎没有重复的,我们用常值替代,然后用LabelBinarizer变成dummy 变量 其他列,我们用最高频次的类别填充,然后用LabelBinarizer变成dummy 变量。

  1. # Apply categorical imputer 
  2.  
  3. constant_cols = ['Name','Cabin','Ticket'
  4. frequency_cols = [_ for _  in categorical_cols if _ not in constant_cols] 
  5.  
  6. categorical_fillna_freq_mapper = DataFrameMapper( 
  7.                                                 [(col, [CategoricalImputer(),LabelBinarizer()]) for col in frequency_cols], 
  8.                                                 input_df=True
  9.                                                 df_out=True 
  10.                                                ) 
  11.  
  12. categorical_fillna_constant_mapper = DataFrameMapper( 
  13.                                                 [(col, [CategoricalImputer(strategy='constant',fill_value='unknown'),LabelBinarizer()]) for col in constant_cols], 
  14.                                                 input_df=True
  15.                                                 df_out=True 
  16.                                                ) 

我们同样进行测试代码:

  1. transformed = categorical_fillna_freq_mapper.fit_transform(raw_df) 
  2. print(transformed.info()) 
  3. transformed = categorical_fillna_constant_mapper.fit_transform(raw_df) 
  4. print(transformed.shape) 

结果如下:

  1. Data columns (total 4 columns): 
  2.  #   Column      Non-Null Count  Dtype 
  3. ---  ------      --------------  ----- 
  4.  0   Sex         891 non-null    int32 
  5.  1   Embarked_C  891 non-null    int32 
  6.  2   Embarked_Q  891 non-null    int32 
  7.  3   Embarked_S  891 non-null    int32 
  8. dtypes: int32(4) 

以及:

  1. (891, 1720) 

featureunion 所有的预处理过程

前面我们已经测试了每一种的预处理的方式(transfomer 或者称为mapper),可以看到结果中只包含处理的部分列对应的结果。

实际中,我们可以用FeatureUnion,直接将所有需要处理的方式(transfomer 或者称为mapper)变成一个pipeline,一目了然。

然后调用fit_transform 对原始数据进行变换,这样我们的预处理看起来更有条理。

  1. feature_union_1 = FeatureUnion([("numeric_fillna_standerdize", numeric_fillna_standardize_mapper), 
  2.                               ("cat_freq", categorical_fillna_freq_mapper), 
  3.                                 ("cat_constant", categorical_fillna_constant_mapper)]) 
  4.  
  5. df_1 = feature_union_1.fit_transform(raw_df) 
  6.  
  7. print(df_1.shape) 
  8. print(raw_df.shape) 

总结

本文介绍了“大佬”级别的数据预处理方式,并且是在实战中进行演示。

通过本文可以学到:

 

来源:今日头条内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯