使用Spark ML进行文本分类

我有一段基于免费文本描述的分类需求。例如,描述可能是关于某事件的。根据事件的描述,我需要预测与该事件相关的风险。例如:“镇上发生了一起谋杀案”——这种描述属于“高”风险的候选。

我尝试过使用逻辑回归,但发现目前仅支持二分类。对于基于免费文本描述的多类分类(只有三个可能的值),最合适的算法是什么?(线性回归还是朴素贝叶斯)


回答:

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

虽然预测准确率还不错,但模型仍需进一步调整以获得更好的结果。

专家们,如果发现有什么不对的地方,请回复我。

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

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

  1. 在输入数据框架中添加一个新的列“标签”。该列将基本解码风险分类,如下所示
sqlContext.udf().register("myUDF", new UDF1<String, Integer>() {            @Override            public Integer call(String input) throws Exception {                if ("LOW".equals(input))                    return 1;                if ("MEDIUM".equals(input))                    return 2;                if ("HIGH".equals(input))                    return 3;                return 0;            }        }, DataTypes.IntegerType);samplingData = samplingData.withColumn("label", functions.callUDF("myUDF", samplingData.col("riskClassification")));
  1. 创建训练数据集(80%)和测试数据集(20%)

例如:

DataFrame lowRisk = samplingData.filter(samplingData.col("label").equalTo(1));DataFrame lowRiskTraining = lowRisk.sample(false, 0.8);
  1. 联合所有数据框架以构建完整的训练数据

  2. 构建测试数据稍微有些 tricky。测试数据应包含训练数据中不存在的所有数据

  3. 开始转换训练数据并构建模型

6 . 对训练数据集中的文本列进行分词

Tokenizer tokenizer = new Tokenizer().setInputCol("text").setOutputCol("words");DataFrame tokenized = tokenizer.transform(trainingRiskData);
  1. 移除停用词。(在这里您还可以使用斯坦福NLP库执行更高级的操作,如词形还原、词干提取、词性标注等)
StopWordsRemover remover = new StopWordsRemover().setInputCol("words").setOutputCol("filtered");DataFrame stopWordsRemoved = remover.transform(tokenized);
  1. 使用HashingTF计算词频。CountVectorizer是另一种执行此操作的方法
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);
  1. 将特征化的输入转换为JavaRDD。朴素贝叶斯在LabeledPoint上运行
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;        }    });
  1. 构建模型
NaiveBayes naiveBayes = new NaiveBayes(1.0, "multinomial");NaiveBayesModel naiveBayesModel = naiveBayes.train(labelledJavaRDD.rdd(), 1.0);
  1. 对测试数据也运行上述所有转换

  2. 遍历测试数据框架并执行以下操作

  3. 使用测试数据框架中的“标签”和“特征”创建一个LabeledPoint

例如:如果测试数据框架的第三列和第七列分别是标签和特征,那么

LabeledPoint labeledPoint = new LabeledPoint(new Double(dataFrameRow.get(3).toString()),(org.apache.spark.mllib.linalg.Vector) dataFrameRow.get(7));
  1. 使用预测模型预测标签
double predictedLabel = naiveBayesModel.predict(labeledPoint.features());
  1. 将预测的标签也作为一列添加到测试数据框架中。

  2. 现在测试数据框架中包含了预期标签和预测标签。

  3. 您可以将测试数据导出为csv进行分析,或者也可以编程计算准确率。

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注