1. 程式人生 > >sklearn 學習筆記-3 機器學習理論基礎

sklearn 學習筆記-3 機器學習理論基礎

本章主要知識點:

  1. 過擬合和欠擬合的概念
  2. 模型的成本及成本函式的含義
  3. 評價一個模型的好壞的標準
  4. 學習曲線,以及用學習曲線來對模型進行診斷
  5. 通用模型優化方法
  6. 其他模型評價標準

##3.1過擬合和欠擬合
過擬合就是模型能很好的擬合訓練樣本,但對新資料的預測性很差。欠擬合是指模型不能很好的擬合訓練樣本。且對新資料的預測的準確性也不好。
隨機生成20個眼本店的訓練樣本:


%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
n_dots = 20
x = np.linspace(0, 1, n_dots)                   # [0, 1] 之間建立 20 個點
y = np.sqrt(x) + 0.2*np.random.rand(n_dots) - 0.1;

樣本為   y = x + r \ y=\sqrt{x}+r

+r,其中r 是[-0.1,0.1]之間的一個隨機數。
然後用一階多項式,二階多項式,十階多項式來擬合這個資料集,得到如下三個圖。
說明:圖中的點是我們生存的20個訓練樣本點;虛線中實際的模型   y = x \ y=\sqrt{x}
;實線是我們用訓練樣本擬合出來的模型。

過擬合和欠擬合

左邊是欠擬合,也稱為高偏差,一階多項式嘗試用一條直線去擬合數據,右側為過擬合,也稱為高方差,用了十階多項式來擬合數據,雖然模型對享有資料擬合的較好,但對新資料預測誤差卻很大,只有中間很好的擬合來資料集,可以看到虛線和實現基本重合。

以上曲線圖是由以下方法繪製,曲線繪製方法函式:

def plot_polynomial_fit(x, y, order):
    p = np.poly1d(np.polyfit(x, y, order)) 
    #np.ployfit(x,y,order)為用最小二乘法擬合x,y,自由度order
	    #np.poly1d(2,1,1) 2*x*x+x+1

    # 畫出擬合出來的多項式所表達的曲線以及原始的點
    t = np.linspace(0, 1, 200)
    plt.plot(x, y, 'ro', t, p(t), '-', t, np.sqrt(t), 'r--')
    return p

呼叫此函式繪圖

plt.figure(figsize=(18, 4), dpi=200)
titles = ['Under Fitting', 'Fitting', 'Over Fitting']
models = [None, None, None]
for index, order in enumerate([1, 3, 10]):
    plt.subplot(1, 3, index + 1)
    models[index] = plot_polynomial_fit(x, y, order)
    plt.title(titles[index], fontsize=20)

##3.2成本函式
成本是衡量模型與訓練樣本符合程度的指標。
成本是針對所有的訓練樣本,模型擬合出來的值與訓練樣本真實值的誤差平均值。
成本函式是成本與模型引數的函式關係。
模型訓練的過程就是找出合適的模型引數,讓成本函式的值最小。
針對一階多項式模型,不同的引數擬合出來的直線和訓練樣本之間的關係。 y = k 1 + k 2 x y=k1+k2*x
[k1,k2]就是一個模型引數,訓練這個模型,使所有的訓練集的點到這條直線的距離最短。
這裡寫圖片描述

# 添加註釋
# 第一個引數是註釋的內容
# xy設定箭頭尖的座標
# xytext設定註釋內容顯示的起始位置
# arrowprops 用來設定箭頭
# facecolor 設定箭頭的顏色
# headlength 箭頭的頭的長度
# headwidth 箭頭的寬度
# width 箭身的寬度
plt.annotate(u"This is a zhushi", xy = (0, 1), xytext = (-4, 50),\
             arrowprops = dict(facecolor = "r", headlength = 10, headwidth = 30, width = 20))
# 可以通過設定xy和xytext中座標的值來設定箭身是否傾斜
# 針對一階多項式的模型,不同的引數擬合出來的直線和訓練樣本對應的位置關係
coeffs_1d = [0.2, 0.6]

plt.figure(figsize=(9, 6), dpi=200)
t = np.linspace(0, 1, 200)
plt.plot(x, y, 'ro', t, models[0](t), '-', t, np.poly1d(coeffs_1d)(t), 'r-')
plt.annotate(r'L1: $y = {1} + {0}x$'.format(coeffs_1d[0], coeffs_1d[1]),
             xy=(0.8, np.poly1d(coeffs_1d)(0.8)), xycoords='data',
             xytext=(-90, -50), textcoords='offset points', fontsize=16,
             arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))
plt.annotate(r'L2: $y = {1} + {0}x$'.format(models[0].coeffs[0], models[0].coeffs[1]),
             xy=(0.3, models[0](0.3)), xycoords='data',
             xytext=(-90, -50), textcoords='offset points', fontsize=16,
             arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))

##3.3模型準確性
測試資料集的成本是描述模型準確性的最直觀的的指標。成本越小,說明模型預測出來的值與實際值差異越小。對顯得資料的預測準確性越好。
###3.3.1 模型效能的不同表述方式
在sciki-learn中,使用分數來表達模型效能,在0~1之間,數值越大說明模型準確性越好,誤差越小,成本越低。
###3.3.2 交叉驗證資料集
一個科學的方法將資料集分為三分,訓練資料集,交叉驗證資料集,測試資料集。比例為6:2:2
測試資料集的主要功能是測試模型的準確性,需要確保模型“沒見過”這些資料。若我們用測試資料集來選擇引數,相當於把測試資料集讓模型看到了,這樣選擇出來的引數本來就是對模型友好的。
我們用懸鏈資料集來訓練演算法引數,用交叉驗證資料集來驗證引數,選擇交叉資料集的成本Jcv(θ)最小的模型引數來最為模型引數,最後再用測試資料集來測試選擇出來的模型針對測試資料集的準確性。
##3.4 學習曲線

把Jtrain(θ)和 Jcv(θ )為縱座標,畫出與資料集m的大小關係。這就是學習曲線,通過學習曲線可以直觀的看出模型的準確性與訓練資料集的大小的關係。
如果資料集的大小為m,則通過以下流程來畫出學習曲線。

  • 把資料集分為訓練資料集和交叉驗證資料集
  • 去蓄念資料集的20%作為訓練樣本,訓練出模型引數。
  • 使用交叉驗證資料集來計算訓練出來的模型的準確性
  • 以訓練資料集的準確性,交叉驗證訓練集的準確性為縱座標,以資料集的大小為橫座標,在座標軸上畫出上述步驟計算出來的模型準確性。
    -訓練資料集增加10%,跳到第三步執行,知道訓練資料集的大小為100%為止。
    學習曲線想要表達的內容是,當訓練資料集增加時,模型對訓練資料擬合的準確性及對交叉驗證資料集預測的準確性的變化規律。

###3.4.1畫出學習曲線

##3.6查準率和召回率
定義:
查準率:Precision=TruePosition/(TruePosition+FalsePositive)
召回率:Recall=TruePositive/(TruePositive+FalseNegative)

如何理解True/False和Positive/Negative?True/False 表示預測結果是否正確,而Positive/Negative表示預測結果是1(惡性腫瘤)還是0(良性腫瘤)
TurePositive表示正確地預測出惡性腫瘤的數量,False表示錯誤地預測出惡性腫瘤的數量。
在處理先驗概率較低的問題時,我們總是把概率較低的事件定義為1,並且把y=1作為Positive的預測結果。

##3.7 F1 Score
引入F1score的概念:
F1Score=2*PR/(P+R)
其中P是查準率,R是召回率。這樣就可以用一個數值判斷哪個演算法效能更好。 在scikit-learn中,的介面為sklearn.metrics.f1_score().