前言

最近在重刷李航老师的《统计机器学习方法》尝试将其与NLP结合,通过具体的NLP应用场景,强化对书中公式的理解,最终形成「统计机器学习方法 for NLP」的系列。这篇将介绍条件随机场CRF(绝对给你一次讲明白)并基于CRF完成一个词性标注的任务。

CRF是什么

条件随机场(Conditional random field, CRF)是一个NLP领域广泛使用的模型,即使在深度学习时代也是如此。尤其在序列标注任务上,DNN+CRF依然是目前最主流的范式。 CRF是一个判别式模型,通过训练数据直接学习输入序列

和对应的标签序列
的条件概率
。相比于逻辑回归(Logistic Regression)的分类,CRF能学习到标签之间的序列关系来辅助分类。例如在词性标注任务中,如果之前上一个词的词性是「动词」,那么当前词的词性就很小的概率依然是「动词」,因为「动词」后面继续跟「动词」是小概率事件。

马尔可夫随机场

条件随机场CRF中的随机场指的是马尔可夫随机场。马尔可夫随机场满足马尔可夫随机性,即节点

上的随机变量
只与跟节点
直接相连的节点有关。所以我们就可以把一个无向图上随机变量进行因式分解,写成「最大团」乘积的形式。这里「最大团」指的是一个子图
中的任何两个节点都有边相连(这就是「团」),并且在这个子图
上不能再添加一个新的节点使其构成一个更大的团。例如下图中的{A,B,C}就是一个最大团。

所以随机变量

可以写成下面的形式,
为图中的一个最大团:

这里

是全部可能的
的概率加和,用来进行概率的归一化(类似softmax);这里的
是一个严格意义上正函数,一般取指数函数。

条件随机场

当马尔可夫随机场中有一部分节点是确定节点

,这时候就是求解在
的条件下,
的概率,即
。我们可以继续按照「最大团」进行概率展开:

线性链条件随机场

NLP任务中一般为上图所示的线性链随机场,

均为线性表示的序列,即
。这里我们称已知变量(确定变量)
为观测变量,未知变量(随机变量)
为隐变量。如上图所示,在图上的边只有
(观测变量和对应的隐变量的边)以及
(相邻的两个隐变量的边)。

所以图中的最大团只有两部分构成:(1) 观测变量和对应的隐变量之间

(2) 相邻的隐变量之间
。 根据上面的公式进行展开:

进一步将

写成指数函数的形式,概率相乘就会转写成指数相加的形式:

这里

为特征函数,函数值为1或者0,满足特征为1,不满足特征为0;其中
为定义在节点的特征函数,称之为状态特征,依赖当前位置;
为定义在边的特征函数,称之为转移特征,依赖当前和前一个位置。
为特征函数对应的系数,
依然是归一化因子。

再进一步,我们可以将这两类最大团合并进行形式上的简化,所以可以写成下面的形式:

这就是线性CRF最终推出的公式了 !!!

额外补充

特征函数:可以看到特征函数与4个变量有关:(1) 整体的观测变量

(2) 当前位置
(3) 当前的隐变量
(4) 前一个隐变量
。所以在词性标注的例子中,整体的观测变量就是输入的句子
, 当前位置就是当前的单词
,当前的隐变量就是当前的位置的词性标签
,前一个隐变量就是前一个单词的词性标签
。这时候我们就可以定义特征函数,例如:如果句子的结尾是问号,当前的单词为第一个单词,且当前单词的词性为动词,那么函数输出为1,否则为0。如果这个特征函数的权重越大,说明这种范式越正确,即问句的第一个词的词性是动词的概率较大,比如:“吃饭了吗?”

与HMM的关系:HMM在之前的文章中专门介绍过,具体参见:胡勇:统计机器学习方法 for NLP:基于HMM的词性标注 。先说结论,HMM是一种特殊的CRF。下面进行推倒,首先对于HMM:

写成log相加的形式:

接着我们通过定义两类特征函数就能转变成CRF的形式:

首先定义一类特征函数,对于HMM中的两个tag

的转移概率
,定义特征函数
,如果
那么函数
为1,否则函数
为0,同时这个函数对应的特征权重就是
的转移概率

首先定义一类特征函数,对于HMM中的tag

到单词
的发射概率
,定义特征函数
,如果
那么函数
为1,否则函数
为0,同时这个函数对应的特征权重就是
的发射概率

所以我们可以看到HMM是一种特殊的CRF,同时具有两方面的局限性:(1) HMM是局部特征而非全局特征,也就是没有利用

整体的特征,而CRF可以利用整个句子的全局特征 (2) HMM中的写成CRF特征函数的形式后,权重就是概率值,所以有加和为1的限制,而CRF没有系数和的限制。

模型训练与预测

在定义了特征函数之后,CRF模型本质是一个线性的模型,模型的参数就是特征函数的权重,这里可以采用「梯度下降」的方法学习模型参数。模型训练之后,预测阶段可通过viterbi算法进行解码,来获得最优的隐变量序列。

基于CRF的词性标注

词性标注任务是指给定一句话,给这种话中的每个词都标记上词性,例如动词/形容词等。例如给定句子:“I love China”, 需要输出: (I: 代词, love: 动词, China: 名词),具体可以参见HMM章节中对词性标注任务的介绍:胡勇:统计机器学习方法 for NLP:基于HMM的词性标注。

下面将分为:数据处理,模型训练,模型预测 三个部分来介绍如何利用CRF实现词性标注,具体参考的是这篇工作:NLP Guide: Identifying Part of Speech Tags using Conditional Random Fields 。

数据处理

这里采用的数据集是:NLTK Treebank 。获取数据并切分数据集为训练集和测试集。

tagged_sentence = nltk.corpus.treebank.tagged_sents(tagset='universal')
print("Number of Tagged Sentences ",len(tagged_sentence))
tagged_words=[tup for sent in tagged_sentence for tup in sent]
print("Total Number of Tagged words", len(tagged_words))
vocab=set([word for word,tag in tagged_words])
print("Vocabulary of the Corpus",len(vocab))
tags=set([tag for word,tag in tagged_words])
print("Number of Tags in the Corpus ",len(tags))
“”“
Number of Tagged Sentences  3914
Total Number of Tagged words 100676
Vocabulary of the Corpus 12408
Number of Tags in the Corpus  12
”“”
train_set, test_set = train_test_split(tagged_sentence,test_size=0.2,random_state=1234)
print("Number of Sentences in Training Data ",len(train_set))
print("Number of Sentences in Testing Data ",len(test_set))
“”“
Number of Sentences in Training Data  3131
Number of Sentences in Testing Data  783
”“”

模型训练

首先我们手工定义一组特征函数(状态特征函数),例如「第一个字母是不是大写」,「是不是第一个单词」,「是不是最后一个单词」,「前一个单词」,「后一个单词」等,并从数据集中进行特征的抽取:

# 特征定义
def features(sentence,index):### sentence is of the form [w1,w2,w3,..], index is the position of the word in the sentencereturn {'is_first_capital':int(sentence[index][0].isupper()),'is_first_word': int(index==0),'is_last_word':int(index==len(sentence)-1),'is_complete_capital': int(sentence[index].upper()==sentence[index]),'prev_word':'' if index==0 else sentence[index-1],'next_word':'' if index==len(sentence)-1 else sentence[index+1],'is_numeric':int(sentence[index].isdigit()),'is_alphanumeric': int(bool((re.match('^(?=.*[0-9]$)(?=.*[a-zA-Z])',sentence[index])))),'prefix_1':sentence[index][0],'prefix_2': sentence[index][:2],'prefix_3':sentence[index][:3],'prefix_4':sentence[index][:4],'suffix_1':sentence[index][-1],'suffix_2':sentence[index][-2:],'suffix_3':sentence[index][-3:],'suffix_4':sentence[index][-4:],'word_has_hyphen': 1 if '-' in sentence[index] else 0}def untag(sentence):return [word for word,tag in sentence]def prepareData(tagged_sentences):X,y=[],[]for sentences in tagged_sentences:X.append([features(untag(sentences), index) for index in range(len(sentences))])y.append([tag for word,tag in sentences])return X,y# 特征抽取
X_train,y_train=prepareData(train_set)
X_test,y_test=prepareData(test_set)

下面简单看一下抽取出来的特征:

[{'is_alphanumeric': 0,'is_complete_capital': 0,'is_first_capital': 1,'is_first_word': 1,'is_last_word': 0,'is_numeric': 0,'next_word': 'Wall','prefix_1': 'O','prefix_2': 'On','prefix_3': 'On','prefix_4': 'On','prev_word': '','suffix_1': 'n','suffix_2': 'On','suffix_3': 'On','suffix_4': 'On','word_has_hyphen': 0},{'is_alphanumeric': 0,'is_complete_capital': 0,'is_first_capital': 1,'is_first_word': 0,'is_last_word': 0,'is_numeric': 0,'next_word': 'Street','prefix_1': 'W','prefix_2': 'Wa','prefix_3': 'Wal','prefix_4': 'Wall','prev_word': 'On','suffix_1': 'l','suffix_2': 'll','suffix_3': 'all','suffix_4': 'Wall','word_has_hyphen': 0},
...
]

