機器學(xué)習(xí) 之 回歸

1. 線性回歸

模型

線性回歸

y表示預(yù)測結(jié)果
n表示特征的個數(shù)
xi表示第 i 個特征的值
θj表示第 j 個參數(shù)


線性回歸向量形式

h表示假設(shè)函數(shù)

正態(tài)方程

實踐過程中系忙,最小化MSE更簡單


MSE

使得MSE最小的解為:


正態(tài)解
構(gòu)造數(shù)據(jù)
import numpy as np

X = 2 * np.random.rand(100, 1)
y = 4 + 3 * X + np.random.randn(100, 1)

plt.plot(X, y, "b.")
plt.xlabel("$x_1$", fontsize=18)
plt.ylabel("$y$", rotation=0, fontsize=18)
plt.axis([0, 2, 0, 15])
plt.show()
可視化構(gòu)造的數(shù)據(jù)
X_b = np.c_[np.ones((100, 1)), X]  # add x0 = 1 to each instance
theta_best = np.linalg.inv(X_b.T.dot(X_b)).dot(X_b.T).dot(y)
theta_best
'''
array([[3.9202609],
       [2.9609808]])
'''

X_new = np.array([[0], [2]]) # x坐標(biāo)軸的兩端
X_new_b = np.c_[np.ones((2, 1)), X_new]  
# 等同于: X_new_b = np.hstack((np.ones((2, 1)), X_new))
add x0 = 1 to each instance
y_predict = X_new_b.dot(theta_best)
y_predict

plt.plot(X_new, y_predict, "r-", linewidth=2, label="Predictions")
plt.plot(X, y, "b.")
plt.xlabel("$x_1$", fontsize=18)
plt.ylabel("$y$", rotation=0, fontsize=18)
plt.legend(loc="upper left", fontsize=14)
plt.axis([0, 2, 0, 15])
plt.show()
模型展示
Sklearn
from sklearn.linear_model import LinearRegression
lin_reg = LinearRegression()
lin_reg.fit(X, y)
lin_reg.intercept_, lin_reg.coef_

# (array([3.9202609]), array([[2.9609808]]))
時間復(fù)雜度

正態(tài)方程需要計算矩陣X^T·X的逆,它是一個的n × n矩陣(n是特征的個數(shù))鹦马。這樣一個矩陣求逆的運算復(fù)雜度大約在O(n^{2.4})O(n^3)之間临燃。

梯度下降

這種方法適合在特征個數(shù)非常多菩掏,訓(xùn)練實例非常多奄毡,內(nèi)存無法滿足要求的時候使用商蕴。
梯度下降的整體思路是通過的迭代來逐漸調(diào)整參數(shù)使得損失函數(shù)達(dá)到最小值出革。它計算誤差函數(shù)關(guān)于參數(shù)向量的局部梯度造壮,同時它沿著梯度下降的方向進(jìn)行下一次迭代。當(dāng)梯度值為零的時候骂束,就達(dá)到了誤差函數(shù)最小值 耳璧。


梯度下降圖解

關(guān)鍵點:合理的步長、可能不是全局最優(yōu)解展箱,如下圖柏靶。(但是沪编,線性回歸的均方差損失函數(shù)是凸函數(shù))


梯度下降法的挑戰(zhàn)

下圖展示了梯度下降在不同訓(xùn)練集上的表現(xiàn)。在左圖中,特征 1 和特征 2 有著相同的數(shù)值尺度碍论。在右圖中唆涝,特征 1 比特征2的取值要小的多靡挥。左面的梯度下降可以直接快速地到達(dá)最小值坟奥,然而在右面的梯度下降第一次前進(jìn)的方向幾乎和全局最小值的方向垂直,并且最后到達(dá)一個幾乎平坦的山谷婴栽,在平坦的山谷走了很長時間满粗。它最終會達(dá)到最小值,但它需要很長時間愚争。


有無特征縮放的梯度下降

當(dāng)使用梯度下降的時候映皆,應(yīng)該確保所有的特征有著相近的尺度范圍(例如:使用Scikit Learn 的 StandardScaler 類)挤聘,否則它將需要很長的時間才能夠收斂。

批量梯度下降

使用梯度下降的過程中捅彻,需要計算每一個θ_j下?lián)p失函數(shù)的梯度组去。換句話說,你需要計算當(dāng)θ_j變化一點點時(即偏導(dǎo)數(shù))步淹,損失函數(shù)改變了多少从隆。

