Spark MLlib 的官方例子里面提供的数据大部分是 libsvm 格式的。这其实是一种非常蛋疼的文件格式,和常见的二维表格形式相去甚远,下图是里面的一个例子:

完整代码

libsvm 文件的基本格式如下:

<label> <index1>:<value1> <index2>:<value2>…

label 为类别标识,index 为特征序号,value 为特征取值。如上图中第一行中 0 为标签,128:51 表示第 128 个特征取值为 51 。

Spark 固然提供了读取 libsvm 文件的API,然而如果想把这些数据放到别的库 (比如scikit-learn) 中使用,就不得不面临一个格式转换的问题了。由于 CSV 文件是广大人民群众喜闻乐见的文件格式,因此分别用 Python 和Java 写一个程序来进行转换。我在网上查阅了一下,基本上全是 csv 转 libsvm,很少有 libsvm 转 csv 的,唯一的一个是 phraug库中的libsvm2csv.py 。但这个实现有两个缺点: 一个是需要事先指定维度; 另一个是像上图中的特征序号是 128 - 658 ,这样转换完之后 0 - 127 维的特征全为 0,就显得多余了,而比较好的做法是将全为 0 的特征列一并去除。下面是基于 Python 的实现:

import sys
import csv
import numpy as np def empty_table(input_file): # 建立空表格, 维数为原数据集中最大特征维数
max_feature = 0
count = 0
with open(input_file, 'r', newline='') as f:
reader = csv.reader(f, delimiter=" ")
for line in reader:
count += 1
for i in line:
num = int(i.split(":")[0])
if num > max_feature:
max_feature = num return np.zeros((count, max_feature + 1)) def write(input_file, output_file, table):
with open(input_file, 'r', newline='') as f:
reader = csv.reader(f, delimiter=" ")
for c, line in enumerate(reader):
label = line.pop(0)
table[c, 0] = label
if line[-1].strip() == '':
line.pop(-1) line = map(lambda x : tuple(x.split(":")), line)
for i, v in line:
i = int(i)
table[c, i] = v delete_col = []
for col in range(table.shape[1]):
if not any(table[:, col]):
delete_col.append(col) table = np.delete(table, delete_col, axis=1) # 删除全 0 列
with open(output_file, 'w') as f:
writer = csv.writer(f)
for line in table:
writer.writerow(line) if __name__ == "__main__":
input_file = sys.argv[1]
output_file = sys.argv[2]
table = empty_table(input_file)
write(input_file, output_file, table)

以下基于 Java 来实现,不得不说 Java 由于没有 Numpy 这类库的存在,写起来要繁琐得多。

import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; public class LibsvmToCsv {
public static void main(String[] args) throws IOException { String src = args[0];
String dest = args[1]; double[][] table = EmptyTable(src);
double[][] newcsv = NewCsv(table, src);
write(newcsv, dest);
} // 建立空表格, 维数为原数据集中最大特征维数
public static double[][] EmptyTable(String src) throws IOException {
int maxFeatures = 0, count = 0;
File f = new File(src);
BufferedReader br = new BufferedReader(new FileReader(f));
String temp = null;
while ((temp = br.readLine()) != null){
count++;
for (String pair : temp.split(" ")){
int num = Integer.parseInt(pair.split(":")[0]);
if (num > maxFeatures){
maxFeatures = num;
}
}
}
double[][] emptyTable = new double[count][maxFeatures + 1];
return emptyTable;
} public static double[][] NewCsv(double[][] newTable, String src) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(src)));
String temp = null;
int count = 0;
while ((temp = br.readLine()) != null){
String[] array = temp.split(" ");
double label = Integer.parseInt(array[0]);
for (String pair : Arrays.copyOfRange(array, 1, array.length)){
String[] pairs = pair.split(":");
int index = Integer.parseInt(pairs[0]);
double value = Double.parseDouble(pairs[1]);
newTable[count][index] = value;
}
newTable[count][0] = label;
count++;
} List<Integer> deleteCol = new ArrayList<>(); // 要删除的全 0 列
int deleteColNum = 0; coll:
for (int col = 0; col < newTable[0].length; col++){
int zeroCount = 0;
for (int row = 0; row < newTable.length; row++){
if (newTable[row][col] != 0.0){
continue coll; // 若有一个值不为 0, 继续判断下一列
} else {
zeroCount++;
}
} if (zeroCount == newTable.length){
deleteCol.add(col);
deleteColNum++;
}
} int newColNum = newTable[0].length - deleteColNum;
double[][] newCsv = new double[count][newColNum]; // 新的不带全 0 列的空表格
int newCol = 0; colll:
for (int col = 0; col < newTable[0].length; col++){
for (int dCol : deleteCol){
if (col == dCol){
continue colll;
}
} for (int row = 0; row < newTable.length; row++){
newCsv[row][newCol] = newTable[row][col];
}
newCol++;
}
return newCsv;
} public static void write(double[][] table, String path) throws FileNotFoundException {
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(path)));
try{
for (double[] row : table){
int countComma = 0;
for (double c : row){
countComma ++;
bw.write(String.valueOf(c));
if (countComma <= row.length - 1){
bw.append(',');
}
}
bw.flush();
bw.newLine();
}
} catch (IOException e){
e.printStackTrace();
} finally {
try{
if (bw != null){
bw.close();
}
} catch (IOException e){
e.printStackTrace();
}
}
}
}

