• 机器学习算法整理(七)支持向量机以及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('	')
    
            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()

  • 相关阅读:
    记录------敬畏生活
    不错的博客分享
    Python学习笔记(一) 字符串和编码
    OSPF(二)基础实验 ASBR--- 在OSPF中引入自治系统外部路由--- LSA4和LSA5
    OSPF(一)基本概念和基础实验
    LAMP--PHP实验(四)使用包含文件提高代码效率
    LAMP--PHP实验(三)在页面之间传送变量 及遇到问题解决
    LAMP--PHP实验(二)常量和变量
    LAMP--PHP实验(一)第一个PHP程序
    随机获取图片的API
  • 原文地址:https://www.cnblogs.com/douzujun/p/8964267.html
Copyright © 2020-2023  润新知