4.2超参数与模型验证
机器学习模型基本步骤:
- 选择模型类;
- 选择模型超参数;
- 用模型拟合训练数据;
- 用模型预测新数据的标签;
当拿到实际数据时,要选择何种模型更好的拟合数据?确保模型适合数据,需要进行模型验证。
机器学习中,使用留出集和交叉检验进行模型验证。
- 留出集
主要使用train_test_split,将数据分为训练集和测试集(留出集);
实例:
#需要使用留出集评估模型
from sklearn.model_selection import train_test_split
#留出一部分数据作为评估数据
#train_size:50%数据
Xtrain,Xtest,ytrain,ytest = train_test_split(X_iris,y_iris,random_state=0,train_size=0.5)
- 交叉验证
留出集方式会出现只有部分数据被训练。使用交叉验证,做一组拟合,让每个子集既是训练集也是验证集。
可以使用cross_val_score进行多轮数据验证
实例:
def skLearn6():
'''
错误的模型验证
:return:
'''
from sklearn.datasets import load_iris
data_iris = load_iris()
#获取特征矩阵
X_iris = data_iris.data
y_iris = data_iris.target
#使用K近邻分类
from sklearn.neighbors import KNeighborsClassifier
model = KNeighborsClassifier(n_neighbors=1)
#拟合数据
model.fit(X_iris,y_iris)
y_model = model.predict(X_iris)
from sklearn.metrics import accuracy_score
#这里准确率达到100%
accuracy_score(y_iris,y_model)
#这里使用同一套数据训练和评估模型。
#需要使用留出集评估模型
from sklearn.model_selection import train_test_split
#留出一部分数据作为评估数据
#train_size:50%数据
Xtrain,Xtest,ytrain,ytest = train_test_split(X_iris,y_iris,random_state=0,train_size=0.5)
#交叉验证
y_model1 = model.fit(Xtrain,ytrain).predict(Xtest)
y_model2 = model.fit(Xtest,ytest).predict(Xtrain)
#计算准确率,取两轮验证的均值
print(accuracy_score(ytest,y_model1))
print(accuracy_score(ytrain,y_model2))
#如何进行多轮交叉验证?
from sklearn.model_selection import cross_val_score
#cv:指定交叉验证轮次,数据划分组数
scores1 = cross_val_score(model,X_iris,y_iris,cv=5)
print(scores1)
#进行极端拆分
#将所有数据进行训练,只留一个数据进行检验
from sklearn.model_selection import LeaveOneOut
scores2 = cross_val_score(model,X_iris,y_iris,cv=LeaveOneOut())
#所有验证平均值
print(scores2.mean())
- 如何选择最优模型?
改善模型效果方法:使用更复杂的模型,使用更简单的模型,采集更多样本,采集更多样本特征。
实际上是对方差与偏差的均衡。
过拟合:模型足够复杂,拟合所有数据,学习了一些数据的噪点;
欠拟合:模型太简单,丢失了大量有效数据;
验证曲线:不断调整模型参数,得到模型在训练集得分和验证集得分的曲线图。
验证曲线特征:
训练得分高于验证得分;
复杂度低的模型(高偏差),训练往往欠拟合;
复杂度高的模型(高方差),训练往往过拟合;
需要选取验证曲线最高点模型,这样得到合适的模型。
学习曲线:不断增加训练数据,得到不同规模数据集的训练得分和验证得分的曲线图。
实例:
def skLearn7():
'''
验证曲线
学习曲线
:return:
'''
from sklearn.datasets import load_iris
data_iris = load_iris()
#获取特征矩阵
X_iris = data_iris.data
y_iris = data_iris.target
#使用模型K-近邻
from sklearn.neighbors import KNeighborsClassifier
#验证曲线
from sklearn.model_selection import validation_curve
neibors = np.arange(0,5)
train_score,val_score = validation_curve(KNeighborsClassifier(),X_iris,y_iris,param_name='n_neighbors',param_range=neibors,cv=5)
# plt.plot(neibors,np.median(train_score,1),color='blue',label='train score')
# plt.plot(neibors,np.median(val_score,1),color='red',label='validation score')
#可以看到在2.8的地方有交叉
from sklearn.model_selection import train_test_split
#留出一部分数据作为评估数据
#train_size:80%数据
Xtrain,Xtest,ytrain,ytest = train_test_split(X_iris,y_iris,random_state=0,train_size=0.8)
model = KNeighborsClassifier(n_neighbors=3)
y_model = model.fit(Xtrain,ytrain).predict(Xtest)
#计算准确率
from sklearn.metrics import accuracy_score
print(accuracy_score(ytest,y_model))
#学习曲线
#不同训练集的大小
from sklearn.model_selection import learning_curve
sizes = np.linspace(0.5,0.8,4)
#不同数据集大小
print(sizes)
N,train_score,val_score = learning_curve(KNeighborsClassifier(n_neighbors=3),X_iris,y_iris,cv=4,train_sizes=sizes)
print(N)
print(train_score)
print(val_score)
plt.plot(N,np.mean(train_score,axis=1),color='blue',label='train score')
plt.plot(N,np.mean(val_score,axis=1),color='red',label='validation score')
#显示图片
plt.show()