当前位置: 首页 > 工具软件 > kcws > 使用案例 >

kcws分词模型

海鸣
2023-12-01

下载kcws: git clone https://github.com/koth/kcws

切换到本项目代码目录,运行

./configure
cd kcws
./configure

词向量训练;

文本预处理:

python kcws/train/process_anno_file.py <语料目录> pre_chars_for_w2v.txt

编译词向量函数:

bazel build third_party/word2vec:word2vec

先得到初步词表

./bazel-bin/third_party/word2vec/word2vec -train pre_chars_for_w2v.txt -save-vocab pre_vocab.txt -min-count 3

处理低频词

python kcws/train/replace_unk.py pre_vocab.txt pre_chars_for_w2v.txt chars_for_w2v.txt

训练word2vec

./bazel-bin/third_party/word2vec/word2vec -train chars_for_w2v.txt -output vec.txt -size 50 -sample 1e-4 -negative 5 -hs 1 -binary 0 -iter 5

构建训练语料工具

bazel build kcws/train:generate_training

这里需要注意,源代码中的,generate_training输入为语料目录,若输入为文件,则需将

# for dirName, subdirList, fileList in os.walk(rootDir):
  # curDir = os.path.join(rootDir, dirName)
  # curDir = dirName
  # print("curDir is "+curDir)
  # for file in fileList:
  #   if file.endswith(".txt"):
  # curFile = os.path.join(curDir, file)

修改为:

curFile =rootDir

加入繁体转简体函数:

line=tradition2simple(line)#繁体转简体

同时,调试发现,函数processToken中,token = token[:nn - 1].strip()错误,例如token=’天安门广场’,此时处理为token=’天安门广’, 修改为token=token.strip()

之后,运行./bazel-bin/kcws/train/generate_training vec.txt

kcws/train/train_cws_lstm.py

可以设置预训练的字向量,batch size,learning_rate等.

分词原理

模型为双向lstm+crf.

即对于输入 input_sequence,将其输入lstm,得到正向lstm输出 forward_output,之后采用 tf.reverse_sequence()函数对input_sequence逆向处理,输入lstm得到后向输出backward_output_,将backward_output_逆向,得到backward_output,最后将backward_output和 forward_output串联得到bilstm的输出:

output = tf.concat(2, [forward_output, backward_output])

得到bilstm输出后,将output输入一个线性层(w,b)得到每个标签的得分unary_scores:

output = tf.reshape(output, [-1, self.numHidden * 2])
matricized_unary_scores = tf.batch_matmul(output, self.W)+self.b
unary_scores = tf.reshape(
    matricized_unary_scores,
    [-1, FLAGS.max_sentence_len, self.distinctTagNum])

将unary_scores输入crf得到预测概率:

log_likelihood, _ = tf.contrib.crf.crf_log_likelihood(
    P, Y, sequence_length,transition_params=self.transition_params)
loss = tf.reduce_mean(-log_likelihood)

解码得到输出序列:

viterbi_sequence, _ = tf.contrib.crf.viterbi_decode(
    tf_unary_scores_, transMatrix)

修改模型为固定bath_size,可变句子长度:

原模型batch_size可变,输入句子长度固定为80,在分词时,需要将小于80的句子padding,大于的切分为多个长度为80的短句,这时候如果在切分边界处恰好为一个词,则发生错误,因此需要将模型改为句子长度可变.

由于rnn使用的为tf.nn.dynamic_rnn可以允许输入长度不固定,因此只需要修改bilstm输入output与矩阵w相乘项即可,修改为:

unary_scores = tf.einsum('ijk,kl->ijl',output, self.W)+self.b

该项的意思是,对于每个输入句子的lstm输出output[:, ,],乘以w,且+b.

模型训练

采用hanlp分词聊天语料,预训练模型,之后采用人民日报,icwb2-data训练该模型.

模型测试

修改batch_size=1,添加输入句子length作为模型输入.

 类似资料: