码迷,mamicode.com
首页 > 编程语言 > 详细

台湾大学林轩田教授机器学习基石课程理解及python实现----PLA

时间:2016-07-11 17:13:07      阅读:599      评论:0      收藏:0      [点我收藏+]

标签:

    最近在班主任的带领下,开始观看台湾大学林轩田教授的机器学习基石课程,虽然吧,台湾人,汉语说得蛮6,但是还是听着怪怪的,不过内容非常值得刚刚入门的机器学习

小白学习,话不多说,直接进入正题。

1.基本介绍(貌似这里一般是应该背景介绍,但是,历史吗,自己去百度吧)

(1)preceptron

翻译中文叫做感知器,如果你之前听说过神经网络的,它其实就是网络中的一个神经元,它自身的作用非常小,只能对于数据只能实现二分类,然而如果连成网络的

话,神经网络的每一层都可以作为一个线性函数或非线性函数,将函数复合的话,理论上可以逼近任何函数(这里的数学模型或者说数学原理我还没有完全理解,如

果有大神的话可以互相交流)。这里林教授以发不发银行卡作为问题引入,即银行面对一位来申请银行卡的人,银行持有此人的一些基本资料,根据之前已有的发卡

记录,建立模型,来判断是否应该发卡给当前的申请人。在实际生活中,有许多是与不是得二分问题,譬如识别类的问题,感知器作为目前最简单的线性分类器,其

实还是有不错的分类能力的。下图是感知器的模型图:

技术分享

从图中可以直观的看出感知器接受多个维度的数据,与对应的权值w相乘之后得到一个值,经过sign函数从而达到二分类的目的,为了表达的简单,我们将偏置值b一

起写入wx中,即w=b,x=1,这在下面的代码中会有体现。在林教授的课程中,偏置值b为阈值(threshold)的负数,即x与w的乘积大于此数值,表明银行可以发给

此人银行卡,反之,则不能发卡。具体的表现形式见下图:

技术分享

(2)PLA

全称为"preceptron learning algorithm",在课程中林教授称之为“知错能改算法”,当然这其实也是这个算法的核心表现。(其实用的比较多的方法应该是梯度下降法,

但是我还是按照课程提供的方法进行)。我们首先考虑的是当前数据线性可分,那么最后的结果一定是感知器可以完美的分开两组数据。

我们假设最初的w是随机的(我是默认wi=1)的,对于分对了的数据,即技术分享,我们不做任何操作。但是如果数据分错了,我

们就需要进行修改了,下图呈现除了两种错误的可能性:

技术分享

此处将w和x看作一个向量,根据向量内积的基本知识,如图一,如果w与x的乘积应该为正数(训练样本本身的label),可现在的乘积为负数,证明向量w与x的角度

过大通过w=w+x来减小w与x之间的角度(图中的黑点其实就是原点,我相信我之类的小白还是看这种熟悉的坐标系舒服),第二张图在此不做解释。技术分享此时,你肯定

有新的疑问,如果按照这种做法岂不是会让之前已经分类对的点出现再次分错的情况吗?所以,它的结束条件是所有点都满足,而不是仅仅扫一遍数据集就好。

2.一些值得思考的问题(其实林教授讲的这些问题都非常有意思)

(1)表明每次修改后的w向量逐渐趋向于最终的完美的wf(向量的乘积不断变大)

技术分享

图片中也有really的字样,因为向量乘积虽然在变大,也有可能是向量的模再增加,而在这个例子中,我们更加关心的是w与wf(最终的w)之间的角度。

技术分享

结果出来了,确实w在不断更新中长度不断增加。。。但是,总归不是无限制的增加,从这页可以看出来,最多也就是‘longest’x我们最初的问题还是没解决,我们用

wf与w的模向量直接相乘(乘出来的结果即为两个向量的结果),过程如下:

技术分享

技术分享

这里需要注意一下,在林教授的课程里,w0里全是0,所以最后是等号

技术分享

技术分享

技术分享

