線性迴歸原理和實現基本認識

一:介紹

       定義:線性迴歸在假設特證知足線性關係,根據給定的訓練數據訓練一個模型,並用此模型進行預測。爲了瞭解這個定義,咱們先舉個簡單的例子;咱們假設一個線性方程 Y=2x+1, x變量爲商品的大小,y表明爲銷售量;當月份x =5時,咱們就能根據線性模型預測出 y =11銷量;對於上面的簡單的例子來講,咱們能夠粗略把 y =2x+1看到迴歸的模型;對於給予的每一個商品大小都能預測出銷量;固然這個模型怎麼獲取到就是咱們下面要考慮的線性迴歸內容;而且在現實中影響銷量(y)的因素好有不少,咱們就拿商品大小(x₁),商品價格爲例 (x₂)爲例:html

      在機器學習以前,獲取數據是第一步(無米難巧婦之炊),假定咱們的樣本以下:其中x1 爲商品的大小,x2 爲商品的價格,y 爲商品的銷量;python

    

二 :模型推導

        爲了推導模型,在假設數據知足線性模型條件下,能夠設定線性模型爲;x1特徵爲商品的大小,X2特徵爲商品的價格;linux

         

       模型假定好後,咱們把訓練數據代入上面的設定模型中,能夠經過模型預測一個樣本最終值;app

         

      而後樣本真實值 y 和模型訓練預測的值之間是有偏差 ε ,再假設訓練樣本的數據量很大的時候,根據中心極限定律能夠獲得   ∑ε   知足 (u ,δ²)高斯分佈的;因爲方程有截距項 ,故使用能夠 u =0; 故知足(0,δ²)的高斯分佈;dom

  

如上面可知,對於每個樣本 x ,代入到 p (y |x ;θ) 都會獲得一個y 的機率;又由於設定樣本是獨立同分布的;對其求最大似然函數:機器學習

對其化簡以下:函數

以上就獲得了迴歸的損失函數最小二乘法的公式,對於好多介紹通常對線性迴歸的線性損失函數就直接給出了上面的公式二乘法。下面咱們就對上面作了階段性的總結:線性迴歸,根據大數定律和中心極限定律假定樣本無窮大的時候,其真實值和預測值的偏差ε 的加和服從u=0,方差=δ²的高斯分佈且獨立同分布,而後把ε =y-Øx 代入公式,就能夠化簡獲得線性迴歸的損失函數;學習

    第二步:對損失函數進行優化也就是求出w,b,使的損失函數最小化;第一種方法使用矩陣(須要知足可逆條件)優化

 以上就是按矩陣方法優化損失函數,但上面方法有必定的侷限性,就是要可逆;下面咱們來講一說另一個優化方法 梯度降低法;對於梯度降低法的說明和講解資料不少,深刻的講解這裏不進行,能夠參考:http://www.cnblogs.com/ooon/p/4947688.html這篇博客,博主對梯度降低方法進行了講解,咱們這裏就簡單的最了流程解說;spa

整體流程就如上所示,就是求出每一個變量的梯度;而後順着梯度方向按必定的步長a,進行變量更新;下面咱們就要求出每一個變量的梯度,下面對每一個θ進行梯度求解公式以下:

如上咱們求出變量的梯度;而後迭代代入下面公式迭代計算就能夠了:

上面每次更新變量,都要把全部的樣本的加起來,數據量大的時候效率不高,下面還有一種就是按單個樣本進行優化,就是隨機梯度降低:

按上面優化步驟就能夠求出w,b,就能夠得到優化的特徵方程:說這麼多先上個代碼:

# -*- coding:utf-8 -*-

import numpy as np
import warnings
from sklearn.exceptions import ConvergenceWarning
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression, RidgeCV, LassoCV, ElasticNetCV
import matplotlib as mpl
import matplotlib.pyplot as plt

