SWE · Coding

下一词预测:一次处理语料后按频次查后继

map of maps存bigram计数,静态数据可预计算最佳后继。

题目重点:map of maps存bigram计数,静态数据可预计算最佳后继。

题意与假设

这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。

  • 输入为已分词的sentence列表,不跨句边界计转移;大小写/标点归一化由调用方确定。
  • 返回最多频后继,并列字典序最小;无后继词不在结果map里,查询时需定义unknown。

解题路线

  1. 每句相邻词(a,b)更新counts[a][b]。句尾不与下一句开头连接,避免伪造语言关系。
  2. 全部静态数据处理完后,每a扫描后继取最大count及稳定tie,预存best[a]使query期望O(1)。
  3. 动态更新才需要维护每词最高频及tie,删除事件可能让旧冠军下降,届时可用有序结构或重扫。不要为静态最大值强行维护每词堆。

手动走一遍

句["we","like","tea"]和["we","like","coffee"]:we最佳like;like两个后继并列选coffee。单词句无bigram;不同句之间tea→we不计。

Python 参考实现

下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。

代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。

from collections import Counter


def predictor(sentences):
    counts={}
    for sentence in sentences:
        for a,b in zip(sentence,sentence[1:]):counts.setdefault(a,Counter())[b]+=1
    return {a:min(counter,key=lambda b:(-counter[b],b)) for a,counter in counts.items()}

复杂度

总token L建表期望O(L),后处理O(E),E不同bigram;存储O(E+V)。预计算后单query期望O(1)。

易错点与追问

容易失分的边界

  • 用出现总频最高的词代替当前词的条件后继。
  • 真实语言模型不止一个前词,bigram只是本接口统计,不代表完整NLP能力。

继续深挖

  • 改为topK后继,预排序与每query heap成本如何比较?
  • 时间衰减频次怎样避免每条查询更新所有历史计数?
✓已复制微信号!