Kaggle:Home Credit Default Risk 特征工程构建及可视化(2)

博主在以前的博客 Kaggle:Home Credit Default Risk 数据探索及可视化(1) 中介绍了 Home Credit Default Risk 竞赛中一个优秀 kernel 关于数据的探索及可视化的工做,本篇博客将围绕如何构建特征工程展开叙述,原文连接地址:Start Here: A Gentle Introductionhtml

 

1 简介

    特征工程是指一个基因过程,能够涉及特征构建:从现有数据中添加新特征和特征选择:仅选择最重要的特征或其余降维方法。咱们可使用许多技术来建立特征和选择特征。
    当咱们开始使用其余数据源时,咱们会作不少功能工程,本次,咱们只会尝试两种简单的功能构建方法:git

  • 多项式特征
  • 领域知识功能

2 特征工程构建

2.1 多项式特征

    一个简单的特征构造方法称为多项式特征。例如,咱们能够建立变量EXT_SOURCE_1 ^ 2和EXT_SOURCE_2 ^ 2以及变量,例如EXT_SOURCE_1 x EXT_SOURCE_2,EXT_SOURCE_1 x EXT_SOURCE_2 ^ 2,EXT_SOURCE_1 ^ 2 x EXT_SOURCE_2 ^ 2等等。这些由多个单独变量组合而成的特征被称为交互项,由于它们捕捉变量之间的交互做用。换句话说,虽然两个变量自己可能不会对目标产生强烈的影响,但将它们组合成单个交互变量可能会显示与目标的关系。统计模型中一般使用交互项来捕捉多个变量的影响,但我没有看到它们在机器学习中常常使用。尽管如此,咱们能够尝试一些看看他们是否能够帮助咱们的模型预测客户是否会偿还贷款。
       Jake VanderPlas 在他的优秀着做 Python for Data Science 中为那些想要了解更多信息的人写了多项式特征。github

    在下面的代码中,咱们使用EXT_SOURCE变量和DAYS_BIRTH变量建立多项式特征。Scikit-Learn有一个称为PolynomialFeatures 的有用类,能够建立多项式和交互项达到指定的程度。咱们可使用3度来查看结果(当咱们建立多项式特征时,咱们但愿避免使用太高的度数,这是由于特征的数量随着度数指数级地变化,而且由于咱们可能遇到问题过拟合)。app

 
  1. # Make a new dataframe for polynomial features框架

  2. poly_features = app_train[['EXT_SOURCE_1', 'EXT_SOURCE_2', 'EXT_SOURCE_3', 'DAYS_BIRTH', 'TARGET']]dom

  3. poly_features_test = app_test[['EXT_SOURCE_1', 'EXT_SOURCE_2', 'EXT_SOURCE_3', 'DAYS_BIRTH']]机器学习

  4.  
  5. # imputer for handling missing values学习

  6. from sklearn.preprocessing import Imputer测试

  7. imputer = Imputer(strategy = 'median')ui

  8.  
  9. poly_target = poly_features['TARGET']

  10.  
  11. poly_features = poly_features.drop(columns = ['TARGET'])

  12.  
  13. # Need to impute missing values

  14. poly_features = imputer.fit_transform(poly_features)

  15. poly_features_test = imputer.transform(poly_features_test)

  16.  
  17. from sklearn.preprocessing import PolynomialFeatures

  18.  
  19. # Create the polynomial object with specified degree

  20. poly_transformer = PolynomialFeatures(degree = 3)

 
  1. # Train the polynomial features

  2. poly_transformer.fit(poly_features)

  3.  
  4. # Transform the features

  5. poly_features = poly_transformer.transform(poly_features)

  6. poly_features_test = poly_transformer.transform(poly_features_test)

  7. print('Polynomial Features shape: ', poly_features.shape)

这创造了至关多的新功能。 要获取名称,咱们必须使用多项式特性 get_feature_names 方法。

poly_transformer.get_feature_names(input_features = ['EXT_SOURCE_1', 'EXT_SOURCE_2', 'EXT_SOURCE_3', 'DAYS_BIRTH'])[:15]

有35个功能提高到3级和互动条件。 如今,咱们能够看到这些新功能是否与目标相关。

 
  1. # Create a dataframe of the features

  2. poly_features = pd.DataFrame(poly_features,

  3. columns = poly_transformer.get_feature_names(['EXT_SOURCE_1', 'EXT_SOURCE_2',

  4. 'EXT_SOURCE_3', 'DAYS_BIRTH']))

  5.  
  6. # Add in the target

  7. poly_features['TARGET'] = poly_target

  8.  
  9. # Find the correlations with the target

  10. poly_corrs = poly_features.corr()['TARGET'].sort_values()

  11.  
  12. # Display most negative and most positive

  13. print(poly_corrs.head(10))

  14. print(poly_corrs.tail(5))

