如何用脚本生成词性标注

wen 实用脚本 1

本文目录导读:

如何用脚本生成词性标注

  1. 使用现成的NLP库(最简单)
  2. 使用Hugging Face Transformers(更准确)
  3. 扩展:批处理多个文本
  4. 自定义词性标注工具
  5. 生成训练数据(用于机器学习)
  6. 实时应用示例
  7. 关键建议

我来详细介绍几种生成词性标注的方法,从简单到复杂:

使用现成的NLP库(最简单)

Python + NLTK

import nltk
from nltk.tokenize import word_tokenize
from nltk.tag import pos_tag
# 下载必要的资源(首次使用时)
nltk.download('punkt')
nltk.download('averaged_perceptron_tagger')
text = "The quick brown fox jumps over the lazy dog"
tokens = word_tokenize(text)
pos_tags = pos_tag(tokens)
print(pos_tags)
# 输出: [('The', 'DT'), ('quick', 'JJ'), ('brown', 'JJ'), ('fox', 'NN'), 
#        ('jumps', 'VBZ'), ('over', 'IN'), ('the', 'DT'), ('lazy', 'JJ'), ('dog', 'NN')]

Python + spaCy(更现代化)

import spacy
# 加载英文模型(首次需要下载)
# python -m spacy download en_core_web_sm
nlp = spacy.load("en_core_web_sm")
doc = nlp("The quick brown fox jumps over the lazy dog")
for token in doc:
    print(f"{token.text:<10} {token.pos_:<6} {token.tag_:<6}")
# 输出效果:
# The        PROPN  DT    
# quick      ADJ    JJ    
# brown      ADJ    JJ    
# fox        NOUN   NN    
# jumps      VERB   VBZ   
# over       ADP    IN    
# the        DET    DT    
# lazy       ADJ    JJ    
# dog        NOUN   NN

使用Hugging Face Transformers(更准确)

from transformers import pipeline
# 加载预训练的词性标注模型
pos_tagger = pipeline("token-classification", 
                     model="vblagoje/bert-english-uncased-finetuned-pos")
text = "The quick brown fox jumps over the lazy dog"
results = pos_tagger(text)
for item in results:
    print(f"{item['word']:<10} {item['entity']}")

扩展:批处理多个文本

import pandas as pd
from nltk.tokenize import word_tokenize
from nltk.tag import pos_tag
def pos_tag_sentences(sentences):
    """批量处理多个句子"""
    results = []
    for sentence in sentences:
        tokens = word_tokenize(sentence)
        tags = pos_tag(tokens)
        results.append(tags)
    return results
# 示例:处理CSV文件中的文本
def process_csv_files(input_file, output_file, text_column):
    df = pd.read_csv(input_file)
    df['pos_tags'] = df[text_column].apply(
        lambda x: pos_tag(word_tokenize(str(x)))
    )
    df.to_csv(output_file, index=False)
    return df

自定义词性标注工具

class CustomPosTagger:
    def __init__(self):
        self.word_tags = self._load_dictionary()
        self.suffix_rules = {
            'ly': 'ADV',  # 副词
            'tion': 'NOUN',  # 名词
            'ment': 'NOUN',  # 名词
            'ing': 'VERB',  # 动词
            'ed': 'VERB',   # 动词
            'ous': 'ADJ',   # 形容词
            'ive': 'ADJ',   # 形容词
            'al': 'ADJ',    # 形容词
            # 更多规则...
        }
    def _load_dictionary(self):
        # 在这里加载词性字典
        return {
            'the': 'DET',
            'a': 'DET',
            'an': 'DET',
            'cat': 'NOUN',
            'dog': 'NOUN',
            'run': 'VERB',
            'jump': 'VERB',
            # ... 更多词条
        }
    def tag(self, word):
        # 1. 先查字典
        if word.lower() in self.word_tags:
            return self.word_tags[word.lower()]
        # 2. 再查后缀规则
        for suffix, tag in self.suffix_rules.items():
            if word.endswith(suffix):
                return tag
        # 3. 默认标为名词
        return 'NOUN'
    def pos_tag_sentence(self, sentence):
        words = sentence.split()
        return [(word, self.tag(word)) for word in words]
# 使用示例
tagger = CustomPosTagger()
print(tagger.pos_tag_sentence("The cat runs quickly"))

生成训练数据(用于机器学习)

import random
import json
class TrainingDataGenerator:
    def __init__(self):
        self.patterns = [
            (["The", "cat", "runs", "fast"], 
             ["DET", "NOUN", "VERB", "ADV"]),
            (["A", "dog", "barks", "loudly"], 
             ["DET", "NOUN", "VERB", "ADV"]),
            # 更多模式...
        ]
    def generate_training_data(self, num_samples=1000):
        training_data = []
        for _ in range(num_samples):
            pattern = random.choice(self.patterns)
            words, tags = pattern
            # 可以添加变体
            if random.random() > 0.5:
                words = words[::-1]
                tags = None  # 需要重新标注
            training_data.append({
                'text': ' '.join(words),
                'tags': tags
            })
        return training_data
    def save_to_json(self, data, filename):
        with open(filename, 'w', encoding='utf-8') as f:
            json.dump(data, f, ensure_ascii=False, indent=2)
# 使用示例
generator = TrainingDataGenerator()
data = generator.generate_training_data(100)
generator.save_to_json(data, 'training_data.json')

实时应用示例

import spacy
class RealTimePosTagger:
    def __init__(self):
        self.nlp = spacy.load("en_core_web_sm")
        self.tag_mapping = {
            'NOUN': '名词',
            'VERB': '动词',
            'ADJ': '形容词',
            'ADV': '副词',
            'DET': '限定词',
            'PRON': '代词',
            'ADP': '介词',
            'CONJ': '连词',  # 或 'CCONJ': '连词'
            'PUNCT': '标点'
        }
    def tag_and_translate(self, text):
        """标注英文并翻译成中文词性"""
        doc = self.nlp(text)
        results = []
        for token in doc:
            pos_zh = self.tag_mapping.get(token.pos_, token.pos_)
            results.append({
                'word': token.text,
                'pos': token.pos_,
                'pos_zh': pos_zh,
                'detail_tag': token.tag_
            })
        return results
    def display_tags(self, text):
        results = self.tag_and_translate(text)
        print(f"原文: {text}\n")
        print(f"{'单词':<10} {'词性':<8} {'中文':<6} {'详细'}")
        print("-" * 40)
        for r in results:
            print(f"{r['word']:<10} {r['pos']:<8} {r['pos_zh']:<6} {r['detail_tag']}")
# 使用示例
tagger = RealTimePosTagger()
tagger.display_tags("I love programming in Python since 2019")

关键建议

  1. 选择库的建议

    • 简单任务:NLTK
    • 生产环境:spaCy
    • 最准确:Transformer模型(如BERT)
    • 多语言:spaCy或Stanza
  2. 性能优化

    # 缓存已处理的文本
    from functools import lru_cache
    @lru_cache(maxsize=1000)
    def tag_text(text):
        return nltk.pos_tag(word_tokenize(text))
  3. 中文词性标注

    import jieba.posseg as pseg
    words = pseg.cut("我爱北京天安门")
    for word, flag in words:
        print(f'{word} {flag}')

这些方法覆盖了从入门到高级的各种场景,你可以根据需求选择合适的方案。

抱歉,评论功能暂时关闭!