2024-08-27|閱讀時間 ‧ 約 23 分鐘

【資料分析】python機器學習-Overfitting的判斷與處理

raw-image

過擬合(Overfitting)是機器學習中的一個常見問題,指的是模型在訓練數據上表現得非常好,但在處理未見過的測試數據或新數據時表現不佳。這通常發生在模型過於複雜,學習到了訓練數據中的噪聲和特異點,導致模型無法很好地泛化到新的數據集。過度擬合的模型可能會在訓練數據上取得很高的準確率,但這種高準確率並不能反映模型的真實性能。為了避免過度擬合,可以採取多種策略,如增加數據量、使用正則化、簡化模型結構、應用交叉驗證等。這些方法可以幫助模型學習到數據中的真正模式,從而提升其在未來預測中的準確性和可靠性。


# 可使用目錄功能快速確認要閱覽的主題


如何判斷自己的模型是否 Overfitting (過擬合)


1. 訓練集與測試集準確率比較

  • 方法:將數據集分成訓練集和測試集,訓練模型後,分別計算訓練集和測試集的準確率。
  • 判斷標準:如果模型在訓練集上表現很好(高準確率),但在測試集上的準確率明顯較低,這通常是過擬合的跡象。
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

# 假設 df 是我們的數據集
df_train = df_analysis[0:891]
X = df_train.drop(columns=['Survived']) # 所有特徵
y = df_train['Survived'] # 目標變數 'Survived'

# 分割數據集
train_X, test_X, train_y, test_y = train_test_split(X, y, train_size=0.7, random_state=42)

# 建立隨機森林模型
model = RandomForestClassifier(n_estimators=100, max_depth=8, random_state=42)
model.fit(train_X, train_y)

# 預測訓練集與測試集
train_pred = model.predict(train_X)
test_pred = model.predict(test_X)

# 計算準確率
train_accuracy = accuracy_score(train_y, train_pred)
test_accuracy = accuracy_score(test_y, test_pred)

print(f"訓練集準確率: {train_accuracy:.2f}")
print(f"測試集準確率: {test_accuracy:.2f}")

"""
訓練集準確率: 0.92
測試集準確率: 0.81
"""

通常如果準確率的差異超過 5%-10%,可能需要考慮過擬合的可能性。


訓練集與測試集準確率比較適用場景:

  • 用於基礎模型訓練和初步評估。
  • 當你有一個明確的訓練集和測試集時,此方法非常直觀且易於執行。

訓練集與測試集準確率比較優點:

  • 簡單直接:只需比較訓練集和測試集的性能差異,即可判斷模型是否過擬合。
  • 快速:計算和解釋簡單,適合初步評估。

訓練集與測試集準確率比較缺點:

  • 可能不可靠:僅依賴單次的訓練/測試分割,結果可能受測試集選擇的影響,導致不穩定的評估結果。
  • 過於簡單:無法充分反映模型的泛化能力,特別是在數據較少或數據異質性較大的情況下。


2. 交叉驗證

  • 方法:使用交叉驗證(如 K 折交叉驗證)來評估模型的穩定性。
  • 判斷標準:如果交叉驗證的各次測試結果差異很大,則可能存在過擬合。交叉驗證的標準差越小,模型的穩定性越高。
from sklearn.model_selection import cross_val_score

# 使用 5 折交叉驗證來評估模型
cv_scores = cross_val_score(model, X, y, cv=5, scoring='accuracy')

print(f"交叉驗證準確率: {cv_scores}")
print(f"交叉驗證平均準確率: {cv_scores.mean():.2f}")
print(f"交叉驗證標準差: {cv_scores.std():.2f}")

"""
交叉驗證準確率: [0.80446927 0.81460674 0.86516854 0.81460674 0.85955056]
交叉驗證平均準確率: 0.83
交叉驗證標準差: 0.03
"""


交叉驗證適用場景:

  • 用於模型選擇和調參時,尤其適合於數據集較小的情況。
  • 在訓練數據有限且希望最大化利用數據時,交叉驗證非常有用。

