python的词性标注

发布时间:2025-12-10 11:49:18 浏览次数:8

词性标注

这里写目录标题

  • 词性标注
    • 词性标注的特殊问题
    • 词性标注的方法
    • 设计简单标注器
    • 常用标注器介绍
    • 词性标注器的应用
      • 词性分布
      • 基于词性标注 研究词的组合

词性标注:在给定的句子中判定每个词的语法范畴,确定词性并加以标注的过程。

难点:兼类词的消歧,未登录词标注

在某具体的语言环境中,一个词只能属于某一类词性。

词性标注的特殊问题

  • 形态标准:不符合汉语划分;
  • 意义标准:参考作用;
  • 分布标准(功能标准);
  • 词性标注的方法

  • 基于规则的词性标注

  • 基于机器学习的词性标注
    无监督学习——聚类方法
    半监督学习——自训练算法、多视角算法、直推式

  • 基于规则与统计相结合的研究方法
    对句子的初始词性标注结果,首先规则消歧,再通过统计消歧,并对未登录词进行此行推测,最后进行人工校对,得到比较正确的标注结果。

  • 基于感知机的标注方法
    输入:词的特征集
    输出:标注结果(词类)

  • 马尔科夫链:将来的状态只与当前有关,短程依赖。
    隐含马尔可夫链HMM
    马尔科夫链:描述状态的转移,用转移概率描述;
    一般随机过程:描述状态与观察序列间的关系,用观察值概率描述。

    设计简单标注器

  • 默认标注器nltk.DefaultTagger
  • 只利用了词本身的统计信息。
    nltk的评估依据是一个标准测试数据,由人手工标注。

    import nltkfrom nltk.corpus import brownfrom nltk.probability import FreqDisttags = [tag for (word, tag) in brown.tagged_words(categories='news')]word = FreqDist(tags).max()# 结果:NNprint(word)brown_sents = brown.sents(categories='news')brown_tagged_sents = brown.tagged_sents(categories='news')dt = nltk.DefaultTagger(word) # 以word作为标注器的输出,设计标注器dt.tag(brown_sents[0]) # 对句子brown_sents[0]进行标注# 结果:0.13089484257215028print(dt.evaluate(brown_tagged_sents)) # 对标注器进行评估
  • 正则表达式标注器nltk.RegexpTagger
    利用词形知识初步提高性能。
  • 定义正则模式:正则表达式之间有一定的次序,前者优先。

    import nltkfrom nltk.corpus import brownfrom nltk.probability import FreqDistimport repatterns = [(r'.*ing$', 'VBG'), # gerunds 动名词(r'.*ed$', 'VBD'), # simple past(r'.*es$', 'VBZ'), # 3rd singular present(r'.*ould$', 'MD'), # modals情态动词(r'.*\'s$', 'NN$'), # possessive nouns名词所有格(r'.*s$', 'NNS'), # plural nouns 复数名词(r'^-?[0-9]+(.[0-9]+)?$', 'CD'), # cardinal numbers基数词(r'.*', 'NN') # nouns (default)]brown_sents = brown.sents(categories='news')brown_tagged_sents = brown.tagged_sents(categories='news')rt = nltk.RegexpTagger(patterns) # 定义正则表达式标注器rt.tag(brown_sents[0]) # 对句子brown_sents[0]进行标注# 结果:0.20326391789486245print(rt.evaluate(brown_tagged_sents)) # 对标注器进行评估
  • 查询标注器nltk.UnigramTagger
    利用词频知识进一步提高性能。
  • 实现:对高频词进行专门标记,找出前N(如100)最高频词的最可能标注。

    import nltkfrom nltk.corpus import brownfrom nltk.probability import FreqDist# 选择brown语料库中的词fd = nltk.FreqDist(brown.words(categories='news'))# 获得brown语料库中的词及其标注的分布cfd = nltk.ConditionalFreqDist(brown.tagged_words(categories='news')) # cfd是一个继承词典# 结果:{'AT': 5558, 'AT-TL': 18, 'AT-HL': 4}print(dict(cfd['the']))# 单词词性AT出现了5888次,词性AT-TL出现了18次,AT-HL出现了4次# 获取高频的N个词,并进行词的标注N = 100most_freq_words = [word for (word, num) in fd.most_common(N)]likely_tags = dict((word, cfd[word].max()) for word in most_freq_words)brown_sents = brown.sents(categories='news')brown_tagged_sents = brown.tagged_sents(categories='news')baseline_tagger = nltk.UnigramTagger(model=likely_tags) # 实现标注器baseline_tagger.tag(brown_sents[0]) # 标注句子# 结果:0.45578495136941344print(baseline_tagger.evaluate(brown_tagged_sents)) # 评估该标注器

    随着词数增加,标注器性能显著增加,一般设置3000词左右较合适。这部分的高频词一般是话题无关的。

  • 组合标注器
    理想的标注流程是:先使用查询标注器,若没查到,再使用默认标注器或者正则标注器。
  • # 之前的代码 略btr = nltk.UnigramTagger(model=likely_tags, backoff=dt) # 查询标注器和默认标注器组合btr.tag(brown_sents[0]) # 对句子brown_sents[0]进行标注# 结果:0.5817769556656125print(btr.evaluate(brown_tagged_sents)) # 评估该标注器btr = nltk.UnigramTagger(model=likely_tags, backoff=rt) # 查询标注器和正则标注器组合btr.tag(brown_sents[0]) # 对句子brown_sents[0]进行标注# 结果:0.6498697217415518print(btr.evaluate(brown_tagged_sents)) # 评估该标注器
  • 一元Uni-gram 二元Bi-gram标注器
    增加对上下文特性的考虑。

    在标注器的实现过程中,带标注的语料即是标注器的依据,根据每个词的标注频次,选择最高的作为其标注,这个过程称为“训练”。

    一元标注器Unigram Tagging

    siz = 100train_sents = brown_tagged_sents[siz:]test_sents = brown_tagged_sents[:siz]ug = nltk.UnigramTagger(train_sents) # 训练# 结果:[('the', 'AT'), ('man', 'NN'), ('is', 'BEZ')]print(list(ug.tag(['the', 'man', 'is'])))# 结果:0.8562610229276896print(ug.evaluate(test_sents)) # 评估

    二元标注器Bigram Tagging

    bg = nltk.BigramTagger(train_sents) # 训练# 结果:[('the', 'AT'), ('man', 'NN'), ('is', 'BEZ')]print(list(bg.tag(['the', 'man', 'is'])))# 结果:0.1318342151675485print(bg.evaluate(test_sents)) # 评估

    三元标注为Trigram n元标注为Ngram

    Bigram的问题数据稀疏:被标注的语料遇到新词,则无法正确标注。

  • n元组合标注器
    Bigram在单独使用时标注比例很低。

  • 常用标注器介绍

  • nltk的词性标注工具
  • word_lis = nltk.word_tokenize(str(text1)) # 词列表的构建nltk.pos_tag(word_lis) # 词串标记工具result = nltk.corpus.nps_chat.tagged_words()# 读取带标记的语料库nps_chat# 结果:[('now', 'RB'), ('im', 'PRP'), ('left', 'VBD'), ...]print(result)# 结果:('fly', 'NN')print(nltk.tag.str2tuple('fly/NN')) # 字符串标注转换为元组形式
  • thulac汉语词性标注工具
  • import thulacthu = thulac.thulac()# 结果:[['从', 'p'], ['繁体', 'n'], ['转换', 'v'], ['为', 'v'], ['简体', 'n'], ['。', 'w']] print(thu.cut("从繁体转换为简体。"))
  • jieba词性标注器
  • import jiebafrom jieba import possegpos = list(jieba.posseg.cut())

    词性标注器的应用

    词性分布

    在语料库中,查找最常见的词性。

    import nltkfrom nltk.corpus import brownbrown_news_tagged = brown.tagged_words(categories='news')tag_fd = nltk.FreqDist(tag for (word, tag) in brown_news_tagged)# 结果:[('NN', 13162), ('IN', 10616), ('AT', 8893)]print(tag_fd.most_common(3))

    基于词性标注 研究词的组合

  • 双词组合
  • 查找often之后的词。

    import nltkfrom nltk.corpus import browntext = brown.words(categories='news')bitext = nltk.bigrams(text)# 结果:['ambiguous', ',', 'hear', 'a', 'needs', 'that', 'in', 'enough', 'did', 'acceptable', 'mar', '.', 'obstructed', 'build']ss = [word for word in bitext]print([b for (a,b) in ss if a=='often']) # 得到全部紧邻在often后的词bd = brown.tagged_words(categories='news')bibd = nltk.bigrams(bd)# 结果:['JJ', ',', 'VB', 'AT', 'VBZ', 'CS', 'IN', 'QLP', 'DOD', 'JJ', 'VB', '.', 'VBD', 'VB'] print([b[1] for (a,b) in bibd if a[0]=='often']) # 得到的是often后的词的标注
  • 三词组合
  • 找到三词组合,中间词是to,前后都是动词。

    # 之前的代码 略tribd = nltk.trigrams(bd)lis = [(a[0],b[0],c[0]) for (a,b,c) in tribd if a[1].startswith('V') and c[1].startswith('V') and b[1]=='TO'] # 查找# 结果:344print(len(lis))
    需要做网站?需要网络推广?欢迎咨询客户经理 13272073477