我尝试使用Spark 1.1.0提供的新的TFIDF算法。我正在用Java写MLLib的工作,但我不知道如何使TFIDF实现正常工作。由于某种原因,IDFModel仅接受JavaRDD作为方法transform的输入,而不接受简单的Vector。 如何使用给定的类为我的LabledPoints建模TFIDF vector ?
注意:文档行的格式为[标签;文本]
到目前为止,这里是我的代码:
// 1.) Load the documents
JavaRDD<String> data = sc.textFile("/home/johnny/data.data.new");
// 2.) Hash all documents
HashingTF tf = new HashingTF();
JavaRDD<Tuple2<Double, Vector>> tupleData = data.map(new Function<String, Tuple2<Double, Vector>>() {
@Override
public Tuple2<Double, Vector> call(String v1) throws Exception {
String[] data = v1.split(";");
List<String> myList = Arrays.asList(data[1].split(" "));
return new Tuple2<Double, Vector>(Double.parseDouble(data[0]), tf.transform(myList));
}
});
tupleData.cache();
// 3.) Create a flat RDD with all vectors
JavaRDD<Vector> hashedData = tupleData.map(new Function<Tuple2<Double,Vector>, Vector>() {
@Override
public Vector call(Tuple2<Double, Vector> v1) throws Exception {
return v1._2;
}
});
// 4.) Create a IDFModel out of our flat vector RDD
IDFModel idfModel = new IDF().fit(hashedData);
// 5.) Create Labledpoint RDD with TFIDF
???
来自Sean Owen的解决方案:
// 1.) Load the documents
JavaRDD<String> data = sc.textFile("/home/johnny/data.data.new");
// 2.) Hash all documents
HashingTF tf = new HashingTF();
JavaRDD<LabeledPoint> tupleData = data.map(v1 -> {
String[] datas = v1.split(";");
List<String> myList = Arrays.asList(datas[1].split(" "));
return new LabeledPoint(Double.parseDouble(datas[0]), tf.transform(myList));
});
// 3.) Create a flat RDD with all vectors
JavaRDD<Vector> hashedData = tupleData.map(label -> label.features());
// 4.) Create a IDFModel out of our flat vector RDD
IDFModel idfModel = new IDF().fit(hashedData);
// 5.) Create tfidf RDD
JavaRDD<Vector> idf = idfModel.transform(hashedData);
// 6.) Create Labledpoint RDD
JavaRDD<LabeledPoint> idfTransformed = idf.zip(tupleData).map(t -> {
return new LabeledPoint(t._2.label(), t._1);
});
最佳答案
如您所见,IDFModel.transform()
接受JavaRDD
的RDD
或Vector
。在单个Vector
上计算模型是没有意义的,所以这不是您想要的吗?
我假设您正在使用Java,所以您的意思是要将其应用于JavaRDD<LabeledPoint>
。 LabeledPoint
包含一个Vector
和一个标签。 IDF不是分类器或回归器,因此不需要标签。您可以map
一堆LabeledPoint
来提取他们的Vector
。
但是您上面已经有一个JavaRDD<Vector>
。 TF-IDF仅仅是根据语料库中的词频将词映射到实值特征的一种方式。它还不输出标签。也许您的意思是想从TF-IDF衍生的特征向量以及其他一些已有的标签中开发分类器?
也许这可以解决问题,但否则,您必须极大地阐明您正在尝试使用TF-IDF实现的目标。