Day08【基于FAQ实现单轮问答系统】

目的

本文实现了一个基于FAQ知识库和文本匹配算法的问答系统,核心目的是根据用户输入的问题(user_query),通过不同的文本匹配算法(例如BM25、Word2Vec等)从知识库中找到最相关的答案。以下是代码的详细解释:

1. QASystem 类

这是问答系统的核心类,包含了各种方法来加载知识库、处理问题,并基于不同的算法进行查询。

初始化类
    def __init__(self, know_base_path, algo):
        '''
        :param know_base_path: 知识库文件路径
        :param algo: 选择不同的算法
        '''
        self.load_know_base(know_base_path)
        self.algo = algo
        if algo == "bm25":
            self.load_bm25()
        elif algo == "word2vec":
            self.load_word2vec()
        else:
            #其余的算法不需要做事先计算
            pass
  • 作用:初始化问答系统对象,加载指定路径的知识库,并根据所选的算法进行初始化。
  • 参数
    • know_base_path:指定知识库文件的路径,知识库是一个包含多个问题和目标(或答案)对的JSON文件。
    • algo:选择文本匹配算法,目前支持的算法包括 "bm25""word2vec""editing_distance""jaccard_distance"
      根据算法选择,分别调用了load_bm25()load_word2vec()方法加载相关的模型,其他算法不需要额外的计算。
加载知识库文件
    def load_know_base(self, know_base_path):
        self.target_to_questions = {}
        with open(know_base_path, encoding="utf8") as f:
            for index, line in enumerate(f):
                content = json.loads(line)
                questions = content["questions"]
                target = content["target"]
                self.target_to_questions[target] = questions
        return
  • 作用:加载知识库文件,将知识库中的问题和目标(答案)存储到self.target_to_questions字典中。
  • 实现:该方法通过打开并读取JSON文件,每一行包含问题列表和对应的目标(即问题的答案或类别)。它将目标和问题对存储在字典中,键是目标,值是对应的多个问题。

加载的数据文件data/train.json

