數據挖掘-邏輯Logistic回歸


        邏輯回歸的基本過程:a建立回歸或者分類模型--->b 建立代價函數 ---> c 優化方法迭代求出最優的模型參數  --->d 驗證求解模型的好壞。

1.邏輯回歸模型:

 

邏輯回歸(Logistic Regression):既可以看做是回歸算法,也可以看做是分類算法。通常作為分類算法,一般用於解決二分類問題。

線性回歸模型如下:

 

邏輯回歸思想是基於線性回歸(Logistic  Regression是廣義的線性回歸模型),公式如下:

其中,

稱為Sigmoid函數

由圖可知:Sigmoid函數值域是在(0 , 1)之間,中間值為0.5 ,所以邏輯回歸函數可以表示數據屬於某一類別的概率:

h_θ(x)  ≥ 0.5,預測 y=1 類

h_θ(x) <  0.5,預測 y=0類

2.代價函數

代價函數是基於最大似然函數推導出來的。

將上式(1)可寫成下面這個式子:

將式子乘一個(-1/m),使用梯度下降法求最優解 θ 參數

 

當x和y為多維時:

            

2.1 梯度下降法求解最小值

         求解函數的最優解(極大值和極小值),在數學中我們一般會對函數求導,然后讓導數等於0,獲得方程,然后通過解方程直接得到結果。但是在機器學習中,我們的函數常常是多維高階的,得到導數為0的方程后很難直接求解(有些時候甚至不能求解),所以就需要通過其他方法來獲得這個結果,而梯度下降就是其中一種。

 

 

 

對θ 參數進行更新:

α 為學習率

3.正則化:

(1)過擬合問題 

過擬合即是過分擬合了訓練數據,使得模型的復雜度提高,但是泛化能力較差。

 

(2)正則化方法 :
正則化是結構風險最小化策略的實現,是在經驗風險上加一個正則化項或懲罰項。

正則項可以取不同的形式,在回歸問題中取平方損失,就是參數的L2范數,也可以取L1范數。取平方損失時,模型的損失函數變為:

 

 

lambda是正則項系數(λ): 


• 如果它的值很大,說明對模型的復雜度懲罰大,可能導致欠擬合; (使得J(θ) 最小化,當λ 值很大時,θ→0)

如:曲線為  z=θ_0+θ_1 x_1+θ_2 x_1^2+λθ_3 x_2^3      ---->       θ_3→0


• 如果它的值很小,說明比較注重對訓練數據的擬合,在訓練數據上的偏差會小,但是可能會導致過擬合。(保留更多的θ)

 正則化后的梯度下降算法θ的更新變為:

 

            

 

 

 

4.邏輯回歸的優缺點:

優點:(1)速度快, 適合二分類問題

            (2)簡單易於理解, 直接看到各個特征的權重

            (3)能容易吸收新的數據

缺點:對數據和場景的使用能力有限, 不如決策樹算法適應性強

      ​  

 

對某一銀行在降低貸款拖欠率的數據進行邏輯回歸建模:

使用穩定性選擇方法中的隨機邏輯回歸進行特征篩選, 然后對篩選后的特征建立邏輯回歸模型

#coding=gbk
#使用穩定性選擇方法中的隨機邏輯回歸進行特征篩選, 然后對篩選后的特征建立邏輯回歸模型
import pandas as pd 
import numpy as np
filename = r'D:\datasets\bankloan.xls'
data = pd.read_excel(filename)
print(data.head())
#    年齡  教育  工齡  地址   收入   負債率      信用卡負債      其他負債  違約
# 0  41   3  17  12  176   9.3  11.359392  5.008608   1
# 1  27   1  10   6   31  17.3   1.362202  4.000798   0
# 2  40   1  15  14   55   5.5   0.856075  2.168925   0
# 3  41   1  15  14  120   2.9   2.658720  0.821280   0
# 4  24   2   2   0   28  17.3   1.787436  3.056564   1
x = data.iloc[:,:8].as_matrix()
y = data.iloc[:,8].as_matrix()      #轉換成矩陣形式,使其沒有索引項    是否違約1,0

from sklearn.linear_model import RandomizedLogisticRegression as RLR
rlr = RLR()
rlr.fit(x, y)
rlr.get_support()   #獲取特征篩選結果, 
print(rlr.get_support())    #[False False  True  True False  True  True False]
print(rlr.scores_)  #[0.085 0.045 0.995 0.395 0.    0.995 0.595 0.04 ]        獲取特征結果的分數
print('通過隨機邏輯回歸模型篩選特征結束')
# print(u'有效特征為:%s' % ','.join(data.columns[rlr.get_support()]))
# x = data[data.columns[rlr.get_support()]].as_matrix()
print(u'有效特征為:%s' % ','.join(np.array(data.iloc[:,:8].columns)[rlr.get_support()]))

x = data[np.array(data.iloc[:,:8].columns)[rlr.get_support()]].as_matrix() #篩選好特征

from sklearn.linear_model import LogisticRegression as LR
lr = LR()
lr.fit(x,y)
print('通過邏輯回歸模型訓練結束')
print('模型的平均正確率為: %s' % lr.score(x,y))
# 通過隨機邏輯回歸模型篩選特征結束
# 有效特征為:工齡,地址,負債率,信用卡負債
# 通過邏輯回歸模型訓練結束
# 模型的平均正確率為: 0.8142857142857143

 

Python中邏輯回歸的實現:

#coding=gbk
'''
Created on 2018年7月2日

@author: Administrator
'''
from math import exp

import matplotlib.pyplot as plt
import numpy as np
from sklearn.datasets.samples_generator import make_blobs

#定義一個sigmoid函數
def sigmoid(num):
    if type(num)==int or type(num)== float:
        return 1.0/(1 + exp(-1 * num))
    else:
        raise ValueError('只有int and float 類型才能進行計算')

#定義一個邏輯回歸的類   
class logistic():
    def __init__(self,x,y):     #判斷輸入的數據是否符合,並將其轉換成ndarray
        if type(x) == type(y) == list:
            self.x = np.array(x)
            self.y = np.array(y)
        elif type(x) == type(y) ==np.ndarray:
            self.x = x 
            self.y = y 
        else:
            raise ValueError('輸入數據錯誤')
        
    def sigmoid(self,x):            #輸出向量整體進行sigmoid 計算后的向量結果
        s = np.frompyfunc(lambda x: sigmoid(x), 1,1)    #得到矩陣
        return s(x)
    
    def train_and_punish(self,alpha, errors , punish = 0.0001):
        '''
        alpha 為學習率
        errors 為誤差小於多少時停止迭代的次數
        punish 為懲罰系數
        times 為最大迭代次數
        '''
        self.punish = punish 
        dimension = self.x.shape[1]    #得到列的數量
        self.theta = np.random.random(dimension)    #對theta 去隨機數
        computer_error = 100000000
        times = 0
        while computer_error > errors:
            res = np.dot(self.x, self.theta)
            delta = self.sigmoid(res) - self.y      #這里使用了向量化,計算sigmoid函數得出的結果與0,1的差
            self.theta = self.theta - alpha * np.dot(self.x.T, delta) - punish * self.theta #更新學習率 
            computer_error = np.sum(delta)
            times+=1
            
        def predict(self, x):
            x = np.array(x)
            if self.sigmoid(np.dot(x, self.theta)) > 0.5:
                return 1
            else:
                return 0
            
def test():
#scikit中的make_blobs方法常被用來生成聚類算法的測試數據,
#直觀地說,make_blobs會根據用戶指定的特征數量、中心點數量、范圍等來生成幾類數據,這些數據可用於測試聚類算法的效果。
# n_samples是待生成的樣本的總數。
# n_features是每個樣本的特征數。
# centers表示類別數。
# cluster_std表示每個類別的方差,例如我們希望生成2類數據,其中一類比另一類具有更大的方差,可以將cluster_std設置為[1.0,3.0]。
#center_box 表示x,y軸的范圍
    x, y = make_blobs(n_samples=200, centers =2, n_features=2, random_state=0, center_box=(10,20))
    x1=[]
    y1=[]
    x2=[]
    y2=[]
    #生成兩類數據
    for i in range(len(y)):
        if y[i] ==0:
            x1.append(x[i][0])
            y1.append(x[i][1])
        elif y[i] == 1:
            x2.append(x[i][0])
            y2.append(x[i][1])
     
    p = logistic(x,y)
    p.train_and_punish(alpha=0.00001, errors=0.005, punish=0.01)
    x_test = np.arange(10,20,0.01)
    y_test = (-1* p.theta[0] / p.theta[1]) * x_test 
    plt.plot(x_test, y_test, c='g', label = 'logistic_line')
    plt.scatter(x1, y1, c='r', label = 'positive')
    plt.scatter(x2, y2, c='b',label ='negtive')
    plt.legend(loc =2)
    plt.title('punish value = ' + p.punish.__str__())
    plt.show() 

if __name__ == '__main__':
    test() 

 

 

 

LogisticRegression類的各項參數的含義:

class sklearn.linear_model.LogisticRegression(penalty='l2', dual=False, tol=0.0001, C=1.0, fit_intercept=True, intercept_scaling=1, class_weight=None, random_state=None, solver='liblinear', max_iter=100, multi_class='ovr', verbose=0, warm_start=False, n_jobs=1) 

penalty='l2' : 字符串‘l1’或‘l2’,默認‘l2’。

  • 用來指定懲罰的基准(正則化參數)。只有‘l2’支持‘newton-cg’、‘sag’和‘lbfgs’這三種算法。
  • 如果選擇‘l2’,solver參數可以選擇‘liblinear’、‘newton-cg’、‘sag’和‘lbfgs’這四種算法;如果選擇‘l1’的話就只能用‘liblinear’算法。