以及对应的标签:

['ADP','NOUN','NOUN',
...
]

接着使用sklearn-crfsuite - sklearn-crfsuite 0.3 documentation 进行模型训练:

from sklearn_crfsuite import CRF
crf = CRF(algorithm='lbfgs',c1=0.01,c2=0.1,max_iterations=100,all_possible_transitions=True
)
crf.fit(X_train, y_train)

模预预测

对测试集进行预测,并计算F1指标

y_pred=crf.predict(X_test)
metrics.flat_f1_score(y_test, y_pred,average='weighted',labels=crf.classes_)
“”“
0.9738471726864286
”“”

可以看到最终评估指标高达97.3% 表明抽取的特征很有效,CRF也是一个很强的模型。

下面看一下头部的转移特征和状态特征:

# 头部的转移特征
[(('ADJ', 'NOUN'), 4.114996),(('NOUN', 'NOUN'), 2.935448),(('NOUN', 'VERB'), 2.891987),(('VERB', 'PRT'), 2.519179),(('X', 'VERB'), 2.271558),(('ADP', 'NOUN'), 2.265833),(('NOUN', 'PRT'), 2.172849),(('PRON', 'VERB'), 2.117186),(('NUM', 'NOUN'), 2.059221),(('DET', 'NOUN'), 2.053832),(('ADV', 'VERB'), 1.994419),(('ADV', 'ADJ'), 1.957063),(('NOUN', 'ADP'), 1.838684),(('VERB', 'NOUN'), 1.763319),(('ADJ', 'ADJ'), 1.660578),(('NOUN', 'CONJ'), 1.591359),(('PRT', 'NOUN'), 1.398473),(('NOUN', '.'), 1.381863),(('NOUN', 'ADV'), 1.380086),(('ADV', 'ADV'), 1.301282)]
# 头部的状态特征
[(('prev_word:will', 'VERB'), 6.751359),(('prev_word:would', 'VERB'), 5.940819),(('prefix_1:*', 'X'), 5.830558),(('suffix_4:rest', 'NOUN'), 5.644523),(('suffix_2:ly', 'ADV'), 5.260228),(('is_first_capital', 'NOUN'), 5.043121),(('prev_word:could', 'VERB'), 5.018842),(('suffix_3:ous', 'ADJ'), 4.870949),(('prev_word:to', 'VERB'), 4.849822),(('suffix_4:will', 'VERB'), 4.677684),(('next_word:appeal', 'ADJ'), 4.386434),(('prev_word:how', 'PRT'), 4.35094),(('suffix_4:pany', 'NOUN'), 4.329975),(('prefix_4:many', 'ADJ'), 4.205028),(('prev_word:lock', 'PRT'), 4.153643),(('word_has_hyphen', 'ADJ'), 4.151036),(('prev_word:tune', 'PRT'), 4.147576),(('next_word:Express', 'NOUN'), 4.137127),(('suffix_4:food', 'NOUN'), 4.116688),(('suffix_2:ed', 'VERB'), 4.070659)]

根据转移特征('ADJ', 'NOUN')可以看到「形容词」后面接「名词」的概率非常高;根据状态特征('prev_word:will', 'VERB')可以看到如果上一个单词是will,那么当前词的词性为「动词」的概率非常高。

本篇的CRF还处于统计学习阶段,所以构建的特征也都是手工构建的特征,还是存在一定的局限性。所以后来在深度学习时代,一般会先用LSTM或者BERT这种深度神经网络先进行特征的抽取,再送到CRF进行标签的预测,能有更加显著的效果提升。

参考

Introduction to Conditional Random Fields

NLP Guide: Identifying Part of Speech Tags using Conditional Random Fields

https://github.com/AiswaryaSrinivas/DataScienceWithPython/blob/master/CRF%20POS%20Tagging.ipynb

