2017-06-06 21 views
24

मुझे विकल्पकक्षा (स्रोत here) से बाहर stats/ols मॉड्यूल के भीतर अच्छा उपयोग मिला। दुर्भाग्य से, यह पूरी तरह से पांडा 0.20 के साथ gutted था।पांडा रोलिंग रिग्रेशन: लूपिंग

रोलिंग ओएलएस रिग्रेशन को कुशल तरीके से चलाने के सवाल को कई बार पूछा गया है (उदाहरण के लिए here), लेकिन मेरे विचार में थोड़ा सा जवाब दिया और बिना किसी बड़े उत्तर के छोड़ा गया।

यहाँ मेरी प्रश्न हैं:

  1. कैसे मैं सबसे अच्छा पांडा की 'MovingOLS बुनियादी ढांचे की नकल कर सकते हैं? इस वर्ग की सबसे आकर्षक विशेषता अलग-अलग विधियों/विशेषताओं को अलग-अलग समय श्रृंखला के रूप में देखने की क्षमता थी - यानी। गुणांक, आर-स्क्वायर, टी-आंकड़े, आदि को पुन: चलाने के लिए पुन: चलाने की आवश्यकता के बिना। उदाहरण के लिए, आप model = pd.MovingOLS(y, x) जैसे कुछ बना सकते हैं और फिर .t_stat, .rmse, .std_err, और इसी तरह कॉल कर सकते हैं। नीचे दिए गए उदाहरण में, इसके विपरीत, मुझे अलग-अलग आंकड़ों की गणना करने के लिए मजबूर होने के आसपास एक रास्ता नहीं दिख रहा है। क्या कोई ऐसी विधि है जिसमें प्रत्येक के लिए मॉडल पैरामीटर प्राप्त करने के लिए स्लाइडिंग/रोलिंग "ब्लॉकों" (स्ट्रिंग) और रैखिक बीजगणित का उपयोग करके रोलिंग/रोलिंग बनाने में शामिल नहीं है?

  2. अधिक मोटे तौर पर, क्या करता है कि पांडा में हुड के नीचे हो रहा है rolling.apply, और अधिक जटिल कार्यों लेने के लिए * जब आप किसी .rolling वस्तु बनाने के आम आदमी की दृष्टि में सक्षम नहीं है, क्या आंतरिक रूप से चल रहा है - यह मूल रूप से अलग है प्रत्येक खिड़की पर लूपिंग और एक उच्च-आयामी सरणी बनाना जैसा कि मैं नीचे कर रहा हूं?

* अर्थात् func.apply के लिए पारित:

एक ndarray इनपुट * args और ** kwargs समारोह

यहाँ जहां है के लिए पारित कर रहे हैं से एक मान का उत्पादन होगा मैं वर्तमान में कुछ नमूना डेटा के साथ हूं, ब्याज दर फैलाने और तांबे की कीमत पर व्यापार भारित डॉलर में प्रतिशत परिवर्तन को पुनर्जीवित करता हूं। (यह भावना का एक टन नहीं बनाता है, बस इन्हें यादृच्छिक रूप से चुना गया है।) मैंने इसे कक्षा-आधारित कार्यान्वयन से बाहर कर लिया है और इसे एक सरल लिपि में पट्टी करने की कोशिश की है।

from datetime import date 
from pandas_datareader.data import DataReader 
import statsmodels.formula.api as smf 

syms = {'TWEXBMTH' : 'usd', 
     'T10Y2YM' : 'term_spread', 
     'PCOPPUSDM' : 'copper' 
     } 

start = date(2000, 1, 1) 
data = (DataReader(syms.keys(), 'fred', start) 
     .pct_change() 
     .dropna()) 
data = data.rename(columns = syms) 
data = data.assign(intercept = 1.) # required by statsmodels OLS 

def sliding_windows(x, window): 
    """Create rolling/sliding windows of length ~window~. 

    Given an array of shape (y, z), it will return "blocks" of shape 
    (x - window + 1, window, z).""" 

    return np.array([x[i:i + window] for i 
        in range(0, x.shape[0] - window + 1)]) 

data.head(3) 
Out[33]: 
       usd term_spread copper intercept 
DATE             
2000-02-01 0.012573 -1.409091 -0.019972  1.0 
2000-03-01 -0.000079  2.000000 -0.037202  1.0 
2000-04-01 0.005642  0.518519 -0.033275  1.0 

window = 36 
wins = sliding_windows(data.values, window=window) 
y, x = wins[:, :, 0], wins[:, :, 1:] 

coefs = [] 

for endog, exog in zip(y, x): 
    model = smf.OLS(endog, exog).fit() 
     # The full set of model attributes gets lost with each loop 
    coefs.append(model.params) 

df = pd.DataFrame(coefs, columns=data.iloc[:, 1:].columns, 
        index=data.index[window - 1:]) 

df.head(3) # rolling 36m coefficients 
Out[70]: 
      term_spread copper intercept 
DATE           
2003-01-01 -0.000122 -0.018426 0.001937 
2003-02-01  0.000391 -0.015740 0.001597 
2003-03-01  0.000655 -0.016811 0.001546 
+2

