方差代价函数 : 知错
时间:2023-2-27 23:17 作者:wen 分类: AI
我们如何评估误差?
你的第一反应可能是: 差值呗.
标准答案和预测答案两者一减就是误差, 这样好吗?
这样不好, 我们举个极端且简明的例子, 假设样本只有两个豆豆, 第一个豆豆误差是0.15, 第二个的是-0.15, 所以预测曲线在这两个豆豆上的总体误差是0, 难道这就是完美预测? 很明显不是, 这就是用差值评估预测误差的问题, 差值有正负, 所以相互之间会发生抵消作用. 机智如你, 肯定立马想到用差值的绝对值, 因为面对误差, 比较标准大0.15和小0.15,其实和标准答案的差距都是0.15, 我们并不关心正负, 不错, 是一个方法, 用绝对值处理的误差叫做"绝对差", 但是绝对差在数学处理和编码上都不是很方便, 于是人们提出了另一个更好的误差评估方式, 把差值取个平方, 正负号就消失了, 这个误差也就是所谓的平方误差.
很明显, 我们对一批豆豆预测的结果和标准答案之间的平方误差越小, 说明偏离事实越小, 小蓝的思考越接近真相. 而我们知道实际上参数w决定了预测函数的样子, 换句话说, 每次w取不同的值, 产生的误差也会不同, 如果我们把误差和w之间的关系画出来, 他是一个开头向上的抛物线, 正是一个开口向上的一元二次函数!
怎么证明它是一个开口向上的一元二次函数?
其实很简单, 研究一组豆豆太麻烦了, 不如我们先看一个豆豆, 大小是0.4, 毒性是0.68, 那么小蓝的预测是: y=w*0.4
误差是: e=(0.68-w*0.4)
e = 0.16w2+(-0.544)w+0.4624
你看这不就是一个标准的一元二次函数吗? w是自变量, e是因变量 a = 0.16 , b=-0.544, c=0.4624, e=aw2+b2+c, 非常标准的一个开口向上的一元二次函数,
多个豆豆, 我们一般用一个求和符号表示整体误差:e=(1/m)∑(xi2w2+(-2xiyi)w+yi2), 当然, 这时候因为去的是平方误差的评价值, 所以我们也称e为均方误差. 同样一件事情, 引入一个符号就变得更加简洁了. 大家不必害怕这个求和符号, 它只是在说一件事情, 面对许多数据, 我们只需把单个的误差求出来, 再全部加起来平均一下, 这既是预测函数再整体样本上的误差
样本只有一个, 也就是求和中的m=1, 实际上样本数量m不论等于几, 这个均方误差e和w的关系都会形成一个开口向上的抛物线, 当我们知道不同的w取值对误差的影响之后, 接下来的事情就很简单了, 我们需要让机器自己找寻这个开口向上的抛物线的最低点, 此处, 恰是误差最小的点, 但是, 对于没有接触过, 或者已经忘却概率和统计相关知识的同学们, 在这里有必要和大家说明一点点数学上的事情, 一开始我们猜想一个w, 然后统计出大量数据(大小和毒性), 去评估我们的w到底合不合适, 这实际及时数学统计学里重要的一个分支----回归分析, 而我们的评估标准是"均方误差", 并试图然他最小, 也就是回归分析中的"最小二乘法", 此时此刻, 如果我们把函数看作处理问题的机器, 那么事情从原先的向机器输入数据, 得到结果变成了 用很多观察到的数据去评估这个歌函数机器到底是否在行, , 原先的自变量x和因变量y变成了从环境中观测到的大量已知数据, 而我们把w作为自变量, 误差e作为因变量, 也就形成了一个新的函数----代价函数(cost function), 这个所谓的"代价函数"展现出当参数w取不同的值的时候, 对环境中问题数据预测时产生不同的误差e, 而利用这个"代价函数"的最低点的w值, 把它放回预测函数中, 这时候预测函数也就很好完成了对数据的拟合.
如果一开始w是0.1距离合适的最低点还有一段距离, 那么究竟如何让机器自己把w向最低点挪动呢?
这个问题并不难, 用初中数学足矣, 最低点很明显是这个抛物线的顶点, 我们自然可以用抛物线的顶点坐标公式来求, 一次性求解出让误差最小的w取值的方法, 也就是所谓的"正规方程"了, w = xiyi/xi2 ,这种方法它合适吗?
当样本数量少的时候它很合适, 但是众所周知, 机器学习往往需要处理海量的数据, 这种一步到位的方式就意味着巨大的计算量和存储量, 这时候事情就开始起了变化, 我们来算一笔账, 比如我们有一百万条样本数据, 每个数据用一个单精度浮点型数表示, 那么在正规方程中, 比如分母部分, 就要运行一百万次乘法和加法浮点运算, 而在后面的学习中, 实际上输入x在实际应用中往往不会是只有一个特征数值, 更一般的情况是一个多维的向量, 比如1000个维度, 那么这个运行的次数就是10亿次, 而在现代神经网络中为了加快运算的速度, 一般都会采用并行计算的方式, 也就是说一次性把她们都计算出来, 这更够劲啊~, 那么接下来, 我们来看一种更加常用的方法, 梯度下降.
# dataset.py 样本数据获取
import numpy as np
def get_beans(counts):
xs = np.random.rand(counts)
xs = np.sort(xs)
ys = [1.2 * x + np.random.rand() / 10 for x in xs]
return xs, ys
# const_function.py
# 方差代价函数
# 数据量少时一步到位, 数据量多时非常消耗计算资源
import dataset
import matplotlib.pyplot as plt
import numpy as np
m = 100
xs, ys = dataset.get_beans(m)
# 正规方程
# 抛物线的顶点坐标公式得出代价函数最低值的求解 就是误差最小
w_min = np.sum(xs * ys) / np.sum(xs * xs)
# 预测数据
y_pre = w_min * xs
# 配置图像
plt.title('Size-Toxicity Function', fontsize=12) # 设置图像名称
plt.xlabel("Bean Size") # 设置横坐标的名字
plt.ylabel("Toxicity") # 设置纵坐标的名字
plt.scatter(xs, ys)
plt.plot(xs, y_pre)
plt.show()
# 代价函数
# y = w*x0
# e0 = (y0-w+x0)**2
# e0= x0**2 * w**2 + (-2x0*y0) +y0**2
# 预估均方误差
es = (ys - y_pre) ** 2
# 求和
sum_e = np.sum(es)
# 平均误差
sum_e = (1 / m) * sum_e
print(sum_e)
# 生产一个0-3,步进为0.1的数组
ws = np.arange(0, 3, .1)
es = []
for w in ws:
y_pre = w * xs
# 平均误差函数
e = (1 / m) * np.sum((ys - y_pre) ** 2)
# print('w:' + str(w) + " e:" + str(e))
es.append(e)
# 配置图像
plt.title('cost Function', fontsize=12) # 设置图像名称
plt.xlabel("w") # 设置横坐标的名字
plt.ylabel("e") # 设置纵坐标的名字
plt.plot(ws, es)
plt.show()
标签: 人工智能