機器學習算法整理(七)支持向量機以及SMO算法實現


以下均為自己看視頻做的筆記,自用,侵刪!

還參考了:http://www.ai-start.com/ml2014/

在監督學習中,許多學習算法的性能都非常類似,因此,重要的不是你該選擇使用學習算法A還是學習算法B,而更重要的是,應用這些算法時,所創建的大量數據在應用這些算法時,表現情況通常依賴於你的水平。比如:你為學習算法所設計的特征量的選擇,以及如何選擇正則化參數,諸如此類的事。還有一個更加強大的算法廣泛的應用於工業界和學術界,它被稱為支持向量機(Support Vector Machine)。與邏輯回歸和神經網絡相比,支持向量機,或者簡稱SVM,在學習復雜的非線性方程時提供了一種更為清晰,更加強大的方式。

容錯能力越強越好

b為平面的偏正向,w為平面的法向量,x到平面的映射:

先求的是,距分界線距離最小的點;然后再求的是 什么樣的w和b,使得這樣的點,距離分界線的值最大。

放縮之后:; 又要取 其為min,即 取 yi*(w^T*Q(xi) + b) = 1  => 

補充:

下面的 x_i · x_j   是算的內積:如,(3_i, 3_i) · (3_j, 3_j) ==> 3_i * 3_j + 3_i * 3_j = 18;

如上面實例,x2就是沒有發揮作用的數據點,α為0;x1, x2就是支持向量,α不為0的點;

松弛因子:

核變換:低微不可分==> 映射到高維

舉例:

SMO算法實現:

除了α1,α2當成變量,其他的α都當成常數項。

(L是取值的下界,H是取值的上界)

代碼實現:

import numpy as np def loadDataSet(fileName): dataMat = []; labelMat = [] fr = open(fileName) for line in fr.readlines(): lineArr = line.strip().split('\t') dataMat.append([float(lineArr[0]), float(lineArr[1])]) labelMat.append(float(lineArr[2])) return dataMat,labelMat def selectJrand(i,m): j=i #we want to select any J not equal to i while (j==i): j = int(np.random.uniform(0,m)) return j # 控制aj的上下界 def clipAlpha(aj,H,L): if aj > H: aj = H if L > aj: aj = L return aj # dataMat: 數據; classLabels: Y值; C:V值; toler:容忍程度; maxIter: 最大迭代次數 def smoSimple(dataMatIn, classLabels, C, toler, maxIter): #初始化操作 dataMatrix = np.mat(dataMatIn); labelMat = np.mat(classLabels).transpose() b = 0; m,n = np.shape(dataMatrix) # 進行初始化 alphas = np.mat(np.zeros((m,1))) iter = 0 while (iter < maxIter): alphaPairsChanged = 0 # m : 數據樣本數 for i in range(m): # 先計算FXi,這里只用了線性的 kernel,相當於不變。 fXi = float(np.multiply(alphas,labelMat).T*(dataMatrix*dataMatrix[i,:].T)) + b Ei = fXi - float(labelMat[i])#if checks if an example violates KKT conditions # 設置限制條件 if ((labelMat[i]*Ei < -toler) and (alphas[i] < C)) or ((labelMat[i]*Ei > toler) and (alphas[i] > 0)): #隨機再選一個不等於i的數 j = selectJrand(i,m) fXj = float(np.multiply(alphas,labelMat).T*(dataMatrix*dataMatrix[j,:].T)) + b Ej = fXj - float(labelMat[j]) alphaIold = alphas[i].copy(); alphaJold = alphas[j].copy(); # 控制邊界條件 # 定義了上(H)下(L)界取值范圍 if (labelMat[i] != labelMat[j]): L = max(0, alphas[j] - alphas[i]) H = min(C, C + alphas[j] - alphas[i]) else: L = max(0, alphas[j] + alphas[i] - C) H = min(C, alphas[j] + alphas[i]) if L==H: print "L==H"; continue #算出 eta = K11 + K22 - K12 #這里需要添加一個負號 eta = 2.0 * dataMatrix[i,:]*dataMatrix[j,:].T - dataMatrix[i,:]*dataMatrix[i,:].T - dataMatrix[j,:]*dataMatrix[j,:].T if eta >= 0: print "eta>=0"; continue # 即這里就用一個減號 alphas[j] -= labelMat[j]*(Ei - Ej)/eta # 控制上下界 alphas[j] = clipAlpha(alphas[j],H,L) if (abs(alphas[j] - alphaJold) < 0.00001): print "j not moving enough"; continue # 算出αi alphas[i] += labelMat[j]*labelMat[i]*(alphaJold - alphas[j])#update i by the same amount as j #the update is in the oppostie direction  b1 = b - Ei- labelMat[i]*(alphas[i]-alphaIold)*dataMatrix[i,:]*dataMatrix[i,:].T - labelMat[j]*(alphas[j]-alphaJold)*dataMatrix[i,:]*dataMatrix[j,:].T b2 = b - Ej- labelMat[i]*(alphas[i]-alphaIold)*dataMatrix[i,:]*dataMatrix[j,:].T - labelMat[j]*(alphas[j]-alphaJold)*dataMatrix[j,:]*dataMatrix[j,:].T if (0 < alphas[i]) and (C > alphas[i]): b = b1 elif (0 < alphas[j]) and (C > alphas[j]): b = b2 else: b = (b1 + b2)/2.0 alphaPairsChanged += 1 print "iter: %d i:%d, pairs changed %d" % (iter,i,alphaPairsChanged) if (alphaPairsChanged == 0): iter += 1 else: iter = 0 print "iteration number: %d" % iter return b,alphas if __name__ == '__main__': dataMat,labelMat = loadDataSet('testSet.txt') b,alphas = smoSimple(dataMat, labelMat, 0.06, 0.01, 100) print 'b:',b print 'alphas',alphas[alphas>0]

