如何解决libsvm格式数据中索引不是按升序排序(scala)

本文介绍了一种使用Scala编程解决Spark MLlib中libsvm格式数据索引未按升序排列的问题的方法。通过自定义排序函数,确保数据格式正确无误,以便于后续的数据处理与机器学习任务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述
在使用spark MLlib的时候,经常会使用MLUtils.loadLibSVMFile去加载libsvm格式的数据,如果你的libsvm数据格式不符合要求,比如,数据中索引不是按照升序排序:
这里写图片描述
这样的数据在运行程序的时候就会报错:
indices should be one-based and in ascending order

这个时候就需要你自己去排序,数据这么多,不可能手动去排序,可以利用scala去编写排序程序对数据进行排序,使其符合libsvm格式要求。

代码如下:

package others

import java.io.{File, PrintWriter}

import org.apache.spark.mllib.util.MLUtils
import org.apache.spark.{SparkContext, SparkConf}

/**
 * Created by Administrator on 2017/4/27.
 */
object Sort {

  def main(args: Array[String]) {

    if(args.length<1){
      System.err.println("Usage:<file>")
      System.exit(1)
    }

    val input_File=args(0)
    val output_file=args(1)

    val conf=new SparkConf().setAppName("Sort")//设置本程序名称
    //这里,我是通过maven构建的spark开发环境,然后打包到集群,通过spark-submit提交到yarn去执行的。
   //如何通过idea的maven去构建spark,参考另一篇博客:http://blog.youkuaiyun.com/u013963380/article/details/71713582
   //如何一步一步地在Intellij IDEA使用Maven搭建Spark开发环境,并基于Scala编写简单的spark中wordcount实例。
    val sc=new SparkContext(conf)

   //读取数据
    val data = sc.textFile(input_File)
  //通过排序方法重新map数据
    val data_ok=data.map(line => trans(line))
   //保存数据到指定文件
    data_ok.repartition(1).saveAsTextFile(output_file)

  }

   def trans(line: String): String = {
    //以第一条为例
    //ne: String = 0 2:1 1:4 6:4 7:37 8:37 9:0 10:10 11:0 12:0 ...
    //以空格分割
    val cols = line.split(" ")
    //把标签和特征分开
    val label = cols(0);
    val features = cols.slice(1, cols.length);
    //对特征进行map,将下标和值分开,并用下标进行排序
    //newFeatures: Array[(Double, Double)] = Array((1.0,4.0), (2.0,1.0), (6.0,4.0), (7.0,37.0), (8.0,37.0)....
    val newFeatures = features.map(l => {
      val k = l.split("\\:");
      //转为double,用于排序
      (k(0).toDouble, k(1).toDouble)
    }).sortBy(_._1)
    //重组字符串,,加上标签,并用空格分隔
    //result: String = 0 1:4.0 2:1.0 6:4.0 7:37.0 8:37.0 9:0.0 10:10.0....
    val result = label + " " + newFeatures.map(l => (l._1.toInt + ":" + l._2)).mkString(" ")
    return result;

  }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值