我正在准备包含ID(标签)和关键字(功能)的数据,以便将它们传递给Java中的MLlib算法。我的关键字是用逗号分隔的字符串。我的目标是使用多类分类算法来预测id。问题是,我如何构建Labeledpoint Vector?
我在下面尝试了这种转换,但我得到了一个低精度(30%)。值得一提的是,当我使用自己的KNN分类代码(普通java)时,我获得了超过70%的优势。
特征转换:
Tokenizer tokenizer = new Tokenizer().setInputCol("keywords")
.setOutputCol("words");
DataFrame wordsData = tokenizer.transform(df);
wordsData.show();
int numFeatures = 35;
HashingTF hashingTF = new HashingTF().setInputCol("words")
.setOutputCol("rawFeatures").setNumFeatures(numFeatures);
DataFrame featurizedData = hashingTF.transform(wordsData);
//featurizedData.show();
featurizedData.cache();
IDF idf = new IDF().setInputCol("rawFeatures").setOutputCol(
"features");
IDFModel idfModel = idf.fit(featurizedData);
DataFrame rescaledData = idfModel.transform(featurizedData);
JavaRDD<Row> rescaledRDD = rescaledData.select("features", "id")
.toJavaRDD();
JavaRDD<LabeledPoint> test = rescaledRDD
.map(new MakeLabledPointRDD());
这是使用稀疏向量将RDD行转换为带标签点的正确方法吗?我是否需要计算关键字并使用CountVectorizer?否则构建它的最佳方法是什么?
public static class MakeLabledPointRDD implements
Function<Row, LabeledPoint> {
@Override
public LabeledPoint call(Row r) throws Exception {
Vector features = r.getAs(0); //keywords in RDD
Integer str = r.getInt(1); //id in RDD
Double label = (double) str;
LabeledPoint lp = new LabeledPoint(label, features);
return lp;
}
}
答案 0 :(得分:0)
您的 MakeLabledPointRDD 似乎是正确的。但是, TFIDF 转换似乎是在行级别上工作的本地转换。这意味着您获得的权重实际上是针对身份的每个实例。
您需要做的就是在创建 TFIDF 向量之前按 ID 对行进行分组,即您的 df 变量应该只包含一行pro ID 。