机器学习(8)---数据预处理

文章目录

  • 一、数据预处理
    • [1.1 数据无量纲化](#1.1 数据无量纲化)
    • [1.2 数据归一化](#1.2 数据归一化)
    • [1.3 数据标准化](#1.3 数据标准化)
    • [1.4 处理选择](#1.4 处理选择)
  • 二、缺失值
    • [2.1 填补的类和参数](#2.1 填补的类和参数)
    • [2.2 用Pandas和Numpy进行填补](#2.2 用Pandas和Numpy进行填补)
  • 三、处理分类型特征:编码与哑变量
    • [3.1 编码](#3.1 编码)
    • [3.2 哑变量(独热编码)](#3.2 哑变量(独热编码))

一、数据预处理

1.1 数据无量纲化

 1. 在机器学习算法实践中,我们往往有着将不同规格的数据转换到同一规格,或不同分布的数据转换到某个特定分布的需求,这种需求统称为将数据"无量纲化"。

  • 譬如梯度和矩阵为核心的算法中,譬如逻辑回归,支持向量机,神经网络,无量纲化可以加快求解速度.
  • 而在距离类模型,譬如K近邻,K-Means聚类中,无量纲化可以帮我们提升模型精度,避免某一个取值范围特别大的特征对距离计算造成影响。

 2. 数据的无量纲化可以是线性的,也可以是非线性的。线性的无量纲化包括中心化处理(Zero-centered或者Mean-subtraction)和缩放处理(Scale)。

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

1.2 数据归一化

 1. 当数据(x)按照最小值中心化后,再按极差(最大值 - 最小值)缩放,数据移动了最小值个单位,并且会被收敛到0,1之间,而这个过程,就叫做数据归一化(Normalization,又称Min-Max Scaling)。公式如下:

注意:Normalization是归一化,不是正则化,真正的正则化是regularization,不是数据预处理的一种手段。归一化之后的数据服从正态分布。

 2. 在sklearn当中,我们使用preprocessing.MinMaxScaler来实现这个功能。MinMaxScaler有一个重要参数feature_range,可以控制我们希望把数据压缩到的范围,默认是0,1

python 复制代码
from sklearn.preprocessing import MinMaxScaler
data = [[-1, 2], [-0.5, 6], [0, 10], [1, 18]]
scaler = MinMaxScaler()

scaler = MinMaxScaler() #实例化
scaler = scaler.fit(data) #fit,在这里本质是生成min(x)和max(x)
result = scaler.transform(data) #通过接口导出结果
print(result)
#也可以一步到位:result_ = scaler.fit_transform(data) #训练和导出结果一步达成
#scaler.inverse_transform(result) #将归一化后的结果逆转

#feature_range=[5,10]
data = [[-1, 2], [-0.5, 6], [0, 10], [1, 18]]
scaler = MinMaxScaler(feature_range=[5,10]) #依然实例化
result = scaler.fit_transform(data) #fit_transform一步导出结果
print(result)

 3. 使用numpy来实现归一化:

python 复制代码
import numpy as np
X = np.array([[-1, 2], [-0.5, 6], [0, 10], [1, 18]])

#归一化
X_nor = (X - X.min(axis=0)) / (X.max(axis=0) - X.min(axis=0))
print(X_nor)

#逆转归一化
X_returned = X_nor * (X.max(axis=0) - X.min(axis=0)) + X.min(axis=0)
print(X_returned)

1.3 数据标准化

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

python 复制代码
from sklearn.preprocessing import StandardScaler
data = [[-1, 2], [-0.5, 6], [0, 10], [1, 18]]
scaler = StandardScaler() #实例化
scaler.fit(data) #fit,本质是生成均值和方差
x_std = scaler.transform(data) #通过接口导出结果
print(x_std)
#x_std.mean() 导出的结果是一个数组,用mean()查看均值
#x_std.std() 用std()查看方差
#scaler.fit_transform(data) 使用fit_transform(data)一步达成结果
#scaler.inverse_transform(x_std) 使用inverse_transform逆转标准化

1.4 处理选择

 大多数机器学习算法中,会选择StandardScaler来进行特征缩放,因为MinMaxScaler对异常值非常敏感。在PCA,聚类,逻辑回归,支持向量机,神经网络这些算法中,StandardScaler往往是最好的选择。

 MinMaxScaler在不涉及距离度量、梯度、协方差计算以及数据需要被压缩到特定区间时使用广泛,比如数字图像处理中量化像素强度时,都会使用MinMaxScaler将数据压缩于0,1区间之中。

二、缺失值

2.1 填补的类和参数

 1. 类:sklearn.impute.SimpleImputer(missing_values=nan, strategy='mean', fill_value=None, verbose=0,copy=True)

 2. 包括四个重要参数:

参数 含义和输入
missing_values 告诉SimpleImputer,数据中的缺失值长什么样,默认空值np.nan
strategy 我们填补缺失值的策略,默认均值。(1)输入"mean"使用均值填补(仅对数值型特征可用);(2)输入"median"用中值填补(仅对数值型特征可用);(3)输入"most_frequent"用众数填补(对数值型和字符型特征都可用);(4)输入"constant"表示请参考参数"fill_value"中的值(对数值型和字符型特征都可用)
fill_value 当参数startegy为"constant"的时候可用,可输入字符串或数字表示要填充的值,常用0
copy 默认为True,将创建特征矩阵的副本,反之则会将缺失值填补到原本的特征矩阵中去。
python 复制代码
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)

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

#使用众数填补Embarked
Embarked = data.loc[:,"Embarked"].values.reshape(-1,1)
imp_mode = SimpleImputer(strategy = "most_frequent")
data.loc[:,"Embarked"] = imp_mode.fit_transform(Embarked)
data.info()

2.2 用Pandas和Numpy进行填补

 注:用Pandas和Numpy进行填补其实更加简单

python 复制代码
import pandas as pd
data = pd.read_csv(r"D:\Download\Narrativedata.csv",index_col=0)
data.head()
data.loc[:,"Age"] = data.loc[:,"Age"].fillna(data.loc[:,"Age"].median())
#.fillna 在DataFrame里面直接进行填补

#Embarked只缺失了两行,我们这里将其删去,不进行填补
data.dropna(axis=0,inplace=True)
#.dropna(axis=0)删除所有有缺失值的行,.dropna(axis=1)删除所有有缺失值的列
#参数inplace,为True表示在原数据集上进行修改,为False表示生成一个复制对象,不修改原数据,默认False

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

3.1 编码

 1. 在机器学习中,大多数算法,譬如逻辑回归,支持向量机SVM,k近邻算法等都只能够处理数值型数据,不能处理文字,在sklearn当中,除了专用来处理文字的算法,其他算法在fit的时候全部要求输入数组或矩阵,也不能够导入文字型数据(其实手写决策树和普斯贝叶斯可以处理文字,但是sklearn中规定必须导入数值型)。

 然而在现实中,许多标签和特征在数据收集完毕的时候,都不是以数字来表现的。比如说,学历的取值可以是"小学","初中","高中","大学",付费方式可能包含"支付宝","现金","微信"等等。在这种情况下,为了让数据适应算法和库,我们必须将数据进行编码,即是说,将文字型数据转换为数值型。

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

python 复制代码
import pandas as pd
from sklearn.preprocessing import LabelEncoder
data = pd.read_csv(r"D:\Download\Narrativedata.csv",index_col=0)
y = data.iloc[:,-1] #要输入的是标签,不是特征矩阵,所以允许一维
le = LabelEncoder() #实例化
le = le.fit(y) #导入数据
label = le.transform(y) #transform接口调取结果
#也可以一行:data.iloc[:,-1] = LabelEncoder().fit_transform(data.iloc[:,-1])
print(label)

 注:此时输出结果全是0、1、2构成的矩阵。

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

python 复制代码
from sklearn.preprocessing import OrdinalEncoder
#接口categories_对应LabelEncoder的接口classes_,一模一样的功能
data_ = data.copy()
data_.head()
OrdinalEncoder().fit(data_.iloc[:,1:-1]).categories_
data_.iloc[:,1:-1] = OrdinalEncoder().fit_transform(data_.iloc[:,1:-1])
print(data_.head())

3.2 哑变量(独热编码)

 1. 我们刚才已经用OrdinalEncoder把分类变量Sex和Embarked都转换成数字对应的类别了。在舱门Embarked这一列中,我们使用0,1,2代表了三个不同的舱门,然而这种转换是正确的吗?

 2. 我们来思考三种不同性质的分类数据:

 (1)舱门(S,C,Q)

三种取值S,C,Q是相互独立的,彼此之间完全没有联系,表达的是S≠C≠Q的概念。这是名义变量。

 (2)学历(小学,初中,高中)

三种取值不是完全独立的,我们可以明显看出,在性质上可以有高中>初中>小学这样的联系,学历有高低,但是学历取值之间却不是可以计算的,我们不能说小学 + 某个取值 = 初中。这是有序变量。

 (3)体重(>45kg,>90kg,>135kg)

各个取值之间有联系,且是可以互相计算的,比如120kg - 45kg = 90kg,分类之间可以通过数学计算互相转换。这是有距变量。

 然而在对特征进行编码的时候,这三种分类数据都会被我们转换为0,1,2,这三个数字在算法看来,是连续且可以计算的,这三个数字相互不等,有大小,并且有着可以相加相乘的联系。所以算法会把舱门,学历这样的分类特征,都误会成是体重这样的分类特征。这是说,我们把分类转换成数字的时候,忽略了数字中自带的数学性质,所以给算法传达了一些不准确的信息,而这会影响我们的建模。

 类别OrdinalEncoder可以用来处理有序变量,但对于名义变量,我们只有使用哑变量的方式来处理,才能够尽量向算法传达最准确的信息。

 注:这样的变化,让算法能够彻底领悟,原来三个取值是没有可计算性质的,是"有你就没有我"的不等概念。在我们的数据中,性别和舱门,都是这样的名义变量。因此我们需要使用独热编码,将两个特征都转换为哑变量。

python 复制代码
from sklearn.preprocessing import OneHotEncoder
X = data.iloc[:,1:-1]
enc = OneHotEncoder(categories='auto').fit(X)
result = enc.transform(X).toarray()

#可以看哪一列对应哪个特征
print(enc.get_feature_names())


 3. 合并哑变量和原数据:

python 复制代码
#axis=1,表示跨行进行合并,也就是将量表左右相连,如果是axis=0,就是将量表上下相连
newdata = pd.concat([data,pd.DataFrame(result)],axis=1)
newdata.drop(["Sex","Embarked"],axis=1,inplace=True)
newdata.columns = ["Age","Survived","Female","Male","Embarked_C","Embarked_Q","Embarked_S"]
print(newdata.head())

特征可以做哑变量,标签也可以吗?可以,使用类sklearn.preprocessing.LabelBinarizer可以对做哑变量,许多算法都可以处理多标签问题(比如说决策树),但是这样的做法在现实中不常见,因此我们在这里就不赘述了。

相关推荐
奔跑中的小象4 小时前
统信UOS + 天数AI卡部署SGLang服务手册
人工智能·uos·sglang·天数智芯
DevSecOps选型指南4 小时前
中国版Mythos,为何是悬镜安全灵脉CodeAI?
人工智能·安全
Shockang4 小时前
LangGraph 状态机实战
人工智能
刹那芳华19924 小时前
循环神经网络的从零开始实现(RNN)
人工智能·rnn·深度学习
阿童木写作5 小时前
跨境图片翻译工具多合一,批量图片视频字幕翻译加智能抠图
人工智能·python·音视频·语音识别
科技之门5 小时前
AI3D从建模到贴图、绑骨和动画的完整流程怎么做?V2Fun完整工作流指南
人工智能·3d·贴图
宇宙第一小趴菜5 小时前
二、机器学习的应用领域和发展史
人工智能·机器学习
前端开发江鸟5 小时前
我写过 MCP Server,却一直以为 MCP 只有 Tool
人工智能
天国梦5 小时前
自习室智能化升级避坑指南:天学网AI智习室方案实测与选型建议
大数据·人工智能
阿里云云原生6 小时前
可用性从 99.9% 跃升至 99.995%:畅捷通如何用 AI 重塑运维底座?
运维·网络·人工智能