損失函數(shù)的偏導(dǎo)數(shù)

損失函數(shù)的梯度向量為:
損失函數(shù)梯度向量

在這個方程中每一步計算時都包含了整個訓(xùn)練集
X
,這也是為什么這個算法稱為批量梯度下降:每一次訓(xùn)練過程都使用所有的的訓(xùn)練數(shù)據(jù)贤旷。因此广料,在大數(shù)據(jù)集上砾脑,其會變得相當(dāng)?shù)穆?br> 一旦求得了方向是上山的梯度向量幼驶,你就可以向著相反的方向去下山。這意味著從
\theta
中減去梯度韧衣,如下公式盅藻,其中
\eta
是學(xué)習(xí)率。
梯度下降步長

eta = 0.1 # 步長
n_iterations = 1000 # 迭代次數(shù)
m = 100 # 總樣本數(shù)
theta = np.random.randn(2,1)

for iteration in range(n_iterations):
    gradients = 2/m * X_b.T.dot(X_b.dot(theta) - y)
    theta = theta - eta * gradients

theta
# array([[3.9202609],
#        [2.9609808]])

在不同學(xué)習(xí)率下畅铭,迭代前10步的區(qū)別:

theta_path_bgd = []

def plot_gradient_descent(theta, eta, theta_path=None):
    m = len(X_b)
    plt.plot(X, y, "b.")
    n_iterations = 1000
    for iteration in range(n_iterations):
        if iteration < 10:
            y_predict = X_new_b.dot(theta)
            style = "b-" if iteration > 0 else "r--"
            plt.plot(X_new, y_predict, style)
        gradients = 2/m * X_b.T.dot(X_b.dot(theta) - y)
        theta = theta - eta * gradients
        if theta_path is not None:
            theta_path.append(theta)
    plt.xlabel("$x_1$", fontsize=18)
    plt.axis([0, 2, 0, 15])
    plt.title(r"$\eta = {}$".format(eta), fontsize=16)

np.random.seed(42)
theta = np.random.randn(2,1)  # random initialization

plt.figure(figsize=(10,4))
plt.subplot(131); plot_gradient_descent(theta, eta=0.02)
plt.ylabel("$y$", rotation=0, fontsize=18)
plt.subplot(132); plot_gradient_descent(theta, eta=0.1, theta_path=theta_path_bgd)
plt.subplot(133); plot_gradient_descent(theta, eta=0.5)
不同學(xué)習(xí)率的梯度下降

隨機梯度下降

批量梯度下降的最要問題是計算每一步的梯度時都需要使用整個訓(xùn)練集氏淑,這導(dǎo)致在規(guī)模較大的數(shù)據(jù)集上,其會變得非常的慢硕噩。與其完全相反的隨機梯度下降假残,在每一步的梯度計算上只隨機選取訓(xùn)練集中的一個樣本。
由于它的隨機性炉擅,與批量梯度下降相比辉懒,其呈現(xiàn)出更多的不規(guī)律性:它到達(dá)最小值不是平緩的下降,損失函數(shù)會忽高忽低谍失,只是在大體上呈下降趨勢眶俩。隨著時間的推移,它會非常的靠近最小值快鱼,但是它不會停止在一個值上颠印,它會一直在這個值附近擺動,如下圖抹竹。


隨機梯度下降

當(dāng)損失函數(shù)很不規(guī)則時线罕,隨機梯度下降算法能夠跳過局部最小值。因此窃判,隨機梯度下降在尋找全局最小值上比批量梯度下降表現(xiàn)要好闻坚。
雖然隨機性可以很好的跳過局部最優(yōu)值,但同時它卻不能達(dá)到最小值兢孝。解決這個難題的一個辦法是逐漸降低學(xué)習(xí)率窿凤。 開始時仅偎,走的每一步較大,然后變得越來越小雳殊,從而使算法到達(dá)全局最小值橘沥。 這個過程被稱為模擬退火,因為它類似于熔融金屬慢慢冷卻的冶金學(xué)退火過程夯秃。 決定每次迭代的學(xué)習(xí)率的函數(shù)稱為 learning schedule 座咆。
下面是原書的代碼,有點奇葩:

theta_path_sgd = []
m = len(X_b)
np.random.seed(42)

n_epochs = 50
t0, t1 = 5, 50  # learning schedule hyperparameters

def learning_schedule(t):
    return t0 / (t + t1)

theta = np.random.randn(2,1)

for epoch in range(n_epochs):
    for i in range(m):
        if epoch == 0 and i < 20:                    
            y_predict = X_new_b.dot(theta)           
            style = "b-" if i > 0 else "r--"         
            plt.plot(X_new, y_predict, style)        
        random_index = np.random.randint(m)
        xi = X_b[random_index:random_index+1]
        yi = y[random_index:random_index+1]
        gradients = 2 * xi.T.dot(xi.dot(theta) - yi)
        eta = learning_schedule(epoch * m + i)
        theta = theta - eta * gradients
        theta_path_sgd.append(theta)                 

plt.plot(X, y, "b.")                                 
plt.xlabel("$x_1$", fontsize=18)                     
plt.ylabel("$y$", rotation=0, fontsize=18)           
plt.axis([0, 2, 0, 15])                              
plt.show() 
隨機梯度下降的前10次迭代以及最后一次迭代結(jié)果
sklearn
from sklearn.linear_model import SGDRegressor
sgd_reg = SGDRegressor(max_iter=50, penalty=None, eta0=0.1, random_state=42)
sgd_reg.fit(X, y.ravel())

sgd_reg.intercept_, sgd_reg.coef_
# (array([4.16782089]), array([2.72603052]))

小批量梯度下降

在迭代的每一步仓洼,批量梯度使用整個訓(xùn)練集介陶,隨機梯度時候用僅僅一個實例,在小批量梯度下降中色建,它則使用一個隨機的小型實例集哺呜。

theta_path_mgd = []

n_iterations = 50
minibatch_size = 20

np.random.seed(42)
theta = np.random.randn(2,1)  # random initialization

t0, t1 = 200, 1000
def learning_schedule(t):
    return t0 / (t + t1)

t = 0
for epoch in range(n_iterations):
    shuffled_indices = np.random.permutation(m)
    X_b_shuffled = X_b[shuffled_indices]
    y_shuffled = y[shuffled_indices]
    for i in range(0, m, minibatch_size):
        t += 1
        xi = X_b_shuffled[i:i+minibatch_size]
        yi = y_shuffled[i:i+minibatch_size]
        gradients = 2/minibatch_size * xi.T.dot(xi.dot(theta) - yi)
        eta = learning_schedule(t)
        theta = theta - eta * gradients
        theta_path_mgd.append(theta)

theta_path_bgd = np.array(theta_path_bgd)
theta_path_sgd = np.array(theta_path_sgd)
theta_path_mgd = np.array(theta_path_mgd)

plt.figure(figsize=(7,4))
plt.plot(theta_path_sgd[:, 0], theta_path_sgd[:, 1], "r-s", linewidth=1, label="隨機梯度")
plt.plot(theta_path_mgd[:, 0], theta_path_mgd[:, 1], "g-+", linewidth=2, label="小批量梯度")
plt.plot(theta_path_bgd[:, 0], theta_path_bgd[:, 1], "b-o", linewidth=3, label="批量梯度")
plt.legend(loc="upper left", fontsize=16)
plt.xlabel(r"$\theta_0$", fontsize=20)
plt.ylabel(r"$\theta_1$   ", fontsize=20, rotation=0)
plt.axis([2.5, 4.5, 2.3, 3.9])
plt.show()
不同梯度算法的路勁比較
線性回歸總結(jié)

2. 多項式回歸

對于非線性數(shù)據(jù),依然可以使用線性模型來擬合箕戳。 一個簡單的方法是對每個特征進(jìn)行加權(quán)后作為新的特征某残,然后訓(xùn)練一個線性模型在這個擴展的特征集。 這種方法稱為多項式回歸陵吸。

創(chuàng)建數(shù)據(jù)
np.random.seed(42)

m = 100
X = 6 * np.random.rand(m, 1) - 3
y = 0.5 * X **2 * X + 2 + np.random.randn(m, 1)

plot.plot(X, y, "b.")
plt.xlabel("$x_1$", fontsize=18)
plt.ylabel("$y$", rotation=0, fontsize=18)
plt.axis([-3, 3, 0, 10])
plt.show()
數(shù)據(jù)集

