当前位置: 首页 > 后端技术 > Python

Python特征选择(全)

时间:2023-03-26 00:01:04 Python

1特征选择的目的特征选择是机器学习中筛选出显着特征,丢弃不显着特征的重要步骤。这样做的效果是:减少特征(避免维度灾难),提高训练速度,减少计算开销;降低干扰噪声,降低过拟合风险,提升模型效果;更少的特征,更好的模型可解释性;2特征选择方法特征选择方法一般分为三类:2.1过滤法-特征选择通过计算特征的缺失率、发散度、相关性、信息量、稳定性等指标对每个特征进行评价和选择,常用的如缺失、单值率、方差验证、皮尔逊相关系数、chi2卡方检验、IV值、信息增益和PSI等方法。2.1.1缺失率通过分析每个特征的缺失率,设置一个阈值来筛选特征。阈值可以根据经验值(如缺失率<0.9)或可观测样本各特征的总体分布,确定特征分布的异常值作为阈值。#特征缺失率miss_rate_df=df.isnull().sum().sort_values(ascending=False)/df.shape[0]2.1.2发散特征不发散是指特征值基本相同,没有区别能力。通过分析特征单值的最大比例和方差来评价特征的发散性,并设置阈值对特征进行过滤。阈值可以基于经验值(如单值率<0.9,方差>0.001)或可观测样本各特征的总体分布,特征分布的异常值可以作为阈值.#分析方差var_features=df.var().sort_values()#特征单值率sigle_rate={}forvarindf.columns:sigle_rate[var]=(df[var].value_counts().max()/df.shape[0])2.1.2Correlation特征之间的高相关性会浪费计算资源,影响模型的可解释性。特别是对于线性模型,会导致拟合模型参数不稳定。常用的分析特征相关性的方法有:VarianceInflationFactorVIF:方差膨胀因子,也称为方差膨胀,用于计算数值特征之间的共线性。通常,当VIF大于10时,表明存在高共线性。fromstatsmodels.stats.outliers_influenceimportvariance_inflation_factor#拦截项df['c']=1name=df.columnsx=np.matrix(df)VIF_list=[variance_inflation_factor(x,i)foriinrange(x.shape[1])]VIF=pd.DataFrame({'feature':name,"VIF":VIF_list})人物相关系数:用于计算两个数值特征之间的相关性,取值范围为[-1,1]。importseabornassnscorr_df=df.corr()#heatmapsns.heatmap(corr_df)#移除相关系数高于threshold=0.9upper=corr_df.where(np.triu(np.ones(corr_df.shape),k=1).astype(np.bool))corr_drop=[columnforcolumninupper.columnsifany(upper[column].abs()>threshold)]Chi2检验经典的卡方检验是检验类别变量对分类变量的相关性。Sklearn的实现是通过矩阵乘法快速得到所有特征的观测值和期望值,计算出每个特征的χ2值后进行排序和选择。在扩大chi2在连续变量中应用范围的同时,也方便了特征选择。fromsklearn.datasetsimportload_irisfromsklearn.feature_selectionimportSelectKBestfromsklearn.feature_selectionimportchi2x,y=load_iris(return_X_y=True)x_new=SelectKBest(chi2,k=2).fit_transform(x,y)2.1.3任务中信息分类,可以计算一个特征对这种事件的分类贡献了多少信息,然后特征选择贡献信息量大的特征。常用的方法包括计算IV值和信息增益。信息增益若目标变量D的信息熵为H(D),D在特征A条件下的条件熵为H(D|A),则信息增益G(D,A)为:gain(mutualinformation)的大小是特征A的信息贡献程度。fromsklearn.feature_selectionimportmutual_info_classiffromsklearn.datasetsimportload_irisx,y=load_iris(return_X_y=True)mutual_info_classif(x,y)IVIV值(信息值),它是风控领域的一个重要信息量指标,衡量的是某个特征(连续变量需要先离散化)对目标变量的影响程度。基本思想是根据特征命中的黑白样本占总黑白样本的比例,比较计算关联度。[Github代码链接]2.1.4稳定性对于大多数数据挖掘场景,尤其是风控领域,特征分布的稳定性是非常关心的,它直接影响到模型生命周期的稳定性。常用的是PSI(PopulationStabilityIndex,群体稳定性指数)。PSIPSI表示实际分配和预期分配之间的差异,SUM((实际份额-预期份额)*ln(实际份额/预期份额))。建模时,训练样本(InSample,INS)通常作为期望分布,验证样本作为实际分布。验证样本一般包括样本外(OOS)和跨时间样本(OutofTime,OOT)[Github代码链接]2.2Embedding方法——特征选择embedding方法直接利用模型训练来确定特征的重要性。模型训练与特征选择同时进行。通过模型得到每个特征的权重系数,根据权重系数从大到小选择特征。常用的如基于L1正则项的逻辑回归、Lightgbm特征重要性选择特征。基于L1正则化的逻辑回归的L1正则化方法具有解稀疏的特点。从二维解空间的角度来看,L1-球是一个正方形。当在顶点处时(如W2=C,W1=0的稀疏解),更容易达到最优解。可以看出,基于L1正则化的方法倾向于生成少量特征,而其他特征为0。fromsklearn.feature_selectionimportSelectFromModelfromsklearn.linear_modelimportLogisticRegressionx_new=SelectFromModel(LogisticRegression(penalty="l1",C=0.1)).fit_transform(x,y)treemodelbasedfeaturerankingdecisiontreebased树模型(随机森林,Lightgbm,Xgboost等),树的生长过程也是一个启发式搜索特征子集的过程,训练好的模型可以直接用于输出特征重要性。importmatplotlib.pyplotaspltfromlightgbmimportplot_importancefromlightgbmimportLGBMClassifiermodel=LGBMClassifier()model.fit(x,y)plot_importance(模型,max_num_features=20,figsize=(10,5),importance_type='split')plt.show()feature_importance=pd.DataFrame({'feature':model.booster_.feature_name(),'gain':model.booster_.feature_importance('gain'),'split':model.booster_.feature_importance('split')}).sort_values('gain',ascending=False)当特征数量较多时,对于输出特征的重要性,通常可以根据重要性的拐点选择较低的阈值。2.3打包方式-特征选择打包方式是通过每次选择一些特征来迭代训练模型,根据模型预测效果得分来选择特征。它一般包括四个部分:生成过程、评价函数、停止准则和验证过程。(1)生成过程(GenerationProcedure)是搜索特征子集的过程。首先,从完整的特征集中生成一个特征子集。搜索方法包括完全搜索(如广度优先搜索、定向搜索)、启发式搜索(如双向搜索、向后选择)、随机搜索(如随机子集选择、模拟退火、遗传算法)。(2)评价函数(EvaluationFunction)是评价一个特征子集好坏的一个准则。(3)停止准则(StoppingCriterion)停止准则与评价函数有关,一般是一个阈值,当评价函数的值达到这个阈值时,就可以停止搜索。(4)验证程序(ValidationProcedure)是验证所选特征子集对验证数据集的实际效果。首先从特征集中生成一个特征子集,然后通过评价函数对特征子集进行评价,并将评价结果与停止准则进行比较,如果评价结果优于停止准则,则停止,否则继续生成下一组特征子集,进行特征选择。最终选定的特征子集一般需要验证其实际效果。RFERFE递归特征剔除是一种常用的特征选择方法。其原理是在剩余的特征上递归建立模型,利用模型判断每个特征的贡献度,并对它们进行排序,进行特征选择。fromsklearn.feature_selectionimportRFErfe=RFE(estimator,n_features_to_select,step)rfe=rfe.fit(x,y)print(rfe.support_)print(rfe.ranking_)双向搜索特征选择鉴于RFE只是一种方法的反向迭代,容易陷入局部最优,不支持Lightgbm等模型自动处理缺失值/类特征,所以基于启发式双向搜索和模拟退火算法的思想,简单的代码方法对于特征选择【Github代码链接】,代码如下:"""作者:公众号-基于启发式双向搜索和模拟退火的高级特征选择方法。"""importpandasaspdimportrandomfromsklearn.metricsimportprecision_score,recall_score,f1_score,accuracy_score,roc_curve,aucdefmodel_metrics(model,x,y,pos_label=1):"""评价数"""yhat=model.预测(x)yprob=model.predict_proba(x)[:,1]fpr,tpr,_=roc_curve(y,yprob,pos_label=pos_label)result={'accuracy_score':accuracy_score(y,yhat),'f1_score_macro':f1_score(y,yhat,average="macro"),'precision':precision_score(y,yhat,average="macro"),'recall':recall_score(y,yhat,average="macro"),'auc':auc(fpr,tpr),'ks':max(abs(tpr-fpr))}returnresultdefbidirectional_selection(model,x_train,y_train,x_test,y_test,annealing=True,anneal_rate=0.1,iters=10,best_metrics=0,metrics='auc',threshold_in=0.0001,threshold_out=0.0001,early_stop=True,verbose=True):"""model选择的模型退火模拟退火算法threshold_in特征进入模型的>阈值threshold_out特征剔除的<阈值"""included=[]best_metrics=best_metricsforiinrange(iters):#forwardstepprint("iters",i)changed=Falseexcluded=list(set(x_train.columns)-set(included))random.shuffle(excluded)fornew_columninexcluded:model.fit(x_train[included+[new_column]],y_train)latest_metrics=model_metrics(模型,x_test[included+[new_column]],y_test)[metrics]如果latest_metrics-best_metrics>threshold_in:included.append(new_column)change=Trueifverbose:print('Add{}withmetricsgain{:.6}'.format(new_column,latest_metrics-best_metrics))best_metrics=latest_metricselif退火:ifrandom.randint(0,iters)<=iters*anneal_rate:included.append(new_column)ifverbose:print('AnnealingAdd{}withmetricsgain{:.6}'.format(new_column,latest_metrics-best_metrics))#backwardsteprandom.shuffle(included)fornew_columninincluded:included.remove(new_column)model.fit(x_train[included],y_train)latest_metrics=model_metrics(model,x_test[included],y_test)[metrics]如果latest_metrics-best_metrics