下图是原始特征相关性系数排序图:

    与原始特征相比,几个新变量与目标的相关性更大(以绝对幅度表示)。 当咱们构建机器学习模型时,咱们能够尝试使用和不使用这些功能来肯定它们是否真的有助于模型学习。

    咱们将这些功能添加到培训和测试数据的副本中,而后评估具备和不具备功能的模型。 不少次机器学习,要知道一种方法是否可行,惟一的方法就是尝试一下!

 
  1. # Put test features into dataframe

  2. poly_features_test = pd.DataFrame(poly_features_test,

  3. columns = poly_transformer.get_feature_names(['EXT_SOURCE_1', 'EXT_SOURCE_2',

  4. 'EXT_SOURCE_3', 'DAYS_BIRTH']))

  5.  
  6. # Merge polynomial features into training dataframe

  7. poly_features['SK_ID_CURR'] = app_train['SK_ID_CURR']

  8. app_train_poly = app_train.merge(poly_features, on = 'SK_ID_CURR', how = 'left')

  9.  
  10. # Merge polnomial features into testing dataframe

  11. poly_features_test['SK_ID_CURR'] = app_test['SK_ID_CURR']

  12. app_test_poly = app_test.merge(poly_features_test, on = 'SK_ID_CURR', how = 'left')

  13.  
  14. # Align the dataframes

  15. app_train_poly, app_test_poly = app_train_poly.align(app_test_poly, join = 'inner', axis = 1)

  16.  
  17. # Print out the new shapes

  18. print('Training data with polynomial features shape: ', app_train_poly.shape)

  19. print('Testing data with polynomial features shape: ', app_test_poly.shape)

2.2 领域知识特征

    也许把这种“领域知识”称为不彻底正确,由于我不是信用专家,但也许咱们能够称之为“尝试应用有限的金融知识”。 在这种思惟框架下,咱们能够制做一些功能,试图捕捉咱们认为可能对于客户是否违约的贷款很重要。 在这里我将使用由 Aguiar 的这个脚本启发的五个特性:
 

  • CREDIT_INCOME_PERCENT:信贷金额相对于客户收入的百分比
  • ANNUITY_INCOME_PERCENT:贷款年金相对于客户收入的百分比
  • CREDIT_TERM:以月为单位的付款期限(由于年金是应付的每个月金额
  • DAYS_EMPLOYED_PERCENT:相对于客户年龄所用天数的百分比
 
  1. app_train_domain = app_train.copy()

  2. app_test_domain = app_test.copy()

  3.  
  4. app_train_domain['CREDIT_INCOME_PERCENT'] = app_train_domain['AMT_CREDIT'] / app_train_domain['AMT_INCOME_TOTAL']

  5. app_train_domain['ANNUITY_INCOME_PERCENT'] = app_train_domain['AMT_ANNUITY'] / app_train_domain['AMT_INCOME_TOTAL']

  6. app_train_domain['CREDIT_TERM'] = app_train_domain['AMT_ANNUITY'] / app_train_domain['AMT_CREDIT']

  7. app_train_domain['DAYS_EMPLOYED_PERCENT'] = app_train_domain['DAYS_EMPLOYED'] / app_train_domain['DAYS_BIRTH']

 
  1. app_test_domain['CREDIT_INCOME_PERCENT'] = app_test_domain['AMT_CREDIT'] / app_test_domain['AMT_INCOME_TOTAL']

  2. app_test_domain['ANNUITY_INCOME_PERCENT'] = app_test_domain['AMT_ANNUITY'] / app_test_domain['AMT_INCOME_TOTAL']

  3. app_test_domain['CREDIT_TERM'] = app_test_domain['AMT_ANNUITY'] / app_test_domain['AMT_CREDIT']

  4. app_test_domain['DAYS_EMPLOYED_PERCENT'] = app_test_domain['DAYS_EMPLOYED'] / app_test_domain['DAYS_BIRTH']

3 特征工程可视化

    咱们应该在图形中直观地探索这些领域知识变量。 对于全部这些,咱们将制做与目标值相同的 KDE 图(核密度估计图)。

 
  1. plt.figure(figsize = (12, 20))

  2. # iterate through the new features

  3. for i, feature in enumerate(['CREDIT_INCOME_PERCENT', 'ANNUITY_INCOME_PERCENT', 'CREDIT_TERM', 'DAYS_EMPLOYED_PERCENT']):

  4.  
  5. # create a new subplot for each source

  6. plt.subplot(4, 1, i + 1)

  7. # plot repaid loans

  8. sns.kdeplot(app_train_domain.loc[app_train_domain['TARGET'] == 0, feature], label = 'target == 0')

  9. # plot loans that were not repaid

  10. sns.kdeplot(app_train_domain.loc[app_train_domain['TARGET'] == 1, feature], label = 'target == 1')

  11.  
  12. # Label the plots

  13. plt.title('Distribution of %s by Target Value' % source)

  14. plt.xlabel('%s' % source); plt.ylabel('Density');

  15.  
  16. plt.tight_layout(h_pad = 2.5)

相关文章
相关标签/搜索