{"questions": ["问一下我的电话号", "办理业务", "办理相关业务", "我收到一个信息是怎么回事", "正常业务", "我想咨询电信业务", "就是这个电话", "我想要个手机", "那个电话", "电信业务", "我的号", "中国电信", "电信服务", "个人业务", "电信号码", "查一下我的号码", "可以办理什么业务", "都有什么业务可以办理"], "target": "宽泛业务问题"}
{"questions": ["查一下我的话费", "报一下话费", "给我说一下话费", "查话费", "查手机费", "我的手机话费", "查一下话费", "查询手机话费", "给我查一下话费", "查询我的手机费", "查话费语音告诉我", "查一下话费以语音的方式通知我", "用语音告诉我话费用了多少", "查话费的结果语音报给我", "我需要查询话费语音报一下", "通过语音查电话费用", "通过语音提示进行打电话的费用查询", "拨通客服电话查下通话的消费", "语音查下打电话用掉的钱数", "我想要查话费", "查一下电话费", "如何查询手机话费", "查询电话费用", "查询一下话费详情", "看一下我用了多少话费", "查看话费使用情况", "话费怎么查", "播报一下我的话费是多少", "告诉我通话的费用是多少", "查话费按几号键", "我想查一下我的话费", "查我话费钱", "我的话费怎么查", "能查我手机话费吗", "我话费的情况", "我的话费给我报一下", "想知道我的话费情况", "请问打什么电话可以查询话费", "帮我看看我的话费", "我想看看话费使用情况", "语音播报话费使用情况", "我想通过语音查话费", "查话费报一下", "看一下通话费用", "我的电话费是多少", "电话费用有多少", "打电话查话费需要通过人工台吗", "查消费记录", "帮我看一下有没有扣费", "号码是怎么消费的", "都是有什么消费呀", "我这个手机都有什么费用", "给我查一下我的消费", "给我查个话费", "手机每个月消费多少钱", "我不知道话费是怎么产生的", "话费多少钱", "我想咨询看我的话费", "我想问一下我手机话费", "我想问一下我手机上这个话费", "查询话费花了多少钱", "怎么操作查话费", "如何查询我的话费", "我想查话费", "帮我查一下我的话费", "打电话查话费具体怎么操作", "查询手机消费情况", "查询我花了多少钱", "交易话费", "我想查询短信的话费", "查查话费", "通话费", "我想查一下手机话费", "可以帮我查一下话费", "话费是多少", "语音话费可以查询", "打电话查话要通过人工台吗", "不是其他的我想查自己的话费", "话费单", "查我的话费", "查我的话费明细", "查话费明细", "话费明细", "查自己的话费", "给我发一下话费", "用短信发过来我的手机费", "给我发一个话费短信", "发给我一个短信查话费的", "用短信方式查询话费", "用短信给我发一下我的话费", "查我的话费短信发来", "给我的手机发一个话费短信", "给我发一条话费短信", "发给我一条话费的信息", "发给我一条查话费的短信", "怎么用短信查话费", "查询话费发什么短信", "短信查话费", "发条短信告诉我话费是多少", "用短信把我的话费查询结果发过来", "短信告知我话费金额", "用短信查打电话的费用", "编写短信怎么查通话费", "我要用短信查一下通话费", "用短信查看打电话使用的钱", "编短信查话费", "发短信多少能查话费", "用短消息查手机话费", "怎么发信息查电话费", "我想通过短信查手机话费", "把话费情况发短信给我", "短信怎么查话费", "可以给我发一个话费短信吗", "短信通知话费查询结果", "用短信查看话费的指令是多少", "给我转为短信查话费", "我想看话费详情的短信", "话费短信发我一下", "发什么短信能查话费", "怎样用短信查话费", "手机的话费请短信告知", "能不能发个短信列出来话费的情况", "话费都是啥发个短信给我", "话费具体情况你们发短信告诉我吧", "请问发送什么短信可以查询话费", "怎么通过短信查话费呀", "给我发一下话费我看看", "通过短信查一下话费", "查一下我的话费然后短信发给我", "通过短信怎么查话费", "给我发一下话费情况我看看", "给我发送一个话费明细", "查询话费可以通过发短信吗", "用短信把我的话费发过来", "短信查询我的消费情况", "发一条短信说明我的消费情况", "短信查查我的手机费", "发一下我的通讯费用", "短信告诉我话费查询的结果", "发个短信告诉我我的话费", "把我的话费情况用短信发过来", "用短信回复一下我的话费情况", "我的话费发到我的手机上", "帮我把话费情况能用短信发过来", "把我的话费发短信到我手机上", "我想短信查询话费", "话费用短信给我发过来", "我这个话费发个短信过来", "可以把我的话费信息短信发到我手机上吗", "话费用短信发我", "话费用短信发我给我发过来", "我想查一查话费给我短信告诉", "把我的话费用短信发过来", "我想查话费发个短信给我", "查话费短信发过来", "话费发到我的手机上", "发过的话费发到我的手机上", "我想查我的话费短信给我发过来", "查询别的号码的话费情况", "怎样查其他手机号码的话费", "我想查别人手机号的话费", "查一下别人号码的话费使用情况", "查我女儿的电话费", "给我查一下那个电话的话费", "能否查询别人手机费", "查一下其他人手机费", "查询一下别人的手机话费", "查一下别的手机号话费", "我想查询我另外一个手机号的话费", "怎么查询其他手机号话费", "想查一下我另一个手机号的话费", "报一下我小手机号的话费", "我工作的手机号不是这个能否查询话费", "怎么查询别的手机号的话费", "查非本机号码的话费", "查一个其他手机号的话费", "查询别的电话号码的话费", "怎么查非本机话费", "我要查其他手机号的话费金额", "能否帮其他电话查话费", "查一下我朋友的话费", "给我查查另外号码的话费", "查他人手机消费", "帮张丽查下通话费", "查询老公的电话消费", "帮同学查查手机消费钱数", "查话费不是查我的", "查下手机的费用帮别人查", "查看别人的话费账单", "替别人查话费", "查其他人的话费使用情况", "他人话费多少能查到吗", "查另外一个人的通话费用", "非本人费用账单查看", "换另外一个号码查费用花了多少钱", "可以查到其他人的话费吗", "非本机号码的话费", "不是我本人电话的话费怎么查", "怎么查其他号码的话费", "能不能查一下别人电话话费", "想知道另外一个号的话费情况", "我朋友的话费情况查询", "你们这里可以查其他电话话费吧", "查询我兄弟的电话费", "我想查一下另一个号码的话费", "其他电话的话费能不能帮我查一下", "我想查一下姐姐的话费可以吗", "是否可以查询其他电话的话费", "查询我妹妹的话费", "我想查我朋友的话费可以吗", "怎么查其他电话的话费", "查其他电话的话费要怎么操作", "查查其他电话的话费", "帮别人查询话费账单", "能帮我查一个电话的话费清单吗", "查询非本人电话的话费", "查一下李丽的话费", "网上能否查别人的话费", "要查别人的话费需要去营业厅吗", "查其他电话话费必须去营业厅吗", "能查别人的话费吗", "给我查一下另外一个手机的话费", "查一下其他手机的话费情况", "能查询其它电话的消费情况吗", "查一下别人手机号码的话费", "能帮我的同事查查手机费吗", "能不能查我女儿的手机的话费", "我想查别人电话的话费", "查一下一个手机号的电话费", "不是自己的我想查其他电话的话费", "我本月一共消费了多少", "我本月的话费明细", "我本月月租多少", "我这个月彩铃费多少", "我这个月打电话花了多少钱了", "我到今天为止一共花了多少钱", "我本月语音通话产生的费用一共是多少", "我这个月截止今天用了多少话费", "我本月的通话费花了多少钱", "帮我查一下我这个月的扣费情况", "这个月打长途花了多少钱", "我本月的市话费用是多少", "我到今天为止漫游花了多少钱", "我这个月一共花了多少钱", "我这个月发短信一共花了多少钱", "我这个月的彩信订阅花了多少钱", "我本月的音乐下载花了多少钱了", "查看一下我这个月的已收费用", "返回到实时话费查询菜单", "我这个月使用了多少流量", "我想查我这个月用了多少话费了", "这个月的话费使用查询", "查询现在话费的使用情况", "我现在话费用了多少了", "话费花了多少钱了现在", "查查我这个月话费花了多少", "我这个月话费使用超额了吗", "这个月电话费花了多少钱了", "本月话费花了多少钱", "这个月扣了多少费用", "月初到现在有多少话费", "这个月打了多少钱", "这周怎么有漫游费", "查询本月话费账单", "目前话费花费了多少钱", "需要知道本月费用情况", "我当前的通话费用是多少", "截止昨天的的话费是多少", "我的当月话费", "我这个月到现在使用了多少话费", "我这个月的长途费花了多少", "这个月有漫游费吗", "当月累计话费", "我的实时话费查询", "这个月我总共的话费", "当月话费金额", "月初到现在我的话费总支出", "我这个月话费用了多少", "帮我查一下到现在用的话费", "我的实时话费是多少钱", "查一下本月长途费", "我想查实时话费", "截止到目前本月短信费是多少", "查询这个月漫游费的金额", "本月固定费是几元查一下", "我想查本月实时话费金额", "本月我花了多少短信费", "刚刚的电话花了多少钱", "这个月流量超了多少", "长途费花了多少", "套餐被扣了多少钱", "当前的话费情况", "我这个卡这个月的消费情况", "这月用了多少话费", "本月消费金额", "当月话费情况", "当月消费情况", "本月实时话费", "本月话费有多少", "当前话费", "这月话费", "我想看看我这月的话费", "我目前的话费是多少", "怎么查我现在的话费", "我这个月话费多少", "查询本月话费", "这个月一共消费了多少钱", "我本月打了多少钱的电话", "本月话费消费怎么查", "想知道本月话费消费明细", "如何查询当月的话费支出", "告诉我本月话费支出情况", "怎么查找本月电话消费", "刚收到一短信扣我钱", "扣钱了帮我查一下", "怎么刚充了钱又没了", "有一个短信说扣费了帮我查一下", "一直在扣钱帮我查一查", "我的号码被扣费了", "为什么手机扣了那么多话费", "我那里面没有那个扣费呀", "我这个话费怎么扣了", "扣了十块钱怎么回事", "我想问一下怎么扣的费", "对扣费有疑问", "扣了很多钱是因为什么扣了", "你帮我查一下我那个话费怎么扣了", "我这个卡消费多少钱了", "订制了这个什么业务产生扣费了吗", "想查询一下我手机的当前话费", "实时查询话费", "查询实时话费", "查一下到现在的话费", "查一下实时话费", "能不能查询实时话费", "我查一下目前的话费", "截止到现在我的话费", "最新的话费情况", "实时话费查查", "到目前的实时话费怎么查询", "我本月话费用了多少", "查一下我的实时话费", "查询本月实时话费金额", "实时话费怎么查", "帮我查下我这个月话费使用情况", "查查我现在打长途的费用", "查询现在长途电话话费", "查询现在市话费消费情况", "我这个月打长途打了多少钱", "这个月有多少漫游费", "这个月话费超过一百没", "我手机这个月用了多少话费", "查一下刚才那通电话花了多少钱", "怎样查当前的话费", "查实时话费", "查我本月的话费", "这月手机一共扣了多少钱", "查询一下我的实时话费", "查询当前的话费消费记录", "我今天打电话用了多少钱", "查一下我本月消费的话费情况", "我手机这月消费多少了", "我手机这个月都是扣了什么钱", "我想查一下现在这个月用了多少费用了", "查一下我目前的话费", "今天为止我的话费使用情况", "给我查一下这个月扣了多少钱了", "查这个月我的话费花了多少", "这个月话费累计是多少", "查询我这个月花了多少钱", "查询我本月的账单", "查询我本月的通话费用", "查询实时话费怎么操作", "我这个月用了多少钱", "给我报一下我这个月用了多少话费", "我这个月一共用了多少话费", "我想知道这个月的话费帮我报一下吧", "帮我查一下这个月用了多少话费", "查一下近期的话费", "最近的话费明细查询", "本机实时话费查询", "怎么实时话费", "这两天是不是花了很多话费", "我想看我现在的话费", "实时的话费", "实时的话", "我这个月话费超50了吗", "怎么查实时话费", "我现在还有多少钱的话费", "现在的话费够打长途吗", "当前话费余额", "话费还剩多少", "再打一个漫游的会不会欠费", "现在话费余额足不足", "目前需不需要充值", "话费余额", "帮我查话费余额", "截止到现在话费余额多少", "目前话费余额是多少", "可用话费余额", "现在话费余额是多少", "现在还有多少话费余额", "目前话费剩余", "话费还剩多少钱", "我查了下我的话费金额不对", "我的话费余额怎么只剩这么点", "话费剩余", "我的话费目前剩多少", "我手机还剩多少话费", "我还需要充话费吗", "我手机卡里还有多少钱", "查下我是否需要充话费", "我账户里的钱够下月使用吗", "本月卡里还剩多少钱", "帮我查一下我的话费余额", "我手机卡里还有钱吗", "话费余额上哪查啊", "怎么知道自己的手机余额", "查看一下我的余额", "手机里还有没有话费", "你给我看一下我的余额", "我这个号码还有多少余额", "手机卡里还有多少话费", "给我查一下余额多少", "我余额有多少", "我话费余额是多少", "帮我查一下存话费了吗", "余额是多少钱", "这个月我余额有多少", "话费余额多少钱", "提示我说话费余额不足", "话费网上我充了钱有没有到账", "我这个卡里面还有多少话费", "我这个手机卡里面还有多少钱话费", "您能帮我查一下这部电话余额是多少", "查查还剩多少钱", "现在还剩多少话费", "我手机号还有话费吗", "我的电话还有多少话费", "报一下目前还有多少钱", "剩余的话费数额", "还剩几块钱话费", "我手机是不是钱快花完了", "我是不是手机费快用光了", "我手机号还有几块钱", "我要查话费余额", "查查截止到现在话费余额多少", "话费余额现在是多少", "我这个月还剩下多少话费", "电话费现在剩下多少钱", "我手机号还剩多少话费", "我手机还有多少钱没用", "我手机号还剩下几百块", "我手机号还剩下钱没", "我现在话费里还剩多少钱", "话费剩多少", "手机里还有多少话费", "刚充过话费怎么提示欠费了", "我还有多少话费余额", "直接告诉我话费余额是多少", "查一下自己账户话费的余额", "导航至话费查询菜单", "卡里钱还多吗", "卡里话费剩多少钱了", "卡里的话费余额还有多少", "卡里话费够不够交下月的月租", "我就是想知道我账户还有多少钱", "话费余额怎么查询", "手机话费余额多少", "我想查询卡里的话费还多少钱", "余额在哪里可以查到", "查一下我的话费还够吗", "如何查询电信话费余额", "我的账户还有多少余额", "我的余额还有多少", "能否查询话费的余额", "查余额要怎么操作", "我手机里现在有多少话费", "这个话费还够用吗", "查一下我的话费余额", "查一下手机里是多少钱", "我最近需不需要充话费", "我现在有欠费吗", "看下我话费需不需要交", "我上个月一共用了多少话费", "我上个月的消费明细", "我上个月总共花了多少钱的话费", "我上个月的话费使用情况", "查一下我前两个月的话费", "查一下我上个月打了多少分钟的电话", "查一下我3个月前的话费单", "能不能查到半年前的账单", "我能不能查三年以前的话费账单", "查询话费历史账单", "我上个月发短信花了多少钱", "查询前几个月话费使用情况", "我前两个月话费都用了多少", "上个月的话费比前两月多吗", "查询上个月的话费是多少", "需要查询前几个月的账单", "历史账单查询", "查询号码的历史短信费用", "从前的漫游费用共计多少", "近三个月话费合计多少", "号码历史消费记录", "话费账单历史统计", "我累计话费是多少", "从我办这个号以来总共用了多少话费", "我这一年每个月的话费清单", "今年每月话费", "去年话费使用情况", "查一下我上个月的流量费用", "查看一下我的历史账单", "查询我上个月的话费是多少", "能否查询我上个月的话费金额", "上个月花了多少钱", "以往为什么总欠费", "前几个月的消费记录", "今年到目前为止总共花了多少钱", "我想了解一下上个月的话费", "上个月的短信费用是多少", "前几个月的费用合计", "过去几个月的流量使用情况", "最近半年的详单", "历史话费情况", "历史费用合计", "以前话费", "能查历史话费吗", "怎么查以前的话费", "我想查上月的话费", "我上月话费是多少", "我想看一下我上半年的话费清单", "我要查以前的话费", "查询上月话费", "想知道以前电话消费情况", "我前几个月消费了多少钱", "能查询前几个月的话费吗", "前几个月的消费总金额", "如何查询历史话费金额", "想查手机历史话费怎么查", "怎样查找历史话费支出情况", "我以前的话费支出是怎样的", "以前的话费清单能查吗", "两个月的话费想查一下怎么花这么多", "上个月怎么用的话费", "上个月怎么用了那么多钱的话费", "上个月怎么用了三百多块钱的话费", "历史话费怎么查询", "过去的话费怎么查", "查查以前用了多少话费", "查查之前的话费账单", "怎么查之前花了多少话费", "帮我查一下之前花了多少钱", "以前的话费是多少钱", "我的历史话费账单是多少", "查最近两个月用的话费金额", "查查上个季度的话费金额", "帮我查询历史账单", "查询我前4个月的话费使用明细", "我要查我前两个月的长途费用", "查询上两个月话费使用情况", "我想知道我前3个月话费用了多少", "上个月用了多少话费", "我最近三个月话费怎么用这么快呢", "今年每个月话费都怎么使的", "去年花了多少长途费", "能查前几个月的话费吗", "查这半年的手机话费", "查历史账单", "我上月用了多少话费", "我前几个月的消费情况", "我前段时间共打掉多少话费", "查一下我手机号的费用历史记录", "能不能查话费的历史情况", "导航至历史话费查询菜单", "半年前的话费情况可以查吗", "我想查询三个月一共用了多少话费", "导航至上个月话费查询菜单", "上个月我的话费使用情况", "我怎么查询上月的话费", "帮我看一下上个月扣了多少钱", "查询历史话费需要提供什么信息吗", "查询我上个月的手机费", "查一下上个月我打电话花了多少钱", "查一下我月份的话费", "给我查下上月的话费", "给我查一下上月的话费", "看一下我第一季度的消费总额", "可以查到我的历史话费吗", "历史话费在哪里可以查到", "上个月的话费可以查到吗", "我怎么查询之前的话费", "用手机卡到现在打电话一共花了多少钱", "我要查上个月的账单明细", "还能查到上一季度的账单记录吗", "我想查一下我这两个月的话费明细", "我想查一下我的历史话费", "过去三个月的话费", "帮我查一下过去个月的话费", "查一下我上个季度总共消费情况", "去年的话费能不能查一下", "这半年多少话费", "给我查一下月份打电话的钱", "我想看一下近三个月的话费多少钱", "给我查一下去年的话费每个月有多少钱", "忘看一下前几个月是不是打了很多电话呀", "把实时话费给我短信发过来", "把我当前话费账单发个短信过来", "查实时话费的结果以短信的方式发给我", "查一下我目前的话费然后给我发个短信", "短信查询我的手机实时话费", "短信发送什么内容能查是实时话费", "短信发我一下实时话费记录", "短信告诉我实时话费是多少", "短信告知我今天的消费情况", "短信回复我本月消费情况", "短信通知我我的实时话费是多少", "短信怎么查询现在话费使用情况", "发短信告诉我这个月的话费", "发什么短信查实时话费", "发什么短信能查当前话费使用量", "给哪个号码发短信可以查询实时话费", "给我发短信查本月话费", "给我发条短信告诉我实时话费金额", "给我发一个实时话费短信", "给我发一个我手机的实时话费短信", "给我发一下手机实时话费的短信吧", "给我下发一下信息这个月扣了多少钱", "截止现在我的话费用了多少短信发到我手机上", "今天为止我的话费使用情况然后发个短信给我", "今天为止我用了多少话费请给我发条短信", "可以把我现在的话费情况用短信发过来吗", "麻烦发一下我的实时话费", "能不能发我一个实时话费的短信", "请把实时话费发到我的手机上", "请发短信告诉我今天用了多少话费", "手机的实时话费给我短信发过来", "我本月实时话费发个信息过来", "我想查实时话费能否通过发短信来查", "以短信的形式告诉我实时话费数目", "用短信查实时话费要发什么", "用短信查实时话费要怎么操作", "用短信发一下我本月的话费", "用短信给我报一下实时话费", "怎么通过短信查本月话费", "怎样用短信查当月话费", "这个月长途费发短信给我", "这个月的话费账单发我手机上", "这个月话费短信发我一下", "把我这个月的话费发送到我的手机上", "实时话费能不能发短信告诉我", "现在的话费发我手机上吗", "当前的话费短信告诉我", "发信息告诉我一下我现在的话费", "将我本月的话费用短信给我发一下", "把我最近的话费使用情况发送一条短信给我", "把我上个月的话费单给我短信发过来", "把我上月的话费情况发给我", "查询上月话费的短信编辑内容", "查一下上月话费短信告诉我", "短信查询上月打了多少钱电话", "短信通知我上个月用了多少话费", "发短信查询上个月的电话消费", "发个短信给我前一个月的话费情况", "发什么短信能查上个月长途费", "发一个上月的话费短信", "发一个上月话费单的短信", "给我打一个上月的短信账单到我手机上", "给我发一个上个月话费的短信", "给我下发一下信息上个月扣了多少钱", "能发短信说明上个月的话费使用吗", "能用短信查上个月的话费情况吗", "前个月的的话费单短信发给我", "上个月的话费单给我短信发过来", "上个月的账单发我一下", "上个月话费使用明细请短信告知", "上个月话费是多少能发个短信吗", "上个月话费用了多少给发个短消息", "上月话费明细怎么用短信查", "我想查上月话费能否通过发短信来查", "我想通过短信查一下上月的话费", "想用短信查看上个月的话费", "以短信的方式查询上个月的话费", "用短消息查上月话费", "用短信把我查的上月话费金额结果发过来", "怎么发信息查看上月的话费", "怎么用短信查上月话费", "怎样用短信查上个月话费使用明细", "把上月话费发到我的手机上", "可以用短信把我的上月话费发过来吗", "将我上个月的话费发一下", "能通过短信查上个月的消费记录吗", "我要查上个月的账单明细编辑短信查行吗", "将我上个月的话费用短信给我发一下", "我想知道上个月用了多少短信费", "把我的历史话费情况短信发过来", "编辑什么短信能查上两个月话费详情", "查历史账单发什么短信", "查询前6个月的话费编写什么短信", "查以前的话费发哪个信息", "导航至历史话费查询菜单然后发个短信给我", "短信编写什么内容查询前两个月的话费", "短信查询过去三个月用的话费总金额", "短信查询我的历史话费账单", "短信方式通知历史消费账单", "短信告知查询前几个月话费的结果", "短信通知我过去两个月花了多少话费", "短信怎么查历史话费", "发短信多少查历史话费", "发什么短信能查本年话费使用", "发条信息告诉我前两个月用的话费金额总数", "发我一下手机历史话费账单", "给我发一个历史话费短信", "给我发一下半年话费账单的短信吧", "给我下发一下9月扣了多少钱", "今年春天的话费怎么用短信查", "历史话费可以查询多久以内的请给我发条短信告知一下", "麻烦发一下我最近半年的账单", "能不能查话费的历史情况然后给我发个短信", "能不能给我把历史消费记录短信发过来", "前半年的话费账单短信发给我", "前几个月的话费情况能用短信查吗", "请问编辑什么内容可以查之前的话费", "去年长途费发什么短信可以查到", "如何通过短信查历史话费", "手机的历史话费给我短信发过来", "我上个季度的话费金额短信告诉我", "我想查询三个月一共用了多少话费短信通知一下", "以短信的方式把我上一季度的话费金额发一下", "用短信查看历史账单", "怎样用短信查去年话费", "最近三个月的话费清单给我发过来", "将我前两个月的话费发到我手机上", "请把历史话费发到我的手机上", "能否将上半年的话费发我手机上", "前两个月的话费发我一下", "历史话费能不能发短信告诉我", "用短信查一下我上两个月打电话的话费情况", "去年九月份的话费单短信发给我", "用短信把历史话费给我发过来", "查询过去半年的话费短信发过来", "短信查我上半年的费用", "帮我查一下18905318975的这月的扣费", "帮我查一下别的手机号截止今天的话费好吗", "别人本月话费使用详情我能查吗", "不是我本人电话的当月话费怎么查", "查别人电话这个月用了多少长途费", "查其他号码这个月的话费", "查询别的手机实时话费", "查询其他号码现在的话费", "查询其他人本月用多少话费", "查询其它电话的实时话费", "查询我妹妹当月的话费", "查询我兄弟的手机这月花了多少钱", "查一下别的号码实时话费", "查一下非本机号的实时话费", "查一下另外一个手机这个月扣了多少钱", "查一下另一个号截止到现在的话费", "查一下这个非本机号本月用了多少话费", "非本机号码这个月的话费", "给我查一个其他号的实时话费", "可以查询其他手机的实时话费吗", "另个手机到目前的实时话费怎么查询", "另一个号最新的话费情况", "能不能查别的号码今天为止的话费", "能不能查询其他号码实时话费", "能查另外一个号的实时话费吗", "其他电话截止现在的话费能不能帮我查一下", "其他号码实时查询话费", "他机实时话费查询", "他人实时话费怎么查", "我查一下另一个号目前的话费", "我可以查一下家人的实时话费吗", "我能不能查别人电话截止今天的话费", "我能查老爸的本月话费的使用情况吗", "我想查别人电话的实时话费", "我想查另一个手机号的实时话费是多少", "我想查其他号码的实时话费", "我想查我朋友这个月的话费", "我想查一下另一个号码目前的话费", "我想知道我妹妹这个月消费多少", "我要怎么查朋友现在话费用了多少", "需要查询非本人账户近两天话费的情况", "怎么查别人电话现在的话费使用情况", "查询别人电话本月的话费", "能不能帮我查下我家人的电话实时话费", "张丽这个月花了多少钱", "想查别人电话的实时话费要提供什么信息吗", "我想查其他的电话现在的话费情况这个月", "查一下别人手机号码这几天的话费", "我想查一下另一个号现在花了多少钱", "帮我查询另外号码过去3个月的话费", "帮我查一下18905318975之前的话费", "帮我查一下另一个手机号前几个月之前花了多少钱", "报一下我另一个手机号之前话费花了多少钱", "别的手机半年前的话费情况可以查吗", "别的手机历史话费可以查询多久以内的", "查查别的电话的历史话费金额行不行", "查查我别的手机号之前的话费账单", "查查我另一个电话以前用了多少话费", "查老公历史话费明细", "查其他号码近三个月的话费使用", "查其他号码这半年的话费单", "查询别的手机号的历史账单", "查询非本机号过去两个月的话费", "查询非本机号码的历史费用情况", "查询张明上半年的话费记录", "查一下朋友手机号上一季度的话费总数", "查一下我兄弟这半年话费花了多少钱", "导航至别的手机历史话费查询菜单", "可不可以查其他电话过去半年用的话费", "另外一个号去年话费使用量", "另一个电话以前的话费是多少钱", "能不能查其他电话话费的历史情况", "能查其他的号去年话费交了多少吗", "能查其他人的话费使用历史吗", "能否查询别的电话的历史话费", "朋友让我帮忙查上月话费我怎么办", "其他电话历史话费可以查吗", "其他号码历史话费查询", "其他手机历史话费怎么查询", "上个月的话费我能帮别查吗", "我的另一个手机号历史话费账单报一下", "我妈手机号码去年话费的使用情况", "我想查询另一个号码三个月一共用了多少话费", "我要查非本机号过去半年的话费", "我要看一下其他号码的历史账单", "怎么查别人手机号码去年的话费", "怎么查其他号码以前的话费", "怎么查其他手机号之前花了多少话费", "怎么用我电话查他人话费历史使用情况", "怎样帮我妹妹查询她的历史话费", "查一下这个非本机号上一季度用了多少话费", "查一下我妹妹上个月的话费", "想查别人电话的历史话费要提供什么信息", "能查另外一个手机卡的历史话费吗", "朋友的电话历史话费我能查到吗", "查其他电话的历史话费要怎么操作", "请帮我查一下另外一个手机号的历史话费", "我想查别人电话的历史话费", "能查询其它电话的历史账单吗", "我想查别人手机号的电话费的历史使用情况", "可以查一下那个号上个月打了多少钱吗", "我查一下另一个号前几个月花多少钱", "查亲戚的历史话费", "我想查别人的历史账单", "历史话费缴纳情况", "本月交话费的记录", "查我所有的缴费记录", "查询我缴纳话费的明细", "查一下我的充值明细", "查一下我这个月的交费记录", "充值明细的查询方法", "从哪里查话费充值明细", "看看我过去两个月交话费的明细", "可以提供我历史缴费记录吗", "能查我最近两个月的交费记录吗", "如何查询所充话费详情", "我今年的交费账单", "我今年交话费的明细", "我今年交了几次话费每次多少钱", "我今年每次交话费的金额", "我想查一下缴费记录", "我想看一下我最近几个月的缴费记录", "我自从购机以来交了几次话费", "我最近交话费的明细有没有", "我最近三个月的缴费记录", "怎么查这段时间所交的全部话费", "最近缴纳话费的详单", "充了一百块钱怎么查话费查不出来了", "您给我查一下我刚交了的话费", "能不能查到这一季度共交了多少话费", "查询我本年的缴费情况", "我过去两个月一共交了多少话费", "查询我上个月交了多少话费", "找一下历史话费缴纳记录", "历史话费缴纳情况能通过短信查吗", "查询一下本手机的交费明细", "我想查一下缴费明细", "查询话费的缴纳情况", "我想查询预存话费明细", "电话费交了有明细吗", "我想知道我从一月份到现在一共交了多少话费", "看一下我交了多少钱话费了", "我最近交多少话费", "帮我查一查这一年所交话费的账单", "我想查一下我的话费缴纳情况", "我想知道我上两个月的话费交了多少", "能查一下我最近几次交话费的金额吗", "我想知道我上次话费是什么时间交的", "手机上还有多少钱短信发下", "余额用短信发", "卡里还有多少钱发个短信", "现在的余额", "用短信发话费还剩多少", "我是不是没费了", "不知道还有没有费", "还有费不"], "target": "话费查询"}
{"questions": ["查一下积分", "现在积分是多少", "怎么查询积分", "怎么查积分", "要看看积分有多少", "报一下积分是多少", "积分怎么查", "查询话费积分", "现在话费累积积分怎么查", "查询积分累积情况", "积分累计", "想查询积分了", "看看积分有多少", "如何看交话费得的积分", "去哪查手机号的积分", "查积分", "看下积分剩余", "积分还有多少", "积分剩余数量", "看看积分的累积量", "积分累积情况查看", "我要查积分", "查一下有多少积分", "查询可使用的积分", "查询关于积分兑换的情况", "积分清零了没", "手机号码积分使用情况", "积分有什么用处", "积分是怎么来的", "查看积分情况", "积分是多少", "怎么看积分", "查那个打电话累计得分", "想看一下那个积分信息", "积分怎么能查询到", "电话里面有多少积分", "还有积分吗", "积分能从你这查吗", "查询一下剩余积分", "手机号的积分你们这里管不管查", "积分的情况你们能查到吗", "想知道已经积了多少分了", "请问怎么查询积分", "查手机卡积分有多少", "积分情况查询", "账户里面有多少积分", "积分明细查询", "积分累计情况帮我看一下", "查询积了多少分了", "查询电话的积分", "积分现在积到多少", "攒了多少积分", "能否发短信查积分", "查看一下已经积了几分", "需要到营业厅才能查积分吗", "查询当前积分", "怎么查询手机的积分", "我想查积分怎么操作", "手机里有多少积分", "积分", "积分兑换", "积分能用来干嘛", "办理移动套餐可以获取积分吗", "充块钱话费送多少积分", "充话费有没有积分", "充一块钱有积分吗", "电话费积分现在是多少", "调测费可以累计积分吗", "多长时间不使用积分会清零", "工料费怎么算积分", "话费积分是怎么算的", "话费是不是一块钱积一分", "积分超过三年会清零吗", "积分的获取方法", "积分的有效期是多久", "积分都能兑换什么东西", "积分多长时间会过期", "积分多久会清一次零", "积分规定", "积分滚动清零的期限是多久", "积分和账期有关系吗", "积分会保留多长时间", "积分活动有那些", "积分可以抵话费吗", "积分可以累计多长时间", "积分可以转赠他人吗", "积分累计时长是多长时间", "积分能从一个账户转到另一个账户吗", "是把当年的积分全部清零吗", "积分去哪儿兑换", "积分使用有没有限制", "积分是年底清零吗", "积分是一块钱积几分", "积分是怎么累积的", "积分是怎么算的", "积分是怎样计算累计的", "积分详情", "积分有没有有效期", "积分有哪几部分组成", "积分有什么用", "积分有效期", "积分有效期是多久", "积分有效期是多少", "积分怎么变成零了", "积分怎么兑换", "奖励的钱算不算积分", "奖励积分是怎么算的", "奖励积分怎么获得", "累计多少积分才有奖励", "哪些情况下的消费不计算积分", "前年交话费赠的积分今年还算吗", "如何使用积分", "什么情况产生奖励积分", "什么消费产生多少积分", "使用赠送的话费算积分吗", "手续费给不给算积分", "通话总时长会影响积分多少吗", "为什么最近不奖励积分了", "违约金有没有积分", "现在还有奖励积分吗", "消费积分和奖励积分是一起用的吗", "消费积分是怎么算的", "消费积分怎么计算", "怎么获得积分", "怎样就有积分了", "这个月积了多少积分", "我想查积了几百分了", "开个积分", "我想查手机号的积分", "我想查一下积分", "我手机号还有多少积分", "积了多少了"], "target": "积分查询"}
{"questions": ["把我的电话转移到另一个手机号上", "办理呼叫转移", "办理呼叫转移业务", "办理转电话", "办转听电话", "帮我办一下呼叫转移", "帮我打开呼叫转移的业务", "帮我开一个呼叫转移", "别人打我怎么无法呼叫转移", "给我办一个转移电话的", "给我开通一下电话呼叫转移", "给我手机开通来电转移", "呼叫的时候转移是怎么弄的", "呼叫转移开通业务的具体流程", "呼叫转移业务", "呼叫转移有哪几种", "呼叫转移怎么办理", "能把他人打到电话转到我另一个手机", "开开呼叫转移", "开启呼叫时就转移的模式", "开启来电转移到另外一个号的模式", "开通打给我能转到别人手机的功能", "开通呼叫转移都有什么步骤", "开通呼叫转移要通过什么途径", "开通可以转移来电的业务", "开通那个呼叫转移", "开通能转接给家人的业务", "开通一下呼叫转移", "开通一下呼转业务", "开一下手机呼叫转移", "马上开通通话转移项目", "能否办理呼叫转移", "呼叫转移开通怎么设置", "请问我怎么把手机来电转移到其他号码上", "如何办理电话转接业务", "设置成呼叫转移的模式", "我手机怎么没有呼叫转移", "我想把号码来电转到其他电话上", "我想办来电转移的相关业务", "我要办呼叫转移", "怎么呼叫转移", "怎么开开呼叫转移的功能", "呼叫转移的开通业务", "转接别人电话怎么办", "转入他人电话开通", "我要开通电话自动转接业务", "帮我开自动转接通话", "帮我开下自动转接电话", "我想把这个号的电话转到别的号码上", "来电转接到别人怎么办理", "开通呼叫转移的流程", "如何进行呼叫转移", "把我的呼叫转移业务开通", "开通呼叫转移用验证身份信息吗", "开通呼叫转移需要提供什么信息", "呼叫转移", "呼叫转移怎么收费用", "可以同时呼叫转移到两个号码吗", "把呼叫时转移的功能关了", "把呼叫转移取消", "把我的呼叫转移取消了吧", "把转入电话的业务撤销", "帮我取掉手机的来电转移", "别人打电话不再转到其他手机", "不想使用来电转移业务了", "不想要呼叫转移功能了", "不想要呼叫转移了", "不要再转听电话了", "撤了转接业务", "电话不要转移功能", "关闭打给我转到别人手机的功能", "关闭呼叫转移", "关闭呼叫转移服务", "关掉呼叫转移", "关了呼叫转移的业务", "关停我手机的呼叫转移", "呼叫转移把他永久关了", "呼叫转移办理后可以取消吗", "呼叫转移不需要了", "呼叫转移可以停掉吗", "呼叫转移浪费钱请取消", "呼叫转移取消业务的具体流程", "呼叫转移用不上需要去掉", "马上停止呼叫转移的业务", "取消电话转接听功能", "取消呼叫时转移的业务", "取消呼叫转移的流程", "取消来电转移到另外一个号的模式", "取消能转接给家人的业务", "取消我办理的来电转移业务", "取消我这个卡的呼叫转移", "取消一下呼转业务", "如何把呼叫转移取消", "如何取消来电转移", "停止呼叫转移功能", "停止手机的呼叫转移", "我想关掉我们呼叫转移", "我想取了来电转移这项业务", "我要取消呼叫转移", "消除转入电话的业务", "要把呼叫转接通话去掉", "怎么取消来电转接", "怎么取消来电转移", "怎样取消呼叫转移", "转入另一个手机的电话不要转了", "帮我关掉每次打给我都呼叫转移", "关闭电话自助转移", "我要取消电话自动转接", "取消呼叫转移的过程", "取消呼叫转移需要提供什么信息", "我不要呼叫转移了", "开通一个呼叫转移业务现在不想要了", "手机里呼转相关的业务都取消掉", "帮我把它直接转接电话的业务取消掉", "不让电话转接听", "我想办电话转接", "来的电话转到别人的手机上"], "target": "呼叫转移设置"}
{"questions": ["用UIM查手机号", "UIM反查手机号有哪些步骤", "哪些途径能用UIM查到手机号", "什么渠道可以办理UIM反查手机号的业务", "手机号忘了怎么用UIM查", "介绍一下UIM反查手机号的流程", "忘记手机号用UIM查的途径", "打电话给工作人员能用UIM反查手机号吗", "UIM反查手机号业务的办理方法", "用UIM查手机号要如何操作", "查下手机号", "我不知道自己的手机号码", "我这个手机的手机号是多少"], "target": "UIM反查手机号"}
{"questions": ["查一下我这个套餐还有多少", "我还剩多少套餐", "查询一下我的话套餐余额", "我卡里套餐还剩多少", "我要查询账户的剩余套餐", "怎么查询套餐的余额", "导航到套餐余额查询菜单", "我的手机还剩多少套餐", "我想知道卡里的套餐还有多少", "我套餐现在还有多少", "查询还余下多少套餐", "帮我看下现在的套餐余额", "我现在套餐剩的还多吗", "查查套餐还有多少是不是不够用了", "查套餐余额", "我手机卡里还有多少套餐", "手机里套餐还多吗", "卡里还有多少套餐", "套餐还有没有余额", "套餐还有多少钱", "账户还有套餐吗", "套餐的剩余情况", "卡里还有套餐余额吗", "我这个月的套餐余额还剩多少", "为什么套餐余额变少了", "我本月套餐还有余额吗", "查一下我的号码还有多少套餐", "查询目前套餐的余额", "查询流量", "查短信包剩余量", "查一下我这个流量还有多少", "我还剩多少流量", "查询一下我的流量余额", "我的账户里面还有多少流量", "我要查询账户的剩余流量", "怎么查询流量的余额", "我想知道卡里的流量还有多少", "我流量现在还有多少", "查询还余下多少流量", "帮我看下现在的流量余额", "流量剩下多少", "我现在流量剩的还多吗", "查查流量还有多少是不是不够用了", "手机里流量还多吗", "还剩多少流量", "卡里还有多少流量", "流量余额是多少", "流量还有没有余额", "账户还有流量吗", "卡里还有流量余额吗", "电话号流量余额详情", "我这个月的流量余额还剩多少", "为什么流量余额变少了", "查一下我的号码还有多少流量", "查询目前流量的余额", "查一下我这个短信还有多少", "查询一下我的短信条数", "我卡里的短信还剩下多少", "我的手机还剩多少短信", "我想知道卡里的短信还有多少", "我短信现在还有多少", "查询还余下多少短信", "短信剩下多少", "我现在短信剩的还多吗", "查查短信还有多少是不是不够用了", "卡里还有多少短信", "账户还有短信吗", "电话号流量短信详情", "我这个月的短信还剩多少", "查一下我的号码还有多少短信", "我还有多少兆流量", "还有几兆可以用", "WLAN时长是多久", "WLAN还剩多少", "查一下我这个WLAN还有多少", "我还剩多少WLAN", "查询一下我的WLAN余额", "我卡里WLAN还剩多少", "我的账户里面还有多少WLAN", "导航到WLAN余额查询菜单", "我卡里的WLAN还剩下多少", "我的手机还剩多少WLAN", "我WLAN现在还有多少", "查询还余下多少WLAN", "帮我看下现在的WLAN余额", "我现在WLAN剩的还多吗", "查查WLAN还有多少是不是不够用了", "查WLAN余额", "我手机卡里还有多少WLAN", "手机里WLAN还多吗", "还剩多少WLAN", "WLAN余额是多少", "账户还有WLAN吗", "WLAN的剩余情况", "电话号WLAN余额详情", "为什么WLAN余额变少了", "我的WLAN余额还剩多少", "我本月WLAN还有余额吗", "查一下我的号码还有多少WLAN", "查询目前WLAN的余额", "查一下我这个通话还有多少", "我还剩多少通话", "我卡里通话还剩多少", "我的账户里面还有多少通话", "我要查询账户的剩余通话", "怎么查询通话的余额", "导航到通话余额查询菜单", "我卡里的通话还剩下多少", "我的手机还剩多少通话", "我想知道卡里的通话还有多少", "查询还余下多少通话", "帮我看下现在的通话余额", "通话剩下多少", "我现在通话剩的还多吗", "查查通话还有多少是不是不够用了", "查通话余额", "手机里通话还多吗", "还剩多少通话", "通话余额是多少", "通话还有没有余额", "账户还有通话吗", "通话的剩余情况", "卡里还有通话余额吗", "为什么通话余额变少了", "我的通话余额还剩多少", "我本月通话还有余额吗", "查一下我的号码还有多少通话", "查询目前通话的余额"], "target": "套餐余量查询"}
{"questions": ["办理的预存话费套餐每个月返多少给我", "办理协议预存款活动有什么条件", "帮我查一下购机后给了我多少话费", "本月活动赠款", "参加协议预存款活动用掉多少返多少吗", "查查这个月返还的话费是多少", "查查这个月赠了我多少话费", "查询给我返了多少钱", "查询每个月扣多少协议预存款", "查询每个月赠送的话费", "查询我的协议预存款还有多少", "查询预存话费", "查询赠款", "查一下话费赠送情况", "查一下买手机赠了我多少话费", "查一下我的赠款还有多少", "查一下我有多少赠款", "查一下协议预存款用了多少", "查一下赠给我的钱数", "查一下赠送的话费", "查找我预充值活动的赠送金额", "充100送50的话费截止到什么时候", "充多少话费才赠话费", "充多少钱才送话费", "充卡里多少钱赠送多少钱", "充钱返话费返了没有", "存话费会多赠送话费吗", "存话费业务每个月返还的钱数是", "存那么多话费一个月赠给我多少钱", "存元送元是真的吗", "达到规定的金额就会自动参加协议预存款活动吗", "电信的活动赠款怎么使用", "都有哪些套餐有送话费活动", "返的话费有没有到账", "返给我的话费在哪呢", "返给我的预存款金额不对", "返话费", "返话费返了没有", "返还话费到期了吗", "购机送话费算不算赠款", "购机赠款什么时候到账", "购买合约机赠多少话费", "购买合约手机送多少话费", "合约里还有没有预存话费", "话费存的越多越好吗", "话费返还完了吗", "话费返完没", "话费共预存了几个月的", "话费是怎么赠送的", "话费预存活动有哪些", "还剩多少话费没送完", "活动赠款详情", "交的协议预存款是否一下全扣除", "今天返话费", "了解下需要预存款的套餐", "买电信手机赠多少话费", "买手机送多少话费", "买手机赠话费是怎么赠", "买协约机送多少话费", "没感觉有多送我话费", "每个月的打到我卡里的钱数", "每个月的预存话费返还是多少", "每个月返给我的金额是一样的吗", "每个月赠送多少话费", "每个月赠送我多少话费", "每个月最低消费是不是返给我的金额", "每月的预交话费是多少", "每月返的话费是几号到", "每月返还金额怎么分的", "每月返钱的套餐有什么优惠", "每月返我话费够交当月话费吗", "每月几号返还话费", "每月赠送的话费哪天到账户", "哪些人可以参加协议预存款活动", "你看每月给我返还多少钱", "你看我的协议款还剩多少钱啊", "你们给我每个月赠多少话费", "你们一个月返我多少话费", "你们赠送的话费金额是怎么算的", "你们最近有充值送话费的活动吗", "如何查询每月返还话费金额", "什么时候停止赠送话费", "什么是赠款", "是预存元每月就有元的话费吗", "说好的送话费能给我送多久", "送的话费返到哪里了", "送的话费和实际到账的不符", "送的话费能抵扣长途费吗", "送的话费什么时候返我", "送的话费为什么没有到账", "送话费一直送多久", "送我的话费在哪查", "提前存话费的优惠活动金额", "通过支付宝充值有没有赠款", "我办的是预存话费套餐你们每个月给我赠多少", "我办了的预存话费中协议预存款是多少钱", "我办了新套餐为什么没给我赠话费", "我的套餐每月赠送多少话费", "我的套餐中协议预存款是多少", "我的协议期到几月份", "我的协议期到什么时候", "我的协议期过了没有", "我的赠费协议合同到什么时候", "我刚才存的话费能返多少", "我每月赠送多少话费", "我手机现在赠话费是每个月多少", "我现在的协议预存款是多少钱", "我现在话费每个月返还多少", "我想查询现在每个月返我多少话费", "我想查询预存话费赠送的话费是多少", "我想查一下每月返话费的套餐", "我想了解一下有哪些赠送话费的套餐", "我想知道你们优惠了我多少话费", "我预存了元每月赠我多少", "我赠送的话费怎么查看", "我这个月扣多少协议预存款", "我这个月有多少的赠话费", "现在还在给我送话费吗", "现在每月话费返还的钱是", "现在我每个月赠送的话费是多少", "想换号的话预存的话费怎么办", "消费预存款项", "协议预存款活动能不能办理退款", "协议预存款是不是办号的时候就要交", "协议预存款需要交多少钱", "协议预存款需要签专门的协议吗", "协议预存款赠款每月何时发放", "一次交1000块钱话费有没有什么活动", "一次缴纳全年的话费有没有什么活动", "一次性充多少才能参加协议预存款", "有购机赠话费活动吗", "有没有赠送话费活动", "预充值以后返还金额是多少", "预存的话费多久才能返完", "预存的话费分几个月扣掉", "预存的话费怎么返还", "预存多少就赠多少吗", "预存话费", "预存话费的合约情况是什么样的", "预存话费后还会欠费吗", "预存话费会多给多少钱", "预存话费活动赠送多少话费", "预存话费截止日期", "预存话费每月返我多少钱", "预存话费送的金额是多少", "预存话费送话费", "预存话费详情", "预存话费有多少", "预存话费有门槛限制吗", "预存话费有什么活动", "预存款", "预存款活动怎么参加", "预存元分几次返给我", "预存元每月赠元是月初就给吗", "预先存好的话费能提前给我吗", "怎么查询每月返还金额数目", "怎么还没返我话费", "赠话费规则", "赠话费活动查询", "赠款到账情况", "赠款能不能提现", "赠款使用有没有限制", "赠款是每月都返还吗", "赠款协议期是多长时间", "赠款余额是什么意思", "赠款在哪查", "赠送的话费金额不对", "赠送的话费能做什么用", "赠送的话费什么时候到账", "赠送话费分几期", "赠送话费是否需要先交一定的钱", "赠送话费协议的截止日期", "赠送话费协议什么时候结束", "这个月赠送我话费了吗", "这月给我返的话费金额不对", "这月没给我返话费", "自主缴费机上面能不能办理协议预存款", "最低消费多少才给赠送话费", "最近有什么预存话费的活动", "最近有赠款活动吗", "我手机号的协议期是多久", "查询协议期只能到营业厅吗", "赠给我的话费怎么还没到账", "我要查我的协议款", "我的送话费活动什么时候到期", "我的协议套餐什么时候到期", "我想查一下协议预存合约计划", "我的协议款什么时候用完", "每月送多少", "每月返回多少钱", "我想查一下这个月返了多少话费", "这个月有没有返还费用", "这个月手机返话费了吗", "看看我这个月返多少话费", "怎么查自己每个月返充的话费"], "target": "月返费查询"}
{"questions": ["去哪里可以重置移动密码", "重置移动密码有什么快捷方式", "怎样使移动密码回到刚开始时的密码", "怎样发短信重置移动密码", "可以用他人的手机对移动密码进行重置吗", "不想去营业厅重置移动密码", "移动密码改为原来的初始密码", "在哪里可以恢复移动初始密码", "不记得移动初始密码了", "怎样查移动初始密码", "需要对移动密码进行重置要怎么做", "查一下移动初始密码", "短信重置移动密码要怎么写", "我不知道自己的移动密码", "我找不到自己的移动密码了", "想修改移动密码初始密码不知道", "重新设置下密码", "重置密码", "手机密码丢了"], "target": "移动密码重置"}
{"questions": ["改一下手机移动密码", "在官网上如何修改移动密码", "去营业厅修改移动密码必须是本人吗", "让其他人帮我改移动密码", "我想换一个新的移动密码", "在哪里查询我的移动密码的改动是否成功", "可以随时对移动密码进行变动吗", "更改移动密码的说明", "移动密码变动后生效需要多长时间", "我可以多次更改我的移动密码吗", "修改移动密码有没有次数限制", "修改移动密码的时候要注意什么", "移动密码的变更需要带什么东西", "营业厅可以修改移动密码吗", "可不可以打电话修改移动密码", "移动密码要怎样修改", "修改移动密码的方法有哪些", "移动密码太长改一个短的", "不想用现在的移动密码了", "移动密码是不是可以随便换", "移动密码是初始密码怎么改成其他的", "移动密码不吉利", "改密码", "改下手机号密码", "手机密码不太安全"], "target": "移动密码修改"}
{"questions": ["把我手机号冻结吧", "办挂失", "办理挂失业务的流程", "办理挂失业务什么时候开始生效", "帮别人办理挂失", "拨打哪个号码办理挂失", "电话可以直接挂失吗", "挂失手机卡", "挂失需要身份证", "紧急挂失我的手机号码", "可以给别人挂失手机号吗", "能否给我办理手机挂失", "手机被人偷了挂失一下", "手机丢了是电信的", "手机丢了需要挂失手机卡", "手机丢了怎么办报失", "手机和卡丢了帮我挂失一下", "手机和卡丢了要怎么报失", "手机卡掉了怎么办", "手机找不见了先挂失一下", "网上怎么挂失电信手机卡", "我手机丢了怎么办理挂失", "我想办理挂失", "我要报失", "我有一个号码丢了需要挂失", "需要办理挂失业务", "在最短时间内挂失", "怎么办理手机挂失业务", "我要挂失我的电信卡", "挂失怎么挂", "手机丢了把我这个卡还剩下", "手机丢了挂一下失", "卡找不见了", "电话丢了", "手机丢了", "电话卡给拿出来不知道放哪了"], "target": "挂失"}
{"questions": ["办理解挂", "办理解挂失只能到营业厅吗", "办理解挂业务什么时候开始生效", "打电话给电信可以办理解挂业务吗", "电信号码解挂", "挂失后想取消可以吗", "挂失后怎么解除", "解挂失需要身份证吗", "可以在网上营业厅自助办理解挂吗", "立即解挂手机号", "麻烦将手机号挂失解除掉", "请把我的手机卡解除挂失", "请帮我在半小时内解挂手机号", "上次挂失那个解挂一下", "手机解挂如何办理", "手机找到了帮我解挂一下", "手机找到了需要解挂", "停止挂失我的手机卡", "我之前有一个号码挂失了现在找到了需要解除挂失", "现在不需要挂失手机了", "已找到手机解挂账号", "怎么办理解除挂失", "找回手机后如何解除挂失", "只能去营业厅解除挂失吗", "网上怎么办理解挂失", "帮我解除一下挂失现在不用挂失", "我前天办的挂失帮我取消掉", "我的卡找到了我要取消挂失", "上次挂失的卡找着了帮我解一下吧", "挂失的卡找到了帮我解一下吧", "上次挂失的卡找到了解一下吧", "取消挂失的手机号", "手机丢了但是现在又找着了"], "target": "解挂失"}
{"questions": ["短信查询亲情号", "查一下与本机绑定的亲情号", "我记不起手机绑定的亲情号了", "营业厅怎样去查手机亲情号码", "所加的亲情号码是什么", "查一下我加了的亲情号", "这个号码是不是我的亲情号", "我需要人工服务查我的亲情号码", "短信查询手机号要发什么", "亲情号里都有哪些手机号", "属于这个手机的亲情号有哪些", "哪些号在亲情号里", "有几个号是我的亲情号", "打电话可不可以查亲情号", "查询亲情号的方法有哪些", "可以通过什么来查亲情号", "我有没有设置亲情号", "设置的亲情号不知道是哪个号", "亲情号不记得关联了谁的电话", "亲情号码修改成谁了忘记了", "加了几个亲情号", "被添加成亲情号的有多少个", "亲情号有哪些", "亲情号码"], "target": "亲情号码查询"}
{"questions": ["我想多加一个号码作为亲情号", "删掉一个亲情号码", "再加一个亲情号需要本人办理吗", "对亲情号进行修改要收费吗", "修改亲情号是免费的吗", "加了亲情号后多长时间立即生效", "月底修改了亲情号会收这个月的费用吗", "修改亲情号要去哪里", "手机可以直接添加亲情号吗", "一共可以加多少个亲情号", "修改亲情号码是怎样收费的", "可以随时修改亲情号码吗", "营业厅修改亲情号码需要带什么东西", "怎样发短信修改亲情号码", "我不想加这个号为亲情号了", "亲情号码好添加吗", "亲情号码怎么添加", "根据使用情况把不常用的不要了", "把这号从亲情号里移掉", "把亲情号码清空", "设亲情号码"], "target": "亲情号码设置与修改"}
{"questions": ["VIP密码太简单了改一个难的", "用手机怎样对VIP密码进行修改", "我不想要现在的VIP密码了", "修改VIP密码麻烦吗", "我想改一个自己喜欢的VIP密码", "我不会对VIP账户修改密码", "变一个新的VIP密码", "修改VIP密码的方法有哪些", "能不能换一个VIP密码", "VIP密码修改需要注意什么", "VIP密码要怎样修改", "变VIP密码的操作是什么", "换个短的VIP密码", "给VIP账户换个密码", "vip密码书写格式有什么要求", "VIP密码不吉利"], "target": "VIP密码修改"}
{"questions": ["我想重置下固话密码", "固话密码怎么重置", "固定电话的密码能重置吗", "固话密码忘了能重置吗", "忘了固话密码怎么办", "在哪里重新设置固话密码", "重置固话密码的步骤是什么", "固话密码重置如何操作", "重新设置固话密码的流程是怎样的", "重新设置固话密码复杂吗", "我不会重置固话密码", "固话密码重置需要提交什么材料", "重置固话密码怎么弄", "固话密码能不能重新设置", "固话密码怎样重置", "重置固话密码很难吗", "有哪些途径可以重置固话密码", "固话密码是多少", "固话密码怎么找回"], "target": "固话密码重置"}
{"questions": ["我想改一下固话密码", "固话密码怎么改", "固话密码在哪里改", "我不会改固话密码", "修改固话密码需要提交什么材料吗", "修改固话密码分几步", "修改固话密码的流程是什么", "修改固话密码的步骤是怎样的", "我能不能修改固话密码", "修改固话密码怎么弄", "修改固话密码需要身份证吗", "修改固话密码过程很复杂吗", "修改固话密码需要多久", "固话密码太简单了我想改一个复杂的", "固话密码修改起来复杂吗", "固话密码咋修改", "固话密码好改吗", "固话密码不吉利", "给固话设个简单的密码"], "target": "固话密码修改"}
{"questions": ["开通来电显示的方法", "我要开通来电显示", "手机没有来电显示怎样办理这个业务", "如何开通来电显示", "开通来电显示是免费的吗", "我想要开启来电显示", "我手机不显示来电号码帮我开启", "我想让我的手机有来电显示", "没有来电显示很不方便请开通", "怎样免费开通来电显示", "开通来电显示", "办来电显示", "我要来电显示功能", "设置手机号码来电显示", "开通我的来电显示功能", "可以办理来电显示开通业务吗", "我的手机怎么没有来电显示", "如何获取来电显示功能", "我怎么开通来电显示啊", "我想开通来电显示", "给我手机开通一下来电显示", "来电以后显示号码怎么开通", "我要申请来电显示", "来电显示的申请流程", "转到来电显示申请菜单", "能不能办来电话了显示对方号码的业务", "把我的来电显示开开", "开来电显示每月交多少钱", "开通来电显示只能到营业厅吗", "我需要来电显示功能", "来电显示没用", "如何让手机能够有来电显示功能", "来电显示", "来显费用便宜就开", "在来电的时候会显示来电人", "电话不会显示来电的信息"], "target": "来电显示开通"}
{"questions": ["我要修改无线宽带的密码", "如何修改无线宽带密码", "无线网密码的修改方法是什么", "更改无线宽带密码有哪些步骤", "通过什么渠道可以改无线宽带密码", "无线宽带密码的修改途径", "更改无线网密码要哪些步骤", "我想在电信官网改无线网密码", "改无线密码要去营业厅吗", "无线网密码可以在哪儿更改", "无线网密码的修改能通过给客服打电话吗", "我该怎么做可以改掉无线网密码", "总被别人蹭网我要改密码", "WLAN改密码", "我家WiFi老被人蹭网"], "target": "无线宽带密码修改"}
{"questions": ["我要修改固定宽带的密码", "修改固定宽带密码的方法", "如何修改固定宽带密码", "通过什么渠道可以改固定宽带密码", "固定宽带密码被别人破解了怎么改", "更改固定网密码要哪些步骤", "介绍一下固定网的密码修改流程", "电信宽带如何更改固定宽带密码", "能在官网改固定宽带密码吗", "客服能给改固定宽带网密码吗", "我想在电信官网改固定网密码", "改固定宽带密码要去营业厅吗", "固定宽带密码可以在哪儿更改", "固定宽带密码的修改能通过给客服打电话吗", "我该怎么做可以改掉固定宽带密码", "想给宽带改一下密码"], "target": "固定宽带服务密码修改"}
{"questions": ["手机暂时不用能办理停机吗", "帮我办一个停机保号", "能不能暂时把号码停用", "手机停机了帮我开一下吗", "手机号码办理停机保号业务", "上个月停机现在帮我恢复一下", "号码停了三个月能不能帮我恢复", "我的手机要恢复使用", "暂停我手机的所有服务", "停机保号怎么办理", "办理停机保号的方法是什么", "停机保号在哪儿能办理", "能在官网办停机保号吗", "停机保号能打电话办吗", "想暂时停机保留号码", "手机号暂时不想停一段时间", "保留手机号的情况下办理停机", "停机保号的办理需要什么手续", "客服能给办理停机保号吗", "停机保号的办理方法", "办理停机保号要去营业厅吗", "停机保号有哪些步骤", "我要打电话办一个停机保号", "什么渠道能办停机保号", "暂时不想用这个号", "卡可不可以下个月再用", "这段时间准备不用这个号", "想把号码给停了但是还想要这个号", "手机号还要但是想暂停服务", "手机卡停机但是手机号还要"], "target": "停机保号"}
{"questions": ["我已经交足了话费请立即帮我开机", "我想办理停机", "我想注销账号", "怎么把账号停掉不用了", "申请手机停机", "关闭我这个手机号所有的服务", "请把我的手机号停掉", "手机卡丢了帮我办停机", "我手机丢了能办停机吗", "办理停机的流程", "手机停机后还会扣费吗", "我要办停机业务", "帮我停一下机", "把我的手机号码停机", "我的手机要重新开机", "现在手机停了怎么办", "电话丢失给我赶快停机", "怎样办理紧急停机业务", "办理紧急停机业务要去营业厅吗", "办理紧急停机后手机还会扣费用吗", "办理了紧急停机能不能立即生效", "赶快给我把原来的手机号注销", "立刻停机", "办理紧急停机需要什么手续", "手机卡丢了给我把这张卡停了", "手机被偷了给我停机", "手机卡找不见了怎样停卡", "找着了之前的手机卡给我重新开通", "打电话怎样办理紧急停机业务", "办理紧急停机的方法有哪些", "怎样可以快速的停机", "在哪里可以办理紧急停机业务", "手机号不想用了办一下停机", "手机不知道谁拿走了现在停机", "办理手机号停机业务", "怎么办理停机", "手机被偷怎么办", "将这个手机号给停了"], "target": "紧急停机"}
{"questions": ["宽带坏了", "网断了", "有线宽带断了", "网速太慢了", "网慢的都不能用了", "宽带出现了问题找人帮我修一下", "显示宽带连接那一直是个感叹号", "电信宽带有毛病能有人来修吗"], "target": "有限宽带障碍报修"}
{"questions": ["改下无线套餐", "想换个无线套餐", "现在这个无线套餐太贵了想换", "WiFi是2G的能升吗"], "target": "无线套餐变更"}
{"questions": ["密码想换一下", "能帮我改密码吗", "密码变更", "换个密码"], "target": "密码修改"}
{"questions": ["把短信套餐取消了", "不要短信套餐了", "把短信套餐退了", "取消短信", "目前这个短信条数太少了不够用我要换个多的"], "target": "短信套餐取消"}
{"questions": ["把短信开通了马上能用的那种", "开通短信套餐", "我想把短信套餐给开通了"], "target": "短信套餐开通立即生效"}
{"questions": ["改下畅聊套餐"], "target": "畅聊套餐变更"}
{"questions": ["彩信", "不想再使用彩信了"], "target": "彩信套餐变更"}
{"questions": ["密码忘了", "没记住密码", "查一下密码"], "target": "密码重置"}
bm25算法
    def load_bm25(self):
        self.corpus = {}
        for target, questions in self.target_to_questions.items():
            self.corpus[target] = []
            for question in questions:
                self.corpus[target] += jieba.lcut(question)
        self.bm25_model = BM25(self.corpus)
  • 作用:使用BM25算法加载知识库中的问题数据,并将问题分词后存储为分词列表。
  • 实现:对于每个目标,遍历问题列表,使用jieba.lcut()对每个问题进行分词,并将结果存储到self.corpus字典中。之后,使用BM25算法对分词后的问题进行建模。
