blog13 使用最大边际相关性的核心方法返回排名前N的嵌入候选词(2)

2021SC@SDUSC

method.py:

通过返回最接近文档嵌入的N个候选短语,嵌入排名只考虑了短语的信息性属性,从而导致了冗余的关键短语。在用户直接看到提取的关键短语的场景中(例如,文本摘要、搜索标签),这是有问题的,因为冗余的关键短语会对用户的体验产生不利影响。这可能会恶化到提供关键字变得完全无用的地步。
此外,如果我们提取固定数量的顶级关键字,冗余会阻碍提取的关键字的多样化。提取的关键字包括拓扑形状、拓扑形状、分子等价数、分子等价数、分子等价指标等。也就是说,十个关键短语“插槽”中有四个被多余的短语使用。
这类似于搜索结果多样化,其中搜索引擎平衡了查询-文档相关性和文档多样性。最简单和最有效的解决方案之一是最大边际相关性(MMR)度量,它以一种可控的方式结合了相关性和多样性的概念。我们展示了如何将MMR适应于关键字提取,以结合关键字信息量与所选关键语之间的不相似性。来自信息检索和文本摘要的原始MMR基于给定输入查询Q的所有初始检索文档的集合R,以及初始空的集合S,这些文档被选择为Q的良好答案。S通过计算MMR迭代填充,其中 D i D_i Di D j D_j Dj是检索到的文档,而Sim1和Sim2是相似性函数。
在这里插入图片描述
当λ=1MMR计算一个标准的、相关性排序的列表,而当λ=0时,它计算r中文档的最大多样性排序。为了在这里使用MMR,我们将原始方程调整为:
在这里插入图片描述
其中C为候选关键语集,K为提取的关键语集,doc为完整的文档嵌入,Ci和Cj分别为候选短语i和j的嵌入。最后,gcossim是一个归一化的余弦相似度(Mori和Sasaki,2003),由以下方程描述。这确保了,当λ=0.5时,方程中的相关性和多样性部分具有同等的重要性。
在这里插入图片描述
我们对候选短语之间的相似性应用了一个类似的变换。
综上所述,上一节的方法相当于使用MMR从带有λ=1的公式(2)中提取关键字。算法的广义版本EmbedRank++保持不变,除了最后一步,我们使用公式(2)执行N个候选项的最终选择,因此同时返回相关和不同的关键短语,由权衡参数λ调优。

对源码的分析:
(1)def _MMR(embdistrib, text_obj, candidates, X, beta, N, use_filtered, alias_threshold)函数:核心方法利用最大边际相关性负责返回前n的候选词。
参数说明:
embdistrib:嵌入分发器,请参见@嵌入分发器。
text_obj:text_obj:输入文本表示,请参见@InputTextObj。
candidates:候选词名单(字符串)。
X:在每行的Numpy数组与嵌入的每个候选项。
beta:MMR的超参数测试(信息量和多样性之间的控制权衡)。
N:要提取的候选词的数量。
use_filtered:如果为真,则在计算文档嵌入之前只保留候选单词来过滤文本。
返回值:一个包含三个元素的元组
(1)前N候选人列表(如果没有足够的候选人,则更少)(字符串列表)
(2)关联的相关性得分列表(浮动列表)
(3)列表,其中包含每个关键字的别名列表(字符串列表的列表)

