如何使用火花朴素贝叶斯分类器进行 IDF 文本分类?

Posted

技术标签:

【中文标题】如何使用火花朴素贝叶斯分类器进行 IDF 文本分类?【英文标题】:How to use spark Naive Bayes classifier for text classification with IDF? 【发布时间】:2015-11-20 18:05:58 【问题描述】:

我想使用 tf-idf 将文本文档转换为特征向量,然后训练一个朴素贝叶斯算法对其进行分类。

我可以轻松加载没有标签的文本文件,并使用 HashingTF() 将其转换为向量,然后使用 IDF() 根据单词的重要性对单词进行加权。但是如果我这样做,我会摆脱标签,即使顺序相同,似乎也无法将标签与向量重新组合。

另一方面,我可以在每个单独的文档上调用 HashingTF() 并保留标签,但是我不能在它上调用 IDF() 因为它需要整个文档语料库(并且标签会进入方式)。

朴素贝叶斯的 spark 文档只有一个示例,其中点已被标记和矢量化,因此帮助不大。

我也看过这个指南:http://help.mortardata.com/technologies/spark/train_a_machine_learning_model 但是这里他只对每个没有 idf 的文档应用散列函数。

所以我的问题是,是否有一种方法不仅可以对朴素贝叶斯分类器使用 idf 的单词进行矢量化,而且还可以对单词进行加权?主要问题似乎是 sparks 坚持只接受 labelPoints 的 rdds 作为 NaiveBayes 的输入。

def parseLine(line):
    label = row[1] # the label is the 2nd element of each row
    features = row[3] # the text is the 4th element of each row
    features = tokenize(features)
    features = hashingTF.transform(features)
    return LabeledPoint(label, features)
labeledData = data1.map(parseLine)

【问题讨论】:

【参考方案1】:

标准 PySpark 方法(拆分 -> 转换 -> zip)似乎工作得很好:

from pyspark.mllib.feature import HashingTF, IDF
from pyspark.mllib.regression import LabeledPoint
from pyspark.mllib.classification import NaiveBayes   

training_raw = sc.parallelize([
    "text": "foo foo foo bar bar protein", "label": 1.0,
    "text": "foo bar dna for bar", "label": 0.0,
    "text": "foo bar foo dna foo", "label": 0.0,
    "text": "bar foo protein foo ", "label": 1.0])


# Split data into labels and features, transform
# preservesPartitioning is not really required
# since map without partitioner shouldn't trigger repartitiong
labels = training_raw.map(
    lambda doc: doc["label"],  # Standard Python dict access 
    preservesPartitioning=True # This is obsolete.
)

tf = HashingTF(numFeatures=100).transform( ## Use much larger number in practice
    training_raw.map(lambda doc: doc["text"].split(), 
    preservesPartitioning=True))

idf = IDF().fit(tf)
tfidf = idf.transform(tf)

# Combine using zip
training = labels.zip(tfidf).map(lambda x: LabeledPoint(x[0], x[1]))

# Train and check
model = NaiveBayes.train(training)
labels_and_preds = labels.zip(model.predict(tfidf)).map(
    lambda x: "actual": x[0], "predicted": float(x[1]))

要获得一些统计数据,您可以使用MulticlassMetrics

from pyspark.mllib.evaluation import MulticlassMetrics
from operator import itemgetter

metrics = MulticlassMetrics(
    labels_and_preds.map(itemgetter("actual", "predicted")))

metrics.confusionMatrix().toArray()
## array([[ 2.,  0.],
##        [ 0.,  2.]])

相关

Handling continuous data in Spark NaiveBayes

【讨论】:

以上是关于如何使用火花朴素贝叶斯分类器进行 IDF 文本分类?的主要内容,如果未能解决你的问题,请参考以下文章

使用 python 的朴素贝叶斯分类器

如何在 R 中为 tf-idf 加权 dfm 训练朴素贝叶斯分类器?

朴素贝叶斯实战:新闻文本分类

如何将 tf-idf 应用于整个数据集(训练和测试数据集),而不是仅在朴素贝叶斯分类器类中训练数据集?

基于TF-IDF及朴素贝叶斯的短文本分类

如何使用 sklearn 库使用朴素贝叶斯执行文本分类?