fuli2020

2020-08-25   阅读量: 799

机器学习——逻辑回归

扫码加入数据分析学习群

图片.png

负极大似然函数就是损失函数

图片.png

计算梯度公式

图片.png


手写逻辑回归

import numpy as np

import pandas as pd

from sklearn.datasets import load_breast_cancer


bc=load_breast_cancer()

X=bc['data']

Y=bc['target']


from sklearn.preprocessing import StandardScaler

from sklearn.metrics import accuracy_score


X=StandardScaler().fit_transform(X)

X=np.hstack(np.ones((X.shape[0],1)),X)


#使用sigmod的函数

def sigmoid(X,w):

z=X*w

return 1/(1+np.exp(-z))


def get_label(Y_pred,threshold=0.5):

return (Y_pred>=threshold).astype(int)


from sklearn.model_selection import train_test_split

Xtrain,Xtest,Ytrain,Ytest=train_test_split(X,Y,test_size=0.3)


def Logistic_regression(X,Y,n_iter=1000,eta=0.01):

X=np.mat(X)

w=np.mat(np.ones((X.shape[1],1)))

Y=np.mat(Y).T

acc_list=[]


for _ in range(n_iter):

sigmoid_result=sigmoid(X,w)

error=sigmoid_result-Y

gd=1/X.shape[0]*error.T*X

w=w-eta*gd.T

Y_pred=sigmoid(X,w)

acc_list.append(accuracy_score(np.array(Y).ravel(),getlabel(np.array(Y_pred).ravel())))


return w,acc_list


w,acc_list=Logistic_regression(Xtrain,Ytrain,n_iter=100000,eta=0.001)


print(acc_list[-1])


Y_pred_test=sigmoid(Xtest,w)

accuracy_score(np.array(Ytest).ravel(),get_label(np.array(Y_pred_test).ravel()))


探索算法参数

#简单使用L1和L2范式

lrl2=LogisticRegression(penalty='l2').fit(Xtrain_,Ytrain)

lrl2.score(Xtrain_,Ytrain),lrl2.score(Xtest_,Ytest)

#对于L2范式,参数值都是非0

lrl2.coef_


#实例化l1范式

lrl1=LogisticRegression(penalty='l1',solver='liblinear').fit(Xtrain_,Ytrain)

lrl1.score(Xtrain_,Ytrain),lrl1.score(Xtest_,Ytest)

#L1范式下,在某一个惩罚力度下,不重要的参数特征值直接压缩成0

lrl1.coef_


Solver优化方法

  1. sag: 随机梯度下降法,通过对损失函数做一阶求导,使用梯度的放方向不断更新,逼近全局最优。数据量小的情况下,结果不收敛,结果不准确,但是数据量大的情况下了,快!并且还能很大可能的绕过局部最优。

  2. newton-cg, lbfgs: 牛顿法,通过对损失函数做二阶求导,从而在小数据集下,更加快的逼近全局最优,如果数据量一旦很大的话,这个方法会非常的慢。得到了嗨森矩阵。

  3. liblinear,效率要低很多,但是万能!不需要损失函数可导,采用一种类似贪心的算法的迭代方法,一直朝着损失函数下降的方向移动,逼近全局最优值。

对于L2范式来说,损失函数可以求导!所以可以使用sag, newton-cg, lbfgs。penalty = 'l2', solver可以是任意的,也可以使用liblinear。

对于L1范式来说,损失函数不可以求导!sag, newton-cg, lbfgs用不了。所以penalty = 'l1',solver必须是liblinear

penalty : 怎么改损失函数,是使用L1范式,还是使用L2范式

solver : 如何最小化损失函数


C惩罚项

#逻辑回归当中的这个C描述1/惩罚,也就是说C越大,惩罚越小,C越小,惩罚越大

使用cv的方法来查看模型的一个在测试集上综合的表现

from sklearn.model_selection import cross_val_score

cross_val_score(lrl1,Xtrain_,Ytrain,cv=5).mean(),cross_val_score(lrl2,Xtrain_,Ytrain,cv=5).mean()


网格搜索

Xtrain,Xtest,Ytrain,Ytest=train_test_split(X,Y,test_size=0.3,random_state=420)

std=StandardScaler().fit(Xtrain)

Xtrain_=std.transform(Xtrain)

Xtest_=std.transform(Xtest)


from sklearn.model_selection import GridSearchCV

params={'penalty':['l1','l2'],'C':np.linspace(0.2,0.7,1000)}

GS=GridSearchCV(model,params,cv=5,scoring='accuracy')

GS.fit(Xtrain_,Ytrain)

#查看最优的参数值

GS.best_params_,GS.best_score_

#GS里面best_estimator_最好分类器,通过coef_查看最好的模型w值

GS.best_estimator_coef_


多分类问题

#鸢尾花数据集做多分类

from sklearn.datasets import load_iris

iris=load_iris()

X=iris['data']

Y=iris['target']

#切分数据集并且来做标准化

Xtrain,Xtest,Ytrain,Ytest=train_test_split(X,Y,test_size=0.3,random_state=420)

std=StandardScaler().fit(Xtrain)

Xtrain_=std.transform(Xtrain)

Xtest_=std.transform(Xtest)


model=LogisticRegression(multi_class='ovr').fit(Xtrain_,Ytrain)

model.score(Xtrain_,Ytrain),model.score(Xtest_,Ytest)


分类方式选择参数

multi_class参数决定了分类方式的选择,有ovr和multinomial两个值可以选择,默认是ovr

ovr即前面提到的one-vs-rest(OvR),而multinomial即前面提到的many-vs-many(MvM),如果是二元逻辑回归,ovr和multinomial并没有任何区别,区别主要是在多元逻辑回归上。

OvR的思想很简单,无论你是多少元逻辑回归,我们都可以看做二元逻辑回归。具体做法是,对于第K
类的分类决策,我们把所有第K类的样本作为正例,除了第K类样本以外的所有样本都作为负例,然后在
上⾯做⼆元逻辑回归,得到第K类的分类模型。其他类的分类模型获得以此类推。

图片.png

当需要预测新的数据的类别时,使用如下公式:

图片.png

使用不同的函数去预测输入x,分别计算不同图片.png的值,然后取其中的最大值。哪个类别i对应的图片.png大,就认为属于哪个类。

而MvM则相对复杂,如果模型有T类,我们每次在所有T类样本里面选择两类样本出来,记作T1类和T2类,把所有的输出为T1和T2的样本放在一起,把T1作为正例,T2作为负例,进行二元逻辑回归,得到模型参数,我们一共需要T(T-1)/2次分类。

从上面的描述可以看出OvR相对简单,但分类效果相对略差。而MvM分类相对精确,但是分类速度没有OvR快。

如果选择了ovr,则4种损失函数的优化方法liblinear,newton-cg,lbfgs和sag都可以选择,但是如果选择了multinomial,则只能选择newton-cg,lbfgs和sag。

#使用网格搜索

model=LogisticRegression(max_iter=10000,solve='lbfgs',penalty='l2')

p={'C':np.linspace(0.1,10,100),

'multi_class':['ovr','multinomial']}

GS=GridSearchCV(model,p,cv=5)

GS.fit(Xtrain_,Ytrain)

print(GS.best_params_,GS.best_score_)

print(GS.score(Xtrain_,Ytrain),GS.score(Xtest_,Ytest))




添加CDA认证专家【维克多阿涛】,微信号:【cdashijiazhuang】,提供数据分析指导及CDA考试秘籍。已助千人通过CDA数字化人才认证。欢迎交流,共同成长!
47.5998 2 0 关注作者 收藏

评论(0)


暂无数据

推荐课程