LIMSVM python接口使用说明(2)

3.SVM分类步骤

import sys
import os
from subprocess import *
from svmutil import *
from grid import *

3.1 读取或创建LIBSVM格式数据

  • 创建数据
# Dense data
>>> y, x = [1,-1], [[1,0,1], [-1,0,-1]]
# Sparse data
>>> y, x = [1,-1], [{1:1, 3:1}, {1:-1,3:-1}]
>>> prob  = svm_problem(y, x)
>>> param = svm_parameter('-t 0 -c 4 -b 1')
>>> m = svm_train(prob, param)
  • 读取数据
#训练数据
>>> y, x = svm_read_problem('./svmguide1')
#测试数据
>>>  y_t, x_t = svm_read_problem('./svmguide1.t')

对于自己创建的数据,需要按LIBSVM的数据格式保存,然后自行选择寻训练、测试样本,在tools文件夹中,提供了subset.py的子样本选择工具。原版的subset工具提供了两种子样本选择模式:

  • mod 0:在所有样本中任选n个样本
  • mod 1:一共选择n个子样本,但是分配给不同类的指标正比与各类样本数的大小,从而得到一个均衡化的子样本。
    另外一种常用的样本选取方法是在各类中随机选取k个样本,为此笔者拓展了一个函数:
def random_selection_mod2(dataset, subset_size):
    labels = [line.split(None,1)[0] for line in open(dataset)]
    #预定义一个元素为list的字典
    label_linenums = defaultdict(list)
    #将样本按标签存在字典的list中
    for i, label in enumerate(labels):
        label_linenums[label] += [i]

    l = len(labels)
    ret = []

    #在每类样本中选取k个训练样本,并存储标签
    for label in label_linenums:
        linenums = label_linenums[label]
        label_size = len(linenums) 
        ret += [linenums[i] for i in random.sample(xrange(label_size), subset_size)]
    return sorted(ret)
  • 训练样本选取
filename = 'muufl'
subset_py = "./subset.py"
file = './'+filename+'_t.txt'
subfile = filename+'.sub'
cmd = '{0} -s 2 "{1}" 20 "{2}"'.format(
    subset_py, file, subfile)
Popen(cmd, shell = True, stdout = PIPE).stdout

3.2 数据特征归一化

对高维数据来说,不同维度的特征可能具有不同数量级,大量级的特征会使小量级特征失效,导致分类精度下降。LIBSVM提供了svm-scale进行数据的预处理。

  • svm-scale
Usage: svm-scale [options] data_filename
options:
-l lower : x scaling lower limit (default -1)
-u upper : x scaling upper limit (default +1)
-y y_lower y_upper : y scaling limits (default: no y scaling)
-s save_filename : save scaling parameters to save_filename
-r restore_filename : restore scaling parameters from restore_filename
  • 归一化代码
#设置svm-scale.exe的路径
svmscale_exe = "../svm-scale"
file_train = filename+'.sub'
file_test = './'+filename+'_t.txt'
#对训练样本进行归一化
cmd = '{0} -l 0 -u 1 -s "{1}.range" "{2}" > "{3}.scale"'.format(
    svmscale_exe, file_train, file_train, file_train)
Popen(cmd, shell = True, stdout = PIPE).communicate()
#对测试样本以同样的规则进行归一化
cmd = '{0} -r "{1}.range" "{2}" > "{3}.scale"'.format(
    svmscale_exe, file_train, file_test, file_test)
Popen(cmd, shell = True, stdout = PIPE).communicate()

3.3 交叉验证寻找最佳参数

tools工具中提供了grid.py进行交叉验证参素选取,适用条件是C-SVM模式并采用RBF核

  • 语法: grid.py [grid_options] [svm_options] dataset
grid_options :
-log2c {begin,end,step | "null"} : set the range of c (default -5,15,2)
    begin,end,step -- c_range = 2^{begin,...,begin+k*step,...,end}
    "null"         -- do not grid with c
-log2g {begin,end,step | "null"} : set the range of g (default 3,-15,-2)
    begin,end,step -- g_range = 2^{begin,...,begin+k*step,...,end}
    "null"         -- do not grid with g
-v n : n-fold cross validation (default 5)
-svmtrain pathname : set svm executable path and name
-gnuplot {pathname | "null"} :
    pathname -- set gnuplot executable path and name
    "null"   -- do not plot 
-out {pathname | "null"} : (default dataset.out)
    pathname -- set output file path and name
    "null"   -- do not output file
-png pathname : set graphic output file path and name (default dataset.png)
-resume [pathname] : resume the grid task using an existing output file (default pathname is dataset.out)
    Use this option only if some parameters have been checked for the SAME data.

svm_options : additional options for svm-train

The program conducts v-fold cross validation using parameter C (and gamma)
= 2^begin, 2^(begin+step), ..., 2^end.

You can specify where the libsvm executable and gnuplot are using the
-svmtrain and -gnuplot parameters.

  • 代码
#输入路径
grid_py = './grid.py'
gnuplot_exe = "/usr/bin/gnuplot"
svmtrain_exe = "../svm-train"
# 方法1
cmd = '{0} -svmtrain "{1}" -gnuplot "{2}" "{3}.scale"'.format(
    grid_py, svmtrain_exe, gnuplot_exe, file_train)
f = Popen(cmd, shell = True, stdout = PIPE).stdout
#方法2
cmd = '{0} "{1}.scale"'.format(
    grid_py, file_train)
f = Popen(cmd, shell = True, stdout = PIPE).stdout
#读取参数
line = ''
while True:
    last_line = line
    line = f.readline()
    if not line: break
c,g,rate = map(float,last_line.split())
print('Best c={0}, g={1} CV rate={2}'.format(c,g,rate))

3.4 SVM分类

#训练model
y, x = svm_read_problem(file_train+".scale")
prob = svm_problem(y,x)
model = svm_train(prob, '-c {0} -g {1}'.format(c, g))
#用model分类
y_t, x_t = svm_read_problem(file_test+".scale")
p_labs, p_acc, p_vals = svm_predict(y_t, x_t, model)
#评价
(ACC, MSE, SCC) = evaluations(y_t, p_labs)
print('ACC={0}, MSE={1}, SCC={2}'.format(ACC,MSE,SCC))
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容