機器學習實戰筆記7——邏輯迴歸

任務安排

1、機器學習導論       8、稀疏表示
2、KNN及其實現       9、核方法
3、K-means聚類      10、高斯混合模型
4、主成分分析          11、嵌入學習
5、線性判別分析      12、強化學習
6、貝葉斯方法          13、PageRank
7、邏輯迴歸              14、深度學習

邏輯迴歸(LR)

Ⅰ最大似然估計

      後面的線性迴歸及邏輯迴歸均會用到最大似然估計,這裏提前講解,方便後續使用

似然函數:

                      設 XX 爲離散隨機變量,θ=(θ1,...,θk)θ=(θ_1,...,θ_k) 爲待估計的多維參數向量,若隨機變量 x1,...,xnx_1,...,x_n 相互獨立且與 XX 同分布,
P(Xi=xi)=p(xi;θ)P(X_i=x_i)=p(x_i;θ),則P(X1=x1,...,Xn=xn)=i=1nP(Xi=xi)=i=1np(xi;θ)P(X_1=x_1,...,X_n=x_n)=∏^n_{i=1}P(X_i=x_i)=∏^n_{i=1}p(x_i;θ)        稱 L(θ)=i=1np(xi;θ)L(θ)=∏^n_{i=1}p(x_i;θ) 爲似然函數(Likelihood function)

最大似然估計算法:

             ①寫出似然函數:L(θ1,...,θk)=L(x1,...,xn;θ1,...,θk)=i=1nf(xi;θ1,...,θk)L(θ_1,...,θ_k)=L(x_1,...,x_n;θ_1,...,θ_k)=∏^n_{i=1}f(x_i;θ_1,...,θ_k)        nn 爲樣本數量,似然函數表示 nn 個樣本(事件)同時發生的概率
             ②對似然函數取對數:lnL(θ1,...,θk)=i=1nlnf(xi;θ1,...,θk)\ln L(θ_1,...,θ_k)=∑^n_{i=1}\ln f(x_i;θ_1,...,θ_k)             ③將對數似然函數對各參數求偏導並令其爲0,得到對數似然方程組
             ④求解方程組得到各個參數

Ⅱ 線性迴歸(Linear Regression)

模型介紹

      迴歸分析目的: 設法找出變量間的關聯/依存(數量)關係,用函數關係式表達
      ①一元線性迴歸: yi=a+bxi+eiy_i=a+bx_i+e_i
      其中:
               aa 是截距
               bb 是迴歸係數(迴歸直線的斜率)
               eie_i 是殘差/損失(服從高斯分佈)

      ②多元線性迴歸:yi=b0+b1x1i++bnxni+eiy_i=b_0+b_1x_{1i}+…+b_nx_{ni}+e_i
      其中:
               b0b_0 是常數項,是各變量都等於0時,因變量的估計值,也稱本底值
               bib_i 是偏回歸係數,其統計學意義是在其他所有自變量不變的情況下,某一自變量每變化一個單位,因變量平均變化的單位數

