基于spark2.0文本分词+多分类模型

本文介绍使用Spark2.0的ml库进行新闻文本多分类预测,涉及数据预处理(包括文本分词、标签索引化、特征向量化)、朴素贝叶斯、逻辑回归、决策树和随机森林的模型训练与超参数调优,以及模型预测和评估。预处理采用HanLP分词工具,模型评估使用MulticlassClassificationEvaluator。
摘要由CSDN通过智能技术生成

文本分类 spark

spark2.0开始引入dataframe作为RDD的上层封装,以屏蔽RDD层次的复杂操作,本文使用spark milib中ml机器学习库进行新闻文本多分类预测,包含数据预预处理,分词,标签和特征向量化转换、多分类模型训练(包含朴素贝叶斯、逻辑回归、决策树和随机森林),分类预测和模型评估等完整的机器学习demo。本文分词方法选用HanLP分词工具包(文档丰富、算法公开、代码开源,并且经测试分词效果比较好)。

1.数据预处理

1.1文本数据

本文使用的数据为4类新闻,每条数据包含标签,标题,时间和新闻内容,以"\u00EF"符号作为分割符,数据格式如下:

首页|文化新闻ï第十一届全国优秀舞蹈节目展演将在武汉举办ï2016-07-05 19:25:00ï新华社北京7月5日电(记者周玮)由文化部、湖北省人民政府主办的...
首页|财经中心|财经频道ï新通教育收购杭州蓝海旅行社100%股权 发力出境游学市场ï2016-07-04 21:49:00ï杭州7月4日电(胡丰盛)7月4日,新通教育...
首页|军事新闻ï环太军演中国参演潜水分队开展潜水事故应急医学处置演练ï2016-07-04 19:40:00ï夏威夷7月4日电 (李纯 于超)当地时间3日,参加...
首页|体育新闻ï斯坦科维奇杯首战将为王治郅举办退役仪式ï2016-07-04 10:39:00ï周二晚上八点,中国男篮将在北京以里约奥运阵容出战在国内...
复制代码

1.2预处理流程

文本清洗 -> 标签索引化 -> 内容文本分词 -> 去除停用词 -> 分词取前5000个词作为特征 -> 特征向量化 -> 保存预处理模型 -> 调用预处理模型 -> 输出预处理数据(indexedLabel,features)

1.3标签索引化

首先将文本读取成Dataframe格式,将标签列数据索引化,{文化,经济,军事和体育}向量化后为{0,1,2,3}

/**
    * 数据清洗 可根据具体数据结构和业务场景的不同进行重写. 注意: 输出必须要有标签字段"label"
    * @param filePath 数据路径
    * @param spark SparkSession
    * @return 清洗后的数据, 包含字段: "label", "title", "time", "content"
    */
  def clean(filePath: String, spark: SparkSession): DataFrame = {
    import spark.implicits._
    val textDF = spark.sparkContext.textFile(filePath).flatMap { line =>
      val fields = line.split("\u00EF")   //分隔符:ï,分成标签,标题,时间,内容
      //首页|文化新闻ï第十一届全国优秀舞蹈节目展演将在武汉举办ï2016-07-05 19:25:00ï新华社北京7月5日电(记者周玮)由文化部...
      //首页|财经中心|财经频道ï上半年浙江口岸原油进口量创同期历史新高ï2016-07-04 21:54:00ï杭州7月4日...
      if (fields.length > 3) {
        val categoryLine = fields(0)
        val categories = categoryLine.split("\\|")
        val category = categories.last
        //分成4个标签名和其他,最后去除标签为其他的数据
        var label = "其他"
        if (category.contains("文化")) label = "文化"
        else if (category.contains("财经")) label = "财经"
        else if (category.contains("军事")) label = "军事"
        else if (category.contains("体育")) label = "体育"
        else {}
        //输出标签,标题,时间,内容
        val title = fields(1)
        val time = fields(2)
        val content = fields(3)
        if (!label.equals("其他")) Some(label, title, time, content) else None
      } else None
    }.toDF("label", "title", "time", "content")
    //输出标签,标题,时间,内容DF
    textDF
  }
  /**
    * 处理label转换为索引形式
    * @param data 输入label字段的数据
    * @return 标签索引模型, 模型增加字段: "indexedLabel"
    */
  def indexrize(data: DataFrame): StringIndexerModel = {
    val labelIndexer = new StringIndexer()
      .setInputCol("label")
      .setOutputCol("indexedLabel")
      .fit(data)
    labelIndexer
  }
复制代码
predictDF.select("label","indexedLabel").show(10, truncate = false)
复制代码

1.4内容字段分词

处理内容字段,首先要进行分词,然后去除停用词以及转换为特征向量,方便分类模型进行训练和预测。本文模仿spark的ml包下的StopWordsRemover类创建了Segmenter类,用于对数据进行分词,其内部调用了HanLP分词工具。

由于spark自带的StopWordsRemover等使用的闭包仅限于ml包,自定义的类无法调用,故只是采用了与StopWordsRemover类似的使用形式,内部结构并不相同,并且由于以上原因,Segmenter类没有继承Transformer类,故无法进行pipeline管道操作,故在分类模型超参数调优过程中,没有加入分词模型的参数调优。

/**
    * 分词过程,包括"分词", "去除停用词"
    * @param data   输入需要分词的字段的数据"content"
    * @param params 分词参数
    * @return 分词处理后的DataFrame,增加字段: "tokens", "removed"
    */
  def segment(data: DataFrame, params: PreprocessParam): DataFrame = {
    val spark = data.sparkSession
    //设置分词模型
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值