在本文中,咱们将回顾个性抉择技术并答复为什么它很重要以及如何应用python实现它。
本文还能够帮忙你解答以下的面试问题:
- 什么是特征选择?
- 说出个性抉择的一些益处
- 你晓得哪些特征选择技巧?
- 辨别单变量、双变量和多变量剖析。
- 咱们能用PCA来进行特征选择吗?
- 前向特征选择和后向特征选择的区别是什么?
什么是特征选择,为什么它很重要?
个性抉择是抉择与ML模型更加统一、非冗余和更相干的根本个性的过程。在ML我的项目中应用个性抉择是必要的,因为:
- 它有助于缩小数据集的大小和复杂性,并且能够应用更少的工夫来训练模型及进行推理;
- 具备较少特色的简略机器学习模型更容易了解和解释;
- 它能够防止适度拟合。更多特色使模型变得更加简单,并带来维度劫难(误差随着特色数量的减少而减少)。
特征选择办法有哪些?
有两种常见的办法能够解决特征选择:
1、前向特征选择。应用一个特色(或一小部分)拟合模型并一直增加特色,直到新加的模型对ML 模型指标没有影响。能够应用相干剖析等办法(例如,基于 Pearson 系数),或者您能够从单个特色或特色子集开始拟合模型。
2、向后特征选择。这是 与1的相同办法。应用这种办法,能够从残缺的特色集开始,而后迭代地一一缩小性能,缩小特色的同时只有 ML 模型指标放弃不变即可。
咱们能够将一些风行的办法总结成以下几种分类:
- Filtered-based基于过滤的办法:这种办法是最间接的,这种特色的抉择独立于任何机器学习算法。应用统计数据(例如 Pearson 相关系数、LDA 等),依据每个特色如何影响指标后果来抉择重要特色。这是计算密集度最低且速度最快的办法。
- Wrapper 基于包装器办法:这种办法依据 ML 训练指标后果抉择特色。每个子集在训练后失去一个分数,而后增加或删除特色,并在最终在达到所需的 ML 指标阈值时进行,这种办法能够是前向、后向或递归的。这是计算最密集的办法,因为须要训练许多 ML 模型,并且逐个进行判断抉择。
- Embedded 基于嵌入的办法:这种办法更加简单,它将下面两种办法组合在一起。这种办法最风行的例子是 LASSO 和树型算法。
应用Python进行特征选择
本文将应用一个金融科技数据集,该数据集蕴含过来贷款申请人的数据,如信用等级、申请人支出、DTI和其余特色。最初的指标是应用ML预测贷款申请人是否可能守约(无奈领取贷款)。这有助于企业做出决策,例如回绝贷款申请、缩小贷款金额或以更高的利率向危险较高的申请人放贷。我用来运行代码的环境是Kaggle。
让咱们开始并加载数据集:
%matplotlib inline from matplotlib import pyplot as plt pd.set_option('display.float_format', lambda x: '%.0f' % x) loan = pd.read_csv('../input/lending-club/accepted_2007_to_2018Q4.csv.gz', compression='gzip', low_memory=True) loan.info
数据集蕴含超过200万行(咱们称之为样本)和超过150个特色。这是相当大的数据量,这些数据通常蕴含了很多“噪声”它对咱们的ML工作没有任何的帮忙,因而咱们须要在ML训练产生之前验证数据的品质和适用性。
第一步:取得业余的畛域常识
对如此详尽的特色列表进行剖析可能须要大量的计算资源和工夫。所以咱们须要具体理解每个数据集的属性。
征询并询问行业的专家哪些特色是必要的;例如,在金融科技数据集的例子中可能须要征询每天执行贷款评估的信贷员。信贷员将确切地晓得是什么驱动了他们的决策过程(咱们其实是心愿将这部分过程通过ML实现自动化)。
假如咱们已失去了以下倡议(请参阅上面的代码片段)。尽管咱们应该对这些倡议放弃审慎,但它为咱们开始初步工作提供了一个很好的根底,咱们能够进一步改良。
loans = loan[['id', 'loan_amnt', 'term','int_rate', 'sub_grade', 'emp_length','grade', 'annual_inc', 'loan_status', 'dti', 'mths_since_recent_inq', 'revol_util', 'bc_open_to_buy', 'bc_util', 'num_op_rev_tl']] #remove missing values loans = loans.dropna()
花正当的工夫来了解数据集中每个特色的含意:
- loan_amnt -借款人申请贷款的清单金额。
- term -偿还贷款的次数,其中的值以月为单位,能够是36或60。
- int_rate -贷款的利率
- sub_grade -依据借款人的信用记录调配贷款等级分数
- emp_length -借款者的待业年限。
- home_ownership-借款人提供的屋宇所有权情况(例如,租金、所有权、抵押贷款等)
- annual_inc -借款人提供的自我报告的年收入
- addr_state-借款人在贷款申请中提供的状态
- dti -用借款人每月偿还的债权总额(不包含按揭)除以借款人每月支出计算的比率。
- mths_since_recent_inq-最近一次查问的月份
- revol_util - 循环额度利用率,或借款人应用的信贷金额绝对于所有可用的循环信贷。
- bc_open_to_buy - 银行卡的总凋谢购买量
- bc_util - 所有银行卡账户的总流动余额与高信用/信用限额的比率
- num_op_rev_tl - 开户数
- loan_status - 以后贷款状态(例如,齐全领取或登记)。这就是咱们要用模型预测的标签。
在进行下一步工作之前,须要先执行数据处理步骤。步骤包含缺失值、异样值和分类特色解决。
loans = loans.dropna() q_low = loans["annual_inc"].quantile(0.08) q_hi = loans["annual_inc"].quantile(0.92) loans = loans[(loans["annual_inc"] < q_hi) & (loans["annual_inc"] > q_low)] loans = loans[(loans['dti'] <=45)] q_hi = loans['bc_open_to_buy'].quantile(0.95) loans = loans[(loans['bc_open_to_buy'] < q_hi)] loans = loans[(loans['bc_util'] <=160)] loans = loans[(loans['revol_util'] <=150)] loans = loans[(loans['num_op_rev_tl'] <=35)] cleaner_app_type = {"term": {" 36 months": 1.0, " 60 months": 2.0}, "sub_grade": {"A1": 1.0, "A2": 2.0, "A3": 3.0, "A4": 4.0, "A5": 5.0, "B1": 11.0, "B2": 12.0, "B3": 13.0, "B4": 14.0, "B5": 15.0, "C1": 21.0, "C2": 22.0, "C3": 23.0, "C4": 24.0, "C5": 25.0, "D1": 31.0, "D2": 32.0, "D3": 33.0, "D4": 34.0, "D5": 35.0, "E1": 41.0, "E2": 42.0, "E3": 43.0, "E4": 44.0, "E5": 45.0, "F1": 51.0, "F2": 52.0, "F3": 53.0, "F4": 54.0, "F5": 55.0, "G1": 61.0, "G2": 62.0, "G3": 63.0, "G4": 64.0, "G5": 65.0, }, "emp_length": {"< 1 year": 0.0, '1 year': 1.0, '2 years': 2.0, '3 years': 3.0, '4 years': 4.0, '5 years': 5.0, '6 years': 6.0, '7 years': 7.0, '8 years': 8.0, '9 years': 9.0, '10+ years': 10.0 } } loans = loans.replace(cleaner_app_type)
在预选特色之后,下一步是进行单变量剖析。剖析单个特色时能够应用的最常见的两种技术:1)删除低方差(超过90%)的特色;2)删除有大量缺失值的特色。
低方差:假如有两个特色,1)性别只蕴含一个性别值(例如,女性),2)年龄蕴含30到50岁之间的不同值。在这种状况下,性别特色的方差很小,因为这个属性中的值都是雷同的,在模型训练时,它不会帮忙模型找到任何模式;因而咱们能够间接删除这个特色。
这种形式得实现非常简单,能够应用sklearn得VarianceThreshold函数。上面的代码将辨认那些在至多90%的实例中雷同的个性。
from sklearn.feature_selection import VarianceThreshold variance = VarianceThreshold(threshold = (.9 * (1 - .9))) variance.fit(loans) variance.get_support()
能够看到在咱们的案例中没有低方差的特色,所以不须要删除。
缺失值:在这组特色中没有任何蕴含大量缺失值的特色;因而,咱们将跳过这一步。以前咱们也发过解决缺失值的文章,如果你对这部分感兴趣,能够搜寻查看。
第二步:辨认高度相干的特色
第二步是辨认特色的多重共线性。咱们应用双变量剖析来找出两组变量之间是否有关系(相干)。
利用这些相关性,你能够失去以下的论断:
- 一个或多个变量依赖于另一个变量,可能导致多重共线性;
- 相关性能够帮忙预测一个变量与另一个变量的关系,表明存在因果关系;
- 在业务层面上能够理解标签后果的因素,在咱们的例子中理解每个个性如何影响贷款领取后果
当数据集的特色之间具备高度的正相干或负相关时,ML模型可能会受到多重共线性的影响。高度相干的特色可能提供雷同的信息。在这种状况下可能会导致扭曲或误导的后果,为了解决这个问题,咱们能够只保留一个特色,删除多余的特色,这样是不失落任何信息的。
比方月薪和年薪;尽管它们可能不一样,但它们可能有雷同的模式。像逻辑回归和线性回归这样的模型对这个问题很敏感,如果用这样的冗余特色训练模型,可能会产生误导的后果。因而咱们应该以打消其中一个为指标。
留神:决策树和加强树等算法不受多重共线性的影响。
如何解决多重共线性?
有很多办法能够解决它。检测高度相干特色的最简略办法是应用 Pearson 相关系数并删除非常(~90%)相干特色。主成分剖析(PCA)也能够用作降维算法。它通常用于降维,它将每个数据点仅投影到前几个主成分上取得低维数据的同时尽可能多地保留数据的变动。
这里咱们应用pandas_profiling来进行剖析
from pandas_profiling import ProfileReport profile = ProfileReport (loans, title = 'Loans Defaults Prediction', html = {'style': {'full_width': True }}) profile
你会发现Pearson和Phik之间不同类型的相关性。当数据中蕴含未解决的分类个性时,Phik是十分好用的。例如,上面的“grade”分类特色,它在相关矩阵上绘制得很好:
如何了解相关矩阵:相关性范畴从+1到-1,其中:
- 零相干示意变量之间没有关系;
- 相关性为-1示意齐全负相关,这意味着当一个变量上升时,另一个变量降落;
- 相关性为+1示意齐全正相干,这意味着两个变量一起朝同一个方向挪动。
上图能够察看到以下高度相干的特色:
- 客户信息相干的特色:bc_open_to_buy / num_op_rev_tl。这两个特色都与循环账户和银行卡无关,因而它们高度相干。为了防止多协同问题,去掉初始模型中的bc_open_to_buy个性。revol_util / bc_util。也是一个相似的状况,能够删除bc_util个性。
- 贷款信息个性:Int_rate和grade是基于借贷专有模型的sub_grade的衍生品;因而它们是高度相干的;咱们把这些删除。这里的sub_grade和loan_amount也是相干的,但关联度较低,能够保留它们。
loans.drop(["bc_util", "bc_open_to_buy","int_rate", "grade"], axis = 1, inplace = True)
第三步:找出特色与指标变量之间的相关性
咱们心愿可能找到与指标变量(在本例中为loan_status)高度相干的个性。这里将回顾下面介绍的两种风行的办法:
基于过滤的办法
相关矩阵能够帮忙咱们辨认高度相干的特色。pandas_profiling生成剖析报告可能须要工夫,因而理解绘制相关矩阵的其余技术是必要的。上面是两种可选办法:
应用pandas自带的corr函数
loans_cor=loan.corr() loans_cor
应用seaborn热点图
import seaborn as sns import matplotlib.pyplot as plt %matplotlib inline plt.figure(figsize=(10,6)) sns.heatmap(loans_cor, annot=True)
咱们能够察看到以下高度相干的特色:sub_grade, term, loan_amnt, dti, emp_length, annual_inc与loan_status。这能够让咱们晓得哪些个性是重要的。
包装器办法
包装器的办法是一种抉择特色的更自动化的形式,咱们将应用内置函数 SequentialFeatureSelector()实现前向抉择,该函数是 mlxtend 库的一部分。此函数具备不同的特征选择技术。
SequentialFeatureSelector() 有 11 个参数,您能够调整这些参数以获得最佳后果。咱们这里将调整以下参数:
- Estimator——外围应用的算法;在这个们的例子中将应用 LogisticRegression() 算法;
- k_features — 心愿算法抉择为最佳特色的特色数(默认为 1)。它应该小于数据集的所有特色数总和。mlxtend 包还提供了“best”参数,其中选择器返回最佳穿插验证性能。因而,与其猜想须要返回多少特色,不如利用“best”;
- Forward 和 floating 参数来标识包装器办法:例如,对于咱们的前向抉择,它将是forward = True,而floating = False;
- Scoring :指定了评估规范:应用 sklearn 评分指标“precision”。对于分类器,因为数据集是不均衡的。咱们还能够应用 f1、precision、recall、roc_auc 等用于分类工作的指标和 r2 、mean_absolute_error、mean_squared_error/neg_mean_squared_error、median_absolute_error 用于回归工作的指标;
- cv——穿插验证,默认为5。
当初让咱们将下面定义的特色选择器利用到的数据集中。
对于给定的数据将尝试一个十分常见的算法-逻辑回归序列特色选择器。Loan_status将被用作预测的标签以查找预测的依赖项:
from sklearn.model_selection import train_test_split, RandomizedSearchCV from sklearn.linear_model import LogisticRegression from sklearn import metrics from sklearn.preprocessing import MinMaxScaler X = loans.drop('loan_status', axis=1) y = loans[['loan_status']] y = y.values.ravel() X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=42, stratify=y) scaler = MinMaxScaler() X_train = scaler.fit_transform(X_train) X_test = scaler.transform(X_test)
下一步是咱们将应用SequentialFeatureSelector来寻找“最佳”特色:
from mlxtend.feature_selection import SequentialFeatureSelector as SFS sfs = SFS(LogisticRegression(), k_features='best', forward=True, floating=False, scoring = 'precision', cv = 0)
将下面的特色选择器利用到咱们的数据:
sfs.fit(X, y) sfs.k_feature_names_
返回并查看ML工作应该应用的最佳个性:
通过比拟每个训练步骤中的性能和特色数量来理解抉择过程。还能够看到所抉择的模型度量在迭代步骤中不会产生很大的变动。
from mlxtend.plotting import plot_sequential_feature_selection as plot_sfs import matplotlib.pyplot as plt fig1 = plot_sfs(sfs.get_metric_dict(), kind='std_dev') plt.title('Sequential Forward Selection') plt.grid() plt.show()
能够看到不同特色的指标体现
总结
在本文中,咱们介绍了特征选择技术的基本原理,这对了解重要特色和后果变量之间的相关性是十分要害的。本篇文章的代码:https://avoid.overfit.cn/post/6f2a58732ffa42ba8dffa6db78c5ebc0
作者:Maria Gusarova