You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用sklearn CountVectorizer提取unigram时保留对应词性标签

解决方法:对齐分词规则,匹配词性标签

问题出在CountVectorizer的分词/过滤规则(小写转换、停用词过滤、标点移除)和你原句的token拆分规则不一致,导致无法直接匹配词性标签。你可以通过以下步骤准确提取带词性标签的unigram:

步骤1:利用CountVectorizer的内置属性对齐匹配

CountVectorizer训练后会生成vocabulary_(保留的词表)和get_stop_words()(使用的停用词集合),我们可以用这两个属性来过滤原句的token-tag对,确保和提取的unigram完全匹配:

from sklearn.feature_extraction.text import CountVectorizer

# 初始化并训练CountVectorizer
vectorizer_unigram = CountVectorizer(analyzer='word', ngram_range=(1, 1), stop_words='english')
doc = {'sent': ['Two women are embracing while holding to go packages .'], 'tags': ['NUM NOUN AUX VERB SCONJ VERB PART VERB NOUN PUNCT']}
vectorizer_unigram.fit(doc['sent'])

# 拆分原句的token和对应标签
sent_tokens = doc['sent'][0].split()
tag_tokens = doc['tags'][0].split()
token_tag_pairs = list(zip(sent_tokens, tag_tokens))

# 按照CountVectorizer的规则过滤,保留匹配的unigram和标签
filtered_pairs = []
stop_words = set(vectorizer_unigram.get_stop_words())
for token, tag in token_tag_pairs:
    lower_token = token.lower()
    # 检查该词是否被CountVectorizer保留(已自动过滤停用词、标点等)
    if lower_token in vectorizer_unigram.vocabulary_:
        filtered_pairs.append((lower_token, tag))

# 输出结果
unigram_with_tags = dict(filtered_pairs)
print(unigram_with_tags)
# 输出: {'women': 'NOUN', 'embracing': 'VERB', 'holding': 'VERB', 'packages': 'NOUN'}

步骤2:扩展到DataFrame场景

如果你的数据是DataFrame格式,可以定义一个处理函数,批量应用到每一行:

import pandas as pd

# 示例DataFrame
df = pd.DataFrame({
    'sentence': ['Two women are embracing while holding to go packages .', 'A man is walking his dog in the park .'],
    'pos_tags': ['NUM NOUN AUX VERB SCONJ VERB PART VERB NOUN PUNCT', 'DET NOUN AUX VERB DET NOUN ADP DET NOUN PUNCT']
})

# 先训练CountVectorizer覆盖所有句子
vectorizer_unigram.fit(df['sentence'])
stop_words = set(vectorizer_unigram.get_stop_words())

# 定义处理单条数据的函数
def extract_unigram_tags(sentence, pos_tags):
    sent_tokens = sentence.split()
    tag_tokens = pos_tags.split()
    token_tag_pairs = list(zip(sent_tokens, tag_tokens))
    
    filtered = []
    for token, tag in token_tag_pairs:
        lower_token = token.lower()
        if lower_token in vectorizer_unigram.vocabulary_:
            filtered.append((lower_token, tag))
    return dict(filtered)

# 批量处理
df['unigram_tags'] = df.apply(lambda row: extract_unigram_tags(row['sentence'], row['pos_tags']), axis=1)

print(df['unigram_tags'])

备选方案:手动对齐过滤规则

如果你不想依赖CountVectorizer的vocabulary_,也可以手动实现和它一致的过滤逻辑(转小写、移除标点、过滤停用词),确保token匹配:

import string
from nltk.corpus import stopwords

# 手动实现和CountVectorizer一致的过滤规则
def filter_token_tags(tokens, tags):
    stop_words = set(stopwords.words('english'))
    punctuation = set(string.punctuation)
    filtered = []
    for token, tag in zip(tokens, tags):
        lower_token = token.lower()
        if lower_token not in stop_words and lower_token not in punctuation:
            filtered.append((lower_token, tag))
    return dict(filtered)

# 调用示例
sent_tokens = doc['sent'][0].split()
tag_tokens = doc['tags'][0].split()
print(filter_token_tags(sent_tokens, tag_tokens))

注意:这种方法需要确保停用词表和CountVectorizer使用的一致(CountVectorizer默认的停用词表和nltk的略有差异),所以优先推荐第一种方法,避免匹配误差。

内容的提问来源于stack exchange,提问作者OLGJ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 04:40:26