我有一个包含专业和媒体列的 df。我想计算这两列之间的相关性。
是否有计算字符串列相关性的简短技巧?或者我是否将每个职业和媒体转换为一个数字,然后计算与 .corr() 的相关性?
我发现了一个类似的问题(有没有办法获得字符串数据和pandas中的数值的相关性?)但我想检查字符串,而不是字符串中的每个单词。
df
profession media
0 media lawyer print
1 student online
2 student print
3 professor online
4 media lawyer online
您可以将数据类型转换为分类类型,然后执行此操作
df['profession']=df['profession'].astype('category').cat.codes
df['media']=df['media'].astype('category').cat.codes
df.corr()
正如 @JAgustinBarrachina 指出的那样,接受的答案引入了偏差,因为它在幕后使用了皮尔逊相关方法。 每列的分类可能会产生以下结果:
因为 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)