dual=False : 對偶或者原始方法。Dual只適用於正則化相為l2的‘liblinear’的情況,通常樣本數大於特征數的情況下,默認為False。C=1.0 : C為正則化系數λ的倒數,必須為正數,默認為1。和SVM中的C一樣,值越小,代表正則化越強。fit_intercept=True : 是否存在截距,默認存在。intercept_scaling=1 : 僅在正則化項為‘liblinear’,且fit_intercept設置為True時有用。solver='liblinear' : solver參數決定了我們對邏輯回歸損失函數的優化方法,有四種算法可以選擇。

  • a) liblinear:使用了開源的liblinear庫實現,內部使用了坐標軸下降法來迭代優化損失函數。
  • b) lbfgs:擬牛頓法的一種,利用損失函數二階導數矩陣即海森矩陣來迭代優化損失函數。
  • c) newton-cg:也是牛頓法家族的一種,利用損失函數二階導數矩陣即海森矩陣來迭代優化損失函數。
  • d) sag:即隨機平均梯度下降,是梯度下降法的變種,和普通梯度下降法的區別是每次迭代僅僅用一部分的樣本來計算梯度,適合於樣本數據多的時候。

 

 

正則化 算法 適用場景
L1 liblinear liblinear適用於小數據集;如果選擇L2正則化發現還是過擬合,即預測效果差的時候,就可以考慮L1正則化;如果模型的特征非常多,希望一些不重要的特征系數歸零,從而讓模型系數稀疏化的話,也可以使用L1正則化。
L2 liblinear libniear只支持多元邏輯回歸的OvR,不支持MvM,但MVM相對精確。
L2 lbfgs/newton-cg/sag 較大數據集,支持one-vs-rest(OvR)和many-vs-many(MvM)兩種多元邏輯回歸。
L2 sag 如果樣本量非常大,比如大於10萬,sag是第一選擇;但不能用於L1正則化。

multi_class='ovr' : 分類方式。官網有個對比兩種分類方式的例子:鏈接地址

  • ovr即one-vs-rest(OvR),multinomial是many-vs-many(MvM)。如果是二元邏輯回歸,ovr和multinomial並沒有任何區別,區別主要在多元邏輯回歸上。
  • ovr不論是幾元回歸,都當成二元回歸來處理。mvm從從多個類中每次選兩個類進行二元回歸。如果總共有T類,需要T(T-1)/2次分類。
  • OvR相對簡單,但分類效果相對略差(大多數樣本分布情況)。而MvM分類相對精確,但是分類速度沒有OvR快。
  • 如果選擇了ovr,則4種損失函數的優化方法liblinear,newton-cg,lbfgs和sag都可以選擇。但是如果選擇了multinomial,則只能選擇newton-cg, lbfgs和sag了。

class_weight=None : 類型權重參數。用於標示分類模型中各種類型的權重。默認不輸入,即所有的分類的權重一樣。

  • 選擇‘balanced’自動根據y值計算類型權重。
  • 自己設置權重,格式:{class_label: weight}。例如0,1分類的er'yuan二元模型,設置class_weight={0:0.9, 1:0.1},這樣類型0的權重為90%,而類型1的權重為10%。

random_state=None : 隨機數種子,默認為無。僅在正則化優化算法為sag,liblinear時有用。

max_iter=100 : 算法收斂的最大迭代次數。

tol=0.0001 : 迭代終止判據的誤差范圍。

verbose=0 : 日志冗長度int:冗長度;0:不輸出訓練過程;1:偶爾輸出; >1:對每個子模型都輸出

warm_start=False : 是否熱啟動,如果是,則下一次訓練是以追加樹的形式進行(重新使用上一次的調用作為初始化)。布爾型,默認False。

n_jobs=1 : 並行數,int:個數;-1:跟CPU核數一致;1:默認值。

 

LogisticRegression類的常用方法

  • fit(X, y, sample_weight=None)
    • 擬合模型,用來訓練LR分類器,其中X是訓練樣本,y是對應的標記向量
    • 返回對象,self。
  • fit_transform(X, y=None, **fit_params)
    • fit與transform的結合,先fit后transform。返回X_new:numpy矩陣。
  • predict(X)
    • 用來預測樣本,也就是分類,X是測試集。返回array。
  • predict_proba(X)
    • 輸出分類概率。返回每種類別的概率,按照分類類別順序給出。如果是多分類問題,multi_class="multinomial",則會給出樣本對於每種類別的概率。
    • 返回array-like。
  • score(X, y, sample_weight=None)
    • 返回給定測試集合的平均准確率(mean accuracy),浮點型數值。
    • 對於多個分類返回,則返回每個類別的准確率組成的哈希矩陣。




參考:機器學習之邏輯回歸

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM