我刚开始学习机器学习领域,按照教程制作了一个模型,但结果准确率很快就跳到了100%。我在网上搜索后发现,这可能是由于模型过拟合造成的。我使用的数据集是从UCI网站上下载的印度肝病患者数据集,这个数据集的观测值只有大约600个。
我的问题是如何克服数据中的过拟合问题。任何帮助都将不胜感激,谢谢。
import pandas as pdfrom keras.models import Sequentialfrom keras.layers import Densefrom sklearn.model_selection import train_test_splitfrom sklearn.metrics import classification_reportimport scikitplot as skpltimport matplotlib.pyplot as pltimport numpy as npimport seaborn as snsdf = pd.read_csv("C:/TF/TEST/ILDP.csv")df["ag_ratio"].fillna("0.6", inplace=True)df.isnull().sum()print(df.head())LD, NLD = df['is_patient'].value_counts()df_sex = pd.get_dummies(df['gender'])df_new = pd.concat([df, df_sex], axis=1)Droop_gender = df_new.drop(labels=['gender'], axis=1)Droop_gender.columns = ['age', 'tot_bilirubin', 'direct_bilirubin', 'tot_proteins', 'albumin', 'ag_ratio', 'sgpt', 'sgot', 'alkphos', 'Female', 'Male', 'is_patient']X = Droop_gender.drop('is_patient', axis=1)y = Droop_gender['is_patient']print(X.shape)X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)from sklearn.preprocessing import StandardScalersc = StandardScaler()X_train = sc.fit_transform(X_train)X_test = sc.transform(X_test)classifier = Sequential() # Initialising the ANNclassifier.add(Dense(units=16, kernel_initializer='uniform', activation='relu', input_dim=11))classifier.add(Dense(units=8, kernel_initializer='uniform', activation='relu'))classifier.add(Dense(units=6, kernel_initializer='uniform', activation='relu'))classifier.add(Dense(units=1, kernel_initializer='uniform', activation='sigmoid'))# compile ANNclassifier.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['accuracy'])# Fitting the datahistroy = classifier.fit(X_train, y_train, batch_size=20, epochs=50)y_pred = classifier.predict(X_test)y_pred = [1 if y >= 0.5 else 0 for y in y_pred]print(classification_report(y_test, y_pred))
回答:
你的模型出现过拟合是一个好现象,因为这意味着你的模型有学习的能力。现在你需要逐步降低模型的容量,使其更好的泛化。我建议你添加正则化。
在一些全连接层之间添加丢弃层(dropout layers):
classifier.add(Dense(units=16, kernel_initializer='uniform', activation='relu', input_dim=11))classifier.add(keras.layers.Dropout(0.5))classifier.add(Dense(units=8, kernel_initializer='uniform', activation='relu'))
你可以在这丢弃层之间添加任意层,但最好是在神经元较多的层之间添加。
如果这不起作用,你可以尝试权重衰减。以下是文档中的一个例子:
from keras import regularizersmodel.add(Dense(64, input_dim=64, kernel_regularizer=regularizers.l2(0.01), activity_regularizer=regularizers.l1(0.01)))
虽然你可以先尝试使用kernel_regularizer或activity_regularizer,它们的效果应该差不多。尝试调整参数,看看不同的参数如何改变。最终,这是一些黑魔法,你需要多做一些实验。祝你好运!