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)
總結
以上是生活随笔為你收集整理的mllib java怎么调用_如何准备mllib中的训练数据的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java实现两个最大整数相加_JAVA-
- 下一篇: supmap java_SuperMap