机器学习:07. sklearn中的数据预处理

1. 数据无量纲化

将不同规格的数据转换到同一规格,或不同分布的数据转换到某个特定分布
的需求,这种需求统称为将数据“无量纲化”。线性的无量纲化包括中心化(Zero-centered或者Meansubtraction)处理和缩放处理(Scale)。

中心化的本质是让所有记录减去一个固定值,即让数据样本数据平移到某个位置。
缩放的本质是通过除以一个固定值,将数据固定在某个范围之中。

1.1 preprocessing.MinMaxScaler 数据归一化

当数据(x)按照最小值中心化后,再按极差(最大值 - 最小值)缩放,数据移动了最小值个单位,并且会被收敛到[0,1]之间,这个过程就叫做数据归一化(Normalization)。归一化后的数据服从正态分布。MinMaxScaler有一个重要参数,feature_range,控制我们希望把数据压缩到的范围,默认是[0,1]。

# 数据归一化
from sklearn.preprocessing import MinMaxScaler
data = [[-1, 2], [-0.5, 6], [0, 10], [1, 18]]
#如果换成表是什么样子?
import pandas as pd
pd.DataFrame(data)

#实现归一化
scaler = MinMaxScaler() #实例化
scaler = scaler.fit(data) #fit,在这里本质是生成min(x)和max(x)
result = scaler.transform(data) #通过接口导出结果
result

result_ = scaler.fit_transform(data) #训练和导出结果一步达成
scaler.inverse_transform(result) #将归一化后的结果逆转

#使用MinMaxScaler的参数feature_range实现将数据归一化到[0,1]以外的范围中
data = [[-1, 2], [-0.5, 6], [0, 10], [1, 18]]
scaler = MinMaxScaler(feature_range=[5,10]) #依然实例化
result = scaler.fit_transform(data) #fit_transform一步导出结果
result
数据归一化到了5-10之间

1.2 preprocessing.StandardScaler 数据标准化

当数据(x)按均值(μ)中心化后,再按标准差(σ)缩放,数据就会服从为均值为0,方差为1的正态分布(即标准正态分布),而这个过程就叫做数据标准化(Standardization,又称Z-score normalization)。

# 数据标准化
from sklearn.preprocessing import StandardScaler
data = [[-1, 2], [-0.5, 6], [0, 10], [1, 18]]

scaler = StandardScaler() #实例化
scaler.fit(data) #fit,本质是生成均值和方差
scaler.mean_ #查看均值的属性mean_
scaler.var_ #查看方差的属性var_

x_std = scaler.transform(data) #通过接口导出结果
x_std.mean() #导出的结果是一个数组,用mean()查看均值 0
x_std.std() #用std()查看方差 1

scaler.fit_transform(data) #使用fit_transform(data)一步达成结果
scaler.inverse_transform(x_std) #使用inverse_transform逆转标准化
x_std

对于StandardScaler和MinMaxScaler来说,空值NaN会被当做是缺失值,在fit的时候忽略,在transform的时候保持缺失NaN的状态显示。
大多数机器学习算法中,会选择StandardScaler来进行特征缩放,因为MinMaxScaler对异常值非常敏感。在PCA,聚类,逻辑回归,支持向量机,神经网络这些算法中,StandardScaler往往是最好的选择。

2 缺失值

import pandas as pd
data = pd.read_csv(r"C:\Users\18700\Desktop\03数据预处理和特征工程\Narrativedata.csv",index_col=0) #index_col是将第0列作为索引
data.head()

这个数据有三个特征,一个数值型,两个字符型,标签也是字符型

2.1 impute.SimpleImputer

专门用来填补缺失值的类,sklearn.impute.SimpleImputer (missing_values=nan, strategy=’mean’, fill_value=None, verbose=0, copy=True),有四个重要参数:

参数解释

填补年龄

#serise,这是pandas中的一种格式(索引+值),.values就是将其中的值提取出来,reshape(-1,1)将数据升维
Age = data.loc[:,"Age"].values.reshape(-1,1) #sklearn当中特征矩阵必须是二维
Age[:20]

