原文地址:http://www.jianshu.com/p/5b4a64874650

问题描述



程序实现

# coding: utf-8

import numpy as np
import matplotlib.pyplot as plt
import time def read_data(dataFile):
with open(dataFile, 'r') as file:
data_list = []
for line in file.readlines():
line = line.strip().split()
# add x0=1.0
data_list.append([1.0] + [float(l) for l in line])
num_data = len(data_list)
data_array = np.array(data_list)
return (num_data,data_array) def sign(n):
if(n>0):
return 1
else:
return -1 # define PLA class
class PLA(object):
def __init__(self,num_data,data_array,training_epochs=2000,ita=1.0,qID=15):
self.num_data=num_data
self.data_array=data_array
self.training_epochs=training_epochs
self.ita=ita
self.qID=qID def train(self,w=np.zeros([5])):
self.update_counts_list=[]
self.last_error_id_list=[]
for k in range(self.training_epochs):
if self.training_epochs==1:
id_array=np.array([m for m in range(self.num_data)])
else:
np.random.seed(k)
id_array = np.random.permutation([m for m in range(self.num_data)])
update_counts = 0
total_counts = 0
self.w=np.array(w)
id = 0
error_point_id = -1
while (total_counts <= self.num_data):
g = 0
g += np.dot(self.w, self.data_array[id_array[id]][:5])
if sign(g) == self.data_array[id_array[id]][5]:
total_counts += 1
else:
self.w += self.ita*self.data_array[id_array[id]][5] * self.data_array[id_array[id]][:5]
error_point_id = id_array[id]
update_counts += 1
total_counts = 0
id += 1
id = id % self.num_data
self.update_counts_list.append(update_counts)
self.last_error_id_list.append(error_point_id)
return def show_results(self):
print("\n",self.qID,"...")
print("training:")
if self.training_epochs==1:
print("the number of updates: ", self.update_counts_list[0])
print("the final error point id: ", self.last_error_id_list[0])
print("-----------------------")
return
else:
print("the list of update counts: ",self.update_counts_list)
print("the list of last error point id: ",self.last_error_id_list)
print("the average number of updates:", sum(self.update_counts_list) / self.training_epochs)
print("-----------------------")
plt.figure()
plt.hist(self.update_counts_list)
plt.xlabel("the number of updates")
plt.ylabel("frequency")
plt.title(self.qID)
plt.savefig("%s_train.png"%self.qID)
return def total_error_counts(w,data_array,num_data):
total_error_counts=0
for i in range(num_data):
if sign(np.dot(w, data_array[i][:5])) != data_array[i][5]:
total_error_counts+=1
return total_error_counts # define PA class
class PA(PLA):
def __init__(self,num_data,data_array,num_test,test_array,
training_epochs=2000,given_updates=50,ita=1.0,pla_flag=False,qID=18):
PLA.__init__(self,num_data,data_array,training_epochs,ita,qID)
self.num_test=num_test
self.test_array=test_array
self.given_updates=given_updates
self.pla_flag=pla_flag def train_and_test(self,w=np.zeros([5])):
self.last_error_id_list=[]
self.test_error_rate_list=[]
for k in range(self.training_epochs):
# train
if self.training_epochs==1:
id_array=np.array([m for m in range(self.num_data)])
else:
np.random.seed(k)
id_array = np.random.permutation([m for m in range(self.num_data)])
update_counts = 0
id = 0
self.pocket_w = np.array(w) # create a copy of w and give it to self.w
w=np.array(w)
error_point_id = -1
while (update_counts <= self.given_updates):
g = 0
g += np.dot(w, self.data_array[id_array[id]][:5])
if sign(g) != self.data_array[id_array[id]][5]:
w += self.ita*self.data_array[id_array[id]][5] * self.data_array[id_array[id]][:5]
if(self.pla_flag or (total_error_counts(w,self.data_array,self.num_data)<total_error_counts(self.pocket_w,self.data_array,self.num_data))):
self.pocket_w=np.array(w)
error_point_id = id_array[id]
update_counts += 1
id += 1
id = id % self.num_data
self.last_error_id_list.append(error_point_id)
# test
self.test_error_rate_list.append(total_error_counts(self.pocket_w, self.test_array, self.num_test)
/ self.num_test)
return def show_results(self):
print("\n",self.qID,"...")
print("training:")
if self.training_epochs==1:
print("the final error point id: ", self.last_error_id_list[0])
else:
print("the list of last error point id: ",self.last_error_id_list)
print("testing:")
print("the average error rate on test set: ",np.sum(self.test_error_rate_list)/self.training_epochs)
print("-----------------------")
plt.figure()
plt.hist(self.test_error_rate_list)
plt.xlabel("error rate")
plt.ylabel("frequency")
plt.title(self.qID)
plt.savefig("%s_test.png"%self.qID)
return if __name__=="__main__":
num_data,data_array=read_data("hw1_15_train.dat") # 15
pla_15=PLA(num_data,data_array,training_epochs=1,qID=15)
pla_15.train()
pla_15.show_results() # 16
pla_16=PLA(num_data,data_array,qID=16)
pla_16.train()
pla_16.show_results() # 17
pla_17=PLA(num_data,data_array,ita=0.5,qID=17)
pla_17.train()
pla_17.show_results() # 16 else 1
pla_16_1=PLA(num_data,data_array,qID=161)
pla_16_1.train(w=np.array([1.0,0,0,0,0]))
pla_16_1.show_results() # 17 else 1
pla_17_1=PLA(num_data,data_array,ita=0.5,qID=171)
pla_17_1.train(w=np.array([1.0,0,0,0,0]))
pla_17_1.show_results() num_data,data_array=read_data("hw1_18_train.dat")
num_test,test_array=read_data("hw1_18_test.dat") # 18
pa_18=PA(num_data,data_array,num_test,test_array,qID=18)
start = time.time()
pa_18.train_and_test()
end=time.time()
print("total time for train and test of 18: ",end-start," s")
pa_18.show_results() # 19
pa_19=PA(num_data,data_array,num_test,test_array,pla_flag=True,qID=19)
start=time.time()
pa_19.train_and_test()
end=time.time()
print("total time for train and test of 19: ",end-start," s")
pa_19.show_results() # 20
pa_20=PA(num_data,data_array,num_test,test_array,given_updates=100,qID=20)
pa_20.train_and_test()
pa_20.show_results() # 18 else 1
pa_18_1=PA(num_data,data_array,num_test,test_array,qID=181)
pa_18_1.train_and_test(w=np.array([1.0,0,0,0,0]))
pa_18_1.show_results() # 20 else 1
pa_20_1=PA(num_data,data_array,num_test,test_array,given_updates=100,qID=201)
pa_20_1.train_and_test(w=np.array([1.0,0,0,0,0]))
pa_20_1.show_results()