交叉驗證優點:

  • 穩定性強:通過多次數據分割來平均性能指標,減少了測試集選擇的隨機性影響。
  • 全數據利用:交叉驗證利用了全部的數據來進行訓練和測試,適合數據稀缺的情況。

交叉驗證缺點:

  • 計算成本高:特別是當數據量大或交叉驗證的折數(如k-fold中的k)較大時,計算代價較高。
  • 不直觀:結果為多次訓練的平均值,有時候可能不如單次測試集評估結果易於解釋。


3. 學習曲線

  • 方法:繪製模型的學習曲線,觀察模型的訓練誤差和測試誤差隨著訓練樣本量增加的變化情況。
  • 判斷標準:如果訓練誤差很低但測試誤差很高,並且測試誤差沒有隨著更多數據的加入而顯著下降,這表示過擬合。
from sklearn.model_selection import learning_curve
import matplotlib.pyplot as plt
import numpy as np

# 繪製學習曲線
train_sizes, train_scores, test_scores = learning_curve(model, X, y, cv=5, n_jobs=-1,
train_sizes=np.linspace(0.1, 1.0, 10))

train_scores_mean = np.mean(train_scores, axis=1)
test_scores_mean = np.mean(test_scores, axis=1)

plt.plot(train_sizes, train_scores_mean, label='Training Accuracy')
plt.plot(train_sizes, test_scores_mean, label='Validation Accuracy')
plt.xlabel('Training Size')
plt.ylabel('Accuracy')
plt.legend()
plt.show()

如果訓練誤差很低但測試誤差很高,並且測試誤差沒有隨著更多數據的加入而顯著下降,這表示過擬合。

範例:

訓練集準確率 (Training Accuracy)

    • 藍色線代表訓練集的準確率,這條線從接近1.0(100%)的高準確率開始,隨著訓練集大小的增加而逐漸下降並趨於穩定,最終穩定在大約 0.9 左右。
    • 這個現象表明,當模型只用少量的訓練數據進行訓練時,它可以非常精確地擬合訓練數據(幾乎完美),但這也意味著可能存在過擬合的風險。隨著更多的訓練數據被加入,模型逐漸學習到更普遍的模式,導致訓練準確率稍微下降,但這也代表模型的泛化能力變得更好。

測試集準確率 (Validation Accuracy)

    • 橘色線代表驗證集的準確率,這條線一開始從較低的準確率(大約 0.75)開始,隨著訓練集的增加而逐漸上升,最終在大約 0.82 左右趨於穩定。
    • 這說明隨著更多的訓練數據被使用,模型能更好地泛化到未見過的數據,因此驗證集準確率上升。

模型的狀態

    • 如果你觀察到兩條線之間存在較大的間隙(訓練準確率明顯高於驗證準確率),這表明你的模型可能存在過擬合的問題。
    • 在這個圖中,訓練集與驗證集之間的準確率差距(約0.1)雖然不小,但在模型學習到穩定的模式後,它們的趨勢開始變得較為穩定,這意味著模型並沒有嚴重的過擬合,但仍可能有進一步改善的空間。

結論:

  • 目前的狀況:你的模型訓練集準確率較高,但測試集的準確率較低,這可能提示存在輕微的過擬合現象。
  • 下一步動作:可以考慮進一步調整模型,例如增加正則化強度、簡化模型結構或收集更多的數據來減少過擬合的風險。


學習曲線適用場景:

  • 當你想了解模型性能隨著訓練數據量增長的變化時,學習曲線特別有用。
  • 用於分析模型複雜度對性能的影響,適合處理高維度數據或在模型調整過程中使用。

學習曲線優點:

  • 全面分析:提供了模型性能隨著訓練數據量和模型複雜度變化的視覺化表示。
  • 過擬合和欠擬合的指導:通過學習曲線可以清晰地看到模型是否過擬合或欠擬合,並且可以通過增加數據量來改善模型。

學習曲線缺點:

  • 計算成本高:需要多次訓練模型以繪製曲線,特別是在數據量大時計算代價更高。
  • 解釋複雜:對於非技術用戶來說,解釋學習曲線可能較為困難。