★目標函數

      ①目標函數求解
      線性迴歸假設特徵和結果滿足線性關係,得到預測模型(幾何意義是一個擬合平面)hθ(x)=θ0+θ1x1+θ2x2+=i=1nθixi=hθ(x)=θTxh_θ(x)=θ_0+θ_1x_1+θ_2x_2+……=∑^n_{i=1}θ_ix_i=h_θ(x)=θ^Tx      θθ 表示 xx 對預測值 hθ(x)h_θ(x) 的影響權重
      代入之前的模型,則得 yi=θTxi+εiy_i=θ^Tx_i+ε_i      εiε_i 是每個樣本點與預測值的差值(損失)

      現在的問題就變成,要利用最大似然估計,求解最合適的 θTθ^T,使得 εiε_i 最小,因爲線性迴歸假設損失滿足高斯分佈,故得似然函數L(θ)=i=1np(yixi;θ)=i=1n12πσe(yiθTxi)22σ2L(θ)=∏^n_{i=1}p(y_i|x_i;θ)=∏^n_{i=1}\frac{1}{\sqrt{2π}σ}e^{-\frac{(y_i-θ^Tx_i)^2}{2σ^2}}      對數似然函數lnL(θ)=lni=1n12πσe(yiθTxi)22σ2\ln L(θ)=\ln ∏^n_{i=1}\frac{1}{\sqrt{2π}σ}e^{-\frac{(y_i-θ^Tx_i)^2}{2σ^2}}      展開化簡i=1nln12πσe(yiθTxi)22σ2=nln12πσ1σ212i=1n(yiθTxi)2∑^n_{i=1}\ln \frac{1}{\sqrt{2π}σ}e^{-\frac{(y_i-θ^Tx_i)^2}{2σ^2}}=n\ln \frac{1}{\sqrt{2π}σ}-\frac{1}{σ^2}·\frac{1}{2}∑^n_{i=1}(y_i-θ^Tx_i)^2
      把可以求得的常數去掉,得到目標函數(保留12\frac{1}{2}爲了得到最小二乘法公式)minJ(θ)=12i=1n(yiθTxi)2\min J(θ)=\frac{1}{2}∑^n_{i=1}(y_i-θ^Tx_i)^2
      ②目標函數優化(最小二乘法)
            J(θ)=12i=1n(yiθTxi)2=12(Xθy)T(Xθy)J(θ)=\frac{1}{2}∑^n_{i=1}(y_i-θ^Tx_i)^2=\frac{1}{2}(Xθ-y)^T(Xθ-y)

       θJ(θ)=θ(12(Xθy)T(Xθy))\triangledown_{θ}J(θ)=\triangledown_{θ}(\frac{1}{2}(Xθ-y)^T(Xθ-y))

                     =θ(12(θTXTyT)(Xθy))=\triangledown_{θ}(\frac{1}{2}(θ^TX^T-y^T)(Xθ-y))

                     =θ(12(θTXTXθθTXTyyTXθ+yTy))=\triangledown_{θ}(\frac{1}{2}(θ^TX^TXθ-θ^TX^Ty-y^TXθ+y^Ty))

                     =12(2XTXθXTy(yTX)T)=\frac{1}{2}(2X^TXθ-X^Ty-(y^TX)^T)

                     =XTXθXTy=X^TXθ-X^Ty

令偏導 θJ(θ)=0\triangledown_{θ}J(θ)=0,則 θ=(XTX)1XTyθ=(X^TX)^{-1}X^Ty
最終,我們成功找到了使樣本點到迴歸模型距離最短的線(面)
在這裏插入圖片描述

Ⅲ 邏輯迴歸(Logistic Regression)

線性迴歸與非線性迴歸

      學習了線性迴歸,我們已經能較好地解決符合線性特徵的樣本了,但是,如果樣本是如下圖一樣非線性的,又該如何解決呢?——邏輯迴歸
在這裏插入圖片描述
      雖然線性迴歸和邏輯迴歸都屬於監督學習範疇,但不同於線性迴歸的是,名字帶有“迴歸”的邏輯迴歸,不屬於迴歸,而屬於分類,根本原因在於它以對數機率函數(Logistic function)作爲激活函數(在人工神經網絡的神經元上運行的函數,負責將神經元的輸入映射到輸出端),使其取值範圍被限定在了 [0,1][0,1],因此邏輯迴歸常常用來解決二分類、非線性問題(當然也可以通過設定多閾值來解決多分類問題)

對數機率函數(Logistic function)

      如圖是 LogisticLogistic 函數,是 SigmoidSigmoid 函數(形狀S型函數)的代表,其特點是自變量在0的附近時,因變量會迅速分離開來,因此對於二分類問題非常方便,其函數表達式爲g(z)=11+ezg(z)=\frac{1}{1+e^{-z}}