运行结果及分析

15

16



17



对比16与17的结果:

16中步长1.0,17中步长0.5,看似步长对更新次数无影响?

16.1



17.1



对比16.1与17.1的结果:

16.1中步长1.0,17.1中步长0.5,可见步长对更新次数有影响;

再看16 vs 16.1、17 vs 17.1,前者\(W\)初始值[0,0,0,0,0],后者\(W\)初始值[1,0,0,0,0],可见\(W\)初始值对更新次数有影响。

18



19



对比18与19的结果:

可见PA(18)速度明显慢于PLA(19);但在数据线性不可分的情况下,PA表现比PLA好。

20



18.1



20.1



分别对比18与20、18.1与20.1、18与18.1、20与20.1的结果:

结论与PLA处类似,

W初始值、更新步长对分类器表现有影响。

机器学习基石笔记:Homework #1 PLA&PA相关习题的更多相关文章

  1. 机器学习基石笔记:11 Linear Models for Classification

    一.二元分类的线性模型 线性分类.线性回归.逻辑回归: 可视化这三个线性模型的代价函数, SQR.SCE的值都是大于等于0/1的. 理论分析上界: 将回归应用于分类: 线性回归后的参数值常用于pla/ ...

  2. 机器学习基石笔记:11 Linear Models for Classification、LC vs LinReg vs LogReg、OVA、OVO

    原文地址:https://www.jianshu.com/p/6f86290e70f9 一.二元分类的线性模型 线性回归后的参数值常用于PLA/PA/Logistic Regression的参数初始化 ...

  3. 机器学习基石笔记:02 Learning to Answer Yes/No、PLA、PA

    原文地址:https://www.jianshu.com/p/ed0aee74523f 一.Perceptron Learning Algorithm (一)算法原理 PLA本质是二元线性分类算法,即 ...

  4. 机器学习基石笔记:Homework #2 decision stump相关习题

    原文地址:http://www.jianshu.com/p/4bc01760ac20 问题描述 程序实现 17-18 # coding: utf-8 import numpy as np import ...

  5. 机器学习基石笔记:Homework #4 Regularization&Validation相关习题

    原文地址:https://www.jianshu.com/p/3f7d4aa6a7cf 问题描述 程序实现 # coding: utf-8 import numpy as np import math ...

  6. 机器学习基石笔记:Homework #3 LinReg&LogReg相关习题

    原文地址:http://www.jianshu.com/p/311141f2047d 问题描述 程序实现 13-15 # coding: utf-8 import numpy as np import ...

  7. 机器学习基石:Homework #0 SVD相关&常用矩阵求导公式

  8. 机器学习基石笔记:03 Types of Learning

    原文地址:https://www.jianshu.com/p/86b2a9cef742 一.学习的分类 根据输出空间\(Y\):分类(二分类.多分类).回归.结构化(监督学习+输出空间有结构): 根据 ...

  9. 机器学习基石笔记:08 Noise and Error

    噪声:误标.对同一数据点的标注不一致.数据点信息不准确...... 噪声是针对整个输入空间的. 存在噪声的情况下,VC bound依旧有用: 存在噪声,就是f------>p(y|x),f是p的 ...

