import jieba from collections import Counter import re
# 读 TXT withopen('zh_comments.txt', encoding='utf-8') as f: texts = [line.strip() for line in f if line.strip()]
# 简单分词 words = [] for text in texts: words.extend(jieba.lcut(text))
# 过滤:去掉标点、单字、停用词 stopwords = set(open('cn_stopwords.txt', encoding='utf-8').read().split()) filtered = [ w for w in words iflen(w) > 1 and w notin stopwords andnot re.match(r'^[\W\d]+$', w) # 不要纯标点/数字 ]
text = '小米手机续航不错,客服态度也挺好' words = pseg.lcut(text) for w, flag in words: print(f'{w:8s}{flag}') # 小米手机 n # 续航 v # 不错 a # , x # 客服 n # 态度 n # 也 d # 挺好 a # . x
jieba 词性对照表(常用):
flag
含义
flag
含义
n
普通名词
v
动词
a
形容词
d
副词
nr
人名
ns
地名
nt
机构名
nz
其他专名
r
代词
c
连词
p
介词
x
标点
业务用法:只要名词 + 形容词 → 关键词候选:
1 2 3
# 只要名词和形容词 keywords = [w for w, flag in pseg.lcut(text) if flag.startswith('n') or flag.startswith('a')] # ['小米手机', '续航', '不错', '客服', '态度', '挺好']
withopen('en_reviews.txt', encoding='utf-8') as f: texts = [line.strip() for line in f if line.strip()]
# 1. 分词 tokens = [] for text in texts: tokens.extend(word_tokenize(text.lower())) # 全部转小写
# 2. 过滤标点 + 停用词 stop_words = set(stopwords.words('english')) filtered = [ w for w in tokens if w.isalpha() # 只要字母(去标点数字) and w notin stop_words # 去停用词 andlen(w) > 2# 至少 3 个字母 ]
# 3. 统计 freq = Counter(filtered) top50 = freq.most_common(50) for word, count in top50: print(f'{word:12s}{count:5d}')
2. 词形归一(lemmatization)
英文一个词有多种形式(run/ran/running/runs),统计时要把它们归一:
1 2 3 4 5 6 7 8 9 10
from nltk.stem import WordNetLemmatizer nltk.download('wordnet', quiet=True)
lemmatizer = WordNetLemmatizer()
# 跑 / 跑了 / 跑步中 全部归一为 run print(lemmatizer.lemmatize('running', pos='v')) # run print(lemmatizer.lemmatize('ran', pos='v')) # run print(lemmatizer.lemmatize('runs', pos='v')) # run print(lemmatizer.lemmatize('better', pos='a')) # good
pos 参数:v=动词, n=名词, a=形容词, r=副词。
进阶版:用 nltk 词性标注自动确定 pos:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
from nltk.tag import pos_tag nltk.download('averaged_perceptron_tagger', quiet=True)
deflemmatize_with_pos(text): tokens = word_tokenize(text.lower()) tagged = pos_tag(tokens) # 词性标注 out = [] for word, tag in tagged: ifnot word.isalpha() or word in stop_words orlen(word) <= 2: continue # nltk 词性转 WordNet 词性 wn_tag = tag[0].lower() wn_tag = wn_tag if wn_tag in'nvars'else'n' lemma = lemmatizer.lemmatize(word, pos=wn_tag) out.append(lemma) return out
3. 英文词性
1 2 3 4 5 6 7 8 9 10 11 12 13
text = 'The quick brown fox jumps over the lazy dog' tagged = pos_tag(word_tokenize(text)) for w, t in tagged: print(f'{w:8s}{t}') # The DT (限定词) # quick JJ (形容词) # brown JJ # fox NN (名词) # jumps VBZ (动词) # over IN (介词) # the DT # lazy JJ # dog NN
defsplit_zh_en(text): """把中英混合文本拆成中文段和英文段""" segments = [] current = [] current_lang = None# 'zh' or 'en' for char in text: lang = 'zh'if is_chinese(char) else ('en'if char.isalpha() elseNone) if lang isNone: # 标点空格等,跳过 continue if current_lang isNoneor current_lang == lang: current.append(char) current_lang = lang else: segments.append((current_lang, ''.join(current))) current = [char] current_lang = lang if current: segments.append((current_lang, ''.join(current))) return segments
text = '这个iPhone15手感很好,但是battery续航一般' parts = split_zh_en(text) # [('zh', '这个'), ('en', 'iPhone'), ('zh', '手感很好但是'), ('en', 'battery'), ('zh', '续航一般')]
# 分别处理 zh_words = [] en_words = [] for lang, segment in parts: if lang == 'zh': zh_words.extend(jieba.lcut(segment)) else: en_words.extend(word_tokenize(segment.lower()))
# pip install langid import langid text = '这个iPhone手感很好' print(langid.classify(text)) # ('zh', 0.99) text2 = 'battery life is great' print(langid.classify(text2)) # ('en', -126.7)
五、词性分析 + 词频组合拳
很多业务场景需要”特定词性”的高频词:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
# 场景1: 找竞品高频形容词(用于文案优化) zh_adjectives = [w for w, flag in pseg.lcut('\n'.join(texts)) if flag == 'a'andlen(w) > 1] top_adjectives = Counter(zh_adjectives).most_common(20) # 输出: [('不错', 234), ('好', 198), ('差', 156), ...]
# 场景2: 找竞品高频专有名词(用于品牌识别) zh_proper_nouns = [w for w, flag in pseg.lcut('\n'.join(texts)) if flag in ('nr', 'ns', 'nt', 'nz')] top_brands = Counter(zh_proper_nouns).most_common(20) # 输出: [('小米', 234), ('华为', 198), ('北京', 156), ...]
# 场景3: 找高频动词(用于用户行为分析) zh_verbs = [w for w, flag in pseg.lcut('\n'.join(texts)) if flag == 'v'andlen(w) > 1] top_actions = Counter(zh_verbs).most_common(20) # 输出: [('买', 234), ('退', 198), ('换', 156), ...]
defprocess_in_chunks(file_path, chunk_size=10000): freq = Counter() withopen(file_path, encoding='utf-8') as f: chunk = [] for line in f: chunk.append(line.strip()) iflen(chunk) >= chunk_size: words = jieba.lcut(' '.join(chunk)) freq.update([w for w in words iflen(w) > 1]) chunk = [] if chunk: words = jieba.lcut(' '.join(chunk)) freq.update([w for w in words iflen(w) > 1]) return freq