使用 Scikit-Learning的PolynomialFeatures類進(jìn)行訓(xùn)練數(shù)據(jù)集的轉(zhuǎn)換玻墅,讓訓(xùn)練集中每個特征的平方(2 次多項式)作為新特征。

from sklearn.preprocessing import PolynomialFeatures
'''
PolynomialFeatures(degree=2, interaction_only=False, include_bias=True)

Generate a new feature matrix consisting of all polynomial combinations
of the features with degree less than or equal to the specified degree.
For example, if an input sample is two dimensional and of the form
[a, b], the degree-2 polynomial features are [1, a, b, a^2, ab, b^2].

interaction_only 是否包含ab
include_bias 是否包含1
'''
poly_features = PolynomialFeatures(degree=2, include_bias=False)
X_poly = poly_features.fit_transform(X)
# X_poly的shape是100*2壮虫,[x, x^2]

lin_reg = LinearRegression()
lin_reg.fit(X_poly, y)
lin_reg.intercept_, lin_reg.coef_
# (array([1.78134581]), array([[0.93366893, 0.56456263]]))

X_new=np.linspace(-3, 3, 100).reshape(100, 1)
X_new_poly = poly_features.transform(X_new)
y_new = lin_reg.predict(X_new_poly)
plt.plot(X, y, "b.")
plt.plot(X_new, y_new, "r-", linewidth=2, label="Predictions")
plt.xlabel("$x_1$", fontsize=18)
plt.ylabel("$y$", rotation=0, fontsize=18)
plt.legend(loc="upper left", fontsize=14)
plt.axis([-3, 3, 0, 10])
plt.show()
多項式回歸預(yù)測

3. 學(xué)習(xí)曲線

過擬合澳厢、欠擬合是很常見的問題,那么我們該如何決定模型的復(fù)雜度呢囚似?
一種方法是觀察學(xué)習(xí)曲線:畫出在不同規(guī)模的訓(xùn)練集上剩拢,模型在所有訓(xùn)練集和測試集上的表現(xiàn)。為了得到圖像谆构,需要在訓(xùn)練集的不同規(guī)模子集上進(jìn)行多次訓(xùn)練裸扶。
關(guān)于學(xué)習(xí)曲線很好的博文

線性回歸的學(xué)習(xí)曲線:
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import train_test_split

def plot_learning_curves(model, X, y):
    X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=10)
    train_errors, val_errors = [], []
    for m in range(1, len(X_train)):
        model.fit(X_train[:m], y_train[:m])
        y_train_predict = model.predict(X_train[:m])
        y_val_predict = model.predict(X_val)
        train_errors.append(mean_squared_error(y_train[:m], y_train_predict))
        val_errors.append(mean_squared_error(y_val, y_val_predict))

    plt.plot(np.sqrt(train_errors), "r-+", linewidth=2, label="train")
    plt.plot(np.sqrt(val_errors), "b-", linewidth=3, label="val")
    plt.legend(loc="upper right", fontsize=14)  
    plt.xlabel("Training set size", fontsize=14) 
    plt.ylabel("RMSE", fontsize=14) 

lin_reg = LinearRegression()
plot_learning_curves(lin_reg, X, y)
plt.axis([0, 80, 0, 3])                         
plt.show()
線性回歸的學(xué)習(xí)曲線
10階多項式模型擬合的學(xué)習(xí)曲線
from sklearn.pipeline import Pipeline

polynomial_regression = Pipeline([
        ("poly_features", PolynomialFeatures(degree=10, include_bias=False)),
        ("lin_reg", LinearRegression()),
    ])

plot_learning_curves(polynomial_regression, X, y)
plt.axis([0, 80, 0, 3])         
plt.show()  
10階多項式模型擬合的學(xué)習(xí)曲線
2階多項式模型擬合的學(xué)習(xí)曲線
from sklearn.pipeline import Pipeline

polynomial_regression = Pipeline([
        ("poly_features", PolynomialFeatures(degree=2, include_bias=False)),
        ("lin_reg", LinearRegression()),
    ])

plot_learning_curves(polynomial_regression, X, y)
plt.axis([0, 80, 0, 3])         
plt.show()  
2階多項式模型擬合的學(xué)習(xí)曲線

