SDU项目实训记录3.1——逻辑回归模型
一、处理数据集
由单变量分析可知: RevolvingUtilizationOfUnsecuredLines 价值过⾼,很可疑,删除;
由多变量分析可知: 多少天逾期之间相关性极⾼,去2留1,我去除的是同样价值过⾼的前两
名’NumberOfTimes90DaysLate’和 ‘NumberRealEstateLoansOrLines’。
features_drop = ['RevolvingUtilizationOfUnsecuredLines','NumberOfTimes90DaysLate','NumberOfTime30-59DaysPastDueNotWorse']
trainset = pd.read_csv('data/trainset填补缺失值.csv')
trainset.drop(features_drop,axis=1,inplace=True)
trainset.to_csv("data/train特征选择后.csv",index=False,sep=',')
testset = pd.read_csv('data/testset删除缺失值.csv')
testset.drop(features_drop,axis=1,inplace=True)
testset.to_csv("data/test特征选择后.csv",index=False,sep=',')
二、拆分x、y,WOE转化
对特征选择后的训练集和测试集分别拆分x、y:
x_train = trainset.iloc[:,1:]
y_train = trainset.iloc[:,0]
x_test = testset.iloc[:,1:]
y_test = testset.iloc[:,0]
拆分后对x中的各特征值进行转化,用woe值替换:
def trans_woe(var, var_name, x_woe, x_cut):
woe_name = var_name + '_woe'
for i in range(len(x_woe)):
if i == 0:
var.loc[(var[var_name]<=x_cut[i+1]),woe_name] = x_woe[i]
elif (i>0) and (i<= len(x_woe)-2):
var.loc[((var[var_name]>x_cut[i])&(var[var_name]<=x_cut[i+1])),woe_name] = x_woe[i]
else:
var.loc[(var[var_name]>x_cut[len(x_woe)-1]),woe_name] = x_woe[len(x_woe)-1]
return var
def all_trans_woe(dataset, features_saving):
for feature in features_saving:
dataset = trans_woe(dataset,feature,woes[feature],boundaries[feature])
dataset = dataset.iloc[:,-len(features_saving):]
return dataset
并分别保存为“data/trainX_transwoe.csv"和“data/testX_transwoe.csv"。
三、训练模型并预测
1、概念
(1)逻辑回归模型判别式:
h
w
(
x
)
=
g
(
w
0
x
0
+
w
1
x
1
+
⋯
+
w
d
x
d
)
=
g
(
∑
i
=
0
D
w
d
x
d
)
=
g
(
x
∗
w
)
h_w(x)=g(w_0 x_0 + w_1 x_1 + \dots + w_d x_d)=g(\sum_{i=0}^{D} w_d x_d)=g(x*w)
hw(x)=g(w0x0+w1x1+⋯+wdxd)=g(i=0∑Dwdxd)=g(x∗w)
其中:
- x 0 , x 1 , … , x d x_0, x_1, \dots, x_d x0,x1,…,xd为特征, D D D为特征的总数
- w 0 , w 1 , … , w d w_0, w_1, \dots, w_d w0,w1,…,wd为权重参数
- h w ( x ) h_w(x) hw(x)代表判别式,用于根据传入的特征预测输出结果
- x 0 x_0 x0称为偏置项(intercept term/bias term),一般设置为1即可
-
g
g
g称为sigmoid激活函数,其定义为:
g
(
z
)
=
1
1
+
e
−
z
g(z)= \dfrac{1}{1+e^{-z}}
g(z)=1+e−z1 ,该函数图像如下:
- 可以看到,当 z = 0 z=0 z=0时, g ( z ) g(z) g(z)的值为0.5。一般情况下,低于0.5的 g ( z ) g(z) g(z)可以认为预测为false,高于0.5的预测为true
- g g g的结果可视为该样本属于某个分类的概率
- 激活函数相当于起了这样的作用:将一个连续的数值量,基于设定的阈值转变成离散的分类结果
- 逻辑回归是典型的二分类模型
(2)模型训练原理
- 根据给定的带有 N N N个样本的训练集,每个样本包括特征 x ( i ) x^{(i)} x(i)和分类标签 y ( i ) y^{(i)} y(i)。其中, ( i ) = 1 , 2 , … , D (i)=1,2,\dots,D (i)=1,2,…,D, x ( i ) x^{(i)} x(i)表示第 i i i个样本的特征, y ( i ) y^{(i)} y(i)表示第 i i i个样本的分类(典型情况下是2个分类,标签值为1和0)
- 将每个样本的特征分别代入 h w ( x ) h_w(x) hw(x),计算出预测其属于某一个分类的概率值: y p r e d ( i ) = h w ( x ( i ) ) y_{pred}^{(i)}=h_w(x^{(i)}) ypred(i)=hw(x(i))
- 计算单个样本的预测结果(概率)与实际分类结果的误差:
δ
(
i
)
=
−
y
(
i
)
l
o
g
(
h
w
(
x
(
i
)
)
)
−
(
1
−
y
(
i
)
)
l
o
g
(
1
−
h
w
(
x
(
i
)
)
)
\delta^{(i)}=-y^{(i)} log(h_w(x^{(i)})) -(1 - y^{(i)})log(1 - h_w(x^{(i)}))
δ(i)=−y(i)log(hw(x(i)))−(1−y(i))log(1−hw(x(i)))
- 该误差又称为二元交叉熵(Binary Crossentropy)
- 所有训练样本的交叉熵取平均值,作为损失函数(Loss Function): J ( w ) = 1 m ∑ i = 1 m [ − y ( i ) l o g ( h w ( x ( i ) ) ) − ( 1 − y ( i ) ) l o g ( 1 − h w ( x ( i ) ) ) ] J(w)= \dfrac{1}{m} \sum_{i=1}^m[-y^{(i)} log(h_w(x^{(i)})) -(1 - y^{(i)})log(1 - h_w(x^{(i)}))] J(w)=m1∑i=1m[−y(i)log(hw(x(i)))−(1−y(i))log(1−hw(x(i)))]
- 通过数值计算方法(例如梯度下降算法)来求解 w w w,使得损失值最小。而此时求出的 w w w即为最优的权重参数
- 一旦最优权重参数 w w w确定,既可以代入到 h w h_w hw中,对新的特征进行预测(其属于某个分类的概率)
2、实现
from sklearn.linear_model import LogisticRegression #导入logistic回归模块
from sklearn.model_selection import train_test_split #导入数据切分函数
import warnings
warnings.filterwarnings("ignore")
''' 训练模型 '''
model = LogisticRegression(penalty='none', max_iter=2000) # 迭代次数设为2000
res = model.fit(x_train,y_train)
''' 预测测试集的y '''
y_pred = model.predict(x_test)
''' 预测每个样本的分类概率 '''
y_proba =model.predict_proba(x_test) # 返回n*k数组,(i,j)是模型预测第i个预测样本的标签为j的概率,每一行的和等于1
''' 将预测样本的特征和结果合并显示 '''
results = x_test.copy()
results['SeriousDlqin2yrs'] = y_test
results['Predicted'] = y_pred
results['Predicts_prob_0'] = y_proba[:, 0] # 获取分类结果为0(好客户)的预测概率
results['Predicts_prob_1'] = y_proba[:, 1] # 获取分类结果为1(坏客户)的预测概率
results.iloc[:, -4:]
results:得到的训练集结果(真实值、预测值、预测为0的概率、预测为1的概率):