【问题标题】:How to use spacy to do Name Entity recognition on CSV file如何使用 spacy 对 CSV 文件进行名称实体识别
【发布时间】:2020-03-10 14:49:20
【问题描述】:

我已经尝试了很多方法来对我的 csv 文件中的列进行名称实体识别,我尝试了 ne_chunk 但我无法在这样的列中获得我的 ne_chunk 的结果

ID  STORY                                       PERSON  NE   NP  NN VB  GE
1   Washington, a police officer James...        1      0    0   0   0   1

改为使用此代码后,

news=pd.read_csv("news.csv")

news['tokenize'] = news.apply(lambda row: nltk.word_tokenize(row['STORY']), axis=1)


news['pos_tags'] = news.apply(lambda row: nltk.pos_tag(row['tokenize']), axis=1)

news['entityrecog']=news.apply(lambda row: nltk.ne_chunk(row['pos_tags']), axis=1)

tag_count_df = pd.DataFrame(news['entityrecognition'].map(lambda x: Counter(tag[1] for tag in x)).to_list())

news=pd.concat([news, tag_count_df], axis=1).fillna(0).drop(['entityrecognition'], axis=1)

news.to_csv("news.csv")

我收到了这个错误

IndexError : list index out of range

所以,我想知道我是否可以使用 spaCy 来做到这一点,这是我不知道的另一件事。有人可以帮忙吗?

【问题讨论】:

    标签: python pandas csv nltk named-entity-recognition


    【解决方案1】:

    您似乎错误地检查了块,这就是您收到关键错误的原因。我猜测您想要做什么,但这会为 NLTK 返回的每种 NER 类型创建新列。对每个 NER 类型列进行预定义并将其归零会更干净一些(因为如果 NER 不存在,这会给你 NaN)。

    def extract_ner_count(tagged):
        entities = {}
        chunks = nltk.ne_chunk(tagged)
        for chunk in chunks:
            if type(chunk) is nltk.Tree:
              #if you don't need the entities, just add the label directly rather than this.
              t = ''.join(c[0] for c in chunk.leaves())
              entities[t] = chunk.label()
        return Counter(entities.values())
    
    news=pd.read_csv("news.csv")
    news['tokenize'] = news.apply(lambda row: nltk.word_tokenize(row['STORY']), axis=1)
    news['pos_tags'] = news.apply(lambda row: nltk.pos_tag(row['tokenize']), axis=1)
    news['entityrecognition']=news.apply(lambda row: extract_ner_count(row['pos_tags']), axis=1)
    news = pd.concat([news, pd.DataFrame(list(news["entityrecognition"]))], axis=1)
    
    print(news.head())
    

    如果您想要的只是计数,则以下是性能更高且没有 NaN 的:

    tagger = nltk.PerceptronTagger()
    chunker = nltk.data.load(nltk.chunk._MULTICLASS_NE_CHUNKER)
    NE_Types = {'GPE', 'ORGANIZATION', 'LOCATION', 'GSP', 'O', 'FACILITY', 'PERSON'}
    
    def extract_ner_count(text):
        c = Counter()
        chunks = chunker.parse(tagger.tag(nltk.word_tokenize(text,preserve_line=True)))
        for chunk in chunks:
            if type(chunk) is nltk.Tree:
                c.update([chunk.label()])
        return c
    
    news=pd.read_csv("news.csv")
    for NE_Type in NE_Types:
        news[NE_Type] = 0
    news.update(list(news["STORY"].apply(extract_ner_count)))
    
    print(news.head())
    

    【讨论】:

    • 多个.apply 一次又一次地遍历整个数据帧最终会导致代码非常慢:stackoverflow.com/questions/47769818/…
    • 为原始问题海报提出更好的解决方案;P
    • @qubert 我能够获得我的名字实体识别的计数,但是,我可以在不包含任何实体识别的列上使用 nil 来代替 0 吗?
    猜你喜欢
    • 1970-01-01
    • 2021-05-06
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-01
    • 1970-01-01
    相关资源
    最近更新 更多