加载词向量模型
#词向量的训练
    def load_word2vec(self):
        #词向量的训练需要一定时间,如果之前训练过,我们就直接读取训练好的模型
        #注意如果数据集更换了,应当重新训练
        #当然,也可以收集一份大量的通用的语料,训练一个通用词向量模型。一般少量数据来训练效果不会太理想
        if os.path.isfile("model.w2v"):
            self.w2v_model = Word2Vec.load("model.w2v")
        else:
            #训练语料的准备,把所有问题分词后连在一起
            corpus = []
            for questions in self.target_to_questions.values():
                for question in questions:
                    corpus.append(jieba.lcut(question))
            #调用第三方库训练模型
            self.w2v_model = Word2Vec(corpus, vector_size=100, min_count=1)
            #保存模型
            self.w2v_model.save("model.w2v")
        #借助词向量模型,将知识库中的问题向量化
        self.target_to_vectors = {}
        for target, questions in self.target_to_questions.items():
            vectors = []
            for question in questions:
                vectors.append(self.sentence_to_vec(question))
            self.target_to_vectors[target] = np.array(vectors)
  • 作用:加载并训练Word2Vec模型。若已训练过并保存模型,则直接加载,否则重新训练并保存。
  • 实现:通过gensim库训练词向量模型。首先检查是否已有训练好的Word2Vec模型(文件名为"model.w2v")。若没有,则将所有问题分词后作为训练语料来训练一个新的Word2Vec模型,并保存训练好的模型。然后,使用该模型将知识库中的所有问题转换为词向量,并保存在self.target_to_vectors字典中,键是目标,值是目标下所有问题的词向量。
