• 如何用Python实现常见机器学习算法-4


    四、SVM支持向量机

    1、代价函数

    在逻辑回归中,我们的代价为:

    其中:

    如图所示,如果y=1,cost代价函数如图所示

    我们想让,即z>>0,这样的话cost代价函数才会趋于最小(这正是我们想要的),所以用图中红色的函数代替逻辑回归中的cost

     当y=0时同样用代替

    最终得到的代价函数为:

    最后我们想要

    之前我们逻辑回归中的代价函数为:

    可以认为这里的,只是表达形式问题,这里C的值越大,SVM的决策边界的margin也越大,下面会说明。

    2、Large Margin

    如下图所示,SVM分类会使用最大的margin将其分开

    先说一下向量内积

    表示U的欧几里德范数(欧式范数),

    向量V在向量U上的投影的长度记为p,则:向量内积:

    根据向量夹角公式推导一即可,

    前面说过,当C越大时,margin也就越大,我们的目的是最小化代价函数J(θ),当margin最大时,C的乘积项

    要很小,所以金丝猴为:

    我们最后的目的就是求使代价最小的θ

    可以得到:

    p即为x在θ上的投影

    如下图所示,假设决策边界如图,找其中的一个点,到θ上的投影为p,则或者,若是p很小,则需要很大,这与我们要求的θ使最小相违背,所以最后求的是large margin

    3、SVM Kernel(核函数)

    对于线性可分的问题,使用线性核函数即可

    对于线性不可分的问题,在逻辑回归中,我们是将feature映射为使用多项式的形式,SVM中也有多项式核函数,但是更常用的是高斯核函数,也称为RBF核

    高斯核函数为:

    假设如图几个点,

    令:

    可以看出,若是x与距离较近,可以推出,(即相似度较大);

    若是x与距离较远,可以推出,(即相似度较低)。

    高斯核函数的σ越小,f下降的越快

    如何选择初始的

    训练集:

    选择:

    对于给出的x,计算f,令:

    所以:

    最小化J求出θ,

     

    如果,==》预测y=1

    4、使用scikit-learn中的SVM模型代码

    全部代码

     1 import numpy as np
     2 from scipy import io as spio
     3 from matplotlib import pyplot as plt
     4 from sklearn import svm
     5 
     6 def SVM():
     7     '''data1——线性分类'''
     8     data1 = spio.loadmat('data1.mat')
     9     X = data1['X']
    10     y = data1['y']
    11     y = np.ravel(y)
    12     plot_data(X,y)
    13     
    14     model = svm.SVC(C=1.0,kernel='linear').fit(X,y) # 指定核函数为线性核函数
    15     plot_decisionBoundary(X, y, model)  # 画决策边界
    16     '''data2——非线性分类'''
    17     data2 = spio.loadmat('data2.mat')
    18     X = data2['X']
    19     y = data2['y']
    20     y = np.ravel(y)
    21     plt = plot_data(X,y)
    22     plt.show()
    23     
    24     model = svm.SVC(gamma=100).fit(X,y)     # gamma为核函数的系数,值越大拟合的越好
    25     plot_decisionBoundary(X, y, model,class_='notLinear')   # 画决策边界
    26     
    27     
    28     
    29 # 作图
    30 def plot_data(X,y):
    31     plt.figure(figsize=(10,8))
    32     pos = np.where(y==1)    # 找到y=1的位置
    33     neg = np.where(y==0)    # 找到y=0的位置
    34     p1, = plt.plot(np.ravel(X[pos,0]),np.ravel(X[pos,1]),'ro',markersize=8)
    35     p2, = plt.plot(np.ravel(X[neg,0]),np.ravel(X[neg,1]),'g^',markersize=8)
    36     plt.xlabel("X1")
    37     plt.ylabel("X2")
    38     plt.legend([p1,p2],["y==1","y==0"])
    39     return plt
    40     
    41 # 画决策边界
    42 def plot_decisionBoundary(X,y,model,class_='linear'):
    43     plt = plot_data(X, y)
    44     
    45     # 线性边界        
    46     if class_=='linear':
    47         w = model.coef_
    48         b = model.intercept_
    49         xp = np.linspace(np.min(X[:,0]),np.max(X[:,0]),100)
    50         yp = -(w[0,0]*xp+b)/w[0,1]
    51         plt.plot(xp,yp,'b-',linewidth=2.0)
    52         plt.show()
    53     else:  # 非线性边界
    54         x_1 = np.transpose(np.linspace(np.min(X[:,0]),np.max(X[:,0]),100).reshape(1,-1))
    55         x_2 = np.transpose(np.linspace(np.min(X[:,1]),np.max(X[:,1]),100).reshape(1,-1))
    56         X1,X2 = np.meshgrid(x_1,x_2)
    57         vals = np.zeros(X1.shape)
    58         for i in range(X1.shape[1]):
    59             this_X = np.hstack((X1[:,i].reshape(-1,1),X2[:,i].reshape(-1,1)))
    60             vals[:,i] = model.predict(this_X)
    61         
    62         plt.contour(X1,X2,vals,[0,1],color='blue')
    63         plt.show()
    64     
    65 
    66 if __name__ == "__main__":
    67     SVM()

    线性可分的代码,指定核函数为linear:

    1 '''data1——线性分类'''
    2     data1 = spio.loadmat('data1.mat')
    3     X = data1['X']
    4     y = data1['y']
    5     y = np.ravel(y)
    6     plot_data(X,y)
    7     
    8     model = svm.SVC(C=1.0,kernel='linear').fit(X,y) # 指定核函数为线性核函数
    9     plot_decisionBoundary(X, y, model)  # 画决策边界

    非线性可分的代码,默认核函数为rbf

     1 '''data2——非线性分类'''
     2     data2 = spio.loadmat('data2.mat')
     3     X = data2['X']
     4     y = data2['y']
     5     y = np.ravel(y)
     6     plt = plot_data(X,y)
     7     plt.show()
     8     
     9     model = svm.SVC(gamma=100).fit(X,y)     # gamma为核函数的系数,值越大拟合的越好
    10     plot_decisionBoundary(X, y, model,class_='notLinear')   # 画决策边界

    5、运行结果

    线性可分的决策边界:

    线性不可分的决策边界:

    五、K-Means聚类算法

    1、聚类过程

    聚类属于无监督学习,不知道y的标记分为K类

    K-Means算法分为两个步骤

    第一步:簇分配,随机选K个点作为中心,计算到这K个点的距离,分为K个簇;

    第二步:移动聚类中心,重新计算每个簇的中心,移动中心,重复以上步骤。

    如下图所示

    随机分配聚类中心:

    重新计算聚类中心,移动一次

    最后10步之后的聚类中心

    计算每条数据到哪个中心最近的代码如下:

     1 # 找到每条数据距离哪个类中心最近    
     2 def findClosestCentroids(X,initial_centroids):
     3     m = X.shape[0]                  # 数据条数
     4     K = initial_centroids.shape[0]  # 类的总数
     5     dis = np.zeros((m,K))           # 存储计算每个点分别到K个类的距离
     6     idx = np.zeros((m,1))           # 要返回的每条数据属于哪个类
     7     
     8     '''计算每个点到每个类中心的距离'''
     9     for i in range(m):
    10         for j in range(K):
    11             dis[i,j] = np.dot((X[i,:]-initial_centroids[j,:]).reshape(1,-1),(X[i,:]-initial_centroids[j,:]).reshape(-1,1))
    12     
    13     '''返回dis每一行的最小值对应的列号,即为对应的类别
    14     - np.min(dis, axis=1)返回每一行的最小值
    15     - np.where(dis == np.min(dis, axis=1).reshape(-1,1)) 返回对应最小值的坐标
    16      - 注意:可能最小值对应的坐标有多个,where都会找出来,所以返回时返回前m个需要的即可(因为对于多个最小值,属于哪个类别都可以)
    17     '''  
    18     dummy,idx = np.where(dis == np.min(dis, axis=1).reshape(-1,1))
    19     return idx[0:dis.shape[0]]  # 注意截取一下

    计算类中心代码实现:

    1 # 计算类中心
    2 def computerCentroids(X,idx,K):
    3     n = X.shape[1]
    4     centroids = np.zeros((K,n))
    5     for i in range(K):
    6         centroids[i,:] = np.mean(X[np.ravel(idx==i),:], axis=0).reshape(1,-1)   # 索引要是一维的,axis=0为每一列,idx==i一次找出属于哪一类的,然后计算均值
    7     return centroids

    2、目标函数

    也叫做失真代价函数

    最后我们想得到:

    其中表示i条数据距离哪个类中心最近,其中即为聚类的中心

    3、聚类中心的选择

    随机初始化,从给定的数据中随机抽取K个作为聚类中心

    随机一次的结果可能不好,可以随机多次,最后取使代价函数最小的作为中心。

    代码实现:(这里随机一次)

    1 # 初始化类中心--随机取K个点作为聚类中心
    2 def kMeansInitCentroids(X,K):
    3     m = X.shape[0]
    4     m_arr = np.arange(0,m)      # 生成0-m-1
    5     centroids = np.zeros((K,X.shape[1]))
    6     np.random.shuffle(m_arr)    # 打乱m_arr顺序    
    7     rand_indices = m_arr[:K]    # 取前K个
    8     centroids = X[rand_indices,:]
    9     return centroids

    4、聚类个数K的选择

    聚类是不知道y的label的,所以也不知道真正的聚类个数

    肘部法则(Elbow method)

    做代价函数J和K的图,若是出现一个拐点,如下图所示,K就取拐点处的值,下图显示K=3

    若是很平滑就不明确,人为选择。

    第二种就是人为观察选择

    5、应用-图片压缩

    将图片的像素分为若干类,然后用这个类代替原来的像素值。

    执行聚类的算法代码:

     1 # 聚类算法
     2 def runKMeans(X,initial_centroids,max_iters,plot_process):
     3     m,n = X.shape                   # 数据条数和维度
     4     K = initial_centroids.shape[0]  # 类数
     5     centroids = initial_centroids   # 记录当前类中心
     6     previous_centroids = centroids  # 记录上一次类中心
     7     idx = np.zeros((m,1))           # 每条数据属于哪个类
     8     
     9     for i in range(max_iters):      # 迭代次数
    10         print u'迭代计算次数:%d'%(i+1)
    11         idx = findClosestCentroids(X, centroids)
    12         if plot_process:    # 如果绘制图像
    13             plt = plotProcessKMeans(X,centroids,previous_centroids) # 画聚类中心的移动过程
    14             previous_centroids = centroids  # 重置
    15         centroids = computerCentroids(X, idx, K)    # 重新计算类中心
    16     if plot_process:    # 显示最终的绘制结果
    17         plt.show()
    18     return centroids,idx    # 返回聚类中心和数据属于哪个类

    6、使用scikit-learn库中的线性模型实现聚类

     1 import numpy as np
     2 from scipy import io as spio
     3 from matplotlib import pyplot as plt
     4 from sklearn.cluster import KMeans
     5 
     6 def kMenas():
     7     data = spio.loadmat("data.mat")
     8     X = data['X']   
     9     model = KMeans(n_clusters=3).fit(X) # n_clusters指定3类,拟合数据
    10     centroids = model.cluster_centers_  # 聚类中心
    11     
    12     plt.scatter(X[:,0], X[:,1])     # 原数据的散点图
    13     plt.plot(centroids[:,0],centroids[:,1],'r^',markersize=10)  # 聚类中心
    14     plt.show()
    15 
    16 if __name__ == "__main__":
    17     kMenas()

    7、运行结果

    二维数据中心的移动

    图片压缩

  • 相关阅读:
    String数组转换成Integer数组
    码云远程仓库用户名和密码修改了,本地如何删除修改?
    Git操作过程(码云)
    SpringCloud应用之配置中心Nacos
    SpringCloud应用之网关GateWay
    SpringCloud应用之熔断器Hystrix
    SpringCloud应用之服务调用Feign
    装饰者设计模式
    Spring 自动装配及其注解
    Spring Bean自动装配有哪些方式?
  • 原文地址:https://www.cnblogs.com/freeman818/p/8260402.html
Copyright © 2020-2023  润新知