数据挖掘学习笔记-简单的特征筛选模型(二)


注:
1.在完成前一部分的数据预处理后,可以构建预测模型,这里简单运用了2个预测模型特征筛选。
2.由于我闲了这么久重新学习python,算是重新复习数据挖掘的知识。
3.这里用了相对简单好用的两个方法。想到通用性啥的,也方便他人借鉴,代码简化了下。

特征筛选的意义

 在一个二分类或者多分类问题中,对结果影响的因子多可能多达数百数千个,也有很多无意义的因子混于其中,若是想筛选出对结果有意义的因子,或者是删除冗余数据,做特征筛选都十分有必要。在有些数据挖掘目标的要求中,例如我之前做的高送转预测题,需要筛选有意义的经济学因子,做特征筛选也能达到此目的。

利用logistics进行特征筛选

logistics模型简述

首先介绍逻辑回归算法,logistic回归为概率型非线性回归模型,其自变量可为连续或者分立值,因变量可为二分类值(0或1)或者多分类值。
假设一组样本x={x1,x2,…xn}为一组样本数据,w={w1,w2,…wn}为前面样本的参数组。若此处假设事件发生概率为p,利用事件几率odds表示事件发生与不发生的比值,那么可以得到事件的发生概率为p/(1-p) ,几率越大发生的概率越大,即表现为如下形式:
log ⁡ ( p 1 − p ) = w T x \log (\frac{p}{{1 - p}}) = {w^T}x log(1pp)=wTx
对于二分类问题,即可转换为如下条件分布形式:
P ( Y = 1 ∣ x ) = e w T x 1 + e w T x = 1 1 + e − w T x P ( Y = 0 ∣ x ) = 1 1 + e w T x \begin{array}{l} P(Y = 1|x) = \frac{{{e^{{w^T}x}}}}{{1 + {e^{{w^T}x}}}} = \frac{1}{{1 + {e^{ - {w^T}x}}}}\\ P(Y = 0|x) = \frac{1}{{1 + {e^{{w^T}x}}}} \end{array} P(Y=1x)=1+ewTxewTx=1+ewTx1P(Y=0x)=1+ewTx1
在实际训练logistics模型时,是利用极大似然法估计训练集的参数,得到模型.具体推导与原理此处不加赘述了。其代价函数如下:
cos ⁡ t = − y i ⋅ log ⁡ ( 1 1 + e − w T X i ) − ( 1 − y i ) ⋅ log ⁡ ( 1 1 + e w T X i ) \cos t = - {y_i} \cdot \log (\frac{1}{{1 + {e^{ - {w^T}{X_i}}}}}) - (1 - {y_i}) \cdot \log (\frac{1}{{1 + {e^{{w^T}{X_i}}}}}) cost=yilog(1+ewTXi1)(1yi)log(1+ewTXi1)

logistics的模型应用

第一步,首先导入必备的库:

import pandas as pd
from sklearn.svm import SVR
import imp
import numpy as np
from sklearn.linear_model import LogisticRegressionCV##有些库可能没用
from  sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score
import matplotlib
import matplotlib.pyplot as plt
from pylab import mpl
from sklearn.feature_selection import SelectFromModel
#from sklearn import cross_validation
#SelectFromModel(LR(threshold=0.5, C=0.1)).fit_transform(iris.data, iris.target)
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics  import roc_curve,auc###ROC图

数据导入,并按照比例划分训练集与测试集:

##########年数据输入
#######划分训练集与测试集
data=pd.read_csv('ytr1.csv',encoding='gbk')##输入csv数据
feature=data[np.r_[np.array(data.columns[4:240].values)]]######columns[内部为输入的各个元素序号,按照自己的需求调整]
X_train = feature
y = data['预测目标的标签']#此处为预测值
#X_train,y_train,x_test,y_test=train_test_split(X_train,y,test_size=0.2)
X_train,x_test,y_train,y_test=train_test_split(X_train,y,test_size=0.2)###划分训练与测试集

利用logistics模型进行特征筛选,此处带了L1惩罚项:

data=pd.read_csv('mutest1.csv',encoding='gbk')##读入csv文件
##data=data.iloc[:7]###选择需要使用的区域
##str1='是否高转送'
feature=data[np.r_[np.array(data.columns[3:120].values)]]
X_train = feature
y = data['预测目标']###内输入预测目标label
def rmse_cv(model):
    rmse= np.sqrt(-cross_val_score(model, X_train, y, scoring="neg_mean_squared_error", cv = 3))
    return(rmse)
