1. 程式人生 > >機器學習基石 作業一

機器學習基石 作業一

機器學習基石 作業一


1-5 省略

  1. 測試N和N+L分別為奇偶的情況。選擇兩個都是向下取整的。
  2. 因為 D D 中對應的N個例子的結果都和 f f
    一樣,因此只有定義域裡剩下的L個x對應的結果會有變化,每個都有兩種情況,因此選擇 2 L 2^{L}
  3. 選擇此項。
    在這裡插入圖片描述
    因為兩個演算法的結果都只對應了一種可能的真實 f
    f
    ,也就是說假設有N種可能的 f f ,每個演算法的結果都有N-1個對應的錯誤情況,且每種情況概率相等。因此對 f f
    求的錯誤率期望相等。這也是No Free Lunch的一種表現,沒有一種演算法的結果一定比另一個好。
  4. 從筐子裡抓小球,每種小球出現概率0.5,抓10個剛好各有5個的概率。選0.24。
  5. 和上題類似,0.39。
  6. 抓10個小球,只有1個或0個目標種類的概率。 9.1 1 0 9 9.1*10^{-9}
  7. 帶入公式即可。 ϵ = 0.8 , N = 10 \epsilon = 0.8, N = 10 。結果是 5.52 1 0 6 5.52*10^{-6}
  8. 橘色1和綠色1概率均為0.5,結果是1/32。
  9. 四種篩子ABCD。1全為橘色篩子只能選BC兩種,2選AC,3選BC,4選AD,5選BD,6選AD。也就是每次的篩子裡只有小於兩種篩子,且篩子為AC,AD,BC,BD四種組合時才可以。對應概率為 4 2 5 / 4 5 4*2^{5}/4^{5} ,其中5個篩子裡只有一種篩子的情況各多算了一次,即結果為 ( 4 2 5 4 ) / 4 5 = 31 / 256 (4*2^{5}-4)/4^{5} = 31/256
import numpy as np
import requests
import pandas as pd

def getData(url):
    content = requests.get(url).content
    content = content.decode('utf-8')
    x = []
    y = []
    content = content.split('\n')
    for line in content[:-1]:
        xs,ys = line.split('\t')
        y.append(int(ys))
        x1 = xs.split(' ')
        for i in range(4):
    	    x1[i] = float(x1[i])
        x.append([1]+x1)
    x = np.array(x)
    y = np.array(y)
    return x,y

def oneIteration(x,y,w,iteration):
	update_num = 0
	for i in range(len(x)):
		mul = np.dot(w,x[i])
		if mul > 0:
			res = 1
		else:
			res = -1
		if res != y[i]:
			w += y[i]*x[i]
			update_num += 1
	print("update",update_num,"times in",iteration,"iteration")
	return update_num

def PLA():
    url = 'https://www.csie.ntu.edu.tw/~htlin/mooc/datasets/mlfound_math/hw1_15_train.dat'
    x,y = getData(url)
    w = np.array([0,0,0,0,0],dtype=float)
    iteration = 1
    while(oneIteration(x,y,w,iteration) != 0):
    	iteration += 1
    print("update finished!")

if __name__ == '__main__':
	PLA()

import numpy as np
import requests
import pandas as pd
import random

def getData(url):
    content = requests.get(url).content
    content = content.decode('utf-8')
    x = []
    y = []
    content = content.split('\n')
    for line in content[:-1]:
        xs,ys = line.split('\t')
        y.append(int(ys))
        x1 = xs.split(' ')
        for i in range(4):
            x1[i] = float(x1[i])
        x.append([1]+x1)
    x = np.array(x)
    y = np.array(y)
    return x,y

def oneRandomIteration(x,y,w,iteration):
    update_num = 0
    indexs = list(range(len(x)))
    random.shuffle(indexs)
    for i in indexs:
        mul = np.dot(w,x[i])
        if mul > 0:
            res = 1
        else:
            res = -1
        if res != y[i]:
            w += 0.5*y[i]*x[i]
            update_num += 1
    print("update",update_num,"times in",iteration,"iteration")
    return update_num

def PLA():
    url = 'https://www.csie.ntu.edu.tw/~htlin/mooc/datasets/mlfound_math/hw1_15_train.dat'
    x,y = getData(url)
    all_update_sum = 0
    for t in range(2000):
        w = np.array([0,0,0,0,0],dtype=float)
        iteration = 1
        update_sum = 0
        update_num = oneRandomIteration(x,y,w,iteration)
        while(update_num != 0):
            update_sum += update_num
            iteration += 1
            update_num = oneRandomIteration(x,y,w,iteration)
        all_update_sum += update_sum
        print("time:",t,"update finished!")
    print("average update number is",all_update_sum/2000)

if __name__ == '__main__':
    PLA()

這裡我實現的時候有個卡殼的地方造成了死迴圈。就是實現pocket PLA的時候,尋找錯誤樣本使用的是一直在更新的係數 w 1 w1 而不是當前最好係數 w w

而且 w 1 w1 是一直在更新的,只不過是當它錯誤率更低的時候存為新的 w w 而已。我實現時錯誤理解了演算法,以為是在 w w 的基礎上只進行一次更新之後就和 w w 繼續比較,這是不對的, w 1 w1 一直在更新。

import numpy as np
import requests
import pandas as pd
import random

def getData(url):
    content = requests.get(url).content
    content = content.decode('utf-8')
    x = []
    y = []
    content = content.split('\n')
    for line in content[:-1]:
        xs,ys = line.split('\t')
        y.append(int(ys))
        x1 = xs.split(' ')
        for i in range(4):
            x1[i] = float(x1[i])
        x.append([1]+x1)
    x = np.array(x)
    y = np.array(y)
    return x,y

def pocketIteration(x,y,w,times):
    update_num = 0
    indexs = list(range(len(x)))
    w1 = w
    while times > 0:
        random.shuffle(indexs)
        for i in indexs:
            res = sign(w1,x[i])
            if res != y[i]:
                w1 = w1 + y[i]*x[i]
                times -= 1
                error1 = verification(x,y,w1)
                error0 = verification(x,y,w)
                if error0 > error1:
                    w = w1
            if times == 0:
                break
        print("remain",times,"times update!")
        if times == 0:
            break
    return w

def verification(x,y,w):
    len_of_x = len(x)
    error_num = 0
    for i in range(len_of_x):
        res = sign(w,x[i])
        if res != y[i]:
            error_num += 1
    #print("error rate:",error_num)
    return error_num/len_of_x

def sign(w,x):
    mul = np.dot(w,x)
    if mul > 0:
        return 1
    else:
        return -1

def PLA():
    train_url = 'https://www.csie.ntu.edu.tw/~htlin/mooc/datasets/mlfound_math/hw1_18_train.dat'
    test_url = 'https://www.csie.ntu.edu.tw/~htlin/mooc/datasets/mlfound_math/hw1_18_test.dat'
    train_x,train_y = getData(train_url)
    test_x,test_y = getData(test_url)
    
    error_rate_sum = 0
    for t in range(2000):
        w = np.array([0,0,0,0,0],dtype=float)
        w = pocketIteration(train_x,train_y,w,100)
        error_rate_sum += verification(test_x,test_y,w)
        print("time:",t,"update finished!")
    print("average error rate is",error_rate_sum/2000)

if __name__ == '__main__':
    PLA()