用于标签预测的特征空间减少

vin*_*ukl 6 python machine-learning feature-extraction tf-idf scikit-learn

我正在编写一个ML模块(python)来预测stackoverflow问题(标签+正文)的标签.我的语料库有大约500万个问题,每个问题都有标题,正文和标签.我正在将这个3:2分成训练和测试.我受到维度诅咒的困扰.


完成工作

  1. 预处理:删除标记,删除停用词,删除特殊字符以及一些零碎.存储到MySQL.这几乎使测试数据的大小减半.
  2. NGRAM协会:每个单字组和两字在标题和正文每个问题,我保持相关标签的列表.存入redis.这导致大约一百万个独特的unigrams和两千万个独特的双桅轮,每个都有相应的标签频率列表.防爆.

    "continuous integration": {"ci":42, "jenkins":15, "windows":1, "django":1, ....}
    
    Run Code Online (Sandbox Code Playgroud)

注意:这里有两个问题:a)并非所有的unigrams和bigrams都很重要,b)并非所有与ngram相关的标签都很重要,尽管这并不意味着频率为1的标签都是等效的或者可以随意删除.与给定ngram相关联的标签数量很容易达到成千上万 - 其中大多数不相关且无关紧要.

  1. tfidf:为了帮助选择要保留的ngram,我计算了每个unigram和bigram的整个语料库的tfidf分数,并将相应的idf值与相关标签一起存储.防爆.

    "continuous integration": {"ci":42, "jenkins":15, ...., "__idf__":7.2123}
    
    Run Code Online (Sandbox Code Playgroud)

    documentxfeature tfidf分数存储在sparse.csr_matrix中,我不知道如何才能利用它.(它由fit_transform()生成)


问题

  1. 如何使用此处理的数据来减小功能集的大小?我读过有关SVD和PCA的内容,但这些例子总是谈论一组文档和词汇.我不确定我的集合中的标签可以进入哪里.此外,我的数据存储方式(redis +稀疏矩阵),很难使用已经实现的模块(sklearn,nltk等)来执行此任务.
  2. 一旦功能集减少,我计划使用它的方式如下:

    • 预处理测试数据.
    • 找到unigrams和bigrams.
    • 对于存储在redis中的那些,找到相应的best-k标签
    • 对标题和正文应用某种权重
    • 除此之外,我还可以在文档中搜索确切的已知标记匹配.例如,如果标题/正文中出现"ruby-on-rails",那么它很可能也是一个相关标签.
    • 此外,对于以高概率预测的标签,我可能会利用标签图(带有标签的无向图,它们经常在它们之间具有加权边缘)来预测更多标签.

    关于如何改进这个有什么建议吗?分类器可以派上用场吗?


脚注

我有一台16核,16GB的RAM机器.redis-server(我将移动到另一台机器)存储在RAM中,大约为10GB.上面提到的所有任务(除了tfidf)都是使用ipython集群并行完成的.

rom*_*ows 0

基线统计方法会将其视为分类问题。特征是由最大熵分类器(如 Mallet http://mallet.cs.umass.edu/classification.php)处理的词袋。Maxent(又名逻辑回归)擅长处理大特征空间。获取与每个标签(即类标签)相关的概率,并选择一些决策阈值,该阈值可以为您提供适合您的项目的精确度/召回率权衡。一些 Mallet 文档甚至提到了主题分类,这与您想要做的非常相似。

悬而未决的问题是 Mallet 处理数据大小(数据并没有那么大)的能力如何,以及这个特定的工具是否无法使用您提到的技术堆栈。您也许能够离线训练(将 reddis 数据库转储到 Mallet 特征格式的文本文件)并在 Python 中运行 Mallet 学习模型。评估 maxent 模型很简单。如果您想继续使用 Python 并使其更加自动化,NLTK 中以及 scikit-learn 中可能有基于 Python 的 maxent 实现。这种方法根本不是最先进的,但它会工作得很好,并且是比较更复杂的方法的一个不错的基线。