改善模型過擬合的一種方法是提供更多的訓(xùn)練數(shù)據(jù),直到訓(xùn)練誤差和驗證誤差相等搬素。
偏差和方差的權(quán)衡
在統(tǒng)計和機器學(xué)習(xí)領(lǐng)域有個重要的理論:一個模型的泛化誤差由三個不同誤差的和決定:

  • 偏差:泛化誤差的這部分誤差是由于錯誤的假設(shè)決定的呵晨。例如實際是一個二次模型,你卻假設(shè)了一個線性模型熬尺。一個高偏差的模型最容易出現(xiàn)欠擬合摸屠。
  • 方差:這部分誤差是由于模型對訓(xùn)練數(shù)據(jù)的微小變化較為敏感,一個多自由度的模型更容易有高的方差(例如一個高階多項式模型)粱哼,因此會導(dǎo)致模型過擬合季二。
  • 不可約誤差:這部分誤差是由于數(shù)據(jù)本身的噪聲決定的。降低這部分誤差的唯一方法就是進(jìn)行數(shù)據(jù)清洗(例如:修復(fù)數(shù)據(jù)源,修復(fù)壞的傳感器胯舷,識別和剔除異常值)刻蚯。

4. 線性模型正則化 Regularized

過擬合的解決辦法一個是減少特征,另一個是正則化桑嘶。對于一個線性模型炊汹,正則化的典型實現(xiàn)就是約束模型中參數(shù)的權(quán)重(\theta_j的大小)逃顶。 接下來我們將介紹三種不同約束權(quán)重的方法:Ridge 回歸,Lasso 回歸和 Elastic Net以政。
正則化好文
L1, L2 物理意義

Ridge回歸(Tikhonov 正則化、L2正則化)

Ridge回歸是線性回歸的正則化版废菱,在損失函數(shù)上直接加上一個正則項\alpha \sum_{i=1}^{n}\theta_{i}^{2}\theta的L2范數(shù)),使得學(xué)習(xí)算法不僅能夠擬合數(shù)據(jù)眉反,而且能夠使模型的參數(shù)權(quán)重盡量的小昙啄。注意到寸五,\theta_0是沒有被正則化的耿币。

Ridge回歸損失函數(shù)

Ridge的解
from sklearn.linear_model import Ridge
ridge_reg = Ridge(alpha=1, solver="cholesky", random_state=42)
ridge_reg.fit(X, y)
ridge_reg.predict([[1.5]])
# array([[1.55071465]])

'''
penalty 參數(shù)指的是正則項的懲罰類型梳杏。指定“l(fā)2”表明你要在損失函數(shù)上添加一項:權(quán)重向量L2范數(shù)平方的一半,這就是簡單的嶺回歸十性。
'''
sgd_reg = SGDRegressor(max_iter=5, penalty="l2", random_state=42)
sgd_reg.fit(X, y.ravel())
sgd_reg.predict([[1.5]])
# array([1.13500145])

Lasso回歸(L1正則化)

在損失函數(shù)上添加了一個正則化項塑悼,權(quán)重向量的 L1范數(shù)。


Lasso回歸的損失函數(shù)

Lasso 回歸的一個重要特征是它傾向于完全消除最不重要的特征的權(quán)重霞势,Lasso回歸自動的進(jìn)行特征選擇同時輸出一個稀疏模型(即斑鸦,具有很少的非零權(quán)重),有特征選擇巷屿、降維的作用。

from sklearn.linear_model import Lasso
lasso_reg = Lasso(alpha=0.1)
lasso_reg.fit(X, y)
lasso_reg.predict([[1.5]])
# array([1.53788174])

彈性網(wǎng)絡(luò)(ElasticNet)

彈性網(wǎng)絡(luò)介于 Ridge 回歸和 Lasso 回歸之間憨琳。它的正則項是 Ridge 回歸和 Lasso 回歸正則項的簡單混合篙螟。


彈性網(wǎng)絡(luò)損失函數(shù)
from sklearn.linear_model import ElasticNet
elastic_net = ElasticNet(alpha=0.1, l1_ratio=0.5, random_state=42)
elastic_net.fit(X, y)
elastic_net.predict([[1.5]])
# array([1.54333232])

5. 邏輯回歸

邏輯回歸博文
邏輯回歸的輸出是概率估計,是在線性回歸的基礎(chǔ)上再加上一層logistic函數(shù)\sigma()慢味。


