pip install sklearn-crfsuite 一个序列到另外一个序列,这是NLP做的事,也叫seq to seq NLP是深度学习模型, 机器学习模型中能处理序列前后关系的还有HMM,但HMM只考虑前后依赖 CRF可考虑上下文,但还是一个序列到序列 CRF对数据集的要求 - python 列表 - 元素为字符串 - 训练集与标签,元素个数要对上 [["准备","吃饭"]] -- ["走起","<PAD>"] 标签只有一个单词,用个标签补一下 数据矩阵化时,通常都对齐,不足的填补一下 |
X=[["你","几点","上班"],["你","几点","下班"],["你","开心","吗"]] y=[["八点","半","<PAD>"],["五点","半","<PAD>"],["别","问","这个"]] X_train = [] for val in X: X_train.append([str(x.encode('utf-8')) for x in val]) y_train = [] for val in y: y_train.append([str(x.encode('utf-8')) for x in val]) from sklearn_crfsuite import CRF import numpy as np # 定义CRF模型 crf = CRF( algorithm='lbfgs', c1=0.1, c2=0.1, max_iterations=100, all_possible_transitions=True ) # 训练模型 crf.fit(X_train, y_train) # 就简单点,直接拿训练做测试 X_test = X_train # 预测 y_pred = crf.predict(X_test) for val in y_pred: print([eval(v).decode('utf-8') for v in val]) ['八点', '半', '<PAD>'] ['八点', '半', '<PAD>'] ['别', '问', '这个'] 注意,第二句预测的不对,看来上下文处理能力还是没有RNN强 三句话,第一个单词就是你,最后一个序列预测正常,说明有一定上下文处理能力 如果我把数据集改为下面的内容,即针对错误,增加五点半出现的概率 X=[["你","几点","上班"],["你","几点","下班"],["你","几点","下班"],["你","开心","吗"]] y=[["八点","半","<PAD>"],["五点","半","<PAD>"],["五点","半","<PAD>"],["别","问","这个"]] 预测结果为,充分显示了CRF按概率办事的特点 ['五点', '半', '<PAD>'] ['五点', '半', '<PAD>'] ['五点', '半', '<PAD>'] ['别', '问', '这个'] 总结 CRF处理序列的能力差: 概率大者会被选择 |
x*x +2*x+1 X = [ [1, 1, 0, 2, 0, 0], [0, 1, 1, 0, 4, 0], [0, 0, 1, 1, 0, 8], [0, 3, 0, 0, 1, 1], ] X_train = [] y_train = [] for word_index in X: X_train.append([str(x) for x in word_index]) y_train.append([str(x*x +2*x+1) for x in word_index]) from sklearn_crfsuite import CRF import numpy as np # 定义CRF模型 crf = CRF( algorithm='lbfgs', c1=0.1, c2=0.1, max_iterations=100, all_possible_transitions=True ) # 训练模型 crf.fit(X_train, y_train) # 就简单点,直接拿训练做测试 X_test = X_train # 预测 y_pred = crf.predict(X_test) print(np.array(y_pred)) [['4' '4' '1' '9' '1' '1'] ['1' '4' '4' '1' '25' '1'] ['1' '1' '4' '4' '1' '81'] ['1' '16' '1' '1' '4' '4']] y_train [['4', '4', '1', '9', '1', '1'], ['1', '4', '4', '1', '25', '1'], ['1', '1', '4', '4', '1', '81'], ['1', '16', '1', '1', '4', '4']] 为什么公式会预测的这么准? 因为公式完全,100%是一对一/多对一, 即对于给定的x,有唯一的y与之对应, 从概率的角度讲, 1对应4的概率是100%, 0对应1的概率是100%, ... 不重不漏,相互独立,准的不能再准了... 即只要能满足,对于x有唯一的y, 别说一元2次方程了, 不管这公式有多复杂,都100%预测正确 |
条件随机场CRF模型 条件随机场(CRF)是一种用于建模 输入序列与输出序列 之间的依赖关系的 统计模型。 CRF广泛应用于各种自然语言处理任务,如词性标注、命名实体识别和语义角色标注等。 CRF的主要优点是能够明确地建模观测数据与标签之间的依赖关系, 同时考虑整个序列的上下文信息。 CRF基于图模型,其中输入序列表示为节点,依赖关系表示为边。 CRF的主要目标是学习一个条件概率分布,用于预测输出序列中的标签。 具体而言,给定输入序列𝑥和输出序列𝑦,CRF试图通过最大化条件概率𝑃(𝑦|𝑥)来学习权重参数。 ![]() |
优点:处理简单的映射关系没有问题 1.模型表现力强:CRF能够对标记之间的依赖关系建模,因此能够处理更加复杂的序列标注任务。 2.预测准确率高:CRF对于模型训练和预测都采用了统计学习的方法,所以预测准确率相对比较高。 3.可解释性强:CRF的特征函数定义比较直观,因此可以帮助我们理解模型的预测过程。 缺点 1.训练速度比较慢:CRF需要对整个训练集进行参数估计,时间复杂度较高,对于大规模数据集训练过程比较缓慢。 2.特征选择比较困难:CRF的性能比较依赖于特征函数的选择和设计,因此需要手动设计特征函数。 3.对于没有显式标记的数据来说准确率会比较低。 |
处理简单的映射关系没问题的 条件随机场(Conditional Random Fields,CRF)是一种机器学习模型,用于处理序列标注问题。 在给定一组输入随机变量条件下,CRF可以预测另外一组输出随机变量的条件概率分布。这种模型在自然语言处理(NLP)和图像处理等领域有着广泛的应用。 以自然语言处理中的命名实体识别(Named Entity Recognition,NER)为例,CRF可以用于识别文本中的实体,如人名、地名、组织名等。在这个任务中,输入随机变量可以是文本中的单词或字符,输出随机变量则是每个单词或字符的实体标签。 假设我们有一个简单的命名实体识别任务,输入文本为“John Doe works at Google in Mountain View”,目标是识别出人名“John Doe”和公司名“Google”。我们可以使用CRF来完成这个任务。 首先,我们需要定义特征函数,用于提取输入文本中的特征。例如,我们可以定义以下特征函数: 如果当前单词的首字母大写,则特征值为1,否则为0。 如果当前单词的前一个单词是介词(如“at”、“in”等),则特征值为1,否则为0。 然后,我们可以使用这些特征函数来构建CRF模型。在训练阶段,我们使用标注好的数据来训练模型,学习条件概率分布P(Y|X),其中X是输入序列(文本中的单词或字符),Y是输出序列(实体标签)。在测试阶段,给定一个新的输入序列,我们可以使用训练好的CRF模型来预测其对应的输出序列。 具体来说,对于每个位置i上的单词或字符,CRF会计算一个状态转移概率矩阵Mi(x),其中Mi(x)[j,k]表示在状态j下,下一个状态为k的概率。同时,CRF还会计算一个发射概率矩阵E(x),其中E(x)[j,l]表示在状态j下,输出标签为l的概率。在给定输入序列X和初始状态y0=start的情况下,CRF可以使用动态规划算法计算出最可能的状态序列Y,即使得条件概率P(Y|X)最大的序列Y。 以上就是使用CRF进行命名实体识别的基本流程和示例。 通过调整特征函数和模型参数,我们可以进一步提高CRF在命名实体识别等任务上的性能。 |
人工智能基础部分18-条件随机场CRF模型的应用