无法在sklearn中拟合多项式回归曲线

时间:2017-06-13 14:20:54

标签: python scikit-learn linear-regression polynomials

我是sklearn的新手,我有一个相当简单的任务:给出一个15点的散点图,我需要

  1. 将其中的11个作为我的“训练样本”,
  2. 通过这11个点拟合度数为3的多项式曲线;
  3. 将得到的多项式曲线绘制在15个点上。
  4. 但是我在第二步陷入困境。

    这是数据图:

    %matplotlib notebook
    
    import numpy as np from sklearn.model_selection 
    import train_test_split from sklearn.linear_model 
    import LinearRegression from sklearn.preprocessing import PolynomialFeatures
    
    np.random.seed(0) 
    n = 15 
    x = np.linspace(0,10,n) + np.random.randn(n)/5 
    y = np.sin(x)+x/6 + np.random.randn(n)/10
    
    X_train, X_test, y_train, y_test = train_test_split(x, y, random_state=0)
    
    plt.figure() plt.scatter(X_train, y_train, label='training data') 
    plt.scatter(X_test, y_test, label='test data') 
    plt.legend(loc=4);
    

    然后我在X_train中取11个点并使用3级多边形特征对它们进行转换,如下所示:

    degrees = 3
    poly = PolynomialFeatures(degree=degree)
    
    X_train_poly = poly.fit_transform(X_train)
    

    然后我尝试通过变换点拟合一条线(注意:X_train_poly.size = 364)。

    linreg = LinearRegression().fit(X_train_poly, y_train)
    

    我收到以下错误:

    ValueError: Found input variables with inconsistent numbers of samples: [1, 11]
    

    我已经阅读了各种问题来解决类似且通常更复杂的问题(例如Multivariate (polynomial) best fit curve in python?),但我无法从中提取解决方案。

2 个答案:

答案 0 :(得分:2)

问题是X_train和y_train中的维度。它是一个单维数组,因此它将每个X记录视为一个单独的变量。

如下所示使用.reshape命令可以解决问题:

# reshape data to have 11 records rather than 11 columns
X_trainT     = X_train.reshape(11,1)
y_trainT     = y_train.reshape(11,1)

# create polynomial features on the single va
poly         = PolynomialFeatures(degree=3)
X_train_poly = poly.fit_transform(X_trainT)

print (X_train_poly.shape)
# 

linreg       = LinearRegression().fit(X_train_poly, y_trainT)

答案 1 :(得分:0)

该错误基本上意味着您的X_train_polyy_train不匹配,其中X_train_poly只有一组x而您的y_train有11个值。我不太确定你想要什么,但我想多项式特征并不是按你想要的方式生成的。您的代码目前正在做的是为单个11维点生成3次多项式特征。

我认为你想要为你的11个点的每个点(实际上每个x)生成3次多项式特征。您可以使用循环或列表推导来执行此操作:

X_train_poly = poly.fit_transform([[i] for i in X_train])
X_train_poly.shape
# (11, 4)

现在,您可以看到X_train_poly有11个点,其中每个点都是4维,而不是单个364维点。这个新X_train_poly符合y_train的形状,回归可能会为您提供所需内容:

linreg = LinearRegression().fit(X_train_poly, y_train)
linreg.coef_
# array([ 0.        , -0.79802899,  0.2120088 , -0.01285893])