机器学习基础:缺失值的处理技巧(附Python代码)

2020-10-31 星星之火 网络

在数据分析和建模中,经常会遇到变量值缺失的情况,这是非常常见的。为了保证数据指标的完整性以及可利用性,通常我们会采取特殊的方式对其进行处理。

在数据分析和建模中,经常会遇到变量值缺失的情况,这是非常常见的。为了保证数据指标的完整性以及可利用性,通常我们会采取特殊的方式对其进行处理。

1、缺失查看

首先,需要查看缺失值的缺失数量以及比例(#数据使用的kaggle平台上预测房价的数据)

import pandas as pd
 
 
# 统计缺失值数量
missing=data.isnull().sum().reset_index().rename(columns={0:'missNum'})
# 计算缺失比例
missing['missRate']=missing['missNum']/data.shape[0]
# 按照缺失率排序显示
miss_analy=missing[missing.missRate>0].sort_values(by='missRate',ascending=False)
  1.  

柱形图可视化

import matplotlib.pyplot as plt
import pylab as pl
 
 
fig = plt.figure(figsize=(18,6))
plt.bar(np.arange(miss_analy.shape[0]), list(miss_analy.missRate.values), align = 'center',color=['red','green','yellow','steelblue'])
 
 
plt.title('Histogram of missing value of variables')
plt.xlabel('variables names')
plt.ylabel('missing rate')
# 添加x轴标签,并旋转90度
plt.xticks(np.arange(miss_analy.shape[0]),list(miss_analy['index']))
pl.xticks(rotation=90)
# 添加数值显示
for x,y in enumerate(list(miss_analy.missRate.values)):
    plt.text(x,y+0.12,'{:.2%}'.format(y),ha='center',rotation=90)    
plt.ylim([0,1.2])
 
 
plt.show()
  1.  
 

这样的统计计算以及可视化基本已经看出哪些变量缺失,以及缺失比例情况,对数据即有个缺失概况。下面将对缺失变量进行相应处理。

2、缺失处理

方式1:删除

直接去除含有缺失值的记录,这种处理方式是简单粗暴的,适用于数据量较大(记录较多)且缺失比较较小的情形,去掉后对总体影响不大。一般不建议这样做,因为很可能会造成数据丢失、数据偏移。

func: df.dropna(axis=0, how='any', thresh=None, subset=None, inplace=False)
 
 
# 1、删除‘age’列
df.drop('age', axis=1, inplace=True)
 
 
# 2、删除数据表中含有空值的行
df.dropna()
 
 
# 3、丢弃某几列有缺失值的行
df.dropna(axis=0, subset=['a','b'], inplace=True)
 
 

直接去除缺失变量,基于第一步我们已经知道每个变量的缺失比例,如果一个变量的缺失比例过高,基本也就失去了预测意义,这样的变量我们可以尝试把它直接去掉。

# 去掉缺失比例大于80%以上的变量
data=data.dropna(thresh=len(data)*0.2, axis=1)

方式2:常量填充

 

在进行缺失值填充之前,我们要先对缺失的变量进行业务上的了解,即变量的含义、获取方式、计算逻辑,以便知道该变量为什么会出现缺失值、缺失值代表什么含义。比如,‘age’ 年龄缺失,每个人均有年龄,缺失应该为随机的缺失,‘loanNum’贷款笔数,缺失可能代表无贷款,是有实在意义的缺失。

全局常量填充:可以用0,均值、中位数、众数等填充。

平均值适用于近似正态分布数据,观测值较为均匀散布均值周围;中位数适用于偏态分布或者有离群点数据,中位数是更好地代表数据中心趋势;众数一般用于类别变量,无大小、先后顺序之分。

# 均值填充
data['col'] = data['col'].fillna(data['col'].means())
# 中位数填充
data['col'] = data['col'].fillna(data['col'].median())
# 众数填充
data['col'] = data['col'].fillna(stats.mode(data['col'])[0][0])
  1.  

也可以借助Imputer类处理缺失:

 
 
from sklearn.preprocessing import Imputer
imr = Imputer(missing_values='NaN', strategy='mean', axis=0)
imputed_data =pd.DataFrame(imr.fit_transform(df.values),columns=df.columns)
imputed_data

方式3:插值填充

采用某种插入模式进行填充,比如取缺失值前后值的均值进行填充:

#  interpolate()插值法,缺失值前后数值的均值,但是若缺失值前后也存在缺失,则不进行计算插补。
df['a'] = df['a'].interpolate()
 
 
# 用前面的值替换, 当第一行有缺失值时,该行利用向前替换无值可取,仍缺失
df.fillna(method='pad')
 
 
# 用后面的值替换,当最后一行有缺失值时,该行利用向后替换无值可取,仍缺失
df.fillna(method='backfill')#用后面的值替换

方式4:KNN填充

 

利用knn算法填充,其实是把目标列当做目标标量,利用非缺失的数据进行knn算法拟合,最后对目标列缺失进行预测。(对于连续特征一般是加权平均,对于离散特征一般是加权投票)

fancyimpute 类

from fancyimpute import KNN
fill_knn = KNN(k=3).fit_transform(data)
data = pd.DataFrame(fill_knn)
 

sklearn类

from sklearn.neighbors import KNeighborsClassifier, KNeighborsRegressor
 
 
def knn_filled_func(x_train, y_train, test, k = 3, dispersed = True):
    # params: x_train 为目标列不含缺失值的数据(不包括目标列)
    # params: y_train 为不含缺失值的目标列
    # params: test 为目标列为缺失值的数据(不包括目标列)
    if dispersed:
        knn= KNeighborsClassifier(n_neighbors = k, weights = "distance")
    else:
        knn= KNeighborsRegressor(n_neighbors = k, weights = "distance")
 
 
    knn.fit(x_train, y_train)
    return test.index, knn.predict(test)

方式5:随机森林填充

 

随机森林算法填充的思想和knn填充是类似的,即利用已有数据拟合模型,对缺失变量进行预测。

from sklearn.ensemble import RandomForestRegressor, RandomForestClassifier
 
 
def knn_filled_func(x_train, y_train, test, k = 3, dispersed = True):
    # params: x_train 为目标列不含缺失值的数据(不包括目标列)
    # params: y_train 为不含缺失值的目标列
    # params: test 为目标列为缺失值的数据(不包括目标列)
    if dispersed:
        rf= RandomForestRegressor()
    else:
        rf= RandomForestClassifier()
 
 
    rf.fit(x_train, y_train)
    return test.index, rf.predict(test)

3、缺失衍生

有时候,可以根据某个字段是否缺失,进行新变量的衍生,比如,"信用卡数量",若该字段缺失,代表'无信用卡',则可以根据"信用卡数量"是否缺失衍生'有无信用卡'字段,这种衍生很可能是很有效果的。

4、总结

总之,处理缺失值是需要研究数据规律与缺失情况来进行处理的,复杂的算法不一定有好的效果,因此,还要具体问题具体分析,尤其是要搞明白字段含义以及缺失意义,这往往容易被忽略。个人经验,数据处理需要去探索,没有一成不变的万全之策。

作者:星星之火

 

版权声明:
本网站所有内容来源注明为“梅斯医学”或“MedSci原创”的文字、图片和音视频资料,版权均属于梅斯医学所有。非经授权,任何媒体、网站或个人不得转载,授权转载时须注明来源为“梅斯医学”。其它来源的文章系转载文章,或“梅斯号”自媒体发布的文章,仅系出于传递更多信息之目的,本站仅负责审核内容合规,其内容不代表本站立场,本站不负责内容的准确性和版权。如果存在侵权、或不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。
在此留言
评论区 (1)
#插入话题
  1. [GetPortalCommentsPageByObjectIdResponse(id=1583271, encodeId=9dc715832e1a9, content=<a href='/topic/show?id=f6e1611840d' target=_blank style='color:#2F92EE;'>#机器#</a>, beContent=null, objectType=article, channel=null, level=null, likeNumber=36, replyNumber=0, topicName=null, topicId=null, topicList=[TopicDto(id=61184, encryptionId=f6e1611840d, topicName=机器)], attachment=null, authenticateStatus=null, createdAvatar=null, createdBy=13dc16973127, createdName=ms6279672939590805, createdTime=Mon Nov 02 06:26:41 CST 2020, time=2020-11-02, status=1, ipAttribution=)]

相关资讯

Nat Med:1000多对双胞胎研究告诉你,人类餐后是怎么对食物进行反应的?

研究人员在英国招募了1,002对双胞胎和没有血缘关系的健康成年人参与PREDICT 1研究,并评估了临床环境和家庭中的餐后代谢反应。

Blood:机器学习揭示MDS基因型和形态学特征的相关性

骨髓增生异常综合征(MDS)是一组起源于造血干细胞的肿瘤性疾病,主要特征是骨髓造血功能异常、血细胞发育异常,表现为难治性的血细胞减少、造血功能衰竭,有向急性白血病转化的高风险,曾被称为白血病前期。

CELL:刘如谦发文,不需要做实验,机器学习预测基因编辑结果

刘如谦团队在哺乳动物细胞中的38,538个基因组整合靶点上表征了11个胞嘧啶和腺嘌呤碱基编辑器(CBEs和ABEs)的序列-活性关系,并将所得结果用于训练BE-蜂巢机器学习模型。

机器学习中处理缺失值的9种方法

数据科学就是关于数据的。它是任何数据科学或机器学习项目的关键。在大多数情况下,当我们从不同的资源收集数据或从某处下载数据时,几乎有95%的可能性我们的数据中包含缺失的值。我们不能对包含缺失值的数据进行