sentence_to_vec
# 将文本向量化
    def sentence_to_vec(self, sentence):
        vector = np.zeros(self.w2v_model.vector_size)
        words = jieba.lcut(sentence)
        # 所有词的向量相加求平均,作为句子向量
        count = 0
        for word in words:
            if word in self.w2v_model.wv:
                count += 1
                vector += self.w2v_model.wv[word]
        vector = np.array(vector) / count
        #文本向量做l2归一化,方便计算cos距离
        vector = vector / np.sqrt(np.sum(np.square(vector)))
        return vector
  • 作用:将单个句子(问题)转换为一个词向量表示。
  • 实现:通过分词,将句子中的每个词转换为词向量,并将所有词向量取平均,得到该句子的词向量表示。最后,对词向量进行L2归一化(单位化),方便计算余弦相似度。
query查询
    def query(self, user_query):
        results = []
        if self.algo == "editing_distance":
            for target, questions in self.target_to_questions.items():
                scores = [editing_distance(question, user_query) for question in questions]
                score = max(scores)
                results.append([target, score])
        elif self.algo == "jaccard_distance":
            for target, questions in self.target_to_questions.items():
                scores = [jaccard_distance(question, user_query) for question in questions]
                score = max(scores)
                results.append([target, score])
        elif self.algo == "bm25":
            words = jieba.lcut(user_query)
            results = self.bm25_model.get_scores(words)
        elif self.algo == "word2vec":
            query_vector = self.sentence_to_vec(user_query)
            for target, vectors in self.target_to_vectors.items():
                cos = query_vector.dot(vectors.transpose())
                # print(cos)
                results.append([target, np.nanmean(cos)])
        else:
            assert "unknown algorithm!!"
        sort_results = sorted(results, key=lambda x:x[1], reverse=True)
        return sort_results[:3]
  • 作用:根据用户输入的查询(user_query),使用不同的算法进行文本匹配并返回最相关的目标(答案)。

  • 实现

    • editing_distance:使用编辑距离算法计算每个问题和用户问题的相似度,取最大相似度的目标。
    • jaccard_distance:使用Jaccard距离计算每个问题和用户问题的相似度,取最大相似度的目标。
    • bm25:使用BM25模型计算每个问题和用户问题的相关性,返回相关度分数。
    • word2vec:将用户输入问题转换为词向量,然后通过计算余弦相似度来衡量与每个目标下问题的相似度,返回相似度最高的目标。

    结果会被排序,并返回相关性最高的3个目标(或答案)。

