1. 程式人生 > >Logisitc Regression 預測員工離職率

Logisitc Regression 預測員工離職率

Logistic Regression 基礎

Logistic Regression 沿用了 Linear Regression 的思路和想法,通過使用線性關係擬合得到真實的函式關係。同樣的,如果模型結果表現不好,可能是超引數沒調好,或者是訓練集的特徵沒處理好(可以多構造一些特徵,將線性特徵構造成為非線性特徵之類的)。

由於用Linear Regression 求得的解範圍是 正無窮 到 負無窮,而最後得到只是某一分類的概率,其取值範圍是 [0,1],所以我們需要將最後得到的值經過某個合適的投影,投射到 [0,1] 範圍內。

這裡就引入了 odds 的概念 和 sigmoid 函式。

引入 odds 的原因是,想要將概率投射到 [0, 正無窮] 這個範圍上,所以要引入 odds。

引入 sigmoid 函式的原因是,想要將 [0, 正無窮] 投射到 [負無窮,正無窮] 這個範圍上,所以要引入 sigmoid 函式。

Logistic Regression 預測員工離職率

直接調庫運算

from sklearn.linear_model import LogisticRegression
from patsy import dmatrices                    # 作用是將 離散變數變為 啞變數
y,X = dmatrices('left~satisfaction + last_evaluation + number_project 
+ C(sales) + C(salary), data, return_type = 'dataframe')
 # C(sales) 表示 將 sales 變成啞變數
model = LogisticRegression()
model.fit(X,y)
pd.DataFrame(list(zip(X.columns, np.transpose(model.coesf_))))  # 顯示係數
pred = model.predict(x)                        # 進行預測

Logistic Regression 理論上是通過梯度下降法來求解的。

LR 的普通 gradient descend 程式碼如下所示:

# 這需要事先知道導數是什麼,計算機可不會幫你去求導
# 我們需要做的就是不斷更新這個導數
# 更新的步長是我們自己設定的,或者是 error 到達某一個比較小的值
np.random.seed(1)
alpha = 1 # learning rate 這個值是比較重要的
beta = np.random.randn(X.shape[1])      # 隨機初始化一個梯度
for T in range(500):    # 迭代次數
    prob = np.array(1./ ( 1 + np.exp(-np.matmul(X, beta)))).ravel()
    prob_y = list(zip(prob, y))                   # 為了下面計算 loss 用的, 對 gd 沒啥作用
    loss = -sum([np.log(p) if y == 1 else np.log(1-p) for p, y in prob)y]) / len(y)  
    # 計算 loss, 目的是為了比較用的,對 gd 沒啥作用
    error_rate = 0
    for i in range(len(y)):
        if ((prob[i] > 0.5 and y[i] == 0) or (prob[i] <= 0.5 and y[i] == 1)):
            error_rate += 1
    error_rate /= len(y)
    if T % 5 ==0:
        print('T=' + str(T) + 'loss = ' + str(loss) + 'error = ; + str(error_rate)) # 目的是實時輸出一個 loss 和 eoor
    deriv = np.zeros(X.shape[1])
   
 for i in range(len(y)):                       # 對每一個 instance 都計算其導數
        deriv += np.asarray(X[i,:].ravel() * (prob[i] - y[i])  # 把所有 instance 對應的導數加起來
 deriv /= len(y)                               # 求一個平均值
 beta -= alpha * deriv                         # 更新這個 beta

對於整個更新的過程,最實質的程式碼是

 for i in range(len(y)):                       # 對每一個 instance 都計算其導數
       deriv += np.asarray(X[i,:].ravel() * (prob[i] - y[i])  # 把所有 instance 對應的導數加起來
 deriv /= len(y)                               # 求一個平均值
 beta -= alpha * deriv                         # 更新這個 beta

這裡計算 prob[i] 的原因是導數中有這一項,所以要在這裡進行計算。

Logistic Regression 中的正則化

關於正則化,首先需要明白的一個結論是:beta (模型中的係數) 越大,則說明模型越複雜。

為了避免overfitting的問題,我們在模型中引入正則化係數。正則化係數設為R。R值越大,則最後訓練出來的 beta 值越小。模型越簡單。

給正則話係數賦值的操作如下所示:

model = LogisticRegression(C = 1e5)

C 的值是 正則化係數的 倒數。