model = LogisticRegression(penalty='l1', tol=0.001,solver='liblinear',C=0.10).fit(X_train, y)
print(model.coef_[0,:])
print( X_train.columns)
coef = pd.Series(model.coef_[0,:],index = X_train.columns)
imp_coef = pd.concat([coef.sort_values().head(0),
                     coef.sort_values().tail(24)])
#imp_coef = pd.concat([coef.sort_values().head(5)])
matplotlib.rcParams['figure.figsize'] = (8.0, 4.0)###绘制特征相关性排名图
imp_coef.plot(kind = "barh",width = 0.35)
plt.title("LRCV-L1模型中各特征的系数")
plt.show()
plt.savefig('特征筛选')
coef.sort_values(ascending=False).to_csv('feature.csv', encoding='gbk',mode='a')#输出特征为csv
#print('测试集准确率:', accuracy_score(y_test, predictions))
#ans1=pd.concat([coef.sort_values().tail(5)])
#imp_coef.to_csv('mutest111.csv', encoding='gbk')
sparsity_l2_LR = np.mean(model == 0) * 100
print("得到的参数的稀疏性: %.2f%%" % sparsity_l2_LR)
print("模型性能: %.4f" % model.score(X_train, y))

L1与L2惩罚项

 L1与L2正则化此处可以视作上述logistics模型损失函数的惩罚项,即对损失函数的参数进行限制。可以分别起到筛选特征和避免过拟合的作用.上面模型中也用到了L1惩罚项。
 L1范数对模型得到的参数项进行压缩,避免共线性问题、重复特征问题。其惩罚项目可表示为: λ ∑ i n ∣ w i ∣ \lambda \sum\limits_i^n {|{w_i}|} λinwi 将改项带入logistics模型中的对数代价函数中,即可得到目标函数为:
min ⁡ { cos ⁡ t + λ ∑ i n ∣ w i ∣ } s . t . { cos ⁡ t = − y i ⋅ log ⁡ ( 1 1 + e − w T X i ) − ( 1 − y i ) ⋅ log ⁡ ( 1 1 + e w T X i ) λ > 0 \begin{array}{c} \min \left\{ {\cos t + \lambda \sum\limits_i^n {|{w_i}|} } \right\}\\ s.t.\left\{ \begin{array}{c} \cos t = - {y_i} \cdot \log (\frac{1}{{1 + {e^{ - {w^T}{X_i}}}}}) - (1 - {y_i}) \cdot \log (\frac{1}{{1 + {e^{{w^T}{X_i}}}}})\\ \lambda > 0 \end{array} \right. \end{array} min{cost+λinwi}s.t.{cost=yilog(1+ewTXi1)(1yi)log(1+ewTXi1)λ>0
 上式中,λ的取值即为约束的强度,可以通过反复测试或者交叉验证去确定合适的取值,L1正则的优点为可以进行特征选择,去掉影响较小和重复的特征,但也有可能将有用的特征筛除。
 L2范数与L1的在数学形式上的不同之处在于其惩罚项的不同,其表现为如下形式:
λ ∑ i n w i 2 , λ > 0 \lambda \sum\limits_i^n {{w_i}^2} ,\lambda > 0 λinwi2,λ>0
 L2正则下具有数据具有一定的趋同、群组效应,即相关性较强的特征会被同时保留或者删除,不能实现矩阵的稀疏化,但可以防止模型的过拟合。

利用XGBoost进行特征筛选

 XGBoost是一套提升树可扩展的机器学习系统,其相当好用,我就不必多加赘述了。在python利用pip安装了xgboost就能直接使用了。
首先,导入相关库:

# use feature importance for feature selection
from numpy import loadtxt
from numpy import sort
import pandas as pd
from xgboost import XGBClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.feature_selection import SelectFromModel
# load data

再导入csv文件,并划分训练测试集:

#dataset = loadtxt('pima-indians-diabetes.csv', delimiter=",")
dataset=pd.read_csv('ytr1.csv',encoding='gbk')
feature1=dataset[np.r_[np.array(dataset.columns[1:10].values)]]######数据用feature,其中[]内为需要参与计算的特征数,例:想看第一到第十个因子对因变量的影响,则填[0:9]
# split data into X and y
X = feature1#特征因子
Y = dataset['需要预测的值标签']
# split data into train and test sets
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.3, random_state=7)
# fit model on all training data

利用xgboos进行特征因子排序:


model = XGBClassifier()
model.fit(X_train, y_train)
# make predictions for test data and evaluate
y_pred = model.predict(X_test)
predictions = [round(value) for value in y_pred]
accuracy = accuracy_score(y_test, predictions)
print("Accuracy: %.2f%%" % (accuracy * 100.0))
# Fit model using each importance as a threshold
thresholds = sort(model.feature_importances_)
for thresh in thresholds:
    # select features using threshold
    selection = SelectFromModel(model, threshold=thresh, prefit=True)
    select_X_train = selection.transform(X_train)
    # train model
    selection_model = XGBClassifier()
    selection_model.fit(select_X_train, y_train)
    # eval model
    select_X_test = selection.transform(X_test)
    y_pred = selection_model.predict(select_X_test)
    predictions = [round(value) for value in y_pred]
    accuracy = accuracy_score(y_test, predictions)
    print("Thresh=%.3f, n=%d, Accuracy: %.2f%%" % (thresh, select_X_train.shape[1], accuracy*100.0))

xgboost里面也自带了绘图程序,完成模型运行后,利用其自带的绘图程序绘制特征重要性排序图,并可以将特征排序输出为csv文件:

# plot feature importance using built-in function
from xgboost import plot_importance
from pylab import mpl
import matplotlib.pyplot as plt
import matplotlib
mpl.rcParams['font.sans-serif'] = ['SimHei']
#matplotlib.rcParams['figure.figsize'] = (8.0, 4.0)
#plt.title("年数据-XGBoost-模型中排名前24的特征及其系数",fontsize=18)
#plt.savefig('LR特征筛选',dpi=300, bbox_inches = 'tight')
#plt.show()
plot_importance(model,max_num_features=24,title='Xgboost特征重要性排序')
fig=plt.gcf()
#fig.set_size_inches(150, 100)
#plt.show()
fig.savefig('XBoost特征.png',dpi=300, bbox_inches = 'tight')
#pyplot.show()
tezheng=pd.DataFrame(model.feature_importances_,dataset.columns.values[1:10])#其中[]内为原文件所有参与的特征,同上
tezheng=tezheng.sort_values(by=0,axis=0,ascending=False)
tezheng.to_csv('data_tezheng.csv',encoding='gbk')##将特征导出为csv文件,并将重要性排序

相关系数热力图绘制

 筛选出来的特征,要进一步进行筛选,例如有些特征可能表达的意思差不多,重复性较大,这样也可能造成数据特征重复。可以通过热力图进行可视化与判断:

###########相关系数热力图
import pandas as pd
import seaborn as sns
import numpy as np
from matplotlib import pyplot as plt
from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['SimHei']
#data=pd.read_csv('ytr1.csv',encoding='gbk')###数据用
data=pd.read_csv('输入筛选后得出的特征数数据文件',encoding='gbk')###数据用
#data1=np.loadtxt(open('feature.csv',dtype='str',skiprows=1)
#data1=pd.read_csv('feature.csv',encoding='gbk')
key=tezheng.index.values[0:18]
#print(data[data1.LABEL])
#data=data[data1.LABEL[0:16]]
data=data[key]
#data=data.iloc[0:7,3:30]
print(np.size(data.corr(),1))
plt.subplots(figsize=(np.size(data.corr(),1),np.size(data.corr(),1)))
sns.heatmap(data.corr(),annot=True,vmax=1,square=True,cmap='Blues')
plt.savefig('')
#plt.title('年数据特征的相关系数热力图',fontsize=28)
plt.title('XGBoost模型-特征的相关系数热力图',fontsize=28)
plt.tick_params(labelsize=24)
#plt.savefig('年数据-LR模型-相关系数热力图',dpi=300)
plt.savefig('XGBoost模型-相关系数热力图',dpi=300)
plt.show()
ax=plt.subplots(figsize=(np.size(data.corr(),1),np.size(data.corr(),1)))
#ax.set_ylabel('')

注:凑合着看吧,我后面运行了再改改试试。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值