logistic函數(shù)

概率估計
\widehat{p}
大于0.5就輸出1纯路,否則就輸出0寞忿。

損失函數(shù)

單個樣本的損失函數(shù)
邏輯回歸損失函數(shù)
邏輯回歸損失函數(shù)偏導(dǎo)

決策邊界

iris數(shù)據(jù)集分析
from sklearn import datasets
iris = datasets.load_iris()
list(iris.keys())
# ['data', 'target', 'target_names', 'DESCR', 'feature_names', 'filename']

iris['data'].shape
# (150, 4)
# 四個特征分別是 花萼長度腔彰、花萼寬度、花瓣長度霹抛、花瓣寬度
pd.Series(iris['target']).value_counts()
# 2    50
# 1    50
# 0    50
# dtype: int64

print(iris.DESCR)
'''
.. _iris_dataset:

Iris plants dataset
--------------------

**Data Set Characteristics:**

    :Number of Instances: 150 (50 in each of three classes)
    :Number of Attributes: 4 numeric, predictive attributes and the class
    :Attribute Information:
        - sepal length in cm
        - sepal width in cm
        - petal length in cm
        - petal width in cm
        - class:
                - Iris-Setosa
                - Iris-Versicolour
                - Iris-Virginica
                
    :Summary Statistics:

    ============== ==== ==== ======= ===== ====================
                    Min  Max   Mean    SD   Class Correlation
    ============== ==== ==== ======= ===== ====================
    sepal length:   4.3  7.9   5.84   0.83    0.7826
    sepal width:    2.0  4.4   3.05   0.43   -0.4194
    petal length:   1.0  6.9   3.76   1.76    0.9490  (high!)
    petal width:    0.1  2.5   1.20   0.76    0.9565  (high!)
    ============== ==== ==== ======= ===== ====================

    :Missing Attribute Values: None
    :Class Distribution: 33.3% for each of 3 classes.
    :Creator: R.A. Fisher
    :Donor: Michael Marshall (MARSHALL%PLU@io.arc.nasa.gov)
    :Date: July, 1988

The famous Iris database, first used by Sir R.A. Fisher. The dataset is taken
from Fisher's paper. Note that it's the same as in R, but not as in the UCI
Machine Learning Repository, which has two wrong data points.

This is perhaps the best known database to be found in the
pattern recognition literature.  Fisher's paper is a classic in the field and
is referenced frequently to this day.  (See Duda & Hart, for example.)  The
data set contains 3 classes of 50 instances each, where each class refers to a
type of iris plant.  One class is linearly separable from the other 2; the
latter are NOT linearly separable from each other.

   - Many, many more ...
'''
###### 首先用花瓣寬度進(jìn)行邏輯回歸
X = iris["data"][:, 3:]  # petal width
y = (iris["target"] == 2).astype(np.int)  # 1 if Iris-Virginica, else 0

from sklearn.linear_model import LogisticRegression
log_reg = LogisticRegression(random_state=42)
log_reg.fit(X, y)

X_new = np.linspace(0, 3, 1000).reshape(-1, 1)
y_proba = log_reg.predict_proba(X_new)
decision_boundary = X_new[y_proba[:, 1] >= 0.5][0]

plt.figure(figsize=(8, 3))
plt.plot(X[y==0], y[y==0], "bs")
plt.plot(X[y==1], y[y==1], "g^")
plt.plot([decision_boundary, decision_boundary], [-1, 2], "k:", linewidth=2)
plt.plot(X_new, y_proba[:, 1], "g-", linewidth=2, label="Iris-Virginica")
plt.plot(X_new, y_proba[:, 0], "b--", linewidth=2, label="Not Iris-Virginica")
plt.text(decision_boundary+0.02, 0.15, "Decision  boundary", fontsize=14, color="k", ha="center")
plt.arrow(decision_boundary, 0.08, -0.3, 0, head_width=0.05, head_length=0.1, fc='b', ec='b')
plt.arrow(decision_boundary, 0.92, 0.3, 0, head_width=0.05, head_length=0.1, fc='g', ec='g')
plt.xlabel("Petal width (cm)", fontsize=14)
plt.ylabel("Probability", fontsize=14)
plt.legend(loc="center left", fontsize=14)
plt.axis([0, 3, -0.02, 1.02])
plt.show()

