線性迴歸也就是可以用一條直線來擬合一個點集。博主大概總結下機器學習的線性模型,以及主要的公式推到,參考書籍是周志華教授的西瓜書《機器學習》,博主給出了一些西書中主要的公式推導思路或過程,對於常用的邏輯迴歸模型,利用sklearn機器學習包實現對MNIST公共數據集的簡單分類應用。機器學習無非是迴歸和分類的問題,其目的就是學習一個數學函數,通過該數學函數輸入得到輸出。線性模型主要有以下三大類,也是本文要總結的三大類,其實只有前兩者是用來做迴歸的,而最後一個是做分類的:
- 一元線性迴歸模型(一個自變量和一個因變量)
- 多元線性迴歸模型(多個因變量)
- 對數機率迴歸模型(邏輯迴歸模型,用來做分類)
1.一元線性迴歸模型
這個其實很好理解,直接看西瓜書給出的公式就知道:
目的很簡單,就是給定樣本輸入x求解輸出f(x),而線性迴歸模型的主要工作就是學得參數w和b,且使得損失函數最小,也就是說在預測過程中,我們需要使預測值和真實值之間的誤差最小。求解參數的主要思路步驟:
- 由最小二乘法導出損失函數E(w,b),也就是均方誤差最小化求解。損失函數定義如下:
- 證損失函數是凸函數,根據二元函數凹凸性判定定理證明即可,也就是分別求出關於w和b的二階偏導值,利用AC-B^2>=0來判斷其爲凸函數。
- 分別對w和b求解一階偏導,並令其爲0,解出的w和b就是我們要求得的參數能使得損失函數值最小,由此可以推導出西瓜書的等式:
- 其實最後一步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