[引言]
SVM是支持向量机(Support Vector Machine)的简称。
SVM具有分类功能(SVC,C是Classification(分类)的首字母);
也具有回归功能(SVR,R是Regression(回归)的首字母)。
[问题分析]
在[Python数据挖掘] sklearn-KMeans聚类一文中,实现了对以下数据集的聚类:
YZN,133,108,76
ZHY,96,145,101
WYZ,132,107,60
DHY,100,102,120
CYH,139,99,93
LHY,73,149,81
ZHY,85,148,93
TQP,39,138,85
ZZL,145,112,71
HJC,101,116,118
XZY,99,98,117
每行第一列是学生姓名,第二列是语文成绩,第三列是数学成绩,第四列是英语成绩。
sklearn-KMeans已成功将该数据集聚为3类:
英语较好的DHY, HJC, XZY聚在一起;
语文较好的YZN, WYZ, CYH, ZZL聚在一起;
数学较好的ZHY, LHY, ZHY, TQP聚在一起。
称以上数据集为train.txt,作为训练集。
设定以下数据集为test.txt,作为测试集。
ZYF,101,142,90
WHQ,140,105,93
LZJ,103,112,115
BHJ,99,140,91
FZY,98,111,118
CWH,144,113,77
使用train.txt的聚类结果对SVC分类器进行训练,然后使用训练好的SVC分类器对test.txt进行分类预测,观察SVC的分类效果如何。
改写[Python数据挖掘] sklearn-KMeans聚类中的代码,首先给出训练集聚类过程:
from sklearn.cluster import KMeans
def loadData(filePath):
fr = open(filePath, 'r+')
lines = fr.readlines()
retName = []
retData = []
for line in lines:
items = line.strip().split(',')
retName.append(items[0])
retData.append([float(items[i]) for i in range(1,len(items))])
return retName, retData
if __name__ == '__main__':
train_Name, train_Data = loadData('train.txt')
test_Name, test_Data = loadData('test.txt')
clusters_cnt = 3
km = KMeans(n_clusters=clusters_cnt)
train_label = km.fit_predict(train_Data)
train_outputName = []
for i in range(clusters_cnt):
train_outputName.append([])
for i in range(len(train_Name)):
train_outputName[train_label[i]].append(train_Name[i])
print('聚类结果:')
print(train_outputName)
下面使用SVC分类器对test.txt分类预测:
导入sklearn.svm,在代码开头增加一行:
from sklearn import svm
回到主函数结尾处,继续增写代码:
读取测试集:
test_Name, testData = loadData('test.txt')
使用svm.SVC()生成并设置clf分类器
(其中kernel是核函数参数,'rbf'为高斯核函数,又称径向基函数;
kernel的取值可以是'rbf'(高斯核函数),'linear'(线性核函数),'poly'(多项式核函数),'sigmoid'(S型核函数),等等
对于'rbf', 'poly', 'sigmoid'等,还需为这些核函数显式指定gamma参数;
gamma参数的取值可以是'auto','scale'等等):
clf = svm.SVC(clf = svm.SVC(kernel='rbf', gamma = 'scale'))
使用训练集训练clf分类器,分类器clf的训练函数fit(),传参有两个,第一个是训练集数据,第二个是训练集标签:
clf.fit(train_Data, train_label)
使用clf分类器的predict()函数对测试集进行分类预测:
test_label = clf.predict(test_Data)
编制分类结果:
test_outputName = []
for i in range(max(test_label)+1):
test_outputName.append([])
for i in range(len(test_Name)):
test_outputName[test_label[i]].append(test_Name[i])
print('分类结果:')
print(test_outputName)
输出聚类结果和分类结果的比较情况:
print('比较:')
for i in range(max(test_label)+1):
print(test_outputName[i], '与', train_outputName[i], '同类')
输出如下:
聚类结果:
[['DHY', 'HJC', 'XZY'], ['ZHY', 'LHY', 'ZHY', 'TQP'], ['YZN', 'WYZ', 'CYH', 'ZZL']]
分类结果:
[['LZJ', 'FZY'], ['ZYF', 'BHJ'], ['WHQ', 'CWH']]
比较:
['LZJ', 'FZY'] 与 ['DHY', 'HJC', 'XZY'] 同类
['ZYF', 'BHJ'] 与 ['ZHY', 'LHY', 'ZHY', 'TQP'] 同类
['WHQ', 'CWH'] 与 ['YZN', 'WYZ', 'CYH', 'ZZL'] 同类
可以看到,SVR能够正确分类出语文较好的LZJ, FZY;数学较好的ZYF, BHJ;英语较好的WHQ, CWH。
这与KMeans的聚类结果:
语文较好的YZN, WYZ, CYH, ZZL;数学较好的ZHY, LHY, ZHY, TQP;英语较好的DHY, HJC, XZY;
分类和聚类的类别特征是一致的。
最后附上完整代码如下:
from sklearn.cluster import KMeans
from sklearn import svm
def loadData(filePath):
fr = open(filePath, 'r+')
lines = fr.readlines()
retName = []
retData = []
for line in lines:
items = line.strip().split(',')
retName.append(items[0])
retData.append([float(items[i]) for i in range(1,len(items))])
return retName, retData
if __name__ == '__main__':
train_Name, train_Data = loadData('train.txt')
test_Name, test_Data = loadData('test.txt')
clusters_cnt = 3
km = KMeans(n_clusters=clusters_cnt)
train_label = km.fit_predict(train_Data)
train_outputName = []
for i in range(clusters_cnt):
train_outputName.append([])
for i in range(len(train_Name)):
train_outputName[train_label[i]].append(train_Name[i])
print('聚类结果:')
print(train_outputName)
test_Name, testData = loadData('test.txt')
clf = svm.SVC(kernel='rbf', gamma = 'scale')
clf.fit(train_Data, train_label)
test_label = clf.predict(test_Data)
test_outputName = []
for i in range(max(test_label)+1):
test_outputName.append([])
for i in range(len(test_Name)):
test_outputName[test_label[i]].append(test_Name[i])
print('分类结果:')
print(test_outputName)
print('比较:')
for i in range(max(test_label)+1):
print(test_outputName[i], '与', train_outputName[i], '同类')