如何防止一个高度相关的变量淹没 scikit-learn 中的其余变量?

Posted

技术标签:

【中文标题】如何防止一个高度相关的变量淹没 scikit-learn 中的其余变量?【英文标题】:How to keep one highly-correlated variable from swamping the rest in scikit-learn? 【发布时间】:2017-08-29 15:50:16 【问题描述】:

我正在构建一个分类器来检测唐纳德特朗普何时从@realDonaldTrump 发推文,而不是一个职员。它使用 2016 年的推文来训练模型,使用推文设备推断作者身份——如果消息是从 android 手机发送的,那就是特朗普;否则就是职员。

现在,我正在使用 Python sklearn BernoulliNB 分类器,它使用两组特征。第一个是总统推文文本的词袋向量。第二个是一个简单的二进制变量——推文是否有链接?

我使用pandas 处理数据并使用sklearn_pandas 使组合功能更容易。这是数据帧的 sn-p:

                                                  text  year   type   link
0    RT @realDonaldTrump: Happy Birthday @DonaldJTr...  2016  staff   true
1    Happy Birthday @DonaldJTrumpJr!\nhttps://t.co/...  2016  staff   true
2    Happy New Year to all, including to my many en...  2016  trump  false
3    Russians are playing @CNN and @NBCNews for suc...  2016  trump  false
4    Join @AmerIcan32, founded by Hall of Fame lege...  2016  staff   true

这是我的代码的简化示例:

# Grab tweets, which have 'text', 'link' and 'type' columns
train_tweets = pd.read_json("data/condensed_2016.json")

vectorizer = DataFrameMapper([
('link', MultiLabelBinarizer()),
('text', CountVectorizer(
    analyzer = 'word', 
    tokenizer = None, 
    preprocessor = None, 
    stop_words = 'english', 
    max_features = 500) )
])

# Build vector of features from training set
train_data_features = vectorizer.fit_transform(train_tweets)

classify = BernoulliNB()
classify = classify.fit( train_data_features, train_tweets['type'] )

唯一的问题是link 专栏与职员作者身份高度相关非常——特朗普几乎从不在他的推文中包含任何类型的链接。因此,每当我对包含链接的推文进行分类并使用 classify.predict_proba() 检查概率时,我都会得到一个疯狂的特异性——比如有 99.999% 的机会是员工写了这条推文。

这基本上使词袋分析变得毫无意义。我想这不是一件的事情,但它使算法更加脆弱。有什么明显的办法可以解决这个问题吗?

【问题讨论】:

哦,好主意!你在某处有数据吗?我想试一试! 这个家伙每小时收集一次:github.com/bpb27/trump_tweet_data_archive 甜蜜!对于您的问题,我将首先清理推文数据以删除所有链接、RT、提及等。如果 link 列相关,我还将删除它。 在我的实际代码中,我在令牌级别进行了大量的自定义清理和排除...但是删除高度相关的列是否被认为是最佳实践? 并非总是如此。但在这种特殊情况下,当您只对推文文本感兴趣时,链接列似乎只是在向您的模型添加泄漏。 【参考方案1】:

您可以尝试随机抽样不足或过度抽样,这将平衡您的数据分布。然而,过度采样会产生内存错误。根据您的数据,在采样下尝试过可能会产生较差的结果,所以我想说两种都试一下。

RandomOverSampler:http://contrib.scikit-learn.org/imbalanced-learn/stable/generated/imblearn.over_sampling.RandomOverSampler.html#imblearn.over_sampling.RandomOverSampler

RandomUnderSampler:http://contrib.scikit-learn.org/imbalanced-learn/stable/generated/imblearn.under_sampling.RandomUnderSampler.html#imblearn.under_sampling.RandomUnderSampler

或者您可以使用欠采样和过采样的组合:http://contrib.scikit-learn.org/imbalanced-learn/stable/generated/imblearn.combine.SMOTETomek.html#imblearn.combine.SMOTETomek

【讨论】:

以上是关于如何防止一个高度相关的变量淹没 scikit-learn 中的其余变量?的主要内容,如果未能解决你的问题,请参考以下文章

防止PHP脚本被淹没

51nod 1276 岛屿的数量

GlobalMapper精品教程038:模拟水位上升(洪水淹没分析)案例教程

GlobalMapper精品教程038:模拟水位上升(洪水淹没分析)案例教程

更改工具栏高度时如何防止按钮向右移动?

如何防止填充属性更改 CSS 中的宽度或高度?