机器学习基础(一)

机器学习

Overview

机器学习其实就是一种最优化问题——给定约束,最优化目标函数。简单来讲,在机器学习中,基于已知数据,假设数据之间存在某种关联,我们想要尽可能接近地找到这种关联。在这里,约束就是已知数据,目标函数则为“模型”和“真实”的差距。从数学的角度,这个问题可以这样表述:

  • 假设我们的模型可以表示为F_{\mathbf{w}}(\mathbf{x})
  • F可以是任意的函数,\mathbf{w}是参数向量,有些地方也把它叫做权重(weights),因为假如F是一个线性模型,\mathbf{w}就是权重一个直观的表示。总之叫参数也好,系数或者权重也好,表达的都是一个东西,只是叫法不同。
  • 此外我们定义一个合理的损失函数Loss Function:L(\mathbf{x},F_{\mathbf{w}}(\mathbf{x})) \rightarrow \mathbb{R}。损失函数表示“模型”和“真实”的差距。在确定模型表达形式后,我们的目标实际上就是找到权重向量,使得期望损失达到最小:
    {\underset {\mathbf{w}}{\operatorname {arg\,min} }}\,E[L(\mathbf{x},F_{\mathbf{w}}(\mathbf{x}))]

监督学习(Supervised Learning)

  • 在监督学习下,我们有一组训练集,训练集中数据可分为输入(input)\mathbf{x}和输出(output)\mathbf{y}。假设\mathbf{y}\mathbf{x}之间存在某个函数关系F使得\mathbf{y}=F(\mathbf{x})+\epsilon。也就是说,我们可以通过某一种方式,输入\mathbf{x}后可以得到\mathbf{y}

  • 因此,监督学习的问题可以表示为最小化期望损失:
    {\underset {\mathbf{w}}{\operatorname {arg\,min} }}\,E[L(\mathbf{x},\mathbf{y},F_{\mathbf{w}}(\mathbf{x}))]

  • 其中L(\mathbf{x},\mathbf{y},F_{\mathbf{w}}(\mathbf{x})) \rightarrow \mathbb{R}为损失函数。

  • 假设我们不存在训练集,没有输入输出数据,这个问题也就被一般化为无监督学习(Unsupervised Learning)。

Recall:统计学模型——最小二乘估计(OLS)

当我们做OLS线性回归模型时,给定因变量\mathbf{y}和自变量\mathbf{x},我们可以得到线性模型:
\mathbf{y} = \mathbf{w}^{T}\mathbf{x} + \mathbf{\epsilon}

其中
\begin{equation} \mathbf{y} = \begin{bmatrix} y_{1}\\ y_{2} \\ \vdots \\ y_{n} \\ \end{bmatrix} , \space \mathbf{x} = \begin{bmatrix} 1 & x_{11} & x_{12} & \cdots & x_{1m}\\ 1 & x_{21} & x_{22} & \cdots & x_{2m} \\ \vdots & \vdots & & & \vdots \\ 1 & x_{n1} & x_{n2} & \cdots & x_{nm} \\ \end{bmatrix} , \space \mathbf{w} = \begin{bmatrix} w_{1}\\ w_{2} \\ \vdots \\ w_{m} \end{bmatrix} , \space \mathbf{\epsilon} = \begin{bmatrix} \epsilon_{1}\\ \epsilon_{2} \\ \vdots \\ \epsilon_{n} \end{bmatrix} \end{equation}

该问题的的目标是最小化残差平方和(RSS):

{\underset {\mathbf{w}}{\operatorname {arg\,min} }}\,\sum_{i=1}^{n}\epsilon_i^2 = \sum_{i=1}^{n}\big(y_i - \mathbf{w}^{T}x_i\big)^2
得到:
\hat{\mathbf{w}} = (\mathbf{x}^{T}\mathbf{x})^{-1}\mathbf{x}^{T}\mathbf{y}

其实这也是一个简单的机器学习问题:

  • 损失函数:L(\mathbf{x},\mathbf{y},\mathbf{w}) = \sum_{i=1}^{n}\big(y_i - \mathbf{w}^{T}x_i\big)^2
  • 模型:F_{\mathbf{w}}(\mathbf{x}) = \mathbf{w}^{T}\mathbf{x}