एक बुनियादी तरीके को मैं अपने पाश का उपयोग करें और सभी विशेषताओं और परिणाम है कि आप एक पास में जरूरत की दुकान होगी। यहां मेरा जवाब नहीं है क्योंकि मुझे पांडा अच्छी तरह से नहीं जानते हैं https://github.com/statsmodels/statsmodels/issues/2302#issuecomment-306389959 – user333700

+0

यहां मेरे विचार हैं। मैं एक कट्टर पांडो और आर उपयोगकर्ता हूं: कुछ भी रिग्रेशन से संबंधित, आर का उपयोग करें, पायथन नहीं। अनुमोदित, आप लगभग कर सकते हैं। वही बात है, लेकिन पायथन आर के पैकेज की चौड़ाई से मेल नहीं खा सकता है। इसके अलावा, आपके पास 'ब्रूम' जैसे पैकेज हैं जो आपको इन प्रतिक्रियाओं के आंकड़ों को आसानी से पकड़ने की अनुमति देते हैं और या तो उन्हें डेटाफ्रेम या लेटेक्स टेबल में डाल देते हैं। –

+0

क्या MovingOLS काम नहीं करता है, या इसे अभी हटा दिया गया था? क्या आप केवल MovingOLS कोड ले सकते हैं और प्रभावी ढंग से अपनी छोटी लाइब्रेरी बना सकते हैं? – BrenBarn

उत्तर

4

मैं एक ols मॉड्यूल पांडा नकल करने के लिए डिज़ाइन किया गया 'MovingOLS पदावनत बनाया; यह here है।

यह तीन मुख्य वर्गों है:

  • OLS: स्थिर (एकल विंडो) साधारण कम से कम वर्गों प्रतिगमन। उत्पादन NumPy arrays
  • RollingOLS: रोलिंग (बहु-खिड़की) साधारण कम-वर्ग प्रतिगमन है। उत्पादन उच्च आयाम NumPy सरणी हैं।
  • PandasRollingOLS: पांडा श्रृंखला & डेटाफ्रेम में RollingOLS के परिणामों को लपेटता है। बहिष्कृत पांडा मॉड्यूल के स्वरूप की नकल करने के लिए बनाया गया है।

ध्यान दें कि मॉड्यूल package (जो अब पीईपीआई पर है) का हिस्सा है और इसके लिए एक अंतर-पैकेज आयात की आवश्यकता है।

उपरोक्त पहले दो वर्ग पूरी तरह से न्यूपी में लागू किए जाते हैं और मुख्य रूप से मैट्रिक्स बीजगणित का उपयोग करते हैं। RollingOLS व्यापक रूप से प्रसारण का लाभ भी लेता है। गुण बड़े पैमाने पर आंकड़े मॉडल की ओएलएस RegressionResultsWrapper नकल करते हैं।

एक उदाहरण:

# Pull some data from fred.stlouisfed.org 
from pandas_datareader.data import DataReader 

syms = {'TWEXBMTH' : 'usd', 
     'T10Y2YM' : 'term_spread', 
     'PCOPPUSDM' : 'copper' 
     } 
data = (DataReader(syms.keys(), 'fred', start='2000-01-01') 
     .pct_change() 
     .dropna()) 
data = data.rename(columns=syms) 
print(data.head()) 
       # usd term_spread copper 
# DATE          
# 2000-02-01 0.01260  -1.40909 -0.01997 
# 2000-03-01 -0.00012  2.00000 -0.03720 
# 2000-04-01 0.00564  0.51852 -0.03328 
# 2000-05-01 0.02204  -0.09756 0.06135 
# 2000-06-01 -0.01012  0.02703 -0.01850 

# Rolling regressions 

from pyfinance.ols import OLS, RollingOLS, PandasRollingOLS 

y = data.usd 
x = data.drop('usd', axis=1) 

window = 12 # months 
model = PandasRollingOLS(y=y, x=x, window=window) 

print(model.beta.head()) # Coefficients excluding the intercept 
      # term_spread copper 
# DATE        
# 2001-01-01  0.00010 0.05568 
# 2001-02-01  0.00047 0.06271 
# 2001-03-01  0.00147 0.03576 
# 2001-04-01  0.00161 0.02956 
# 2001-05-01  0.00158 -0.04497 

print(model.fstat.head()) 
# DATE 
# 2001-01-01 0.28121 
# 2001-02-01 0.42602 
# 2001-03-01 0.38802 
# 2001-04-01 0.39230 
# 2001-05-01 0.41706 
# Freq: MS, Name: fstat, dtype: float64 

print(model.rsq.head()) # R-squared 
# DATE 
# 2001-01-01 0.05882 
# 2001-02-01 0.08648 
# 2001-03-01 0.07938 
# 2001-04-01 0.08019 
# 2001-05-01 0.08482 
# Freq: MS, Name: rsq, dtype: float64 
+1

इस दृष्टिकोण के साथ मुख्य समस्या यह है कि सभी ओएलएस उदाहरणों को ध्यान में रखते हुए बहुत मेमोरी की आवश्यकता होती है। – user333700

+0

@ user333700 मैंने कुछ बड़े बदलाव किए हैं जो आपको देखने में रूचि रखते हैं तो स्मृति के लिए बहुत दयालु होना चाहिए। –

संबंधित मुद्दे