Svm实现多分类
機器學習---Svm實現多分類詳解
- Svm實現多類分類原理
- 代碼實現
- 訓練的圖片
Svm實現多類分類原理
1.支持向量機分類算法最初只用于解決二分類問題,缺乏處理多分類問題的能力。后來隨著需求的變化,需要svm處理多分類分為。目前構造多分類支持向
量機分類器的方法主要有兩類: 一類是“同時考慮所有分類”方法,另一類是組合二分類器解訣多分類問題。
第一類方法主要思想是在優化公式的同時考慮所有的類別數據,J.Weston 和C.Watkins 提出的“K-Class 多分類算法”就屬于這一類方法。該算法在經典的SVM理論的基礎上,重新構造多類分類型,同時考慮多個類別,然后將問題也轉化為-個解決二次規劃(Quadratic Programming,簡稱QP)問題,從而實現多分類。該算法由于涉及到的變量繁多,選取的目標函數復雜,實現起來比較困難,計算復雜度高。
第二類方法的基本思想是通過組合多個二分類器實現對多分類器的構造,常見的構造方法有“一對一”(one-against-one)和“一對其余”(one-against-the rest兩種。 其中“一對一”方法需要對n類訓練數據兩兩組合,構建n(n- 1)/2個支持向量機,每個支持向量機訓練兩種不同類別的數據,最后分類的時候采取“投票”的方式決定分類結果。“一對其余”方法對n分類問題構建n個支持向量機,每個支持向量機負責區分本類數據和非本類數據。該分類器為每個類構造一個支持向量機, 第k個支持向量機在第k類和其余n-1個類之間構造一個超平面,最后結果由輸出離分界面距離wx+ b最大的那個支持向量機決定。
本文將上述“一對其余”的SVM多分類方法對鶯尾花數據進行分類識別,并設法減少訓練樣本個數,提高訓練速度。
代碼實現
#-*- coding:utf-8 -*- ''' @project: exuding-bert-all @author: exuding @time: 2019-04-23 09:59:52 ''' #svm 高斯核函數實現多分類 import matplotlib.pyplot as plt import numpy as np import tensorflow as tf from sklearn import datasetssess = tf.Session()#加載數據集,并為每類分離目標值 iris = datasets.load_iris() #提取數據的方法 x_vals = np.array([[x[0],x[3]] for x in iris.data])y_vals1 = np.array([1 if y==0 else -1 for y in iris.target]) y_vals2 = np.array([1 if y==1 else -1 for y in iris.target]) y_vals3 = np.array([1 if y==2 else -1 for y in iris.target]) #合并數據的方法 y_vals = np.array([y_vals1,y_vals2,y_vals3]) #數據集四個特征,只是用兩個特征就可以 class1_x = [x[0] for i,x in enumerate(x_vals) if iris.target[i]==0] class1_y = [x[1] for i,x in enumerate(x_vals) if iris.target[i]==0] class2_x = [x[0] for i,x in enumerate(x_vals) if iris.target[i]==1] class2_y = [x[1] for i,x in enumerate(x_vals) if iris.target[i]==1] class3_x = [x[0] for i,x in enumerate(x_vals) if iris.target[i]==2] class3_y = [x[1] for i,x in enumerate(x_vals) if iris.target[i]==2] #從單類目標分類到三類目標分類,利用矩陣傳播和reshape技術一次性計算所有的三類SVM,一次性計算,y_target的占位符維度是[3,None] batch_size = 50 x_data = tf.placeholder(shape = [None,2],dtype=tf.float32) y_target = tf.placeholder(shape=[3,None],dtype=tf.float32) #TODO prediction_grid = tf.placeholder(shape=[None,2],dtype=tf.float32) b = tf.Variable(tf.random_normal(shape=[3,batch_size])) #計算高斯核函數 TODO gamma = tf.constant(-10.0) dist = tf.reduce_sum(tf.square(x_data),1) dist = tf.reshape(dist,[-1,1]) sq_dists = tf.add(tf.subtract(dist,tf.multiply(2.,tf.matmul(x_data,tf.transpose(x_data)))),tf.transpose(dist)) my_kernel = tf.exp(tf.multiply(gamma,tf.abs(sq_dists))) #擴展矩陣維度 def reshape_matmul(mat):v1 = tf.expand_dims(mat,1)v2 = tf.reshape(v1,[3,batch_size,1])return (tf.matmul(v2,v1)) #計算對偶損失函數 model_output = tf.matmul(b,my_kernel) first_term = tf.reduce_sum(b) b_vec_cross = tf.matmul(tf.transpose(b),b) y_target_cross = reshape_matmul(y_target) second_term = tf.reduce_sum(tf.multiply(my_kernel,tf.multiply(b_vec_cross,y_target_cross)),[1,2]) loss = tf.reduce_sum(tf.negative(tf.subtract(first_term,second_term))) #創建預測核函數 rA = tf.reshape(tf.reduce_sum(tf.square(x_data),1),[-1,1]) rB = tf.reshape(tf.reduce_sum(tf.square(prediction_grid),1),[-1,1]) pred_sq_dist = tf.add(tf.subtract(rA,tf.multiply(2.,tf.matmul(x_data,tf.transpose(prediction_grid)))),tf.transpose(rB)) pred_kernel = tf.exp(tf.multiply(gamma,tf.abs(pred_sq_dist))) #創建預測函數,這里實現的是一對多的方法,所以預測值是分類器有最大返回值的類別 prediction_output = tf.matmul(tf.multiply(y_target,b),pred_kernel) prediction = tf.arg_max(prediction_output-tf.expand_dims(tf.reduce_mean(prediction_output,1),1),0) accuracy = tf.reduce_mean(tf.cast(tf.equal(prediction,tf.arg_max(y_target,0)),tf.float32)) #準備好核函數,損失函數,預測函數以后,聲明優化器函數和初始化變量 my_opt = tf.train.GradientDescentOptimizer(0.01) train_step = my_opt.minimize(loss) init = tf.initialize_all_variables() sess.run(init) #該算法收斂的相當快,所以迭代訓練次數不超過100次 loss_vec = [] batch_accuracy = [] for i in range(100):rand_index = np.random.choice(len(x_vals),size=batch_size)rand_x = x_vals[rand_index]rand_y = y_vals[:,rand_index]sess.run(train_step,feed_dict={x_data:rand_x,y_target:rand_y})temp_loss = sess.run(loss,feed_dict={x_data:rand_x,y_target:rand_y})loss_vec.append(temp_loss)acc_temp = sess.run(accuracy,feed_dict={x_data:rand_x,y_target:rand_y,prediction_grid:rand_x})batch_accuracy.append(acc_temp)if(i+1)%25 ==0:print('Step #' + str(i+1))print('Loss #' + str(temp_loss))x_min,x_max = x_vals[:,0].min()-1,x_vals[:,0].max()+1 y_min,y_max = x_vals[:,1].min()-1,x_vals[:,1].max()+1 xx,yy = np.meshgrid(np.arange(x_min,x_max,0.02),np.arange(y_min,y_max,0.02)) grid_points = np.c_[xx.ravel(),yy.ravel()] grid_predictions = sess.run(prediction,feed_dict={x_data:rand_x,y_target:rand_y,prediction_grid:grid_points}) grid_predictions = grid_predictions.reshape(xx.shape) #繪制訓練結果,批量準確度和損失函數 #等高線圖 plt.contourf(xx,yy,grid_predictions,cmap=plt.cm.Paired,alpha=0.8) plt.plot(class1_x,class1_y,'ro',label = 'I.setosa') plt.plot(class2_x,class2_y,'kx',label = 'I.versicolor') plt.plot(class3_x,class3_y,'gv',label = 'T.virginica') plt.title('Gaussian Svm Results on Iris Data') plt.xlabel('Pedal Length') plt.ylabel('Sepal Width') plt.legend(loc='lower right') plt.ylim([-0.5,3.0]) plt.xlim([3.5,8.5]) plt.show()plt.plot(batch_accuracy,'k-',label='Accuracy') plt.title('Batch Accuracy') plt.xlabel('Generation') plt.ylabel('Sepal Width') plt.legend(loc = 'lower right') plt.show()plt.plot(loss_vec,'k--') plt.title('Loss per Generation') plt.xlabel('Generation') plt.ylabel('Loss') plt.show()訓練的圖片
總結
- 上一篇: gaussian09使用教程linux,
- 下一篇: java 线程工厂_Java并发编程:J