LogisticRegression的Spark MLLib TFIDF实现

Joh*_*000 9 java tf-idf apache-spark apache-spark-mllib

我尝试使用火花1.1.0提供的新TFIDF算法.我正在用Java编写我的MLLib工作,但我无法弄清楚如何使TFIDF实现工作.由于某种原因,IDFModel仅接受JavaRDD作为方法转换的输入而不是简单的Vector.如何使用给定的类为我的LabledPoints建模TFIDF向量?

注意:文档行的格式为[标签; 文本]


到目前为止我的代码:

        // 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
        ???
Run Code Online (Sandbox Code Playgroud)

肖恩欧文的解决方案:

        // 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);
        });
Run Code Online (Sandbox Code Playgroud)

Sea*_*wen 11

IDFModel.transform()接受JavaRDDRDDVector,如你所见.计算单个模型是没有意义的Vector,所以这不是你想要的吗?

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

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

也许这会让事情变得清晰,但除此之外,你必须大大澄清你想用TF-IDF实现的目标.

  • 啊我在这里犯了一个错误.它是计算频率的"IDF".是的,如果`IDFModel`也在单个`Vector`上运行会更有意义.你可以提出拉取请求.在此期间,这可能有效:1.持续输入RDD.2.将其转换为向量并应用`IDFModel` 3.`zip`与原始RDD 4.将标签和新向量转换为`LabeledPoint` (3认同)