Question 15-20 Homework 1 Machine Learning Foundation 机器学习基石 作业一 python code

实现PLA和PLA Pocket。visit example次序是顺序或者random cycle。Question 18 中“visit examples purely randomly”需要循环前先设定一个random cycle,再loop整个random ordered example。我开始的实现是每次random挑一个example,这样error很高,感觉是因为没有保证每个example被visit的次数相同。

import random
import numpy as np


def get_sign(w, x, y):
    weighted_sum = 0
    for j in range(0, len(w)):
        weighted_sum += w[j] * x[j]
    if weighted_sum * y <= 0:
        # print weighted_sum, y
        return False
    return True


def standardPLA():
    x = []
    y = []
    try:
        fin = open("hw1_15_train.dat", 'r')
    except IOError:
        return
    for data in fin:
        data = data.strip("\n")
        data = data.strip("\r")
        items = data.split("\t")
        # print items
        y.append(float(items[1]))
        items2 = items[0].split(" ")
        # print items2
        tmp = [1]
        for i in range(0, len(items2)):
            tmp.append(float(items2[i]))
        x.append(tmp)
        print x[-1], y[-1]
    fin.close()
    # return
    w = [0 for i in range(0, len(x[0]))]
    cnt = 0
    correct_num = 0
    idx = 0
    while True:
        if get_sign(w, x[idx], y[idx]) is False:
            for j in range(0, len(w)):
                w[j] += y[idx] * x[idx][j]
            cnt += 1  # add one correction
            # print w, y[i], cnt
            correct_num = 0
            print cnt
        else:
            correct_num += 1
        idx = (idx + 1) % len(x)
        if correct_num >= len(x):
            print cnt
            break
        # flg = True
        # for i in range(0, len(x)):
        #     if get_sign(w, x[i], y[i]) is False:
        #         for j in range(0, len(w)):
        #             w[j] += y[i] * x[i][j]
        #         cnt += 1  # add one correction
        #         # print w, y[i], cnt
        #         print cnt
        #         flg = False
        # if flg is True:
        #     print cnt
        #     break

def random_cycle_PLA(rate=1.0):
    x = []
    y = []
    try:
        fin = open("hw1_15_train.dat", 'r')
    except IOError:
        return
    for data in fin:
        data = data.strip("\n")
        data = data.strip("\r")
        items = data.split("\t")
        # print items
        y.append(float(items[1]))
        items2 = items[0].split(" ")
        # print items2
        tmp = [1]
        for i in range(0, len(items2)):
            tmp.append(float(items2[i]))
        x.append(tmp)
        print x[-1], y[-1]
    fin.close()
    # return

    cycle = [i for i in range(0, len(x))]
    repeat_num = 2000
    ave_cnt = []
    for rep in range(0, repeat_num):
        w = [0 for i in range(0, len(x[0]))]
        np.random.shuffle(cycle)
        cnt = 0
        correct_num = 0
        idx = 0
        while True:
            if get_sign(w, x[cycle[idx]], y[cycle[idx]]) is False:
                for j in range(0, len(w)):
                    w[j] += rate * y[cycle[idx]] * x[cycle[idx]][j]
                cnt += 1  # add one correction
                # print w, y[i], cnt
                correct_num = 0
                # print cnt
            else:
                correct_num += 1
            idx = (idx + 1) % len(x)
            if correct_num >= len(x):
                print cnt
                ave_cnt.append(cnt)
                break
    print np.mean(ave_cnt)

def load_test_data():
    x = []
    y = []
    try:
        fin = open("hw1_18_test.dat", 'r')
    except IOError:
        return
    for data in fin:
        data = data.strip("\n")
        data = data.strip("\r")
        items = data.split("\t")
        # print items
        y.append(float(items[1]))
        items2 = items[0].split(" ")
        # print items2
        tmp = [1]
        for i in range(0, len(items2)):
            tmp.append(float(items2[i]))
        x.append(tmp)
        # print x[-1], y[-1]
    fin.close()
    return x, y

def test_pocket(w, x, y):
    error = 0
    for i in range(0, len(x)):
        if get_sign(w, x[i], y[i]) is False:
            error += 1
    return 1.0 * error / len(x)

def pocket():
    x = []
    y = []
    try:
        fin = open("hw1_18_train.dat", 'r')
    except IOError:
        return
    for data in fin:
        data = data.strip("\n")
        data = data.strip("\r")
        items = data.split("\t")
        # print items
        y.append(float(items[1]))
        items2 = items[0].split(" ")
        # print items2
        tmp = [1]
        for i in range(0, len(items2)):
            tmp.append(float(items2[i]))
        x.append(tmp)
        print x[-1], y[-1]
    fin.close()
    # return
    test_x, test_y = load_test_data()
    cycle = [i for i in range(0, len(x))]
    repeat_num = 2000
    ave_err = []
    for rep in range(0, repeat_num):
        w = [0 for i in range(0, len(x[0]))]
        w_pocket = [0 for i in range(0, len(x[0]))]
        np.random.shuffle(cycle)
        index = 0
        cnt = 0
        while True:
            # idx = np.random.randint(0, len(x))
            idx = cycle[index]
            if get_sign(w, x[idx], y[idx]) is False:
                for j in range(0, len(w)):
                    w[j] += y[idx] * x[idx][j]
                cnt += 1  # add one correction
                if test_pocket(w, test_x, test_y) < test_pocket(w_pocket, test_x, test_y):
                    w_pocket[:] = w
                # print w, y[i], cnt
                # print cnt
            index = (index + 1) % len(cycle)
            if cnt >= 100:
                # print cnt
                tmp = test_pocket(w_pocket, test_x, test_y)
                # tmp = test_pocket(w, test_x, test_y)
                print rep, tmp
                ave_err.append(tmp)
                break
    print np.mean(ave_err)



if __name__ == '__main__':
    np.random.seed(1111)
    # standardPLA()
    # random_cycle_PLA(0.5)
    pocket()

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值