svm本身只适用于二分类问题,但是通过sklearn也可以做多分类问题。在确定超参数的过程中,通常使用网格搜索。

多类别分类问题,有两种构建分类器的策略:One-vs-All及One-vs-One。

多类别分类策略

One-Vs-The-Rest策略

这个策略同时也称为One-vs-all策略,即通过构造K个判别式(K为类别的个数),第i个判别式将样本归为第i个类别或非第i个类别。这种分类方法虽然比较耗时间,但是能够通过每个类别对应的判别式获得关于该类别的直观理解(如文本分类中每个话题可以通过只属于该类别的高频特征词区分)。

One-Vs-One策略

One-Vs-One策略即是两两类别之间建立一个判别式,这样,总共需要K(K−1)/2个判别式,最后通过投票的方式确定样本所属类别。

网格搜索

主要使用GridSearchCV。

Demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#coding:utf-8

from sklearn.metrics import classification_report
from sklearn import preprocessing
from sklearn.cross_validation import train_test_split
from sklearn.model_selection import GridSearchCV
from sklearn.multiclass import OneVsOneClassifier
from sklearn.multiclass import OneVsRestClassifier
import pandas as pd

data_path='./winequality-red.csv'

data=pd.read_csv(data_path,delimiter=';')

# 属性有11个
data_src=data.iloc[:,:11]
data_tar=data.iloc[:,11:]

X_train, X_test, Y_train, Y_test=train_test_split(data_src,data_tar,test_size=0.20,random_state=33)
ss = StandardScaler()

X_train = ss.fit_transform(X_train)
X_test = ss.transform(X_test)

# 网格搜索
grid = GridSearchCV(SVC(), param_grid={"C":[0.1,0.5,1,5,10], "gamma": [1,0,5,0.1,0.05, 0.01]}, cv=4)
grid.fit(X, y)
print("The best parameters are %s with a score of %0.2f"
% (grid.best_params_, grid.best_score_))

# rbf需要双引号

csvm = svm.SVC(C=0.5, kernel="rbf", degree=3, gamma=1, coef0=0.0, shrinking=True, probability=False, tol=0.001, cache_size=200)

# 多类别分类

#Y_predict=OneVsRestClassifier(csvm).fit(X_train,Y_train).predict(X_test)
Y_predict=OneVsOneClassifier(csvm).fit(X_train,Y_train).predict(X_test)

print classification_report(Y_test, Y_predict)

reference