Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache spark Scala Spark中基于数据帧的朴素贝叶斯多项式文本分类器_Apache Spark_Text Classification_Apache Spark Mllib_Naivebayes - Fatal编程技术网

Apache spark Scala Spark中基于数据帧的朴素贝叶斯多项式文本分类器

Apache spark Scala Spark中基于数据帧的朴素贝叶斯多项式文本分类器,apache-spark,text-classification,apache-spark-mllib,naivebayes,Apache Spark,Text Classification,Apache Spark Mllib,Naivebayes,我试图构建一个NaiveBayes分类器,将数据库中的数据作为包含(标签、文本)的数据帧加载。 以下是数据样本(多项式标签): 我对标记化、stopword、n-gram和hashTF使用了以下转换: val selectedData=df.select(“标签”、“特征”) //标记化RDD val tokenizer=new tokenizer().setInputCol(“功能”).setOutputCol(“文字”) val regexTokenizer=new regexTokeniz

我试图构建一个NaiveBayes分类器,将数据库中的数据作为包含(标签、文本)的数据帧加载。 以下是数据样本(多项式标签):

我对标记化、stopword、n-gram和hashTF使用了以下转换:

val selectedData=df.select(“标签”、“特征”)
//标记化RDD
val tokenizer=new tokenizer().setInputCol(“功能”).setOutputCol(“文字”)
val regexTokenizer=new regexTokenizer().setInputCol(“功能”).setOutputCol(“文字”).setPattern(\\W)
val tokenized=tokenizer.transform(selectedData)
标记化。选择(“单词”、“标签”)。获取(3)。foreach(println)
//删除停止词
val remover=new StopWordsRemover().setInputCol(“文字”).setOutputCol(“过滤”)
val parsedData=remover.transform(标记化)
//N克
val ngram=new ngram().setInputCol(“过滤”).setOutputCol(“ngrams”)
val ngramDataFrame=ngram.transform(parsedData)
ngramDataFrame.take(3).map(u.getAs[Stream[String]](“ngrams”).toList.foreach(println)
//散列函数
val hashingTF=new hashingTF().setInputCol(“ngrams”).setOutputCol(“hash”).setNumFeatures(1000)
val FeatureizedData=hashingTF.transform(ngramDataFrame)
转换的输出:

+-----+--------------------+--------------------+--------------------+------    --------------+--------------------+
|label|             feature|               words|            filtered|                  ngrams|                hash|
+-----+--------------------+--------------------+--------------------+------    --------------+--------------------+
|    1|combusting prepar...|[combusting, prep...|[combusting, prep...|    [combusting prepa...|(1000,[124,161,69...|
|    1|adhesives for ind...|[adhesives, for, ...|[adhesives, indus...| [adhesives indust...|(1000,[451,604],[...|
|    1|                    |                  []|                  []|                     []|        (1000,[],[])|
|    1| salt for preserving|[salt, for, prese...|  [salt, preserving]|   [salt   preserving]|  (1000,[675],[1.0])|
|    1|auxiliary fluids ...|[auxiliary, fluid...|[auxiliary, fluid...|[auxiliary fluids...|(1000,[661,696,89...|
要构建朴素的贝叶斯模型,我需要将标签和特征转换为
LabelPoint
。我尝试了以下方法将数据帧转换为RDD并创建labelpoint:

val rddData=featureizeddata.select(“label”、“hash”).rdd
val trainData=rddData.map{line=>
val parts=line.split(',')
贴标点(第(0)部分、第(1)部分)
}
val rddData=featureizeddata.select(“label”、“hash”).rdd.map(r=>(Try(r(0).asInstanceOf[Integer]).get.toDouble,Try(r(1).asInstanceOf[org.apache.spark.mllib.linalg.SparseVector]).get))
val trainData=rddData.map{line=>
val parts=line.split(',')
LabeledPoint(部分(0).toDouble,Vectors.dense(部分(1).split('),').map(0.toDouble)))
}
我得到以下错误:

 scala> val trainData = rddData.map { line =>
 |   val parts = line.split(',')
 |   LabeledPoint(parts(0).toDouble, Vectors.dense(parts(1).split(',').map(_.toDouble)))
 | }
 <console>:67: error: value split is not a member of (Double,    org.apache.spark.mllib.linalg.SparseVector)
     val parts = line.split(',')
                      ^
<console>:68: error: not found: value Vectors
     LabeledPoint(parts(0).toDouble,   Vectors.dense(parts(1).split(',').map(_.toDouble)))

使用N-gram和不使用N-gram以及不同的散列特征数时,我的准确率降低了40%左右。我的数据集包含5000行和45个多行标签。有没有办法提高模型的性能?提前感谢

您不需要将您的
FeatureizedData
转换为
RDD
,因为
ApacheSark
有两个库
ML
MLLib
,第一个库使用
DataFrame
s,而
MLLib
使用
RDD
s。因此,您可以使用
ML
,因为您已经有了一个
DataFrame

为了实现这一点,您只需将列重命名为(
label
features
),并适合您的模型,如下面的示例所示

df=sqlContext.createDataFrame([
行(标签=0.0,特征=向量。密集([0.0,0.0])),
行(标签=0.0,特征=Vectors.dense([0.0,1.0]),
行(label=1.0,features=Vectors.densite([1.0,0.0]))
nb=朴素贝叶斯(平滑=1.0,modelType=“多项式”)
型号=nb.配合(df)
关于您得到的错误,是因为您已经有了一个
SparseVector
,而该类没有
split
方法。因此,仔细考虑一下,您的
RDD
几乎具有您实际需要的结构,但是您必须将
元组
转换为
标签点


有一些技巧可以提高性能,我想到的第一个技巧是删除停止词(例如,a,an,to,虽然等等),第二个技巧是计算文本中不同单词的数量,然后手动构建向量,也就是说,这是因为如果哈希值较低,则不同的单词可能具有相同的哈希值,因此性能较差。

感谢@alberto的回复。如果我错了,请纠正我,我正在尝试使用特征化数据将数据转换为LabelPoint。你能给我建议什么方法把数据转换成LabelPoint吗?@ManishV读了我信息的最后一部分,我给你一个提示:)谢谢你的建议@alberto,我已经更新了代码并创建了模型。你能建议我改进模型的性能吗。
 scala> val trainData = rddData.map { line =>
 |   val parts = line.split(',')
 |   LabeledPoint(parts(0).toDouble, Vectors.dense(parts(1).split(',').map(_.toDouble)))
 | }
 <console>:67: error: value split is not a member of (Double,    org.apache.spark.mllib.linalg.SparseVector)
     val parts = line.split(',')
                      ^
<console>:68: error: not found: value Vectors
     LabeledPoint(parts(0).toDouble,   Vectors.dense(parts(1).split(',').map(_.toDouble)))
val trainData = featurizedData.select("label","features")

val trainLabel = trainData.map(line =>  LabeledPoint(Try(line(0).asInstanceOf[Integer]).get.toDouble,Try(line(1).asInsta nceOf[org.apache.spark.mllib.linalg.SparseVector]).get))

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

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

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