中科院深度文本匹配开源项目MatchZoo简单上手

MatchZoo是一个Python环境下基于TensorFlow开发的开源文本匹配工具,让大家更加直观地了解深度文本匹配模型的设计、更加便利地比较不同模型的性能差异、更加快捷地开发新型的深度匹配模型。就我的理解,MatchZoo是实现了主要思想为孪生网络的深度模型

文本匹配包含了文本相似度、文本蕴含、问答匹配等问题,在这里,我会简单的使用微软公开的MSR数据集进行相似度计算解说,代码由本人参考matchzoo官方的解说完成的,如果有什么错误,请大胆指出,我会进一步改进。

数据集说明:MSR数据集是英文短文本相似度计算的标准数据集,其中训练集有4076个句子,其中包含2753个相似度为1,即为正例句子;测试集有1725个句子,其中包含1147个正例句子。
下载链接:https://www.microsoft.com/en-us/download/details.aspx?id=52398&from=http%3A%2F%2Fresearch.microsoft.com%2Fen-us%2Fdownloads%2F607d14d9-20cd-47e3-85bc-a2f65cd28042%2Fdefault.aspx
如果觉得麻烦,我已经下载好分享出来:https://download.csdn.net/download/weixin_40902563/12047069
赚积分不容易,如果没有积分,可以私聊并发邮箱,我会免费发送给你们(前提是我有看消息哈,大概两天一看)

官方提供的数据集是这样的格式:在这里插入图片描述
说它是tsv文件,但是用pandas去读的话,会有点错误,所以我采用readlines方式,分隔符用\t来切割每一行。
接下来代码开始,虽然我不是这种写代码的风格,但为了每一步说清楚,我会一段段解释一下。
导入的模块和定义数据处理器:

#!/usr/bin/python3
# -*- coding:utf-8 -*-
# Author:ChenYuan

import matchzoo as mz
import pandas as pd
import re  # 这个可以不用
from sklearn import preprocessing  # 用于正则化
import numpy as np 
preprocessor = mz.preprocessors.BasicPreprocessor()  # 定义一个数据处理器,有四种处理器,Basic是通用的、基础的数据处理器,可看官方文档,这里不做解说

数据格式转换:

data = []
data_type = 'train'
with open('msr_paraphrase_%s.txt' % data_type, 'r', encoding='utf-8')as f:
    for line in f.readlines()[1:]:  # 这个是为了忽略标题
        line = line.strip().split('\t')
        data.append([line[1], line[3], line[2], line[4], line[0]])  # 是为了方便matchzoo的输入格式
data = pd.DataFrame(data)
data.to_csv(train_data_path, header=False, index=False, sep='\t')

读取数据:

def load_data(data_path):
	df_data = pd.read_csv(data_path, sep='\t', header=None)
	df_data = pd.DataFrame(df_data.values, columns=['id_left', 'text_left', 'id_right', 'text_right', 'label'])
	df_data = mz.pack(df_data)
	reture df_data

train_data = load_data(train_data_path)  # 这里就是上面数据格式转换的训练集和测试集路径
test_data = load_data(test_data_path)

数据处理:

train_dev_split = int(len(train_data) * 0.9)  # 验证集占训练数据的0.1
train = train_data[:train_dev_split]
dev = train_data[train_dev_split:]
train_pack_processed = preprocessor.fit_transform(train)  # 其实就是做了一个字符转id操作,所以对于中文文本,不需要分词
dev_pack_processed = preprocessor.transform(dev)  
test_pack_processed = preprocessor.transform(test_data)
train_data_generator = mz.DataGenerator(train_pack_processed, batch_size=32, shuffle=True)  # 训练数据生成器

test_x, test_y = test_pack_processed.unpack()
dev_x, dev_y = dev_pack_processed.unpack()

定义模型:

def build():
    model = mz.models.DUET()  # 同样,DUET网络可看官网的论文,这里不做解释;同样,模型的参数不做解释,官方文档有
    ranking_task = mz.tasks.Ranking(loss=mz.losses.RankCrossEntropyLoss(num_neg=1))  # 定义损失函数,这里采用的是排序交叉熵损失函数,它还有一个分类交叉熵损失函数,看你如何定义你的数据
    model.params['input_shapes'] = preprocessor.context['input_shapes']
    model.params['embedding_input_dim'] = preprocessor.context['vocab_size']  # 如果版本较老,这里需要加1,因为要考虑一个UNK的字符,如果版本较新,这个以更新解决
    model.params['embedding_output_dim'] = 300 
    model.params['task'] = ranking_task
    model.params['optimizer'] = 'adam'
    model.params['padding'] = 'same'
    model.params['lm_filters'] = 32
    model.params['lm_hidden_sizes'] = [32]
    model.params['dm_filters'] = 32
    model.params['dm_kernel_size'] = 3
    model.params['dm_d_mpool'] = 3
    model.params['dm_hidden_sizes'] = [32]
    model.params['activation_func'] = 'relu'
    model.params['dropout_rate'] = 0.32
    model.params['embedding_trainable'] = True
    model.guess_and_fill_missing_params(verbose=0)
    model.params.completed()
    model.build()
    model.backend.summary()
    model.compile()
    return model