decision_boundary
# array([1.61561562])
概率估計和決策邊界
######用花瓣長度和寬度兩個來特征進(jìn)行判斷
from sklearn.linear_model import LogisticRegression

X = iris["data"][:, (2, 3)]  # petal length, petal width
y = (iris["target"] == 2).astype(np.int)

# C: 正則化系數(shù)λ的倒數(shù)霞篡,float類型端逼,默認(rèn)為1.0。必須是正浮點型數(shù)余掖。越小的數(shù)值表示越強的正則化
log_reg = LogisticRegression(C=10**10, random_state=42)
log_reg.fit(X, y)

x0, x1 = np.meshgrid(
        np.linspace(2.9, 7, 500).reshape(-1, 1),
        np.linspace(0.8, 2.7, 200).reshape(-1, 1),
    )
X_new = np.c_[x0.ravel(), x1.ravel()]

y_proba = log_reg.predict_proba(X_new)

plt.figure(figsize=(10, 4))
plt.plot(X[y==0, 0], X[y==0, 1], "bs")
plt.plot(X[y==1, 0], X[y==1, 1], "g^")

zz = y_proba[:, 1].reshape(x0.shape)
contour = plt.contour(x0, x1, zz, cmap=plt.cm.brg)
# contour的用法: https://blog.csdn.net/cymy001/article/details/78513712

left_right = np.array([2.9, 7])
boundary = -(log_reg.coef_[0][0] * left_right + log_reg.intercept_[0]) / log_reg.coef_[0][1]

plt.clabel(contour, inline=1, fontsize=12)
plt.plot(left_right, boundary, "k--", linewidth=3)
plt.text(3.5, 1.5, "Not Iris-Virginica", fontsize=14, color="b", ha="center")
plt.text(6.5, 2.3, "Iris-Virginica", fontsize=14, color="g", ha="center")
plt.xlabel("Petal length", fontsize=14)
plt.ylabel("Petal width", fontsize=14)
plt.axis([2.9, 7, 0.8, 2.7])
plt.show()
線性決策邊界

Softmax回歸

Logistic 回歸模型可以直接推廣到支持多類別分類礁鲁,不必組合和訓(xùn)練多個二分類器,其稱為 Softmax 回歸或多類別 Logistic 回歸找田。
當(dāng)給定一個實例x時着憨,Softmax 回歸模型首先計算k類的分?jǐn)?shù)s_k(x),然后將分?jǐn)?shù)應(yīng)用在Softmax函數(shù)(也稱為歸一化指數(shù))上漆改,估計出每類的概率。s_k(x)=\theta^T_k\cdot x

Softmax函數(shù)
  • K表示有多少類
  • s(x)表示包含樣本x每一類得分的向量
  • \sigma(s(x))_k表示給定每一類分?jǐn)?shù)之后去扣,實例x屬于第k類的概率
預(yù)測結(jié)果

argmax 運算返回一個函數(shù)取到最大值的變量值樊破。返回使\sigma(s(x))_k最大時的k的值。

交叉熵

交叉熵博文

交叉熵的梯度向量
X = iris["data"][:, (2, 3)]  # petal length, petal width
y = iris["target"]

softmax_reg = LogisticRegression(multi_class="multinomial",solver="lbfgs", C=10, random_state=42)
softmax_reg.fit(X, y)

x0, x1 = np.meshgrid(
        np.linspace(0, 8, 500).reshape(-1, 1),
        np.linspace(0, 3.5, 200).reshape(-1, 1),
    )
X_new = np.c_[x0.ravel(), x1.ravel()]


y_proba = softmax_reg.predict_proba(X_new)
y_predict = softmax_reg.predict(X_new)

zz1 = y_proba[:, 1].reshape(x0.shape)
zz = y_predict.reshape(x0.shape)

plt.figure(figsize=(10, 4))
plt.plot(X[y==2, 0], X[y==2, 1], "g^", label="Iris-Virginica")
plt.plot(X[y==1, 0], X[y==1, 1], "bs", label="Iris-Versicolor")
plt.plot(X[y==0, 0], X[y==0, 1], "yo", label="Iris-Setosa")

from matplotlib.colors import ListedColormap
custom_cmap = ListedColormap(['#fafab0','#9898ff','#a0faa0'])

