摘要:邏輯回歸將樣本特征和樣本發生的概率聯系起來,用于解決分類問題。因此可對二分類的分類方式為損失函數如果實際的分類為,越小時,損失越大如果實際的分類為,越大時,損失越大。對于有樣本的數據集,損失函數為其中。
邏輯回歸將樣本特征和樣本發生的概率聯系起來,用于解決分類問題。
Sigmoid 函數在最簡單的二分類中,邏輯回歸里樣本發生的概率的值域為 [0, 1],對于線性回歸 $hat{y} = heta^T·x_b$,為了將 $hat y$ 映射到值域 [0, 1] 中,引入了 $sigma$ 函數得到了概率函數 $hat p$,即:
$$ hat p=sigma( heta^T·x_b), hat pin[0, 1] $$
Sigmoid 函數 $sigma$ 表示為:$sigma(t)=frac{1}{1+e^{-t}}$,圖示如下:
當 t > 0 時,$sigma$ > 0.5;當 t < 0 時,$sigma$ < 0.5。因此可對二分類的分類方式為:
$$hat y=egin{cases} 1, & hat p geq 0.5 0, & hat p leq 0.5 end{cases}; hat p=sigma( heta^T·x_b)=frac{1}{1+e^{- heta^T·x_b}}$$
損失函數如果實際的分類為1,p 越小時,損失越大;如果實際的分類為0,p 越大時,損失越大。引入 log 函數表示則為:
$$ -ylog(hat p)-(1-y)log(1-hat p) $$
當 y=0 時,損失為 $-log(1-hat p)$;當 y=1 時,損失為 $-log(hat p)$。
對于有 m 樣本的數據集 (X, y),損失函數為:
$$ J( heta)=-frac{1}{m}sum_{i=1}^my^{(i)}log(sigma(X_b^{(i)} heta))+(1-y^{(i)})log(1-sigma(X_b^{(i)} heta)) $$
其中:$X_b^{(i)} = (1,x_{1}^{(i)},x_{2}^{(i)},...,x_{n}^{(i)})$;$ heta = ( heta_{0}, heta_{1}, heta_{2},..., heta_{n})^T$。
損失函數的梯度為了得到在損失盡可能的小的情況下的 $ heta$,可以對 $J( heta)$ 使用梯度下降法,結果為:
$$ abla J( heta) = frac{1}{m}·egin{pmatrix} sum_{i=1}^{m}(sigma(X_b^{(i)} heta) - y^{(i)}) sum_{i=1}^{m}(sigma(X_b^{(i)} heta) - y^{(i)})·X_1^{(i)} sum_{i=1}^{m}(sigma(X_b^{(i)} heta) - y^{(i)})·X_2^{(i)} cdots sum_{i=1}^{m}(sigma(X_b^{(i)} heta) - y^{(i)})·X_n^{(i)} end{pmatrix} $$
略去了公式的推導過程。
進行向量化處理后結果為:
$$ abla J( heta) = frac{2}{m}·X_b^T·(sigma(X_b heta)-y) $$
實現二分類邏輯回歸算法使用 Scikit Learn 的規范將邏輯回歸的過程封裝到 LogisticRegression 類中。
_init_() 方法首先初始化邏輯回歸模型,_theta 表示 $ heta$,interception_ 表示截距,chef_ 表示回歸模型中自變量的系數:
class LogisticRegression: def __init__(self): self.coef_ = None self.interceiption_ = None self._theta = None
_sigmoid() 方法實現 Sigmoid 函數:
def _sigmoid(self, t): return 1 / (1 + np.exp(-t))
fit() 方法根據訓練數據集訓練模型,J() 方法計算損失 $J heta$,dJ() 方法計算損失函數的梯度 $ abla J( heta)$,gradient_descent() 方法就是梯度下降的過程,X_b 表示添加了 $x_{0}^{(i)}equiv1$ 的樣本特征數據:
def fit(self, X_train, y_train, eta=0.01, n_iters=1e4): def J(theta, X_b, y): y_hat = self._sigmoid(X_b.dot(theta)) try: return - np.sum(y * np.log(y_hat) + (1 - y) * np.log(1- y_hat) ** 2) / len(y) except: return float("inf") def dJ(theta, X_b, y): return X_b.T.dot(self._sigmoid(X_b.dot(theta)) - y) /len(y) def gradient_descent(X_b, y, initial_theta, eta, n_iters=n_iters, epsilon=1e-8): theta = initial_theta i_ters = 0 while i_ters < n_iters: gradient = dJ(theta, X_b, y) last_theta = theta theta = theta - eta * gradient if (abs(J(theta, X_b, y) - J(last_theta, X_b, y)) < epsilon): break i_ters += 1 return theta X_b = np.hstack([np.ones((len(X_train), 1)), X_train]) initial_theta = np.zeros(X_b.shape[1]) self._theta = gradient_descent(X_b, y_train, initial_theta, eta) self.interception_ = self._theta[0] self.coef_ = self._theta[1:] return self
predict_proba() 將傳入的測試數據與訓練好模型后的 $ heta$ 經過計算后返回該測試數據的概率:
def predict_proba(self, X_predict): X_b = np.hstack([np.ones((len(X_predict), 1)), X_predict]) return self._sigmoid(X_b.dot(self._theta))
predict() 方法將經過 predict_proba() 方法得到的測試數據的概率以 0.5 為界轉換成類別(0或1):
def predict(self, X_predict): proba = self.predict_proba(X_predict) return np.array(proba >= 0.5, dtype="int")
score() 將測試數據集的預測分類與實際分類進行比較計算模型準確度:
def score(self, X_test, y_test): y_predict = self.predict(X_test) return sum(y_predict == y_test) / len(y_test)決策邊界
對于 $hat p=sigma( heta^T·x_b)=frac{1}{1+e^{- heta^T·x_b}}$,要使 $hat p=0.5$ 則 $ heta^T·x_b=0$,這就是決策邊界。
假設 X 數據集只有兩個特征,則由 $ heta_0+ heta_1x_1+ heta_2x_2=0$ 得到 $x_2$ 和 $x_1$ 的關系為:
$$ x_2=frac{- heta_0- heta_1x_1}{ heta_2} $$
如圖所示,圖中的點為只有兩個特征的數據,縱軸為特征 $x_2$,橫軸為特征 $x_1$,梯度下降法得到的 $ heta$ 與上面公式計算后的決策邊界即為圖中斜線:
邏輯回歸中使用多項式特征對于多項式回歸,如對 $y=x_1^2+x_2^2-r$ 進行邏輯回歸,可以將 $x_1^2$ 看作一個特征 $z_1$,將 $x_2^2$ 看作一個特征 $z_2$,Scikit Learn 提供了 PolynomialFeatures 可以方便的進行轉換。
舉例如下。首先準備數據:
import numpy as np X = np.random.normal(0, 1, size=(200, 2)) y = np.array(X[:, 0] ** 2 + X[:, 1] ** 2 < 1.5, dtype="int")
數據可視化如圖:
使用前面的 LogisticRegression 類進行邏輯回歸,并且使用 Scikit Learn 的 Pipeline 將多項式特征、數據歸一化和邏輯回歸組合在一起:
from LogisticRegression import LogisticRegression from sklearn.pipeline import Pipeline from sklearn.preprocessing import PolynomialFeatures from sklearn.preprocessing import StandardScaler def PolynomailLogisticRegression(degree): return Pipeline([ ("poly", PolynomialFeatures(degree=degree)), ("std_scaler", StandardScaler()), ("log_reg", LogisticRegression()) ])
設定 PolynomialFeatures 處理后得到的新的特征數據最高維度為2,然后 fit() 方法訓練模型:
poly_log_reg = PolynomailLogisticRegression(degree=2) poly_log_reg.fit(X, y)
得到模型可視化如圖:
Scikit Learn 中的邏輯回歸Scikit Learn 中的 linear_model 模塊中也提供了邏輯回歸的算法,同時也封裝了模型正則化相關的內容。
根據正則化中的正則項的不同,正則化的方式主要有四種:
$J( heta)+alpha L_1$
$J( heta)+alpha L_2$
$C·J( heta)+L_1$
$C·J( heta)+L_2$
Scikit Learn 中的邏輯回歸算法的模型正則化采用后兩種的方式。
L1 為 L1正則項,即 $sum_{i=1}^n| heta_i|$,LASSO 回歸使用了L1;L2 為 L2正則項,即 $frac{1}{2}sum_{i=1}^n heta_i^2$,嶺回歸使用了L2;
Scikit Learn 的邏輯回歸算法中的參數 c 設定 C 的大小,參數 penalty 設定使用哪種正則項(l1 或 l2)。使用方式如下:
from sklearn.linear_model import LogisticRegression def PolynomailLogisticRegression(degree, C, penalty="l2"): return Pipeline([ ("poly", PolynomialFeatures(degree=degree)), ("std_scaler", StandardScaler()), ("log_reg", LogisticRegression(C=C, penalty=penalty)) ]) poly_log_reg = PolynomailLogisticRegression(degree=20, C=0.1, penalty="l1") poly_log_reg.fit(X_train, y_train)OvR 與 OvO
前面說的都是二分類的邏輯回歸,如果要進行多分類的邏輯回歸,有 OvR 和 OvO 兩種方式。
OvR(One vs Rest)將多類別簡化成其中一個類別和其余類別為一個類別這種二分類,因此 n 個類別就進行 n 次分類,對于新的數據,看它在這 n 個分類結果中哪個分類得分最高即為哪個類別。
OvO(One vs One)在多類別中選取兩個類別作為二分類,因此 n 個類別就進行 $C_n^2$ 次分類,對于新的數據,看它在這 $C_n^2$ 次分類結果中數量最大即為哪個類別。
Scikit Learn 的邏輯回歸算法中的參數 multi_class 用于設定使用 OvR(參數值為 ovr)還是 OvO(參數值為 multinomial),如:
LogisticRegression(multi_class="ovr") LogisticRegression(multi_class="multinomial")
同時 Scikit Learn 中的 multiclass 模塊中也提供了 OneVsRestClassifier(OvR)類和 OneVsOneClassifier(OvO)類,可以將任意的二分類算法(要求符合 Scikit Learn 規范)應用在這兩個類上完成多分類。使用方式如下:
# OvR from sklearn.multiclass import OneVsRestClassifier ovr = OneVsRestClassifier(LogisticRegression()) ovr.fit(X, y) # OvO from sklearn.multiclass import OneVsOneClassifier ovo = OneVsOneClassifier(log_reg) ovo.fit(X, y)
Github | ML-Algorithms-Action
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/42772.html
摘要:不能用于機器學習太慢幻覺矩陣操作太難有函數庫啊,比如只能用于前端開發開發者笑了機器學習庫都是開發者機器學習庫神經網絡神經網絡自然語言處理卷積神經網絡一系列庫神經網絡深度學習我們將使用來實現線性回歸,源代碼在倉庫。 譯者按: AI時代,不會機器學習的JavaScript開發者不是好的前端工程師。 原文: Machine Learning with JavaScript : Part 1 ...
閱讀 3667·2021-10-11 11:09
閱讀 1337·2021-09-24 10:35
閱讀 3423·2021-07-29 13:48
閱讀 460·2019-08-30 13:15
閱讀 2511·2019-08-30 12:53
閱讀 3183·2019-08-30 12:44
閱讀 2712·2019-08-29 16:57
閱讀 957·2019-08-29 12:26