算法应用

【实例】sklearn实现一个简单的逻辑回归多分类例子(带公式提取)

作者 : 老饼 发表日期 : 2022-06-26 10:11:39 更新日期 : 2024-06-30 01:13:52
本站原创文章,转载请说明来自《老饼讲解-机器学习》www.bbbdata.com



逻辑回归一般用来做二分类,但有时也需要用来做多分类,

本文讲解如何使用sklearn实现逻辑回归多分类,并提取多分类的模型表达式



  01. sklearn中的多分类逻辑回归  




本节简单介绍sklearn中多分类逻辑回归模型有哪些,及其调用方式




   sklearn中的多分类逻辑回归   


如何调用sklearn的多分类逻辑回归
sklearn多分类的逻辑回归调用格式与二分类是一致的,
当输出是多类别时,就会自动使用多分类模式

   关于OVR和multinomial多分类   
sklearn逻辑回归多分类有两种模型:ovr与multinomial,
在默认值下,多分类调用的就是multinomial模型
 严谨来说,在multi_class设为auto(默认值)的时候,
如果二分类或者求解器为liblinear时,则为OVR,否则为multinomial

如果我们要指定用的是multinomial还是OVR,
只要设置multi_class的值即可:
clf = LogisticRegression(multi_class='multinomial')    # 使用multinomial模型   
clf = LogisticRegression(multi_class='OVR')                # 使用OVR模型               
多分类时ovr与multinomial的区别请参考:《sklearn逻辑回归多分类ovr与multinomial》






   02. 多分类逻辑回归-实例与代码   




本节通过一个简单的多分类实例

讲解如何使用sklearn实现逻辑回归multinomial模型,并提取最后的模型表达式




   问题及思路  


下面是一个简单的多分类问题
问题
现已采集150组 鸢尾花数据,包括鸢尾花的四个特征与鸢尾花的类别
我们希望通过采集的数据,训练一个决策树模型
之后应用该模型,可以根据鸢尾花的四个特征去预测它的类别
      数据      
数据如下(即sk-learn中的iris数据):
  
  花萼长度 sepal length (cm) 、花萼宽度 sepal width (cm)    
花瓣长度 petal length (cm) 、花瓣宽度 petal width (cm)  
山鸢尾:0,杂色鸢尾:1,弗吉尼亚鸢尾:2      
             
 
   思路  
 
用多类别逻辑回归解决该问题的具体思路如下
 
1. 数据归一化(用sklearn的逻辑回归一般要作数据归一化)
2. 用归一化数据训练逻辑回归模型                                      
3. 用训练好的逻辑回归模型预测                                         
4. 模型参数提取                                                                




    sklearn实现多类别逻辑回归的代码   


# -*- coding: utf-8 -*-
"""
sklearn逻辑回归多分类例子(带模型公式提取)
"""
from sklearn.linear_model import LogisticRegression
import numpy as np
from sklearn.datasets import load_iris
#----数据加载------

iris = load_iris()    
X    = iris.data
y    = iris.target
#----数据归一化------
xmin   = X.min(axis=0)
xmax   = X.max(axis=0)
X_norm = (X-xmin)/(xmax-xmin)

#-----训练模型--------------------
clf = LogisticRegression(random_state=0,multi_class='multinomial')            
clf.fit(X_norm,y)

#------模型预测-------------------------------
pred_y      = clf.predict(X_norm)
pred_prob_y    = clf.predict_proba(X_norm) 

#------------提取系数w与阈值b-----------------------
w_norm = clf.coef_                             # 模型系数(对应归一化数据)
b_norm = clf.intercept_                           # 模型阈值(对应归一化数据)
w    = w_norm/(xmax-xmin)                       # 模型系数(对应原始数据)
b    = b_norm -  (w_norm/(xmax - xmin)).dot(xmin)      # 模型阈值(对应原始数据)
# ------------用公式预测------------------------------
wxb = X.dot(w.T)+ b
wxb = wxb - wxb.sum(axis=1).reshape((-1, 1)) # 由于担心数值过大会溢出,对wxb作调整
self_prob_y = np.exp(wxb)/np.exp(wxb).sum(axis=1).reshape((-1, 1))
self_pred_y = self_prob_y.argmax(axis=1)


#------------打印信息--------------------------
print("\n------模型参数-------")     
print( "模型系数:",w)
print( "模型阈值:",b)
print("\n-----验证准确性-------")  
print("提取公式计算的概率与sklearn自带预测概率的最大误差", abs(pred_prob_y-self_prob_y).max())





     运行结果    


代码运行结果如下:
------模型参数-------
模型系数: [[-0.3902573   0.65000868 -0.48485313 -1.16130665]
 [ 0.07259933 -0.59884596  0.0709145  -0.19934931]
 [ 0.31765797 -0.05116272  0.41393863  1.36065596]]
模型阈值: [ 3.18277053  2.06368594 -5.24645647]


-----验证准确性-------
提取公式计算的概率与sklearn自带预测概率的最大误差 3.3306690738754696e-16




     最终的模型表达式    


模型表达式
由模型系数,得到最后的模式表达式为:
 
 
 关于概率预测
P的输出就是属于各类的概率
例如P(X)=[0.3 0.2 0.5],
那么属于第0类、1类、2类的概率分别为0.3、0.2、0.5     

  关于类别预测
 
P中哪个的值大,就是哪一类
例如P(X)=[0.3 0.2 0.5],0.5最大,所以X属于0、1、2类中的类别2
✍️备注: sklearn担心e的指数部分太大,产生数值溢出,对P的计算会再做一些处理,详细见代码里的处理










 End 






联系老饼