1. 線性回歸
模型
y表示預(yù)測結(jié)果
n表示特征的個數(shù)
xi表示第 i 個特征的值
θj表示第 j 個參數(shù)
h表示假設(shè)函數(shù)
正態(tài)方程
實踐過程中系忙,最小化MSE更簡單
使得MSE最小的解為:
構(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()
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ù)雜度大約在到之間临燃。
梯度下降
這種方法適合在特征個數(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ù))
下圖展示了梯度下降在不同訓(xùn)練集上的表現(xiàn)。在左圖中,特征 1 和特征 2 有著相同的數(shù)值尺度碍论。在右圖中唆涝,特征 1 比特征2的取值要小的多靡挥。左面的梯度下降可以直接快速地到達(dá)最小值坟奥,然而在右面的梯度下降第一次前進(jìn)的方向幾乎和全局最小值的方向垂直,并且最后到達(dá)一個幾乎平坦的山谷婴栽,在平坦的山谷走了很長時間满粗。它最終會達(dá)到最小值,但它需要很長時間愚争。
當(dāng)使用梯度下降的時候映皆,應(yīng)該確保所有的特征有著相近的尺度范圍(例如:使用Scikit Learn 的 StandardScaler 類)挤聘,否則它將需要很長的時間才能夠收斂。
批量梯度下降
使用梯度下降的過程中捅彻,需要計算每一個下?lián)p失函數(shù)的梯度组去。換句話說,你需要計算當(dāng)變化一點點時(即偏導(dǎo)數(shù))步淹,損失函數(shù)改變了多少从隆。
損失函數(shù)的梯度向量為:
在這個方程中每一步計算時都包含了整個訓(xùn)練集
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)
隨機梯度下降
批量梯度下降的最要問題是計算每一步的梯度時都需要使用整個訓(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()
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()
使用 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()
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()
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()
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()
改善模型過擬合的一種方法是提供更多的訓(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)重(的大小)逃顶。 接下來我們將介紹三種不同約束權(quán)重的方法:Ridge 回歸,Lasso 回歸和 Elastic Net以政。
正則化好文
L1, L2 物理意義
Ridge回歸(Tikhonov 正則化、L2正則化)
Ridge回歸是線性回歸的正則化版废菱,在損失函數(shù)上直接加上一個正則項(的L2范數(shù)),使得學(xué)習(xí)算法不僅能夠擬合數(shù)據(jù)眉反,而且能夠使模型的參數(shù)權(quán)重盡量的小昙啄。注意到寸五,是沒有被正則化的耿币。
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 回歸的一個重要特征是它傾向于完全消除最不重要的特征的權(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 回歸正則項的簡單混合篙螟。
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ù)慢味。
概率估計
損失函數(shù)
決策邊界
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)給定一個實例時着憨,Softmax 回歸模型首先計算類的分?jǐn)?shù),然后將分?jǐn)?shù)應(yīng)用在Softmax函數(shù)(也稱為歸一化指數(shù))上漆改,估計出每類的概率。
- 表示有多少類
- 表示包含樣本x每一類得分的向量
- 表示給定每一類分?jǐn)?shù)之后去扣,實例屬于第類的概率
argmax 運算返回一個函數(shù)取到最大值的變量值樊破。返回使最大時的的值。
交叉熵博文
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()
練習(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ù)。