पंकित-सीखें LinearRegression में p-value (महत्व) का पता लगाएं


154

मैं प्रत्येक गुणांक का पी-मान (महत्व) कैसे पा सकता हूं?

lm = sklearn.linear_model.LinearRegression()
lm.fit(x,y)

2
आपका जवाब नहीं, लेकिन शायद दूसरों के लिए एक जवाब: scipy अलंकरण में pvalues ​​प्रदान करता है: docs.scipy.org/doc/scipy-0.14.0/reference/generated/…
DaveRGPP

यह केवल एक आयाम बनाम एक आयाम के लिए काम करता है।
रिचर्ड लियांग

जवाबों:


162

यह एक तरह का ओवरकिल है लेकिन इसे छोड़ देना चाहिए। पहले पी-वैल्यूज़ क्या होनी चाहिए, यह जानने के लिए स्टैटमॉडल का उपयोग करें

import pandas as pd
import numpy as np
from sklearn import datasets, linear_model
from sklearn.linear_model import LinearRegression
import statsmodels.api as sm
from scipy import stats

diabetes = datasets.load_diabetes()
X = diabetes.data
y = diabetes.target

X2 = sm.add_constant(X)
est = sm.OLS(y, X2)
est2 = est.fit()
print(est2.summary())

और हम प्राप्त करते हैं

                         OLS Regression Results                            
==============================================================================
Dep. Variable:                      y   R-squared:                       0.518
Model:                            OLS   Adj. R-squared:                  0.507
Method:                 Least Squares   F-statistic:                     46.27
Date:                Wed, 08 Mar 2017   Prob (F-statistic):           3.83e-62
Time:                        10:08:24   Log-Likelihood:                -2386.0
No. Observations:                 442   AIC:                             4794.
Df Residuals:                     431   BIC:                             4839.
Df Model:                          10                                         
Covariance Type:            nonrobust                                         
==============================================================================
                 coef    std err          t      P>|t|      [0.025      0.975]
------------------------------------------------------------------------------
const        152.1335      2.576     59.061      0.000     147.071     157.196
x1           -10.0122     59.749     -0.168      0.867    -127.448     107.424
x2          -239.8191     61.222     -3.917      0.000    -360.151    -119.488
x3           519.8398     66.534      7.813      0.000     389.069     650.610
x4           324.3904     65.422      4.958      0.000     195.805     452.976
x5          -792.1842    416.684     -1.901      0.058   -1611.169      26.801
x6           476.7458    339.035      1.406      0.160    -189.621    1143.113
x7           101.0446    212.533      0.475      0.635    -316.685     518.774
x8           177.0642    161.476      1.097      0.273    -140.313     494.442
x9           751.2793    171.902      4.370      0.000     413.409    1089.150
x10           67.6254     65.984      1.025      0.306     -62.065     197.316
==============================================================================
Omnibus:                        1.506   Durbin-Watson:                   2.029
Prob(Omnibus):                  0.471   Jarque-Bera (JB):                1.404
Skew:                           0.017   Prob(JB):                        0.496
Kurtosis:                       2.726   Cond. No.                         227.
==============================================================================

ठीक है, चलो इसे पुन: पेश करते हैं। यह ओवरकिल की तरह है क्योंकि हम मैट्रिक्स बीजगणित का उपयोग करके एक रेखीय प्रतिगमन विश्लेषण का पुनरुत्पादन कर रहे हैं। लेकिन क्या बिल्ली।

lm = LinearRegression()
lm.fit(X,y)
params = np.append(lm.intercept_,lm.coef_)
predictions = lm.predict(X)

newX = pd.DataFrame({"Constant":np.ones(len(X))}).join(pd.DataFrame(X))
MSE = (sum((y-predictions)**2))/(len(newX)-len(newX.columns))

# Note if you don't want to use a DataFrame replace the two lines above with
# newX = np.append(np.ones((len(X),1)), X, axis=1)
# MSE = (sum((y-predictions)**2))/(len(newX)-len(newX[0]))

var_b = MSE*(np.linalg.inv(np.dot(newX.T,newX)).diagonal())
sd_b = np.sqrt(var_b)
ts_b = params/ sd_b

p_values =[2*(1-stats.t.cdf(np.abs(i),(len(newX)-len(newX[0])))) for i in ts_b]

sd_b = np.round(sd_b,3)
ts_b = np.round(ts_b,3)
p_values = np.round(p_values,3)
params = np.round(params,4)

