词性标注的python实现-基于平均感知机算法

本文介绍了如何利用平均感知机算法进行词性标注。通过训练数据,使用平均感知机模型进行词性预测,涉及特征提取、权值更新和预处理步骤。在实验部分,对比了模型在不同语料上的准确率。
摘要由CSDN通过智能技术生成

平均感知机算法(Averaged Perceptron)

感知机算法是非常好的二分类算法,该算法求取一个分离超平面,超平面由w参数化并用来预测,对于一个样本x,感知机算法通过计算y = [w,x]预测样本的标签,最终的预测标签通过计算sign(y)来实现。算法仅在预测错误时修正权值w。
平均感知机和感知机算法的训练方法一样,不同的是每次训练样本xi后,保留先前训练的权值,训练结束后平均所有权值。最终用平均权值作为最终判别准则的权值。参数平均化可以克服由于学习速率过大所引起的训练过程中出现的震荡现象。

词性标注

词性标注是一个监督学习。先读入训练预料,利用平均感知机算法训练得到tagging模型,并存储在硬盘上。当需要进行词性预测时,首先从硬盘上加载tagging模型,再读入测试语料,进行自动标注。

过程说明

1、为了存储权值weights,建立了一个双层的字典,保存了特征->词性类别->权重,结构如图:
weights字典结构

2、从语料库中读取单词,当读取到”.”时,代表是一个句子的结尾,将前面的若干单词组成为一句话,形成一个sentence,存储在二元组中:例如([‘good’,’man’],[‘adj’,’n’])第一个列表是句子中的单词,第二个列表是单词对应的词性。语料库中的所有句子存储在列表training_data中(sentences),形如[ ([ ],[ ]), ([ ],[ ]), ([ ],[ ]) 。。。]

3、模型训练过程中,权值的更新是通过将(特征,正确词性)对应的特征权值+1,并且将(特征,错误词性)对应的特征权值-1。不仅增加正确词性对应的权值,还要惩罚错误词性对应的权值。

4、为了训练一个更通用的模型,在特征提取之前对数据进行预处理:

  • 所有英文词语都转小写
  • 四位数字并且在1800-2100之间的数字被转义为!YEAR
  • 其他数字被转义为!DIGITS
  • 当然还可以写一个专门识别日期、电话号码、邮箱等的模块,但目前先不拓展这部分

5、对第i个单词进行特征提取:

  • 单词的首字母
  • 单词的后缀
  • 第i-1个单词的词性
  • 第i-1个单词的后缀
  • 第i-2个单词的词性
  • 第i-2个单词的后缀
  • 第i+1个单词的词性,等等

实验

代码1:

AP_algorithm.py

# -*- coding:utf-8 -*-
# 平均感知机算法Averaged Perceptron:训练结束后平均所有权值,使用平均权值作为最终的权值

from collections import defaultdict
import pickle


class AveragedPerceptron(object):


    def __init__(self):
        # 每个'位置'拥有一个权值向量
        self.weights = {}
        self.classes = set()
        # 累加的权值,用于计算平均权值
        self._totals = defaultdict(int)  # 生成了一个默认为0的带key的数据字典
        self._tstamps = defaultdict(int) # 上次更新权值时的i
        self.i = 0   # 记录实例的数量

    def predict(self, features):  # 特征向量乘以权值向量,返回词性标签
        scores = defaultdict(float)
        for feat, value in features.items():
            if feat not in self.weights or value == 0:
                continue
            weights = self.weights[feat]
            for label, weight in weights.items():
                scores[label] += value * weight
        # 返回得分最高的词性
        return max(self.classes, key=lambda label: (scores[label], label)) # 返回得分最高的词性标签,如果得分相同取字母大的

    def update(self, truth, guess, features): # 更新权值

        def upd_feat(c, f, w, v): # c:正确的(或预测的)词性; f:feat某个特征; w:对应c的权值; v:1(或-1)
            param = (f, c)
            self._totals[param] += (self.i - self._tstamps[param]) * w  # 累加:(此时的i - 上次更新该权值时的i)*权值
            self._tstamps[param] = self.i # 记录更新此权值时的i
            self.weights[f][c] = w + v  # 更新权值

        self.i += 1
        if truth == guess:  # 如果预测正确,不做更新
  
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
实现中文分词和词性标注可以使用jieba和pynlpir这两个库,而TF-IDF的实现可以使用sklearn库。以下是Python代码实现: ```python import jieba import jieba.posseg as pseg import pynlpir from sklearn.feature_extraction.text import TfidfVectorizer # 分词和词性标注 def segment(text): # 使用jieba分词 words = jieba.cut(text) # 使用pseg标注词性 words_with_pos = pseg.cut(text) return [(word, flag) for word, flag in words_with_pos] # 初始化pynlpir pynlpir.open() # 分词和词性标注 def segment(text): # 使用pynlpir分词 words = pynlpir.segment(text) # 使用pynlpir标注词性 words_with_pos = pynlpir.postag(words) return [(word, flag) for word, flag in words_with_pos] # 计算TF-IDF def tfidf(texts): # 初始化TfidfVectorizer vectorizer = TfidfVectorizer() # 计算TF-IDF矩阵 tfidf_matrix = vectorizer.fit_transform(texts) # 获取关键词列表 feature_names = vectorizer.get_feature_names() # 遍历每个文本 for i in range(len(texts)): # 获取该文本的TF-IDF矩阵 tfidf_vector = tfidf_matrix[i] # 将该文本的关键词按照TF-IDF值从大到小排序 sorted_indices = tfidf_vector.toarray()[0].argsort()[::-1] # 获取该文本的前10个关键词 top_10 = [feature_names[j] for j in sorted_indices[:10]] print("Top 10 keywords in text ", i+1, ": ", top_10) # 测试代码 text1 = "这是一段测试文本,用于测试分词和词性标注。" text2 = "这是另外一段测试文本,用于测试TF-IDF关键词提取。" texts = [text1, text2] for text in texts: print(segment(text)) tfidf(texts) ``` 注意,使用pynlpir需要先安装pynlpir库,并且需要下载pynlpir所需的数据包。可以使用以下代码进行安装和下载: ```python import pynlpir # 安装pynlpir pynlpir.open() # 下载所需的数据包 pynlpir.nlpir.update() ``` 另外,TF-IDF的计算需要将文本转换为向量表示,因此需要使用TfidfVectorizer类。在调用fit_transform方法计算TF-IDF矩阵之前,需要先使用get_feature_names方法获取所有的关键词。最后,可以使用argsort方法对TF-IDF值进行排序,并获取前10个关键词。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值