मैंने मूल रूप से सिफारिश करने के उद्देश्य से नीचे दिए गए बेंचमार्क पोस्ट किए numpy.corrcoef
, मूर्खतापूर्ण रूप से यह महसूस नहीं किया कि मूल प्रश्न पहले से ही उपयोग करता है corrcoef
और वास्तव में उच्च आदेश बहुपद फिट के बारे में पूछ रहा था। मैंने स्टेटमॉमियल आर-स्क्वैयर प्रश्न का एक वास्तविक समाधान जोड़ा है, जिसमें स्टैटमोडल का उपयोग किया गया है, और मैंने मूल बेंचमार्क को छोड़ दिया है, जो ऑफ-टॉपिक के दौरान संभावित रूप से किसी के लिए उपयोगी है।
statsmodels
r^2
एक बहुपद फिट सीधे गणना करने की क्षमता है , यहाँ 2 तरीके हैं ...
import statsmodels.api as sm
import statsmodels.formula.api as smf
def get_r2_statsmodels(x, y, k=1):
xpoly = np.column_stack([x**i for i in range(k+1)])
return sm.OLS(y, xpoly).fit().rsquared
def get_r2_statsmodels_formula(x, y, k=1):
formula = 'y ~ 1 + ' + ' + '.join('I(x**{})'.format(i) for i in range(1, k+1))
data = {'x': x, 'y': y}
return smf.ols(formula, data).fit().rsquared
आगे लाभ उठाने के लिए statsmodels
, किसी को फिट किए गए मॉडल सारांश को भी देखना चाहिए, जिसे जुपिटर / आईपीथॉन नोटबुक में एक समृद्ध HTML तालिका के रूप में मुद्रित या प्रदर्शित किया जा सकता है। परिणाम वस्तु के अलावा कई उपयोगी सांख्यिकीय मैट्रिक्स तक पहुँच प्रदान करता है rsquared
।
model = sm.OLS(y, xpoly)
results = model.fit()
results.summary()
नीचे मेरा मूल उत्तर है जहां मैंने विभिन्न रैखिक प्रतिगमन r ^ 2 विधियों को बेंचमार्क किया है ...
प्रश्न में उपयोग किया जाने वाला गलियारा फ़ंक्शन सहसंबंध गुणांक की गणना करता है r
, केवल एक रेखीय प्रतिगमन के लिए, इसलिए यह r^2
उच्च क्रम बहुपद फिट के लिए प्रश्न को संबोधित नहीं करता है । हालांकि, इसके लायक क्या है, मुझे पता चला है कि रैखिक प्रतिगमन के लिए, यह वास्तव में गणना का सबसे तेज़ और सबसे प्रत्यक्ष तरीका है r
।
def get_r2_numpy_corrcoef(x, y):
return np.corrcoef(x, y)[0, 1]**2
1000 यादृच्छिक (x, y) बिंदुओं के लिए तरीकों की एक गुच्छा की तुलना करने से ये मेरे समय परिणाम थे:
- शुद्ध अजगर (प्रत्यक्ष
r
गणना)
- 1000 लूप, सर्वश्रेष्ठ 3: 1.59 एमएस प्रति लूप
- Numpy पॉलीफ़िट (n-th डिग्री बहुपद फिट करने के लिए लागू)
- 1000 लूप, सर्वश्रेष्ठ 3: 326 µ प्रति लूप
- Numpy मैनुअल (प्रत्यक्ष
r
गणना)
- 10000 लूप, सर्वश्रेष्ठ 3: 62.1 ops प्रति लूप
- Numpy नाली (प्रत्यक्ष
r
गणना)
- 10000 लूप, सर्वश्रेष्ठ 3: 56.6। प्रति लूप
- स्किप (
r
उत्पादन के रूप में रैखिक प्रतिगमन )
- 1000 लूप, सर्वश्रेष्ठ 3: 676 ops प्रति लूप
- Statsmodels (n-th डिग्री बहुपद और कई अन्य फिट कर सकते हैं)
- 1000 लूप, सर्वश्रेष्ठ 3: 422 of प्रति लूप
नालीदार विधि संकरी विधियों का उपयोग करके r ^ 2 "मैन्युअल रूप से" की गणना करते हुए संकीर्ण रूप से धड़कती है। यह पॉलीफ़िट विधि की तुलना में> 5X तेज़ और स्किपी.लाइनरग्रेड की तुलना में ~ 12X तेज़ है। सिर्फ यह बताने के लिए कि आपके लिए क्या खस्ता है, यह शुद्ध अजगर की तुलना में 28X तेज है। मैं सुब्बा और पिपी जैसी चीजों से अच्छी तरह वाकिफ नहीं हूं, इसलिए किसी और को उन अंतरालों को भरना होगा, लेकिन मुझे लगता है कि यह मेरे लिए काफी ठोस corrcoef
है जो r
एक सरल रेखीय प्रतिगमन की गणना के लिए सबसे अच्छा उपकरण है ।
यहाँ मेरा बेंचमार्किंग कोड है। मैं ज्यूपिटर नोटबुक से कॉपी-पेस्ट करता हूं (हार्ड इसे आईपाइथॉन नोटबुक नहीं कहता ...), इसलिए अगर रास्ते में कुछ भी टूट गया तो मैं माफी मांगता हूं। % टाइमिट मैजिक कमांड के लिए IPython की आवश्यकता होती है।
import numpy as np
from scipy import stats
import statsmodels.api as sm
import math
n=1000
x = np.random.rand(1000)*10
x.sort()
y = 10 * x + (5+np.random.randn(1000)*10-5)
x_list = list(x)
y_list = list(y)
def get_r2_numpy(x, y):
slope, intercept = np.polyfit(x, y, 1)
r_squared = 1 - (sum((y - (slope * x + intercept))**2) / ((len(y) - 1) * np.var(y, ddof=1)))
return r_squared
def get_r2_scipy(x, y):
_, _, r_value, _, _ = stats.linregress(x, y)
return r_value**2
def get_r2_statsmodels(x, y):
return sm.OLS(y, sm.add_constant(x)).fit().rsquared
def get_r2_python(x_list, y_list):
n = len(x_list)
x_bar = sum(x_list)/n
y_bar = sum(y_list)/n
x_std = math.sqrt(sum([(xi-x_bar)**2 for xi in x_list])/(n-1))
y_std = math.sqrt(sum([(yi-y_bar)**2 for yi in y_list])/(n-1))
zx = [(xi-x_bar)/x_std for xi in x_list]
zy = [(yi-y_bar)/y_std for yi in y_list]
r = sum(zxi*zyi for zxi, zyi in zip(zx, zy))/(n-1)
return r**2
def get_r2_numpy_manual(x, y):
zx = (x-np.mean(x))/np.std(x, ddof=1)
zy = (y-np.mean(y))/np.std(y, ddof=1)
r = np.sum(zx*zy)/(len(x)-1)
return r**2
def get_r2_numpy_corrcoef(x, y):
return np.corrcoef(x, y)[0, 1]**2
print('Python')
%timeit get_r2_python(x_list, y_list)
print('Numpy polyfit')
%timeit get_r2_numpy(x, y)
print('Numpy Manual')
%timeit get_r2_numpy_manual(x, y)
print('Numpy corrcoef')
%timeit get_r2_numpy_corrcoef(x, y)
print('Scipy')
%timeit get_r2_scipy(x, y)
print('Statsmodels')
%timeit get_r2_statsmodels(x, y)