4. 簡化模型

  • 方法:減少模型的複雜度,例如減少決策樹的深度、使用更少的特徵、或者減少神經網絡的層數和參數數量。
  • 判斷標準:觀察簡化後模型的測試誤差是否降低。如果測試誤差降低而訓練誤差略有增加,則說明之前的模型可能過擬合。
# 建立更簡單的模型,減少 max_depth
simple_model = RandomForestClassifier(n_estimators=100, max_depth=4, random_state=42)
simple_model.fit(train_X, train_y)

# 再次預測訓練集與測試集
train_pred_simple = simple_model.predict(train_X)
test_pred_simple = simple_model.predict(test_X)

# 計算簡化模型的準確率
train_accuracy_simple = accuracy_score(train_y, train_pred_simple)
test_accuracy_simple = accuracy_score(test_y, test_pred_simple)

print(f"簡化模型訓練集準確率: {train_accuracy_simple:.2f}")
print(f"簡化模型測試集準確率: {test_accuracy_simple:.2f}")

觀察簡化後模型的測試誤差是否降低。如果測試誤差降低而訓練誤差略有增加,則說明之前的模型可能過擬合。


簡化模型適用場景:

  • 當模型表現出過擬合現象且希望減少模型的複雜度時,這是常用的策略。
  • 適合模型複雜度高或特徵數量多的情況。

簡化模型優點:

  • 減少過擬合風險:通過減少模型參數或特徵數量,可以降低模型的複雜度,從而減少過擬合的風險。
  • 提升解釋性:簡化後的模型通常更容易解釋和理解。

簡化模型缺點:

  • 可能犧牲精度:過度簡化模型可能導致模型無法捕捉數據中的所有模式,從而降低模型的準確性。
  • 需要經驗:簡化模型需要對數據和模型有較深入的理解,否則可能誤減去重要特徵。


5. 正則化 (Regularization)

※因翻譯問題,有時被翻譯為正規化,但要注意 Normalization 也被翻譯為正規化,兩者是不同東西

  • 方法:正則化通過在損失函數(loss function)中加入懲罰項(penalty term)來約束模型的複雜度,從而鼓勵模型參數(如權重)的值保持較小或接近零。這樣,模型更能泛化到新數據,減少過度擬合的風險。應用正則化技術(如 L1 或 L2 正則化)來限制模型的複雜度。
  • 判斷標準:引入正則化項後,如果模型的測試誤差降低而訓練誤差略有增加,則過擬合得到了改善。


常見的正則化方法

小結

  • L1正則化適合特徵數量多且希望進行特徵選擇的情況。
  • L2正則化適合希望獲得穩定解且特徵間存在多重共線性的情況。
  • Elastic Net適合同時需要L1和L2優勢的場景,可以在特徵選擇和模型穩定性之間取得平衡。


5-1 L1正則化(Lasso, Least Absolute Shrinkage and Selection Operator)

  • 在損失函數中加入權重的絕對值之和作為懲罰項。
  • 正則化項:λ * Σ|w|
  • 這會導致一些權重變為零,因此可以用來進行特徵選擇(Feature Selection),因為它會將不重要的特徵的權重壓縮為零。

適用場景

  • 特徵選擇:L1正則化適合在特徵數量較多,但其中一些特徵可能是冗餘的或不重要的情況下使用。由於L1會將某些權重壓縮為零,它能幫助識別並排除不重要的特徵。
  • 稀疏解:當希望模型的解是稀疏的(即僅有少量非零權重)時,L1正則化是理想選擇。
from sklearn.linear_model import Lasso
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error

# 載入數據集
data = load_boston()
X = data.data
y = data.target

# 分割資料集為訓練集和測試集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# 標準化數據
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)

# 應用L1正則化(Lasso)
lasso = Lasso(alpha=0.1) # alpha是正則化強度的參數
lasso.fit(X_train, y_train)

# 預測與評估
y_pred = lasso.predict(X_test)
mse = mean_squared_error(y_test, y_pred)
print(f"Mean Squared Error: {mse}")
print(f"Selected Features: {lasso.coef_}")

