日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

机器学习实战(用Scikit-learn和TensorFlow进行机器学习)(五)

發(fā)布時間:2024/1/17 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 机器学习实战(用Scikit-learn和TensorFlow进行机器学习)(五) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

上幾節(jié)講述了真實數(shù)據(jù)集在回歸問題以及分類問題上的總流程,但是對于模型的選擇及參數(shù)的選擇仍然一知半解,因此本節(jié)開始講述關(guān)于模型的一些知識,本節(jié)會略過一些比較基礎(chǔ)的知識,將一些較為深入的知識。如果在哪個方面沒有看懂,可以在網(wǎng)上查詢,網(wǎng)上基礎(chǔ)資料也比較多,也可以在下方評論。

五、訓練模型

1、線性模型

線性模型形如:

y=θ0+θ1x1+θ2x2+?θnxny=θ0+θ1x1+θ2x2+?θnxn 為了得到使均方誤差最小的θθ,一般采用兩種方法:

Normal Equation

使用數(shù)學方法推導能直接求得參數(shù)θθ的方法為Normal Equation。而對于線性模型,數(shù)學方法為:最小二乘法。

通過最小二乘法能直接得到線性模型:

θ^=(XTX)?1XTyθ^=(XTX)?1XTy 對應的Scikit-learn中的函數(shù)為LinearRegression,下面是一個例子y=4*x+3

import numpy as np X = 2 * np.random.rand(100, 1) y = 4 + 3 * X + np.random.randn(100, 1)from sklearn.linear_model import LinearRegression lin_reg = LinearRegression() lin_reg.fit(X, y) lin_reg.intercept_, lin_reg.coef_
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

可以看到得到的結(jié)果接近4和3,沒有達到準確值是由于加入了隨機噪聲的原因。

??雖然能夠精確的得到結(jié)果,但是這個算法的復雜度很高,計算XTXXTX?的逆的算法復雜度就為O(n2.4)?O(n3)O(n2.4)?O(n3),如果訓練樣本非常大,則運行時間會很長。而且這只是只有一種特征的情況,則運行時間會更長。?
??因此這種方法適合數(shù)據(jù)量較小的情況,能夠找到精確解。

梯度下降法(Gradient Descent)

??為了處理訓練樣本數(shù)比較大數(shù)據(jù),通常采用梯度下降法,得到一個近似解,但是速度較快。梯度下降法就是通過設(shè)置學習率eta與迭代次數(shù),每一代計算目標函數(shù)的梯度來更新權(quán)值的方法。(具體不做介紹)?
??學習率太小會導致收斂太慢,學習率太大會導致偏離最優(yōu)解,因此可以通過之前講的grid search來調(diào)整參數(shù)。對于迭代次數(shù)可以一開始設(shè)置一個比較大的數(shù),當梯度開始變得很小時,則可以停下來,記錄迭代次數(shù)。

Batch Gradient Descent

Batch Gradient Descent即每次迭代使用所有樣本計算梯度,取平均,來更新參數(shù)。可以看到這個方法能直接朝著最優(yōu)解方向前進。

??????????????

eta = 0.1 # learning rate n_iterations = 1000 m = 100 theta = np.random.randn(2,1) # random initialization X_b = np.c_[np.ones((100, 1)), X] for iteration in range(n_iterations):gradients = 2/float(m) * X_b.T.dot(X_b.dot(theta) - y)theta = theta - eta * gradients
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

Stochastic Gradient Descent

??由于Batch Gradient Descent每次迭代使用全部訓練集,當訓練集數(shù)據(jù)量較大時,訓練速度則會很慢。因此與這個相反,隨機梯度下降(Stochastic Gradient Descent)就是每一代隨機選擇一個樣本,計算梯度,更新參數(shù)。由于每次只抽取一個樣本,因此在大量數(shù)據(jù)也能很好的計算。

?????????????

??但是當接近最優(yōu)解時(如圖)始終無法收斂到最優(yōu)解,這是由于每次根據(jù)一個樣本更新參數(shù),每個樣本都有自己的梯度方向,所以會不斷的在最優(yōu)解附近振蕩。為了解決這個問題,引入了learning_schedule參數(shù),這個一個學習率衰減參數(shù),在迭代的過程中,不斷減少學習率,在迭代結(jié)束時學習率非常小,可以看作不再振蕩,接近最優(yōu)解。

隨機梯度下降skicit-learn也有對應的函數(shù):其中n_iter為迭代次數(shù),eta0為學習率,penalty下面會說到。

from sklearn.linear_model import SGDRegressor sgd_reg = SGDRegressor(n_iter=50, penalty=None, eta0=0.1) sgd_reg.fit(X, y.ravel()) sgd_reg.intercept_, sgd_reg.coef_
  • 1
  • 2
  • 3
  • 4

Mini-batch Gradient Descent

??結(jié)合Batch Gradient Descent和Stochastic Gradient Descent,每一代計算Mini-batch(遠小于Batch)個樣本的梯度,計算平均值,更新參數(shù)。這種方式的好處是能在數(shù)據(jù)量比較大的訓練樣本中進行矩陣運算,特別是可以在GPU上計算。(在深度學習中運用的比較多)?


2、多項式模型

??如果數(shù)據(jù)不是簡單的一條直線,也可以通過線性模型來訓練,其中一種比較簡單的方法是通過給訓練數(shù)據(jù)特征開n次方。下面是一個例子:

m = 100 X = 6 * np.random.rand(m, 1) - 3 y = 0.5 * X**2 + X + 2 + np.random.randn(m, 1)from sklearn.preprocessing import PolynomialFeatures poly_features = PolynomialFeatures(degree=2, include_bias=False) X_poly = poly_features.fit_transform(X) X[0],X_poly[0]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

可以看到,通過PolynomialFeatures以后,得到新的特征(x,x2)(x,x2),再用這個新特征訓練一個線性模型。

lin_reg = LinearRegression() lin_reg.fit(X_poly, y)
  • 1
  • 2

注:若存在兩個特征a和b,若degree=2時,不僅增加了a2a2b2b2,還有abab

Learning Curves

??如果使用高degree創(chuàng)造非常多特征來作多項式模型,你能夠很好的擬合訓練數(shù)據(jù)。然而這種只對訓練數(shù)據(jù)擬合的情況稱為過擬合(如圖),而對于線性模型則為欠擬合。

????

??為了檢測模型是否有效,在第3節(jié)已經(jīng)講述了其中一種方法,交叉驗證法。下面再介紹一種方法Learning Curves。通過分開訓練和驗證集,不斷調(diào)整訓練集的數(shù)量,計算均方誤差來畫出曲線,觀察訓練集和驗證集在訓練中的情況。

import matplotlib.pyplot as plt 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)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_predict, y_train[:m]))val_errors.append(mean_squared_error(y_val_predict, y_val))plt.plot(np.sqrt(train_errors), "r-+", linewidth=2, label="train")plt.plot(np.sqrt(val_errors), "b-", linewidth=3, label="val")plt.xlabel("Training set size") plt.ylabel("RMSE") lin_reg = LinearRegression() plot_learning_curves(lin_reg, X, y)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

????????

??可以看到當訓練集中只有一個或兩個實例時,模型可以完美地擬合它們,這就是曲線從零開始的原因。但是,當新樣本被添加到訓練集時,模型不可能很好地擬合訓練數(shù)據(jù),這是由于樣本是復雜的。再看看驗證數(shù)據(jù)上模型的性能。當模型在很少的訓練樣本時,就不能很好的泛化推廣,這就是為什么驗證錯誤最初是相當大的。當新樣本被添加到訓練集時,通過學習,從而驗證錯誤緩慢下降。誤差最終會停留在一個類似高原的地方。?
??上面為degree=1的模型,再看看degree=10的模型

from sklearn.pipeline import Pipeline polynomial_regression = Pipeline(( ("poly_features", PolynomialFeatures(degree=10, include_bias=False)), ("sgd_reg", LinearRegression()), )) plot_learning_curves(polynomial_regression, X, y) plt.ylim(0,2)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

??????????

??可以看到degree=10的訓練誤差和驗證誤差都比degree=1的要小。所以該模型較好。我們還可以看到兩條曲線中間的間隙,間隙越大,說明過擬合程度越大。?


3、正則化線性模型(Regularized Linear Models)

為了防止過擬合,可以給模型損失函數(shù)(如均方誤差)增加正則項。

Ridge Regression(L2正則化)

Ridge Regression的損失函數(shù)為:

J(θ)=MSE(θ)+α12i=1nθi2J(θ)=MSE(θ)+α12∑i=1nθi2

