基於scikit learn的logistic迴歸實現



(logistic regression)屬於概率型非線性迴歸,它是研究二分類觀察結果與一些影響因素之間關係的一種多變量分析方法。在流行病學研究中,經常需要分析疾病與各危險因素之間的定量關係,爲了正確說明這種關係,需要排除一些混雜因素的影響。傳統上常常使用Mantel-Haenszel分層分析方法,但這一方法適用於樣本含量大,分析因素較少的情況。如果用線性迴歸分析,由於應變量Y是一個二值變量(通常取值1或0),不滿足應用條件,尤其當各因素都處於低水平或高水平時,預測值Y值可能超出0~1範圍,出現不合理都現象。用logistic迴歸分析則可以較好的解決上述問題。

與多重線性迴歸的比較
logistic迴歸(Logistic regression) 與多重線性迴歸實際上有很多相同之處,最大的區別就在於他們的因變量不同,其他的基本都差不多,正是因爲如此,這兩種迴歸可以歸於同一個家族,即廣義線性模型(generalized linear model)。這一家族中的模型形式基本上都差不多,不同的就是因變量不同,如果是連續的,就是多重線性迴歸,如果是二項分佈,就是logistic迴歸,如果是poisson分佈,就是poisson迴歸,如果是負二項分佈,就是負二項迴歸,等等。只要注意區分它們的因變量就可以了。[1] 
logistic迴歸的因變量可以是二分非線性差分方程類的,也可以是多分類的,但是二分類的更爲常用,也更加容易解釋。所以實際中最爲常用的就是二分類的logistic迴歸。
logistic迴歸目標函數爲:
其中Z可表示爲:
x爲特徵值
這裏用logistic迴歸實現的三分類不是常用分類,代碼實現如下:
#!/usr/bin/python
# -*- coding:utf-8 -*-

import csv
import numpy as np
from sklearn.cross_validation import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.linear_model import LogisticRegression
import matplotlib.pyplot as plt


def iris_type(s):
    it = {'Iris-setosa': 0, 'Iris-versicolor': 1, 'Iris-virginica': 2}
    return it[s]


if __name__ == "__main__":
    path = u'D:\\testData\\4.iris.data'  # 數據文件路徑

    # 路徑,浮點型數據,逗號分隔,第4列使用函數iris_type單獨處理
    data = np.loadtxt(path, dtype=float, delimiter=',', converters={4: iris_type})

    # 將數據的0到3列組成x,第4列得到y
    x, y = np.split(data, (4,), axis=1)

    # 爲了可視化,僅使用前兩列特徵
    x = x[:, :2]

    # print x
    # print y

    logreg = LogisticRegression()   # Logistic迴歸模型
    logreg.fit(x, y.ravel())        # 根據數據[x,y],計算迴歸參數

    # 畫圖
    N, M = 500, 500     # 橫縱各採樣多少個值
    x1_min, x1_max = x[:, 0].min(), x[:, 0].max()   # 第0列的範圍
    x2_min, x2_max = x[:, 1].min(), x[:, 1].max()   # 第1列的範圍
    t1 = np.linspace(x1_min, x1_max, N)
    t2 = np.linspace(x2_min, x2_max, M)
    x1, x2 = np.meshgrid(t1, t2)                    # 生成網格採樣點
    x_test = np.stack((x1.flat, x2.flat), axis=1)   # 測試點

    # # 無意義,只是爲了湊另外兩個維度
    # x3 = np.ones(x1.size) * np.average(x[:, 2])
    # x4 = np.ones(x1.size) * np.average(x[:, 3])
    # x_test = np.stack((x1.flat, x2.flat, x3, x4), axis=1)  # 測試點

    y_hat = logreg.predict(x_test)                  # 預測值
    y_hat = y_hat.reshape(x1.shape)                 # 使之與輸入的形狀相同
    plt.pcolormesh(x1, x2, y_hat, cmap=plt.cm.Spectral, alpha=0.1)  # 預測值的顯示Paired/Spectral/coolwarm/summer/spring/OrRd/Oranges
    plt.scatter(x[:, 0], x[:, 1], c=y, edgecolors='k', cmap=plt.cm.prism)  # 樣本的顯示
    plt.xlabel('Sepal length')
    plt.ylabel('Sepal width')
    plt.xlim(x1_min, x1_max)
    plt.ylim(x2_min, x2_max)
    plt.grid()
    plt.show()

    # 訓練集上的預測結果
    y_hat = dt_clf.predict(x)
    y = y.reshape(-1)       # 此轉置僅僅爲了print時能夠集中顯示
    print y_hat.shape       # 不妨顯示下y_hat的形狀
    print y.shape
    result = (y_hat == y)   # True則預測正確,False則預測錯誤
    print y_hat
    print y
    print result
    c = np.count_nonzero(result)    # 統計預測正確的個數
    print c
    print 'Accuracy: %.2f%%' % (100 * float(c) / float(len(result)))

運行結果如下圖:

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