[原]PySpark NaiveBayes算法之中文文本分类测试

标签: | 发表时间:2018-06-19 16:33 | 作者:moxiaomomo
出处:https://blog.csdn.net/moxiaomomo

假设现在有N行文本,每行文本的第一列已经打好标签, Y 或 N, 用于标识该行文本是否包含敏感词汇;第二列之后的每一列是对某些句子或文本进行中文分词之后的词汇。比如

  N 朴素贝叶斯算法 是 生成模型 中 最经典 分类算法 之一
Y 这是 一条 包含 色情 的 语句

我们现在用pyspark结合NaiveBayes分类算法来进行训练和测试,这个过程大概包括:

  • 词条转换成特征向量
  • 统计词频及权重计算(TF-IDF)
  • 通过NaiveBayes对训练集进行训练得到训练模型
  • 使用训练模型对测试集进行预测
  • 计算测试数据集分类的准确率
  #!/usr/bin/python
# coding: utf-8

from pyspark.sql import SparkSession
from pyspark.sql import Row

from pyspark.ml.feature import HashingTF, IDF, Tokenizer
from pyspark.ml.linalg import Vectors
from pyspark.ml.classification import NaiveBayes  
from pyspark.ml.classification import NaiveBayesModel
from pyspark.ml.evaluation import MulticlassClassificationEvaluator 

SPARK_MASTER_HOST = "yarn"

def parse_line(p):
    cols = p.split(' ')
    label = cols[0]
    if label not in ('Y', 'N'):
        return None

    label = 1.0 if label=='Y' else 0.0
    fname = ' '.join(cols[1:])

    return Row(label=label, sentence=fname)

def words_classify_main(spark):
    sc = spark.sparkContext

    # Tokenizer将输入的字符串格式化为小写,并按空格进行分割
    tokenizer = Tokenizer(inputCol="sentence", outputCol="words")
    # 自定义使用numFeatures个hash桶来存储特征值
    hashingTF = HashingTF(inputCol="words", outputCol="rawFeatures", numFeatures=8000)
    # Inverse Document Frequency(计算逆文本频率指数)
    idf = IDF(inputCol="rawFeatures", outputCol="features")

    # 从HDFS中加载输入源到dataframe中
    srcdf = sc.textFile('/yourpath/text_classified3_*').\
        map(parse_line_v1).filter(lambda x: x is not None).toDF()
    # 这里按80%-20%的比例分成训练集和测试集
    training, testing = srcdf.randomSplit([0.8, 0.2])

    # 得到训练集的词条集合
    wordsData = tokenizer.transform(training)
    # 将词条集合转换为特征向量集合
    featurizedData = hashingTF.transform(wordsData)
    # 在特征向量上应用fit()来得到model
    idfModel = idf.fit(featurizedData)
    # 得到每个单词对应的TF-IDF度量值
    rescaledData = idfModel.transform(featurizedData)
    # 持久化,避免重复加载
    rescaledData.persist()

    # 转换数据集用于NaiveBayes的输入
    trainDF = rescaledData.select("features", "label").rdd.map(
         lambda x:Row(label=float(x['label']), features=Vectors.dense(x['features']))
         ).toDF()
    # NaiveBayes分类器
    naivebayes = NaiveBayes(smoothing=1.0, modelType="multinomial")
    # 通过训练集得到NaiveBayesModel
    model = naivebayes.fit(trainDF)

    # 得到测试集的词条集合
    testWordsData = tokenizer.transform(testing)
    # 将词条集合转换为特征向量集合
    testFeaturizedData = hashingTF.transform(testWordsData)
    # 在特征向量上应用fit()来得到model
    testIDFModel = idf.fit(testFeaturizedData)
    # 得到每个单词对应的TF-IDF度量值
    testRescaledData = testIDFModel.transform(testFeaturizedData)
    # 持久化,避免重复加载
    testRescaledData.persist()

    testDF = testRescaledData.select("features", "label").rdd.map(
         lambda x:Row(label=float(x['label']), features=Vectors.dense(x['features']))
         ).toDF()
    # 使用训练模型对测试集进行预测
    predictions = model.transform(testDF)
    predictions.show()

    # 计算model在测试集上的准确性
    evaluator = MulticlassClassificationEvaluator(
        labelCol="label", predictionCol="prediction", metricName="accuracy")
    accuracy = evaluator.evaluate(predictions)
    print("The accuracy on test-set is " + str(accuracy))


if __name__ == "__main__":
    spark = SparkSession \
        .builder \
        .master(SPARK_MASTER_HOST) \
        .appName("spark_naivebayes_classify") \
        .getOrCreate()

    words_classify_main(spark)

    spark.stop()

最终在我本地的测试准确率达到89%,说明分类样本集还算是比较有代表性。可以在这个基础上继续优化样本集,在提升准确率之后,再对样本集外的数据进行预测和优化的迭代。