2. 主程序部分

if __name__ == '__main__':
    qas = QASystem("data/train.json", "word2vec")
    question = "告诉我一下手机话费"
    res = qas.query(question)
    print(question)
    print(res)
  • 作用:在主程序中,实例化一个QASystem对象,并选择word2vec算法来进行意图识别。加载指定路径下的知识库文件(data/train.json)。
  • 然后,输入一个示例问题“告诉我一下手机话费”,调用query()方法进行查询,最后打印查询结果。

总结

本文代码通过不同的文本匹配算法(如BM25、Word2Vec等)来实现一个基于FAQ的智能问答系统。通过加载知识库中的问题,算法会根据用户的查询返回最相关的答案或目标。

全部代码

FAQ程序文件

import os
import json
import jieba
import numpy as np
from bm25 import BM25
from similarity_function import editing_distance, jaccard_distance
from gensim.models import Word2Vec

'''
基于faq知识库和文本匹配算法进行意图识别,完成单轮问答
'''

class QASystem:
    def __init__(self, know_base_path, algo):
        '''
        :param know_base_path: 知识库文件路径
        :param algo: 选择不同的算法
        '''
        self.load_know_base(know_base_path)
        self.algo = algo
        if algo == "bm25":
            self.load_bm25()
        elif algo == "word2vec":
            self.load_word2vec()
        else:
            #其余的算法不需要做事先计算
            pass

    def load_bm25(self):
        self.corpus = {}
        for target, questions in self.target_to_questions.items():
            self.corpus[target] = []
            for question in questions:
                self.corpus[target] += jieba.lcut(question)
        self.bm25_model = BM25(self.corpus)

    #词向量的训练
    def load_word2vec(self):
        #词向量的训练需要一定时间,如果之前训练过,我们就直接读取训练好的模型
        #注意如果数据集更换了,应当重新训练
        #当然,也可以收集一份大量的通用的语料,训练一个通用词向量模型。一般少量数据来训练效果不会太理想
        if os.path.isfile("model.w2v"):
            self.w2v_model = Word2Vec.load("model.w2v")
        else:
            #训练语料的准备,把所有问题分词后连在一起
            corpus = []
            for questions in self.target_to_questions.values():
                for question in questions:
                    corpus.append(jieba.lcut(question))
            #调用第三方库训练模型
            self.w2v_model = Word2Vec(corpus, vector_size=100, min_count=1)
            #保存模型
            self.w2v_model.save("model.w2v")
        #借助词向量模型,将知识库中的问题向量化
        self.target_to_vectors = {}
        for target, questions in self.target_to_questions.items():
            vectors = []
            for question in questions:
                vectors.append(self.sentence_to_vec(question))
            self.target_to_vectors[target] = np.array(vectors)

    # 将文本向量化
    def sentence_to_vec(self, sentence):
        vector = np.zeros(self.w2v_model.vector_size)
        words = jieba.lcut(sentence)
        # 所有词的向量相加求平均,作为句子向量
        count = 0
        for word in words:
            if word in self.w2v_model.wv:
                count += 1
                vector += self.w2v_model.wv[word]
        vector = np.array(vector) / count
        #文本向量做l2归一化,方便计算cos距离
        vector = vector / np.sqrt(np.sum(np.square(vector)))
        return vector

    def load_know_base(self, know_base_path):
        self.target_to_questions = {}
        with open(know_base_path, encoding="utf8") as f:
            for index, line in enumerate(f):
                content = json.loads(line)
                questions = content["questions"]
                target = content["target"]
                self.target_to_questions[target] = questions
        return

    def query(self, user_query):
        results = []
        if self.algo == "editing_distance":
            for target, questions in self.target_to_questions.items():
                scores = [editing_distance(question, user_query) for question in questions]
                score = max(scores)
                results.append([target, score])
        elif self.algo == "jaccard_distance":
            for target, questions in self.target_to_questions.items():
                scores = [jaccard_distance(question, user_query) for question in questions]
                score = max(scores)
                results.append([target, score])
        elif self.algo == "bm25":
            words = jieba.lcut(user_query)
            results = self.bm25_model.get_scores(words)
        elif self.algo == "word2vec":
            query_vector = self.sentence_to_vec(user_query)
            for target, vectors in self.target_to_vectors.items():
                cos = query_vector.dot(vectors.transpose())
                # print(cos)
                results.append([target, np.nanmean(cos)])
        else:
            assert "unknown algorithm!!"
        sort_results = sorted(results, key=lambda x:x[1], reverse=True)
        return sort_results[:3]