if __name__ == "__main__":

    warnings.filterwarnings(action='ignore', category=ConvergenceWarning)
    np.random.seed(0)
    np.set_printoptions(linewidth=1000)
    N = 9
    x = np.linspace(0, 6, N) + np.random.randn(N)
    x = np.sort(x)
    y = x ** 2 - 4 * x - 3 + np.random.randn(N)
    x.shape = -1, 1
    y.shape = -1, 1
    p = Pipeline([
        ('poly', PolynomialFeatures()),
        ('linear', LinearRegression(fit_intercept=False))])
    mpl.rcParams['font.sans-serif'] = [u'simHei']
    mpl.rcParams['axes.unicode_minus'] = False
    np.set_printoptions(suppress=True)
    plt.figure(figsize=(8, 6), facecolor='w')
    d_pool = np.arange(1, N, 1)  # 階
    m = d_pool.size
    clrs = []  # 顏色
    for c in np.linspace(16711680, 255, m):
        clrs.append('#%06x' % c)
    line_width = np.linspace(5, 2, m)
    plt.plot(x, y, 'ro', ms=10, zorder=N)
    for i, d in enumerate(d_pool):
        p.set_params(poly__degree=d)
        p.fit(x, y.ravel())
        lin = p.get_params('linear')['linear']
        output = u'%s:%d階,係數爲:' % (u'線性迴歸', d)
        print output, lin.coef_.ravel()
        x_hat = np.linspace(x.min(), x.max(), num=100)
        x_hat.shape = -1, 1
        y_hat = p.predict(x_hat)
        s = p.score(x, y)
        z = N - 1 if (d == 2) else 0
        label = u'%d階,$R^2$=%.3f' % (d, s)
        plt.plot(x_hat, y_hat, color=clrs[i], lw=line_width[i], alpha=0.75, label=label, zorder=z)
        plt.legend(loc='upper left')
        plt.grid(True)
        # plt.title('線性迴歸', fontsize=18)
        plt.xlabel('X', fontsize=16)
        plt.ylabel('Y', fontsize=16)
    plt.show()

運行代碼後可見打印控制檯信息以下:

/home/mymotif/PycharmProjects/py2/venv/bin/python /opt/pycharm-2018.1.3/helpers/pydev/pydev_run_in_console.py 40267 39581 /home/mymotif/PycharmProjects/py2/ml1.py
Running /home/mymotif/PycharmProjects/py2/ml1.py
import sys; print('Python %s on %s' % (sys.version, sys.platform))
sys.path.extend(['/home/mymotif/PycharmProjects/py2'])
線性迴歸:1階,係數爲: [-12.12113792   3.05477422]
線性迴歸:2階,係數爲: [-3.23812184 -3.36390661  0.90493645]
線性迴歸:3階,係數爲: [-3.90207326 -2.61163034  0.66422328  0.02290431]
線性迴歸:4階,係數爲: [-8.20599769  4.20778207 -2.85304163  0.73902338 -0.05008557]
線性迴歸:5階,係數爲: [ 21.59733285 -54.12232017  38.43116219 -12.68651476   1.98134176  -0.11572371]
線性迴歸:6階,係數爲: [ 14.73304784 -37.87317493  23.67462341  -6.07037979   0.42536833   0.06803132  -0.00859246]
線性迴歸:7階,係數爲: [ 314.3034477  -827.89447307  857.33293579 -465.46543848  144.21883914  -25.67294689    2.44658613   -0.09675941]
線性迴歸:8階,係數爲: [-1189.50155038  3643.69126592 -4647.92962086  3217.22828675 -1325.87389914   334.32870442   -50.57119322     4.21251834    -0.14852101]
PyDev console: starting.
Python 2.7.12 (default, Dec  4 2017, 14:50:18) 
[GCC 5.4.0 20160609] on linux2

 

圖像顯示以下:

從上面圖像能夠看出,當模型複雜度提升的時候,對訓練集的數據擬合很好,但會出現過分擬合現象,爲了防止這種過擬合現象的出現,咱們在損失函數中加入了懲罰項,根據懲罰項不一樣分爲如下:

 

       

最後一個爲Elastic Net 迴歸,把 L1 正則和 L2 正則按必定的比例結合起來:

L1會趨向於產生少許的特徵,而其餘的特徵都是0,而L2會選擇更多的特徵,這些特徵都會接近於0。Lasso在特徵選擇時候很是有用,而Ridge就只是一種規則化而已。在全部特徵中只有少數特徵起重要做用的狀況下,選擇Lasso比較合適,由於它能自動選擇特徵。而若是全部特徵中,大部分特徵都能起做用,並且起的做用很平均,那麼使用Ridge也許更合適。對於各類迴歸的比較能夠看下圖:

相關文章
相關標籤/搜索