myDF3 = pd.DataFrame()
myDF3["Coefficients"],myDF3["Standard Errors"],myDF3["t values"],myDF3["Probabilities"] = [params,sd_b,ts_b,p_values]
print(myDF3)

और यह हमें देता है।

    Coefficients  Standard Errors  t values  Probabilities
0       152.1335            2.576    59.061         0.000
1       -10.0122           59.749    -0.168         0.867
2      -239.8191           61.222    -3.917         0.000
3       519.8398           66.534     7.813         0.000
4       324.3904           65.422     4.958         0.000
5      -792.1842          416.684    -1.901         0.058
6       476.7458          339.035     1.406         0.160
7       101.0446          212.533     0.475         0.635
8       177.0642          161.476     1.097         0.273
9       751.2793          171.902     4.370         0.000
10       67.6254           65.984     1.025         0.306

इसलिए हम स्टैटस्मॉडल से मानों को पुन: पेश कर सकते हैं।


2
इसका क्या मतलब है कि मेरे var_b सभी Nans हैं? क्या कोई अंतर्निहित कारण है कि रैखिक बीजगणित का हिस्सा विफल क्यों होता है?
famargar

वास्तव में यह अनुमान लगाना कठिन है कि ऐसा क्यों हो सकता है। मैं आपके डेटा की संरचना को देखूंगा और इसकी तुलना उदाहरण से करूंगा। यह एक सुराग प्रदान कर सकता है।
17

1
ऐसा लगता है कि codenp.linalg.inv मैट्रिक्स के नॉन-इनवर्टेबल होने पर भी कभी-कभी परिणाम लौटा सकता है। यह मुद्दा हो सकता है।
JARH

7
@famargar मैं भी सभी nans की समस्या थी । मेरे लिए यह इसलिए था क्योंकि Xमेरे डेटा का एक नमूना था इसलिए सूचकांक बंद था। यह कॉल करते समय त्रुटियों का कारण बनता है pd.DataFrame.join()। मैंने इसे एक पंक्ति में बदल दिया और यह अब काम करने लगता है:newX = pd.DataFrame({"Constant":np.ones(len(X))}).join(pd.DataFrame(X.reset_index(drop=True)))
change

1
@ mLstudent33 "संभावनाएँ" कॉलम।
skeller88

52

scikit-learn का रेखीयकरण इस जानकारी की गणना नहीं करता है लेकिन आप इसे करने के लिए आसानी से कक्षा का विस्तार कर सकते हैं:

from sklearn import linear_model
from scipy import stats
import numpy as np


class LinearRegression(linear_model.LinearRegression):
    """
    LinearRegression class after sklearn's, but calculate t-statistics
    and p-values for model coefficients (betas).
    Additional attributes available after .fit()
    are `t` and `p` which are of the shape (y.shape[1], X.shape[1])
    which is (n_features, n_coefs)
    This class sets the intercept to 0 by default, since usually we include it
    in X.
    """

    def __init__(self, *args, **kwargs):
        if not "fit_intercept" in kwargs:
            kwargs['fit_intercept'] = False
        super(LinearRegression, self)\
                .__init__(*args, **kwargs)

    def fit(self, X, y, n_jobs=1):
        self = super(LinearRegression, self).fit(X, y, n_jobs)

        sse = np.sum((self.predict(X) - y) ** 2, axis=0) / float(X.shape[0] - X.shape[1])
        se = np.array([
            np.sqrt(np.diagonal(sse[i] * np.linalg.inv(np.dot(X.T, X))))
                                                    for i in range(sse.shape[0])
                    ])

        self.t = self.coef_ / se
        self.p = 2 * (1 - stats.t.cdf(np.abs(self.t), y.shape[0] - X.shape[1]))
        return self

यहां से चोरी हुई

पायथन में इस तरह के सांख्यिकीय विश्लेषण के लिए आपको सांख्यिकीमॉडल्स पर एक नज़र डालनी चाहिए ।


कुंआ। यह काम करने के लिए नहीं रिसता है क्योंकि sse एक स्केलर है इसलिए sse.shape का वास्तव में कोई मतलब नहीं है।
आशु

15

संपादित करें: शायद ऐसा करने का सही तरीका नहीं है, टिप्पणी देखें

आप sklearn.feature_selection.f_regression का उपयोग कर सकते हैं।