from sklearn.impute import SimpleImputer
imp_mean = SimpleImputer() #实例化,默认均值填补
imp_median = SimpleImputer(strategy="median") #用中位数填补
imp_0 = SimpleImputer(strategy="constant",fill_value=0) #用0填补

imp_mean = imp_mean.fit_transform(Age) #fit_transform一步完成调取结果
imp_median = imp_median.fit_transform(Age)
imp_0 = imp_0.fit_transform(Age)

imp_mean[:20]
imp_median[:20]
imp_0[:20]

#在这里我们使用中位数填补Age
data.loc[:,"Age"] = imp_median
data.info()

使用众数填补Embarked

Embarked = data.loc[:,"Embarked"].values.reshape(-1,1)

imp_mode = SimpleImputer(strategy = "most_frequent") #实例化,使用众数填补,most_frequent可以用来填写字符型数据
data.loc[:,"Embarked"] = imp_mode.fit_transform(Embarked)
data.info()

用pandas和numpy进行数据填补 (均值的填补更为简单)

import pandas as pd
data_ = pd.read_csv(r"C:\Users\18700\Desktop\03数据预处理和特征工程\Narrativedata.csv",index_col=0)
data_.head()
data_.loc[:,"Age"] = data_.loc[:,"Age"].fillna(data_.loc[:,"Age"].median())
#.fillna 在DataFrame里面直接进行填补
data_.dropna(axis=0,inplace=True)
#.dropna(axis=0)删除所有有缺失值的行,.dropna(axis=1)删除所有有缺失值的列
#参数inplace,为True表示在原数据集上进行修改,为False表示生成一个复制对象,不修改原数据,默认False
data_.info()

3 处理分类型特征:编码与哑变量

将文字型数据转换为数值型。

3.1 preprocessing.LabelEncoder: 标签专用,能够将分类转换为分类数值

#将标签转换为分类数值
from sklearn.preprocessing import LabelEncoder
y = data.iloc[:,-1] #要输入的是标签,不是特征矩阵,所以允许一维 iloc就是取列,取最后一列

le = LabelEncoder() #实例化
le = le.fit(y) #导入数据
label = le.transform(y) #transform接口调取结果

le.classes_ #属性.classes_查看标签中究竟有多少类别
label #查看获取的结果label

le.fit_transform(y) #也可以直接fit_transform一步到位
le.inverse_transform(label) #使用inverse_transform可以逆转
data.iloc[:,-1] = label #让标签等于我们运行出来的结果
data.head()
data

简化代码

from sklearn.preprocessing import LabelEncoder
data.iloc[:,-1] = LabelEncoder().fit_transform(data.iloc[:,-1]) #实例化,训练和导出放在一起

3.2 preprocessing.OrdinalEncoder: 特征专用,能够将分类特征转换为分类数值

#特征专用
from sklearn.preprocessing import OrdinalEncoder
data_ = data.copy()
data_.head()

#接口categories_对应LabelEncoder的接口classes_,一模一样的功能
OrdinalEncoder().fit(data_.iloc[:,1:-1]).categories_  #data_.iloc[:,1:-1]是取第一列到最后一列前,最后一列不取

data_.iloc[:,1:-1] = OrdinalEncoder().fit_transform(data_.iloc[:,1:-1])
data_.head()
OrdinalEncoder().fit(data_.iloc[:,1:-1]).categories_  #再次查看是否变成数据
data_.loc[:,'Sex'] #取出sex这一列进行查看
data_.iloc[:,1] #也是取出了sex这一列进行查看。只是loc是直接根据列名进行取,iloc是取出所需要列的所有行。
data_.iloc[1,:] #这就是取出第一行的所有数据

3.3 preprocessing.OneHotEncoder:独热编码,创建哑变量

