9

我尝试使用 spark 1.1.0 提供的新 TFIDF 算法。我正在用 Java 编写我的 MLLib 工作,但我不知道如何让 TFIDF 实现工作。出于某种原因,IDFModel只接受JavaRDD作为方法转换的输入,而不是简单的 Vector。如何使用给定的类为我的 LabledPoints 建模 TFIDF 向量?

注意:文档行格式为 [Label; 文本]


到目前为止,这是我的代码:

        // 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
        ???

肖恩欧文的解决方案

        // 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);
        });
4

1 回答 1

11

IDFModel.transform()如您所见,接受JavaRDDor RDDVector在单个 上计算模型是没有意义的Vector,所以这不是你要找的,对吧?

我假设你正在使用 Java,所以你的意思是你想把它应用到JavaRDD<LabeledPoint>. LabeledPoint包含一个Vector和一个标签。IDF 不是分类器或回归器,因此它不需要标签。你可以map一堆LabeledPoint只提取他们的Vector.

但是你已经有了JavaRDD<Vector>上面。TF-IDF 只是一种基于语料库中词频将词映射到实值特征的方法。它也不输出标签。也许你的意思是你想从 TF-IDF 派生的特征向量和你已经拥有的一些其他标签中开发一个分类器?

也许这可以解决问题,但否则您必须非常清楚您要使用 TF-IDF 实现的目标。

于 2014-11-15T14:38:03.933 回答