使用朴素贝叶斯(哈希词频率)的文本分类

Posted

技术标签:

【中文标题】使用朴素贝叶斯(哈希词频率)的文本分类【英文标题】:Text classification using Naive Bayes (Hashing Term Frequnecy) 【发布时间】:2016-04-21 03:43:38 【问题描述】:

我正在尝试使用朴素贝叶斯算法构建文本分类模型。

这是我的示例数据(标签和特征):

1|combusting [chemical]
1|industrial purposes
1|
2|salt for preserving, 
2|other for foodstuffs
2|auxiliary 
2|fluids for use with abrasives
3|vulcanisation 
3|accelerators
3|anti-frothing solutions for batteries
4|anti-frothing solutions for accumulators
4|acetates 
4|[chemicals]*
4|acetate of cellulose, unprocessed

以下是我的示例代码

import org.apache.spark.SparkContext
import org.apache.spark.SparkConf
import org.apache.spark.mllib.classification.NaiveBayes,     NaiveBayesModel
import org.apache.spark.mllib.linalg.Vectors
import org.apache.spark.mllib.regression.LabeledPoint
import org.apache.spark.mllib.util.MLUtils
import org.apache.spark.mllib.evaluation.MulticlassMetrics
import org.apache.spark.mllib.feature.HashingTF

val rawData = sc.textFile("~/data.csv")

val rawData1 = rawData.map(x => x.replaceAll(",","")) 

val htf = new HashingTF(1000) 

val parsedData = rawData1.map  line =>
val values = (line.split("|").toSeq)
val featureVector = htf.transform(values(1).split(" "))
val label = values(0).toDouble
LabeledPoint(label, featureVector)


val splits = parsedData.randomSplit(Array(0.8, 0.2), seed = 11L)
val training = splits(0)
val test = splits(1)

val model = NaiveBayes.train(training, lambda = 2.0, modelType = "multinomial")

val predictionAndLabels = test.map  point => 
val score = model.predict(point.features)
(score, point.label)


val metrics = new MulticlassMetrics(predictionAndLabels)
metrics.labels.foreach( l => println(metrics.fMeasure(l)))

val testData1 = htf.transform("salt")
val predictionAndLabels1 = model.predict(testData1)

我得到了大约 33% 的准确率(非常少),并且测试数据预测错误的标签。我已经打印了包含标签和特征的 parsedData,如下所示:

(1.0,(1000,[48],[1.0]))
(3.0,(1000,[49],[1.0]))
(1.0,(1000,[48],[1.0]))
(3.0,(1000,[49],[1.0]))
(1.0,(1000,[48],[1.0]))

我无法找出缺少的东西;散列项频率函数似乎会产生重复的数据项频率。请建议我改进模型性能,在此先感谢

【问题讨论】:

阅读这篇文章Text Classification。我认为你所做的一切都很好,除了散列部分。 【参考方案1】:

在开始实施算法之前,您必须问自己很多问题:

您的文本看起来很短,您的词汇量是多少,回答这个问题将帮助您调整 HashingTF 维度的值。在您的情况下,您可能需要使用较低的值。 您可能需要考虑对文本进行一些预处理。例如使用 StopWordsRemover、词干提取、分词器? 分词器将构建比您正在执行的临时文本处理更好的文本。 更改您的参数,即 HashingTF 的 NumFeatures 和朴素贝叶斯的 lambda。 基本上在机器学习中,您需要对一组参数进行交叉验证以优化您的结果。检查this 示例并尝试通过调整您的 HashingTF 和 lambda 来做类似的事情,如下所示:
val paramGrid = new ParamGridBuilder()
 .addGrid(hashingTF.numFeatures, Array(10, 100, 1000))
 .addGrid(naiveBayes.lambda, Array(0.1, 0.01))
 .build()

一般来说,使用 Pipelines 和 CrossValidation 可以与朴素贝叶斯一起进行多类分类,因此请查看 here,而不是手动对所有 septs 进行硬编码。

【讨论】:

感谢您的回复,培训文本超过 1000 行,这就是我使用 htf (1000) 的原因。我将尝试使用 tokenizer 和 stopwordremover 方法来预处理文本。

以上是关于使用朴素贝叶斯(哈希词频率)的文本分类的主要内容,如果未能解决你的问题,请参考以下文章

朴素贝叶斯方法的R语言实现

朴素贝叶斯应用:垃圾邮件分类

朴素贝叶斯分类算法的sklearn实现

朴素贝叶斯的应用

机器学习实验使用朴素贝叶斯进行文本的分类

朴素贝叶斯应用:垃圾邮件分类