目录
- 标准化
- 归一化
- 正则化
- 二值化
- 标签二值化
- 多标签二值化
- 哑编码
- 缺省值填充
掉包方法:
处理方法 | sklearn掉包 | 备注 |
---|---|---|
标准化 | from sklearn.preprocessing import StandardScaler | |
归一化 | from sklearn.preprocessing import MinMaxScaler | |
正则化 | from sklearn.preprocessing import Normalizer | |
二值化 | from sklearn.preprocessing import Binarizer | |
标签二值化 | from sklearn.preprocessing import LabelBinarizer | |
哑编码 | from sklearn.preprocessing import OneHotEncoder | 只能处理数据类型 |
哑编码2 | from sklearn.preprocessing import LabelEncoder | 处理带字符的哑编码,需配合OneHot使用 |
缺省值填充 | from sklearn.preprocessing import Imputer |
标准化、归一化是对X的特征进行处理,标准化、归一化又叫做无量纲化, 一般用于将多个特征属性之间的取值范围转换为同一个取值范围,可以加快模型的求解速度,也可以让模型效果更加稳定、效果更好。正则化是对每条样本的特征进行缩放,按照L1范数、L2范数、LP范数来进行
1、标准化
x = (x-u)/sigma
标准化公式: X=(x−u)σX =\frac{(x-u)}{\sigma}X=σ(x−u)
标准化后均值为0,方差为1
#1、设置数据
import numpy as np
import pandas as pd
X = [
[1, 2, 3, 2],
[7, 8, 9, 2.01],
[4, 8, 2, 2.01],
[9, 5, 2, 1.99],
[7, 5, 3, 1.99],
[1, 4, 9, 2]
]
x_test = [
[12,11,13,12],
[5,6,7,9]
]
#2、查看原始数据主要指标
df=pd.DataFrame(X)
df.describe().T
#3、 标准化操作,转换前查看
from sklearn.preprocessing import StandardScaler
ss = StandardScaler()
ss.fit(X)
print(ss.mean_)# 计算每个特征属性的均值
print(ss.n_samples_seen_) #输出有多少个样本进行训练
print(ss.scale_)# 输出每个特征属性的标准差(σ),注:方差(σ²)等于标准差的平方
#4、标准化转换并查看
Std_train=ss.transform(X)
Std_test=ss.transform(x_test)
# 相当于对训练集做一个数据转换
print('标准化后的训练集数据:\n',Std_train)
print('标准化后训练集数据主要指标:\n',pd.DataFrame(Std_train).describe().T)
2、归一化
缩、放特征
x = (x-min_x)/(max_x-min_x)
0-1的范围内
#1、设置数据
import numpy as np
from sklearn.preprocessing import MinMaxScaler
X = np.array([
[1, -1, 2, 3],
[2, 0, 0, 3],
[0, 1, -10, 3]
], dtype=np.float64)
#2、归一化操作,转换前查看数据重要指标
scaler = MinMaxScaler(feature_range=(0,1))#feature_range属性为最后映射到的范围,这里最后是把所有数据映射到0~1之间
scaler.fit(X)
# 原始特征属性的最大值
print(scaler.data_max_)
# 原始特征属性的最小值
print(scaler.data_min_)
# 原始特征属性的取值范围大小(最大值-最小值)
print(scaler.data_range_)
#3、归一化后的数据转换
MinMax_X=scaler.transform(X)
print(MinMax_X)
3、正则化
正则化则是将样本的某个范数缩放到单位1(针对的是单个样本的)。
L1范式公式: L1=∣x1∣+∣x2∣+∣x3∣+…∣xi∣L1 = |x1|+|x2|+|x3|+…|xi|L1=∣x1∣+∣x2∣+∣x3∣+…∣xi∣
L2范式公式: L2=(x1)2+(x2)2+(x3)2+…(xi)2L2 = \sqrt {(x1)^2+(x2)^2+(x3)^2+…(xi)^2}L2=(x1)2+(x2)2+(x3)2+…(xi)2
LP范式公式: LP=(x1)p+(x2)p+(x3)p+…(xi)pPLP = \sqrt[P] {(x1)^p+(x2)^p+(x3)^p+…(xi)^p}LP=P(x1)p+(x2)p+(x3)p+…(xi)p
#正则化
#1、设置数据
import numpy as np
from sklearn.preprocessing import Normalizer
X = np.array([
[1, -1, 2],
[2, 0, 0],
[0, 2, -10]
], dtype=np.float64)
#2、定义正则化
normalizer1 = Normalizer(norm='l1') #norm属性可填正则:l1范式、l2范式、max范式
normalizer2 = Normalizer(norm='l2')
normalizer3 = Normalizer(norm='max')
normalizer1.fit(X)
normalizer2.fit(X)
normalizer3.fit(X)
#3、正则化后转换数据
L1_X=normalizer1.transform(X)
L2_X=normalizer2.transform(X)
Max_X=normalizer3.transform(X)
print('L1范数:\n',L1_X) #l1正则化后,将Xi=Xi/l1 l1=|X1|+|X2|+|X3|……|Xn| ,l1正则化之后的样本l1=1
print("**********************************")
print('L2范数:\n',L2_X)#l2正则化后,将Xi=Xi/l2 l1=(|X1|²+|X2|²+|X3|²……|Xn|²)½
print("**********************************")
print('Max范数:\n',Max_X)
L1范数:
[[ 0.25 -0.25 0.5 ]
[ 1. 0. 0. ]
[ 0. 0.16666667 -0.83333333]]
L2范数:
[[ 0.40824829 -0.40824829 0.81649658]
[ 1. 0. 0. ]
[ 0. 0.19611614 -0.98058068]]
Max范数:
[[ 0.5 -0.5 1. ]
[ 1. 0. 0. ]
[ 0. 1. -5. ]]
4、二值化
掉包方法:
from sklearn.preprocessing import Binarizer
对特征实现0或1的二值处理
1、一般情况下,对于每个特征需要使用不同的阈值进行二值化操作;
2、一般情况下,对数据进行划分的时候,不是进行二值化,而是进行多值化(分区化/分桶化);即:将一个连续的数据,按照不同的取值范围,分为不同的级别;比如:在某一个模型中,存在人的收入情况,单位为元,根据业务来判断的话,可能会得到影响因变量的因素其实是区间后的收入情况,那么这个时候就可以基于业务的特征,将收入划分为收入等级,比如:1w -> 0, 1w~2w -> 1, 2w~3w -> 2, 3w+ -> 3(至于这里到底做不做哑编码操作,具体的看对于区间化之后的数据的理解。如果认为区间化之后的特征数据是具有等级意义的,那么就可以考虑不做哑编码。如果认为区间化之后的数据是一个类别数据,那么一般需要做哑编码操作)
#二值化代码
#1、加载数据
import numpy as np
from sklearn.preprocessing import Binarizer
arr = np.array([
[1.5, 2.3, 1.9],
[0.5, 0.5, 1.6],
[1.1, 2, 0.2]
])
# 2、定义二值化学习器;针对所有的特征属性选择同一个阈值
binarizer = Binarizer(threshold=1.5) #定义二值化学习器,threshold属性为阈值,大于该阈值的为1,小于等于该阈值的为0
binarizer.fit(arr)#学习训练
Bin_arr=binarizer.transform(arr)#数据二值化转换
print('原始的arr:\n',arr)
print('threshold=1.5:\n',Bin_arr)
#2.1、对单独的列设置阈值进行过滤
binarizer = Binarizer(threshold=[1.0,2.0,1.0])
binarizer.fit(arr)
Bin_arr2=binarizer.transform(arr)
print('threshold=[1.0,2.0,1.0]:\n',Bin_arr2)
#2.2 、使用特征的均值来进行二值化处理
print("均值:{}".format(np.mean(arr, axis=0)))
binarizer = Binarizer(threshold=np.mean(arr, axis=0))
binarizer.fit(arr)
Bin_arr3=binarizer.transform(arr)
print('使用特征的均值来进行二值化处理:\n',Bin_arr3)
# 2.3、基于NumPy API进行转换
arr2 = arr.copy()
print('原始arr2:\n',arr2)
condition1 = arr <= [1.0,2.0,1.0]
print('arr小于等于[1.0,2.0,1.0]的结果:\n',condition1)
condition2 = arr > [1.0,2.0,1.0]
print('arr大于[1.0,2.0,1.0]的结果:\n',condition2)
arr2[condition1] = 0#第一步True值填充0,False不能处理
arr2[condition2] = 1#第二步True值填充1,False不能处理
print('过滤后的arr2:\n',arr2)#合起来的结果就是0、1二值化了
原始的arr:
[[1.5 2.3 1.9]
[0.5 0.5 1.6]
[1.1 2. 0.2]]
threshold=1.5:
[[0. 1. 1.]
[0. 0. 1.]
[0. 1. 0.]]
threshold=[1.0,2.0,1.0]:
[[1. 1. 1.]
[0. 0. 1.]
[1. 0. 0.]]
均值:[1.03333333 1.6 1.23333333]
使用特征的均值来进行二值化处理:
[[1. 1. 1.]
[0. 0. 1.]
[1. 1. 0.]]
原始arr2:
[[1.5 2.3 1.9]
[0.5 0.5 1.6]
[1.1 2. 0.2]]
arr小于等于[1.0,2.0,1.0]的结果:
[[False False False]
[ True True False]
[False True True]]
arr大于[1.0,2.0,1.0]的结果:
[[ True True True]
[False False True]
[ True False False]]
过滤后的arr2:
[[1. 1. 1.]
[0. 0. 1.]
[1. 0. 0.]]
5、标签二值化
掉包方法:
from sklearn.preprocessing import LabelBinarizer
参数:
neg_label:必须对负标签进行编码的值
pos_label:必须编码正标签的值。
sparse_output:如果希望转换的返回数组采用稀疏格式,则为True。
sparse_output=True neg_label=0
#标签二值化——两个特征
#1、定义数据
from sklearn.preprocessing import LabelBinarizer
labelList=['男', '女', '女', '男']
# 2、将标签矩阵二值化
lb = LabelBinarizer()
dummY=lb.fit_transform(labelList)
print('两个特征(男、女)二值化:',dummY.T)
#3、 逆过程
yesORno=lb.inverse_transform(np.array([[0],[1]]))#注意逆过程学习器里面必须传入np.array
print('[[0],[1]]逆过程:',yesORno)
输出:
两个特征(男、女)二值化: [[1 0 0 1]]
[[0],[1]]逆过程: [‘女’ ‘男’]
#标签二值化——多个特征
#1、加载数据
from sklearn import preprocessing
# 标签矩阵
labelList=['yes', 'no', 'no', 'yes','unknow','ok']
print('原始特征列表labelList:\n',labelList)
# 2、将标签矩阵二值化
lb = preprocessing.LabelBinarizer()
dummY=lb.fit_transform(labelList)
print('输出四个特征二值化结果:\n',dummY)
print('输出四个特征:\n',lb.classes_)
#3、 逆过程
yesORno=lb.inverse_transform(dummY)
print('输出逆结果:\n',yesORno)
原始特征列表labelList:
[‘yes’, ‘no’, ‘no’, ‘yes’, ‘unknow’, ‘ok’]
输出四个特征二值化结果:
[[0 0 0 1]
[1 0 0 0]
[1 0 0 0]
[0 0 0 1]
[0 0 1 0]
[0 1 0 0]]
输出四个特征:
[‘no’ ‘ok’ ‘unknow’ ‘yes’]
输出逆结果:
[‘yes’ ‘no’ ‘no’ ‘yes’ ‘unknow’ ‘ok’]
6、多标签二值化
掉包方法:
sklearn.preprocessing.MultiLabelBinarizer(classes=None, sparse_output=False)
参数:
classes_属性:若设置classes参数时,其值等于classes参数值,否则从训练集统计标签值
①classes默认值,classes_属性值从训练集中统计标签值
②设置classes参数,classes_属性值等于classes参数值
#多标签二值化
#1、定义标签数据
from sklearn.preprocessing import MultiLabelBinarizer
label = [(1,2),(2,3),(3,5),(6,)]
print('原始数据:',label)
#2、定义学习器,不设定参数
mlb = MultiLabelBinarizer()
mlb_label=mlb.fit_transform(label)
print('不设定特征类别,转换后的结果:\n',mlb_label)
print('输出5个特征类别:',mlb.classes_)
#3、定义学习器,设定特征
mlb01 = MultiLabelBinarizer(classes=[7,1,2,3,4,5,6])
mlb_label2=mlb01.fit_transform(label)
print('设定了7个特征,转换后的结果:\n',mlb_label2)
print('输出7个特征类别:',mlb01.classes_)
print('转换(7,4),(2,3)样本结果:\n',mlb01.transform([(7,4),(2,3)]))
原始数据: [(1, 2), (2, 3), (3, 5), (6,)]
不设定特征类别,转换后的结果:
[[1 1 0 0 0]
[0 1 1 0 0]
[0 0 1 1 0]
[0 0 0 0 1]]
输出5个特征类别: [1 2 3 5 6]
设定了7个特征,转换后的结果:
[[0 1 1 0 0 0 0]
[0 0 1 1 0 0 0]
[0 0 0 1 0 1 0]
[0 0 0 0 0 0 1]]
输出7个特征类别: [7 1 2 3 4 5 6]
转换(7,4),(2,3)样本结果:
[[1 0 0 0 1 0 0]
[0 0 1 1 0 0 0]]
多标签输出结果解析:
1 2 3 5 6
[[1 1 0 0 0] #(1, 2)
[0 1 1 0 0] #(2, 3)
[0 0 1 1 0] #(3, 5)
[0 0 0 0 1]] #(6,)
7、哑编码
常用于:回归算法(线性回归、Ridge、Lasso、Logistic回归等)、SVM(svc/svr)、KNN、KMeans等
一般不需要哑编码的算法:决策树、贝叶斯、HMM等
7.1哑编码——只对数据类型的处理
注意:OneHotEncoder要求数据类别必须是数值的
#哑编码
# OneHotEncoder要求数据类别必须是数值的
# categorical_features:给定对哪些列的数据进行哑编码操作,默认是对所有列数据做
# n_values:明确给定各个特征属性的类别数目,其实是最大值+1
1、加载数据
from sklearn.preprocessing import OneHotEncoder
import numpy as np
import pandas as pd
a=np.array([
[0, 0, 3],
[2, 1, 0],
[0, 2, 1],
[1, 0, 2],
[1, 1, 1]])
#2、定义学习器
enc = OneHotEncoder()
enc.fit(a)
print('原始数据:\n',a)
#3、数据转换输出
OH_a=enc.transform(a).toarray()
print('转换后的数据:\n',OH_a)
print("每列特征数:",enc.n_values_)
print("每个定性特征的有效值范围:\n",enc.feature_indices_)
print('备注上面特征范围,结果指的是,前0~3表示第一个特征,3~6表示第二个特征,6~10表示第三个特征')
原始数据:
[[0 0 3]
[2 1 0]
[0 2 1]
[1 0 2]
[1 1 1]]
转换后的数据:
[[1. 0. 0. 1. 0. 0. 0. 0. 0. 1.]
[0. 0. 1. 0. 1. 0. 1. 0. 0. 0.]
[1. 0. 0. 0. 0. 1. 0. 1. 0. 0.]
[0. 1. 0. 1. 0. 0. 0. 0. 1. 0.]
[0. 1. 0. 0. 1. 0. 0. 1. 0. 0.]]
每列特征数: [3 3 4]
每个定性特征的有效值范围:
[ 0 3 6 10]
备注上面特征范围,结果指的是,前03表示第一个特征,36表示第二个特征,6~10表示第三个特征
7.2哑编码——只对类别数据是字符串类型处理
两种方法
方法一:
使用pandas命令:get_dummies()方法实现,如下代码
注意:该命令只转换字符串类型的特征,对于数字类型的特征不转换
# 如果类别数据是字符串类型的,可以使用pandas的API进行哑编码转换
#该命令只转换字符串类型的特征,对于数字类型的特征不转换
a = DataFrame([
['a', 1, 2],
['b', 1, 1],
['a', 2, 1],
['c', 1, 2],
['d', 1, 2]
], columns=['c1', 'c2', 'c3'])
print('原始数据:\n',a)
# 将DataFrame中的字符串列转换为哑编码的形式
a = pd.get_dummies(a)
print('pandas命令实现字符串类型的转换:\n',a)
输出->
原始数据:
c1 c2 c3
0 a 1 2
1 b 1 1
2 a 2 1
3 c 1 2
4 d 1 2
pandas命令实现字符串类型的转换:
c2 c3 c1_a c1_b c1_c c1_d
0 1 2 1 0 0 0
1 1 1 0 1 0 0
2 2 1 1 0 0 0
3 1 2 0 0 1 0
4 1 2 0 0 0 1
方法二:
使用sklearn,掉包命令:
from sklearn.preprocessing import LabelEncoder
注意:该命令只能对单列特征进行转换
# 如果类别数据是字符串类型的,首先使用sklearn中的API将数据转换为从0开始的值
#哑编码——带字符类型数据转换
#1.设置数据
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import OneHotEncoder
a = DataFrame([
['aa', 1, 2],
['b', 1, 1],
['a', 2, 1],
['c', 1, 2],
['c', 1, 2]
], columns=['c1', 'c2', 'c3'])
print('原始数据:\n',a)
# 2、定义学习器,学习转换数据
le = LabelEncoder()
a['c4'] = le.fit_transform(a['c1'])#把C1列的转换的结果给了C4,这种结果后期需进行One-Hot
print('添加C4列转换后的数据:\n',a)
print('[0,1,2,3]逆结果:\n',le.inverse_transform([0,1,2,3]))#逆结果
data = a.drop('c1', axis=1)#删除C1列特征
print('删除C1列特征后的结果:\n',data)
# 3.1、进行哑编码操作,只对第C3列进行哑编码操作转换为0/1
enc = OneHotEncoder(categorical_features=[2])
enc.fit(data)
print('只对第C3列进行哑编码操作的结果:\n',enc.transform(data).toarray())
# 3、进行哑编码操作,对所有进行哑编码操作的转换为0/1
enc = OneHotEncoder()
enc.fit(data)
print('对所有进行哑编码操作的结果:\n',enc.transform(data).toarray())
原始数据:
c1 c2 c3
0 aa 1 2
1 b 1 1
2 a 2 1
3 c 1 2
4 c 1 2
添加C4列转换后的数据:
c1 c2 c3 c4
0 aa 1 2 1
1 b 1 1 2
2 a 2 1 0
3 c 1 2 3
4 c 1 2 3
[0,1,2,3]逆结果:
[‘a’ ‘aa’ ‘b’ ‘c’]
删除C1列特征后的最终结果:
c2 c3 c4
0 1 2 1
1 1 1 2
2 2 1 0
3 1 2 3
4 1 2 3
只对第C3列进行哑编码操作的结果:
[[0. 1. 0. 0. 1. 2.]
[0. 0. 1. 0. 1. 1.]
[1. 0. 0. 0. 2. 1.]
[0. 0. 0. 1. 1. 2.]
[0. 0. 0. 1. 1. 2.]]
对所有进行哑编码操作的结果:
[[1. 0. 0. 1. 0. 1. 0. 0.]
[1. 0. 1. 0. 0. 0. 1. 0.]
[0. 1. 1. 0. 1. 0. 0. 0.]
[1. 0. 0. 1. 0. 0. 0. 1.]
[1. 0. 0. 1. 0. 0. 0. 1.]]
8、缺省值填充
#缺省值填充
#1、读取数据
import numpy as np
from sklearn.preprocessing import Imputer
X = [
[2, 2, 4, 1],
[np.nan, 3, 4, 4],
[1, 1, 1, np.nan],
[2, 2, np.nan, 3]
]
X2 = [
[2, 6, np.nan, 1],
[np.nan, 5, np.nan, 1],
[4, 1, np.nan, 5],
[np.nan, np.nan, np.nan, 1]
]
#2、按照列进行填充计算
# 按照列进行填充值的计算(计算每个特征属性的填充值)(一般使用填充方式)
imp1 = Imputer(missing_values='NaN', strategy='mean', axis=0)
# 如果以列进行数据填充的时候,是计算每个特征属性的填充值分别是什么
imp1.fit(X)
print('X原始数据:\n',pd.DataFrame(X))
print('X2原始数据:\n',pd.DataFrame(X2))
# 当axis=0的时候,获取每个特征的计算出来的填充值
print('获取训练X的填充均值:\n',imp1.statistics_)
print('用X训练的列数据均值([1.666,2.0,3.0,2.666]),进行填充X2:\n',imp1.transform(X2))
#3、按照行进行填充计算
# 按照行计算填充值(计算每个样本的填充值) -- 一般不用
#(如果按照行进行填充的话,那么是不需要进行模型fit的,直接使用X的现有的行信息进行填充的)
imp2 = Imputer(missing_values='NaN', strategy='mean', axis=1)
print(imp2)
# imp2.fit(X) # 因为按照行数据进行填充转换的时候,是不需要计算到底填充值是什么的
print('按照X2的行平均值([3.0,3.0,3.333,1])行进行填充X2:\n',imp2.transform(X2))
#4、使用不同的填充方法(平均值、中值、众数)进行填充
imp1 = Imputer(missing_values='NaN', strategy='mean', axis=0)
imp2 = Imputer(missing_values='NaN', strategy='median', axis=0)
imp3 = Imputer(missing_values='NaN', strategy='most_frequent', axis=0)
imp1.fit(X)
imp2.fit(X)
imp3.fit(X)
print('X原始数据:\n',pd.DataFrame(X))
print('使用X的平均值特征列表填充:',imp1.statistics_)
print('使用X的中值特征列表填充:',imp2.statistics_)
print('使用X的众数特征列表填充:',imp3.statistics_)
X原始数据:
0 1 2 3
0 2.0 2 4.0 1.0
1 NaN 3 4.0 4.0
2 1.0 1 1.0 NaN
3 2.0 2 NaN 3.0
X2原始数据:
0 1 2 3
0 2.0 6.0 NaN 1
1 NaN 5.0 NaN 1
2 4.0 1.0 NaN 5
3 NaN NaN NaN 1
获取训练X的填充均值:
[1.66666667 2. 3. 2.66666667]
用X训练的列数据均值([1.666,2.0,3.0,2.666]),进行填充X2:
[[2. 6. 3. 1. ]
[1.66666667 5. 3. 1. ]
[4. 1. 3. 5. ]
[1.66666667 2. 3. 1. ]]
Imputer(axis=1, copy=True, missing_values=‘NaN’, strategy=‘mean’, verbose=0)
按照X2的行平均值([3.0,3.0,3.333,1])行进行填充X2:
[[2. 6. 3. 1. ]
[3. 5. 3. 1. ]
[4. 1. 3.33333333 5. ]
[1. 1. 1. 1. ]]
X原始数据:
0 1 2 3
0 2.0 2 4.0 1.0
1 NaN 3 4.0 4.0
2 1.0 1 1.0 NaN
3 2.0 2 NaN 3.0
使用X的平均值特征列表填充: [1.66666667 2. 3. 2.66666667]
使用X的中值特征列表填充: [2. 2. 4. 3.]
使用X的众数特征列表填充: [2. 2. 4. 1.]