引入正則化項後,如果模型的測試誤差降低而訓練誤差略有增加,則過擬合得到了改善。


5-2 L2正則化(Ridge)

  • 在損失函數中加入權重的平方和作為懲罰項。
  • 正則化項:λ * Σw²
  • 這會使得權重趨向於較小的值,但不會將它們變為零。它有助於減少模型的複雜性,但不會像L1那樣進行特徵選擇。

適用場景

  • 避免過度擬合:L2正則化適合在特徵數量較多且它們之間可能存在多重共線性的情況下使用。L2正則化會平滑權重,防止它們變得過大。
  • 穩定解:當需要一個穩定的解,不希望完全忽略某些特徵(即權重不會完全壓縮為零)時,L2正則化是首選。
from sklearn.linear_model import Ridge

# 應用L2正則化(Ridge)
ridge = Ridge(alpha=0.1) # alpha是正則化強度的參數
ridge.fit(X_train, y_train)

# 預測與評估
y_pred = ridge.predict(X_test)
mse = mean_squared_error(y_test, y_pred)
print(f"Mean Squared Error: {mse}")
print(f"Model Coefficients: {ridge.coef_}")

引入正則化項後,如果模型的測試誤差降低而訓練誤差略有增加,則過擬合得到了改善。


5-3 Elastic Net

  • 結合了L1和L2正則化的優點,在損失函數中同時加入權重的絕對值和平方和作為懲罰項。
  • 正則化項:λ1 * Σ|w| + λ2 * Σw²
  • 這種方法同時具備L1的特徵選擇能力和L2的穩定性。

適用場景

  • 混合稀疏和穩定性:Elastic Net適合在特徵之間存在多重共線性、並且希望同時擁有L1和L2正則化優勢的情況下使用。它能在L1的稀疏性和L2的穩定性之間取得平衡。
  • 模型性能優化:當單獨使用L1或L2無法獲得最佳結果時,Elastic Net經常被用來優化模型性能。
from sklearn.linear_model import ElasticNet

# 應用Elastic Net
elastic_net = ElasticNet(alpha=0.1, l1_ratio=0.5) # l1_ratio控制L1L2的比例
elastic_net.fit(X_train, y_train)

# 預測與評估
y_pred = elastic_net.predict(X_test)
mse = mean_squared_error(y_test, y_pred)
print(f"Mean Squared Error: {mse}")
print(f"Model Coefficients: {elastic_net.coef_}")

引入正則化項後,如果模型的測試誤差降低而訓練誤差略有增加,則過擬合得到了改善。


正則化適用場景:

  • 當你懷疑模型過擬合時,正則化是一種有效的方法來控制模型複雜度。
  • 對於高維數據集或特徵數量較多的情況下,正則化尤其有效。

正則化優點:

  • 靈活性強:正則化可以在不過度簡化模型的情況下有效控制模型的複雜度。
  • 自動特徵選擇:L1 正則化(Lasso)可以自動將不重要的特徵的權重縮小為零,起到特徵選擇的作用。

正則化缺點:

  • 需要調參:正則化強度的選擇(如 L1 或 L2 的懲罰參數)需要仔細調整,否則可能導致模型表現不佳。
  • 不適用於所有模型:某些模型(如決策樹)不直接適用於正則化,因此需要改用其他方法(如剪枝)。


如何避免 Overfitting (過擬合) 的發生

1. 使用正則化(Regularization)

  • L1正則化(Lasso):會將一些不重要的特徵權重壓縮為零,實現特徵選擇。
  • L2正則化(Ridge):通過抑制權重過大來控制模型的複雜性。
  • Elastic Net:結合了L1和L2正則化的優點,能在特徵選擇和模型穩定性之間取得平衡。

L1正則化(Lasso)

from sklearn.linear_model import Lasso
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error

