<jupyter_start><jupyter_text>说明：1、这里通过数据模拟直观展示模型复杂度和训练误差的关系。随模型复杂度的提高，训练误差单调下降。2、首先设定输入变量和输出变量的真实关系，并通过加上服从正态分布的随机数模拟其他随机因素对输出变量的影响。这里，设定的真实关系函数可以被泰勒展开，因此一定是次数越高的多项式模型越贴近真实观测值。 到达一定阶数（这里为9）后继续增加阶数对参数估计结果的影响很小可以忽略，无需再增加阶数。3、分别建立各个多项式模型。这里消除了模型复杂度本身导致对MSE计算结果的影响，MSE计算时分母为自由度：样本量-(输入变量个数+1)。4、考察训练集样本量对对于特定模型（这里为五项式）学习充分性的影响。样本量依次为原数据集的20%至99%。这里消除了样本量本身对MSE计算结果的影响，MSE计算时分母为自由度：样本量-(输入变量个数+1)。对不同样本量下的MSE进行三次曲线拟合。<jupyter_code>fig,axes=plt.subplots(nrows=1,ncols=2,figsize=(10,4))  
modelLR=LM.LinearRegression()

np.random.seed(123)
Ntraining=int(N*0.7)
Ntest=int(N*0.3)
id=np.random.choice(N,Ntraining,replace=False)
X_train=x[id].reshape(Ntraining,1)
y_train=np.array(z)[id].reshape(Ntraining,1)
modelLR.fit(X_train,y_train)
MSEtrain=[np.sum((y_train-modelLR.predict(X_train))**2)/(Ntraining-2)]

xtest= np.delete(x, id).reshape(Ntest,1)
X_test= np.delete(x, id).reshape(Ntest,1)
y_test=np.delete(z,id).reshape(Ntest,1)
MSEtest=[np.sum((y_test-modelLR.predict(X_test))**2)/(Ntest-2)]

for i in np.arange(1,9):
    tmp=pow(x[id],(i+1)).reshape(Ntraining,1)
    X_train=np.hstack((X_train,tmp))
    modelLR.fit(X_train,y_train)
    MSEtrain.append(np.sum((y_train-modelLR.predict(X_train))**2)/(Ntraining-(i+2)))
    tmp=pow(xtest,(i+1)).reshape(Ntest,1)    
    X_test=np.hstack((X_test,tmp))
    MSEtest.append(np.sum((y_test-modelLR.predict(X_test))**2)/(Ntest-(i+2)))

axes[0].plot(np.arange(1,10,1),MSEtrain,marker='o',label='训练误差')
axes[0].plot(np.arange(1,10,1),MSEtest,marker='*',label='测试误差')
axes[0].legend()
axes[0].set_title("不同复杂度模型的训练误差和测试误差")
axes[0].set_xlabel("模型复杂度")
axes[0].set_ylabel("MSE")

MSEtrain=[]
MSEtest=[]
for j in range(20):
    x=np.linspace(0.1,10, num=N)
    id=np.random.choice(N,Ntraining,replace=False)
    X_train=x[id].reshape(Ntraining,1)
    y_train=np.array(z)[id].reshape(Ntraining,1)
    modelLR.fit(X_train,y_train)
    mse_train=[np.sum((y_train-modelLR.predict(X_train))**2)/(Ntraining-2)]

    xtest= np.delete(x, id).reshape(Ntest,1)
    X_test= np.delete(x, id).reshape(Ntest,1)
    y_test=np.delete(z,id).reshape(Ntest,1)
    mse_test=[np.sum((y_test-modelLR.predict(X_test))**2)/(Ntest-2)]

    for i in np.arange(1,9):
        tmp=pow(x[id],(i+1)).reshape(Ntraining,1)
        X_train=np.hstack((X_train,tmp))
        modelLR.fit(X_train,y_train)
        mse_train.append(np.sum((y_train-modelLR.predict(X_train))**2)/(Ntraining-(i+2)))
        tmp=pow(xtest,(i+1)).reshape(Ntest,1)    
        X_test=np.hstack((X_test,tmp))
        mse_test.append(np.sum((y_test-modelLR.predict(X_test))**2)/(Ntest-(i+2)))
    plt.plot(np.arange(1,10),mse_train,marker='o',linewidth=0.8,c='lightcoral',linestyle='-')
    plt.plot(np.arange(1,10),mse_test,marker='*',linewidth=0.8,c='lightsteelblue',linestyle='-.')
    MSEtrain.append(mse_train)
    MSEtest.append(mse_test)
    
MSETrain=pd.DataFrame(MSEtrain)
MSETest=pd.DataFrame(MSEtest)
axes[1].plot(np.arange(1,10),MSETrain.mean(),marker='o',linewidth=1.5,c='red',linestyle='-',label="训练误差的期望")
axes[1].plot(np.arange(1,10),MSETest.mean(),marker='*',linewidth=1.5,c='blue',linestyle='-',label="测试误差的期望")
axes[1].set_title("不同复杂度模型的训练误差和测试误差及其期望")
axes[1].set_xlabel("模型复杂度")
axes[1].set_ylabel("MSE")
axes[1].legend()
plt.show()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.2102674454349831, 'fraction_numerical': 0.032892714417460805, 'mean_word_length': 7.7238605898123325, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '603456', 'license': 'MIT', 'n_tokens_mistral': 1776, 'n_tokens_neox': 1842, 'n_words': 81, 'path': 'chapter2-3.ipynb', 'repo_name': 'cutelittletiantian/python-ML-principles-and-practice', 'size': '3253'}