यहां क्लिक करें scikit-learn पेज के लिए


1
तो वे एफ-टेस्ट हैं? मैंने सोचा था कि रैखिक प्रतिगमन के लिए पी-मान आमतौर पर प्रत्येक व्यक्ति के प्रतिगमन के लिए था, और यह गुणांक 0 के शून्य से एक परीक्षण था? एक अच्छे उत्तर के लिए फ़ंक्शन की अधिक व्याख्या आवश्यक होगी।
शब्दफोर्ट वाइज

@wordsforthewise प्रलेखन पृष्ठ कहता है कि लौटाया गया मान p_values ​​का एक सरणी है। तो यह वास्तव में प्रत्येक व्यक्ति प्रतिगामी के लिए एक मूल्य है।
आशु

1
इस विधि का उपयोग न करें क्योंकि यह सही नहीं है! यह अविभाजित प्रतिगमन करता है, लेकिन आप संभवतः एक बहुभिन्नरूपी प्रतिगमन चाहते हैं
user357269

1
नहीं, f_regression का उपयोग न करें। प्रत्येक गुणांक का वास्तविक पी-मूल्य डेटा फिटिंग के बाद प्रत्येक गुणांक के लिए टी परीक्षण से आना चाहिए। sk_earn में f_regression univariate regressions से आता है। इसने मोड का निर्माण नहीं किया, बस प्रत्येक चर के लिए f स्कोर को शांत किया। Sklearn में chi2 फंक्शन के रूप में भी यही सही है: एसएमआई = sm.OLS (Y, X) के रूप में importmmodels.api आयात करें
रिचर्ड लियांग

@RichardLiang, sm.OLS () किसी भी एल्गोरिथ्म के लिए p- मूल्य (बहुभिन्नरूपी) की गणना करने का सही तरीका है? (जैसे निर्णय पेड़, svm, k- साधन, उपस्कर प्रतिगमन, आदि)? मैं पी-मूल्य प्राप्त करने के लिए एक सामान्य विधि चाहूंगा। धन्यवाद
गिलियन १ilian

11

Elyase के जवाब में कोड https://stackoverflow.com/a/27928411/4240413 वास्तव में काम नहीं करता है। ध्यान दें कि sse एक अदिश राशि है, और फिर यह इसके माध्यम से पुनरावृति करने की कोशिश करता है। निम्नलिखित कोड एक संशोधित संस्करण है। आश्चर्यजनक रूप से साफ नहीं है, लेकिन मुझे लगता है कि यह कम या ज्यादा काम करता है।

class LinearRegression(linear_model.LinearRegression):

    def __init__(self,*args,**kwargs):
        # *args is the list of arguments that might go into the LinearRegression object
        # that we don't know about and don't want to have to deal with. Similarly, **kwargs
        # is a dictionary of key words and values that might also need to go into the orginal
        # LinearRegression object. We put *args and **kwargs so that we don't have to look
        # these up and write them down explicitly here. Nice and easy.

        if not "fit_intercept" in kwargs:
            kwargs['fit_intercept'] = False

        super(LinearRegression,self).__init__(*args,**kwargs)

    # Adding in t-statistics for the coefficients.
    def fit(self,x,y):
        # This takes in numpy arrays (not matrices). Also assumes you are leaving out the column
        # of constants.

        # Not totally sure what 'super' does here and why you redefine self...
        self = super(LinearRegression, self).fit(x,y)
        n, k = x.shape
        yHat = np.matrix(self.predict(x)).T

        # Change X and Y into numpy matricies. x also has a column of ones added to it.
        x = np.hstack((np.ones((n,1)),np.matrix(x)))
        y = np.matrix(y).T

        # Degrees of freedom.
        df = float(n-k-1)

        # Sample variance.     
        sse = np.sum(np.square(yHat - y),axis=0)
        self.sampleVariance = sse/df

        # Sample variance for x.
        self.sampleVarianceX = x.T*x

        # Covariance Matrix = [(s^2)(X'X)^-1]^0.5. (sqrtm = matrix square root.  ugly)
        self.covarianceMatrix = sc.linalg.sqrtm(self.sampleVariance[0,0]*self.sampleVarianceX.I)

        # Standard erros for the difference coefficients: the diagonal elements of the covariance matrix.
        self.se = self.covarianceMatrix.diagonal()[1:]

        # T statistic for each beta.
        self.betasTStat = np.zeros(len(self.se))
        for i in xrange(len(self.se)):
            self.betasTStat[i] = self.coef_[0,i]/self.se[i]

        # P-value for each beta. This is a two sided t-test, since the betas can be 
        # positive or negative.
        self.betasPValue = 1 - t.cdf(abs(self.betasTStat),df)

