知识图谱学习笔记-命名实体识别

一、命名实体识别简单概要

按照类型标记每一个名词:对句子名词进行分类

我今天(时间)要去北京(地点)参加面试

张三(人名)出生于上海(地名),清华大学(组织)毕业后去百度(组织)任职。

命名实体识别:1、构建知识图谱  2、聊天机器人

如:聊天机器人

机器人:先生,请问有什么可以帮到您的嘛?

客户:能不能帮我查询一下明天中午(时间)从北京(地名)飞哈尔滨(地名)的机票?

        |命名实体识别

{
时间:明天中午:11:00 - 13:00,

出发:北京                                                     ----> searchForticket(from,to,time)(填槽)    数据库  -->回复(根据模版填槽)

达到:哈尔滨

}

目前又一个满足要求的航班XXX

二、命名实体识别的评价指标

Contingency Table

 correctNot correct
selectedtpfp
not selectedfntn

             精确率: precision = tp/(tp + fp)

             召回率: recall = tp/(tp+fn)

             F1: F1 = 2PR/(P+R)

三、基于规则的命名实体识别

      1、基于正则表达方式    2、基于已知的词典库(建立词典库-匹配(精确、模糊-规则、相似度算法上下文信息))

 

四、命名实体识别-分类问题

语料

-> 分词  (名词准确分为指定的实体名)

-> 特征提取(特征1,特征2,.....,特征D)

-> 分类器   f(特征1,特征2.......特征D)

 

张三  出生 于 北京, 北京大学 毕业 后 去 华为  任职

                                    X - 特征                                                                     Y - label

(张三,-- ,出生,--,张三出生,人名,--,动词)                         (人名)

(于,出生,北京,出生于,于北京,介词,动词,地名)                              (NA)

(北京,于,北京大学,于北京,北京北京大学,地名,介词,组织)            (地名)

(北京大学,北京,毕业,北京北京大学,北京大学毕业,组织,地名,动词) (组织名)

(毕业,北京大学,后,北京大学毕业,毕业后,动词,组织,方位词)         (NA)

 

命名实体识别-分类器:

1、时序无关模型:

逻辑回归、支持向量机、最大熵模型....

2、时序相关模型:

条件随机场....

 

五、命名实体识别-分类算法特征提取

The professor Colin proposed a model for NER in 1990

1) 基于单词的特征(word)  Unigram bigram Trigram.....

-当前词: Colin   

-前/后词:professor proposed

-前前/后后词:the  model

2) 基于stemming

proposed - > propose

3) 词性

当前词:名

前/后词:名,动

前前/后后:定冠词,名词

4)前缀/后缀

前缀/后缀 : pro/ssor

5)当前词的特点

当前词的长度

是否包含大写字母

包含多少个数字

包含了多少个大写字符

是否包含数字

是否包含符号

是否包含特定的后缀

6)句法分析/依存分析

 

文本-》 提取特征 -》1、设计特征  2、转化向量形式 3、特征选择

 

六、变量类型

1)cateforcal variable(没有数值大小)  onhot-encoding

-单词相关的特征:Apple。professor

-小学,高中,大学

-男女

2)Real variable(数值型变量)  归一化,不做操作

-身高、体重

-气温

3)Ordinal variable  跟数值一样,分类变量

-评价1星、2星、.....

-10,9,8,7.........

 

七、构建分类器:

方法一:根据历史数据进行统计

from sklearn.base import BaseEstimator,TransformerMixmin

class MajorityVotingTagger(BaseEstimator,TransformerMixmin):

    def fit(self,x,y):
        """
        x:list of words
        y:list of tags
        """
        word2cnt = {}
        self.tags = []

        for x,t in zip(x,y):
            if t not in self.tags:
                self.tags.append(t)

            if x in word2cut:
                if t in word2cnt[x]:
                    word2cnt[x][t] += 1
                else:
                    word2cnt[x][t] = 1
            else:
                word2cnt[x] = {t:1}

        self.mjvote = {}
        
        for k,d in word2cnt.items():
            self.mjvote[k] = max(d,key=d.get)


    def predict(self,X,y=None):

        """  x is user input """

        return [self.mjvote.get(x,'O') for x in X]


words = data['Word'].values.tolist()
tags = data['Tag'].values.tolist()

from sklearn.cross_validation import cross_val_predict
from sklearn.metrics import classification_report

pred = cross_val_predict(estimator=MajorityVotingTagger,X=words,y=tags,cv=5)
report = classification_report(y_pred=pred,y_true=tags)
print(report)

方法二:通过随机森林

import numpy as np

def get_feature(word):
    return np.array([word.istitle(),word.islower(),word.isupper(),len(word),word.isdigit(),word.isalpha(),....])

words = [get_feature(w) for w in data['Word'].value.tolist()]
tags = data['Tag'].values.tolist()