机器学习的简单实践

  • 我们假设F_{\mathbf{w}}(\mathbf{x}) = \mathbf{w}^{T}\mathbf{x} = x^2 + 2x + 3
  • 此时\mathbf{w} = [1,2,3]^T\mathbf{x} = [x^2, x, 1]^T
  • 理论上\mathbf{y}\mathbf{x}存在基于以上形式的二次关系。
  • 我们现在随机生成一组数据$:
import numpy as np
import matplotlib.pyplot as plt
import scipy.optimize as opt

def F(x):
    return x**2 + 2*x + 3
xs = np.random.uniform(-6, 4, 20)
ys = [F(x) + np.random.normal(0,2) for x in xs]
data = (xs, ys)

我们看看随机生成的点的分布情况

domain = np.linspace(-6,4,50)
fig, ax = plt.subplots(figsize = (8,6))
ax.plot(domain, F(domain), label='Theoretical Model')
ax.scatter(xs, ys, c='r', marker='x', label='Data')
plt.legend()
output_13_1.png

现在我们不知道原本的函数关系,只已知这些数据,怎么去拟合这个函数?这就是机器学习中的一个简单问题。

fig, ax = plt.subplots(figsize = (8,6))
ax.scatter(xs, ys, c='r', marker='x', label='Data')
plt.legend()
output_15_1.png

函数F_{\mathbf{w}}(\mathbf{x})我们可以假设成任意的形式,因为基于泰勒展开原理,任何一个函数都可以展开成一个多项式的形式。因此我们函数的也理所当然地从多项式开始入手,可以是一次,可以是二次甚至更高次。

def F_hat_o1(x, w): 
    (a, b) = w
    return a*x + b

def F_hat_o2(x, w): 
    (a, b, c) = w
    return a*x**2 + b*x + c

def F_hat_o4(x, w): 
    (a, b, c, d, e) = w
    return a*x**4 + b*x**3 + c*x**2 + d*x + e

定义损失函数:

def L(w):
    predicted_data = np.array([F_hat(x, w) for x in data[0]])
    training_data = np.array(data[1])
    return np.sum((training_data - predicted_data) ** 2)

一阶:

initial_weights = [0., 0.]
F_hat = F_hat_o1
final_weights = opt.minimize(L, initial_weights)
weights_o1 = final_weights.x
print(weights_o1)
[ 0.46082929 10.87317174]

二阶:

initial_weights = [0., 0., 0.]
F_hat = F_hat_o2
final_weights = opt.minimize(L, initial_weights)
weights_o2 = final_weights.x
print(weights_o2)
[0.99123066 1.94480201 2.41571896]

四阶:

initial_weights = [0., 0., 0., 0., 0.]
F_hat = F_hat_o4
final_weights = opt.minimize(L, initial_weights)
weights_o4 = final_weights.x
print(weights_o4)
[-0.0155209  -0.05878026  1.28288611  2.52211275  1.32693671]
def F_hat(x, weights, order):
    xs = np.array([x**i for i in range(order,-1,-1)])
    weights = np.array(weights)
    y_hat = np.sum(np.array(xs.T*weights.T), axis=1)
    return y_hat
F_o1 = lambda x: F_hat(x, weights_o1, 1)
F_o2 = lambda x: F_hat(x, weights_o2, 2)
F_o4 = lambda x: F_hat(x, weights_o4, 4)
domain = np.linspace(-6,4,50)
fig, ax = plt.subplots(figsize = (8,6))
ax.plot(domain, F(domain), label='Theoretical Model')
ax.plot(domain, F_o1(domain), label='1st order')
ax.plot(domain, F_o2(domain), label='2nd order')
ax.plot(domain, F_o4(domain), label='4th order')
ax.scatter(xs, ys, c='r', marker='x', label='Data')
plt.legend()
output_29_1.png

虽然4阶的模型能够让数据点更紧密地落在曲线上,但实际上因为阶数过高而过拟合了,效果并没有二阶模型好。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
禁止转载,如需转载请通过简信或评论联系作者。

相关阅读更多精彩内容

友情链接更多精彩内容