机器学习模型训练前,需要把原始数据进行预处理,并建立合适的特征工程。
机器学习工作流程
一般使用pandas库进行数据的清洗
import pandas as pd
import numpy as np
dict1 = {'ID':[1,2,3,4,5,6,7,8,9],
'System':['win10','win10',np.nan,'win10',
np.nan,np.nan,'win7','win7','win8'],
'cpu':['i7','i5',np.nan,'i7',np.nan,np.nan,'i5','i5','i3']}
dict2 = {'ID':[1,2,3,4,5,6,7,8,9],
'System':[np.nan, np.nan,'win7',np.nan,
'win8','win7',np.nan,np.nan,np.nan],
'cpu':[np.nan,np.nan,'i3',np.nan,'i7',
'i5',np.nan,np.nan,np.nan]}
df1 = pd.DataFrame(dict1)
df2 = pd.DataFrame(dict2)
display(df1)
display(df2)
横向堆叠,即将两个表在X轴向拼接在一起,可以使用concat函数完成,concat函数的基本语法如下。
常见的参数设置
连接两个表
现为df1增加一列新数据
df2的nn列都是nan,因为默认连接方式是outer.
concat其他的参数设置
纵向表堆叠——append方法
append方法也可以用于纵向合并两张表。但是append方法实现纵向表堆叠有一个前提条件,那就是两张表的列名需要完全一致。
pandas.DataFrame.append(self, other, ignore_index=False, verify_integrity=False)。
纵向合并
主键合并,即通过一个或多个键将两个数据集的行连接起来,类似于SQL中的JOIN。针对同一个主键存在两张包含不同字段的表,将其根据某几个字段—一对应拼接起来,结果集列数为两个元数据的列数和减去连接键的数量。
在实际的生产环境中,可能会把数据存储到不同的表中,比如餐饮行业,用户的订单信息会不停的实时更新,而菜品的种类变化就比较小,为了节省空间可能会把数组存到不同的两张表中。而我们想要进行整体的数据分析的时候就需要合并两张表。
数据链接点击
提取码:eqnk
读入数据
主键合并----merge函数
和数据库的join一样,merge函数也有左连接(left)、右连接(right)、内连接(inner)和外连接(outer),但比起数据库SQL语言中的join和merge函数还有其自身独到之处,例如可以在合并过程中对数据集中的数据进行排序等。
现在以左连接的方式连接两个表(以dishes_id作为合并的主键)
参数设置
下面举个简单的例子
df=pd.DataFrame(
{'id':[1,2,3,4],
'price':[11,22,33,44]
}
)
df_1=pd.DataFrame({
'id':[1,3,8],
'value':[66,77,88]
})
pd.merge(df,df_1) # 默认是内连接
pd.merge(df,df_1,how='left')
pd.merge(df,df_1,how='right')
pd.merge(df,df_1,how='outer')
主键合并——join方法
join方法也可以实现部分主键合并的功能,它默认以index作为对齐的列。但是join方法使用时,on参数只有 右表的索引值正是左表的某一列的值,这时可以通过将 右表的索引和左表的列对齐合并,两个表有相同的列名的时候,on指定重复列名是会报错的
比如上面的两个表按dishes_id合并,直接on='dishes_id’是会报错的,想要进行合并可以通过下面的方法
join函数多用于两个表没有相同键的时候。
参数设置
重叠合并:combine_first
数据分析和处理过程中若出现两份数据的内容几乎一致的情况,但是某些特征在其中一张表上是完整的,而在另外一张表上的数据则是缺失的时候,可以用combine_first方法进行重叠数据合并,其原理如下。
pandas.DataFrame.combine_first(other)
比如重叠上面的df1和df2
pandas提供了一个名为drop_duplicates的去重方法。该方法只对DataFrame或者Series类型有效。这种方法不会改变数据原始排列,并且兼具代码简洁和运行稳定的特点。该方法不仅支持单一特征的数据去重,还能够依据DataFrame的其中一个或者几个特征进行去重操作。
读入数据
删除重复值后,第七行数据消失
还可以指定以某列数据为基准,比如删除’order_id’的有重复值
利用isnull或notnull找到缺失值
数据中的某个或某些特征的值是不完整的,这些值称为缺失值。
pandas提供了识别缺失值的方法isnul以及识别非缺失值的方法notnull,这两种方法在使用时返回的都是布尔值True和False。
结合sum函数和isnull、notnull函数,可以检测数据中缺失值的分布以及数据中一共含有多少缺失值。
isnull和notnull之间结果正好相反,因此使用其中任意一个都可以判断出数据中缺失值的位置。
dropna函数删除缺失值
也可以指定以某列nan为基础删除(删除指定列中nan所在的行)
除了对缺失值进行删除,也可以填充缺失值
fillna()函数
fillna的具体用法可以参考我的另一篇博客点击此处
异常值
异常值是指数据中个别值的数值明显偏离其余的数值,有时也称为离群点,检测异常值就是检验数据中是否有录入错误以及是否含有不合理的数据。
异常值的存在对数据分析十分危险,如果计算分析过程的数据有异常值,那么会对结果会产生不良影响,从而导致分析结果产生偏差乃至错误。
常用的异常值检测主要为3a原则和箱线图分析两种方法。
1.3o原则又称为拉依达法则。该法则就是先假设一组检测数据只含有随机误差,对原始数据进行计算处理得到标准差,然后按一定的概率确定一个区间,认为误差超过这个区间的就属于异常值。
2.这种判别处理方法仅适用于对正态或近似正态分布的样本数据进行处理,如下表所示,其中σ代表标准差,u代表均值,x=u为图形的对称轴。
3.数据的数值分布几乎全部集中在区间(u-3σ,u+3σ)内,超出这个范围的数据仅占不到0.3%。故根据小概率原理,可以认为超出3σ的部分数据为异常数据。
1.箱型图提供了识别异常值的一个标准,即异常值通常被定义为小于QL-1.5IQR或大于QU+1.5IQR的值。
QL称为下四分位数,表示全部观察值中有四分之一的数据取值比它小。
QU称为上四分位数,表示全部观察值中有四分之一的数据取值比它大。
IQR称为四分位数间距,是上四分位数QU与下四分位数QL之差,其间包含了全部观察值的一半。2.箱线图依据实际数据绘制,真实、直观地表现出了数据分布的本来面貌,且没有对数据做任何限制性要求,其判断异常值的标准以四分位数和四分位数间距为基础。
3.四分位数给出了数据分布的中心、散布和形状的某种指示,具有一定的鲁棒性,即25%的数据可以变得任意远而不会很大地扰动四分位数,所以异常值通常不能对这个标准施加影响。鉴于此,箱线图识别异常值的结果比较客观,因此在识别异常值方面具有一定的优越性。
首先读入数据
提取一列数据画箱线图
有了这三条线,就可以可以计算正常数据上限和下限
QL-1.5IQR<=X<=QU+1.5IQR
自定义一个函数实现清除缺失值
def replace(x):
import numpy as np
QU = x.quantile(0.75)
QL = x.quantile(0.25)
IQR = QU -QL
x[(x>(QU+1.5*IQR)) | (x<(QL - 1.5*IQR))] = np.nan
return x
1.离差标准化
离差标准化是对原始数据的一种线性变换,结果是将原始数据的数值映射到[0,1]区间之间,转换公式为
其中max为样本数据的最大值, min为样本数据的最小值, max-min为极差。离差标准化保留了原始数据值之间的联系,是消除量纲和数据取值范围影响最简单的方法。
如果A列数据取值0-100,而B列的数据2000-5000
如果不加处理,那么B列数据对结果的影响可能过大,而这仅仅是因为B的取值大。
➢数据的整体分布情况并不会随离差标准化而发生改变,原先取值较大的数据,在做完离差标准化后的值依旧较大。
➢当数据和最小值相等的时候, 通过离差标准化可以发现数据变为0。
➢若数据极差过大就会出现数据在离差标准化后数据之 间的差值非常小的情况。
➢同时,还可以看出离差标准化的缺点:若数据集中某个数值很大,则离差标准化的值就会接近于0,并且相互之间差别不大。
2.标准差标准化
标准差标准化也叫零均值标准化或分数标准化,是当前使用最广泛的数据标准化方法。经过该方法处理的数据均值为0 ,标准差为1 , 转化公式如下。
其中X为原始数据的均值, δ为原始数据的标准差。标准差标准化后的值区间不局限于[0,1] ,并且存在负值。同时也不难发现,标准差标准化和离差标准化- -样不会改变数据的分布情况。
3.小数定标标准化
通过移动数据的小数位数,将数据映射到区间[-1,1]之间,移动的小数位数取决于数据绝对值的最大值。转化公式如下。
其中的k是数据中的最大值以10的底对数向上取整
比如最大值是101,k=3;最大值是99,k=2
总之,三种标准化方法各有其优势:
➢离差标准化方法简单,便于理解,标准化后的数据限定在[0, 1]区间内。
➢标准差标准化受到数据分布的影响较小。
➢小数定标标准化方法的适用范围广,并且受到数据分布的影响较小,相比较于前两种方法而言该方法适用程度适中。
读入数据
def min_max_scaler(x): #离差
return (x-x.min())/(x.max()-x.min())
def stander_scaler(x): #标准差
return (x-x.mean())/x.std()
def decimal_scaler(x): #小数定标
import numpy as np
k=np.ceil(np.log10(x.abs().max()))
return x/(10**k)
数据分析模型中有相当一部分的算法模型都要求输入的特征为数值型,但实际数据中特征的类型不一定只有数值型,还会存在相当一部分的类别型, 这部分的特征需要经过哑变量处理才可以放入模型之中。哑变量处理的原理示例如图。
Python中可以利用pandas库中的get_ dummies函数对类别型特征进行哑变量处理
➢某些模型算法,特别是某些分类算法如ID3决策树算法和Apriori算法等,要求数据是离散的,此时就需要将连续型特征(数值型)变换成离散型特征(类别型)
➢连续特征的离散化就是在数据的取值范围内设定若干个离散的划分点,将取值范围划分为一-些离散化的区间,最后用不同的符号或整数值代表落在每个子区间中的数据值。
➢因此离散化涉及两个子任务,即确定分类数以及如何将连续型数据映射到这些类别型数据上。其原理如图。
1.等宽法
将数据的值域分成具有相同宽度的区间,区间的个数由数据本身的特点决定或者用户指定,与制作频率分布表类似。pandas提供 了cut函数,可以进行连续型数据的等宽离散化,其基础语法格式如下。
pd.cut的详细用法传送门
2.等频法
➢cut函数虽然不能够直接实现等频离散化,但是可以通过定义将相同数量的记录放进每个区间。
➢等频法离散化的方法相比较于等宽法离散化而言,避免了类分布不均匀的问题,但同时却也有可能将数值非常接近的两个值分到不同的区间以满足每个区间中固定的数据个数。
3.基于聚类分析的方法
➢一维聚类的方法包括两个步骤:
●将连续型数据用聚类算法(如K-Means算法等)进行聚类。
●处理聚类得到的簇,将合并到一-个簇的连续型数据做同-标记。
➢聚类分析的离散化方法需要用户指定簇的个数,用来决定产生的区间数。
➢k-Means聚类分析的离散化方法可以很好地根据现有特征的数据分 布状况进行聚类,但是由于k- Means算法本身的缺陷,用该方法进行离散化时依旧需要指定离散化后类别的数目。此时需要配合聚类算法评价方法,找出最优的聚类簇数目。
这里只做简单的应用