機器學習之線性模型

線性迴歸也就是可以用一條直線來擬合一個點集。博主大概總結下機器學習的線性模型,以及主要的公式推到,參考書籍是周志華教授的西瓜書《機器學習》,博主給出了一些西書中主要的公式推導思路或過程,對於常用的邏輯迴歸模型,利用sklearn機器學習包實現對MNIST公共數據集的簡單分類應用。機器學習無非是迴歸和分類的問題,其目的就是學習一個數學函數,通過該數學函數輸入得到輸出。線性模型主要有以下三大類,也是本文要總結的三大類,其實只有前兩者是用來做迴歸的,而最後一個是做分類的

  • 一元線性迴歸模型(一個自變量和一個因變量
  • 多元線性迴歸模型(多個因變量
  • 對數機率迴歸模型(邏輯迴歸模型,用來做分類

1.一元線性迴歸模型

這個其實很好理解,直接看西瓜書給出的公式就知道:
在這裏插入圖片描述
目的很簡單,就是給定樣本輸入x求解輸出f(x),而線性迴歸模型的主要工作就是學得參數w和b且使得損失函數最小,也就是說在預測過程中,我們需要使預測值和真實值之間的誤差最小。求解參數的主要思路步驟:

  1. 由最小二乘法導出損失函數E(w,b),也就是均方誤差最小化求解。損失函數定義如下:
  2. 在這裏插入圖片描述
  3. 證損失函數是凸函數,根據二元函數凹凸性判定定理證明即可,也就是分別求出關於w和b的二階偏導值,利用AC-B^2>=0來判斷其爲凸函數。
  4. 分別對w和b求解一階偏導,並令其爲0,解出的w和b就是我們要求得的參數能使得損失函數值最小,由此可以推導出西瓜書的等式:在這裏插入圖片描述在這裏插入圖片描述
  5. 其實最後一步w參數的向量化目的是方便編程,在實際的應用中,給出的數據樣本值x一般是一個序列,向量化有助於python利用矩陣工具計算相應的參數值。

2.多元線性迴歸模型

多元迴歸模型的推導思路和一元是一樣的,但是不同的是需要把w和b統一爲向量的形式(w;b),西瓜書中直接給出了損失函數讓人看不懂:在這裏插入圖片描述
實際的推導如下*(因爲公式不好敲,這裏就貼個圖片了哈,諒解!!!)*在這裏插入圖片描述
現在最關鍵的一步就是損失函數的求解,求解最小值,這裏有兩種方式,第一種就是和一元的思路差不多,涉及到矩陣的求導和微分,第二種也是值得推薦的一種常用的方法,梯度下降法,其不只是使用在一元/多元線性迴歸上,其它機器學習的模型也常用梯度下降法來優化損失函數,求解最優參數解。現在分別大致描述下兩種方法的思路。

1. 西瓜書的思路屬於第一種,判斷凹凸性,也就是Hessian矩陣正定,則爲凸函數。Hessian矩陣其實就是在梯度(一階偏導數存在) 的類似基礎上,求解二階偏導數存在。推到過程如下:在這裏插入圖片描述
2. 梯度下降法它是用迭代的方法求解目標函數得到最優解,是在cost function(成本函數)的基礎上,利用梯度迭代求出局部最優解。
對於線性迴歸模型:
在這裏插入圖片描述
損失函數爲:
在這裏插入圖片描述

給一個初始值,使損失函數逐次變小,使每次都往梯度下降的方向改變:
在這裏插入圖片描述表示下降速度。
爲了求偏導數,當只有一個樣本時,即
在這裏插入圖片描述
當有多個訓練樣本時,下降梯度算法即爲:
在這裏插入圖片描述
由於每次迭代都需要計算所有樣本的殘差並加和,因此此方法也叫做批下降梯度法(batch gradient descent),當有大規模數據時,此方法不太適合,可採取它得一個變種,即每次更新權重時,不是計算所有的樣本,而是選取其中一個樣本進行計算梯度,這個方法叫做隨機下降梯度法(stochastic gradient descent):
在這裏插入圖片描述
隨機下降梯度法與下降梯度法對比可能收斂更快,但是可能找不到最優點而在最優點附近徘徊。

對於局部加權線性迴歸(LWLR),可以參考如下博客:
https://blog.csdn.net/tercel_w/article/details/62883704

**總結:**線性迴歸的優點計算簡單,容易實現,缺點使無法擬合非線性數據!!!

邏輯迴歸模型(對數機率迴歸)

Logistic是用來分類的,是一種線性分類器。邏輯迴歸的表達式可以通過替代函數和廣義線性模型來推導,需要記住其表達式爲:
在這裏插入圖片描述
其導數形式爲:
在這裏插入圖片描述
logsitc迴歸方法主要是用極大似然估計來學習的,所以單個樣本的後驗概率爲:
在這裏插入圖片描述
所以,整個樣本的後驗概率爲:
在這裏插入圖片描述
取對數,得似然函數
在這裏插入圖片描述
似然函數取得最大值即爲損失函數取得最小值,也可採用梯度下降法求解參數:
在這裏插入圖片描述

**總結:**邏輯迴歸的優點計算簡單,分類時計算很快;缺點就是容易欠擬合,準確度不高,只能處理兩分類問題(在此基礎上衍生出來的softmax可以用於多分類),且必須線性可分。

Logistic迴歸模型的實踐

採用的數據集爲MNIST數據,可以進入該網盤下載:鏈接
鏈接:https://pan.baidu.com/s/1kc8oLBfUKdI_oK8j60RTNw
提取碼:qcad

PyCharm+Anaconda實現代碼:

import time
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.utils import check_random_state

# 讀取數據集
df = pd.read_csv('mnist_784.csv')

#按照行號來索引,區別於loc是按照index來索引
X = df.iloc[:, :-1].values
y = df.iloc[:, -1].values

print(X.shape,y.shape) #查看維度

t0 = time.time()
train_samples = 5000 #訓練樣本大小

#check_random_state():這裏使用的是numpy.random.RandomState().RandomState()可以使用int,array,None。None的時候就是隨機。和np.random.seed()比較,seed只能用一次,每次調用隨機函數用在之前再聲明一下。
random_state = check_random_state(0)
permutation = random_state.permutation(X.shape[0]) #打亂順序
X = X[permutation]
y = y[permutation]
X = X.reshape((X.shape[0],-1)) #reshape()最後一位如果是-1,表示適應前面的分法

X_train, X_test, y_train, y_test = train_test_split(X,y,train_size=train_samples,test_size=10000) #劃分測試集和訓練集,指定訓練集和測試集的大小

#對每個特徵,數據歸一化(x-u)/s
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train) #訓練集上需要先擬合再標準化
X_test = scaler.transform(X_test) #測試集上直接標準化

"""
    @penalty:正則化類型,默認爲L2
    @tol:迭代終止判斷的誤差範圍
    @C:默認:1.0;其值等於正則化強度的倒數,爲正的浮點數。數值越小表示正則化越強。
    @solver:{'newton-cg', 'lbfgs', 'liblinear', 'sag', 'saga'},默認: 'liblinear';用於優化問題的算法。
    @multi_class:{ovr', 'multinomial'},默認:'ovr';如果選擇的選項是“ovr”,那麼一個二進制問題適合於每個標籤,否則損失最小化就是整個概率分佈的多項式損失。對liblinear solver無效。
"""
clf = LogisticRegression(C=50./train_samples,
                         multi_class='multinomial',
                         penalty='l1', solver='saga', tol=0.1)

clf.fit(X_train,y_train)  #訓練
sparsity = np.mean(clf.coef_ == 0) * 100
score = clf.score(X_test, y_test)

#打印結果
print("Sparsity with L1 penalty: %.2f%%" % sparsity)
print("Test score with L1 penalty: %.4f" % score)

coef = clf.coef_.copy()
plt.figure(figsize=(10, 5))
scale = np.abs(coef).max()
for i in range(10):
    l1_plot = plt.subplot(2, 5, i + 1)
    l1_plot.imshow(coef[i].reshape(28, 28), interpolation='nearest',
                   cmap=plt.cm.RdBu, vmin=-scale, vmax=scale)
    l1_plot.set_xticks(())
    l1_plot.set_yticks(())
    l1_plot.set_xlabel('Class %i' % i)
plt.suptitle('Classification vector for...')

run_time = time.time() - t0
print('Example run in %.3f s' % run_time)
plt.show()

結語:下一篇文章將在博主的博客**“項目”**裏,簡單運用Logistic分類模型實現達觀杯的一個文本分類競賽題,目的不是刷榜,而是想熟悉一下sklearn機器學習包的運用,以及一個機器學習算法是如何在一個實際場景中進行運用的。

參考資料:
[1]: 周志華.西瓜書《機器學習》
[2]:https://www.cnblogs.com/tornadomeet/p/3395593.html
[3]:https://blog.csdn.net/tercel_w/article/details/62883704

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