ML算法:逻辑回归
逻辑回归
实验内容及步骤
本实验主要利用逻辑回归(logistics regression)对kaggle数据集进行分析预测。
- 数据处理
#NULL项舍弃
df=df.dropna()
- ENcode,将非数字型的属性值编码为0~1的数字
df.Gender=df.Gender.map({'Male':1,'Female':0})
df.Married=df.Married.map({'Yes':1,'No':0})
df.Dependents=df.Dependents.map({'1':0,'0':0.3,'2':0.6,'3+':1})
df.Education=df.Education.map({'Graduate':1,'Not Graduate':0})
df.Self_Employed=df.Self_Employed.map({'Yes':1,'No':0})
df.Property_Area=df.Property_Area.map({'Rural':0,'Urban':0.5,'Semiurban':1})
df.Loan_Status=df.Loan_Status.map({'Y':1,'N':0})
- 数据归一化,采用$X_{norm}=(X-\mu)/\sigma$,其中$\mu$为平均值,$\sigma$为标准差
import numpy as np
from sklearn.model_selection import train_test_split
X = df.drop(["Loan_Status"], axis=1)
y = df["Loan_Status"]
X_norm=np.array(X)
mu = np.mean(X_norm,0)
sigma = np.std(X_norm,0)
for i in range(X.shape[1]):
X_norm[:,i]=(X_norm[:,i]-mu[i])/sigma[i]
- 划分训练集和测试集,此处采用训练集:测试机=8:2的方式进行划分,利用permutation()函数进行处理
num=np.random.permutation(len(y))
X_norm=X_norm[num]
y=y[num]
a=int(0.2*len(y))
X_test=X_norm[0:a-1,:]
X_train=X_norm[a:,:]
y_test=y[0:a-1]
y_train=y[a:]
- 训练部分预处理
col=X.shape[1]+1
m=len(y)
X=np.array(X)
X = np.hstack((np.ones((m,1)),X))
y=np.array(y).reshape(-1,1)
theta=np.zeros((col,1))
n=len(theta)
temp=np.matrix(np.zeros((n,int(max_iter))))
- 损失函数:利用交叉熵损失函数计算
loss=-np.dot(np.transpose(np.log(self.sigmoid(X,theta))),y)/m-np.dot(np.transpose(np.log(1-self.sigmoid(X,theta))),1-y)/m
- 梯度下降
grad=np.dot(np.transpose(X),self.sigmoid(X,theta)-y)
- 正则化,其中L1相当于添加1-范数项,L2相当于在损失函数中添加2-范数项
if self.penalty=="l1":
loss+=self.gamma*np.sum(np.abs(theta))/m
grad+=self.gamma*np.sign(theta)
else:
loss+=self.gamma*np.sum(np.square(theta))/m
grad+=self.gamma*theta
- 训练部分函数主体
for i in range(int(max_iter)):
#计算loss和gard
temp[:,i]=theta-(lr/m)*grad
theta=temp[:,i]
m = len(y)
j_history=np.append(j_history,np.sum(np.square(loss))
if np.sum(np.square(loss))<tol:
break
- sigmoid函数
return 1.0/(1+np.exp(-np.dot(w,x)))
- 预测函数
def predict(self, X,y,theta):
m=len(y)
X=np.array(X)
X=np.hstack((np.ones((m,1)),X))
p=np.dot(X,theta)
p=p.reshape(-1,1)
y=np.array(y).reshape(-1,1)
sum=0
for i in range(m):
if y[i]==1 and p[i]>0:
sum+=1
elif y[i]==0 and p[i]<0:
sum+=1
return sum/m
实验结果及分析
采用实验默认参数进行训练:lr=0.01, tol=1e-7, max_iter=3e3,penalty=”l2”,gamma=0,fit_intercept=True
Acc=83.2%
- 参数比较
首先对不同的学习率进行比较,如下为不同的学习率下的损失函数
lr=0.001,此时到达max_iter时损失函数仍在快速递减、
相比之下lr=0.01的学习率避免了图像的抖动,也避免了训练过慢导致训练时间长。
不同的正则化参数:
观察图像的纵坐标,可以看出选择l2正则化的收敛效果最好,因此采取l2正则化。
- 最佳准确率的情况:
(此时的参数:lr=0.01, tol=1e-7, max_iter=3e3,penalty=”l2”,gamma=1,fit_intercept=True)
准确率达到了87.37%,其中测试集和训练集的比例为2:8
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 SN1987A!
评论