def _MMR(embdistrib, text_obj, candidates, X, beta, N, use_filtered, alias_threshold):
   
    N = min(N, len(candidates))
    doc_embedd = extract_doc_embedding(embdistrib, text_obj, use_filtered)  # Extract doc embedding
    doc_sim = cosine_similarity(X, doc_embedd.reshape(1, -1))

    doc_sim_norm = doc_sim/np.max(doc_sim)
    # np.std:将数组当作扁平化数组,并计算扁平化数组的标准差。
    doc_sim_norm = 0.5 + (doc_sim_norm - np.average(doc_sim_norm)) / np.std(doc_sim_norm)

    sim_between = cosine_similarity(X)
    np.fill_diagonal(sim_between, np.NaN)

    sim_between_norm = sim_between/np.nanmax(sim_between, axis=0)
    sim_between_norm = \
        0.5 + (sim_between_norm - np.nanmean(sim_between_norm, axis=0)) / np.nanstd(sim_between_norm, axis=0)

    selected_candidates = []    # 被选中的候选词
    unselected_candidates = [c for c in range(len(candidates))] # 没被选中的候选词

    j = np.argmax(doc_sim)  # 取出doc_sim中的最大值的索引
    selected_candidates.append(j)
    unselected_candidates.remove(j)

    for _ in range(N - 1):
        selec_array = np.array(selected_candidates)
        unselec_array = np.array(unselected_candidates)

        distance_to_doc = doc_sim_norm[unselec_array, :]
        dist_between = sim_between_norm[unselec_array][:, selec_array]
        if dist_between.ndim == 1:
            dist_between = dist_between[:, np.newaxis]
        j = np.argmax(beta * distance_to_doc - (1 - beta) * np.max(dist_between, axis=1).reshape(-1, 1))
        item_idx = unselected_candidates[j]
        selected_candidates.append(item_idx)
        unselected_candidates.remove(item_idx)

    # Not using normalized version of doc_sim for computing relevance
    relevance_list = max_normalization(doc_sim[selected_candidates]).tolist()
    aliases_list = get_aliases(sim_between[selected_candidates, :], candidates, alias_threshold)

    return candidates[selected_candidates].tolist(), relevance_list, aliases_list

(2)def MMRPhrase(embdistrib, text_obj, beta=0.65, N=10, use_filtered=True, alias_threshold=0.8)函数:提取N个关键短语。

def MMRPhrase(embdistrib, text_obj, beta=0.65, N=10, use_filtered=True, alias_threshold=0.8):
   
    candidates, X = extract_candidates_embedding_for_doc(embdistrib, text_obj)

    if len(candidates) == 0:
        warnings.warn('No keyphrase extracted for this document')
        return None, None, None

    return _MMR(embdistrib, text_obj, candidates, X, beta, N, use_filtered, alias_threshold)

(3)def MMRSent(embdistrib, text_obj, beta=0.5, N=10, use_filtered=True): 提取N个关键句子。

def MMRSent(embdistrib, text_obj, beta=0.5, N=10, use_filtered=True):
   
    candidates, X = extract_sent_candidates_embedding_for_doc(embdistrib, text_obj)

    if len(candidates) == 0:
        warnings.warn('No keysentence extracted for this document')
        return []

    return _MMR(embdistrib, text_obj, candidates, X, beta, N, use_filtered)

(4)def max_normalization(array)函数:计算数组的最大归一化值(最大值设置为1)
参数说明:
array:1-d数组。
返回值:
1-d array max- normalized:每个值乘以1/最大值。

def max_normalization(array):
   
    return 1/np.max(array) * array.squeeze(axis=1)

(5)def get_aliases(kp_sim_between, candidates, threshold)函数:找到与关键词(别名)非常相似的候选词。
参数说明:
kp_sim_between:形状的ndarray(nb_kp,nb候选)包含每个kp与所有候选p的相似性。请注意,关键短语和它本身之间的相似性应该设置为NaN或0。
candidates:候选字符串数组(字符串数组)。
返回值:包含每个关键短语的列表,其中包含别名(非常相似)的候选列表(字符串列表的列表)。

def get_aliases(kp_sim_between, candidates, threshold):

    kp_sim_between = np.nan_to_num(kp_sim_between, 0)
    idx_sorted = np.flip(np.argsort(kp_sim_between), 1)
    aliases = []
    for kp_idx, item in enumerate(idx_sorted):
        alias_for_item = []
        for i in item:
            if kp_sim_between[kp_idx, i] >= threshold:
                alias_for_item.append(candidates[i])
            else:
                break
        aliases.append(alias_for_item)
    return aliases
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值