在這裏插入圖片描述
故可以得到邏輯迴歸預測函數 hθ(x)=g(θTx)=11+eθTxh_θ(x)=g(θ^Tx)=\frac{1}{1+e^-θ^Tx}
對上式變換,得到 lnhθ(x)1hθ(x)=θTx\ln \frac{h_θ(x)}{1-h_θ(x)}=θ^Tx,即對於輸入 xx,預測的分類結果有:P(y=1x;θ)=hθ(x)P(y=1|x;θ)=h_θ(x)P(y=0x;θ)=1hθ(x)P(y=0|x;θ)=1-h_θ(x)

損失函數

      不同於線性迴歸假設損失滿足高斯分佈,邏輯迴歸假設損失滿足伯努利分佈(二項分佈在試驗次數n=1時的特例)
      類比之前用最大似然估計的求法,似然函數:L(θ)=i=1mp(yx;θ)=i=1mhθ(xi)yi(1hθ(xi))1yiL(θ)=∏^m_{i=1}p(y|x;θ)=∏^m_{i=1}h_θ(x_i)^{y_i}(1-h_θ(x_i))^{1-y_i}      取對數,對數似然函數:lnL(θ)=i=1myilnhθ(xi)+(1yi)ln(1hθ(xi))\ln L(θ)=∑^m_{i=1}y_i\ln h_θ(x_i)+(1-y_i)\ln (1-h_θ(x_i))      定義目標函數爲:minJ(θ)=1m[i=1myilnhθ(xi)+(1yi)ln(1hθ(xi))]\min J(θ)=-\frac{1}{m}[∑^m_{i=1}y_i\ln h_θ(x_i)+(1-y_i)\ln (1-h_θ(x_i))]      該函數也叫交叉熵損失函數,在通信原理中常用

梯度下降法

      對於非線性問題,最小二乘法也可以使用,但是比起線性會複雜不少,故這裏採用梯度下降(迭代)來求解參數
      參數更新公式θj:=θjαθjJ(θ)=θjα1mi=1m(hθ(x(i)y(i))xj(i))θ_j:=θ_j-α\frac{\partial}{\partialθ_j}J(θ)=θ_j-α\frac{1}{m}∑^m_{i=1}(h_θ(x^{(i)}-y^{(i)})x_j^{(i)})
參考 線性迴歸
邏輯迴歸(Logistic Regression, LR)簡介

今日任務

1.給定圖像數據集,比較分類性能在這裏插入圖片描述
2.給定圖像數據集CIFAR10,比較分類性能
在這裏插入圖片描述

任務解決

1、老師還讓我們也跑一下線性迴歸的,不難,寫法和之前差不多

from sklearn.datasets import load_digits
from sklearn.linear_model import LogisticRegression, LinearRegression
from sklearn.model_selection import train_test_split
import numpy as np
import os
import cv2 as cv


def createDatabase(path):
    # 查看路徑下所有文件
    TrainFiles = os.listdir(path)  # 遍歷每個子文件夾
    # 計算有幾個文件(圖片命名都是以 序號.jpg方式)
    Train_Number = len(TrainFiles)  # 子文件夾個數
    X_train = []
    y_train = []
    # 把所有圖片轉爲1維並存入X_train中
    for k in range(0, Train_Number):
        Trainneed = os.listdir(path + '/' + TrainFiles[k])  # 遍歷每個子文件夾裏的每張圖片
        Trainneednumber = len(Trainneed)  # 每個子文件裏的圖片個數
        for i in range(0, Trainneednumber):
            image = cv.imread(path + '/' + TrainFiles[k] + '/' + Trainneed[i]).astype(np.float32)  # 數據類型轉換
            image = cv.cvtColor(image, cv.COLOR_RGB2GRAY)  # RGB變成灰度圖
            X_train.append(image)
            y_train.append(k)
    X_train = np.array(X_train)
    y_train = np.array(y_train)
    return X_train, y_train


