python非线性可分支持向量机模型(实现iris分类)
生活随笔
收集整理的這篇文章主要介紹了
python非线性可分支持向量机模型(实现iris分类)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
內容:
非線性可分支持向量機模型
????????分別使用線性核﹑多項式核與高斯核對lris 數據集的2/3數據訓練支持向量機,剩余1/3數據進行測試,計算正確率。 分別使用線性核、多項式核與高斯核對lris數據集的2/3數據訓練支持向量機,剩余1/3數據進行測試,計算正確率。
數據集(150)
具體數據如下(如果不能運行,嘗試在末尾加回車)
5.1 3.5 1.4 0.2 1 4.9 3 1.4 0.2 1 4.7 3.2 1.3 0.2 1 4.6 3.1 1.5 0.2 1 5 3.6 1.4 0.2 1 5.4 3.9 1.7 0.4 1 4.6 3.4 1.4 0.3 1 5 3.4 1.5 0.2 1 4.4 2.9 1.4 0.2 1 4.9 3.1 1.5 0.1 1 5.4 3.7 1.5 0.2 1 4.8 3.4 1.6 0.2 1 4.8 3 1.4 0.1 1 4.3 3 1.1 0.1 1 5.8 4 1.2 0.2 1 5.7 4.4 1.5 0.4 1 5.4 3.9 1.3 0.4 1 5.1 3.5 1.4 0.3 1 5.7 3.8 1.7 0.3 1 5.1 3.8 1.5 0.3 1 5.4 3.4 1.7 0.2 1 5.1 3.7 1.5 0.4 1 4.6 3.6 1 0.2 1 5.1 3.3 1.7 0.5 1 4.8 3.4 1.9 0.2 1 5 3 1.6 0.2 1 5 3.4 1.6 0.4 1 5.2 3.5 1.5 0.2 1 5.2 3.4 1.4 0.2 1 4.7 3.2 1.6 0.2 1 4.8 3.1 1.6 0.2 1 5.4 3.4 1.5 0.4 1 5.2 4.1 1.5 0.1 1 5.5 4.2 1.4 0.2 1 4.9 3.1 1.5 0.1 1 5 3.2 1.2 0.2 1 5.5 3.5 1.3 0.2 1 4.9 3.1 1.5 0.1 1 4.4 3 1.3 0.2 1 5.1 3.4 1.5 0.2 1 5 3.5 1.3 0.3 1 4.5 2.3 1.3 0.3 1 4.4 3.2 1.3 0.2 1 5 3.5 1.6 0.6 1 5.1 3.8 1.9 0.4 1 4.8 3 1.4 0.3 1 5.1 3.8 1.6 0.2 1 4.6 3.2 1.4 0.2 1 5.3 3.7 1.5 0.2 1 5 3.3 1.4 0.2 1 7 3.2 4.7 1.4 2 6.4 3.2 4.5 1.5 2 6.9 3.1 4.9 1.5 2 5.5 2.3 4 1.3 2 6.5 2.8 4.6 1.5 2 5.7 2.8 4.5 1.3 2 6.3 3.3 4.7 1.6 2 4.9 2.4 3.3 1 2 6.6 2.9 4.6 1.3 2 5.2 2.7 3.9 1.4 2 5 2 3.5 1 2 5.9 3 4.2 1.5 2 6 2.2 4 1 2 6.1 2.9 4.7 1.4 2 5.6 2.9 3.6 1.3 2 6.7 3.1 4.4 1.4 2 5.6 3 4.5 1.5 2 5.8 2.7 4.1 1 2 6.2 2.2 4.5 1.5 2 5.6 2.5 3.9 1.1 2 5.9 3.2 4.8 1.8 2 6.1 2.8 4 1.3 2 6.3 2.5 4.9 1.5 2 6.1 2.8 4.7 1.2 2 6.4 2.9 4.3 1.3 2 6.6 3 4.4 1.4 2 6.8 2.8 4.8 1.4 2 6.7 3 5 1.7 2 6 2.9 4.5 1.5 2 5.7 2.6 3.5 1 2 5.5 2.4 3.8 1.1 2 5.5 2.4 3.7 1 2 5.8 2.7 3.9 1.2 2 6 2.7 5.1 1.6 2 5.4 3 4.5 1.5 2 6 3.4 4.5 1.6 2 6.7 3.1 4.7 1.5 2 6.3 2.3 4.4 1.3 2 5.6 3 4.1 1.3 2 5.5 2.5 4 1.3 2 5.5 2.6 4.4 1.2 2 6.1 3 4.6 1.4 2 5.8 2.6 4 1.2 2 5 2.3 3.3 1 2 5.6 2.7 4.2 1.3 2 5.7 3 4.2 1.2 2 5.7 2.9 4.2 1.3 2 6.2 2.9 4.3 1.3 2 5.1 2.5 3 1.1 2 5.7 2.8 4.1 1.3 2 6.3 3.3 6 2.5 3 5.8 2.7 5.1 1.9 3 7.1 3 5.9 2.1 3 6.3 2.9 5.6 1.8 3 6.5 3 5.8 2.2 3 7.6 3 6.6 2.1 3 4.9 2.5 4.5 1.7 3 7.3 2.9 6.3 1.8 3 6.7 2.5 5.8 1.8 3 7.2 3.6 6.1 2.5 3 6.5 3.2 5.1 2 3 6.4 2.7 5.3 1.9 3 6.8 3 5.5 2.1 3 5.7 2.5 5 2 3 5.8 2.8 5.1 2.4 3 6.4 3.2 5.3 2.3 3 6.5 3 5.5 1.8 3 7.7 3.8 6.7 2.2 3 7.7 2.6 6.9 2.3 3 6 2.2 5 1.5 3 6.9 3.2 5.7 2.3 3 5.6 2.8 4.9 2 3 7.7 2.8 6.7 2 3 6.3 2.7 4.9 1.8 3 6.7 3.3 5.7 2.1 3 7.2 3.2 6 1.8 3 6.2 2.8 4.8 1.8 3 6.1 3 4.9 1.8 3 6.4 2.8 5.6 2.1 3 7.2 3 5.8 1.6 3 7.4 2.8 6.1 1.9 3 7.9 3.8 6.4 2 3 6.4 2.8 5.6 2.2 3 6.3 2.8 5.1 1.5 3 6.1 2.6 5.6 1.4 3 7.7 3 6.1 2.3 3 6.3 3.4 5.6 2.4 3 6.4 3.1 5.5 1.8 3 6 3 4.8 1.8 3 6.9 3.1 5.4 2.1 3 6.7 3.1 5.6 2.4 3 6.9 3.1 5.1 2.3 3 5.8 2.7 5.1 1.9 3 6.8 3.2 5.9 2.3 3 6.7 3.3 5.7 2.5 3 6.7 3 5.2 2.3 3 6.3 2.5 5 1.9 3 6.5 3 5.2 2 3 6.2 3.4 5.4 2.3 3 5.9 3 5.1 1.8 3代碼:
? ? ? ? 有不對的請多指正
????????實在不想寫了就來這看看吧~~~
import math # 數學 import random # 隨機 import numpy as np import matplotlib.pyplot as pltdef zhichi_w(zhichi, xy, a): # 計算更新 ww = [0, 0]if len(zhichi) == 0: # 初始化的0return wfor i in zhichi:w[0] += a[i] * xy[0][i] * xy[2][i] # 更新ww[1] += a[i] * xy[1][i] * xy[2][i]return wdef zhichi_b(zhichi, xy, a): # 計算更新 bb = 0if len(zhichi) == 0: # 初始化的0return 0for s in zhichi: # 對任意的支持向量有 ysf(xs)=1 所有支持向量求解平均值sum = 0for i in zhichi:sum += a[i] * xy[2][i] * (xy[0][i] * xy[0][s] + xy[1][i] * xy[1][s])b += 1 / xy[2][s] - sumreturn b / len(zhichi)def SMO(xy, m):a = [0.0] * len(xy[0]) # 拉格朗日乘子zhichi = set() # 支持向量下標loop = 1 # 循環標記(符合KKT)w = [0, 0] # 初始化 wb = 0 # 初始化 bwhile loop:loop += 1if loop == 150:print("達到早停標準")print("循環了:", loop, "次")loop = 0break# 初始化=========================================fx = [] # 儲存所有的fxyfx = [] # 儲存所有yfx-1的值Ek = [] # Ek,記錄fx-y用于啟發式搜索E_ = -1 # 貯存最大偏差,減少計算a1 = 0 # SMO a1a2 = 0 # SMO a2# 初始化結束======================================# 尋找a1,a2======================================for i in range(len(xy[0])): # 計算所有的 fx yfx-1 Ekfx.append(w[0] * xy[0][i] + w[1] * xy[1][i] + b) # 計算 fx=wx+byfx.append(xy[2][i] * fx[i] - 1) # 計算 yfx-1Ek.append(fx[i] - xy[2][i]) # 計算 fx-yif i in zhichi: # 之前看過的不看了,防止重復找某個acontinueif yfx[i] <= yfx[a1]:a1 = i # 得到偏離最大位置的下標(數值最小的)if yfx[a1] >= 0: # 最小的也滿足KKTprint("循環了:", loop, "次")loop = 0 # 循環標記(符合KKT)置零(沒有用到)breakfor i in range(len(xy[0])): # 遍歷找間隔最大的a2if i == a1: # 如果是a1,跳過continueEi = abs(Ek[i] - Ek[a1]) # |Eki-Eka1|if Ei < E_: # 找偏差E_ = Ei # 儲存偏差的值a2 = i # 儲存偏差的下標# 尋找a1,a2結束===================================zhichi.add(a1) # a1錄入支持向量zhichi.add(a2) # a2錄入支持向量# 分析約束條件=====================================# c=a1*y1+a2*y2c = a[a1] * xy[2][a1] + a[a2] * xy[2][a2] # 求出c# n=K11+k22-2*k12if m == "xianxinghe": # 線性核n = xy[0][a1] ** 2 + xy[1][a1] ** 2 + xy[0][a2] ** 2 + xy[1][a2] ** 2 - 2 * (xy[0][a1] * xy[0][a2] + xy[1][a1] * xy[1][a2])elif m == "duoxiangshihe": # 多項式核(這里是二次)n = (xy[0][a1] ** 2 + xy[1][a1] ** 2) ** 2 + (xy[0][a2] ** 2 + xy[1][a2] ** 2) ** 2 - 2 * (xy[0][a1] * xy[0][a2] + xy[1][a1] * xy[1][a2]) ** 2else: # 高斯核 取 2σ^2 = 1n = 2 * math.exp(-1) - 2 * math.exp(-((xy[0][a1] - xy[0][a2]) ** 2 + (xy[1][a1] - xy[1][a2]) ** 2))# 確定a1的可行域=====================================if xy[2][a1] == xy[2][a2]:L = max(0.0, a[a1] + a[a2] - 0.5) # 下界H = min(0.5, a[a1] + a[a2]) # 上界else:L = max(0.0, a[a1] - a[a2]) # 下界H = min(0.5, 0.5 + a[a1] - a[a2]) # 上界if n > 0:a1_New = a[a1] - xy[2][a1] * (Ek[a1] - Ek[a2]) / n # a1_New = a1_old-y1(e1-e2)/n# print("x1=",xy[0][a1],"y1=",xy[1][a1],"z1=",xy[2][a1],"x2=",xy[0][a2],"y2=",xy[1][a2],"z2=",xy[2][a2],"a1_New=",a1_New)# 越界裁剪============================================================if a1_New >= H:a1_New = Helif a1_New <= L:a1_New = Lelse:a1_New = min(H, L)# 參數更新=======================================a[a2] = a[a2] + xy[2][a1] * xy[2][a2] * (a[a1] - a1_New) # a2更新a[a1] = a1_New # a1更新w = zhichi_w(zhichi, xy, a) # 更新wb = zhichi_b(zhichi, xy, a) # 更新b# print("W=", w, "b=", b, "zhichi=", zhichi, "a1=", a[a1], "a2=", a[a2])# 標記支持向量======================================for i in zhichi:if a[i] == 0: # 選了,但值仍為0loop = loop + 1e = 'silver'else:if xy[2][i] == 1:e = 'b'else:e = 'r'plt.scatter(x1[0][i], x1[1][i], c='none', s=100, linewidths=1, edgecolor=e)print("支持向量數為:", len(zhichi), "\na為零支持向量:", loop)print("有用向量數:", len(zhichi) - loop)# 返回數據 w b =======================================return [w, b]def panduan(xyz, w_b1,w_b2):c = 0for i in range(len(xyz[0])):if (xyz[0][i] * w_b1[0][0] + xyz[1][i] * w_b1[0][1] + w_b1[1]) * xyz[2][i][0] < 0:c = c + 1continueif (xyz[0][i] * w_b2[0][0] + xyz[1][i] * w_b2[0][1] + w_b2[1]) * xyz[2][i][1] < 0:c = c + 1continuereturn (1 - c / len(xyz[0])) * 100def huitu(x1,x2,wb1,wb2,name):x = [x1[0][:],x1[1][:],x1[2][:]]for i in range(len(x[2])): # 對訓練集‘上色’if x[2][i] == [1, 1]:x[2][i] = 'r' # 訓練集 1 1 紅色elif x[2][i] == [-1, 1]:x[2][i] = 'g' # 訓練集 -1 1 綠色else:x[2][i] = 'b' # 訓練集 -1 -1 藍色plt.scatter(x[0], x[1], c=x[2], alpha=0.8) # 繪點訓練集x = [x2[0][:],x2[1][:],x2[2][:]]for i in range(len(x[2])): # 對測試集‘上色’if x[2][i] == [1, 1]:x[2][i] = 'orange' # 訓練集 1 1 橙色elif x[2][i] == [-1, 1]:x[2][i] = 'y' # 訓練集 -1 1 黃色else:x[2][i] = 'm' # 訓練集 -1 -1 紫色plt.scatter(x[0], x[1], c=x[2], alpha=0.8) # 繪點測試集plt.xlabel('x') # x軸標簽plt.ylabel('y') # y軸標簽plt.title(name) # 標題xl = np.arange(min(x[0]), max(x[0]), 0.1) # 繪制分類線一yl = (-wb1[0][0] * xl - wb1[1]) / wb1[0][1]plt.plot(xl, yl, 'r')xl = np.arange(min(x[0]), max(x[0]), 0.1) # 繪制分類線二yl = (-wb2[0][0] * xl - wb2[1]) / wb2[0][1]plt.plot(xl, yl, 'b')# 主函數======================================================= f = open('Iris.txt', 'r') # 讀文件 x = [[], [], [], [], []] # 花朵屬性,(0,1,2,3),花朵種類 while 1:yihang = f.readline() # 讀一行if len(yihang) <= 1: # 讀到末尾結束breakfenkai = yihang.split('\t') # 按\t分開for i in range(4): # 分開的四個值x[i].append(eval(fenkai[i])) # 化為數字加到x中if (eval(fenkai[4]) == 1): # 將標簽化為向量形式x[4].append([1, 1])else:if (eval(fenkai[4]) == 2):x[4].append([-1, 1])else:x[4].append([-1, -1])print('數據集=======================================================') print(len(x[0])) # 數據大小 # 選擇數據=================================================== shuxing1 = eval(input("選取第一個屬性:")) if shuxing1 < 0 or shuxing1 > 4:print("無效選項,默認選擇第1項")shuxing1 = 1 shuxing2 = eval(input("選取第一個屬性:")) if shuxing2 < 0 or shuxing2 > 4 or shuxing1 == shuxing2:print("無效選項,默認選擇第2項")shuxing2 = 2 # 生成數據集================================================== lt = list(range(150)) # 得到一個順序序列 random.shuffle(lt) # 打亂序列 x1 = [[], [], []] # 初始化x1 x2 = [[], [], []] # 初始化x2 for i in lt[0:100]: # 截取部分做訓練集x1[0].append(x[shuxing1][i]) # 加上數據集x屬性x1[1].append(x[shuxing2][i]) # 加上數據集y屬性x1[2].append(x[4][i]) # 加上數據集c標簽 for i in lt[100:150]: # 截取部分做測試集x2[0].append(x[shuxing1][i]) # 加上數據集x屬性x2[1].append(x[shuxing2][i]) # 加上數據集y屬性x2[2].append(x[4][i]) # 加上數據集c標簽 print('\n\n開始訓練==============================================') print('\n線性核==============================================') # 計算 w b============================================ plt.figure(1) # 第一張畫布 x = [x1[0][:], x1[1][:], []] # 第一次分類 for i in x1[2]:x[2].append(i[0]) # 加上數據集標簽 wb1 = SMO(x,"xianxinghe") x = [x1[0][:], x1[1][:], []] # 第二次分類 for i in x1[2]:x[2].append(i[1]) # 加上數據集標簽 wb2 = SMO(x,"xianxinghe") print("w1為:", wb1[0], " b1為:", wb1[1]) print("w2為:", wb2[0], " b2為:", wb2[1]) # 計算正確率=========================================== print("訓練集上的正確率為:", panduan(x1, wb1,wb2), "%") print("測試集上的正確率為:", panduan(x2, wb1,wb2), "%") # 繪圖 =============================================== # 圈著的是曾經選中的值,灰色的是選中但更新為0 huitu(x1,x2,wb1,wb2,"xianxinghe") print('\n多項式核============================================') # 計算 w b============================================ plt.figure(2) # 第二張畫布 x = [x1[0][:], x1[1][:], []] # 第一次分類 for i in x1[2]:x[2].append(i[0]) # 加上數據集標簽 wb1 = SMO(x,"duoxiangshihe") x = [x1[0][:], x1[1][:], []] # 第二次分類 for i in x1[2]:x[2].append(i[1]) # 加上數據集標簽 wb2 = SMO(x,"duoxiangshihe") print("w1為:", wb1[0], " b1為:", wb1[1]) print("w2為:", wb2[0], " b2為:", wb2[1]) # 計算正確率=========================================== print("訓練集上的正確率為:", panduan(x1, wb1,wb2), "%") print("測試集上的正確率為:", panduan(x2, wb1,wb2), "%") # 繪圖 =============================================== # 圈著的是曾經選中的值,灰色的是選中但更新為0 huitu(x1,x2,wb1,wb2,"duoxiangshihe") print('\n高斯核==============================================') # 計算 w b============================================ plt.figure(3) # 第三張畫布 x = [x1[0][:], x1[1][:], []] # 第一次分類 for i in x1[2]:x[2].append(i[0]) # 加上數據集標簽 wb1 = SMO(x,"gaosihe") x = [x1[0][:], x1[1][:], []] # 第二次分類 for i in x1[2]:x[2].append(i[1]) # 加上數據集標簽 wb2 = SMO(x,"gaosihe") print("w1為:", wb1[0], " b1為:", wb1[1]) print("w2為:", wb2[0], " b2為:", wb2[1]) # 計算正確率=========================================== print("訓練集上的正確率為:", panduan(x1, wb1,wb2), "%") print("測試集上的正確率為:", panduan(x2, wb1,wb2), "%") # 繪圖 =============================================== # 圈著的是曾經選中的值,灰色的是選中但更新為0 huitu(x1,x2,wb1,wb2,"gaosihe") #顯示所有圖 plt.show() # 顯示結果實例:
選取 0 1
數據集======================================================= 150 選取第一個屬性:0 選取第一個屬性:1開始訓練==============================================線性核============================================== 循環了: 59 次 支持向量數為: 58 a為零支持向量: 43 有用向量數: 15 循環了: 81 次 支持向量數為: 80 a為零支持向量: 37 有用向量數: 43 w1為: [-1.2015577886380138, 1.0472346551913316] b1為: 3.193887811107239 w2為: [-0.9046180342303862, -0.050401017033139706] b2為: 5.818677047436661 訓練集上的正確率為: 84.0 % 測試集上的正確率為: 80.0 %多項式核============================================ 達到早停標準 循環了: 150 次 支持向量數為: 70 a為零支持向量: 2 有用向量數: 68 達到早停標準 循環了: 150 次 支持向量數為: 100 a為零支持向量: 2 有用向量數: 98 w1為: [-1.5323422583266884, -0.6451163863274796] b1為: 10.19605818386737 w2為: [-0.32703052684507555, -0.07341379665570845] b2為: 2.474197513122665 訓練集上的正確率為: 55.00000000000001 % 測試集上的正確率為: 60.0 %高斯核============================================== 循環了: 44 次 支持向量數為: 43 a為零支持向量: 37 有用向量數: 6 循環了: 66 次 支持向量數為: 65 a為零支持向量: 37 有用向量數: 28 w1為: [-1.4000000000000004, 1.2000000000000002] b1為: 3.821860465116281 w2為: [-1.2206265744055393, -0.29455424617379977] b2為: 8.488342156179229 訓練集上的正確率為: 84.0 % 測試集上的正確率為: 80.0 %選取 1 3
數據集======================================================= 150 選取第一個屬性:1 選取第一個屬性:3開始訓練==============================================線性核============================================== 循環了: 67 次 支持向量數為: 66 a為零支持向量: 50 有用向量數: 16 循環了: 44 次 支持向量數為: 43 a為零支持向量: 17 有用向量數: 26 w1為: [0.5633951571969109, -1.042348513330865] b1為: -0.9195155744439709 w2為: [-0.06277727278771472, -2.4362648813243806] b2為: 4.185161300086744 訓練集上的正確率為: 97.0 % 測試集上的正確率為: 94.0 %多項式核============================================ 達到早停標準 循環了: 150 次 支持向量數為: 88 a為零支持向量: 19 有用向量數: 69 達到早停標準 循環了: 150 次 支持向量數為: 39 a為零支持向量: 4 有用向量數: 35 w1為: [0.21771014101070363, -0.5387711292789139] b1為: -0.3383609523351082 w2為: [-0.010052537823134533, -0.3832264577071416] b2為: 0.6811197228851011 訓練集上的正確率為: 96.0 % 測試集上的正確率為: 94.0 %高斯核============================================== 循環了: 45 次 支持向量數為: 44 a為零支持向量: 36 有用向量數: 8 達到早停標準 循環了: 150 次 支持向量數為: 44 a為零支持向量: 42 有用向量數: 2 w1為: [0.9855920219400248, -1.21694723510404] b1為: -2.034100651391037 w2為: [0.19999999999999996, -0.9500000000000001] b2為: 1.0344318181818182 訓練集上的正確率為: 97.0 % 測試集上的正確率為: 94.0 %?
????????可以對所有屬性組合。
????????可以看出,多項式核一定有一些錯誤,,,希望能夠有人指正
總結
以上是生活随笔為你收集整理的python非线性可分支持向量机模型(实现iris分类)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 好玩的Python彩蛋
- 下一篇: matlab创作歌曲——《月半小夜曲》