赞
踩
在一个二分类或者多分类问题中,对结果影响的因子多可能多达数百数千个,也有很多无意义的因子混于其中,若是想筛选出对结果有意义的因子,或者是删除冗余数据,做特征筛选都十分有必要。在有些数据挖掘目标的要求中,例如我之前做的高送转预测题,需要筛选有意义的经济学因子,做特征筛选也能达到此目的。
首先介绍逻辑回归算法,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(1−pp)=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
P(Y=1|x)=ewTx1+ewTx=11+e−wTxP(Y=0|x)=11+ewTx
在实际训练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=−yi⋅log(1+e−wTXi1)−(1−yi)⋅log(1+ewTXi1)
第一步,首先导入必备的库:
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正则化此处可以视作上述logistics模型损失函数的惩罚项,即对损失函数的参数进行限制。可以分别起到筛选特征和避免过拟合的作用.上面模型中也用到了L1惩罚项。
L1范数对模型得到的参数项进行压缩,避免共线性问题、重复特征问题。其惩罚项目可表示为:
λ
∑
i
n
∣
w
i
∣
\lambda \sum\limits_i^n {|{w_i}|}
λi∑n∣wi∣ 将改项带入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}
上式中,λ的取值即为约束的强度,可以通过反复测试或者交叉验证去确定合适的取值,L1正则的优点为可以进行特征选择,去掉影响较小和重复的特征,但也有可能将有用的特征筛除。
L2范数与L1的在数学形式上的不同之处在于其惩罚项的不同,其表现为如下形式:
λ
∑
i
n
w
i
2
,
λ
>
0
\lambda \sum\limits_i^n {{w_i}^2} ,\lambda > 0
λi∑nwi2,λ>0
L2正则下具有数据具有一定的趋同、群组效应,即相关性较强的特征会被同时保留或者删除,不能实现矩阵的稀疏化,但可以防止模型的过拟合。
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('')
注:凑合着看吧,我后面运行了再改改试试。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。