训练:

model = build()
batch_size = 32

evaluate = mz.callbacks.EvaluateAllMetrics(model, x=dev_x, y=dev_y, batch_size=batch_size)
model.fit_generator(train_data_generator, epochs=5, callbacks=[evaluate], workers=5, use_multiprocessing=False)
y_pred = model.predict(test_x)

left_id = test_x['id_left']
right_id = test_x['id_right']
assert (len(left_id) == len(left_id))
assert (len(left_id) == len(y_pred))
assert (len(test_y) == len(y_pred))
Scale = preprocessing.MinMaxScaler(feature_range=(0, 1))  # 对结果做规范化
y_pred = Scale.fit_transform(y_pred)

至此,代码结束,最后的这个结果y_pred是一个规范到0-1之间的分数,代表左句子和右句子的相似度打分,因为matchzoo生成的分数有大于1和小于0,就相似度来讲,大于1理论上不可能,相似度最大应该是1,最小小于0,所以采用了规范化,以便阈值的取值(也可以不用,直接取阈值也可以)。
对于MSR数据,评价指标有F1-macro和准确率(accuracy),需要将结果变成0和1再去和测试集结果求分数。这里就不给这个代码了,剩下的评价只是数组操作问题,最难的数据读取和模型训练已给出。

总结一下:

  1. matchzoo的Embedding层是采用keras的Embedding层来随机训练word2id序列,而且官方也提供了导入自己预训练词向量模型的方法,本人用Wiki的中文预训练模型尝试过很多次,一个是效率较低,一个是结果并不佳,所以在此也不写这份代码了。
  2. 为什么写了DUET?在我的机器中,这个模型效率是比较高的,而且效果是最好的,即便是只使用官方的初始模型参数。
  3. 我们实验并非采用这个数据集,我是特意找了这份数据集来写博客,也就是说,我的代码已经run通了。
  4. 对于DSSM和CDSSM模型的数据处理器,我们的机器无法运行,所以对于这两个模型,没有进行实验,但是我们自己复现了DSSM和CDSSM的模型。
  5. 学习matchzoo最大的宝藏我觉得不是会打代码,而且了解这些孪生网络结果,并自己复现才是最好的。
  6. 感谢大家能看到这里,谢谢支持。
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
对面向开发者的干货内容进行了梳理和总结: 一是理论。 过去一年间, AI 科技评论不断报道与人工智能技术相关的公开课程, 请来多个相关领域的资深学者, 持续解读基础概念, 为大家答疑解惑。 该栏目涵盖深度学习以及相关应用和延伸, 涉及自动驾驶、 语音、医疗、 人脸识别等方方面面。 二是工具。 AI 科技评论也在时刻关注着相关深度学习工具的动态和更新,如 TensorFlow、PyTorch、 Theano 等。 不仅如此, 我们还推出相关实战课程, 例如如何搭建系统进行图像识别。 除了底层工具,我们还关注大大小小的开源项目, 如 OpenBLAS、 阿里 Pouch、中科院 MatchZoo 等。 此外, 这一栏目也集结了腾讯、 阿里、英特尔等公司的深度学习解决方案。 三是赛事。 在与人工智能相关的一系列比赛中, 也能见到 AI 科技评论报道的身影。2017 年,我们对多个数据科学类的比赛进行跟踪报导, 涵盖 KDD Cup、 ICCV 2017 COCO&Places; 挑战赛、 DARPA 挑战赛、 京东金融全球数据探索者大赛等, 内容覆盖冠军解决方案、 赛事难点等多个层次, 冠军团队包括微软、 旷视等多家企业,清华大学、北京大学等多所高校。 希望大家能通过「理论」、「工具」、「赛事」 这 3 个栏目、 50 篇文章, 不断进阶,不断思考, 从理论走向实践, 成为一名优秀的开发者, 为人工智能社群贡献自己的一份力量。 也希望, AI 科技评论的这份总结和梳理能帮助到读者朋友们, 大家都能真正学有所获。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值