上面两种方式将分类转换成数字的时候,忽略了数字中自带的数学性质,所
以给算法传达了一些不准确的信息,而这会影响我们的建模。
类别OrdinalEncoder可以用来处理有序变量,比如学历;但对于名义变量,我们只有使用哑变量的方式来处理,才能够尽量向算法传达最准确的信息。

哑变量概念图

即三个取值是没有可计算性质的,是“有你就没有我”的不等概念。在我们的
数据中,性别和舱门,都是这样的名义变量。因此我们需要使用独热编码,将两个特征都转换为哑变量。

创建哑变量

data.head()
from sklearn.preprocessing import OneHotEncoder #独热编码
X = data.iloc[:,1:-1] #提取特征性别和年龄
enc = OneHotEncoder(categories='auto').fit(X) #categories='auto'是自动遍历特征中有几类
result = enc.transform(X).toarray() #toarray转化为数组,不转化的话是由0,1组成的sparse matrix
result
性别两个类别,年龄3个类别
#简化的代码
OneHotEncoder(categories='auto').fit_transform(X).toarray()
#依然可以还原
pd.DataFrame(enc.inverse_transform(result))

enc.get_feature_names() #返回每个哑变量指的是哪个特征中的哪个类别
# array(['x0_female', 'x0_male', 'x1_C', 'x1_Q', 'x1_S'], dtype=object)

#axis=1,表示按照列进行合并,也就是将量表左右相连,如果是axis=0,按照行进行合并
newdata = pd.concat([data,pd.DataFrame(result)],axis=1)
newdata.head()
newdata.drop(["Sex","Embarked"],axis=1,inplace=True) #将这两列进行删除,aixs=1就是对列进行操作
newdata.columns =["Age","Survived","Female","Male","Embarked_C","Embarked_Q","Embarked_S"]
newdata.head()
newdata

4 处理连续型特征:二值化与分段

4.1 sklearn.preprocessing.Binarizer 二值化

根据阈值将数据二值化(将特征值设置为0或1),用于处理连续型变量。大于阈值的值映射为1,而小于或等于阈值的值映射为0。二值化是对文本计数数据的常见操作,分析人员可以决定仅考虑某种现象的存在与否.

将年龄二值化

data_2 = data.copy()

from sklearn.preprocessing import Binarizer #二值化
X = data_2.iloc[:,0].values.reshape(-1,1) #这个类为特征专用,所以不能使用一维数组
transformer = Binarizer(threshold=30).fit_transform(X) #30岁作为区分,小于等于30为0,大于30为1
data_2.iloc[:,0] = transformer

4.2 preprocessing.KBinsDiscretizer 分箱

将连续型变量划分为分类变量的类,能够将连续型变量排序后按顺序分箱后编码。包含三个参数:


参数介绍

对年龄进行分箱操作

from sklearn.preprocessing import KBinsDiscretizer
X = data.iloc[:,0].values.reshape(-1,1)
est = KBinsDiscretizer(n_bins=3, encode='ordinal', strategy='uniform')
est.fit_transform(X)
#查看转换后分的箱:变成了一列中的三箱
set(est.fit_transform(X).ravel()) #降维ravel,set是将降维后的数据放入集合中,可用来查看到底有几个箱子

est = KBinsDiscretizer(n_bins=3, encode='onehot', strategy='uniform')
#查看转换后分的箱:变成了哑变量
est.fit_transform(X).toarray() #因为分了三箱,所以是三列的稀疏矩阵
#shift+tab查看函数怎么使用
结果展示

参考菜菜的sklearn

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 224,983评论 6 522
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 96,354评论 3 403
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 172,216评论 0 367
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 61,061评论 1 300
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 70,073评论 6 400
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 53,541评论 1 314
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 41,906评论 3 428
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 40,881评论 0 279
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 47,428评论 1 324
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 39,460评论 3 346
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 41,578评论 1 355
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 37,176评论 5 351
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,913评论 3 339
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 33,348评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 34,490评论 1 277
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 50,142评论 3 381
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 46,650评论 2 366

推荐阅读更多精彩内容