實驗要求
數據說明 :數據集data4train.mat是一個2*150的矩陣,代表了150個樣本,每個樣本具有兩維特征,其類標在truelabel.mat文件中,trainning sample 圖展示了理想的分類類結果;
方案選擇:
選擇並實現一種兩分類方法(如感知機方法,SVM等);在此基礎上設計使用該二分類器實現三分類問題的策略,並程序實現,畫出分類結果
直接采用現成的可實現多分類的方法(如多類SVM,BP網絡等)進行問題求解。畫出分類結果。我選擇第二種,時間不夠,只能使用sklearn中的svc實現
實現思想
一對一:
其做法是在任意兩類樣本之間設計一個SVM,因此k個類別的樣本就需要設計k(k-1)/2個SVM。當對一個未知樣本進行分類時,最后得票最多的類別即為該未知樣本的類別。
優點:不需要重新訓練所有的SVM,只需要重新訓練和增加語音樣本相關的分類器。在訓練單個模型時,速度較快。
缺點:所需構造和測試的二值分類器的數量關於k成二次函數增長,總訓練時間和測試時間相對較慢。
一對多
訓練時依次把某個類別的樣本歸為一類,其他剩余的樣本歸為另一類,這樣k個類別的樣本就構造出了k個SVM。分類時將未知樣本分類為具有最大分類函數值的那類。
**優點:**訓練k個分類器,個數較少,其分類速度相對較快。
缺點:
①每個分類器的訓練都是將全部的樣本作為訓練樣本,這樣在求解二次規划問題時,訓練速度會隨着訓練樣本的數量的增加而急劇減慢;
②同時由於負類樣本的數據要遠遠大於正類樣本的數據,從而出現了樣本不對稱的情況,且這種情況隨着訓練數據的增加而趨向嚴重。解決不對稱的問題可以引入不同的懲罰因子,對樣本點來說較少的正類采用較大的懲罰因子C;
③還有就是當有新的類別加進來時,需要對所有的模型進行重新訓練
層次樹:
首先將所有類別分為兩個類別,再將子類進一步划分為兩個次級子類,如此循環下去,直到所有的節點都只包含一個單獨的類別為止,此節點也是二叉樹樹種的葉子。該分類將原有的分類問題同樣分解成了一系列的兩類分類問題,其中兩個子類間的分類函數采用SVM。
我這里選擇一對多,因為只有三類
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2019/7/2 23:25
# @Author : 朱紅喜
# @File : Multi-classify.py
# @Software: PyCharm
# 引入必要的庫
import numpy as np
import matplotlib.pyplot as plt
from sklearn import svm
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import label_binarize
from sklearn.multiclass import OneVsRestClassifier
from FileUtil import FileUtil
# 加載數據
# 1.訓練模型的數據
X = FileUtil.open_matfile("data4train.mat").T # 數據集
y = FileUtil.open_matfile("truelabel.mat") # 真實標簽
print(X)
print(y[0])
print(y.shape)
# 2.測試模型的數據
X_2 = FileUtil.open_matfile("data4test.mat").T
y_2 = FileUtil.open_matfile("testtruelabel.mat")
print(X_2)
print(y_2[0])
print(y_2.shape)
# 標簽二值化
y = label_binarize(y[0], classes=[1, 2, 3])
# print(y)
# 划分訓練集和測試集
# 設置種類
n_classes = y.shape[1]
# print(y.shape[1])
# 訓練模型並預測
random_state = np.random.RandomState(0)
n_samples, n_features = X.shape
# 隨機化數據,並划分訓練數據和測試數據
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=.5, random_state=0)
# 訓練模型
# Learn to predict each class against the other
model = OneVsRestClassifier(svm.SVC(kernel='linear', probability=True, random_state=random_state))
clt = model.fit(X_train, y_train)
# 性能評估
# 1.在訓練集上的得分
clt.score(X_train, y_train)
print(clt.score(X_train, y_train))
# 2.在測試集上的評分
clt.score(X_test, y_test)
print(clt.score(X_test, y_test))
# 查看各類別的預測情況
y_predict_scores = clt.decision_function(X_test)
print(y_predict_scores[:149])
# 轉化為原始標簽模式
result = np.argmax(clt.decision_function(X_test), axis=1)[:149]
# print(result)
# 轉化為老師需要的 1,2,3類標
for i in range(result.__len__()):
result[i] = result[i]+1
print(result)
print("++++++++++++++++++++++data4train數據集++++++++++++++++++")
result_2 = np.argmax(clt.decision_function(X), axis=1)[:149]
# print(result_2)
# 轉化為老師需要的 1,2,3類標
for i in range(result_2.__len__()):
result_2[i] = result_2[i]+1
print(result_2)
print("++++++++++++++++++++++data4test測試集++++++++++++++++++")
result_2 = np.argmax(clt.decision_function(X_2), axis=1)[:59]
# print(result_2)
# 轉化為老師需要的 1,2,3類標
for i in range(result_2.__len__()):
result_2[i] = result_2[i]+1
print(result_2)
分類結果