??可以看到加入后面的正則項后會使θθ靠近0,直觀上可以理解為對MSE(θ)MSE(θ)(即模型)貢獻越小的θθ,懲罰越大,這樣的θθ越小,所以通過正則化能夠減小這些無關(guān)特征帶來的影響。

需要注意的是:在Ridge Regression之前要先對特征進行縮放(標準化或最大最小縮放),這是因為Ridge Regression對特征的尺度大小很敏感。

??同樣有兩種方法計算最優(yōu)解Normal Equation和梯度下降法。

??對于Normal Equation結(jié)果為:

θ^?= (XTX +?αA)?1XTyθ^?= (XTX +?αA)?1XTy

對應的代碼為

from sklearn.linear_model import Ridge ridge_reg = Ridge(alpha=1, solver="cholesky") ridge_reg.fit(X, y)
  • 1
  • 2
  • 3

隨機梯度下降L2正則化對應的代碼為

from sklearn.linear_model import SGDRegressor sgd_reg = SGDRegressor(penalty="l2") sgd_reg.fit(X, y.ravel())
  • 1
  • 2
  • 3

??????????

?? 通過設(shè)置不同的αα值,可以看到通過正則化后曲線變得平緩,看起來比沒有正則化的曲線有著更好的泛化推廣能力。

Lasso Regression(L1正則化)

Lasso Regression的損失函數(shù)為:?

J(θ)=MSE(θ)+αi=1n|θi|J(θ)=MSE(θ)+α∑i=1n|θi| ??與L2正則化不同的是,正則項從二次方變?yōu)榱艘淮畏诺慕^對值,這就帶來的一個特性,不同于L2正則化使得θθ在原點附近(即大部分θθ都靠近0),L1正則化使得θθ更趨向于在坐標軸上(即大部分的θθ等于零,少部分靠近零),相當于懲罰變得更大。

#最小二乘LASSO方法 from sklearn.linear_model import Lasso lasso_reg = Lasso(alpha=0.1) lasso_reg.fit(X, y)#隨機梯度下降正則化L2(線性) from sklearn.linear_model import SGDRegressor sgd_reg = SGDRegressor(penalty="l1") sgd_reg.fit(X, y.ravel())
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

???????????

可以看到經(jīng)過L1正則化后曲線變得更加平緩,更像一條直線。

需要注意的是:L1正則化后會導致在最優(yōu)點附近震蕩,因此要像隨機梯度下降一樣減小學習率。

Elastic Net

Elastic Net的損失函數(shù)為:

J(θ)=MSE(θ)+rαi=1n|θi|+1?r2αi=1nθi2J(θ)=MSE(θ)+rα∑i=1n|θi|+1?r2α∑i=1nθi2

??可以看到Elastic Net是L1正則化和L2正則化的結(jié)合,通過一個參數(shù)調(diào)整比例。

#最小二乘ElasticNet方法 from sklearn.linear_model import ElasticNet elastic_net = ElasticNet(alpha=0.1, l1_ratio=0.5) elastic_net.fit(X, y)#隨機梯度下降ElasticNet(線性) from sklearn.linear_model import SGDRegressor sgd_reg = SGDRegressor(penalty="elasticnet",l1_ratio=0.5) sgd_reg.fit(X, y.ravel())
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

如何選擇正則化

??加入少量的正則化一般都會給模型帶來一定的提升。一般情況下都會選擇Ridge(L2正則化);但是如果得知數(shù)據(jù)中只有少量的特征是有用的,那么推薦使用Lasso(L1正則化)或Elastic Net;一般來說Elastic Net會比Lasso效果要好,因為當遇到強相關(guān)性特征說特征數(shù)量大于訓練樣本時Lasso會表現(xiàn)的很奇怪。?

提前中斷訓練(Early Stopping)

??通過調(diào)整迭代次數(shù),在驗證誤差達到最小時立即停止訓練。圖中是用Batch Gradient Descent訓練的,隨著迭代次數(shù)的上升,驗證集上的預測誤差會下降。 但是,過了一段時間驗證錯誤停止下降,反而往上開始回升。 這表明該模型已經(jīng)開始過度擬合訓練數(shù)據(jù)。 一旦驗證錯誤達到最小,立即停止訓練。 這是一種簡單而有效的正則化技術(shù)。

??????