# 邏輯迴歸分類器
def test_LR(*data):
    X_train, X_test, y_train, y_test = data
    lr = LogisticRegression(max_iter=10000)
    lr.fit(X_train, y_train)
    print('邏輯迴歸分類器')
    print('Testing Score: %.4f' % lr.score(X_test, y_test))
    return lr.score(X_test, y_test)


def test_Linear(*data):
    X_train, X_test, y_train, y_test = data
    linear = LinearRegression()
    linear.fit(X_train, y_train)
    print('線性迴歸分類器')
    print('Testing Score: %.4f' % linear.score(X_test, y_test))


path_face = 'C:/Users/1233/Desktop/Machine Learning/face_images/'
path_flower = 'C:/Users/1233/Desktop/Machine Learning/17flowers/'


X_train_flower, y_train_flower = createDatabase(path_flower)
X_train_flower = X_train_flower.reshape(X_train_flower.shape[0], 180*200)
X_train_flower, X_test_flower, y_train_flower, y_test_flower = \
    train_test_split(X_train_flower, y_train_flower, test_size=0.2, random_state=22)

digits = load_digits()
X_train_digits, X_test_digits, y_train_digits, y_test_digits = \
    train_test_split(digits.data, digits.target, test_size=0.2, random_state=22)

X_train_face, y_train_face = createDatabase(path_face)
X_train_face = X_train_face.reshape(X_train_face.shape[0], 180*200)
X_train_face, X_test_face, y_train_face, y_test_face = \
    train_test_split(X_train_face, y_train_face, test_size=0.2, random_state=22)

print('17flowers分類')
test_LR(X_train_flower, X_test_flower, y_train_flower, y_test_flower)
test_Linear(X_train_flower, X_test_flower, y_train_flower, y_test_flower)
print('Digits分類')
test_LR(X_train_digits, X_test_digits, y_train_digits, y_test_digits)
test_Linear(X_train_digits, X_test_digits, y_train_digits, y_test_digits)
print('Face images分類')
test_LR(X_train_face, X_test_face, y_train_face, y_test_face)
test_Linear(X_train_face, X_test_face, y_train_face, y_test_face)

