【问题标题】:Cant make Prediction on OLS Model无法对 OLS 模型进行预测
【发布时间】:2020-12-08 11:48:46
【问题描述】:

我正在构建一个 OLS 模型,但无法做出任何预测。

你能解释一下我做错了什么吗?

构建模型:

import numpy as np
import pandas as pd
from scipy import stats
import statsmodels.api as sm 
import matplotlib.pyplot as plt

d = {'City': ['Tokyo','Tokyo','Lisbon','Tokyo','Madrid','New York','Madrid','London','Tokyo','London','Tokyo'], 
     'Card': ['Visa','Visa','Visa','Master Card','Bitcoin','Master Card','Bitcoin','Visa','Master Card','Visa','Bitcoin'],
     'Colateral':['Yes','Yes','No','No','Yes','No','No','Yes','Yes','No','Yes'],
     'Client Number':[1,2,3,4,5,6,7,8,9,10,11],
     'Total':[100,100,200,300,10,20,40,50,60,100,500]}

d = pd.DataFrame(data=d).set_index('Client Number')

df = pd.get_dummies(d,prefix='', prefix_sep='')

X = df[['Lisbon','London','Madrid','New York','Tokyo','Bitcoin','Master Card','Visa','No','Yes']]
Y = df['Total']

X1 = sm.add_constant(X)
reg = sm.OLS(Y, X1).fit()

reg.summary()

预测:

d1 = {'City': ['Tokyo','Tokyo','Lisbon'], 
     'Card': ['Visa','Visa','Visa'],
     'Colateral':['Yes','Yes','No'],
     'Client Number':[11,12,13],
     'Total':[0,0,0]}

df1 = pd.DataFrame(data=d1).set_index('Client Number')

df1 = pd.get_dummies(df1,prefix='', prefix_sep='')
y_new = df1[['Lisbon','Tokyo','Visa','No','Yes']]
x_new = df1['Total']
mod = sm.OLS(y_new, x_new)

mod.predict(reg.params)

然后它显示:ValueError:形状(3,1)和(11,)未对齐:1(dim 1)!= 11(dim 0)

我做错了什么?

【问题讨论】:

    标签: python pandas dataframe linear-regression statsmodels


    【解决方案1】:

    这是我的 cmets 代码的固定预测部分:

    d1 = {'City': ['Tokyo','Tokyo','Lisbon'], 
         'Card': ['Visa','Visa','Visa'],
         'Colateral':['Yes','Yes','No'],
         'Client Number':[11,12,13],
         'Total':[0,0,0]}
    
    df1 = pd.DataFrame(data=d1).set_index('Client Number')
    df1 = pd.get_dummies(df1,prefix='', prefix_sep='')
    x_new = df1.drop(columns='Total')
    

    主要问题是训练X1x_new 数据集的假人数量不同。 下面我添加缺少的虚拟列并用零填充:

    x_new = x_new.reindex(columns = X1.columns, fill_value=0)
    

    现在x_new 的列数等于训练数据集X1

                   const  Lisbon  London  Madrid  ...  Master Card  Visa  No  Yes
    Client Number                                 ...                            
    11                 0       0       0       0  ...            0     1   0    1
    12                 0       0       0       0  ...            0     1   0    1
    13                 0       1       0       0  ...            0     1   1    0
    
    [3 rows x 11 columns]
    

    最终使用先前训练的模型reg在新数据集x_new上进行预测:

    reg.predict(x_new)
    

    结果:

    Client Number
    11     35.956284
    12     35.956284
    13    135.956284
    dtype: float64
    

    附录

    根据要求,我在下面附上了完全可重现的代码,以测试训练和预测任务:

    import numpy as np
    import pandas as pd
    from scipy import stats
    import statsmodels.api as sm 
    import matplotlib.pyplot as plt
    
    d = {'City': ['Tokyo','Tokyo','Lisbon','Tokyo','Madrid','New York','Madrid','London','Tokyo','London','Tokyo'], 
         'Card': ['Visa','Visa','Visa','Master Card','Bitcoin','Master Card','Bitcoin','Visa','Master Card','Visa','Bitcoin'],
         'Colateral':['Yes','Yes','No','No','Yes','No','No','Yes','Yes','No','Yes'],
         'Client Number':[1,2,3,4,5,6,7,8,9,10,11],
         'Total':[100,100,200,300,10,20,40,50,60,100,500]}
    
    d = pd.DataFrame(data=d).set_index('Client Number')
    
    df = pd.get_dummies(d,prefix='', prefix_sep='')
    
    X = df[['Lisbon','London','Madrid','New York','Tokyo','Bitcoin','Master Card','Visa','No','Yes']]
    Y = df['Total']
    
    X1 = sm.add_constant(X)
    reg = sm.OLS(Y, X1).fit()
    
    reg.summary()
    
    ###
    d1 = {'City': ['Tokyo','Tokyo','Lisbon'], 
         'Card': ['Visa','Visa','Visa'],
         'Colateral':['Yes','Yes','No'],
         'Client Number':[11,12,13],
         'Total':[0,0,0]}
    
    df1 = pd.DataFrame(data=d1).set_index('Client Number')
    df1 = pd.get_dummies(df1,prefix='', prefix_sep='')
    x_new = df1.drop(columns='Total')
    
    x_new = x_new.reindex(columns = X1.columns, fill_value=0)
    
    reg.predict(x_new)
    

    【讨论】:

    • 感谢您的帮助。当我使用真实数据时,它显示“无法从重复轴重新索引”......知道它可能有什么问题吗??
    • 然后我使用部分数据集来测试训练
    • 您使用的是与问题相同的数据集df 还是其他外部数据?如果相同的数据,我也可以提供具有预测部分的可重复工作示例。
    • 相同的数据集。基本上占了df的一部分,我试着跑模型
    • 我在答案的附录中附上了完整的测试代码。如果有任何错误以及在哪一行,请告诉我。
    【解决方案2】:

    最大的问题是您没有使用相同的虚拟转换。也就是说,df1 中的某些值不存在。您可以使用以下代码(来自here)添加缺失值/列:

    d1 = {'City': ['Tokyo','Tokyo','Lisbon'], 
     'Card': ['Visa','Visa','Visa'],
     'Colateral':['Yes','Yes','No'],
     'Client Number':[11,12,13],
     'Total':[0,0,0]}
    
    df1 = pd.DataFrame(data=d1).set_index('Client Number')
    df1 = pd.get_dummies(df1,prefix='', prefix_sep='')
    print(df1.shape)  # Shape is 3x6 but it has to be 3x11
    # Get missing columns in the training test
    missing_cols = set( df.columns ) - set( df1.columns )
    # Add a missing column in test set with default value equal to 0
    for c in missing_cols:
        df1[c] = 0
    # Ensure the order of column in the test set is in the same order than in train set
    df1 = df1[df.columns]
    print(df1.shape)  # Shape is 3x11
    

    此外,您混淆了x_newy_new。所以应该是:

    x_new = df1.drop(['Total'], axis=1).values
    y_new = df1['Total'].values
    mod = sm.OLS(y_new, x_new)
    
    mod.predict(reg.params)
    

    请注意,我使用x_new = df1.drop(['Total'], axis=1).values 而不是df1[['Lisbon','Tokyo','Visa','No','Yes']],因为它更方便(就1)不太容易出现(打字)错误和2)更少的代码

    【讨论】:

      【解决方案3】:

      首先,您需要对所有单词进行字符串索引,或者对值进行一次热编码。 ML 模型不接受单词,只接受数字。接下来,您希望 X 和 y 成为:

      X = d.iloc[:,:-1]
      y = d.iloc[:,-1]
      

      这样,X 的形状为 [11,3],y 的形状为 [11,],这是所需的正确形状。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-11-18
        • 1970-01-01
        • 1970-01-01
        • 2020-08-29
        • 2022-11-11
        • 1970-01-01
        • 2021-11-13
        • 1970-01-01
        相关资源
        最近更新 更多