大家好,欢迎来到IT知识分享网。
文章目录
前言
随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容之过拟合和欠拟合。
什麽是过拟合和欠拟合?
- 欠拟合是指模型在训练集、验证集和测试集上均表现不佳的情况;
- 过拟合是指模型在训练集上表现很好,到了验证和测试阶段就很差,即模型的泛化能力很差。
过拟合和欠拟合产生的原因:
欠拟合(underfitting):
- 模型复杂度过低
- 特征量过少
过拟合(overfitting):
- 建模样本选取有误,如样本数量太少,选样方法错误,样本标签错误等,导致选取的样本数据不足以代表预定的分类规则
- 样本噪音干扰过大,使得机器将部分噪音认为是特征从而扰乱了预设的分类规则
- 假设的模型无法合理存在,或者说是假设成立的条件实际并不成立
- 参数太多,模型复杂度过高
- 对于决策树模型,如果我们对于其生长没有合理的限制,其自由生长有可能使节点只包含单纯的事件数据(event)或非事件数据(no event),使其虽然可以完美匹配(拟合)训练数据,但是无法适应其他数据集
- 对于神经网络模型:a)对样本数据可能存在分类决策面不唯一,随着学习的进行,,BP算法使权值可能-收敛过于复杂的决策面;b)权值学习迭代次数足够多(Overtraining),拟合了训练数据中的噪声和训练样例中没有代表性的特征
解决欠拟合(高偏差)的方法
1、模型复杂化
2、增加更多的特征,使输入数据具有更强的表达能力
3、调整参数和超参数
4、增加训练数据往往没有用
欠拟合本来就是模型的学习能力不足,增加再多的数据给它训练它也没能力学习好。
5、降低正则化约束
正则化约束是为了防止模型过拟合,如果模型压根不存在过拟合而是欠拟合了,那么就考虑是否降低正则化参数λ或者直接去除正则化项
解决过拟合(高方差)的方法:
1、增加训练数据数
- 发生过拟合最常见的现象就是数据量太少而模型太复杂
- 过拟合是由于模型学习到了数据的一些噪声特征导致,增加训练数据的 量能够减少噪声的影响,让模型更多地学习数据的一般特征
- 增加数据量有时可能不是那么容易,需要花费一定的时间和精力去搜集处理数据
- 利用现有数据进行扩充或许也是一个好办法。例如在图像识别中,如果没有足够的图片训练,可以把已有的图片进行旋转,拉伸,镜像,对称等,这样就可以把数据量扩大好几倍而不需要额外补充数据
- 注意保证训练数据的分布和测试数据的分布要保持一致,二者要是分布完全不同,那模型预测真可谓是对牛弹琴了。
2、使用正则化约束
代价函数后面添加正则化项,可以避免训练出来的参数过大从而使模型过拟合。使用正则化缓解过拟合的手段广泛应用,不论是在线性回归还是在神经网络的梯度下降计算过程中,都应用到了正则化的方法。常用的正则化有l1正则和l2正则,具体使用哪个视具体情况而定,一般l2正则应用比较多。
3、减少特征数
欠拟合需要增加特征数,那么过拟合自然就要减少特征数。去除那些非共性特征,可以提高模型的泛化能力.
4、调整参数和超参数
不论什么情况,调参是必须的
5、降低模型的复杂度
欠拟合要增加模型的复杂度,那么过拟合正好反过来。
6、使用Dropout
7、提前结束训练
即early stopping,在模型迭代训练时候记录训练精度(或损失)和验证精度(或损失),如果模型训练的效果不再提高,比如训练误差一直在降低但是验证误差却不再降低甚至上升,这时候便可以结束模型训练了。
小例
我们知道酶的活性会随温度的变化而变化,在最适温度达到最高,高于或低于最适温度都会有所降低,那么我们若想预测某温度下酶的活性时,该怎么判断模型是否欠拟合或过拟合了呢?来看几幅图
可以看到大概在60度左右酶的活性最高,在这之前和之后都会有所降低,我们预想的模型大概是这样的。它的决策边界可能如图所示。
r = θ₀ + θ₁t + θ₂t²
如果说模型过于简单了,就可能就会得到一条直线。这种训练好后的模型既不能满足训练数据的预期,也不能满足新数据的预期,此时它就是属于欠拟合。(训练数据和新数据的预测结果都不准确)
r = θ₀ + θ₁t
實戰
酶活性預測實戰task:
- 基於T-R-train.csv數據,建立綫性回歸模型,計算其在T-R-test.csv數據上的r2分數,可視化模型預測結果
- 加入多項式特徵(2次、3次),建立回歸模型
- 計算多項式回歸模型對測試數據進行預測的r2分數,判斷哪個模型預測更準確
- 可視化多項式回歸模型數據預測結果,判斷哪個模型預測更准確
#load the data import pandas as pd import numpy as np data_train = pd.read_csv('T-R-train.csv') data_train
#define X_train and y_train X_train = data_train.loc[:,'T'] y_train = data_train.loc[:,'rate']
#visualize the data from matplotlib import pyplot as plt fig1 = plt.figure(figsize=(5,5)) plt.scatter(X_train,y_train) plt.title('raw data') plt.xlabel('temperature') plt.ylabel('rate') plt.show()
X_train = np.array(X_train).reshape(-1,1)
轉一下類型不然後面會報下面錯誤
ValueError: Expected 2D array, got 1D array instead: array=[46.53 48.14 50.15 51.36 52.57 54.18 56.19 58.58 61.37 63.34 65.31 66.47 68.03 69.97 71.13 71.89 73.05 74.21]. Reshape your data either using array.reshape(-1, 1) if your data has a single feature or array.reshape(1, -1) if it contains a single sample.
#linear regression model prediction from sklearn.linear_model import LinearRegression lr1 = LinearRegression() lr1.fit(X_train,y_train)
#load the test data data_test = pd.read_csv('T-R-test.csv') data_test
#define X_test and y_test X_test = data_test.loc[:,'T'] y_test = data_test.loc[:,'rate'] X_test = np.array(X_test).reshape(-1,1)
#make prediction on the training and testing data y_train_predict = lr1.predict(X_train) y_test_predict = lr1.predict(X_test) from sklearn.metrics import r2_score r2_train = r2_score(y_train,y_train_predict) r2_test = r2_score(y_test,y_test_predict) print('training r2:',r2_train) print('test r2:',r2_test)
可以看出r2_score值很低也就是説明模型很差
#generate new data X_range = np.linspace(40,90,300).reshape(-1,1) y_range_predict = lr1.predict(X_range)
fig2 = plt.figure(figsize=(5,5)) plt.plot(X_range,y_range_predict) plt.scatter(X_train,y_train) plt.title('prediction data') plt.xlabel('temperature') plt.ylabel('rate') plt.show()
可視化看一下,可以明顯看出不是一個好的訓練模型,這是個明顯的欠擬合的bad fit
加入多項式特徵(2次、3次),建立回歸模型
#多項式模式 #generate new features from sklearn.preprocessing import PolynomialFeatures poly2 = PolynomialFeatures(degree=2) # 二階 X_2_train = poly2.fit_transform(X_train) X_2_test = poly2.transform(X_test) poly5 = PolynomialFeatures(degree=5) # 五階 X_5_train = poly5.fit_transform(X_train) X_5_test = poly5.transform(X_test) print(X_5_train.shape)
lr2 = LinearRegression() lr2.fit(X_2_train,y_train) y_2_train_predict = lr2.predict(X_2_train) y_2_test_predict = lr2.predict(X_2_test) r2_2_train = r2_score(y_train,y_2_train_predict) r2_2_test = r2_score(y_test,y_2_test_predict) lr5 = LinearRegression() lr5.fit(X_5_train,y_train) y_5_train_predict = lr5.predict(X_5_train) y_5_test_predict = lr5.predict(X_5_test) r2_5_train = r2_score(y_train,y_5_train_predict) r2_5_test = r2_score(y_test,y_5_test_predict) print('training r2_2:',r2_2_train) print('test r2_2:',r2_2_test) print('training r2_5:',r2_5_train) print('test r2_5:',r2_5_test)
看一下r2_score越接近1越好,可以看出多項式的比綫性回歸的效果好的多。同時也可以看出五階對於訓練數據r2分數高(預測準確),但對於預測數據r2分數低(預測不準確)
X_2_range = np.linspace(40,90,300).reshape(-1,1) X_2_range = poly2.transform(X_2_range) y_2_range_predict = lr2.predict(X_2_range) X_5_range = np.linspace(40,90,300).reshape(-1,1) X_5_range = poly5.transform(X_5_range) y_5_range_predict = lr5.predict(X_5_range)
fig3 = plt.figure(figsize=(5,5)) plt.plot(X_range,y_2_range_predict) plt.scatter(X_train,y_train) plt.scatter(X_test,y_test) plt.title('polynomial prediction result (2)') plt.xlabel('temperature') plt.ylabel('rate') plt.show()
可視化二階,看出擬合和預測效果都還不錯,是個good fit
fig4 = plt.figure(figsize=(5,5)) plt.plot(X_range,y_5_range_predict) plt.scatter(X_train,y_train) plt.scatter(X_test,y_test) plt.title('polynomial prediction result (5)') plt.xlabel('temperature') plt.ylabel('rate') plt.show()
可視化五階,看出擬合很完美但是預測效果不佳,是個過擬合bad fit
總結
酶活性預測實戰summary:
- 通過建立二階多項式回歸模型,對酶活性實現一個較好的預測,無論針對訓練或測試數據都得到一個高的r2分數
- 通過建立綫性回歸、五階多項式回歸模型,發現存在欠擬合或過擬合情況。過擬合情況下,對於訓練數據r2分數高(預測準確),但對於預測數據r2分數低(預測不準確)
- 無論是通過r2分數,或是可視化模型結果,都可以發現二階多項式回歸模型效果最好
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/135800.html