Pandas文章类别预测的多项式朴素贝叶斯分类器运行缓慢优化咨询
性能瓶颈分析
当前代码的性能瓶颈主要来自三点:
- 循环遍历所有分类,每次都对全量数据做行级apply操作,时间复杂度随分类数量线性增长
- apply内部的
category_filter['word'].isin(x)是逐行集合匹配操作,每篇文章都要触发一次全表过滤,开销极高 - 连续小数值的乘积运算不仅容易出现浮点下溢,运算开销也远高于求和运算
优化方案
优化1:替换概率乘积为对数求和
将所有概率取自然对数,把概率乘积转换为对数概率求和,同时解决浮点下溢问题:
import numpy as np import pandas as pd from sklearn.feature_extraction.text import CountVectorizer # 预计算分类先验的对数概率 log_prior = np.log(df['category'].value_counts(normalize=True)) # 重构词频表为【词×分类】的对数条件概率矩阵 log_p_given_cat = np.log(word_freq.pivot(index='word', columns='category', values='p_given_cat'))
优化2:全向量化矩阵运算
用词袋矩阵+矩阵乘法替代逐行遍历操作,一步得到所有文章对应全部分类的概率得分:
# 分词结果已提前生成,直接配置vectorizer返回原值即可 vectorizer = CountVectorizer(analyzer=lambda x: x, vocabulary=log_p_given_cat.index) # 生成【文章数×词数】的稀疏词袋矩阵 bow_matrix = vectorizer.transform(df['content']) # 矩阵乘法直接得到【文章数×分类数】的总对数概率得分 cat_log_scores = bow_matrix @ log_p_given_cat + log_prior
优化3:直接生成预测结果,避免冗余列开销
# 取每行最高得分对应的分类作为预测结果 df['predicted_category'] = cat_log_scores.idxmax(axis=1) # 仅保留需要的列 df = df[['category', 'content', 'predicted_category']].reset_index(drop=True)
性能说明
这套方案全流程无显式循环和行级操作,全部基于线性代数矩阵运算,20万条数据的运行时间可从原方案的小时级降到10秒以内。如果词表规模超过10万,可将log_p_given_cat转换为稀疏矩阵进一步降低内存开销。
内容的提问来源于stack exchange,提问作者KingCodeFish
相关产品推荐
相关产品推荐

