其他分享
首页 > 其他分享> > 数据缺失处理的一些技术

数据缺失处理的一些技术

作者:互联网

本文参考自:https://www.kaggle.com/code/residentmario/simple-techniques-for-missing-data-imputation/data
数据亦来源该页

样本中的数据缺失是ML界非常常见的问题,本文就这问题进行讨论。

使用 MissingNo 查看数据

import pandas as pd
import numpy as np
import tensorflow as tfimport missingno as msno

df = pd.read_csv('../../datasets/recipeData.csv', encoding='latin-1').set_index("BeerID")

MissingNo是常用的观察缺失数据的库,包含了多种图可以观测缺失数据情况。

msno.matrix(df)

image

msno.bar(df)

image

drop

处理缺失数据的一个最简单思路就是把缺失的行drop掉,对于非常小样本的缺失可以这么做。
可以用dropna()丢掉缺失行

len(df), len(df.dropna())

(73861, 757)

可以看到对于本数据,dropna会丢掉绝大多数行,并不适用。
还有一种思路,对于数据缺失非常严重的feature,往往不再具有参考意义,可以drop掉

df.drop(['PrimingMethod', 'PrimingAmount'], axis='columns')

简单插补

简单的数据插补有均值插补,众数插补,pandas自带的方法就能很简单地实现。

df['MashThickness'].isnull().sum(), df['MashThickness'].fillna(df['MashThickness'].mean()).isnull().sum()

df['MashThickness'].mean(), df['MashThickness'].fillna(df['MashThickness'].mean()).mean()

除此之外,sklearn.preprocessing也带了简单的插补方法。

from sklearn.preprocessing import Imputer 
imputer = Imputer(strategy="median")
imputer.fit(df)

sklearn提供了SimpleImputer,impute.IterativeImputer,MissingIndicator(用于二进制),KNNImputer4种插补模型

模型插补

数据用于机器学习,而机器学习同样可以用于数据填补。
!如果我们以缺失数据的列作为目标变量,以完整数据的现有列作为预测变量,那么我们可以以完整记录作为训练和测试数据集,以不完整数据的记录作为泛化目标,构建一个机器学习模型。这是一个完全确定的机器学习问题。

用Linear Regression做该数据的插补:

# Format the data for applying ML to it.
popular_beer_styles = (pd.get_dummies(df['Style']).sum(axis='rows') > (len(df) / 100)).where(lambda v: v).dropna().index.values

dfc = (df
       .drop(['PrimingMethod', 'PrimingAmount', 'UserId', 'PitchRate', 'PrimaryTemp', 'StyleID', 'Name', 'URL'], axis='columns')
       .dropna(subset=['BoilGravity'])
       .pipe(lambda df: df.join(pd.get_dummies(df['BrewMethod'], prefix='BrewMethod')))
       .pipe(lambda df: df.join(pd.get_dummies(df['SugarScale'], prefix='SugarScale')))       
       .pipe(lambda df: df.assign(Style=df['Style'].map(lambda s: s if s in popular_beer_styles else 'Other')))
       .pipe(lambda df: df.join(pd.get_dummies(df['Style'], prefix='Style')))       
       .drop(['BrewMethod', 'SugarScale', 'Style'], axis='columns')
      )

c = [c for c in dfc.columns if c != 'MashThickness']
X = dfc[dfc['MashThickness'].notnull()].loc[:, c].values
y = dfc[dfc['MashThickness'].notnull()]['MashThickness'].values
yy = dfc[dfc['MashThickness'].isnull()]['MashThickness'].values

# Apply a regression approach to imputing the mash thickness.
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import KFold
from sklearn.metrics import r2_score

import numpy as np
np.random.seed(42)
kf = KFold(n_splits=4)
scores = []
for train_index, test_index in kf.split(X):
    X_train, X_test = X[train_index], X[test_index]
    y_train, y_test = y[train_index], y[test_index]
    
    clf = LinearRegression()
    clf.fit(X_train, y_train)
    y_test_pred = clf.predict(X_test)
    
    scores.append(r2_score(y_test, y_test_pred))

print(scores)

[0.012942533393265787, 0.009359944248067964, 0.00924054218885928, -0.00039579117668386843]

其中r2_score是一个可以评价Linear Regression较baseline的拟合效果的评价指标,其绝对值约接近于0代表拟合效果更好。

Maximum Likelihood Estimator(MLE)

简单的方法容易实现,但可能导致高偏差。模型imputation方法更有挑战性,但它仍然是现成的,它在向数据集引入偏差方面仍然存在问题。

在统计学中,Maximum Likelihood Estimator是对感兴趣的分布的任何统计估计器,其特性是使该数据的“似然函数”最大化。

回想一下,统计估计值取随机样本数据,并试图通过从样本中一般化来解释总体分布。例如,∑(y)/len(y)是一组数据y平均值的估计值。它是MLE,因为它没有任何偏差:它收敛于分布的真实均值(给定足够多的样本)。对于大多数问题,MLE估计器是构建最简单的估计器。但有时MLE估计器是不可能的,在其他情况下,估计器中的一些偏差是有用的(如果你知道一些模型不知道的东西;见如正则化)。

最大似然估计是对缺失数据进行的最大似然估计。首先,用数据集中的完整记录作为预测变量,用包含缺失值的变量作为目标,构建一个最大似然估计器。然后,对于每个包含缺失数据的记录,从您生成的分布中提取一个值,该值使用数据的已知依赖值进行参数化。

这种解决这个问题的纯统计方法在更普遍的情况下具有统计模型的缺点,因为它依赖于你在估计器中使用的概率分布。如果你期望数据是正态分布,你可能会拟合一个正态分布的数据。如果是伯努利分布,你可以拟合伯努利分布。

MultiImpute - fancyimpute

上述讨论的插补都是"SimpleImpute",而Impute可以用Multiple Impute的思路,融合多个插补器达到更好的Impute效果。
其中一个广泛使用的方法称为MICE,以下是它的执行方法:

fancyimpute

fancyimpute是一个可以用于插补的库,包含了均值,众数,KNN,Iterative,MICE等多种插补方法。

from fancyimpute import KNN, NuclearNormMinimization, SoftImpute, BiScaler

# X is the complete data matrix
# X_incomplete has the same values as X except a subset have been replace with NaN

# Use 3 nearest rows which have a feature to fill in each row's missing features
X_filled_knn = KNN(k=3).fit_transform(X_incomplete)

# matrix completion using convex optimization to find low-rank solution
# that still matches observed values. Slow!
X_filled_nnm = NuclearNormMinimization().fit_transform(X_incomplete)

# Instead of solving the nuclear norm objective directly, instead
# induce sparsity using singular value thresholding
X_incomplete_normalized = BiScaler().fit_transform(X_incomplete)
X_filled_softimpute = SoftImpute().fit_transform(X_incomplete_normalized)

# print mean squared error for the  imputation methods above
nnm_mse = ((X_filled_nnm[missing_mask] - X[missing_mask]) ** 2).mean()
print("Nuclear norm minimization MSE: %f" % nnm_mse)

softImpute_mse = ((X_filled_softimpute[missing_mask] - X[missing_mask]) ** 2).mean()
print("SoftImpute MSE: %f" % softImpute_mse)

knn_mse = ((X_filled_knn[missing_mask] - X[missing_mask]) ** 2).mean()
print("knnImpute MSE: %f" % knn_mse)

标签:处理,df,MashThickness,test,import,数据,缺失
来源: https://www.cnblogs.com/Asp1rant/p/16372310.html