복붙노트

[PYTHON] 통계적 유의성과 판다 열 상관 관계

PYTHON

통계적 유의성과 판다 열 상관 관계

df.1과 df.2 열 사이의 상관 관계를 얻기 위해 판다 데이터 프레임 df가 주어 졌을 때 가장 좋은 방법은 무엇입니까?

pandas가 내장 된 상관 관계가있는 NaN을 사용하여 출력 결과를 계산하지 않기를 바랍니다. 그러나 pvalue 또는 표준 오류를 출력하기를 원합니다.이 오류는 기본 제공되지 않습니다.

SciPy는 NaN에 의해 ​​잡힐 것 같지만, 중요성을보고한다고 생각합니다.

데이터 예 :

     1           2
0    2          NaN
1    NaN         1
2    1           2
3    -4          3
4    1.3         1
5    NaN         NaN

해결법

  1. ==============================

    1.@Shashank가 제공 한 답변은 훌륭합니다. 그러나 순수한 팬더의 솔루션을 원한다면 다음과 같이 할 수 있습니다.

    @Shashank가 제공 한 답변은 훌륭합니다. 그러나 순수한 팬더의 솔루션을 원한다면 다음과 같이 할 수 있습니다.

    import pandas as pd
    from pandas.io.data import DataReader
    from datetime import datetime
    import scipy.stats  as stats
    
    
    gdp = pd.DataFrame(DataReader("GDP", "fred", start=datetime(1990, 1, 1)))
    vix = pd.DataFrame(DataReader("VIXCLS", "fred", start=datetime(1990, 1, 1)))
    
    #Do it with a pandas regression to get the p value from the F-test
    df = gdp.merge(vix,left_index=True, right_index=True, how='left')
    vix_on_gdp = pd.ols(y=df['VIXCLS'], x=df['GDP'], intercept=True)
    print(df['VIXCLS'].corr(df['GDP']), vix_on_gdp.f_stat['p-value'])
    

    결과 :

    -0.0422917932738 0.851762475093
    

    통계 함수와 같은 결과 :

    #Do it with stats functions. 
    df_clean = df.dropna()
    stats.pearsonr(df_clean['VIXCLS'], df_clean['GDP'])
    

    결과 :

      (-0.042291793273791969, 0.85176247509284908)
    

    더 많은 변수로 확장하기 위해 나는 추한 루프 기반 접근법을 제공한다.

    #Add a third field
    oil = pd.DataFrame(DataReader("DCOILWTICO", "fred", start=datetime(1990, 1, 1))) 
    df = df.merge(oil,left_index=True, right_index=True, how='left')
    
    #construct two arrays, one of the correlation and the other of the p-vals
    rho = df.corr()
    pval = np.zeros([df.shape[1],df.shape[1]])
    for i in range(df.shape[1]): # rows are the number of rows in the matrix.
        for j in range(df.shape[1]):
            JonI        = pd.ols(y=df.icol(i), x=df.icol(j), intercept=True)
            pval[i,j]  = JonI.f_stat['p-value']
    

    rho의 결과 :

                 GDP    VIXCLS  DCOILWTICO
     GDP         1.000000 -0.042292    0.870251
     VIXCLS     -0.042292  1.000000   -0.004612
     DCOILWTICO  0.870251 -0.004612    1.000000
    

    pval의 결과 :

     [[  0.00000000e+00   8.51762475e-01   1.11022302e-16]
      [  8.51762475e-01   0.00000000e+00   9.83747425e-01]
      [  1.11022302e-16   9.83747425e-01   0.00000000e+00]]
    
  2. ==============================

    2.scipy.stats 상관 함수를 사용하여 p 값을 얻을 수 있습니다.

    scipy.stats 상관 함수를 사용하여 p 값을 얻을 수 있습니다.

    예를 들어 pearson 상관 관계 분석과 같은 상관 관계를 찾고있는 경우 pearsonr 함수를 사용할 수 있습니다.

    from scipy.stats import pearsonr
    pearsonr([1, 2, 3], [4, 3, 7])
    

    산출물을 제공합니다.

    (0.7205766921228921, 0.48775429164459994)
    

    튜플의 첫 번째 값은 상관 값이고 두 번째 값은 p- 값입니다.

    귀하의 경우, pandas의 dropna 함수를 사용하여 NaN 값을 먼저 제거 할 수 있습니다.

    df_clean = df[['column1', 'column2']].dropna()
    pearsonr(df_clean['column1'], df_clean['column2'])
    
  3. ==============================

    3.한 번에 모든 p- 값을 계산하려면 다음 calculate_pvalues ​​함수를 사용할 수 있습니다.

    한 번에 모든 p- 값을 계산하려면 다음 calculate_pvalues ​​함수를 사용할 수 있습니다.

    df = pd.DataFrame({'A':[1,2,3], 'B':[2,5,3], 'C':[5,2,1], 'D':['text',2,3] })
    calculate_pvalues(df)
    
    from scipy.stats import pearsonr
    import pandas as pd
    
    def calculate_pvalues(df):
        df = df.dropna()._get_numeric_data()
        dfcols = pd.DataFrame(columns=df.columns)
        pvalues = dfcols.transpose().join(dfcols, how='outer')
        for r in df.columns:
            for c in df.columns:
                pvalues[r][c] = round(pearsonr(df[r], df[c])[1], 4)
        return pvalues
    
  4. ==============================

    4.

    rho = df.corr()
    rho = rho.round(2)
    pval = calculate_pvalues(df) # toto_tico's answer
    # create three masks
    r1 = rho.applymap(lambda x: '{}*'.format(x))
    r2 = rho.applymap(lambda x: '{}**'.format(x))
    r3 = rho.applymap(lambda x: '{}***'.format(x))
    # apply them where appropriate
    rho = rho.mask(pval<=0.1,r1)
    rho = rho.mask(pval<=0.05,r2)
    rho = rho.mask(pval<=0.01,r3)
    rho
    # note I prefer readability over the conciseness of code, 
    # instead of six lines it could have been a single liner like this:
    # [rho.mask(pval<=p,rho.applymap(lambda x: '{}*'.format(x)),inplace=True) for p in [.1,.05,.01]]
    

  5. ==============================

    5.함수에서 논리를 합산하려고 시도했지만, 가장 효율적인 접근 방식은 아니지만 pandas df.corr ()과 비슷한 출력을 제공합니다. 이를 사용하려면 코드에 다음 함수를 넣고 데이터 프레임 객체를 제공하십시오. corr_pvalue (your_dataframe).

    함수에서 논리를 합산하려고 시도했지만, 가장 효율적인 접근 방식은 아니지만 pandas df.corr ()과 비슷한 출력을 제공합니다. 이를 사용하려면 코드에 다음 함수를 넣고 데이터 프레임 객체를 제공하십시오. corr_pvalue (your_dataframe).

    나는 당신이 다른 출력을 원할 경우를 대비하여 소수점 이하 4 자리로 반올림했습니다.

    from scipy.stats import pearsonr
    import numpy as np
    import pandas as pd
    
    def corr_pvalue(df):
    
    
        numeric_df = df.dropna()._get_numeric_data()
        cols = numeric_df.columns
        mat = numeric_df.values
    
        arr = np.zeros((len(cols),len(cols)), dtype=object)
    
        for xi, x in enumerate(mat.T):
            for yi, y in enumerate(mat.T[xi:]):
                arr[xi, yi+xi] = map(lambda _: round(_,4), pearsonr(x,y))
                arr[yi+xi, xi] = arr[xi, yi+xi]
    
        return pd.DataFrame(arr, index=cols, columns=cols)
    

    나는 pandas v0.18.1로 테스트했습니다.

  6. ==============================

    6.그것은 oztalha가 작성한 매우 유용한 코드입니다. r이 중요하지 않은 곳에서는 형식을 변경했습니다 (2 자리로 반올림 됨).

    그것은 oztalha가 작성한 매우 유용한 코드입니다. r이 중요하지 않은 곳에서는 형식을 변경했습니다 (2 자리로 반올림 됨).

        rho = data.corr()
        pval = calculate_pvalues(data) # toto_tico's answer
        # create three masks
        r1 = rho.applymap(lambda x: '{:.2f}*'.format(x))
        r2 = rho.applymap(lambda x: '{:.2f}**'.format(x))
        r3 = rho.applymap(lambda x: '{:.2f}***'.format(x))
        r4 = rho.applymap(lambda x: '{:.2f}'.format(x))
        # apply them where appropriate --this could be a single liner
        rho = rho.mask(pval>0.1,r4)
        rho = rho.mask(pval<=0.1,r1)
        rho = rho.mask(pval<=0.05,r2)
        rho = rho.mask(pval<=0.01,r3)
        rho
    
  7. ==============================

    7.@toto_tico 및 @ Somendra-joshi의 멋진 답변. 그러나 불필요한 NAs 값은 삭제됩니다. 이 스 니펫에서는 현재 계산중인 상관 관계에 속하는 NA를 그냥 삭제합니다. 실제 corr 구현에서는 동일하게 수행됩니다.

    @toto_tico 및 @ Somendra-joshi의 멋진 답변. 그러나 불필요한 NAs 값은 삭제됩니다. 이 스 니펫에서는 현재 계산중인 상관 관계에 속하는 NA를 그냥 삭제합니다. 실제 corr 구현에서는 동일하게 수행됩니다.

    def calculate_pvalues(df):
        df = df._get_numeric_data()
        dfcols = pd.DataFrame(columns=df.columns)
        pvalues = dfcols.transpose().join(dfcols, how='outer')
        for r in df.columns:
            for c in df.columns:
                if c == r:
                    df_corr = df[[r]].dropna()
                else:
                    df_corr = df[[r,c]].dropna()
                pvalues[r][c] = pearsonr(df_corr[r], df_corr[c])[1]
        return pvalues
    
  8. from https://stackoverflow.com/questions/25571882/pandas-columns-correlation-with-statistical-significance by cc-by-sa and MIT license