from sklearn.cross_validation import cross_val_predict
from sklearn.metrics import classification_report
from sklearn.ensemble import RandomForestClassifier

pred = cross_val_predict(RandomForestClassifier(n_estimators=20),X=words,y=tags)
report = classification_report(y_pred=pred,y_true=tags)
print(report)

    
def get_sentences(data):
    agg_func = lambda s:[(w,p,t) for w,p,t in zip(s["Word".values.tolist(),s["POS"].values.tolist(),s['Tag'].values.tolist()])]
    sentence_grouped = data.groupby("sentence").apply(agg_func)

    return [s for s in sentence_grouped]

sentence = get_sentence(data)

八、获取每个单词的特征

from sklearn.preprocessing import LabelEncoder

out = []
y = []

mv_tagger = MyjorityVotingTagger()
tag_encoder = LabelEncoder()
pos_encoder = LabelEncoder()

words = data["Words"].values.tolist()
tags = data['Tag'].values.tolist()
pos = data['POs'].values.tolist()

my_tagger.fit(words,tags)
tag_encoder.fit(tags)
pos_encoder.fit(pos)

for sentence in sentence:
    for i in range(len(sentences)):
        # w: 单词 p:词性 t:NER标签
        w,p,t = sentence[i][0],sentence[i][1],sentence[i][2]

        if i < len(sentence) - 1:
            # 如果不是句子中最后一个单词,则可以提取出下文的特征
            mem_tag_r = tag_encoder.transform(mv_tagger.predict([sentence[i+1][0]]))[0]
            true_pos_r = pos_encoder.transform([sentencer[i+1][1]])[0]
        else:
            mem_tag_r = tag_encoder.transform(['O'])[0]
            true_pos_r = pos_encoder.transform(['.'])[0]

        if i > 0:
            # 如果不是句子中的第一个单词,则可以提取上文的特征
            mem_tag_1 = tag_encoder.transform(mv_tagger.predict([sentence[i-1][0]]))[0]
            true_pos_1 = pos_encoder.transform([sentence[i-1][1]])[0]
        else:
            mem_tag_1 = tag_encoder.transform([')'])[0]
            true_pos_1 = pos_encoder.transform(['.'])[0]
    
        # 特征整合
        out.append(np.array([w.istitle(),
                    w.islower(),
                    w.isuppper(),
                    len(w),
                    w.isdigit(),
                    w.isalpha(),
                    tag_encoder.transform(mv_tagger.predict([w]))[0],
                    pos_encoder.transform([p])[0],
                    mem_tag_r,
                    true_pos_r,
                    mem_tag_1,
                    true_pos_1]))      
        # 标签      
        y.append(t)

from sklearn.cross_validation import cross_val_predict
from sklearn.metrics import classification_report

pred = cross_val_predict(RandomForestClassifier(n_estimators=20),x=out,y=y,cv=5)
report = classification_report(y_pred=pred,y_true=y)
print(report)

九、通过CRF命名实体识别

def word2features(sentence,i):

    """
    sentence: input sentence
    i: index of word
    """

    word = sentence[i][0]
    postag = sentence[i][1]

    features = {
        'bias':1.0,
        'word.lower()':word.lower(),
        'word[-3:]':word[-3:],
        'word[-2:]':word[-2:],
        'word.isupper()':word.isupper(),
        'word.istitle()':word.istitle(),
        'word.isdigit()':word.isdigit(),
        'postag':postag,
        'postag[:2]':postag[:2],
    }

    if i > 0:
        word1 = sentence[i-1][0]
        postag1 = sentence[i-1][1]
    
        features.update({
            '-1:word.lower()':word1.lower(),
            '-1:word.istitle()':word1.istitle(),
            '-1:word.isupper()':word1.isupper(),
            '-1:postag':postag1,
            '-1:postag[:2]':postag1[:2],
        })

    else:
        features['BOS'] = True
        
    if i < len(sentence)-1:
        word1 = sentence[i+1][0]
        postag1 = sentence[i+1][1]
        features.update([
                '+1:word.lower()':word1.lower(),
                '+1:word.istitle()':word1.istitle(),
                '+1:word.isupper()':word1.isupper(),
                '+1:postag':postag1,
                '+1:postag[:2]':postag2
            ])
    else:
        features['EOS'] = True


def sentence2features(sentence):
    return [word2features(sentence,i) for i in range(len(sentence))]

def sentence2labels(sentences):
    return [label for token,postag,label in sent]

X = [sentence2features(s) for s in sentences]
y = [sentence2labels(s) for s in sentences]

from sklearn_crfsuite import CRF

crf = CRF(algorithm='lbfgs',c1=0.1,c2=0.1,max_iterations=100)

from sklearn.cross_validation import cross_val_predict
from sklearn.crfsuite.metrics import flat_classification_report

pred = cross_val_predict(estimator=crf,X=x,y=y,cv=5)
report = flat_classification_report(y_pred=pred,y_true=y)

print(report)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值