機器學習:邏輯回歸(scikit-learn 中的邏輯回歸)


一、基礎理解

  • 使用邏輯回歸算法訓練模型時,為模型引入多項式項,使模型生成不規則的決策邊界,對非線性的數據進行分類
  • 問題引入多項式項后,模型變的復雜,可能產生過擬合現象
  • 方案對模型正則化處理,損失函數添加正則項(αL2),生成新的損失函數,並對新的損失函數進行優化
  • 優化新的損失函數
  1. 滿足了讓原來的損失函數盡量的小;
  2. 另一方面,對於 L2 正則項(包含參數 θ 值),限制 θ 的大小;
  3. 引入了參數 α ,調節新的損失函數中兩部分(原損失函數和 L2 正則項)的重要程度;當然也可以引入 αL1 正則項;

 

 

二、正則化的其它方式

  • 新的表達正則化的方式:只是方式不同,正則化的原來一樣;
  1. 改變了超參數的位置:α、C;
  2. 如果超參數 C 越大,原損失函數 J(θ) 的地位相對較重要,優化損失函數時主要集中優化 J(θ) ,使其減少到最小;
  3. 如果超參數 C 非常小,正則項 L2 的地位相對較重要,優化損失函數時主要集中優化 L2 ,使參數 θ 中的元素盡量的小;
  4. 如果想讓使正則項不重要,需要增大參數 C

 

  • 其實在 J(θ) 前加參數 C,相當於將原來的 αL2 變為 1/αL2 ,兩中方式等效;
  • α、C:平衡新的損失函數中兩部分的關系;
  • 在邏輯回歸、SVM算法中,更偏好使用 C.J(θ) + L2 的方式;scikit-learn 的邏輯回歸算法中,也是使用此方式
  1. 原因:使用 C.J(θ) + L2 方式時,正則項的系數為 1,也就是說優化算法模型時不得不使用正則化;

 

 

三、思考

  • 多項式回歸:假設在特征空間中,樣本的分布規律呈多項式曲線狀態,可能類似 2 次多項式曲線,也可能是 3 次多項式的曲線,也可能是 n 次多項式的曲線;
  1. n 次多項式曲線:y = xn + ...,最高 n 次方,還有其他很多項,x 與 y 的關系曲線;

 

  • 疑問1:是不是二維空間的所有不規則曲線都存在一個多項式與其對應?
  • 疑問2:如果樣本分布規律不是多項式曲線的規律,再使用多項式回歸算法,或者邏輯回歸的多項式形式進行分類,是不是就不准確?
  • 思考:解決具體的問題,通過可視化查看樣本相根據特征大致的分布,再判斷可以使用哪些算法,組個嘗試,找個最合適的一個;
  1. 最合適:准確度高、效率高;

 

 

