文章目錄
- 概述
- 缺失值的常用處理方式
- sklearn中缺失值填充子產品
- 缺失值填充示例
-
- 準備工作
- 0填充
- 均值填充
- 衆數填充
- 中位數填充
- 随機森林填充
- 總結
概述
機器學習和資料挖掘中所使用的資料,永遠不可能是完美的。很多特征,對于分析和模組化來說意義非凡,但對于實際收集資料的人卻不是如此,是以資料挖掘之中,常常會有重要的字段缺失值很多,但又不能舍棄字段的情況。是以,資料預進行中非常重要的一項就是處理缺失值。
缺失值的常用處理方式
- 删除:資料缺失量比較少,删除後對模型的結果幾乎不會造成影響;與模型準确性幾乎無關的屬性
- 填充
- 均值
- 衆數
- 中位數
- 随機森林
sklearn中缺失值填充子產品
對pandas熟悉的可用使用pandas來進行缺失值的填充,詳情見我的pandas筆記,這裡主要将sklearn中對缺失值處理的相關方法。本次使用的資料為kaggle上泰坦尼克幸存者資料集,原始資料下載下傳位址,也可以在我的資料集下載下傳位址獲得同樣的資料
sklearn中impute子產品的SimpleImputer類專門用來進行缺失值的簡單填充,它包含四個重要參數
參數 | 含義 |
---|---|
missing_values | 告訴SimpleImputer對象,資料的缺失值長什麼樣子,預設為np.nan |
strategy | 填補缺失值的政策 strategy=‘mean’(預設)僅适用數值型特征 strategy=‘median’ 使用中值填充,僅适用數值型特征 strategy=‘most_frequent’ 使用衆數填充,數值型字元型均可使用 strategy=‘constant’ 表示參考fill_value參數中的值,數值型和字元型均可使用 |
fill_value | 參數為strategy=‘constant’時可用,可輸入字元串或數值來填充缺失值 |
copy | 預設為True,表示建立原資料的副本,修改後的資料不會對原始資料造成影響 |
缺失值填充示例
準備工作
導入相關子產品,讀取資料集
# 導入相關子產品
from sklearn.impute import SimpleImputer
import numpy as np
import pandas as pd
# 資料路徑,自己本地的檔案路徑
file_name = "../../data/titanic/train.csv"
# 加載資料集
df = pd.read_csv(file_name)
df.head()
# 删除不必要的列
df.drop(['Name', 'Ticket', 'Cabin'], inplace=True, axis=1)
df.head()
檢視原始資料的資訊
df.info()
'''
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 891 entries, 0 to 890
Data columns (total 9 columns):
PassengerId 891 non-null int64
Survived 891 non-null int64
Pclass 891 non-null int64
Sex 891 non-null object
Age 714 non-null float64
SibSp 891 non-null int64
Parch 891 non-null int64
Fare 891 non-null float64
Embarked 889 non-null object
dtypes: float64(2), int64(5), object(2)
memory usage: 62.8+ KB
'''
原始資料共891條記錄,其中Age屬性缺失接近200個資料,占比達到了20%左右,這是一個很巨大的占比了,已經不能簡單的删除缺失值操作了,如果删除了這個屬性,樣本資料會變小很多,那麼訓練出來的模型将會獲得一個不好的表現。是以這裡需要對Age屬性進行缺失值填充。Embarked屬性缺失兩個,占比相當小,這種情況可用直接删除即可,這裡隻考慮對Age的填充,可用使用 的方法由pandas填補缺失值,詳見我的pandas筆記,下面主要介紹用sklearn.impute子產品的SimpleImputer類進行填充缺失值。
注意點:使用sklearn中的方法時,要求輸入的資料必須是二維的,是以需要對單特征列進行reshape操作
0填充
# 用0填充年齡的缺失值
df0 = df.copy() # 複制原資料,避免原資料被覆寫
# 執行個體化
impute_0 = SimpleImputer(strategy='constant', fill_value=0)
# 去除Age屬性的原始資料,并通過values轉化為一維數組,在通過reshape變為二維數組
# 因為sklearn中傳到資料必須是二維的
raw_data = df0['Age'].values.reshape(-1, 1)
# fit_transform()一步到位,傳回填充後的資料
new_data = impute_0.fit_transform(raw_data)
# 用新資料替換原資料
df0['Age'] = new_data
df0.head(10)
均值填充
# 用均值填充年齡的缺失值
df_mean = df.copy()
impute_mean = SimpleImputer()
raw_data = df_mean['Age'].values.reshape(-1, 1)
new_data = impute_mean.fit_transform(raw_data)
df_mean['Age'] = new_data
df_mean.head(10)
衆數填充
# 用衆數填充年齡缺失值
df_mode = df.copy()
impute_mode = SimpleImputer(strategy='most_frequent')
raw_data = df_mode['Age'].values.reshape(-1, 1)
new_data = impute_mode.fit_transform(raw_data)
df_mode['Age'] = new_data
df_mode.head(10)
中位數填充
# 用中位數填充年齡缺失值
df_median = df.copy()
impute_median = SimpleImputer(strategy='median')
raw_data = df_median['Age'].values.reshape(-1, 1)
new_data = impute_median.fit_transform(raw_data)
df_median['Age'] = new_data
df_median.head(10)
随機森林填充
見用随機森林填充缺失值
總結
具體用哪一種填充方式看個人和具體的資料情況,隻要達到目的都是好的。大多數情況下先考慮正常的填充方法(0,均值,中位數,衆數),當這些方法用了之後發現鮮果不明顯,但是又不能将缺失值删除的情況下九月考慮用随機森林等方式來填充缺失值。