当前位置:   article > 正文

简单的词性标注实战_nlp词性标注实战

nlp词性标注实战

定义

词性标注(Part-Of-Speech tagging, POS tagging)也被称为语法标注(grammatical tagging)或词类消疑(word-category disambiguation),是语料库语言学(corpus linguistics)中将语料库内单词的词性按其含义和上下文内容进行标记的文本数据处理技术 。常见的词性标注算法包括隐马尔可夫模型(Hidden Markov Model, HMM)、条件随机场(Conditional random fields, CRFs)等 。
词性标注主要被应用于文本挖掘(text mining)和NLP领域,是各类基于文本的机器学习任务,例如语义分析(semantic analysis)和指代消解(coreference resolution)的预处理步骤。

基于viterbi算法的词性标注

维特比算法(Viterbi algorithm)是一种动态规划算法,它用于寻找最可能产生观测到的事件的序列,这个序列是隐含状态序列,也叫维特比路径(Viterbi path)。观测序列即为分词后的语句,隐藏序列即为经过标注后的词性标注序列。初始状态概率向量,观测矩阵和状态转移矩阵,可以通过大规模语料统计得到。观测序列到隐藏序列的计算通过viterbi算法,利用统计得到的初始状态概率向量pi 观测矩阵A和状态转移矩阵A来得到。得到隐藏序列后,就完成了词性标注过程。在这里插入图片描述
下图为词典的一部分词语。每一行对应一个词语,分为三部分,分别为词语、分隔符以及词性。
在这里插入图片描述

完整代码

tag2id  , id2tag  = {} , {}
word2id , id2word = {} , {}

for line in open('D:/nlp/gitlab资料/2.23[直播]Viterbi实战/课程内容/Lesson9-CaseStudy-Viterbi/traindata.txt'):
    items = line.split('/')
    word , tag = items[0], items[1].rstrip()  # 提取每一行的单词和词性

    if word not in word2id :
        word2id[word] = len(word2id)
        id2word[len(id2word)] = word
    if tag not in tag2id :
        tag2id[tag] = len(tag2id)
        id2tag[len(id2tag)] = tag

M = len(word2id)  # 词典中单词数
N = len(tag2id)   # 词典中词性数

# 构造 pi ,A , B
import numpy as np
pi = np.zeros([N])       # 句子中第一个词性的概率
A = np.zeros([N,M])      # 每行为一种词性,每列为一个单词,A[i][j]表示在词性i下,出现单词j的概率
B = np.zeros([N,N])      # 行列均为词性,B[i][j]表示在词性i下,出现词性j的概率

pre_tag = ''
for line in open('D:/nlp/gitlab资料/2.23[直播]Viterbi实战/课程内容/Lesson9-CaseStudy-Viterbi/traindata.txt'):
    items = line.split('/')
    wordId, tagId = word2id[items[0]], tag2id[items[1].rstrip()]
    if pre_tag == '' :            #   此处意味着句子的开头
        pi[tagId] +=1
        A[tagId][wordId] +=1      # 统计在每个词性下,出现每个词的次数,用于后面转化为概率
    else :                        #   若不是句子的开头
        A[tagId][wordId] += 1
        B[tag2id[pre_tag]][tagId] +=1    # 统计在前个词性下,出现其它词性(包括自身)的次数

    if items[0] == '.' :
        pre_tag = ''
    else :
        pre_tag = items[1].rstrip()

# 将上述统计值转化为概率值
pi = pi/sum(pi)
for i in range(N):
    A[i] /= sum(A[i])
    B[i] /= sum(B[i])

def log(v):
    if v == 0:
        return np.log(v+0.000001)
    return np.log(v)

def viterbi(x,pi,A,B):
    """
    :param x: 用户输入的句子
    :param pi: 句子中第一个词性的概率
    :param A:  给定词性下,每个单词出现的概率
    :param B:  词性间的转移概率
    """
    x = [word2id[word] for word in x.split(' ')]    # x=[1,5,3....],句子中每个词的ID
    T = len(x)
    dp = np.zeros((T,N))  # dp[i][j]:存放在第i个word下是第j个tag的概率
    ptr = np.array([[0 for x in range(N)] for y in range(T)])   # T*N  或 ptr = np.zeros((T,N), dtype=int)
    for j in range(N):   # basecase for DP算法
        dp[0][j] = log(pi[j]) + log(A[j][x[0]])

    for i in range(1,T):    # 每个单词
        for j in range(N):    # 每个词性
            # TODO:以下几行代码可以写成一行(vectorize的操作, 会使得效率变高)
            dp[i][j] = -9999999
            for k in range(N):   # 从每一个k到达j
                score = dp[i-1][k] + log(A[j][x[i]]) + log(B[k][j])
                if score > dp[i][j] :
                    dp[i][j] = score
                    ptr[i][j] = k           # 存放选择的前一个最佳词性的位置
    # decoding: 打印最佳tag sequence
    best_seq = [0]*T
    # step1: 找出对应于最后一个单词的词性
    best_seq[T-1] = np.argmax(dp[T-1])

    # step2:  通过从后到前的循环来依次求出每个单词的词性
    for i in range(T-2,-1,-1):
        best_seq[i] = ptr[i+1][best_seq[i+1]]

    # 到目前为止, best_seq存放了对应于x的词性序列
    for i in range(len(best_seq)):
        print(id2tag[best_seq[i]])
        
x = "Social Security number , passport number and details about the services provided for the payment"
viterbi(x,pi,A,B)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87

结果显示

NNP
NNP
NN
,
NN
NN
CC
NNS
IN
DT
NNS
VBN
IN
DT
NN
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/599261
推荐阅读
相关标签
  

闽ICP备14008679号