8

पी-वैल्यू को खींचने का एक आसान तरीका है, स्टैटस्मॉडल रिग्रेशन का उपयोग करना:

import statsmodels.api as sm
mod = sm.OLS(Y,X)
fii = mod.fit()
p_values = fii.summary2().tables[1]['P>|t|']

आपको पी-मानों की एक श्रृंखला मिलती है जिसे आप हेरफेर कर सकते हैं (उदाहरण के लिए प्रत्येक पी-मान का मूल्यांकन करके आप जो ऑर्डर रखना चाहते हैं उसे चुनें:

यहाँ छवि विवरण दर्ज करें


किसी भी एल्गोरिथ्म के लिए p.-value (बहुभिन्नरूपी) की गणना करने का सही तरीका sm.OLS () का उपयोग करना है? (जैसे निर्णय पेड़, svm, k- साधन, उपस्कर प्रतिगमन, आदि)? मैं पी-मूल्य प्राप्त करने के लिए एक सामान्य विधि चाहूंगा। धन्यवाद
गिलियन १ilian

7

p_value f आँकड़ों के बीच है। यदि आप मूल्य प्राप्त करना चाहते हैं, तो कोड की कुछ पंक्तियों का उपयोग करें:

import statsmodels.api as sm
from scipy import stats

diabetes = datasets.load_diabetes()
X = diabetes.data
y = diabetes.target

X2 = sm.add_constant(X)
est = sm.OLS(y, X2)
print(est.fit().f_pvalue)

3
यह प्रश्न का उत्तर नहीं देता है क्योंकि आप एक से अधिक लाइब्रेरी का उपयोग कर रहे हैं जो उल्लेख किया गया है।
gented

@gent वे परिदृश्य क्या हैं जहाँ गणना का एक तरीका दूसरे से बेहतर होगा?
डॉन क्विक्सोट

6

बहुविकल्पी प्रतिगमन के मामले में @JARH के उत्तर में कोई गलती हो सकती है । (मेरे पास टिप्पणी करने के लिए पर्याप्त प्रतिष्ठा नहीं है।)

निम्नलिखित पंक्ति में:

p_values =[2*(1-stats.t.cdf(np.abs(i),(len(newX)-1))) for i in ts_b],

टी-मान डिग्री के ची-चुकता वितरण के len(newX)-1बजाय डिग्री के ची-चुकता वितरण का अनुसरण करता है len(newX)-len(newX.columns)-1

तो यह होना चाहिए:

p_values =[2*(1-stats.t.cdf(np.abs(i),(len(newX)-len(newX.columns)-1))) for i in ts_b]

( अधिक विवरण के लिए ओएलएस प्रतिगमन के लिए टी-मान देखें)


5

आप p-value के लिए scipy का उपयोग कर सकते हैं । यह कोड scipy प्रलेखन से है।

>>> from scipy import stats
>>> import numpy as np
>>> x = np.random.random(10)
>>> y = np.random.random(10)
>>> slope, intercept, r_value, p_value, std_err = stats.linregress(x,y)

1
मुझे नहीं लगता कि यह फिट के दौरान इस्तेमाल होने वाले कई वैक्टरों के लिए लागू होता है
O.rka

1

एक-लाइनर के लिए आप pingouin.linear_regression फ़ंक्शन ( अस्वीकरण: मैं पिंगउइन का निर्माता हूं ) का उपयोग कर सकते हैं , जो NumPy सरणियों या पंडों डेटाफ्रेम, उदा का उपयोग करते हुए यूनी / मल्टी-वेरिएंट रिग्रेशन के साथ काम करता है: उदा:

import pingouin as pg
# Using a Pandas DataFrame `df`:
lm = pg.linear_regression(df[['x', 'z']], df['y'])
# Using a NumPy array:
lm = pg.linear_regression(X, y)

आउटपुट बीटा गुणांक, मानक त्रुटियां, टी-मान, पी-मान और प्रत्येक भविष्यवक्ता के लिए आत्मविश्वास अंतराल, साथ ही साथ आर ^ 2 और फिट के आर ^ 2 के साथ एक डेटाफ्रेम है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.