Apache spark 基于sparkml的文本分类

Apache spark 基于sparkml的文本分类,apache-spark,machine-learning,distributed-computing,apache-spark-mllib,data-science,spark,bigdata,python,pyspark,Apache Spark,Machine Learning,Distributed Computing,Apache Spark Mllib,Data Science,Spark,Bigdata,Python,Pyspark,我有一个自由文本描述,我需要根据它进行分类。例如,描述可以是事件的描述。根据对事件的描述,我需要预测与事件相关的风险。例如:“镇上的谋杀案”——这一描述是“高”风险的候选 我尝试了逻辑回归,但意识到目前只支持二元分类。对于基于自由文本描述的多类分类(只有三个可能的值),最合适的算法是什么?(线性回归或朴素贝叶斯)这就是我解决上述问题的方法 虽然预测精度不差,但模型还需要进一步调整 为了更好的结果 专家,如果您发现任何错误,请返回 我的输入数据框有两列“文本”和“风险分类” 下面是在Java中使用

我有一个自由文本描述,我需要根据它进行分类。例如,描述可以是事件的描述。根据对事件的描述,我需要预测与事件相关的风险。例如:“镇上的谋杀案”——这一描述是“高”风险的候选


我尝试了逻辑回归,但意识到目前只支持二元分类。对于基于自由文本描述的多类分类(只有三个可能的值),最合适的算法是什么?(线性回归或朴素贝叶斯)

这就是我解决上述问题的方法

虽然预测精度不差,但模型还需要进一步调整 为了更好的结果

专家,如果您发现任何错误,请返回

我的输入数据框有两列“文本”和“风险分类”

下面是在Java中使用朴素贝叶斯进行预测的一系列步骤

  • 将新列“标签”添加到输入数据框。本专栏将基本上解码如下所示的风险分类
  • 合并所有数据帧以构建完整的训练数据

  • 构建测试数据有点棘手。测试数据应包含以下所有数据: 在培训数据中不存在

  • 开始转换培训数据并建立模型

  • 六,。标记训练数据集中的文本列

    Tokenizer tokenizer = new Tokenizer().setInputCol("text").setOutputCol("words");
    DataFrame tokenized = tokenizer.transform(trainingRiskData);
    
  • 删除停止词。(在这里,您还可以使用斯坦福NLP库执行高级操作,如lemme、词干分析器、POS等)
  • 使用HashingTF计算术语频率。CountVectorizer是另一种方法
  • 将特征化输入转换为JavaRDD。NaiveBayes在LabeledPoint上工作
  • 还对测试数据运行上述所有转换

  • 循环测试数据帧并执行以下操作

  • 使用测试数据框中的“标签”和“特征”创建标签点

  • 例如:如果测试数据框在第三列和第七列中有标签和特征,则

    LabeledPoint labeledPoint = new LabeledPoint(new Double(dataFrameRow.get(3).toString()),
    (org.apache.spark.mllib.linalg.Vector) dataFrameRow.get(7));
    
  • 使用预测模型预测标签
  • 将预测标签也作为列添加到测试数据框中

  • 现在,测试数据帧具有预期标签和预测标签

  • 您可以将测试数据导出到csv并进行分析,也可以通过编程计算精度

  • 由于您正在使用,我想您已经使用了,所以-我不是专家-但在阅读您的答案后,我想提出一些观点

    创建培训(80%)和测试数据集(20%)

    我会将我的数据划分为培训(60-70%)、测试(15-20%)和评估(15-20%)集

    这个想法是你可以微调你的分类算法w.r.t.训练集,但我们真正想做的是分类任务,就是让他们对看不见的数据进行分类。因此,使用测试集对算法进行微调,完成后,使用评估集,以真正了解事物的工作原理

    停止语

    如果你的数据是报纸上的文章之类的,我个人没有看到使用更复杂的停止词删除方法有任何显著的改进

    但这只是个人陈述,但如果我是你,我不会专注于这一步

    术语频率

    用术语权重代替如何?您可能需要阅读:

    我会尝试两者并进行比较

    多项式

    你有什么特别的理由去尝试多项式分布吗?如果否,因为当n为1,k为2时,多项式分布为伯努利分布,如中所述,其中

    尝试两者并进行比较(如果你想让你的模型更好,这是你必须习惯的!)


    我也看到了这些提议,至少值得一读!)


    如果您的数据不是那么大,我也会尝试支持向量机(SVM),但是它支持,所以您应该切换到或普通,放弃。顺便说一句,如果你真的要去sklearn,这可能会派上用场:因为熊猫和sklearn玩得很好

    希望这有帮助


    离题:

    这并不是在堆栈溢出中提问的方式。阅读

    就个人而言,如果我是你,我会先做你在回答中做的所有事情,然后发布一个问题,总结我的方法


    至于赏金,你可能想读一读:

    谢谢你的夸奖。我会按照你的建议去做mentioned@lives伟大的我也更新了我的答案,因为我现在在做支持向量机,我感觉你很好!
    Tokenizer tokenizer = new Tokenizer().setInputCol("text").setOutputCol("words");
    DataFrame tokenized = tokenizer.transform(trainingRiskData);
    
    StopWordsRemover remover = new StopWordsRemover().setInputCol("words").setOutputCol("filtered");
    DataFrame stopWordsRemoved = remover.transform(tokenized);
    
    int numFeatures = 20;
    HashingTF hashingTF = new HashingTF().setInputCol("filtered").setOutputCol("rawFeatures")
            .setNumFeatures(numFeatures);
    DataFrame rawFeaturizedData = hashingTF.transform(stopWordsRemoved);
    
    IDF idf = new IDF().setInputCol("rawFeatures").setOutputCol("features");
    IDFModel idfModel = idf.fit(rawFeaturizedData);
    
    DataFrame featurizedData = idfModel.transform(rawFeaturizedData);
    
    JavaRDD<LabeledPoint> labelledJavaRDD = featurizedData.select("label", "features").toJavaRDD()
        .map(new Function<Row, LabeledPoint>() {
    
            @Override
            public LabeledPoint call(Row arg0) throws Exception {
                LabeledPoint labeledPoint = new LabeledPoint(new Double(arg0.get(0).toString()),
                        (org.apache.spark.mllib.linalg.Vector) arg0.get(1));
                return labeledPoint;
            }
        });
    
    NaiveBayes naiveBayes = new NaiveBayes(1.0, "multinomial");
    NaiveBayesModel naiveBayesModel = naiveBayes.train(labelledJavaRDD.rdd(), 1.0);
    
    LabeledPoint labeledPoint = new LabeledPoint(new Double(dataFrameRow.get(3).toString()),
    (org.apache.spark.mllib.linalg.Vector) dataFrameRow.get(7));
    
    double predictedLabel = naiveBayesModel.predict(labeledPoint.features());