SMO實例:

import matplotlib.pyplot as plt import numpy as np %matplotlib inline from matplotlib.colors import ListedColormap def plot_decision_regions(X, y, classifier, test_idx=None, resolution=0.02): # setup marker generator and color map
    markers = ('s', 'x', 'o', '^', 'v') colors = ('red', 'blue', 'lightgreen', 'gray', 'cyan') cmap = ListedColormap(colors[:len(np.unique(y))]) # plot the decision surface
    x1_min, x1_max = X[:, 0].min() - 1, X[:, 0].max() + 1 x2_min, x2_max = X[:, 1].min() - 1, X[:, 1].max() + 1 xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, resolution), np.arange(x2_min, x2_max, resolution)) Z = classifier.predict(np.array([xx1.ravel(), xx2.ravel()]).T) Z = Z.reshape(xx1.shape) plt.contourf(xx1, xx2, Z, alpha=0.4, cmap=cmap) plt.xlim(xx1.min(), xx1.max()) plt.ylim(xx2.min(), xx2.max()) # plot class samples
    for idx, cl in enumerate(np.unique(y)): plt.scatter(x=X[y == cl, 0], y=X[y == cl, 1],alpha=0.8, c=cmap(idx),marker=markers[idx], label=cl) # highlight test samples
    if test_idx: X_test, y_test = X[test_idx, :], y[test_idx] plt.scatter(X_test[:, 0], X_test[:, 1], c='', alpha=1.0, linewidth=1, marker='o', s=55, label='test set')
from sklearn import datasets import numpy as np from sklearn.cross_validation import train_test_split iris = datasets.load_iris() # 由於Iris是很有名的數據集,scikit-learn已經原生自帶了。 X = iris.data[:, [1, 2]] y = iris.target # 標簽已經轉換成0,1,2了 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0) # 為了看模型在沒有見過數據集上的表現,隨機拿出數據集中30%的部分做測試 # 為了追求機器學習和最優化算法的最佳性能,我們將特征縮放 from sklearn.preprocessing import StandardScaler sc = StandardScaler() sc.fit(X_train) # 估算每個特征的平均值和標准差 sc.mean_ # 查看特征的平均值,由於Iris我們只用了兩個特征,所以結果是array([ 3.82857143, 1.22666667]) sc.scale_ # 查看特征的標准差,這個結果是array([ 1.79595918, 0.77769705]) X_train_std = sc.transform(X_train) # 注意:這里我們要用同樣的參數來標准化測試集,使得測試集和訓練集之間有可比性 X_test_std = sc.transform(X_test) X_combined_std = np.vstack((X_train_std, X_test_std)) y_combined = np.hstack((y_train, y_test)) # 導入SVC from sklearn.svm import SVC svm1 = SVC(kernel='linear', C=0.1, random_state=0) # 用線性核 svm1.fit(X_train_std, y_train) svm2 = SVC(kernel='linear', C=10, random_state=0) # 用線性核 svm2.fit(X_train_std, y_train) fig = plt.figure(figsize=(10,6)) ax1 = fig.add_subplot(1,2,1) #ax2 = fig.add_subplot(1,2,2)  plot_decision_regions(X_combined_std, y_combined, classifier=svm1) plt.xlabel('petal length [standardized]') plt.ylabel('petal width [standardized]') plt.title('C = 0.1') ax2 = fig.add_subplot(1,2,2) plot_decision_regions(X_combined_std, y_combined, classifier=svm2) plt.xlabel('petal length [standardized]') plt.ylabel('petal width [standardized]') plt.title('C = 10') plt.show()

svm1 = SVC(kernel='rbf', random_state=0, gamma=0.1, C=1.0) # 令gamma參數中的x分別等於0.1和10 svm1.fit(X_train_std, y_train) svm2 = SVC(kernel='rbf', random_state=0, gamma=10, C=1.0) svm2.fit(X_train_std, y_train) fig = plt.figure(figsize=(10,6)) ax1 = fig.add_subplot(1,2,1) plot_decision_regions(X_combined_std, y_combined, classifier=svm1) plt.xlabel('petal length [standardized]') plt.ylabel('petal width [standardized]') plt.title('gamma = 0.1') ax2 = fig.add_subplot(1,2,2) plot_decision_regions(X_combined_std, y_combined, classifier=svm2) plt.xlabel('petal length [standardized]') plt.ylabel('petal width [standardized]') plt.title('gamma = 10') plt.show()

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM