機器學習之LinearRegression與Logistic Regression邏輯斯蒂迴歸(三)

一 評價尺度

sklearn包含四種評價尺度python

1 均方差(mean-squared-error)git

2 平均絕對值偏差(mean_absolute_error)算法

3 可釋方差得分(explained_variance_score) app

4 中值絕對偏差(Median absolute error)dom

5 R2 決定係數(擬合優度)函數

  • 模型越好:r2→1
  • 模型越差:r2→0

二 邏輯斯蒂迴歸

1 概述

在邏輯斯蒂迴歸中,咱們將會採用sigmoid函數做爲激勵函數,因此它被稱爲sigmoid迴歸或對數概率迴歸(logistic regression),須要注意的是,雖然帶有迴歸,但事實上它並非一種迴歸算法,而是一種分類算法。測試

優勢:fetch

1 它是直接對分類的可能性進行建模的,無需事先假設數據分佈,這樣就避免了假設分佈不許確所帶來的問題spa

2 其針對於分類的可能性進行建模的,因此它不只能預測出類別,還能夠獲得屬於該類別的機率code

3 實現簡單,易於理解和實現;計算代價不高,速度很快,存儲資源低

4 數據量大就用邏輯斯蒂 數據量小,特徵多,用SVM knn

缺點:

容易欠擬合,分類精度可能不高

線性迴歸與邏輯迴歸的區別

線性迴歸: 線性迴歸用來作迴歸預測,解決迴歸問題

根據幾組已知數據和擬合函數訓練其中未知參數,使得擬合損失達到最小。而後用所得擬合函數進行預測。

邏輯迴歸: 邏輯迴歸用於作二分類 , 解決分類問題

和擬合函數訓練其中未知參數 , 使得對數似然函數最大。而後用所得的擬合函數進行二分類。

線性迴歸 邏輯迴歸
目的 預測 分類
未知 {0,1}
函數 擬合函數 預測函數
參數計算方式 最小二乘 最大似然估計

注意:

1 預測函數其實就是擬合函數作了一個邏輯函數的轉換

2 最大似然估計是計算使得數據出現的可能性最大的參數,依仗的天然是Probability。而最小二乘是計算偏差損失。所以二者不可混淆

(2) 本質的區分

  • 邏輯迴歸就是對線性迴歸作了一個壓縮,將y 的值從y∈(+∞,−∞)壓縮到(0,1)。爲何簡單的壓縮就能將回歸問題變成分類問題?

  • 從數聽說起,線性迴歸的樣本的輸出,都是連續值,y∈(+∞,−∞)而,邏輯迴歸中y∈{0,1},只能取0和1。對於擬合函數也有本質上的差異:

\[ 邏輯迴歸:f(x)=p(y=1∣x;θ)=g(θTX) \]

\[ 線性迴歸:f(x)=θTX=θ1x1+θ2x2+⋯+θnxn \]

​ 線性迴歸擬合函數,的確是對f(x)的輸出變量y的擬合,而邏輯迴歸的擬合函數是對爲1類的樣本機率擬合。

  • 爲何採用1類的樣本機率進行擬合,這裏就要談到logstic函數的本質

    若要直接經過迴歸的方法去預測二分類問題, y 究竟是0類仍是1類,最好的函數是單位階躍函數。然而單位階躍函數不連續(GLM 的必要條件),而 logsitic 函數剛好接近於單位階躍函數,且單調可微。因而但願經過該複合函數去擬合分類問題,產生:

  • 因而,θTX=0就至關因而1類和0類的決策邊界:

  • \[ 當θTX>0,則有y>0.5;若θTX→+∞ ,則y→1 ,即y 爲1類; \]

  • \[ 當θTX<0,則有y<0.5 ; 若θTX→−∞,則y→0,即 y 爲0類。 \]

    這個時候就能看出區別來了,在線性迴歸中θTXθTX爲預測值的擬合函數;而在邏輯迴歸中θTX=0爲決策邊界

    ​所以利用Logistics迴歸進行分類的主要思想是:根據現有數據對分類邊界線創建迴歸公式,以此進行分類。

三 Logistic Regression實戰練習

實例: 手寫數字分類

import numpy as np
import pandas as pd
from pandas import Series,DataFrame
import matplotlib.pyplot as plt
%matplotlib inline

# LogisticRegression雖然是線性迴歸模型,可是隻能處理分類問題
# 機率模型,使用機率進行分類
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier

# 加載手寫數字集
from sklearn import datasets
digits = datasets.load_digits()    #

#輸出  {'data': array([[ 0.,  0.,  5., ...,  0.,  0.,  0.],
        [ 0.,  0.,  0., ..., 10.,  0.,  0.],
        [ 0.,  0.,  0., ..., 16.,  9.,  0.],
        ...,
        [ 0.,  0.,  1., ...,  6.,  0.,  0.],
        [ 0.,  0.,  2., ..., 12.,  0.,  0.],
        [ 0.,  0., 10., ..., 12.,  1.,  0.]]),
 'target': array([0, 1, 2, ..., 8, 9, 8]),
 'target_names': array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]),
 'images': array([[[ 0.,  0.,  5., ...,  1.,  0.,  0.],
         [ 0.,  0., 13., ..., 15.,  5.,  0.],
                   ....
data = digits.data    #(1797, 64)  表示1797條,一維64的矩陣
images = digits.images   #(1797, 8, 8)  表示1797條,8*8的二維矩陣
display(data.shape,images.shape)

plt.imshow(images[0],cmap='gray')
plt.imshow(data[0].reshape((8,8)),cmap='gray')  #將64一維轉成8*8的二維矩陣實際都是表示一組數據

# 對數據集進行拆分,獲得訓練集和測試集
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test = train_test_split(data,target,test_size=0.2,random_state=1)

#採用邏輯斯蒂迴歸模型與KNN
logistic = LogisticRegression()
knn = KNeighborsClassifier(n_neighbors=5)

#對knn與邏輯斯蒂進行訓練
logistic.fit(X_train,y_train)
y1_ = logistic.predict(X_test)
knn.fit(X_train,y_train)
y2_ = knn.predict(X_test)

查看模型評分

# 分類模型能夠查看準確率來對模型進行評價
# 直接用算法模型調用score方法來實現
logistic.score(X_test,y_test)  
knn.score(X_test,y_test)

#輸出  0.9694444444444444
      0.9944444444444445
# 模型在測試集上評分特別高,可是在真實環境下準確率卻很低,這叫病態
# 引發這種現象的緣由,主要是算法訓練的過分擬合

分類展現

# 展現分類的成果
# 取測試集的前100個數據
plt.figure(figsize=(12,16))
for i in range(100):
    axes = plt.subplot(10,10,i+1)
    img = X_test[i].reshape((8,8))
    axes.imshow(img,cmap='gray')
    axes.axis('off')
    true = y_test[i]
    knn_r = y2_[i]
    logistic_r = y1_[i]
    title = 'T:'+str(true)+'\nK:'+str(knn_r) + ' L:'+str(logistic_r)
    axes.set_title(title)

# 對logistic函數進行調參,查看參數對結果的影響
# 超參 函數級別 knn n_neibors logistic pentily C
# 模型參數 f(x) = wx+b

logistic = LogisticRegression(C=0.5,penalty='l1')
logistic.fit(X_train,y_train)
logistic.score(X_test,y_test)
#0.975

人臉的自動補全

導包

import numpy as np
import pandas as pd
from pandas import Series,DataFrame
from sklearn.datasets import fetch_olivetti_faces
import matplotlib.pyplot as plt
%matplotlib inline

提取數據

faces = fetch_olivetti_faces()
data = faces.data
images = faces.images
target = faces.target

拆分測試訓練集

from sklearn.linear_model import LinearRegression,Ridge,Lasso
from sklearn.neighbors import KNeighborsRegressor
# 拆分訓練集和測試集
from sklearn.model_selection import train_test_split

# 每一個人拿出9張照片作訓練數據,拿出1張照片作測試數據
# 樣本特徵採用上半邊臉,樣本標籤採用下半邊臉
def train_test_split_face(data,test_size):
    X_train = []
    X_test = []
    y_train = []
    y_test = []
    for i in range(40):
        for j in range(10):
            face = data[i*10+j]
            up_face = face[:2048]
            bottom_face = face[2048:]
            if j < (1-test_size)*10:
                # 保存爲訓練數據
                X_train.append(up_face)
                y_train.append(bottom_face)
            else:
                # 保存爲測試數據
                X_test.append(up_face) 
                y_test.append(bottom_face)
    return np.array(X_train),np.array(X_test),np.array(y_train),np.array(y_test)
#訓練集與測試集
X_train,X_test,y_train,y_test = train_test_split_face(data,test_size=0.1)
#拆分出的上下半邊臉
plt.imshow(X_train[0].reshape((32,64)),cmap='gray')
plt.imshow(y_train[0].reshape((32,64)),cmap='gray')

訓練模型

knn = KNeighborsRegressor()
linear = LinearRegression()
ridge = Ridge()
lasso = Lasso()

knn.fit(X_train,y_train)
linear.fit(X_train,y_train)
ridge.fit(X_train,y_train)
lasso.fit(X_train,y_train)

預測數據

# 預測全部數據
knn_y_ = knn.predict(X_test)
linear_y_ = linear.predict(X_test)
ridge_y_ = ridge.predict(X_test)
lasso_y_ = lasso.predict(X_test)


plt.figure(figsize=(10,4))

true_up_face = X_test[0]
true_bottom_face = y_test[0]
pre_bottom_face = knn_y_[0]
axes1 = plt.subplot(1,2,1)
true_face = np.concatenate((true_up_face,true_bottom_face))
axes1.imshow(true_face.reshape((64,64)),cmap='gray')
axes1.set_title('True')

axes2 = plt.subplot(1,2,2)
pre_face = np.concatenate((true_up_face,pre_bottom_face))
axes2.imshow(pre_face.reshape((64,64)),cmap='gray')
axes2.set_title('Predict')

results = np.array([knn_y_,ridge_y_,lasso_y_,linear_y_])
titles = np.array(['KNN','RIDGE','LASSO','LINEAR'])


plt.figure(figsize=(16,18))
for i in range(5):
    true_up_face = X_test[i]
    true_bottom_face = y_test[i]
    true_face = np.concatenate((true_up_face,true_bottom_face)).reshape((64,64))
    axes = plt.subplot(5,5,i*5+1)
    axes.imshow(true_face,cmap='gray')
    axes.set_title('True')
    for index,y_ in enumerate(results):
        axes = plt.subplot(5,5,i*5+1+index+1)
        pre_bottom_face = y_[index]
        pre_face = np.concatenate((true_up_face,pre_bottom_face)).reshape((64,64))
        axes.imshow(pre_face,cmap='gray')
        axes.set_title(titles[index])

數據量較少,僅爲測試使用

相關文章
相關標籤/搜索