(麻烦问一下,有没有知道怎么直接将Math Type的公式写进博客啊,哭晕在厕所)

最后突然发现,对于一组数据,我们可以直接测出最大的迭代次数。

(2)线性不可分

此时PLA完全没有用了吗?

根据林教授所讲的利用贪心算法的pocket learning,即如果出现点分类错误的情况,比较wt+1和wt的出错的点的个数,从而确定更新还是不更新。而终止条件也会有所改变,需要人

为限定迭代次数(亲测速度较慢)。

3.代码

(1)PLA

<span style="font-size:10px;">#encoding:utf-8
from numpy import *
import matplotlib.pyplot as plt
import operator
import time
def createTrainDataSet():#训练样本,第一个1为阈值对应的w,下同
    trainData = [   [1, 1, 4],
                    [1, 2, 3], 
                    [1, -2, 3], 
                    [1, -2, 2], 
                    [1, 0, 1], 
                    [1, 1, 2]]
    label = [1, 1, 1, -1, -1,  -1]
    return trainData, label
def createTestDataSet():#数据样本
    testData = [   [1, 1, 1],
                   [1, 2, 0], 
                   [1, 2, 4], 
                   [1, 1, 3]]
    return testData
def sigmoid(X):
    X = float(X)
    if X > 0:
        return 1
    elif X < 0:
        return -1
    else:
        return 0
def pla(traindataIn,trainlabelIn):
    traindata=mat(traindataIn)
    trainlabel=mat(trainlabelIn).transpose()
    m,n=shape(traindata)
    w=ones((n,1))
    while True:
        iscompleted=True
        for i in range(m):
            if (sigmoid(dot(traindata[i],w))==trainlabel[i]):
                continue
            else:
                iscompleted=False
                w+=(trainlabel[i]*traindata[i]).transpose()
        if iscompleted:
            break
    return w
def classify(inX,w):
    result=sigmoid(sum(w*inX))
    if result>0:
        return 1
    else:
        return -1
def plotBestFit(w):
    traindata,label=createTrainDataSet()
    dataArr = array(traindata)
    n = shape(dataArr)[0]
    xcord1=[];ycord1=[]
    xcord2=[];ycord2=[]
    for i in range(n):
        if int(label[i])==1:
            xcord1.append(dataArr[i,1])
            ycord1.append(dataArr[i,2])
        else:
            xcord2.append(dataArr[i, 1])
            ycord2.append(dataArr[i, 2])
    fig=plt.figure()
    ax= fig.add_subplot(111)
    ax.scatter(xcord1, ycord1,s=30,c='red',marker='s')
    ax.scatter(xcord2, ycord2,s=30,c='green')
    x = arange(-3.0, 3.0, 0.1)
    y = (-w[0]-w[1] * x)/w[2]
    ax.plot(x, y)
    plt.xlabel('X1'); plt.ylabel('X2')
    plt.show()
def classifyall(datatest,w):
    predict=[]
    for data in datatest:
        result=classify(data,w)
        predict.append(result)
    return predict
def main():
    trainData,label=createTrainDataSet()
    testdata=createTestDataSet()
    w=pla(trainData,label)
    result=classifyall(testdata,w)
    plotBestFit(w)
    print w
    print result
if __name__=='__main__':
    start = time.clock()
    main()
    end = time.clock()
    print('finish all in %s' % str(end - start))</span>
效果图:

技术分享

(2)pocket learning

<span style="font-size:10px;">#encoding:utf-8
from numpy import *
import sklearn
import sklearn.datasets
import matplotlib.pyplot as plt
import matplotlib
import operator
import sklearn.linear_model
import time
def createData(dim=200,cnoise=0.2):
    random.seed(0)
    X,y=sklearn.datasets.make_moons(dim,noise=cnoise)#创造二分类的数据集
    #plt.scatter(X[:,0],X[:,1],s=40,c=y,cmap=plt.cm.Spectral)#cmap里面的参数为一种布局方式,y在此处既代表点的种类,也代表点的颜色,http://matplotlib.org/api/colors_api.html
    num=len(y)
    x_change=ones((200,1))
    X=hstack((x_change,X))
    for i in range(num):
        if y[i]==0:
            y[i]=-1
    return X,y
