本文来自《Python机器学习 第三版》第四章《构建良好的训练数据集 – 数据预处理》
本文的笔记对应的代码见https://github.com/LittleWhale0531/PythonMachineLearning_3ed/blob/master/ch04/ch04-note.ipynb
目录
2、scikit-learn转换器(transformer) 和估计器(estimator)的区别
1、序数特征(nominal)和 标称(ordinal)特征
一、处理缺失数据
1、方法简介
本节介绍几种处理缺失值得实用技术,包括从数据集删除这些条目或用其他训练样本和特征填充
- 识别缺失值:dataframe的isnull方法
- 删除有缺失值的训练样本或特征:dataframe的dropna方法
- 填补缺失值:均值插补可以调用scikit-learn的SimpleImputer类,用整个特征列的均值来替换缺失值
2、scikit-learn转换器(transformer) 和估计器(estimator)的区别
scikit-learn包含转换器(transformer) 和估计器(estimator)
- 转换器:(左图)fit方法从训练数据中学习参数,transform方法利用这些参数来转换数据,任何需要转换的数据数组,都必须要有与拟合模型的数据数组具有相同数量的特征
- 估计器:(右图)也有fit方法,还有一个predict方法,可能还有transform方法。在监督学习中,可以通过predict方法对新数据样本进行预测。
二、处理类别数据
序数特征(nominal)和 标称(ordinal)特征
- 序数特征:可以排序的类别特征,比如T恤的尺寸,XL>L>M。映射序数特征需要人工定义序数关系
- 标称特征:不蕴含任何顺序,比如T恤的颜色
处理类别特征:可以在scikit-learn中调用LabelEncoder来实现,fit_transform是分别调用fit和transform的快捷方式 inverse_transform将整数类型分类标签转换回原来的字符串形式
在标称特征用LabelEncoder后,尽管这些特征没有顺序,但是机器学习算法仍会假设特征值之间有序,解决方法是采用独热编码(one-hot encoding),为标称特征的每个唯一值创建一个新的虚拟特征。
三、划分训练数据集和测试数据集
把数据集随机划分成独立的训练数据集和测试数据集,使用scikit-learn的model_selection子模块调用train_test_split函数
四、保持相同的特征缩放
决策树和随机森林不需要进行特征缩放的算法。
特征缩放的方法:
* 标准化:把特征的中心点设在均值为0且标准差为1的位置,特征列呈标准正态分布。
* 归一化:把特征重新缩放到[0,1]之间
from sklearn.preprocessing import MinMaxScaler
mms = MinMaxScaler()
X_train_norm = mms.fit_transform(X_train)
X_test_norm = mms.transform(X_test)
from sklearn.preprocessing import StandardScaler
stdsc = StandardScaler()
X_train_std = stdsc.fit_transform(X_train)
X_test_std = stdsc.transform(X_test)
五、选择有意义的特征
1、过拟合的解决方法
- 收集更多的训练数据
- 通过引入正则化对复杂性进行惩罚
- 选择参数较少的简单模型
- 降低数据的维数
- 方法1:L1可以理解为一种特征选择方法,因为与L2正则化相比,L1正则化更容易产生大部分特征权重为0的稀疏特征向量。但是scikit-learn中的部分算法不支持L1正则
- 方法2:通过特征选择进行降维,主要有2类降维技术:特征选择及特征提取
- 特征选择:从原始特征中选择子集,把初始的d维空间降低到k维特征子空间(k<d)
- 特征提取:从特征集中提取信息以构造新的特征子空间
2、特征选择方法
经典的特征选择方法序列后向选择SBS,它顺序地从完整的特征子集中移除特征,知道新的特征子空间包含需要的特征数量。为了确定每个阶段删除哪个特征,需要定义期待最小化的标准函数J。可以把标准函数计算的标准值定义为:在去除特定特征前后,分类器的性能差异。
另一个特征选择方法是随机森林,计算所有决策树的平均杂质度衰减,来测量特征的重要性,不必考虑数据是否线性可分。scikit-learn中,在RandomForestClassifier拟合后,可以通过访问feature_importances_属性取得特征重要性。
六、代码示例
https://github.com/LittleWhale0531/PythonMachineLearning_3ed/blob/master/ch04/ch04-note.ipynb
这里仅展示“处理缺失数据”的代码,其他代码真的太多了,看github吧!如果打不开链接需要科学上网。
import pandas as pd
from io import StringIO
import sys
csv_data = \
'''A,B,C,D
1.0,2.0,3.0,4.0
5.0,6.0,,8.0
10.0,11.0,12.0,'''
# If you are using Python 2.7, you need
# to convert the string to unicode:
if (sys.version_info < (3, 0)):
csv_data = unicode(csv_data)
df = pd.read_csv(StringIO(csv_data))
df
```
A B C D
0 1.0 2.0 3.0 4.0
1 5.0 6.0 NaN 8.0
2 10.0 11.0 12.0 NaN
```
# 可以调用isnull方法返回包含布尔值的DataFrame
df.isnull().sum()
```
A 0
B 0
C 1
D 1
dtype: int64
```
# 删除缺失的特征
# 删除包含缺失特征的行
df.dropna(axis=0)
```
A B C D
0 1.0 2.0 3.0 4.0
```
# 删除包含缺失特征的列
df.dropna(axis=1)
```
A B
0 1.0 2.0
1 5.0 6.0
2 10.0 11.0
```
# 仅删除全部为NAN的行或列
df.dropna(how='all')
```
A B C D
0 1.0 2.0 3.0 4.0
1 5.0 6.0 NaN 8.0
2 10.0 11.0 12.0 NaN
```
# 删除小于3个实值得行
df.dropna(thresh=4)
```
A B C D
0 1.0 2.0 3.0 4.0
```
# 只删除 'C'列中为NaN的行
df.dropna(subset=['C'])
```
A B C D
0 1.0 2.0 3.0 4.0
2 10.0 11.0 12.0 NaN
```
# 缺失值填补
# 看下原始的数据
df.values
```
array([[ 1., 2., 3., 4.],
[ 5., 6., nan, 8.],
[10., 11., 12., nan]])
```
# 用列的均值填补缺失值
from sklearn.impute import SimpleImputer
import numpy as np
imr = SimpleImputer(missing_values=np.nan, strategy='mean')
imr = imr.fit(df.values)
imputed_data = imr.transform(df.values)
imputed_data
```
array([[ 1. , 2. , 3. , 4. ],
[ 5. , 6. , 7.5, 8. ],
[10. , 11. , 12. , 6. ]])
```
df.fillna(df.mean())
```
A B C D
0 1.0 2.0 3.0 4.0
1 5.0 6.0 7.5 8.0
2 10.0 11.0 12.0 6.0
```