如何为处理含特殊符号推文的sklearn分类模型添加列表特征?
针对你处理带数学公式特殊符号推文的场景,我整理了几个实用的特征添加思路,完全适配你现有的sklearn Pipeline结构:
1. 保留并增强特殊符号的字符n-gram特征
你当前的CountVectorizer已经用了字符n-gram,但默认配置可能会过滤掉数学特殊符号,所以首先要调整配置确保这些符号被纳入特征:
- 修改
token_pattern参数:默认的token_pattern=r'(?u)\b\w\w+\b'只会保留字母数字,改成token_pattern=r'.+'或者直接不指定(因为analyzer='char'模式下,这个参数会被忽略,但明确设置更保险),让所有字符包括$、∑、=、√这类数学符号都能被纳入n-gram统计。 - 新增数学符号专属n-gram特征:单独提取连续的数学符号组合(比如
'=+'、'∑_'),这类特征对区分含公式的推文很有帮助。可以用FeatureUnion把原特征和这个新特征合并。
示例代码:
from sklearn.pipeline import FeatureUnion # 原字符n-gram特征(确保保留所有字符) char_ngram = Pipeline([ ('vect', CountVectorizer(analyzer='char', ngram_range=(3,5), token_pattern=r'.+')), ('tfidf', TfidfTransformer()) ]) # 数学符号专属n-gram特征(只匹配数学符号组合) math_symbol_ngram = Pipeline([ ('vect', CountVectorizer(analyzer='char', ngram_range=(1,3), token_pattern=r'[\$\+\-\*\/\=\∑\√\π\^\_\{\}\[\]]+')), ('tfidf', TfidfTransformer()) ]) # 合并两类特征 combined_features = FeatureUnion([ ('char_ngram', char_ngram), ('math_symbol_ngram', math_symbol_ngram) ]) # 重新构建完整模型Pipeline model = Pipeline([ ('features', combined_features), ('clf', SGDClassifier(alpha = 0.0001, loss = 'log', epsilon = 7, max_iter=8, random_state = 40, tol = None)) ])
2. 添加规则式统计特征
除了n-gram,你可以手工提取一些和数学公式强相关的统计特征,这类特征能直接给模型传递“是否含公式、公式复杂度”这类信号:
- 推文中数学符号的占比:总字符数中数学符号的比例
- 特定高频数学符号的出现次数:比如$(公式标记)、=、∑这类符号的出现次数
- 最长连续数学符号序列的长度:反映公式的复杂程度
用FunctionTransformer可以把这些特征整合到Pipeline中,示例:
from sklearn.preprocessing import FunctionTransformer import re def extract_math_stats(texts): stats = [] # 定义需要统计的数学符号集合,可根据你的数据补充 math_symbols = r'[\$\+\-\*\/\=\∑\√\π\^\_\{\}\[\]]' for text in texts: total_chars = len(text) math_count = len(re.findall(math_symbols, text)) # 计算数学符号占比,避免除以0 math_ratio = math_count / total_chars if total_chars > 0 else 0 # 统计公式标记$的次数 dollar_count = text.count('$') # 最长连续数学符号序列长度 longest_math_seq = max([len(seq) for seq in re.findall(math_symbols+'+', text)] + [0]) stats.append([math_ratio, dollar_count, longest_math_seq]) return stats # 将统计函数转为sklearn兼容的转换器 math_stats_transformer = FunctionTransformer(extract_math_stats, validate=False) # 合并所有特征(包括之前的n-gram) combined_features = FeatureUnion([ ('char_ngram', char_ngram), ('math_symbol_ngram', math_symbol_ngram), ('math_stats', math_stats_transformer) ]) # 更新后的模型Pipeline model = Pipeline([ ('features', combined_features), ('clf', SGDClassifier(alpha = 0.0001, loss = 'log', epsilon = 7, max_iter=8, random_state = 40, tol = None)) ])
3. 补充词级n-gram特征(兼顾自然语言内容)
推文里除了数学公式,肯定还有普通自然语言内容,加入词级的n-gram特征(比如1-2 gram)可以补充字符n-gram在语义捕捉上的不足,让模型同时理解文本的自然语言部分:
# 词级n-gram特征(过滤停用词) word_ngram = Pipeline([ ('vect', CountVectorizer(ngram_range=(1,2), stop_words='english')), ('tfidf', TfidfTransformer()) ]) # 合并所有四类特征 combined_features = FeatureUnion([ ('char_ngram', char_ngram), ('math_symbol_ngram', math_symbol_ngram), ('word_ngram', word_ngram), ('math_stats', math_stats_transformer) ])
这些调整后,模型既能捕捉字符层面的细节(包括数学符号的组合模式),又能利用手工统计特征强化公式相关的信号,同时兼顾自然语言内容,应该能显著提升针对这类带公式推文的分类效果。
内容的提问来源于stack exchange,提问作者Minions
相关产品推荐
相关产品推荐

