使用Python的NLTK处理聊天语料,如何将重复字符词视为同一词汇?
处理聊天语料中的重复字符词汇问题
这个问题在聊天语料预处理里太常见了!我之前处理类似的社交/聊天数据时也碰到过,给你两个实用的解决办法,能轻松把这类重复字符的词汇归一化成同一个:
方法1:正则表达式统一重复字符
最通用的方式是用正则把连续重复的字符序列归一化——比如把3个及以上的相同字符替换成2个,这样不管是xxxxx/xxx还是hahahaha/hahahah,都会变成xx和haha,自然就被当成同一个词了。
直接上代码,你可以把这个逻辑整合到你的预处理流程里:
import re from nltk.corpus import stopwords from nltk.stem import PorterStemmer # 定义归一化重复字符的函数 def normalize_repeated_chars(text): # 匹配连续3个及以上的相同字符,替换成2个(比如xxxxx→xx, hahahaha→haha) return re.sub(r'(.)\1{2,}', r'\1\1', text) # 你的原有预处理配置 stop = set(stopwords.words('english')) stop.update(['.', ',', '"', "'", '?', '!', ':', ';', '(', ')', '[',']', '{', '}', '@', '#', 'http', 'https', '/', '://', '_']) p_stemmer = PorterStemmer() texts = ['bla bla xxxxxx', 'hahahah', 'haha xx', 'hello xx'] # 第一步:先处理重复字符 processed_texts = [normalize_repeated_chars(text) for text in texts] # 第二步:继续原有预处理流程(分词、去停用词、词干化) def preprocess(text): tokens = text.lower().split() tokens = [token for token in tokens if token not in stop] tokens = [p_stemmer.stem(token) for token in tokens] return tokens final_corpus = [preprocess(text) for text in processed_texts]
这里的正则(.)\1{2,}是核心:(.)匹配任意单个字符,\1引用刚才匹配的字符,{2,}表示至少重复2次(加上前面的1次就是总共3次及以上),替换成\1\1就是保留2个重复字符,完美统一所有过度重复的变体。
方法2:自定义映射字典(针对特定场景)
如果你的语料里有一些特定的重复模式(比如loooool想统一成lol,或者hehehe统一成hehe),可以做一个自定义映射字典,针对性更强:
# 自定义重复词映射规则 repeat_mapping = { r'x{3,}': 'xx', # 匹配3个及以上的x,替换成xx r'ha{3,}': 'haha', # 匹配h后面跟3个及以上a,替换成haha r'lo+l': 'lol', # 匹配l后面跟1个及以上o,再跟l,替换成lol r'hehe+': 'hehe' # 匹配hehe后面跟1个及以上e,替换成hehe } def normalize_with_mapping(text): for pattern, replacement in repeat_mapping.items(): text = re.sub(pattern, replacement, text) return text
把这个函数替换前面的normalize_repeated_chars就行,适合你对语料里的重复模式有明确认知的情况。
小提示
处理重复字符一定要放在分词、词干化之前,这样才能保证所有变体被统一成同一个词,之后的高频词统计和LDA主题识别才会更准确。
内容的提问来源于stack exchange,提问作者Titus Pullo
相关产品推荐
相关产品推荐

