Kaggle学习笔记--data leakage

Kaggle学习笔记--data leakage

  • 简介
    • 在本教程中,您将学习什么是数据泄漏以及如何防止数据泄漏
    • 目标泄漏——预测变量包含不可用数据
    • 训练-测试污染
  • 数据准备
  • 结论

原文:https://www.kaggle.com/alexisbcook/data-leakage

简介

在本教程中,您将学习什么是数据泄漏以及如何防止数据泄漏

如果您不知道如何预防,则会经常出现泄漏,并且会以微妙而危险的方式破坏模型。
数据泄露会导致模型在训练时高性能,使得结果准确;而在预测时变得效果很差。
泄漏有两种主要类型:【target leakage 】目标泄漏和【train-test contamination】训练-测试污染。

目标泄漏——预测变量包含不可用数据

1.要根据数据可用的时间顺序或时间顺序来考虑目标泄漏,而不仅仅是功能是否有助于做出良好的预测。
2.为防止目标泄漏,应排除在实现目标值后更新(或创建)的任何变量。

训练-测试污染

当您不小心将训练数据与验证数据区分开时,会发生另一种类型的泄漏——【train-test contamination】。验证【validation】是用来衡量模型如何处理之前未考虑过的数据。如果验证数据影响预处理行为,则可以用微妙的方式破坏此过程。如在调用train_test_split()之前进行了预处理(填补了缺失值)。最终结果是模型可能会获得良好的验证评分,但是在调用模型进行决策时却表现不佳。

如果您的验证是基于简单的train-test split,则将验证数据排除在任何类型的拟合中,包括预处理步骤的拟合。如果使用scikit-learn管道,这会更容易。使用交叉验证时,在管道内进行预处理就显得尤为重要!当您不小心区分训练数据和验证数据时,会发生不同类型的泄漏。

数据准备

在此示例中,将介绍一种检测和消除目标泄漏的方法。
1.使用有关信用卡申请的数据集来预测y系列接受了哪些应用程序。
2.由于这是一个很小的数据集,因此我们将使用交叉验证来确保模型质量的准确度量。

import pandas as pd
# Read the data
data = pd.read_csv('C:/Users/Administrator/Desktop/home-data-for-ml-course/AER_credit_card_data.csv',
                   true_values = ['yes'], false_values = ['no'])
# Select target
y = data.card
# Select predictors
X = data.drop(['card'], axis=1)
print("Number of rows in the dataset:", X.shape[0])
print(X.head())

Number of rows in the dataset: 1319

from sklearn.pipeline import make_pipeline
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score

'''
from sklearn.pipeline import Pipeline
my_pipeline = Pipeline(steps=[
    ('preprocessor', SimpleImputer()),
    ('model', RandomForestRegressor(n_estimators=50, random_state=0))
])
'''
# Since there is no preprocessing, we don't need a pipeline (used anyway as best practice!)
my_pipeline = make_pipeline(RandomForestClassifier(n_estimators=100))
#在交叉验证中使用管道。使用[`cross_val_score()`]函数来获取平均绝对误差(MAE),该平均误差在五个不同的折叠中平均。 使用`cv`参数设置了折数。
cv_scores = cross_val_score(my_pipeline, X, y,
                            cv=5,
                            scoring='accuracy')

print("Cross-validation accuracy: %f" % cv_scores.mean())

Cross-validation accuracy: 0.981052

有了经验,您会发现很少有98%的时间都能找到准确的模型。
它确实发生了,但是我们应该更仔细地检查数据是否存在目标泄漏
以下是数据摘要,您也可以在“数据”标签【data tab】下找到该数据:
card: 1 if credit card application accepted, 0 if not
reports: Number of major derogatory reports
age: Age n years plus twelfths of a year
income: Yearly income (divided by 10,000)
share: Ratio of monthly credit card expenditure to yearly income
expenditure: Average monthly credit card expenditure
owner: 1 if owns home, 0 if rents
selfempl: 1 if self-employed, 0 if not
dependents: 1 + number of dependents
months: Months living at current address
majorcards: Number of major credit cards held
active: Number of active credit accounts

卡:如果接受信用卡申请则为1,否则为0
报告:主要贬损报告的数量
年龄:年龄n岁加上一年的十二分之一
收入:年收入(除以10,000)
份额:每月信用卡支出与年收入的比率
支出:信用卡平均每月支出
业主:如果拥有房屋,则为1;如果租金,则为0
selfempl:如果是自雇人士,则为1;如果不是,则为0
受抚养人:1 +受抚养人数量
月:居住在当前地址的月份
majorcards:持有的主要信用卡数
活跃:活跃的信用账户数量

一些变量看起来很可疑。 例如,支出是否表示此卡或在申请前使用的卡上的支出?此时,基本数据比较可能会非常有帮助:

#输出有卡的支出字段的值  y = data.card
expenditures_cardholders = X.expenditure[y]
#无卡的支出字段的值
expenditures_noncardholders = X.expenditure[~y]
print('Fraction of those who did not receive a card and had no expenditures: %.2f' \
      %((expenditures_noncardholders == 0).mean()))

print('Fraction of those who received a card and had no expenditures: %.2f' \
      %(( expenditures_cardholders == 0).mean()))


Fraction of those who did not receive a card and had no expenditures: 1.00
Fraction of those who received a card and had no expenditures: 0.02

如上所示,每个未收到卡的人都没有支出,而只有2%的收到卡的人没有支出。
我们的模型似乎具有很高的准确性也就不足为奇了。 但这似乎也是目标泄漏的一种情况,
1.其中支出可能意味着他们申请的卡上的支出。
2.由于份额部分由支出决定,因此也应将其排除在外。
3.变量active和majorcard不太清楚,但是从描述中看,它们令人担忧。
在大多数情况下,如果您无法追踪创建数据的人员来查找更多信息,则最好不要感到遗憾。
我们将运行一个没有目标泄漏的模型,如下所示:

# Drop leaky predictors from dataset
potential_leaks = ['expenditure', 'share', 'active', 'majorcards','dependents']
X2 = X.drop(potential_leaks, axis=1)

# Evaluate the model with leaky predictors removed
cv_scores = cross_val_score(my_pipeline, X2, y,
                            cv=5,
                            scoring='accuracy')

print("Cross-val accuracy: %f" % cv_scores.mean())

Cross-val accuracy: 0.834716

由上可见此时交叉检验的准确性为83%左右,比起上面98%的正确率要低很多,但是,在应用于新模型时,它的表现会更好。

结论

在许多数据科学应用中,数据泄漏可能导致巨大的损失。
仔细分离训练和验证数据可以防止训练测试污染,管道可以帮助实现这种分离。 同样,谨慎、常识和数据探索相结合可以帮助识别目标泄漏。

你可能感兴趣的:(Kaggle学习笔记--data leakage)