前言
这是补的昨天的学习内容总结,算下来有两天没更了。那两天,第一天我上午做了一上午实验,晚上开了一晚上的大创组会,收获也颇丰。第二天我码了一点代码,后来发现matlab有工具箱能直接预测,又试了下工具箱,因为内容较为简单,便没有写一篇总结。
现在进度到能实现多元输入一元输出的线性预测模型了,之后做出多元输入一元输出的非线性回归预测就能解决问题了,先结合预测和实际做实验测真实值看看实际效果,效果不好还得再改进。
接下来的一两天我想学一学图像识别,做一做集创赛的东西。
模型选择
拟合能力强模型复杂程度高,容易过拟合。如果限制模型复杂度,降低拟合能力,容易欠拟合。
如何选择模型呢?并不是在训练集上错误率越低越好,往往会导致过拟合,在选择模型时,测试集不可见。
解决方法:引入验证集。将训练集分为两部分,训练集和验证集,在训练集上训练不同模型,选择在验证集上错误最小的模型。
一些准则:赤池信息量准则和贝叶斯信息准则。
赤池信息量准则(英语:Akaike information criterion,简称AIC)是评估统计模型的复杂度和衡量统计模型“拟合”资料之优良性(英语:Goodness of Fit,白话:合身的程度)的一种标准。
在一般的情况下,AIC可以表示为:
其中:K是参数的数量,L是似然函数。
假设条件是模型的误差服从独立正态分布。
让n为观察数,RSS为残差平方和,那么AIC变为:
增加自由参数的数目提高了拟合的优良性,AIC鼓励数据拟合的优良性但是尽量避免出现过度拟合(Overfitting)的情况。
所以优先考虑的模型应是AIC值最小的那一个。赤池信息量准则的方法是寻找可以最好地解释数据但包含最少自由参数的模型。
在统计学当中,贝叶斯信息量准则(英语:Bayesian information criterion或者:Schwarz information criterion;缩写:BIC、SIC、SBC、SBIC)是在有限集合中进行的模型选择准则:BIC最低的模型是最好的。该准则部分基于似然函数并与赤池信息量准则(AIC)紧密相关。
拟合模型时,增加参数可提高似然,但如此下去可能导致过拟合。BIC与AIC都致力于向模型中引入关于参数数量的惩罚项;其中,BIC中的惩罚项会大于AIC中的惩罚项。
深度学习常用定理
没有免费午餐定理
对于基于迭代的最优化算法,不存在某种算法对所有问题都有效,如果一个问题对某些问题有效,那么它一定在另外一些问题上比纯随机搜索算法更差。
奥卡姆剃刀原理
如无必要,勿增实体。假如一个简单模型就能解决的话,没必要引入复杂模型。复杂模型会带来过拟合,计算量过大等问题。
归纳偏置
很多学习算法都会对学习的问题做出一些假设,这些假设称为归纳偏置。在最近邻分类器中,我们会假设在特征空间中,一个小的局部区域中的大部分样本都同属一类。在朴素贝叶斯分类器中,我们会假设每个特征的条件概率是相互独立的。
PAC学习
根据大数定律,当训练集大小趋向无穷时,泛化误差趋向于0,经验风险趋近于期望风险。PAC学习理论可以帮助分析一个机器学习在什么条件下可以学习到一个近似正确的分类器,如果希望模型的假设空间越大,泛化误差越小,需要的样本数越多。
MP理论及代码实现
MP模型
MP是单层感知器,单层多个MP模型并联,可以实现多线性回归问题,通过多层MP模型串联,可以构建多层感知器,解决非线性。
MP的输入和输出都是N维向量,客观上存在一个绝对的函数f,能够建立输入到输出的精准映射。
前馈形式:f的具体表达式
具体计算如下:
激活函数,达到阈值激活。
梯度下降法——局部极小值收敛
梯度下降算法在有些情况下得到的解不是唯一的,取决于初始值, 容易陷入局部收敛。解决这个可以后期找论文。
简单MP模型
只能解决线性回归问题,训练模型如下
单层感知器预测代码如下,能实现多元输入,一元输出的回归预测
# -*- coding = utf-8 -*-
# @Time : 2022/4/12 20:15
# @Author : yeye
# @File : MP.py
# @software: PyCharm
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
#定义函数,读取函数数据
def get_all_data(dataset_path):
all_data = pd.read_csv(dataset_path)
# 单独取两列,实际做时可以去掉,但是是以行向量的形式,需要转成列向量
x_df = all_data[["RM","LSTAT"]].values
x_np = np.array(x_df,dtype=np.float32).reshape(-1,2,1) #生成2*1矩阵
#这里的-1被理解为unspecified value,意思是未指定为给定的。如果我只需要特定的行数,
# 列数多少我无所谓,我只需要指定行数,那么列数直接用-1代替就行了,计算机帮我们算有多少列
y_df = all_data[["PRICE"]].values
y_np = np.array(y_df,dtype=np.float32).reshape(-1,1)
return x_np,y_np
#进行w,b的初始化,可以随便赋值
#有两个自变量,所以w为二维
def initialize():
w = np.array([
[1],
[1]
],dtype=np.float32)
b = np.array([0],dtype=np.float32)
return w,b
def model(w,b,x):
return np.dot(w.T,x) + b #令激活函数f=x,前馈形式退化为y=w.T*x+b,由此计算出y_pre
def loss(y,y_pre):
return np.mean(0.5 * np.power(y-y_pre,2))
#基于loss函数进行梯度下降
def gd(w, b, x, y, lr):
#np.dot(w.T,x) + b -y 生成的是向量,用reshape变成标量
#得到三个梯度
d_w0 = np.dot((np.dot(w.T,x) + b - y).reshape(-1,1).T, x[:,0]).reshape(1) / len(x)
d_w1 = np.dot((np.dot(w.T,x) + b - y).reshape(-1,1).T, x[:,1]).reshape(1) / len(x)
d_b = np.mean(np.dot(w.T,x) + b - y)
#不断更新三个梯度
w[0] = w[0] - lr * d_w0
w[1] = w[1] - lr * d_w1
b = b - lr * d_b
return w,b
def train():
x , y = get_all_data(r"C:\Users\xiaomi\PycharmProjects\bpyuce\dataset\train_dataset.csv")
w , b = initialize()
losses = list()
#进行1000次迭代,梯度下降
for i in range(1000):
y_pre = model(w,b,x)
ls = loss(y,y_pre)
losses.append(losses)
w, b = gd(w, b, x, y, 1e-3)
print("Epoch:{}/{} Loss:{:.4f}".format(i,1000,ls))
print(w, b)
#绘制loss的变化曲线
plt.figure(figsize=(100, 100), dpi=100)
plt.plot(losses)
plt.show()
if __name__=="__main__":
train()