zoukankan      html  css  js  c++  java
  • python学习13之数据泄密

      在本教程中,您将了解什么是数据泄漏以及如何防止数据泄漏。如果你不知道如何防止它,泄漏将经常出现,它将破坏您的模型在微妙和危险的方式。因此,对于实践数据科学家来说,这是最重要的概念之一。

      1、摘要

        数据泄漏(或泄漏)发生在您的训练数据包含关于目标的信息时,但是当使用模型进行预测时,将无法获得类似的数据。

        这将导致训练集上的高性能(甚至可能是验证数据),但是模型在生产中表现很差。

        换句话说,泄漏导致模型看起来很精确,直到您开始使用模型做出决策,然后模型变得非常不准确。

          泄漏主要有两种类型:

            target leakage 和 train-test contamination.

      2、两种泄密类型

        1)、目标泄漏

          当预测器包含在进行预测时不可用的数据时,就会发生目标泄漏。

          从数据可用的时间或时间顺序来考虑目标泄漏是很重要的,而不仅仅是某个特性是否有助于做出良好的预测。

          举个例子会很有帮助。假设您想要预测谁会感染肺炎。

            原始数据的前几行是这样的:

            

          人们在患肺炎后服用抗生素药物是为了恢复健康。

          原始数据显示这些列之间有很强的关系,但是在确定got_pneumonia的值之后,took_antibiotic_medicine经常被更改。

          这是目标泄漏。该模型将看到,任何对took_tic_medicine值为False的人都没有患肺炎。

          由于验证数据与培训数据来自同一个源,因此模式将在验证中重复,并且模型将具有良好的验证(或交叉验证)得分。

          但这个模型在随后的实际应用中会非常不准确,因为即使是肺炎患者,在我们需要对他们未来的健康状况做出预测时,他们也不会使用抗生素。

          为了防止这种类型的数据泄漏,应该排除在实现目标值之后更新(或创建)的任何变量。

        2)、train-test contamination

          当我们不小心将培训数据与验证数据区分开来时,就会发生另一种类型的泄漏。

          回想一下,验证意味着度量模型如何处理它以前没有考虑过的数据。如果验证数据影响预处理行为,则可以以微妙的方式破坏此过程。

          这有时被称为train-test contamination。

          例如,假设在调用train_test_split()之前运行预处理(比如为缺失的值拟合一个灌输器)。

          最终的结果可能是我们的模型可能得到很好的验证分数,这给了您很大的信心,但是当您部署它来做决策时,它的性能很差。

          毕竟,我们将来自验证或测试数据的数据合并到如何进行预测中,所以即使不能泛化到新数据,也可以很好地处理特定的数据。

          当我们进行更复杂的特性工程时,这个问题会变得更加微妙(也更加危险)。如果您的验证基于简单的训练-测试分割,则将验证数据排除在任何类型的拟合之外,包括预处理步骤的拟合。

          如果我们使用scikit-learn管道,这将更加容易。在使用交叉验证时,在管道中进行预处理更为重要。

      3、举例说明

          在本例中,我们将学习一种检测和删除目标泄漏的方法。

          我们将使用一个关于信用卡应用程序的数据集,跳过基本的数据设置代码。最终的结果是,关于每个信用卡应用程序的信息存储在一个DataFrame x中。   

    import pandas as pd
    import csv
    
    data = pd.read_csv('E:/data_handle/AER_credit_card_data.csv',
                       true_values=['yes'],false_values=['no'])
    y = data.card
    
    X = data.drop(['card'], axis=1)
    
    print("Number of rows in the dataset:",X.shape[0],"
    ",X.head())

          接着我们开始进行验证处理,由于这是一个小数据集,我们将使用交叉验证来确保模型质量的准确度量。

    from sklearn.pipeline import make_pipeline
    from sklearn.ensemble import RandomForestClassifier
    from sklearn.model_selection import cross_val_score
    
    #由于没有预处理,所以我们不需要管道(无论如何,作为最佳实践使用!)
    my_pipeline = make_pipeline(RandomForestClassifier(n_estimators=100))
    cv_scores = cross_val_score(my_pipeline, X, y, cv=5, scoring= 'accuracy')
    print("Cross-validation accuracy: %f" % cv_scores.mean())

          有了经验,你会发现很难找到准确率高达98%的模型。

          这种情况时有发生,但我们应该更仔细地检查数据以发现目标泄漏的情况非常少见。

          这是一个汇总的数据,你也可以找到在数据选项卡:

            信用卡:接受信用卡申请1张,不接受0张

            报告:主要贬损性报告的数量

            年龄:n岁加12岁

            收入:年收入(除以10000)

            份额:每月信用卡支出与年收入之比

            支出:平均每月信用卡支出

            业主:1(如果拥有房产),0(如果出租)

            selfempl: 1(如果是个体经营者),0(如果不是)

            受养人:1 +受养人人数

            月份:住在当前地址的月份

            主卡:持有的主卡数量

            活跃的:活跃的信用帐户的数量

          有几个变量看起来可疑。

          例如,支出是指此卡上的支出还是应用前使用的卡上的支出?

            在这一点上,基本数据比较是非常有用的:
    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()))     

          如上图所示,没有收到卡片的人没有支出,而收到卡片的人中只有2%没有支出。

          我们的模型似乎有很高的精确度,这并不奇怪。  

          但这似乎也是目标泄漏的一个例子,其中支出可能意味着他们申请的卡上的支出。    

          由于份额部分由支出决定,因此也应排除在外。活动变量和主卡不太清楚,但是从描述来看,它们听起来令人担忧。

          在大多数情况下,如果您无法找到创建数据的人以了解更多信息,那么安全总比遗憾好。

          我们将运行一个没有目标泄漏的模型,如下所示:

    #从dataset中删除泄漏的预测器
    potential_leaks = ['expenditure', 'share', 'active', 'majorcards']
    X2 = X.drop(potential_leaks, axis= 1)
    #删除泄漏预测器后评估模型
    cv_scores = cross_val_score(my_pipeline, X2, y, cv=5, scoring='accuracy')
    print("Cross-val accuracy: %f" % cv_scores.mean())

          这个精度要低一些,这可能会令人失望。

          然而,在新应用程序中使用它时,我们可以期望它在80%的情况下是正确的,而泄漏模型可能会做得比这糟糕得多(尽管它在交叉验证中明显得分更高)。

       4、总结

        在许多数据科学应用中,数据泄漏可能是数百万美元的错误。

        仔细分离培训和验证数据可以防止培训测试污染,管道可以帮助实现这种分离。

        同样,结合谨慎、常识和数据探索可以帮助识别目标泄漏。

      5、代码总结

        

    import pandas as pd
    
    from sklearn.pipeline import make_pipeline
    from sklearn.ensemble import RandomForestClassifier
    from sklearn.model_selection import cross_val_score
    
    data = pd.read_csv('E:/data_handle/AER_credit_card_data.csv',
                       true_values=['yes'],false_values=['no'])
    y = data.card
    
    X = data.drop(['card'], axis=1)
    
    print("Number of rows in the dataset:",X.shape[0],"
    ",X.head())
    
    #由于没有预处理,所以我们不需要管道(无论如何,作为最佳实践使用!)
    my_pipeline = make_pipeline(RandomForestClassifier(n_estimators=100))
    cv_scores = cross_val_score(my_pipeline, X, y, cv=5, scoring= 'accuracy')
    print("Cross-validation accuracy: %f" % cv_scores.mean())
    
    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()))
    
    #从dataset中删除泄漏的预测器
    potential_leaks = ['expenditure', 'share', 'active', 'majorcards']
    X2 = X.drop(potential_leaks, axis= 1)
    #删除泄漏预测器后评估模型
    cv_scores = cross_val_score(my_pipeline, X2, y, cv=5, scoring='accuracy')
    print("Cross-val accuracy: %f" % cv_scores.mean())

        本次得学习还是缺少很多理解,只是看了个大概,很多东西都不是很懂,还需要继续研究、理解,这些内容都会都很多的变动的。

    本次学习到此结束!!!!!

  • 相关阅读:
    MFC 监控界面上所有文本框值的变化
    VC遍历窗体控件的实现
    VC关于置顶窗口的方法小结
    查看linux系统版本命令
    windows下maven打包eclipse工程
    Java多线程-一个简单的线程,实现挂起和恢复的功能
    maven常用操作
    eclipse调试java技巧
    Linux下报 java.net.SocketException权限不够 异常解决
    体验vSphere 6之1-安装VMware ESXi 6 RC版(转载)
  • 原文地址:https://www.cnblogs.com/fb1704011013/p/11203906.html
Copyright © 2011-2022 走看看