if __name__ == '__main__':
    qas = QASystem("data/train.json", "word2vec")
    question = "告诉我一下手机话费"
    res = qas.query(question)
    print(question)
    print(res)
    #
    # while True:
    #     question = input("请输入问题:")
    #     res = qas.query(question)
    #     print("命中问题:", res)
    #     print("-----------")

similarity_function程序文件

#编辑距离
def editing_distance(string1, string2):
    matrix = np.zeros((len(string1) + 1, len(string2) + 1))
    for i in range(len(string1) + 1):
        matrix[i][0] = i
    for j in range(len(string2) + 1):
        matrix[0][j] = j
    for i in range(1, len(string1) + 1):
        for j in range(1, len(string2) + 1):
            if string1[i - 1] == string2[j - 1]:
                d = 0
            else:
                d = 1
            matrix[i][j] = min(matrix[i - 1][j] + 1, matrix[i][j - 1] + 1, matrix[i - 1][j - 1] + d)
    edit_distance = matrix[len(string1)][len(string2)]
    return 1 - edit_distance / max(len(string1), len(string2))


#jaccard距离
def jaccard_distance(string1, string2):
    words1 = set(string1)
    words2 = set(string2)
    distance = len(words1 & words2) / len(words1 | words2)
    return distance

bm25程序文件

