逻辑斯谛回归(Logistic回归)最详解
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Logistic回歸學習思路
一.邏輯回歸模型的原理與定義(主要思想)
邏輯斯諦回歸是經典的分類方法,它屬于對數線性模型,原理是根據現有的數據對分類邊界線建立回歸公式,以此進行分類。(主要思想)
定義:
在線性回歸模型的基礎上,使用Sigmoid函數,將線性模型的結果壓縮到[0,1]之間,使其擁有概率意義,它可以將任意輸入映射到[0,1]區間,實現值到概率轉換。
- 屬于概率性判別式模型
- 線性分類算法
在學習邏輯回歸模型之前,先來看一下邏輯斯諦分布,因為我們的邏輯斯蒂模型就是根據邏輯斯蒂分布得到的;通過參數估計方法直接估計出參數,從而得到P(Y|X)。
下面給出《統計學習方法》上邏輯斯蒂分布的定義:
二.邏輯回歸的推導過程
為了實現根據所有輸入預測出類別,為此引入了sigmoid函數p=1/(1+exp(-z)),sigmoid函數剛好也有二分類的功能。
1. 為什么要使用sigmoid函數作為假設?
因為線性回歸模型的預測值為一般為大于1的實數,而樣本的類標簽為(0,1),我們需要將分類任務的真實標記y與線性回歸模型的預測值聯系起來,也就是找到廣義線性模型中的聯系函數。如果選擇單位階躍函數的話,它是不連續的不可微。而如果選擇sigmoid函數,它是連續的,而且能夠將z轉化為一個接近0或1的值。
當z=0時,p=0.5
當z>0時,p>0.5 ?歸為1類
當z<0時,p<0.5 ?歸為0類
確定了分類器的函數形式,最佳回歸系數是多少,如何確定?
sigmoid函數的輸入記為z,將線性模型結果賦值到z,即:
z=w0x0+w1x1+w2x2+w3x3...wnxn
如果采用向量的寫法,
上述公式寫成z=WT*X,
其中向量X是分類器的輸入數據,即為特征值;向量W就是我們要找到的最佳參數,從而使得分類器盡可能精確。
為了找出最佳的回歸系數,所以我們可以對兩種損失函數進行優化算法
①均方差 (后面會介紹舍棄使用這種作為損失函數)
②對數極大似然估計法
三.數學模型
二項邏輯斯蒂回歸模型
知道分布的定義和推導過程之后,就是給出我們的邏輯斯蒂模型了:
引用了李航的《統計學習方法》書中如下
注意:(1)最終的結果是通過比較P(Y=1|X)和P(Y=0|X)的大小來確定類別的(類似于樸素貝葉斯);
? ? ? ? ? (2)b在這里其實可以看做是w0x0,其中x0 = 1;
? ? ? ? ? (3)其實本質上這個就是一個二項分布,所以遵循二項分布的分布律。
事件的對數幾率(log odds)
也就是說,如果我的模型是邏輯回歸模型,那么事件{Y=1|X}發生的對數幾率就是輸入X的線性函數(模型),反之,知道了這個推論,我們是可以反推出邏輯斯蒂模型的形式的
四.目標函數
求目標參數,常用目標函數的選取:
①損失函數:均方差(標準值-預測值)
②對數似然函數
首先極大似然函數是一種確定模型參數的方法,它確定參數值的方法是通過找到最大化模型產生真實數據的那一組參數。
最大似然估計就是通過已知結果去反推最大概率導致該結果的參數。
極大似然估計是概率論在統計學中的應用,它提供了一種給定觀察數據來評估模型參數的方法,即 “模型已定,參數未知”,通過若干次試驗,觀察其結果,利用實驗結果得到某個參數值能夠使樣本出現的概率為最大,則稱為極大似然估計。邏輯回歸是一種監督式學習,是有訓練標簽的,就是有已知結果的,從這個已知結果入手,去推導能獲得最大概率的結果參數,只要我們得出了這個參數,那我們的模型就自然可以很準確的預測未知的數據了。(對極大似然函數的詳細理解可以參考:https://blog.csdn.net/qq_44543774/article/details/109735754)
?
通過極大似然推導得出邏輯回歸的目標函數,這里我給出手寫的推導:
極大似然函數是概率論在統計學中的應用,它提供了一種給定觀察數據來評估模型參數的方法,即 “模型已定,參數未知”,通過若干次試驗,觀察其結果,利用實驗結果得到某個參數值能夠使樣本出現的概率為最大,則稱為極大似然估計。通過求極大似然函數來得到參數w的估計值。
以上就是通過極大似然函數作為目標函數,得出了參數向量w值
綜上logistic回歸模型的目標函數是極大似然函數
五.算法源碼
源碼:
from sklearn.linear_model import LogisticRegression from math import exp from math import * from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from numpy import * import numpy as npclass LogisticRegressionClassifier(object):def __init__(self,eta=0.1,loop=30):self.eta=etaself.loop=loopdef sigmoid(self,x):return 1.0/(1+exp(-x))def data_tranforce(self,x_train):data=[]d=[]for x in x_train: #x因為是數組類型data.append([1.0,*x]) #將每一行數組增加一個1.0數值,*x是去掉[]符號,形成一行數值#c=list(x) #將一維數組變成列表#c.insert(0, 1.0) #這種insert()方法必須是列表#print(list(x).insert(0,1.0))#d.append(c) #類似d=[[1.0,2,3],[1.0,3,4.8]]return datadef fit(self,x_train,y_train):data_mat=self.data_tranforce(x_train) #處理每個樣本的特征值n=shape(data_mat)[1] #求出data_mat對應參數的個數self.weight=ones((n,1)) #初始化參數w數組cls=self.loopfor k in range(cls): #循環多少次for i in range(len(x_train)): #遍歷每一個樣本h=self.sigmoid(np.dot(data_mat[i],self.weight))err=(y_train[i]-h)#隨著每次更新err下面就會更新self.weight的向量self.weight+=self.eta*err*np.transpose([data_mat[i]]) #[data_mat[i]]變成1*4的數組,一維數組轉置必須加一個[]#測試訓練模型的準確性def test(self,x_test,y_test):numbers=0x_test = self.data_tranforce(x_test) # 處理每個樣本的特征值加一個1.0for x,y in zip(x_test,y_test):result=np.dot(x,self.weight)if(result>0 and y==1)or(result<0 and y==0):numbers+=1return float(numbers)/float(len(x_test)) def main():load=load_iris()x=load.data[:100,:2]y=load.target[:100]y=np.where(y==1,1,0)x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.3)my_l=LogisticRegressionClassifier()my_l.fit(x_train,y_train)print("準確率:",my_l.test(x_test,y_test))if __name__== "__main__":main()運行結果:
用示例來解釋代碼的執行過程:
六.優缺點
優點:計算代價不高,易于理解和實現
缺點:容易欠擬合,分類精度不高
七.應用場景
邏輯回歸主要是解決二分類問題
使用邏輯回歸判斷年收入
項目描述
二元分類是機器學習中最基礎的問題之一,在這份教學中,你將學會如何實作一個線性二元分類器,來根據人們的個人資料,判斷其年收入是否高于 50,000 美元。我們將用?logistic regression 來達成以上目的,你可以嘗試了解、分析兩者的設計理念及差別。 實現二分類任務:
- 個人收入是否超過50000元?
數據集介紹
這個資料集是由UCI Machine Learning Repository 的Census-Income (KDD) Data Set 經過一些處理而得來。為了方便訓練,我們移除了一些不必要的資訊,并且稍微平衡了正負兩種標記的比例。事實上在訓練過程中,只有 X_train、Y_train 和 X_test 這三個經過處理的檔案會被使用到,train.csv 和 test.csv 這兩個原始資料檔則可以提供你一些額外的資訊。
- 已經去除不必要的屬性。
- 已經平衡正標和負標數據之間的比例。
特征格式
- 基于文本的原始數據
- 去掉不必要的屬性,平衡正負比例。
- train.csv中的離散特征=>在X_train中onehot編碼(學歷、狀態...)
- train.csv中的連續特征 => 在X_train中保持不變(年齡、資本損失...)。
- X_train, X_test : 每一行包含一個510-dim的特征,代表一個樣本。
- Y_train: label = 0 表示 "<=50K" 、 label = 1 表示 " >50K " 。
項目要求
請動手編寫 gradient descent 實現 logistic regression
數據準備
項目數據集以及源碼:https://e.coding.net/xucancan1/logistic/logistic.git。
源碼:
# 下面該你動手啦! import pandas as pd import numpy as np from math import exp from math import * df=pd.read_csv("work/data/X_train",encoding="big5") #print(df) train_label=pd.read_csv("work/data/Y_train",encoding="big5") train_label=train_label.iloc[:700,1:] #處理標簽 train_label=np.array(train_label) #處理標簽 print(train_label.shape) #print(train_label) #打印標簽 df=df.iloc[:700,1:] #處理特征 print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>") df=np.array(df) df=df.astype("float") #訓練集特征的處理 #print(df.shape) #print(df)w=np.ones((511,1)) #初始化w eta=0.00000008 loop= 100 #循環次數 m=len(train_label) data=[] def sigmoid(x):return 1.0/(1+exp(-x)) for k in df:data.append([1.0,*k]) #每一個特征數據樣本添加一個1.0 #print(np.shape(data)) data=np.array(data) #特征數據 #print(data)w=np.mat(w) data=np.mat(data)for i in range(1000): #梯度下降,第一種:根據矩陣乘法直接計算wh1=[]for k in range(m):h=sigmoid(np.dot(data[k],w))h1.append(h)h2=np.array(h1)h2=h2.reshape(700,1) #變成列向量#print(h2.shape)err=train_label-h2w+=eta*data.transpose()*err #用矩陣梯度下降,下面也是 #print(w.shape)打印參數w #print(w) ''' for i in range(100): #梯度下降,第二種:一個一個的下降,訓練模型參數wfor k in range(m):h=sigmoid(np.dot(data[k],w))err=train_label[k]-h#print(err)d=data[k].reshape(511,1)d=np.array(d)w+=eta*err*d #梯度下降print(w) '''test=pd.read_csv("work/data/X_test",encoding="big5") #處理測試集 test=test.iloc[:,1:] #處理數據集 test=np.array(test) print(test.shape) #print(test) true=1 false=0 for t in test: #在每個測試樣本增加一個1.0的特征值,并預測年收入dt=[1.0,*t]h=np.dot(dt,w)if h>0:print(true) #輸出為1,大于5000else:print(false) #輸出為0,小于等于5000邏輯回歸也可以做以下的二分類問題:
1.區分是否是垃圾郵件
2.銀行判斷是否給用戶辦信用卡
3.從氙氣病癥預測病馬的死亡率
?
總結
以上是生活随笔為你收集整理的逻辑斯谛回归(Logistic回归)最详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 贪心算法———房间搬桌子
- 下一篇: 基于感知机的手写体识别