从计数计算 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-Gene
或 Gene-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
我需要为生物实体的共现计算 PMI 分数,例如Gene A - Gene B
,或 Gene C - Disease A
。从 Pubtator 中提取了共现。我用 Python 3.
对于一组文档,我按共现类别提取了所有实体的个体计数 freq(x)
和 freq(y)
,例如Gene-Gene
或 Gene-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