统计机器学习方法 for NLP:基于CRF的词性标注相关推荐

  1. 统计机器学习方法 for NLP:基于HMM的词性标注

    前言 最近在重刷李航老师的<统计机器学习方法>尝试将其与NLP结合,通过具体的NLP应用场景,强化对书中公式的理解,最终形成「统计机器学习方法 for NLP」的系列.这篇将介绍隐马尔可夫 ...

  2. 基于机器学习方法的POI品类推荐算法

    前言 在美团商家数据中心(MDC),有超过100w的已校准审核的POI数据(我们一般将商家标示为POI,POI基础信息包括:门店名称.品类.电话.地址.坐标等).如何使用这些已校准的POI数据,挖掘出 ...

  3. 李航老师新作《机器学习方法》上市了!附购买链接

    李航老师的<统计学习方法>第一版于 2012年出版,讲述了统计机器学习方法,主要是一些常用的监督学习方法.第二版增加了一些常用的无监督学习方法,由此本书涵盖了传统统计机器学习方法的主要内容 ...

  4. 统计学习-机器学习方法概论

    统计学习-机器学习方法概论 机器学习的对象是:具有一定的统计规律的数据. 机器学习根据任务类型,可以划分为: 监督学习任务:从已标记的训练数据来训练模型. 主要分为:分类任务.回归任务.序列标注任务. ...

  5. 机器学习实验笔记-基于信用卡数据建立行为评分模型的机器学习方法

    基于信用卡数据建立行为评分模型的机器学习方法 很久之前的一个答疑, 应该不会再影响评分了, 记录以供复习. 数据集与代码放在CSDN下载区域, 也可以留言索要. https://download.cs ...

  6. 基于python多光谱遥感数据处理、图像分类、定量评估及机器学习方法

    普通数码相机记录了红.绿.蓝三种波长的光,多光谱成像技术除了记录这三种波长光之外,还可以记录其他波长(例如:近红外.热红外等)光的信息.与昂贵.不易获取的高光谱.高空间分辨率卫星数据相比,中等分辨率的 ...

  7. 基于 python 多光谱遥感数据处理、图像分类、定量评估及机器学习方法

    普通数码相机记录了红.绿.蓝三种波长的光,多光谱成像技术除了记录这三种波长光之外,还 可以记录其他波长(例如:近红外.热红外等)光的信息.与昂贵.不易获取的高光谱.高空间分辨 率卫星数据相比,中等分辨 ...

  8. 谷歌AI论文BERT双向编码器表征模型:机器阅读理解NLP基准11种最优(公号回复“谷歌BERT论文”下载彩标PDF论文)

    谷歌AI论文BERT双向编码器表征模型:机器阅读理解NLP基准11种最优(公号回复"谷歌BERT论文"下载彩标PDF论文) 原创: 秦陇纪 数据简化DataSimp 今天 数据简化 ...

  9. 《Python自然语言处理-雅兰·萨纳卡(Jalaj Thanaki)》学习笔记:08 自然语言处理中的机器学习方法

    08 自然语言处理中的机器学习方法 8.1 机器学习的基本概念 8.1.1 ML类型 8.1.2 ML 监督学习 8.1.3 无监督学习 8.1.4 强化学习 8.2 自然语言处理应用的开发步骤 8. ...

最新文章

  1. Vivado下几条 Verilog 综合规则
  2. boxfilter 函数
  3. 查看mysql表中的所有索引
  4. 项目管理基础:系统评价相关知识
  5. 对于“知识”,我们存在哪些误解?
  6. matlab光学毕业论文,光学信息处理实验的Matlab仿真.doc
  7. Apache Hawq--优化笔记
  8. php表格合并_如何在php生成的表中合并单元格?
  9. php 量 高并发 nosql,nosql - 高并发下Apache+mongodb的php驱动不稳定
  10. [来自软件No1]XP Skin Pack系统主题-把windows 7变回xp的模样
  11. 医药箱APP静态小项目
  12. 证件照排版软件_傻瓜式证件照片排版以及尺寸的调整
  13. 元胞自动机:森林火灾模拟(Python:numpy、seaborn)
  14. R中设置图形参数--函数par()详解
  15. 潘丽云:魏尔斯特拉斯的复变函数思想分析(2009)(2011-01-14 22:34:30)
  16. 如何在QII中直接调用ModelSim
  17. 提取QQ游戏图标并显示
  18. 武汉第一职业教育中心计算机技能高考,武汉市第一职业教育中心2019年招生简章...
  19. python脚本计算STM32的bxCAN的波特率
  20. 关于svn在eclipse中上传和拉取代码

热门文章

  1. Android设置“沉浸式状态栏”的方法
  2. vue+element模仿腾讯视频电影网站(二),增加视频播放详情页
  3. 数字孪生三维可视化平台是什么?
  4. [OpenSceneGraph入门指导]1.6 OpenSceneGraph 概览
  5. 天下武功为快不破,戏说Python与Go高并发争锋!
  6. iCloud7_Next Steps
  7. docker部署fastapi
  8. QT的安装 [新版2022]
  9. 拓视角丨拓宽市场边界,数字化智能化转型构建产业新格局
  10. 作者写书自己出版的一个讨论