在样本数量不是很多的情况下,想要检验拟合一个完美的模型。最常见的方法就是K折交叉检验。
写一个住房数据案例
# 先把数据分成k个部分,把其中一个部分用作测试集,把其余部分用作训练集以拟合模型 # 模型拟合好之后,使用测试集进行 测试,并计算误差。不断重复这个过程,知道k个部分都测试过。 # 模型的最终误差是所有模型的平均值 import pandas as pd housing=pd.read_csv('housing_renamed.csv') from sklearn.model_selection import train_test _split from sklearn.linear_model import LinearRegression print(housing.columns)以上工作就是 读取文件,调用我们需要的模块。 第一个模块是分训练样本和测试样本的模块,从sklearn.model_selection中调用,即train_test_split。
其次是 拟合回归线的 sklearn.linear_model 中调用LinearRegression。
由于sklearn高度依赖Numpy ndarray,所以patsy库允许指定一个公式,比如statsmodels中的公式API,并且会返回合适的Numpy数组,以便在sklearn中使用。 这里我们再从patsy中调用一个dmatrices。
from patsy import dmatrices # 获取训练数据和测试数据 y,X=dmatrices('value_per_sq_ft~units+sq_ft+boro',housing,return_type='dataframe') # 给y和x指定变量,最后参数指定返回一个DataFrame数据集 X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.20,random_state=42) # 数据分成四份分X测试、X训练,y测试,y训练。 lr=LinearRegression().fit(X_train,y_train) # 对x训练样本和y训练样本fit一个回归线 print(lr.score(X_test,y_test)) # 并且用.score()函数 以及x和y的测试样本 ,算出一个分数,衡量模型在测试数据上的表现准备工作做好后,就可以开始执行k折交叉验证了,先从sklearn库导入该函数
from sklearn.model_selection import KFold,cross_val_score # 重新获取住房数据 housing=pd.read_csv('housing_renamed.csv') # 再指定要折几下 # 一般折的越多,计算起来越慢,这里就按照5来处理吧 kf=KFold(n_splits=5) # 直接给n_splits赋值就行然后在每一折上训练并测试模型
coefs=[] scores=[] for train,test in kf.split(X): # 遍历样本 X_train,X_test=X[train],X[test] y_train,y_test=y[train],y[test] # 存放列表赋值 lr=LinearRegression().fit(X_train,y_train) # 拟合模型 coefs.append(pd.DataFrame(lr.coef_)) scores.append(lr.score(X_test,y_test))查看代码
coefs_df=pd.concat(coefs) coefs_df.columns=X.design_info.column_names print(coefs_df)可以使用apply和 np.mean 来查看所有折的平均系数
import numpy as np print(coefs_df.apply(np.mean())还可以查看分数
print(scores) # 还可以使用cross_val_scores(交叉验证分数)计算分数 # 使用cross_val_scores计算cv分数 model=LinearRegression() scores=cross_val_score(model,X,y,cv=5) print(scores) # 如果要比较多个模型,可以比较平均分数 print(scores.mean())比较多个模型: 除了变量之间是+的形式,还有* 的形式,试试别的模型,再得出各个模型的分数,看看哪个更好
# 用k折交叉验证重新拟合模型 # 创建预测变量矩阵和响应矩阵 y1,X1=dmatrices('value_per_sq_ft~units+sq_ft+boro',housing) y2,X2=dmatrices('value_per_sq_ft~units*sq_ft+boro',housing) y3,X3=dmatrices('value_per_sq_ft~units+sq_ft*boro+type',housing) y4,X4=dmatrices('value_per_sq_ft~units+sq_ft*boro+sq_ft*type',housing) y5,X5=dmatrices('value_per_sq_ft~boro+type',housing) # 拟合模型 model=LinearRegression() scores1=cross_val_score(model,X1,y1,cv=5) scores2=cross_val_score(model,X2,y2,cv=5) scores3=cross_val_score(model,X3,y3,cv=5) scores4=cross_val_score(model,X4,y4,cv=5) scores5=cross_val_score(model,X5,y5,cv=5) # 最后查看交叉验证分数 scores_df=pd.DataFrame([scores1,scores2,scores3,scores4,scores5]) print(scores_df.apply(np.mean,axis=1))