سؤال

أنا باستخدام بيثون Numpy لحساب تناسب متعدد الحدود التعسفية درجة.مررت من قائمة قيم x, y والقيم درجة متعدد الحدود أريد أن صالح (الخطية والتربيعية.... الخ).

هذا يعمل, ولكن أريد أيضا أن حساب r (معامل الارتباط) و التربيعي(معامل العزم).أنا مقارنة النتائج مع Excel أفضل تناسب خط الاتجاه القدرة ، التربيعي قيمة يحسب.باستخدام هذا, وأنا أعلم أنا حساب الجذر التربيعي بشكل صحيح الخطي أفضل تناسب (درجة يساوي 1).ومع ذلك ، لا تعمل وظيفة على الحدود مع درجة أكبر من 1.

Excel غير قادرة على القيام بذلك.كيف يمكنني حساب الجذر التربيعي ل العليا متعددو الحدود باستخدام Numpy?

هنا هو بلدي وظيفة:

import numpy

# Polynomial Regression
def polyfit(x, y, degree):
    results = {}

    coeffs = numpy.polyfit(x, y, degree)
     # Polynomial Coefficients
    results['polynomial'] = coeffs.tolist()

    correlation = numpy.corrcoef(x, y)[0,1]

     # r
    results['correlation'] = correlation
     # r-squared
    results['determination'] = correlation**2

    return results
هل كانت مفيدة؟

المحلول

من numpy.polyfit. وثائق، هو المناسب الانحدار الخطي. على وجه التحديد، numpy.polyfit بدرجة "D" يناسب الانحدار الخطي مع وظيفة المتوسط

E (Y | x) = p_d * x ** d + p_ {d-1} * x * x ** (d-1) + ... + p_1 * x + p_0

لذلك تحتاج فقط لحساب R-Squared لهذا الملاءمة. صفحة ويكيبيديا على الانحدارالخطي يعطي التفاصيل الكاملة. أنت مهتم ب R ^ 2 الذي يمكنك حسابه في بذل عدة طرق، ويسهل على الأرجح

SST = Sum(i=1..n) (y_i - y_bar)^2
SSReg = Sum(i=1..n) (y_ihat - y_bar)^2
Rsquared = SSReg/SST

حيث يمكنني استخدام "Y_BAR" لتوسيع Y، و "Y_IHAT" ليكون قيمة FIT لكل نقطة.

أنا لست على دراية رهيبة ب Nutpy (عادة ما أعمل في R)، لذلك ربما تكون هناك طريقة مدائية لحساب R-Squared، ولكن يجب أن يكون ما يلي صحيحا

import numpy

# Polynomial Regression
def polyfit(x, y, degree):
    results = {}

    coeffs = numpy.polyfit(x, y, degree)

     # Polynomial Coefficients
    results['polynomial'] = coeffs.tolist()

    # r-squared
    p = numpy.poly1d(coeffs)
    # fit values, and mean
    yhat = p(x)                         # or [p(z) for z in x]
    ybar = numpy.sum(y)/len(y)          # or sum(y)/len(y)
    ssreg = numpy.sum((yhat-ybar)**2)   # or sum([ (yihat - ybar)**2 for yihat in yhat])
    sstot = numpy.sum((y - ybar)**2)    # or sum([ (yi - ybar)**2 for yi in y])
    results['determination'] = ssreg / sstot

    return results

نصائح أخرى

الرد المتأخر للغاية، ولكن فقط في حالة يحتاج شخص ما إلى وظيفة جاهزة لهذا:

scipy.stats.linregress.

بمعنى آخر

slope, intercept, r_value, p_value, std_err = scipy.stats.linregress(x, y)

كما هو الحال في إجابة aadam marably.

من يانل (مكتبة أخرى) sklearn.metrics لديه r2_square وظيفة؛

from sklearn.metrics import r2_score

coefficient_of_dermination = r2_score(y, p(x))

لقد كنت أستخدم هذا بنجاح، حيث تشبه x و y صفيف.

def rsquared(x, y):
    """ Return R^2 where x and y are array-like."""

    slope, intercept, r_value, p_value, std_err = scipy.stats.linregress(x, y)
    return r_value**2

أنا أصلا نشر المعايير أدناه مع الغرض من التوصية numpy.corrcoef, ، لا يدرك بحماقة أن السؤال الأصلي يستخدم بالفعل corrcoef وكان في الواقع يسأل عن ارتباط أعلى ترتيب متعدد الحدود. لقد أضفت حل فعلي لسؤال متعدد الحدود باستخدام StatSmodels، وتركت المعايير الأصلية، والتي في حين أن خارج الموضوع، تكون مفيدة لشخص ما.


statsmodels لديه القدرة على حساب r^2 من متعدد الحدود مناسبا مباشرة، وهنا هي 2 طرق ...

import statsmodels.api as sm
import statsmodels.formula.api as smf

# Construct the columns for the different powers of x
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

# Use the formula API and construct a formula describing the polynomial
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 # or rsquared_adj

لمزيد من الاستفادة من statsmodels, ، يجب أن ينظر المرء أيضا إلى ملخص النموذج المجهز، والذي يمكن طباعته أو عرضه كجدول HTML غني في دفتر Jupyter / Ipython. يوفر كائن النتائج الوصول إلى العديد من المقاييس الإحصائية المفيدة بالإضافة إلى rsquared.

model = sm.OLS(y, xpoly)
results = model.fit()
results.summary()

أدناه هي إجابتي الأصلية حيث قمت بقياس الانحدار الخطي المختلفة R ^ 2 طرق ...

ال corcoef. وظيفة تستخدم في السؤال يحسب معامل الارتباط، 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 MS لكل حلقة
  • Numpy Polyfit (ينطبق على N-Then Begr Bulnomial Fits)
    • 1000 حلقات، أفضل من 3: 326 μs لكل حلقة
  • دليل Numpy (مباشر r عملية حسابية)
    • 10000 حلقات، أفضل من 3: 62.1 μs لكل حلقة
  • numpy corclef (مباشرة r عملية حسابية)
    • 10000 حلقات، أفضل من 3: 56.6 μs لكل حلقة
  • Scipy (الانحدار الخطي مع r كإخراج)
    • 1000 حلقات، أفضل من 3: 676 μs لكل حلقة
  • StatSmodels (يمكن القيام بدرجة N-th درجة متعددة وغيرها من يناسب الأخرى)
    • 1000 حلقات، أفضل من 3: 422 μs لكل حلقة

طريقة Corcookef بفارق بفارق ضيق حساب R ^ 2 "يدويا" باستخدام أساليب Numpy. إنه> 5x أسرع من طريقة Polyfit و ~ 12x أسرع من SCIPY.LINRGRESS. فقط لتعزيز الفمبي الذي يفعله لك، فإنه أسرع 28x من بيثون نقي. أنا لست على دراية جيدة في أشياء مثل numba و pyby، لذلك سيتعين على شخص آخر ملء هذه الثغرات، لكنني أعتقد أن هذا مقنع معي ذلك corrcoef هي أفضل أداة لحساب r لانحدار خطي بسيط.

ها هي رمز القياس الخاص بي. أقوم بالنسخ من دفتر ملاحظات جوبير (من الصعب عدم الاتصال به دفتر ملاحظات iPython ...)، لذلك أعتذر إذا كان أي شيء قد انقطع في الطريق. يتطلب الأمر Magic Magic٪٪ 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)
    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)

مقالة ويكيبيديا r-squareds. يقترح أنه قد يتم استخدامه للنموذج العام المناسب بدلا من الانحدار الخطي فقط.

هنا هي وظيفة لحساب مرجحة التربيعي مع الثعبان Numpy (أكثر من رمز يأتي من sklearn):

