使用支持向量机进行问题分类

时间:2017-12-14 07:31:12

标签: pyspark svm apache-spark-mllib

我正在尝试使用SVM对问题进行分类。我正在关注此链接以供参考 -

https://shirishkadam.com/2017/07/03/nlp-question-classification-using-support-vector-machines-spacyscikit-learnpandas/

但是他们使用了SPACY,SCIKIT-LEARN和PANDAS。我想用Spark Mllib做同样的事情。 我正在使用此代码创建一个Dataframe -

sc = SparkContext(conf=sconf)  # SparkContext
sqlContext = SQLContext(sc)
data = sc.textFile("<path_to_csv_file>")
header = data.first()
trainingDF = sqlContext.createDataFrame(data
    .filter(lambda line: line != header)
    .map(lambda line: line.split("|"))
    .map(lambda line: ([line[0]], [line[2]], [line[6]]))).toDF("Question", "WH-Bigram", "Class")

我通过打印dataframe- trainingDF.show(3)

获得了以下结果
+--------------------+-------------------+------+
|            Question|          WH-Bigram| Class|
+--------------------+-------------------+------+
|[How did serfdom ...|          [How did]|[DESC]|
|[What films featu...|       [What films]|[ENTY]|
|[How can I find a...|          [How can]|[DESC]|

我的示例csv文件是 -

#Question|WH|WH-Bigram|Class
How did serfdom develop in and then leave Russia ?|How|How did|DESC

我正在使用word2vec为SVM创建训练数据并尝试使用SVM进行训练。

word2Vec1 = Word2Vec(vectorSize=2, minCount=0, inputCol="Question", outputCol="result1")
training = word2Vec1.fit(trainingDF).transform(trainingDF)
model = SVMWithSGD.train(training, iterations=100)

使用word2vec后,我的数据将以这种格式转换 -

[Row(Question=[u'How did serfdom develop in and then leave Russia ?'], WH-Bigram=[u'How did'], Class=[u'DESC'], result1=DenseVector([0.0237, -0.186])), Row(Question=[u'What films featured the character Popeye Doyle ?'], WH-Bigram=[u'What films'], Class=[u'ENTY'], result1=DenseVector([-0.2429, 0.0935]))]

但是当我尝试使用SVM训练数据帧时,会收到TypeError: data should be an RDD of LabeledPoint, but got <class 'pyspark.sql.types.Row'>

的错误

我被困在这里......我认为我创建的数据帧不正确。 是否有人知道如何使用SVM创建合适的数据框进行训练。如果我做错了,请告诉我。

1 个答案:

答案 0 :(得分:0)

很高兴您在Spark中尝试了一种机器学习方法,但是您的方法存在多个问题,

1)您的数据有多个类,它不是二进制分类模型,因此Spark中的SVM不适用于此数据集(您可以查看源代码here)。您可以尝试一个类与所有其他方法,并训练与数据中的类一样多的模型。但是,最好在Spark中使用MultilayerPerceptronClassifier或多类逻辑模型。

2)其次,Mllib在您使用的类标签方面非常无情,您只能指定0,1,2或0.0,1.0,2.0等,即它不会根据您自动推断出类的数量输出栏。即使你指定两个类为1.0&amp; 2.0它不会工作它必须是0.0&amp; 1.0。

3)您需要使用标记点RDD而不是spark数据帧,请记住spark.mllib用于RDD,而spark.ml用于数据帧。关于如何创建Labeledpoint rdd的帮助,您可以参考spark文档here,其中有多个示例。

4)在一个特色工程说明中,我认为你不想把你的word2vec模型的vectorSize视为2(类似于10的东西更适合作为起点),这些太简单了一个合理的预测。