计算字符串列之间的相关性

问题描述 投票:0回答:2

我有一个包含专业和媒体列的 df。我想计算这两列之间的相关性。

是否有计算字符串列相关性的简短技巧?或者我是否将每个职业和媒体转换为一个数字,然后计算与 .corr() 的相关性?

我发现了一个类似的问题(有没有办法获得字符串数据和pandas中的数值的相关性?)但我想检查字符串,而不是字符串中的每个单词。

df

  profession        media      

0 media lawyer      print
1 student           online
2 student           print
3 professor         online
4 media lawyer      online
python python-3.x pandas string correlation
2个回答
36
投票

您可以将数据类型转换为分类类型,然后执行此操作

df['profession']=df['profession'].astype('category').cat.codes
df['media']=df['media'].astype('category').cat.codes
df.corr()

0
投票

正如 @JAgustinBarrachina 指出的那样,接受的答案引入了偏差,因为它在幕后使用了皮尔逊相关方法。 每列的分类可能会产生以下结果:

  • 媒体律师 --> 0
  • 学生 --> 1
  • 教授 --> 2

因为 Pearson 方法计算线性相关性,所以它会计算每个类别之间的距离。从算法的角度来看,a

media lawyer
professor
(它们的距离为 2 - 0 = 2)的差异要大于它与
student
(1 - 0 = 1)的差异。在这种情况下情况并非如此,因此所得的相关性将会有偏差。

从文档中还有其他 2 种相关方法可用:Kendall 和 Spearman 方法。但他们都认为类别是有序的。 例如,诸如

revenue : ["low", "medium", "high"]
之类的类别可以被视为有序。

如果列的类别之间没有顺序,则使用 Chi² 和 Cramér V 的方法更合适:

import scipy.stats as ss
import pandas as pd
from pandas import DataFrame, Series

profession_and_media = DataFrame(data = {
    # Decupling data to simulate significance
    "profession" : ["media lawyer" , "student" , "student" , "professor" , "media lawyer"] * 10,
    "media" : ["print" , "online" , "print" , "online" , "online"] * 10
    })

def cramers_corrected_stat(columnA: Series, columnB: Series):
    """ calculate Cramers V statistic for categorial-categorial association.
        uses correction from Bergsma and Wicher, 
        Journal of the Korean Statistical Society 42 (2013): 323-328
    """
    confusion_matrix = pd.crosstab(columnA, columnB)
    chi2 = ss.chi2_contingency(confusion_matrix)[0]
    n = confusion_matrix.to_numpy().sum(axis=None)
    phi2 = chi2/n
    r,k = confusion_matrix.shape
    phi2corr = max(0, phi2 - ((k-1)*(r-1))/(n-1))    
    rcorr = r - ((r-1)**2)/(n-1)
    kcorr = k - ((k-1)**2)/(n-1)
    return np.sqrt(phi2corr / min( (kcorr-1), (rcorr-1)))


def compute_category_correlation(df: DataFrame):
    """ Compute the correlation between string columns of a DataFrame
    """
    for column in df.columns:
        df.loc[:, column] = df[column].astype('category').cat.codes
    result = df.corr(method=cramers_corrected_stat)
    return result.style.background_gradient(cmap='Reds')

compute_category_correlation(profession_and_media)

这给出了

© www.soinside.com 2019 - 2024. All rights reserved.