随机推荐

  1. C#通过文件路径获取文件名小技巧

    string fullPath = @"\WebSite1\Default.aspx"; string filename = System.IO.Path.GetFileName( ...

  2. ansible中的map

    ansible中的filter:   map  ,其实是jinja2中的filter python中 map(func, iter) 返回func与每个元素计算后的迭代器,iter是个可迭代对象 an ...

  3. docker 安装使用 mssql2017

    1.拉取镜像 官方文档参考 : https://docs.microsoft.com/zh-cn/sql/linux/quickstart-install-connect-docker?view=sq ...

  4. PHP左侧菜单栏的管理与实现

    以thinkPHP5.0为例 后台config.php文件里配置 //配置文件设置菜单内容属性 'menu' => [ [ 'name' => '菜单栏1', 'url' => '/ ...

  5. .NET Core on K8S快速入门课程学习笔记

    课程链接:http://video.jessetalk.cn/course/explore 良心课程,大家一起来学习哈! 目录 01-介绍K8s是什么 02-为什么要学习k8s 03-如何学习k8s ...

  6. POSIX-Data Structure

    struct sigevent The <signal.h> header shall define the sigeventstructure, which shall include ...

  7. css边框动画

    <div class="button">hover me to change</div> .button{ width:200px; height:60px ...

  8. 可变参数函数(stdarg.h)的使用

    2013/5/3记录: stdarg.h是C语言中C标准函数库的头文件,stdarg是由standard(标准) arguments(参数)简化而来,主要目的为让函数能够接收可变参数.   stdar ...

  9. git 修改用户名和密码

    初次运行 Git 前的配置 一般在新的系统上,我们都需要先配置下自己的 Git 工作环境.配置工作只需一次,以后升级时还会沿用现在的配置.当然,如果需要,你随时可以用相同的命令修改已有的配置. Git ...

  10. CSS特例定位方式

    同级向下一个元素定位,一个+表示下一个元素,++表格下下个元素 input[name='name1'] +input td:eq(0)表示第一个td元素,此定位方式限于执行js,在selenium时用 ...