class BM25:
    EPSILON = 0.25
    PARAM_K1 = 1.5  # BM25算法中超参数
    PARAM_B = 0.6  # BM25算法中超参数

    def __init__(self, corpus: Dict):
        """
            初始化BM25模型
            :param corpus: 文档集, 文档集合应该是字典形式,key为文档的唯一标识,val对应其文本内容,文本内容需要分词成列表
        """
        self.corpus_size = 0  # 文档数量
        self.wordNumsOfAllDoc = 0  # 用于计算文档集合中平均每篇文档的词数 -> wordNumsOfAllDoc / corpus_size
        self.doc_freqs = {}  # 记录每篇文档中查询词的词频
        self.idf = {}  # 记录查询词的 IDF
        self.doc_len = {}  # 记录每篇文档的单词数
        self.docContainedWord = {}  # 包含单词 word 的文档集合
        self._initialize(corpus)


    def _initialize(self, corpus: Dict):
        """
            根据语料库构建倒排索引
        """
        # nd = {} # word -> number of documents containing the word
        for index, document in corpus.items():
            self.corpus_size += 1
            self.doc_len[index] = len(document)  # 文档的单词数
            self.wordNumsOfAllDoc += len(document)
            frequencies = {}  # 一篇文档中单词出现的频率
            for word in document:
                if word not in frequencies:
                    frequencies[word] = 0
                frequencies[word] += 1
            self.doc_freqs[index] = frequencies

            # 构建词到文档的倒排索引,将包含单词的和文档和包含关系进行反向映射
            for word in frequencies.keys():
                if word not in self.docContainedWord:
                    self.docContainedWord[word] = set()
                self.docContainedWord[word].add(index)

        # 计算 idf
        idf_sum = 0  # collect idf sum to calculate an average idf for epsilon value
        negative_idfs = []
        for word in self.docContainedWord.keys():
            doc_nums_contained_word = len(self.docContainedWord[word])
            idf = (math.log(self.corpus_size - doc_nums_contained_word + 0.5)
                   - math.log(doc_nums_contained_word + 0.5))
            self.idf[word] = idf
            idf_sum += idf
            if idf < 0:
                negative_idfs.append(word)

        average_idf = float(idf_sum) / len(self.idf)
        eps = BM25.EPSILON * average_idf
        for word in negative_idfs:
            self.idf[word] = eps

    @property
    def avgdl(self):
        return float(self.wordNumsOfAllDoc) / self.corpus_size


    def get_score(self, query: List, doc_index):
        """
        计算查询 q 和文档 d 的相关性分数
        :param query: 查询词列表
        :param doc_index: 为语料库中某篇文档对应的索引
        """
        k1 = BM25.PARAM_K1
        b = BM25.PARAM_B
        score = 0
        doc_freqs = self.doc_freqs[doc_index]
        for word in query:
            if word not in doc_freqs:
                continue
            score += self.idf[word] * doc_freqs[word] * (k1 + 1) / (
                    doc_freqs[word] + k1 * (1 - b + b * self.doc_len[doc_index] / self.avgdl))
        return [doc_index, score]

    def get_scores(self, query):
        scores = [self.get_score(query, index) for index in self.doc_len.keys()]
        return scores
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值