数据挖掘项目(2)特征选择

此次进行特征选择的数据还是上次用到的金融数据并预测贷款用户是否会逾期。此次数据为了排除缺失值对数据的影响,将所有缺失的样本数据进行删除,并删除了几个对数据分类无影响的变量,最后保留1534×86的数据量。

1.删除方差较小的特征,也就是所谓的不发散的特征,因为这些特征在所有的数据中变化量很小或者几乎没有变化,那么可以认为这个变量对分类的结果不会产生太大的影响。

import pandas as pd
from sklearn.feature_selection import VarianceThreshold

data = pd.read_csv('data.csv')
label = data['status']#get label
data.drop('status',axis = 1, inplace = True)
names = data.columns

2.IV值进行特征选择

对于数据集中的变量来说,其蕴含的信息越多,那么对于分类结果的贡献就越大,信息价值就越大,也就是说此变量的IV(Information Value)就越大。对于IV值的具体计算可以参考:https://blog.csdn.net/a786150017/article/details/84573202

from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import StratifiedKFold

def CalcIV(X,Y):
    N_0=np.sum(Y==0)
    N_1=np.sum(Y==1)
    N_0_group=np.zeros(np.unique(X).shape)
    
    N_1_group=np.zeros(np.unique(X).shape)
    for i in range(len(np.unique(X))):
        N_0_group[i] = Y[(X==np.unique(X)[i])&(Y==0)].count()
        N_1_group[i] = Y[(X==np.unique(X)[i])&(Y==1)].count()
    iv = np.sum((N_0_group/N_0-N_1_group/N_1)*np.log((N_0_group/N_0)/(N_1_group/N_1)))
    if iv>=1.0:## 处理极端值
        iv=1
    return iv

def caliv_batch(data,Y):
    ivlist=[]
    for col in data.columns:
        iv=CalcIV(data[col],Y)
        ivlist.append(iv)
    names=list(data.columns)
    iv_df=pd.DataFrame({'Var':names,'Iv':ivlist},columns=['Var','Iv'])

    return iv_df,ivlist

im_iv, ivl = caliv_batch(data,label)

threshold = 0.02
threshold2 = 0.6
data_index=[]
for i in range(len(ivl)):
    if (im_iv['Iv'][i]< threshold)|(im_iv['Iv'][i] > threshold2):
        data_index.append(im_iv['Var'][i])
data.drop(data_index,axis=1,inplace=True)

skf = StratifiedKFold(n_splits=10)#10折交叉
ac = []
for train_index, test_index in skf.split(data,label):
    x_train, x_test = data.iloc[train_index,:], data.iloc[test_index,:]
    y_train, y_test = label.iloc[train_index],label.iloc[test_index]
    forest = RandomForestClassifier(n_estimators=100, random_state=0, n_jobs=-1)  
    forest.fit(x_train, y_train) #training
    pre_rf = forest.predict(x_test)
    ac_train = forest.score(x_train,y_train)
    ac.append(ac_train)
print('the accuracy RF is : {:.4}'.format(np.mean(ac)))

最后数据集中只剩下3个特征['top_trans_count_last_1_month', 'rank_trad_1_month', 'regional_mobility']

分类的正确率为:0.7877,比用所有特征得到的结果要好。

3.用随机森林的方法来对其进行特征选择,这里主要是根据特征的重要性来选择的特征,属于filter类的方法

from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import StratifiedKFold

forest = RandomForestClassifier(n_estimators=100, random_state=0,n_jobs=1)
forest.fit(data, label)
importance = forest.feature_importances_
imp_result = np.argsort(importance)[::-1]
columns = []
for i in range(data.shape[1]):
    print("%2d. %-*s %f"%(i+1, 30, names[i], importance[imp_result[i]]))
    columns.append(names[i])
columns = columns[0:44]    
data1 = data[columns]

def RF_classify(train_data, train_label, test_data, test_label):
    forest = RandomForestClassifier(n_estimators=15, random_state=0, n_jobs=-1)  
    forest.fit(train_data, train_label) #training
#    pre_rf = forest.predict(x_test)
    ac_train = forest.score(test_data, test_label)
    return ac_train

skf = StratifiedKFold(n_splits=10)#10折交叉
ac = []
for train_index, test_index in skf.split(data1,label):
    x_train, x_test = data1.iloc[train_index,:], data1.iloc[test_index,:]
    y_train, y_test = label.iloc[train_index],label.iloc[test_index]
    acc = RF_classify(x_train, y_train, x_test, y_test)
#    acc = lightgbm_classify(x_train, y_train, x_test, y_test)
    ac.append(acc)
print('the accuracy RF is : {:.4}'.format(np.mean(ac)))

4.除了filter类的方法外,我们还可以用遗传算法对特征进程编码,然后经过选择、交叉、变异最后选择出特征

代码后续再补充

5.sklearn中还有用wrapper的方法来进行特征选择,如递归特征消除法等,这里可以设置要选择特征的个数以及用的分类算法

from sklearn.feature_selection import RFE

data_=RFE(estimator=RandomForestClassifier(), n_features_to_select=10).fit_transform(data,label)

用随机森林分类的准确率为0.7764

6、以上的选择方法都是在完整的数据集上进行特征选择,但有的时候我们担心缺失值的填补会对数据分布造成影响,此时可以用决策树的方法来进行特征选择。在计算基尼指数或者信息熵的时候按照比例进行计算,最后按照特征的重要性排序选择特征。代码后续补充。

由于对此数据不是很熟悉,不太确定要怎么进行特征衍生,所以这部分后续进行补充。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值