plt.contourf(x0, x1, zz, cmap=custom_cmap)
contour = plt.contour(x0, x1, zz1, cmap=plt.cm.brg)
plt.clabel(contour, inline=1, fontsize=12)
plt.xlabel("Petal length", fontsize=14)
plt.ylabel("Petal width", fontsize=14)
plt.legend(loc="center left", fontsize=14)
plt.axis([0, 7, 0, 3.5])
plt.show()
Softmax回歸的決策邊界

練習(xí)

如果有一個數(shù)百萬特征的訓(xùn)練集,應(yīng)該選擇哪種線性回歸訓(xùn)練算法朋其?

隨機梯度下降脆炎、小批量梯度下降
如果內(nèi)存夠,也可以使用批量梯度下降

如果訓(xùn)練集中特征的尺度(scale)差異很大秒裕,那種算法會受到影響?

損失函數(shù)的形狀會變得很細(xì)長癞松,梯度下降算法收斂會很慢入蛆。訓(xùn)練之前應(yīng)該應(yīng)該將尺度歸一化硕勿。

在有足夠的訓(xùn)練時間下,是否所有的梯度下降都會得到相同的模型參數(shù)扼褪?

隨機梯度和小批量梯度的結(jié)果會有略微區(qū)別粱栖,其他的區(qū)別不大。

假設(shè)使用批量梯度下降法闹究,畫出每一迭代的驗證誤差。當(dāng)發(fā)現(xiàn)驗證誤差一直增大赏寇,接下來會發(fā)生什么?你怎么解決這個問題嗅定?

說明學(xué)習(xí)率太大了渠退,減小學(xué)習(xí)率

當(dāng)驗證誤差升高時,立即停止小批量梯度下降是否是一個好主意碎乃?

應(yīng)該保留那個值,如果長時間沒有更好的值旱眯,則停止证九。

假設(shè)使用多項式回歸,畫出學(xué)習(xí)曲線愧怜,在圖上發(fā)現(xiàn)學(xué)習(xí)誤差和驗證誤差之間有著很大的間隙拥坛。這表示發(fā)生了什么蓬蝶?什么方法可以解決這個問題丸氛?

過擬合了著摔。減小多項式的最高項,或者正則化模型谍咆,即添加懲罰項。

假設(shè)使用嶺回歸恩掷,并發(fā)現(xiàn)訓(xùn)練誤差和驗證誤差都很高供嚎,并且?guī)缀跸嗟鹊┣D愕哪P捅憩F(xiàn)是高偏差還是高方差寸宏?這時你應(yīng)該增大正則化參數(shù) ,還是降低它羔巢?

高偏差罩阵,降低正則化參數(shù)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末幽钢,一起剝皮案震驚了整個濱河市傅是,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌帽驯,老刑警劉巖书闸,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異嫌术,居然都是意外死亡牌借,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進(jìn)店門蚯嫌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來丙躏,“玉大人束凑,你說我怎么就攤上這事⊥羲撸” “怎么了谈秫?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵拟烫,是天一觀的道長迄本。 經(jīng)常有香客問我,道長置媳,這世上最難降的妖魔是什么公条? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮寥袭,結(jié)果婚禮上关霸,老公的妹妹穿的比我還像新娘。我一直安慰自己谒拴,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布炭序。 她就那樣靜靜地躺著苍日,像睡著了一般。 火紅的嫁衣襯著肌膚如雪辜纲。 梳的紋絲不亂的頭發(fā)上拦耐,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天,我揣著相機與錄音扫俺,去河邊找鬼固翰。 笑死羹呵,一個胖子當(dāng)著我的面吹牛疗琉,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播凑耻,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼送火,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了弃衍?” 一聲冷哼從身側(cè)響起坚俗,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎速缆,沒想到半個月后恩闻,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡破停,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年尉剩,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片理茎。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖朗鸠,靈堂內(nèi)的尸體忽然破棺而出式撼,到底是詐尸還是另有隱情,我是刑警寧澤扰楼,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布美浦,位于F島的核電站,受9級特大地震影響蹬竖,放射性物質(zhì)發(fā)生泄漏流酬。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一旦装、第九天 我趴在偏房一處隱蔽的房頂上張望摊滔。 院中可真熱鬧,春花似錦艰躺、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至纷纫,卻和暖如春陪腌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背诗鸭。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工强岸, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蝌箍。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像杂拨,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子檀夹,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,465評論 2 348