def sigmoid(X):
    X = float(X)
    if X > 0:
        return 1
    elif X < 0:
        return -1
    else:
        return 0
def classify(inX,w):
    result=sigmoid(sum(w*inX))
    if result>0:
        return 1
    else:
        return -1
def plotBestFit(w):
    traindata,label=createData()
    dataArr = array(traindata)
    n = shape(dataArr)[0]
    w=array(w)
    xcord1=[];ycord1=[]
    xcord2=[];ycord2=[]
    for i in range(n):
        if int(label[i])==1:
            xcord1.append(dataArr[i,1])
            ycord1.append(dataArr[i,2])
        else:
            xcord2.append(dataArr[i, 1])
            ycord2.append(dataArr[i, 2])
    fig=plt.figure()
    ax= fig.add_subplot(111)
    ax.scatter(xcord1, ycord1,s=30,c='red',marker='s')
    ax.scatter(xcord2, ycord2,s=30,c='green')
    x = arange(-3.0, 3.0, 0.1)
    y = (-w[0][0]-w[1][0] * x)/w[2][0]
    ax.plot(x, y)
    plt.xlabel('X1'); plt.ylabel('X2')
    plt.show()
def best(w,w1,traindataIn,trainlabelIn):
    trainData=mat(traindataIn)
    trainlabel=mat(trainlabelIn)
    num=0
    num1=0
    m,n=shape(trainData)
    for i in range(m):
        if(sigmoid(dot(trainData[i],w))!=trainlabel[i]):
            num=num+1
        if(sigmoid(dot(trainData[i],w1))!=trainlabel[i]):
            num1=num1+1
        i=i+1
    if num<num1:#w作为最后的结果错误比较少
        return w
    else:
        return w1
def classifyall(datatest,w):
    predict=[]
    for data in datatest:
        result=classify(data,w)
        predict.append(result)
    return predict
def pla(trainDataIn,trainlabelIn):
    trainData=mat(trainDataIn)
    trainlabel=mat(trainlabelIn).transpose()
    m,n=shape(trainData)
    w=ones((n,1))
    for i in range(100):
        for k in range(m):
            if (sigmoid(dot(trainData[k],w))==trainlabel[k]):
                continue
            else:
                w1=(trainlabel[k]*trainData[k]).transpose()+w
                w=best(w,w1,trainData,trainlabel)
            k=k+1
        i=i+1
    return w
def main():
    trainData,label=createData()
    w=pla(trainData,label)
    plotBestFit(w)
    print w
if __name__=='__main__':
    start = time.clock()
    main()
    end = time.clock()
    print('finish all in %s' % str(end - start))</span>

效果图:
技术分享
(3)嘿嘿,其实不会直接告诉你们sklearn模块里就有现成的函数,不然谁看我的代码啊,啊哈哈哈哈!

<span style="font-size:10px;">#encoding:utf-8
from numpy import *
import sklearn
import sklearn.datasets
import matplotlib.pyplot as plt
import matplotlib
import operator
import sklearn.linear_model
import time
import matplotlib
random.seed(0)
X,y=sklearn.datasets.make_moons(200,noise=0.2)#创造二分类的数据集
plt.scatter(X[:,0],X[:,1],s=40,c=y,cmap=plt.cm.Spectral)#cmap里面的参数为一种布局方式,y在此处既代表点的种类,也代表点的颜色,http://matplotlib.org/api/colors_api.html
clf = sklearn.linear_model.LogisticRegressionCV()
clf.fit(X, y)

# Plot the decision boundary
plt.title("Logistic Regression")
plt.show()</span>

效果图:(盗的图)

技术分享

技术分享
技术分享

台湾大学林轩田教授机器学习基石课程理解及python实现----PLA

标签:

原文地址:http://blog.csdn.net/qq_30537063/article/details/51879081

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!