/

LibSVM文件转换为csv格式的更多相关文章

  1. 如何将EDI报文转换为CSV格式文件?

    如果您对EDI项目实施有一定的了解,想必您一定知道,在正式开始EDI项目实施之前,都会有EDI顾问与您接洽,沟通EDI项目需求.其中,会包含EDI通信双方使用哪种传输协议,传输的报文是符合什么标准的, ...

  2. C# 将PDF文件转换为word格式

    Pdf(Portable Document Format)意为“便携式文档格式”,是现在最流行的文件格式之一,它有很多优点如:尺寸较小.阅读方便.操作系统平台通用等,非常适合在网络上传播和使用.如今在 ...

  3. java 调用OpenOffice将word格式文件转换为pdf格式

    一:环境搭建 OpenOffice 下载地址http://www.openoffice.org/ JodConverter 下载地址http://sourceforge.net/projects/jo ...

  4. 将 Graphviz .dot 文件转换为其他格式的图像

    参考: Graphviz: How to go from .dot to a graph? 将 Graphviz .dot 文件转换为其他格式的图像 在Linux系统下,使用以下命令: dot -Tp ...

  5. PHP 将amr音频文件转换为mp3格式

    说下整体思路 1.服务器安装ffmpeg 2.使用ffmpeg -i 指令来转换amr为mp3格式(这个到时候写在PHP代码中,使用exec函数执行即可) 3.在网页端使用HTML5的audio标签来 ...

  6. excel批量转换为CSV格式,xls批量导出csv格式

    工具/原料   excel 2013 地址链接:http://pan.baidu.com/s/1c1ZABlu 密码:d3rc 方法/步骤     首选我们把需要导出为CVS的Excel文件整理集中到 ...

  7. 将dos格式文件转换为unix格式

    在windows下换行符是\r\n,表示回到行首并换到下一行 而unix系统中换行符是\n 这样就存在一个问题,在windows上的文档到了unix上可能就无法使用了 针对这个情况有几种解决办法: 1 ...

  8. 如何使用python把json文件转换为csv文件

    @ 目录 了解json整体格式 转换格式 提取key和value 使用pandas写入csv 了解json整体格式 这里有一段json格式的文件,存着全球陆地和海洋的每年异常气温(这里只选了一部分): ...

  9. 将excel2003文档文件转换为excel2007格式

    在sharepoint 2010 中,excel2007或excel 2010文档格式,支持web app 应用,能够在浏览器在线打开,查看,但excel 2003格式的文档只能用office客户端打 ...

随机推荐

  1. 51NOD 1117 聪明的木匠

    来源:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1117 挑战原题吧  大概 每次挑选最小的两个,合起来 #inclu ...

  2. C# String.Join 与 StringBuilder 对比,谁更快

    String.Join 文档      StringBuilder 文档 这两天刷 Leedcode 做到一道 String 的题时突然想到这俩对比的问题,于是查了一下资料并简单对比了一下. 首先对于 ...

  3. UVa 116 单向TSP(多段图最短路)

    https://cn.vjudge.net/problem/UVA-116 题意:给出m行n列的整数矩阵,从第一列任何一个位置出发每次往右,右上或右下走一格,最终到达最后一列,要求经过的整数之和最小. ...

  4. Python3 学习

    没有大括号,使用TAB缩进实现大括号的功能,if else等语句后面也没有小括号,注意和其他高级语言区别句尾没有分号,但if else后面有没有字符概念,用单引号包起来的也是字符串,也就是说单双引号都 ...

  5. c++ primer plus 第四章 课后题答案

    #include<iostream> #include<string> using namespace std; int main() { string first_name; ...

  6. js audio 播放音乐

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  7. Codeforces 525A - Vitaliy and Pie

    525A - Vitaliy and Pie 思路:贪心+hashing. 代码: #include<bits/stdc++.h> using namespace std; string ...

  8. apktool 打包解包apk的总结

    1) 不需要另外下载 baksmali-2.1.2.jar, apktool.jar 好像都包含了. apktool d zhanqi.xxx.apk -o zhanqi 2) smalidea-0. ...

  9. docker on mac:误删default vm的处理方法

    通过docker-machine 重新建一个vm,在virtualbox里可以直接看到多出来一个vm docker-machine create --driver virtualbox default

  10. hdu6405Make ZYB Happy 广义sam

    题意:给出n(n<=10000)个字符串S[1~n],每个S[i]有权值val[i],随机等概率造一个由小写字母构成的字符串T,Sum = 所有含有子串T的S[i]的val[i]之积,求Sum的 ...