从计数计算 PMI 的策略:数据帧或矩阵

Strategy for computing PMI from counts: dataframes or matrices

我需要为生物实体的共现计算 PMI 分数,例如Gene A - Gene B,或 Gene C - Disease A。从 Pubtator 中提取了共现。我用 Python 3.

对于一组文档,我按共现类别提取了所有实体的个体计数 freq(x)freq(y),例如Gene-GeneGene-Disease,我有实体对的共现计数 freq(x,y)。所有计数都存储在 Dict 中。

从原始计数计算逐点互信息 (PMI) 分数的最佳方法是什么:

假设一组数据有 3 列:entity, category, count,另一组数据有 4 列:entity_a, category, entity_b, count,其中类别表示共现类别。我需要单个实体计数的类别,因为如果我要使用它们的总计数,它会扭曲给定共现类型的结果。

我已经尝试过数据框方法,但无法找到一种方法来创建一个新的 PMI 列,该列使用两个不同的数据框 (DF) 计算结果,因此我认为也许矩阵方法可能效果更好?如果是,为什么?

转换为 DF 的数据示例:

df1.head():

ent rel count 177 5197 Gene_Gene 2 176 56744 Gene_Gene 2 175 12766 Gene_Gene 2 174 3091 Gene_Gene 2 173 3162 Gene_Gene 2

df2.head():

ent_a rel ent_b count 247 5197 Gene_Gene 56744 1 246 12766 Gene_Gene 5197 1 245 12766 Gene_Gene 56744 1 244 3091 Gene_Gene 3162 1 243 3091 Gene_Gene 54583 1

PMI 公式:

我发现对我有用的策略包括同时使用数据帧 (DF) 和 numpy 数组。

第一步,DF 可用于查找和填充 df2 同现实体各自的计数。然后,在第二步中,使用 numpy 数组有效地计算每个同时出现的(近似)PMI 分数。

第 1 步:查找个人计数

  • 首先拆分同时出现的实体并将每个实体添加到一个新列中,例如:

    df_ab['ent_a'] = df_ab.ent_ab.apply(lambda x: x.split('-')[0])

  • 然后调用查找函数来获取个人计数,例如:

    df_ab['ent_a_count'] = df_ab.ent_a.apply(get_ent, args=(df_a, 'ent_a', ))

    查找函数如下所示:

    def get_ent(ent_df_ab, df_a, colname_df_ab): row_df_a = df_a[df_a[colname_df_ab] == ent_df_ab] i = row_df_a.iloc[0]['count'] return i

df2 现在看起来像这样

```
        ent_ab  count_ab       type  ent_a  ent_b  ent_a_count  ent_b_count
0   5197-56744         2  Gene_Gene   5197  56744            2            2
1   12766-5197         1  Gene_Gene  12766   5197            2            1
2  12766-56744         1  Gene_Gene  12766  56744            2            2
3    3091-3162         4  Gene_Gene   3091   3162            6            1
4   3091-54583         2  Gene_Gene   3091  54583            6            1
```

第 2 步:矢量化 PMI 计算

  • 用于计算分数的基于数组的 numpy 函数

    def compute_pmi(df): count_ab = np.array(df[['count_ab']]) ent_a_count = np.array(df[['ent_a_count']]) ent_b_count = np.array(df[['ent_b_count']]) pmi = np.round(count_ab / (ent_a_count * ent_b_count), 3) df['pmi'] = pmi return df