效果圖(可以看到,在比較複雜的數據集裏,邏輯迴歸的性能會略好於別的分類方法,且線性迴歸性能隨數據集複雜程度上升迅速下降
在這裏插入圖片描述
      根據官方給的該 scorescore 函數返回值,是以決定係數(coefficient of determination)來判斷迴歸方程擬合程度的
①平均值yˉ=1ni=1nyi\bar y=\frac{1}{n}∑^n_{i=1}y_i②總平方和(The total sum of squares)SStot=(yiyˉ)2SS_{tot}=∑(y_i-\bar y)^2③迴歸平方和(The regression sum of squares)SSreg=(fiyˉ)2SS_{reg}=∑(f_i-\bar y)^2④決定係數(Coefficient of determination)R2=1SSregSStotR^2=1-\frac{SS_{reg}}{SS_{tot}}
所以 scorescore 函數返回值越接近1表示擬合程度越好,且有可能負數(這裏和統計學裏的可決係數定義不一樣,統計學裏的可決係數 R2[0,1]R^2∈[0, 1]

2、CIFAR10在很多地方都有提供,老師讓我們用 PyTorchPyTorch 裏的,可以直接導入(PyTorchPyTorch 是一個開源的 Python 機器學習庫(也有 C++,Java的庫),基於 TorchTorch,用於自然語言處理等應用程序)

      然而安裝 pytorchpytorch 前,pippip又又又又又更新了,結果這次不知道什麼原因,用機器學習實戰筆記1——機器學習導論裏原來記的命令行沒更新成功,看了sitepackagesite-package 裏面有新版20.1的包,但是安裝 pytorchpytorch 就是叫我升級,升級了就報錯,無奈之下,又找到了一個新的升級方法——pycharmpycharmsettingsetting裏手動更新
在這裏插入圖片描述
在這裏插入圖片描述
雙擊 LatestLatest  versionversion 一欄下方要更新的那個包
在這裏插入圖片描述
注意 左邊 InstalltoInstall to …… 和右邊 SpecifySpecify  versionversion 都要勾選
更新完成再用下面命令行安裝 pytorchpytorch

pip install torch==1.3.1 -f https://download.pytorch.org/whl/torch_stable.html
pip install torchvision==0.4.1

PyTorch官網根據他們給的命令行下載也可以,但是通常速度非常慢
在這裏插入圖片描述
安裝完以後,終於是可以開始跑了,用PyTorch中文文檔裏給的python代碼把數據集CIFAR10載下來即可

from torchvision.datasets import CIFAR10

CIFAR10(root=path, download=True)

當然,它是從官網上載的,非常慢,找到了一個前輩分享的CIFAR10百度雲鏈接,下載以後解壓出來,根據文檔說的,把解壓後的文件夾改成 “cifar-10-batches-py”,或者再用上面代碼跑一遍,就會自動解壓,輸出

Files already downloaded and verified

即可
在這裏插入圖片描述
接下來是真的可以開始測試CIFAR10的分類性能了

import pickle
import numpy as np
from sklearn.linear_model import LogisticRegression
from myModule import clustering_performance
from sklearn.neighbors import KNeighborsClassifier
from sklearn import naive_bayes

path = 'C:/Users/1233/Desktop/Machine Learning/CIFAR10/cifar-10-batches-py/'


def unpickle(file):  # 官方給的例程
    with open(file, 'rb') as fo:
        cifar = pickle.load(fo, encoding='bytes')
    return cifar


def test_LR(*data):
    X_train, X_test, y_train, y_test = data
    lr = LogisticRegression(max_iter=10000)
    lr.fit(X_train, y_train)
    # ACC = lr.score(X_test, y_test)
    print('邏輯迴歸分類器')
    print('Testing Score: %.4f' % lr.score(X_test, y_test))
    # print('Testing Score: %.4f' % ACC)
    return lr.score(X_test, y_test)


def test_GaussianNB(*data):
    X_train, X_test, y_train, y_test = data
    cls = naive_bayes.GaussianNB()  # ['BernoulliNB', 'GaussianNB', 'MultinomialNB', 'ComplementNB','CategoricalNB']
    cls.fit(X_train, y_train)
    # print('高斯貝葉斯分類器')
    print('貝葉斯分類器')
    print('Testing Score: %.4f' % cls.score(X_test, y_test))
    return cls.score(X_test, y_test)


def test_KNN(*data):
    X_train, X_test, y_train, y_test = data
    knn = KNeighborsClassifier()
    knn.fit(X_train, y_train)
    y_sample = knn.predict(X_test)
    print('KNN分類器')
    ACC = clustering_performance.clusteringMetrics1(y_test, y_sample)
    print('Testing Score: %.4f' % ACC)
    return ACC


test_data = unpickle(path + 'test_batch')
for i in range(1, 4):
    train_data = unpickle(path + 'data_batch_' + str(i))
    X_train, y_train = train_data[b'data'][0:1234], np.array(train_data[b'labels'][0:1234])
    X_test, y_test = test_data[b'data'][0:1234], np.array(test_data[b'labels'][0:1234])
    print('data_batch_' + str(i))
    test_KNN(X_train, X_test, y_train, y_test)
    test_GaussianNB(X_train, X_test, y_train, y_test)
    test_LR(X_train, X_test, y_train, y_test)

效果圖(訓練集:測試集 = 1:1 只分別跑了batch1~3的前1234張,量實在是太大了,跑全部的時候電腦熱得可怕,有電腦好的感興趣的可以試試跑全部的效果,還可以試試線性迴歸分類,效果應該是非常不好的)
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章