词性标注语料预处理实战

此部分基于词性标注的数学表示后,针对给定的语料,做一些viterbi算法的一些预处理。

给定的语料格式如下所示:

it/PRP
will/MD
introduce/VB
a/DT
new/JJ
incentive/NN
plan/NN
for/IN
advertisers/NNS
./.

其中每行是一个单词和其词性标注,用/分割,每个句子的结尾用./.作为结束标志。则基于上述说明,我们对训练语料进行预处理,代码如下所示:

# 词性与对应id的词典对应关系,比如tag2id={"NNP":0, "VBG":1, ..., } id2tag={0:"NNP", 1:"VBG", ..., }
tag2id, id2tag = {}, {}
# 词与对应id的词典对应关系
word2id, id2word = {}, {}
# 读取训练文件,做预处理
for line in open("traindata.txt"):
    items = line.split("/")
    word, tag = items[0], items[1].rstrip()  # 提取每一行里面的单词和词性
    if word not in word2id:
        word2id[word] = len(word2id)
        id2word[len(word2id)] = word
    if tag not in tag2id:
        tag2id[tag] = len(tag2id)
        id2tag[len(id2tag)] = tag

M = len(word2id)  # 词典的大小, num of words in dictionary
N = len(tag2id)  # 词性的种类个数, num of tags in tag set

# print(tag2id)
# print(id2tag)
#
# print(M)
# print(N)

# 基于上述处理,构建pi、A、B
import numpy as np

pi = np.zeros(N)  # pi标识每个词性出现在句子第一个位置的概率
A = np.zeros((N, M))  # A[i][j]给定tag i,出现单词j的概率
B = np.zeros((N, N))  # B[i][j]词性从状态i转移到j的概率

# 计算pi 、 A 、B
prev_tag = ""
for line in open("traindata.txt"):
    items = line.split("/")
    # 获取单词和词性对应的id
    wordId, tagId = word2id[items[0]], tag2id[items[1].rstrip()]
    if prev_tag == "":    # 意味着句子的开头
        pi[tagId] += 1  # 计算每个开头词性出现的次数,后面再根据次数计算概率值
        A[tagId][wordId] += 1   # 计算该词性对应的单词出现的次数
    else:   # 如果不是句子开头
        A[tagId][wordId] += 1
        B[tag2id[prev_tag]][tagId] += 1 # 计算该词性出现时其上一个词性出现的次数
    if items[0] == ".":
        prev_tag = ""
    else:
        prev_tag = items[1].rstrip()

# normalize
pi = pi/sum(pi)
for i in range(N):
    A[i] /= sum(A[i])
    B[i] /= sum(B[i])

# print(pi)
# print(A)
# print(B)

打印pi结果如下所示:

[1.81324111e-01 0.00000000e+00 1.00049407e-02 3.33498024e-03
 3.95256917e-03 3.68083004e-02 1.11660079e-01 3.66847826e-02
 6.17588933e-04 3.81669960e-02 8.76976285e-03 5.18774704e-02
 6.02766798e-02 2.47035573e-04 2.17267787e-01 0.00000000e+00
 1.48221344e-03 6.05237154e-03 8.64624506e-04 2.47035573e-04
 0.00000000e+00 4.73073123e-02 0.00000000e+00 7.16403162e-03
 1.72924901e-03 2.09980237e-03 7.53458498e-02 6.36116601e-02
 2.59387352e-03 1.85276680e-03 5.92885375e-03 1.97628458e-03
 2.84090909e-03 0.00000000e+00 0.00000000e+00 2.71739130e-03
 5.92885375e-03 5.92885375e-03 9.88142292e-04 3.70553360e-04
 1.23517787e-04 0.00000000e+00 0.00000000e+00 1.85276680e-03
 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00
 0.00000000e+00 0.00000000e+00]

通过上述处理后,我们可以得到矩阵A、pi、B,及在上节中我们说明的值。其中A是词性为 \(t_i\)的词\(w_i\)的概率,\(\pi\)可以解释为开头的词性概率,B可解释为为词性\(t_{i-1}\)到词性\(t_i\)转移的概率。

你可能感兴趣的:(词性标注语料预处理实战)