一、开发环境
1.语言:python
2.开源工具:nltk
3.语料库:维基百科英文语料库
二、环境配置
关于pyhton项目对nltk的部署,我看了以下文章。
在安装nltk库的过程中,我又遇到了pip更新的问题,看了以下文章。
三、实验要求
利用n-gram语言模型完成,输入文字时的推荐功能,一个单词时推荐1-gram统计词频最大的前五个,两个单词时看前一个单词和当前单词的2-gram得分最高的前五个,已输入第三个单词时看前两个单词与当前单词的3-gram得分最高的前五个,最多看3-gram。
四、分析与实现
根据以上计算公式,得出,当已输入词大于等于1时,以使用tri-gram模型进行推荐为例,假设已输入的词分别为A,B,语料库中其他的单词为X,所以只计算,找出其中最大的前五个单词X。由于分子相同,所以只比较分母。以下是实现的代码。
import re
from collections import Counter
from nltk.tokenize import word_tokenize
from collections import defaultdict
text_file = 'wiki01.txt'
# 读取文件内容
with open(text_file, 'r', encoding='utf-8') as file:
text = file.read()
# 使用正则表达式去除标点符号
text = re.sub(r'[^\w\s]', '', text)
# 分词
tokens = word_tokenize(text)
# 第一次推荐
def uni_gram():
word_counts = Counter(tokens)
# 输出词频最高的前五个单词
for word, count in word_counts.most_common(5):
print(f"推荐:{word}")
# 第二次推荐
def bi_gram(A):
word_pairs_counts = defaultdict(int)
# 遍历分词后的列表,找到包含目标单词A的词对
for i in range(len(tokens) - 1):
if tokens[i].lower() == A.lower(): # 忽略大小写比较
# 词对是(A,后一个词)
if i > 0 and i < len(tokens)-1:
word_pairs_counts[(A, tokens[i + 1])] += 1
if not word_pairs_counts:
print("未找到合适的推荐")
else:
# 输出频率最高的前五个词对
top_pairs = sorted(word_pairs_counts.items(), key=lambda x: x[1], reverse=True)[:5]
# 如果频率最高的词对个数不足五个,输出提示信息
if len(top_pairs) < 5:
print("合适的推荐不足五个,只找到以下推荐:")
for pair, count in sorted(word_pairs_counts.items(), key=lambda x: x[1], reverse=True)[:5]:
print(f"推荐:({pair[0]} {pair[1]})")
else:
for pair, count in sorted(word_pairs_counts.items(), key=lambda x: x[1], reverse=True)[:5]:
print(f"推荐:({pair[0]} {pair[1]})")
def tri_gram(A,B):
tri_word_pairs_counts = defaultdict(int)
# 遍历分词后的列表,找到同时包含A和B,且顺序为A, B, C的词对
for i in range(len(tokens) - 2):
if tokens[i].lower() == A.lower() and tokens[i + 1].lower() == B.lower():
# 三词词对是(A, B, C)
tri_word_pairs_counts[(tokens[i], tokens[i + 1], tokens[i + 2])] += 1
# 输出频率最高的前五个三词词对
if not tri_word_pairs_counts:
print("未找到合适的推荐")
else:
# 输出频率最高的前五个三词词对
top_pairs = sorted(tri_word_pairs_counts.items(), key=lambda x: x[1], reverse=True)[:5]
# 如果频率最高的词对个数不足五个,输出提示信息
if len(top_pairs) < 5:
print("合适的推荐不足五个,只找到以下推荐:")
for pair, count in sorted(tri_word_pairs_counts.items(), key=lambda x: x[1], reverse=True)[:5]:
print(f"推荐 ({pair[0]}, {pair[1]}, {pair[2]})")
else:
for pair, count in sorted(tri_word_pairs_counts.items(), key=lambda x: x[1], reverse=True)[:5]:
print(f"推荐 ({pair[0]}, {pair[1]}, {pair[2]})")
def main():0
# 主程序代码
uni_gram()
word_list = []
while True:
word = input("请输入一个单词(输入'0'结束): ")
if word == '0':
break
word_list.append(word) # 将单词添加到列表中
length = len(word_list)
if length == 1:
bi_gram(word_list[0])
else:
tri_gram(word_list[length-2],word_list[length-1])
# 检查脚本是否作为主程序运行(而不是被导入为模块)
if __name__ == "__main__":
main()
五、实验结果
为了方便测试,我只截取了维基英文语料库中的一部分作为本次实验的语料库。实验结果如下:当已输入单词超过两个时,一直使用tri-gram模型进行推荐,由于在前两个单词的影响下,有时会无法在语料库中找到足够的合适的推荐(与语料库的大小有关)。
六、语料库资源下载
链接:https://pan.baidu.com/s/1HKvYn974fiuX0QgZ2hOmDA
提取码:qtra
感谢观看,希望对你有帮助!
标签:pairs,word,语料库,单词,源码,gram,pair,counts From: https://blog.csdn.net/weixin_62284803/article/details/139373412