mllib java怎么调用_如何准备mllib中的训练数据

ML LogisticRegression 尚不支持多项分类,但MLLib NaiveBayes 和 LogisticRegressionWithLBFGS 都支持它 . 在第一种情况下,它应该默认工作:

import org.apache.spark.mllib.classification.NaiveBayes

val nbModel = new NaiveBayes()

.setModelType("multinomial") // This is default value

.run(train)

但是对于逻辑回归,你应该提供一些类:

import org.apache.spark.mllib.classification.LogisticRegressionWithLBFGS

val model = new LogisticRegressionWithLBFGS()

.setNumClasses(n) // Set number of classes

.run(trainingData)

关于预处理步骤,这是一个相当广泛的主题,如果没有访问您的数据,很难给您一个有意义的建议,所以您在下面找到的所有内容只是一个疯狂的猜测:

据我所知,您使用维基数据进行培训和推文进行测试 . 如果这是真的,一般来说这是一个坏主意 . 您可以预期两组使用显着不同的词汇,语法和拼写

简单的正则表达式标记符可以在标准化文本上很好地执行,但根据我的经验,它不会像推文那样在非正式文本上运行良好

HashingTF 可以是获得基线模型的好方法,但它是极其简化的方法,特别是如果您不应用任何过滤步骤 . 如果您决定使用它,至少应增加功能数量或使用默认值(2 ^ 20)

EDIT (用IDF为朴素贝叶斯准备数据)

使用ML管道:

import org.apache.spark.mllib.regression.LabeledPoint

import org.apache.spark.mllib.linalg.Vector

import org.apache.spark.ml.feature.IDF

import org.apache.spark.sql.Row

val tokenizer = ???

val hashingTF = new HashingTF()

.setNumFeatures(1000)

.setInputCol(tokenizer.getOutputCol)

.setOutputCol("rawFeatures")

val idf = new IDF()

.setInputCol(hashingTF.getOutputCol)

.setOutputCol("features")

val pipeline = new Pipeline().setStages(Array(tokenizer, hashingTF, idf))

val model = pipeline.fit(labeledData)

model

.transform(labeledData)

.select($"label", $"features")

.map{case Row(label: Double, features: Vector) => LabeledPoint(label, features)}

使用MLlib变换器:

import org.apache.spark.mllib.feature.HashingTF

import org.apache.spark.mllib.linalg.Vector

import org.apache.spark.mllib.feature.{IDF, IDFModel}

val labeledData = wikiData.map(x =>

LabeledData(x.category, x.text, categoryMap.get(x.category).getOrElse(0.0)))

val p = "\\W+".r

val raw = labeledData.map{

case LabeledData(_, text, label) => (label, p.split(text))}

val hashingTF: org.apache.spark.mllib.feature.HashingTF = new HashingTF(1000)

val tf = raw.map{case (label, text) => (label, hashingTF.transform(text))}

val idf: org.apache.spark.mllib.feature.IDFModel = new IDF().fit(tf.map(_._2))

tf.map{

case (label, rawFeatures) => LabeledPoint(label, idf.transform(rawFeatures))}

注意:由于变换器需要JVM访问,因此MLlib版本在PySpark中不起作用 . 如果你更喜欢Python,你必须split data transform and zip .

EDIT (为ML算法准备数据):

虽然下面的代码看起来有点乍一看

val categoryMap = wikiData

.map(x=>x.category)

.distinct

.zipWithIndex

.mapValues(x=>x.toDouble/1000)

.collectAsMap

val labeledData = wikiData.map(x=>LabeledData(

x.category, x.text, categoryMap.get(x.category).getOrElse(0.0))).toDF

它不会为 ML 算法生成有效标签 .

首先 ML 期望标签在(0.0,1.0,...,n.0)中,其中n是类的数量 . 如果你的示例管道中有一个类得到标签0.001,你将得到如下错误:

ERROR LogisticRegression:分类标签应在{0到0中找到1个无效标签 .

显而易见的解决方案是在生成映射时避免除法

.mapValues(x=>x.toDouble)

虽然它适用于 LogisticRegression 其他 ML 算法仍然会失败 . 例如 RandomForestClassifier 你会得到

给RandomForestClassifier输入了无效的标签列标签,没有指定的类数 . 请参见StringIndexer .

有趣的是, RandomForestClassifier 的ML版本与 MLlib 版本不同,它没有提供设置多个类的方法 . 事实证明,它希望在 DataFrame 列上设置特殊属性 . 最简单的方法是使用错误消息中提到的 StringIndexer :

import org.apache.spark.ml.feature.StringIndexer

val indexer = new StringIndexer()

.setInputCol("category")

.setOutputCol("label")

val pipeline = new Pipeline()

.setStages(Array(indexer, tokenizer, hashingTF, idf, lr))

val model = pipeline.fit(wikiData.toDF)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值