任務安排
1、機器學習導論 8、稀疏表示
2、KNN及其實現 9、核方法
3、K-means聚類 10、高斯混合模型
4、主成分分析 11、嵌入學習
5、線性判別分析 12、強化學習
6、貝葉斯方法 13、PageRank
7、邏輯迴歸 14、深度學習
邏輯迴歸(LR)
Ⅰ最大似然估計
後面的線性迴歸及邏輯迴歸均會用到最大似然估計,這裏提前講解,方便後續使用
似然函數:
設 爲離散隨機變量, 爲待估計的多維參數向量,若隨機變量 相互獨立且與 同分布,
記,則 稱 爲似然函數(Likelihood function)
最大似然估計算法:
①寫出似然函數: 爲樣本數量,似然函數表示 個樣本(事件)同時發生的概率
②對似然函數取對數: ③將對數似然函數對各參數求偏導並令其爲0,得到對數似然方程組
④求解方程組得到各個參數
Ⅱ 線性迴歸(Linear Regression)
模型介紹
迴歸分析目的: 設法找出變量間的關聯/依存(數量)關係,用函數關係式表達
①一元線性迴歸:
其中:
是截距
是迴歸係數(迴歸直線的斜率)
是殘差/損失(服從高斯分佈)
②多元線性迴歸:
其中:
是常數項,是各變量都等於0時,因變量的估計值,也稱本底值
是偏回歸係數,其統計學意義是在其他所有自變量不變的情況下,某一自變量每變化一個單位,因變量平均變化的單位數
★目標函數
①目標函數求解
線性迴歸假設特徵和結果滿足線性關係,得到預測模型(幾何意義是一個擬合平面) 表示 對預測值 的影響權重
代入之前的模型,則得 是每個樣本點與預測值的差值(損失)
現在的問題就變成,要利用最大似然估計,求解最合適的 ,使得 最小,因爲線性迴歸假設損失滿足高斯分佈,故得似然函數 對數似然函數 展開化簡
把可以求得的常數去掉,得到目標函數(保留爲了得到最小二乘法公式)
②目標函數優化(最小二乘法)
令偏導 ,則
最終,我們成功找到了使樣本點到迴歸模型距離最短的線(面)
Ⅲ 邏輯迴歸(Logistic Regression)
線性迴歸與非線性迴歸
學習了線性迴歸,我們已經能較好地解決符合線性特徵的樣本了,但是,如果樣本是如下圖一樣非線性的,又該如何解決呢?——邏輯迴歸
雖然線性迴歸和邏輯迴歸都屬於監督學習範疇,但不同於線性迴歸的是,名字帶有“迴歸”的邏輯迴歸,不屬於迴歸,而屬於分類,根本原因在於它以對數機率函數(Logistic function)作爲激活函數(在人工神經網絡的神經元上運行的函數,負責將神經元的輸入映射到輸出端),使其取值範圍被限定在了 ,因此邏輯迴歸常常用來解決二分類、非線性問題(當然也可以通過設定多閾值來解決多分類問題)
對數機率函數(Logistic function)
如圖是 函數,是 函數(形狀S型函數)的代表,其特點是自變量在0的附近時,因變量會迅速分離開來,因此對於二分類問題非常方便,其函數表達式爲
故可以得到邏輯迴歸預測函數
對上式變換,得到 ,即對於輸入 ,預測的分類結果有:
損失函數
不同於線性迴歸假設損失滿足高斯分佈,邏輯迴歸假設損失滿足伯努利分佈(二項分佈在試驗次數n=1時的特例)
類比之前用最大似然估計的求法,似然函數: 取對數,對數似然函數: 定義目標函數爲: 該函數也叫交叉熵損失函數,在通信原理中常用
梯度下降法
對於非線性問題,最小二乘法也可以使用,但是比起線性會複雜不少,故這裏採用梯度下降(迭代)來求解參數
參數更新公式:
參考 線性迴歸
邏輯迴歸(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)
效果圖(可以看到,在比較複雜的數據集裏,邏輯迴歸的性能會略好於別的分類方法,且線性迴歸性能隨數據集複雜程度上升迅速下降)
根據官方給的該 函數返回值,是以決定係數(coefficient of determination)來判斷迴歸方程擬合程度的
①平均值②總平方和(The total sum of squares)③迴歸平方和(The regression sum of squares)④決定係數(Coefficient of determination)
所以 函數返回值越接近1表示擬合程度越好,且有可能負數(這裏和統計學裏的可決係數定義不一樣,統計學裏的可決係數 )
2、CIFAR10在很多地方都有提供,老師讓我們用 裏的,可以直接導入( 是一個開源的 Python 機器學習庫(也有 C++,Java的庫),基於 ,用於自然語言處理等應用程序)
然而安裝 前,又又又又又更新了,結果這次不知道什麼原因,用機器學習實戰筆記1——機器學習導論裏原來記的命令行沒更新成功,看了 裏面有新版20.1的包,但是安裝 就是叫我升級,升級了就報錯,無奈之下,又找到了一個新的升級方法——在 的 裏手動更新
雙擊 一欄下方要更新的那個包
注意 左邊 和右邊 都要勾選
更新完成再用下面命令行安裝
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張,量實在是太大了,跑全部的時候電腦熱得可怕,有電腦好的感興趣的可以試試跑全部的效果,還可以試試線性迴歸分類,效果應該是非常不好的)