四、實例scikit-learn中的邏輯回歸算法

  • scikit-learn中的邏輯回歸算法自動封裝了模型的正則化的功能,只需要調整 C 和 penalty;
  • 主要參數:degree、C、penalty;(還有其它參數)

 1)直接使用邏輯回歸算法

  • import numpy as np
    import matplotlib.pyplot as plt
    
    np.random.seed(666)
    X = np.random.normal(0, 1, size=(200, 2))
    y = np.array(X[:,0]**2 + X[:,1] < 1.5,dtype='int')
    
    # 隨機抽取 20 個樣本,讓其分類為 1,相當於認為更改數據,添加噪音
    for _ in range(20):
        y[np.random.randint(200)] = 1
    
    plt.scatter(X[y==0,0], X[y==0,1])
    plt.scatter(X[y==1,0], X[y==1,1])
    plt.show()

  • 為虛擬的測試數據設置種子 666:則每次執行 np.random.normal(0, 1, size=(200, 2)) 時,隨機生成的 X 不變;
  • 隨機生成數據是系統內定的,隨機種子是系統隨機生成數據時的依據,只要設定的隨機種子相同,所有人生成的數據一樣;(待考察
  • from sklearn.model_selection import train_test_split
    
    X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=666)
    
    from sklearn.linear_model import LogisticRegression
    
    log_reg = LogisticRegression()
    log_reg.fit(X_train, y_train)
    # LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,
              intercept_scaling=1, max_iter=100, multi_class='ovr', n_jobs=1,
              penalty='l2', random_state=None, solver='liblinear', tol=0.0001,
              verbose=0, warm_start=False)
  1. C=1.0:默認超參數 C 的值為1.0;

  2. penalty='l2':默認使用 L2 正則項;
  • def plot_decision_boundary(model, axis):
        
        x0, x1 = np.meshgrid(
            np.linspace(axis[0], axis[1], int((axis[1]-axis[0])*100)).reshape(-1,1),
            np.linspace(axis[2], axis[3], int((axis[3]-axis[2])*100)).reshape(-1,1)
        )
        X_new = np.c_[x0.ravel(), x1.ravel()]
        
        y_predict = model.predict(X_new)
        zz = y_predict.reshape(x0.shape)
        
        from matplotlib.colors import ListedColormap
        custom_cmap = ListedColormap(['#EF9A9A','#FFF59D','#90CAF9'])
        
        plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap)
    
    plot_decision_boundary(log_reg, axis=[-4, 4, -4, 4])
    plt.scatter(X[y==0,0], X[y==0,1])
    plt.scatter(X[y==1,0], X[y==1,1])
    plt.show()

 

 2)為邏輯回歸算法的模型添加多項式項

  • degree = 2、C 默認1.0

    from sklearn.pipeline import Pipeline
    from sklearn.preprocessing import PolynomialFeatures
    from sklearn.preprocessing import StandardScaler
    
    def PolynomialLogisticRegression(degree):
        return Pipeline([
            ('poly', PolynomialFeatures(degree=degree)),
            ('std_scaler', StandardScaler()),
            ('log_reg', LogisticRegression())
        ])
    
    # 使用管道時,先生成實例的管道對象,在進行 fit;
    poly_log_reg = PolynomialLogisticRegression(degree=2)
    poly_log_reg.fit(X_train, y_train)
    
    plot_decision_boundary(poly_log_reg, axis=[-4, 4, -4, 4])
    plt.scatter(X[y==0,0], X[y==0,1])
    plt.scatter(X[y==1,0], X[y==1,1])
    plt.show()

 

  • degree = 20、C 默認1.0

    poly_log_reg2 = PolynomialLogisticRegression(degree=20)
    poly_log_reg2.fit(X_train, y_train)
    
    plot_decision_boundary(poly_log_reg2, axis=[-4, 4, -4, 4])
    plt.scatter(X[y==0,0], X[y==0,1])
    plt.scatter(X[y==1,0], X[y==1,1])
    plt.show()

 

  • degree = 20、C = 0.1

    def PolynomialLogisticRegression(degree, C):
        return Pipeline([
            ('poly', PolynomialFeatures(degree=degree)),
            ('std_scaler', StandardScaler()),
            ('log_reg', LogisticRegression(C=C))
        ])
    
    poly_log_reg3 = PolynomialLogisticRegression(degree=20, C=0.1)
    poly_log_reg3.fit(X_train, y_train)
    
    plot_decision_boundary(poly_log_reg3, axis=[-4, 4, -4, 4])
    plt.scatter(X[y==0,0], X[y==0,1])
    plt.scatter(X[y==1,0], X[y==1,1])
    plt.show()

 

  • degree = 20、C = 0.1、penalty = 'L1'(penalty:正則項類型, 默認為 L2)

    def PolynomialLogisticRegression(degree, C, penalty='l2'):
        return Pipeline([
            ('poly', PolynomialFeatures(degree=degree)),
            ('std_scaler', StandardScaler()),
            ('log_reg', LogisticRegression(C=C, penalty=penalty))
        ])
    
    poly_log_reg4 = PolynomialLogisticRegression(degree=20, C=0.1, penalty='l1')
    poly_log_reg4.fit(X_train, y_train)
    
    plot_decision_boundary(poly_log_reg4, axis=[-4, 4, -4, 4])
    plt.scatter(X[y==0,0], X[y==0,1])
    plt.scatter(X[y==1,0], X[y==1,1])
    plt.show()

  1. 分析:degree = 20,模型的決策邊界太復雜,模型可能過擬合,使用 L1 正則項進行模型的正則化;
  2. 分析2:模型過擬合后,有很多多項式項,使用 L1 正則項,使得這些多項式項的系數為 0,進而使模型決策邊界更加規則,不會彎彎曲曲,便於可視化;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM