2016-06-27 6 views
0

statsmodels을 파이썬에서 사용하여 팬더 DataFrame의 일부 값을 대체하려고합니다.statsmodels : 수식을 사용하여 샘플 밖 예측에 대해 result.predict()에 허용되는 형식은 무엇입니까?

아래의 세 번째 및 네 번째 시도 (df2 및 df3)는 오류를 나타냅니다. *** AttributeError: 'DataFrame' object has no attribute 'design_info' 데이터 프레임에 이러한 특성이 없으므로 이상한 오류가 발생합니다.

어쨌든 나는 df2에서 A의 누락 된 값에 대한 예측을 얻기 위해 predict()로 전달해야하는 것을 이해하지 못합니다. df3의 경우 마지막 요소에 np.nan이 포함 된 예측을 제공하면 좋을 수도 있습니다. 시험판을 사용

import pandas as pd 
import numpy as np 
import statsmodels.formula.api as sm 

df0 = pd.DataFrame({"A": [10,20,30,324,2353,], 
        "B": [20, 30, 10, 100, 2332], 
        "C": [0, -30, 120, 11, 2]}) 

result0 = sm.ols(formula="A ~ B + C ", data=df0).fit() 
print result0.summary() 
test0 = result0.predict(df0) #works 
print test0 

df1 = pd.DataFrame({"A": [10,20,30,324,2353,], 
        "B": [20, 30, 10, 100, 2332], 
        "C": [0, -30, 120, 11, 2]}) 
result1 = sm.ols(formula="A ~ B+ I(C**2) ", data=df1).fit() 
print result1.summary() 
test1 = result1.predict(df1) #works 
print test1 


df2 = pd.DataFrame({"A": [10,20,30,324,2353,np.nan], 
        "B": [20, 30, 10, 100, 2332, 2332], 
        "C": [0, -30, 120, 11, 2, 2 ]}) 
result2 = sm.ols(formula="A ~ B + C", data=df2).fit() 
print result2.summary() 

test2 = result2.predict(df2)  # Fails 
newvals=df2[['B','C']].dropna() 
test2 = result2.predict(newvals) # Fails 
test2 = result2.predict(dict([[vv,df2[vv].values] for vv in newvals.columns]))  # Fails 




df3 = pd.DataFrame({"A": [10,20,30,324,2353,2353], 
        "B": [20, 30, 10, 100, 2332, np.nan], 
        "C": [0, -30, 120, 11, 2, 2 ]}) 
result3 = sm.ols(formula="A ~ B + C", data=df3).fit() 
print result3.summary() 
test3 = result3.predict(df3)  # Fails 

업데이트, statsmodels 0.8의 DF2 예를 새 릴리스 후보를 사용

statsmodels, 위의 작동합니다. 그러나 제 (DF3) 예 ValueError: Wrong number of items passed 5, placement implies 6

가 예측 가능한되는 행 올바르게 상기 np.nan 포함 작동 마지막 행, 즉 result3.predict(df3[:-1])이 예측을 적가 result3.predict(df3) 실패.

전체 df3을 전달할 옵션이 있지만 마지막 행에 대한 예측으로 np.nan을 수신하는 것이 좋습니다.

+0

omd. Statsmodels 0.6.1의 버그 일뿐입니다. https://github.com/statsmodels/statsmodels/issues/2171 이전에 폐쇄되었지만 이후로 다른 릴리스가 없었습니다. – CPBL

+0

statsmodels 0.8.0rc1은 pypi – user333700

+0

에서 사용 가능합니다. 'pip install --upgrade --user statsmodels'은 내가 0.6.1 버전으로 업데이트되었다는 것을 알려줍니다. 그래서 나는 pypi 사용법을 모릅니다. – CPBL

답변

0

이 질문에 답하는 방법으로, 임의의 (OLS) 모델을 사용하여 데이터 프레임의 일부 값을 채우는 결과적인 방법이 있습니다. 그것은 예측하기 전에 필요에 따라 np.nans를 삭제합니다.

#!/usr/bin/python 
import statsmodels.formula.api as sm 
import pandas as pd 
import numpy as np 

def df_impute_values_ols(adf,outvar,model, verbose=True): 
    """Specify a Pandas DataFrame with some null (eg. np.nan) values in column <outvar>. 
    Specify a string model (in statsmodels format, which is like R) to use to predict them when they are missing. Nonlinear transformations can be specified in this string. 

    e.g.: model=' x1 + np.sin(x1) + I((x1-5)**2) ' 

    At the moment, this uses OLS, so outvar should be continuous. 

    Two dfs are returned: one containing just the updated rows and a 
    subset of columns, and version of the incoming DataFrame with some 
    null values filled in (those that have the model variables) will 
    be returned, using single imputation. 

    This is written to work with statsmodels 0.6.1 (see https://github.com/statsmodels/statsmodels/issues/2171) ie this is written in order to avoid ANY NaN's in the modeldf. That should be less necessary in future versions. 

    To do: 
    - Add plots to verbose mode 
    - Models other than OLS should be offered 

    Issues: 
    - the "horrid kluge" line below will give trouble if there are   
     column names that are part of other column names. This kludge should be 
     temporary, anyway, until statsmodels 0.8 is fixed and released. 

    The latest version of this method will be at 
    https://github.com/cpbl/cpblUtilities/ in stats/ 
    """ 
    formula=outvar+' ~ '+model 
    rhsv=[vv for vv in adf.columns if vv in model] # This is a horrid kluge! Ne 
    updateIndex= adf[pd.isnull(adf[outvar]) ] [rhsv].dropna().index 
    modeldf=adf[[outvar]+rhsv].dropna() 
    results=sm.ols(formula, data=modeldf).fit() 
    if verbose: 
     print results.summary() 
    newvals=adf[pd.isnull(adf[outvar])][rhsv].dropna() 
    newvals[outvar] = results.predict(newvals) 
    adf.loc[updateIndex,outvar]=newvals[outvar] 
    if verbose: 
     print(' %d rows updated for %s'%(len(newvals),outvar)) 
    return(newvals, adf) 


def test_df_impute_values_ols(): 
    # Find missing values and fill them in: 
    df = pd.DataFrame({"A": [10, 20, 30, 324, 2353, np.nan], 
         "B": [20, 30, 10, 100, 2332, 2332], 
         "C": [0, np.nan, 120, 11, 2, 2 ]}) 
    newv,df2=df_impute_values_ols(df,'A',' B + C ', verbose=True) 
    print df2 
    assert df2.iloc[-1]['A']==2357.5427562610648 
    assert df2.size==18 

    # Can we handle some missing values which also have missing predictors? 
    df = pd.DataFrame({"A": [10, 20, 30,  324, 2353, np.nan, np.nan], 
         "B": [20, 30, 10,  100, 2332, 2332, 2332], 
         "C": [0, np.nan, 120, 11, 2, 2,  np.nan ]}) 
    newv,df2=df_impute_values_ols(df,'A',' B + C + I(C**2) ', verbose=True) 
    print df2 

    assert pd.isnull( df2.iloc[-1]['A']) 
    assert df2.iloc[-2]['A'] == 2352.999999999995