更新內(nèi)容:missingno庫可視化缺失值
在實際的應(yīng)用過程中球化,樣本由于各種原因缺少一個或多個值的情況并不少見构罗,其主要原因有:在數(shù)據(jù)收集過程中出現(xiàn)了錯誤,常用的度量方法并不適用于某些特征媳友,或在某些調(diào)查過程中有些數(shù)據(jù)未被填寫丛版,等等。我們見到的缺失值是數(shù)據(jù)表中的空值汹来,或者是類似于NaN的占位符续膳。
有些時候缺失值的存在是合乎邏輯的,比如婚姻狀態(tài)是未婚收班,則孩子數(shù)量不填是很正常的坟岔,但是有些缺失值我們忽略之后會讓機(jī)器學(xué)習(xí)算法的效能大打折扣,所以我們必須采取一些措施來處理缺失值闺阱。
關(guān)于處理缺失值的方案在當(dāng)我們在談?wù)摂?shù)據(jù)時我們應(yīng)該談些什么炮车?有提及,這里就不贅述了。
數(shù)據(jù)集的準(zhǔn)備
改數(shù)據(jù)來與R中的“klaR”包中的German credit data
install.packages("klaR")
library(klaR)
write.csv(GermanCredit,file="C:\\Users\\Administrator\\OneDrive\\步履不停\\評分卡制作\\數(shù)據(jù)\\GermanCredit.csv")
或者也可以直接去http://archive.ics.uci.edu/ml/datasets/Statlog+(German+Credit+Data)下載
關(guān)于數(shù)據(jù)集中各個屬性所代表的含義可以去https://pan.baidu.com/s/1o8aaGXk下載doc文件查看
一瘦穆、缺失值的識別
- 在python中缺失值可以用pandas中的isnull()
import pandas as pd
df = pd.read_csv("C:\\Users\\Administrator\\OneDrive\\步履不停\\評分卡制作\\數(shù)據(jù)\\GermanCredit.csv",engine='python')
df.isnull().sum()
得到如下結(jié)果,可以看到?jīng)]有缺失值纪隙。沒辦法,這個數(shù)據(jù)應(yīng)該是事先被處理過的扛或,方便建模绵咱。總之熙兔,呵呵悲伶。。住涉。麸锉。。舆声。
Unnamed: 0 0
status 0
duration 0
credit_history 0
purpose 0
amount 0
savings 0
employment_duration 0
installment_rate 0
personal_status_sex 0
other_debtors 0
present_residence 0
property 0
age 0
other_installment_plans 0
housing 0
number_credits 0
job 0
people_liable 0
telephone 0
foreign_worker 0
credit_risk 0
dtype: int64
- 還可以用missingno這個庫圖形化缺失值
import missingno
missingno.matrix(data)
那我們可以自己構(gòu)造數(shù)據(jù)
import pandas as pd
from io import StringIO
csv_data='''A,B,C,D
1,2,3,4
5,6,7,8
0,11,12,'''
data = pd.read_csv(StringIO(csv_data))
data
A B C D
0 1 2 3.0 4.0
1 5 6 NaN 8.0
2 0 11 12.0NaN
data.isnull().sum()
A 0
B 0
C 1
D 1
dtype: int64
二花沉,將存在缺失值的特征或樣本刪除
- 優(yōu)點:簡單方便
- 缺點:可能會刪除過多的樣本,導(dǎo)致分析結(jié)果可靠性不高
在python中可以用DataFrame.dropna()方法刪除缺失值
#刪除存在缺失值的行
data.dropna()
A B C D
0 1 2 3.0 4.0
data.dropna(axis=1) #刪除存在缺失值的列
df.dropna(how='all') #刪除所有列都是缺失值的行
df.dropna(thresh=4) #刪除沒有至少4個非NaN值的行
df.dropna(subset=['C']) #刪除指定列中存在缺失值的行
三媳握,缺失值的填充
在不能剔除缺失值的時候碱屁,我們可以使用不同的插值技術(shù),通過數(shù)據(jù)集中其他訓(xùn)練樣本的數(shù)據(jù)來估計缺失值蛾找。對于數(shù)值型數(shù)據(jù)來說娩脾,通常使用能代表變量中心趨勢的值來填補。通常有平均值打毛,中位數(shù)柿赊,眾數(shù)等。選擇哪種中心趨勢值來填充需要觀察變量的分布隘冲。因為平均值易受極端值影響闹瞧,在這中偏態(tài)數(shù)據(jù)中,我們可以用中位數(shù)來填充展辞,而在正態(tài)分布下我們可以用平均值。對于定性數(shù)據(jù)來講万牺,我們可以用眾數(shù)來填充
在numpy中罗珍,缺失值可以用numpy.NaN或者numpy.nan來表示
在scikit-learn中,有可以實現(xiàn)的類-Imputer
- 平均值
from sklearn.preprocessing import Imputer
#axis=0,代表用列的均值來進(jìn)行相應(yīng)的替換脚粟,等于1代表用行的均值來替換
imr = Imputer(missing_values='NaN',strategy='mean',axis=0)
imr.fit(data)
imputed_data = imr.transform(data.values)
imputed_data
- 中位數(shù)
from sklearn.preprocessing import Imputer
imr = Imputer(missing_values='NaN',strategy='median',axis=0)
imr.fit(data)
imputer_data = imr.transform(data.values)
imputer_data
- 眾數(shù)
from sklearn.preprocessing import Imputer
imr = Imputer(missing_values='NaN',strategy='most_frequent',axis=0)
imr.fit(data)
imputer_data = imr.transform(data.values)
imputer_data
也可以使用pandas 中的相關(guān)方法覆旱,具體可以參考這篇文章http://blog.csdn.net/helen1313/article/details/53304641
- 采用拉格朗日插值法
#構(gòu)建數(shù)據(jù)
import numpy as np
sales = pd.DataFrame(data={'sale_money':[3442.1,3393.1,3136.6,3744.1,6607.4,4060.3,3614.7,3295.5,2332.1,2699.3,np.nan,3036.8]})
#導(dǎo)入庫
from scipy.interpolate import lagrange #導(dǎo)入拉格朗日插值函數(shù)
#過濾異常值,將其變?yōu)榭罩?sales['sale_money'][(sales['sale_money']<400) | (sales['sale_money']>5000)]=None
#自定義函數(shù)
##導(dǎo)入拉格朗日插值函數(shù)
from scipy.interpolate import lagrange
def ployinterp_columns(s,n,k=5):
#s為列向量核无,n為缺失值位置扣唱,K為取前后的數(shù)據(jù)個數(shù)。默認(rèn)為5
y = s[list(range(n-k,n))+list(range(n+1,n+1+k))] #取數(shù)
y=y[y.notnull()] #剔除空值
return(lagrange(y.index,list(y))(n))
#逐個列逐個行判斷是否需要插值
for i in sales.columns:
for j in range(len(sales)):
if(sales[i].isnull())[j]:
sales[i][j] = ployinterp_columns(sales[i],j)