中医药天池大数据竞赛——中医文献问题生成挑战(一)
程序员文章站
2022-07-14 14:37:40
...
比赛详情见https://tianchi.aliyun.com/competition/entrance/531826/introduction
第一次读到这个比赛,脑子出跳出来的就是苏大神的bert4keras(https://github.com/bojone/bert4keras),因此,我就用bert4keras来做了,而且苏大神也给了我们example。
我给一下我用的一些包的版本:
tensorflow-gpu =2.1.0 keras=2.3.1 bert4keras=0.8.3
先来导包
import tensorflow as tf
import os
os.environ['CUDA_VISIBLE_DEVICES'] = "0"
import json, os
import numpy as np
from bert4keras.backend import keras, K
from bert4keras.layers import Loss
from bert4keras.models import build_transformer_model
from bert4keras.tokenizers import Tokenizer, load_vocab
from bert4keras.optimizers import Adam
from bert4keras.snippets import sequence_padding
from bert4keras.snippets import DataGenerator, AutoRegressiveDecoder
from bert4keras.snippets import text_segmentate
from keras.models import Model
from tqdm import tqdm
tf.test.is_gpu_available()
用tf.test.is_gpu_available()来判断gpu是否可用
需要的参数设置:
# 基本参数
max_p_len = 128
batch_size = 18
epochs = 20
# bert配置
config_path = './bert/publish/bert_config.json'
checkpoint_path = './bert/publish/bert_model.ckpt'
dict_path = './bert/publish/vocab.txt'
# 切分句子标志
seps, strips = u'\n。!?!?;;,, ', u';;,, '
# 文件路径
train_file = './data/round1_train_0907.json'
test_file = './data/round1_test_0907.json'
# K折交叉验证
k_folds = 5
数据处理:
def process_data(file_name):
with open(file_name,mode="rb") as f:
data_json = json.loads(f.read())
data = []
for line in data_json:
for p in line['annotations']:
if p['A']:
for t in text_segmentate(line['text'], max_p_len - 2, seps, strips):
if p['A'] in t:
data.append((t, p['Q'], p['A']))
return data
data = process_data(train_file)
这样生成了训练数据,(篇章,问题,答案)组合一条数据。
来看一下训练数据中问题和答案的长度情况:
def plot_process(data):
import matplotlib.pyplot as plt
q_len = list(map(lambda x:len(x[1]), data))
a_len = list(map(lambda x:len(x[2]), data))
print("max q_len: {}".format(max(q_len)))
print("max a_len: {}".format(max(a_len)))
plt.figure(figsize=[18,12])
plt.subplot(221)
plt.hist(x = q_len, bins = 20, color = 'steelblue', edgecolor = 'black', rwidth=0.7 )
# 添加x轴和y轴标签
plt.xlabel('q_len')
plt.ylabel('freq')
# 添加标题
plt.title('q_len distribution')
plt.subplot(222)
plt.boxplot(q_len) #垂直显示箱线图
plt.title('q_len distribution')
plt.subplot(223)
plt.hist(x = a_len, bins = 20, color = 'r', edgecolor = 'black', rwidth=0.7 )
# 添加x轴和y轴标签
plt.xlabel('a_len')
plt.ylabel('freq')
# 添加标题
plt.title('a_len distribution')
plt.subplot(224)
plt.boxplot(a_len) #垂直显示箱线图
plt.title('a_len distribution')
# 显示图形
plt.show()
plot_process(data)
因此我就把问题最大长度max_q_len设置成80,答案最大长度max_a_len也设置成80
接下来这段代码是用来产生随机数的,记录下来,方便用来做K折交叉验证:
def prodece_random_order(data):
# 保存一个随机序(供划分valid用)
if not os.path.exists('../user_data/random_order.json'):
random_order = list(range(len(data)))
np.random.shuffle(random_order)
json.dump(random_order, open('../user_data/random_order.json', 'w'), indent=4)
else:
random_order = json.load(open('../user_data/random_order.json'))
return random_order
接下来就是搭建模型,k折交叉验证了,下一篇继续。