# 載入數據集
X, y = load_boston(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# Lasso (L1正則化)
lasso = Lasso(alpha=0.1)
lasso.fit(X_train, y_train)
y_pred = lasso.predict(X_test)

# 評估
mse = mean_squared_error(y_test, y_pred)
print(f"Lasso MSE: {mse}")

L2正則化(Ridge)

from sklearn.linear_model import Ridge

# Ridge (L2正則化)
ridge = Ridge(alpha=0.1)
ridge.fit(X_train, y_train)
y_pred = ridge.predict(X_test)

# 評估
mse = mean_squared_error(y_test, y_pred)
print(f"Ridge MSE: {mse}")

Elastic Net

from sklearn.linear_model import ElasticNet

# Elastic Net
elastic_net = ElasticNet(alpha=0.1, l1_ratio=0.5)
elastic_net.fit(X_train, y_train)
y_pred = elastic_net.predict(X_test)

# 評估
mse = mean_squared_error(y_test, y_pred)
print(f"Elastic Net MSE: {mse}")


2. 使用交叉驗證(Cross-Validation)

  • 將數據集分成多個子集,並使用不同的子集作為訓練集和驗證集進行多次訓練。交叉驗證能有效評估模型在未見過的數據上的性能,從而避免過度擬合。
from sklearn.model_selection import cross_val_score

# 使用Ridge模型進行交叉驗證
ridge = Ridge(alpha=0.1)
scores = cross_val_score(ridge, X, y, cv=5, scoring='neg_mean_squared_error')

# 計算平均MSE
average_mse = -scores.mean()
print(f"Cross-Validated MSE: {average_mse}")


3. 增加數據量

  • 當有更多的訓練數據時,模型可以學習到更廣泛的模式,而不僅僅是針對少量數據進行擬合。數據擴充(Data Augmentation)也是一種常見的增加數據量的方法,尤其在圖像和文本領域。


4. 簡化模型

  • 減少模型的複雜性,如減少神經網絡中的層數或節點數,使用較少的特徵,或選擇較簡單的模型。這樣可以防止模型學習到數據中的噪聲。
from keras.models import Sequential
from keras.layers import Dense

# 簡化模型
model = Sequential([
Dense(64, input_dim=X_train.shape[1], activation='relu'),
Dense(32, activation='relu'),
Dense(1, activation='linear')
])

model.compile(optimizer='adam', loss='mean_squared_error')
model.fit(X_train, y_train, epochs=50, batch_size=32, validation_data=(X_test, y_test))


5. 提前停止(Early Stopping)

  • 在訓練過程中監控模型在驗證集上的性能,當性能不再提升時,停止訓練。這可以防止模型在訓練數據上過度擬合。
from keras.callbacks import EarlyStopping

# 設置提前停止
early_stopping = EarlyStopping(monitor='val_loss', patience=5, restore_best_weights=True)

# 訓練模型時使用提前停止
model.fit(X_train, y_train, epochs=100, batch_size=32, validation_data=(X_test, y_test), callbacks=[early_stopping])


6. 使用Dropout(僅限於神經網絡)

  • Dropout是一種在訓練過程中隨機丟棄神經網絡中的某些節點的方法。這種技術可以減少神經元之間的相互依
from keras.layers import Dropout

# 模型中加入Dropout層
model = Sequential([
Dense(64, input_dim=X_train.shape[1], activation='relu'),
Dropout(0.5),
Dense(32, activation='relu'),
Dropout(0.5),
Dense(1, activation='linear')
])

model.compile(optimizer='adam', loss='mean_squared_error')
model.fit(X_train, y_train, epochs=50, batch_size=32, validation_data=(X_test, y_test))


7. 資料預處理與特徵選擇

  • 通過資料清理和選擇合適的特徵,剔除不相關或噪聲特徵,減少模型學習不必要模式的機會。
from sklearn.feature_selection import SelectKBest, f_regression

# 選擇K個最好的特徵
selector = SelectKBest(f_regression, k=10)
X_new = selector.fit_transform(X, y)


8. 使用集成方法(Ensemble Methods)

  • 集成方法如隨機森林(Random Forest)和梯度提升機(Gradient Boosting Machine, GBM)通過結合多個弱模型來提升性能,並且降低單一模型過度擬合的風險。
from sklearn.ensemble import RandomForestRegressor

# 使用隨機森林模型
rf = RandomForestRegressor(n_estimators=100, max_depth=5)
rf.fit(X_train, y_train)
y_pred = rf.predict(X_test)

# 評估
mse = mean_squared_error(y_test, y_pred)
print(f"Random Forest MSE: {mse}")


9. 正則化回歸模型的複雜性

  • 對於回歸模型,增加懲罰項來限制模型的複雜性,使其不能過度擬合訓練數據中的特異點。

假設你使用的是多項式回歸模型,進行正則化:

from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import Ridge

# 多項式回歸與正則化
poly = PolynomialFeatures(degree=2)
X_poly = poly.fit_transform(X_train)

ridge = Ridge(alpha=0.1)
ridge.fit(X_poly, y_train)


10. 調整學習率

  • 在優化過程中,學習率過高或過低都可能導致過度擬合。調整學習率或使用學習率衰減策略可以幫助模型更好地找到全局最優解。
from keras.optimizers import Adam

# 使用學習率衰減策略
optimizer = Adam(learning_rate=0.01, decay=1e-6)

model.compile(optimizer=optimizer, loss='mean_squared_error')
model.fit(X_train, y_train, epochs=50, batch_size=32, validation_data=(X_test, y_test))


如何處理 Overfitting (過擬合)

1. 增加正則化力度

  • 增加L1或L2正則化:調整正則化參數(如alpha)的值,增強對模型複雜性的約束,減少過大的權重值,從而使模型更加平滑。
from sklearn.linear_model import Lasso
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error

# 載入數據集
X, y = load_boston(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# Lasso (L1正則化)
lasso = Lasso(alpha=0.1)
lasso.fit(X_train, y_train)
y_pred = lasso.predict(X_test)

# 評估
mse = mean_squared_error(y_test, y_pred)
print(f"Lasso MSE: {mse}")
  • Elastic Net:如果你已經使用了L1或L2,可以考慮轉換為Elastic Net,這樣能同時獲得特徵選擇和穩定性的優點。
from sklearn.linear_model import ElasticNet

# Elastic Net
elastic_net = ElasticNet(alpha=0.1, l1_ratio=0.5)
elastic_net.fit(X_train, y_train)
y_pred = elastic_net.predict(X_test)

# 評估
mse = mean_squared_error(y_test, y_pred)
print(f"Elastic Net MSE: {mse}")


2. 簡化模型

  • 減少模型的複雜度:可以考慮減少神經網絡中的層數或節點數,或者在決策樹模型中減少樹的深度。如果使用的是多項式回歸,則可以考慮降低多項式的階數。
  • 減少特徵數量:通過特徵選擇方法(如基於L1正則化的特徵選擇)刪除不必要或不重要的特徵,減少模型學習到的噪聲。
from keras.models import Sequential
from keras.layers import Dense

# 簡化模型
model = Sequential([
Dense(64, input_dim=X_train.shape[1], activation='relu'),
Dense(32, activation='relu'),
Dense(1, activation='linear')
])

model.compile(optimizer='adam', loss='mean_squared_error')
model.fit(X_train, y_train, epochs=50, batch_size=32, validation_data=(X_test, y_test))


3. 使用更多的訓練數據

  • 擴展數據集:增加訓練數據的數量可以讓模型學習到更多的模式,而不僅僅是擬合少量數據中的噪聲。可以通過收集更多數據或使用數據增強(Data Augmentation)技術來實現。
  • 數據清洗:確保數據質量,移除或修正異常值和噪聲數據,以提升模型在新數據上的表現。


4. 使用提前停止(Early Stopping)

  • 訓練過程中監控性能:在訓練模型時,使用驗證集監控模型的性能,並在驗證集上的損失不再下降時停止訓練。這可以防止模型在訓練數據上過度擬合。
from keras.callbacks import EarlyStopping

# 設置提前停止
early_stopping = EarlyStopping(monitor='val_loss', patience=5, restore_best_weights=True)

# 訓練模型時使用提前停止
model.fit(X_train, y_train, epochs=100, batch_size=32, validation_data=(X_test, y_test), callbacks=[early_stopping])


5. 採用Dropout(適用於神經網絡)

  • 引入Dropout層:在神經網絡中引入Dropout層,每次訓練時隨機丟棄一部分神經元,這能夠減少神經元之間的相互依賴,從而提升模型的泛化能力。
from keras.layers import Dropout

# 模型中加入Dropout層
model = Sequential([
Dense(64, input_dim=X_train.shape[1], activation='relu'),
Dropout(0.5),
Dense(32, activation='relu'),
Dropout(0.5),
Dense(1, activation='linear')
])

model.compile(optimizer='adam', loss='mean_squared_error')
model.fit(X_train, y_train, epochs=50, batch_size=32, validation_data=(X_test, y_test))


6. 採用集成方法(Ensemble Methods)

  • 使用集成模型:例如隨機森林(Random Forest)、梯度提升機(Gradient Boosting Machine, GBM)或集成多個模型的預測結果,這樣可以減少單一模型過度擬合的風險。
from sklearn.ensemble import RandomForestRegressor

# 使用隨機森林模型
rf = RandomForestRegressor(n_estimators=100, max_depth=5)
rf.fit(X_train, y_train)
y_pred = rf.predict(X_test)

# 評估
mse = mean_squared_error(y_test, y_pred)
print(f"Random Forest MSE: {mse}")


7. 調整模型的學習率

  • 減少學習率:如果使用的是梯度下降法,考慮減少學習率,使模型能夠更穩定地收斂到一個更好的解,而不是快速收斂到一個局部最優解,這可能導致過度擬合。
from keras.optimizers import Adam

# 使用學習率衰減策略
optimizer = Adam(learning_rate=0.01, decay=1e-6)

model.compile(optimizer=optimizer, loss='mean_squared_error')
model.fit(X_train, y_train, epochs=50, batch_size=32, validation_data=(X_test, y_test))


8. 重新劃分訓練集和驗證集

  • 使用交叉驗證:重新劃分數據集,確保訓練集和驗證集的分佈合理,避免數據劃分不均衡導致模型過度擬合特定的數據模式。
from sklearn.model_selection import cross_val_score

# 使用Ridge模型進行交叉驗證
ridge = Ridge(alpha=0.1)
scores = cross_val_score(ridge, X, y, cv=5, scoring='neg_mean_squared_error')

# 計算平均MSE
average_mse = -scores.mean()
print(f"Cross-Validated MSE: {average_mse}")


9. 資料標準化或正規化

  • 重新標準化數據:檢查數據的標準化或正規化是否恰當,特別是在使用正則化時,數據的標準化至關重要。
from sklearn.preprocessing import StandardScaler

# 標準化數據
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)


10. 模型調參

  • 重新調整模型超參數:通過超參數調整,嘗試不同的參數組合,找到一個能夠有效控制過度擬合的最佳配置。
from sklearn.model_selection import GridSearchCV
from sklearn.linear_model import Ridge

# 定義參數網格
param_grid = {'alpha': [0.01, 0.1, 1, 10]}

# 使用GridSearch進行調參
ridge = Ridge()
grid_search = GridSearchCV(ridge, param_grid, cv=5, scoring='neg_mean_squared_error')
grid_search.fit(X_train, y_train)

# 獲取最佳參數
best_params = grid_search.best_params_
print(f"Best Params: {best_params}")


11. 探索更多特徵工程

  • 生成更多有用的特徵:考慮生成新的特徵或轉換已有的特徵,這可以幫助模型更好地理解數據中的模式,而不僅僅依賴於現有的特徵。




分享至
成為作者繼續創作的動力吧!
從 Google News 追蹤更多 vocus 的最新精選內容從 Google News 追蹤更多 vocus 的最新精選內容

JayRay 的沙龍 的其他內容

你可能也想看

發表回應

成為會員 後即可發表留言
© 2024 vocus All rights reserved.