from __future__ import division 
import numpy as np

def compute_r2_weighted(y_true, y_pred, weight):
    sse = (weight * (y_true - y_pred) ** 2).sum(axis=0, dtype=np.float64)
    tse = (weight * (y_true - np.average(
        y_true, axis=0, weights=weight)) ** 2).sum(axis=0, dtype=np.float64)
    r2_score = 1 - (sse / tse)
    return r2_score, sse, tse

على سبيل المثال:

from __future__ import print_function, division 
import sklearn.metrics 

def compute_r2_weighted(y_true, y_pred, weight):
    sse = (weight * (y_true - y_pred) ** 2).sum(axis=0, dtype=np.float64)
    tse = (weight * (y_true - np.average(
        y_true, axis=0, weights=weight)) ** 2).sum(axis=0, dtype=np.float64)
    r2_score = 1 - (sse / tse)
    return r2_score, sse, tse    

def compute_r2(y_true, y_predicted):
    sse = sum((y_true - y_predicted)**2)
    tse = (len(y_true) - 1) * np.var(y_true, ddof=1)
    r2_score = 1 - (sse / tse)
    return r2_score, sse, tse

def main():
    '''
    Demonstrate the use of compute_r2_weighted() and checks the results against sklearn
    '''        
    y_true = [3, -0.5, 2, 7]
    y_pred = [2.5, 0.0, 2, 8]
    weight = [1, 5, 1, 2]
    r2_score = sklearn.metrics.r2_score(y_true, y_pred)
    print('r2_score: {0}'.format(r2_score))  
    r2_score,_,_ = compute_r2(np.array(y_true), np.array(y_pred))
    print('r2_score: {0}'.format(r2_score))
    r2_score = sklearn.metrics.r2_score(y_true, y_pred,weight)
    print('r2_score weighted: {0}'.format(r2_score))
    r2_score,_,_ = compute_r2_weighted(np.array(y_true), np.array(y_pred), np.array(weight))
    print('r2_score weighted: {0}'.format(r2_score))

if __name__ == "__main__":
    main()
    #cProfile.run('main()') # if you want to do some profiling

النواتج:

r2_score: 0.9486081370449679
r2_score: 0.9486081370449679
r2_score weighted: 0.9573170731707317
r2_score weighted: 0.9573170731707317

هذا يتوافق مع الصيغة (مرآة):

enter image description here

مع f_i هو القيمة المتوقعة من يصلح ، y_{av} هو يعني من البيانات لاحظ y_i هو لاحظ بيانات القيمة.w_i هو الترجيح تطبيقها على كل نقطة بيانات ، وعادة w_i=1.SSE هو مجموع المربعات بسبب الخطأ SST هو مجموع مجموع المربعات.


اذا كانت مهتمة, مدونة في ص: https://gist.github.com/dhimmel/588d64a73fa4fef02c8f (مرآة)

التربيعي هو الإحصائية التي ينطبق فقط على الانحدار الخطي.

أساسا, فهو يقيس مقدار التغير في البيانات الخاصة بك يمكن أن يكون أوضح من الانحدار الخطي.

لذا حساب "مجموع مجموع المربعات" الذي هو مجموع تربيع الانحراف من كل من نتائج المتغيرات من يعني بهم...

\sum_{أنا}(y_{أنا} - y_bar)^2

حيث y_bar هو يعني من ص.

ثم حساب "الانحدار مجموع المربعات" ، وهو مقدار تركيبها القيم تختلف من يعني

\sum_{أنا}(yHat_{أنا} - y_bar)^2

والعثور على نسبة من هذين.

الآن كل ما عليك القيام به لفترة متعدد الحدود تناسب المكونات في y_hat من هذا النموذج ، ولكن ذلك ليس دقيقا أن نسمي ذلك التربيعي.

هنا هو ارتباط وجدت أن يتحدث قليلا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top