需要注意的是:對于Stochastic 和 Mini-batch Gradient Descent的曲線不會這么平滑。其中一種方案是當?shù)竭_最低點時,再過一段時間(當你覺得不會再下降),停止,將參數(shù)調(diào)回到當時的最低點。

下面是一個例子,當warm_start=True時,調(diào)用fit()后繼續(xù)訓練模型而不是重新訓練模型。

from sklearn.base import clone sgd_reg = SGDRegressor(n_iter=1, warm_start=True, penalty=None, learning_rate="constant", eta0=0.0005) minimum_val_error = float("inf") #正無窮 best_epoch = None best_model = None for epoch in range(1000):sgd_reg.fit(X_train_poly_scaled, y_train) # 繼續(xù)訓練y_val_predict = sgd_reg.predict(X_val_poly_scaled)val_error = mean_squared_error(y_val_predict, y_val)if val_error < minimum_val_error:minimum_val_error = val_errorbest_epoch = epochbest_model = clone(sgd_reg) #保存模型
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14



4、Logistic回歸(Logistic Regression)

Logistic回歸與線性回歸模型比較相似,Logistic回歸在線性回歸模型的基礎(chǔ)上增加了sigmoid函數(shù)σ()σ(),即

hθ(x)=σ(θTx)hθ(x)=σ(θTx) 其中 σ(t)=11+e?tσ(t)=11+e?t 損失函數(shù)采用對數(shù)似然損失函數(shù): J(θ)=?1mi=1m[yilog(hθ(xi))+(1?yi)log(1?hθ(xi)]J(θ)=?1m∑i=1m[yilog?(hθ(xi))+(1?yi)log?(1?hθ(xi)] 訓練與線性回歸模型相似,可以計算梯度,用梯度下降法更新參數(shù)。

??下面利用Logistic回歸對真實數(shù)據(jù)Iris進行分類。Iris數(shù)據(jù)為150個訓練樣本,包含4個特征,分為3類。

??首先先用Logistic模型作一個二分類器。取出其中一種特征,判斷是否為某一類。

#Iris import numpy as np from sklearn import datasets iris = datasets.load_iris() X = iris["data"][:, 3:] # 只讀取最后一個特征 y = (iris["target"] == 2).astype(np.int) # 取出判斷是否為第3類的label#訓練Logistic回歸模型 from sklearn.linear_model import LogisticRegression log_reg = LogisticRegression() log_reg.fit(X, y)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

對于一個二分類問題,還可以畫出判別線

????????????

注:對于Logistic回歸同樣需要L1,L2正則化,而這個scikit-learn也默認設(shè)置了。?


4、Softmax回歸(Softmax Regression)

??對于Logistic回歸是一個二分類器,然而不需要像第4節(jié)所講到了訓練多個二分類器來實現(xiàn)多分類。Logistic回歸可以直接擴展成一個多分類器Softmax回歸。

??與Logistic回歸相似,Softmax回歸計算每一類的一個概率,歸為概率最大的一類。

Softmax函數(shù)為:

p^k=σ(s(x))k=exp(sk(x))j=1Kexp(sj(x))p^k=σ(s(x))k=exp?(sk(x))∑j=1Kexp?(sj(x)) 其中: sk(x)=θkTxsk(x)=θkTx 其中K為類別數(shù),需要注意的是 θkθk說明每個類別對應有自己的 θθ,所有 θkθk組合起來是全部的參數(shù)。

對于Softmax回歸使用交叉熵(cross entropy)函數(shù)作為損失函數(shù):

J(θ)=?1mi=1mk=1Kyk(i)log(p^k(i))J(θ)=?1m∑i=1m∑k=1Kyk(i)log?(p^k(i)) 訓練與線性回歸模型相似,可以計算每一類的偏導數(shù),用梯度下降法更新每一類的參數(shù)。

下面是一個實例,LogisticRegression默認使用(OVA),如果使用Softmax就把multi_class=”multinomial”

X = iris["data"][:, (2, 3)] # petal length, petal width y = iris["target"] softmax_reg = LogisticRegression(multi_class="multinomial",solver="lbfgs", C=10) softmax_reg.fit(X, y)
  • 1
  • 2
  • 3
  • 4
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎

總結(jié)

以上是生活随笔為你收集整理的机器学习实战(用Scikit-learn和TensorFlow进行机器学习)(五)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。