作者:moxiaomomo 发表于 2018/06/19 16:33:39 原文链接 https://blog.csdn.net/moxiaomomo/article/details/80735784
阅读:5

相关 [pyspark naivebayes 算法] 推荐:

[原]PySpark NaiveBayes算法之中文文本分类测试

- - moxiaomomo的专栏
假设现在有N行文本,每行文本的第一列已经打好标签, Y 或 N, 用于标识该行文本是否包含敏感词汇;第二列之后的每一列是对某些句子或文本进行中文分词之后的词汇. N 朴素贝叶斯算法 是 生成模型 中 最经典 分类算法 之一 Y 这是 一条 包含 色情 的 语句. 我们现在用pyspark结合NaiveBayes分类算法来进行训练和测试,这个过程大概包括:.

缓存算法

- lostsnow - 小彰
没有人能说清哪种缓存算法由于其他的缓存算法. (以下的几种缓存算法,有的我也理解不好,如果感兴趣,你可以Google一下  ). 大家好,我是 LFU,我会计算为每个缓存对象计算他们被使用的频率. 我是LRU缓存算法,我把最近最少使用的缓存对象给踢走. 我总是需要去了解在什么时候,用了哪个缓存对象.

BFPRT算法

- zii - 小彰
BFPRT算法的作者是5位真正的大牛(Blum 、 Floyd 、 Pratt 、 Rivest 、 Tarjan),该算法入选了在StackExchange上进行的当今世界十大经典算法,而算法的简单和巧妙颇有我们需要借鉴学习之处. BFPRT解决的问题十分经典,即从某n个元素的序列中选出第k大(第k小)的元素,通过巧妙的分析,BFPRT可以保证在最坏情况下仍为线性时间复杂度.

贪心算法

- Shan - 博客园-首页原创精华区
顾名思义,贪心算法总是作出在当前看来最好的选择. 也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上的局部最优选择. 当然,希望贪心算法得到的最终结果也是整体最优的. 虽然贪心算法不能对所有问题都得到整体最优解,但对许多问题它能产生整体最优解. 如单源最短路经问题,最小生成树问题等.

缓存算法

- 成 - FeedzShare
来自: 小彰 - FeedzShare  . 发布时间:2011年09月25日,  已有 2 人推荐. 没有人能说清哪种缓存算法由于其他的缓存算法. (以下的几种缓存算法,有的我也理解不好,如果感兴趣,你可以Google一下  ). 大家好,我是 LFU,我会计算为每个缓存对象计算他们被使用的频率.

K-Means 算法

- - 酷壳 - CoolShell.cn
最近在学习一些数据挖掘的算法,看到了这个算法,也许这个算法对你来说很简单,但对我来说,我是一个初学者,我在网上翻看了很多资料,发现中文社区没有把这个问题讲得很全面很清楚的文章,所以,把我的学习笔记记录下来,分享给大家. k-Means 算法是一种  cluster analysis 的算法,其主要是来计算数据聚集的算法,主要通过不断地取离种子点最近均值的算法.

查找算法:

- - CSDN博客推荐文章
从数组的第一个元素开始查找,并将其与查找值比较,如果相等则停止,否则继续下一个元素查找,直到找到匹配值. 注意:要求被查找的数组中的元素是无序的、随机的. 比如,对一个整型数组的线性查找代码:. // 遍历整个数组,并分别将每个遍历元素与查找值对比. 要查找的值在数组的第一个位置. 也就是说只需比较一次就可达到目的,因此最佳情况的大O表达式为:O(1).

排序算法

- - 互联网 - ITeye博客
排序算法有很多,所以在特定情景中使用哪一种算法很重要. 为了选择合适的算法,可以按照建议的顺序考虑以下标准: .     对于数据量较小的情形,(1)(2)差别不大,主要考虑(3);而对于数据量大的,(1)为首要.  一、冒泡(Bubble)排序——相邻交换 .  二、选择排序——每次最小/大排在相应的位置 .

联接算法

- - CSDN博客数据库推荐文章
本文摘自《锋利的SQL》: http://item.jd.com/10380652.html. 在Microsoft SQLServer Management Studio中执行查询时,如果选定工具栏中的 按钮,可以看到为查询生成的执行计划. 执行计划以图形方式显示了SQL Server查询优化器选择的数据检索方法,如表扫描、排序、哈希匹配等.

理解EM算法

- Chin - 我爱自然语言处理
EM(Expectation-Maximization)算法在机器学习和自然语言处理应用非常广泛,典型的像是聚类算法K-means和高斯混合模型以及HMM(Hidden Markov Model). 笔者觉得讲EM算法最好的就是斯坦福大学Andrew Ng机器学习课的讲课笔记和视频. 本文总结性的给出普遍的EM算法的推导和证明,希望能够帮助接触过EM算法但对它不是很明白的人更好地理解这一算法.