【问题标题】:Pandas: Article category prediction performance slowPandas:文章类别预测性能缓慢
【发布时间】:2021-12-12 05:50:09
【问题描述】:

我正在为 Pandas 中的文章开发一个朴素的多项式贝叶斯分类器,但在性能方面遇到了一些问题。如果你想要完整的代码和我正在使用的数据集,我的仓库就在这里:https://github.com/kingcodefish/multinomial-bayesian-classification/blob/master/main.ipynb

这是我当前使用两个数据框的设置:df 用于带有标记词列表的文章,word_freq 用于存储预先计算的频率和 P(word | category) 值。

for category in df['category'].unique():
    category_filter = word_freq.loc[word_freq['category'] == category]
    cat_articles = df.loc[df['category'] == category].shape[0] # The number of categorized articles
    p_cat = cat_articles / df.shape[0] # P(Cat) = # of articles per category / # of articles
    df[category] = df['content'].apply(lambda x: category_filter[category_filter['word'].isin(x)]['p_given_cat'].prod()) * p_cat

示例数据:

df

        category                                            content
0   QUEER VOICES  [online, dating, thoughts, first, date, grew, ...
1        COLLEGE  [wishes, class, believe, generation, better, j...
2       RELIGION  [six, inspiring, architectural, projects, revi...
3       WELLNESS  [ultramarathon, runner, micah, true, died, hea...
4  ENTERTAINMENT  [miley, cyrus, ball, debuts, album, art, cyrus...

word_freq

           category         word  freq  p_given_cat
46883         MEDIA         seat   1.0     0.333333
14187         CRIME         ends   1.0     0.333333
81317    WORLD NEWS         seat   1.0     0.333333
12463        COMEDY       living   1.0     0.200000
20868     EDUCATION     director   1.0     0.500000

请注意,word_freq 表是类别 x 单词的叉积,因此每个单词在每个类别中出现一次且仅出现一次,因此该表确实包含重复项。此外,freq 列已增加 1 以避免零值(拉普拉斯平滑)。

运行上述后,我这样做是为了找到最大类别 P(每个类别的 P 存储在其名称后面的列中)并得到以下内容:

df['predicted_category'] = df[df.columns.difference(['category', 'content'])].idxmax(axis=1)
df = df.drop(df.columns.difference(['category', 'content', 'predicted_category']), axis=1).reset_index(drop = True)
          category                                            content  \
0         POLITICS  [bernie, sanders, campaign, split, whether, fi...   
1           COMEDY  [bill, maher, compares, police, unions, cathol...   
2         WELLNESS  [busiest, people, earth, find, time, relax, th...   
3    ENTERTAINMENT  [lamar, odom, gets, standing, ovation, first, ...   
4            GREEN                      [lead, longer, life, go, gut]   
   predicted_category  
0                ARTS  
1                ARTS  
2                ARTS  
3               TASTE  
4               GREEN  

这种方法似乎效果很好,但不幸的是它真的很慢。我正在使用一个包含 200,000 篇简短描述的文章的大型数据集,并且仅对其中的 1% 进行操作需要将近一分钟。我知道这是因为我正在遍历类别而不是依赖矢量化,但是我对 Pandas 非常陌生,并且试图在 groupby 中简洁地表达这一点让我无法理解(特别是对于两个数据表,也可能是不必要的) ,所以我在这里寻找建议。

谢谢!

【问题讨论】:

    标签: python pandas dataframe statistics bayesian


    【解决方案1】:

    以防万一以后有人碰巧遇到这个......

    我没有将我的类别 x 单词表示为每个类别的每个可能单词的叉积,在我的数据集中膨胀到超过 300 万行,我决定将它们减少到每个类别只需要的那些并提供默认值那些不存在的值,最终大约是 600k 行。

    但最大的加速来自于更改为以下内容:

    for category in df['category'].unique():
        # Calculate P(Category)
        category_filter = word_freq.loc[word_freq['category'] == category]
        cat_articles = df.loc[df['category'] == category].shape[0]
        p_cat = cat_articles / df.shape[0]
        
        # Create a word->P(word | category) dictionary for quick lookups
        category_dict = category_filter.set_index('word').to_dict()['p_given_cat']
        
        # For every article, find the product of P(word | category) values of the words, then multiply by P(category) to get bayes.
        df[category] = df['content'].apply(lambda x: np.prod([category_dict.get(y, 0.001 / (cat_articles + 0.001)) for y in x])) * p_cat
    

    我分别从word 和 P(word | category) 两列作为键值对创建了一个字典。这将问题简化为对每个列表的每个元素进行快速字典查找并计算该乘积。

    这最终提高了大约 100 倍,在大约 40 秒内解析整个数据集。

    【讨论】:

      猜你喜欢
      • 2012-08-16
      • 2023-02-01
      • 1970-01-01
      • 2010-10-14
      • 2015-01-27
      • 2021-06-04
      • 2016-11-09
      • 2021-06-21
      • 2012-05-11
      相关资源
      最近更新 更多