{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "经过前面的学习，我们来看一个使用线性回归解决真实问题的实例：使用线性回归检测水泥质量（[案例来源](https://www.ibm.com/developerworks/cn/analytics/library/ba-lo-machine-learning-cement-quality/index.html)）。\n",
    "\n",
    "已知类似于下面这样的水泥成分样本数据，如何得到一个水泥质量预测模型，能预测出水泥的好坏？\n",
    "\n",
    "![](../images/cement.png)\n",
    "\n",
    "其中，每一行代表一个样本，1-7 列是每立方米混合物中各个成分的重量（单位：千克），第 8 列是已使用天数，第 9 列 是该行水泥样本的强度（单位：MPa）。前 8 列 是水泥的输入属性，最后 1 列是输出，我们要让机器学习这些样本后得到一个模型，这个模型可以输入样本表格之外的数据，预测出水泥的强度。很显然，这是一个回归问题。\n",
    "\n",
    "我们假设该模型为线性模型，用线性回归去解决该问题，我们可以使用正规方程法或梯度下降法，上文中采用的是梯度下降法。\n",
    "\n",
    "不过在计算之前，我们观察到部分这样的样本数据：\n",
    "\n",
    "![](../images/cement-2.png)\n",
    "\n",
    "可以发现不同维度的数值范围差异会很大，塑化剂维度和粗粒料的维度值范围分别是 10 左右和 1000 多 ，如此大的差异如果用梯度下降，会使得不同方向的下降速度差异很大，迭代算法可能收敛得很慢甚至不收敛。如果直接将该样本送入训练，会使目标函数的形状太\"扁\"，在找到最优解前，梯度下降的过程不仅是曲折的，也是非常耗时的，如下面图 3 所示，如果特征差异太大，就会像左图一样，在求最优解时，会得到一个窄长的椭圆形，导致在梯度下降时，梯度的方向为垂直等高线的方向而走之字形路线，这样会使迭代很慢；而如果特征差异不大，如右图会形成一个近似的圆形，则迭代就会很快。\n",
    "\n",
    "![](../images/cement-3.png)\n",
    "\n",
    "所以如果求解使用迭代算法，需要在计算前把不同的特征缩放到同一个范围内，比如控制在 [-1 1] 内。这个特征数据缩放的过程就是数据归一化。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 标准化和归一化\n",
    "\n",
    "在实际的运用中我们选取的特征，比如长度，重量，面积等等，通常单位和范围都不同，这会导致梯度下降算法变慢，所以我们要将特征缩放到相对统一的范围内。通常的方法有 **标准化（Standardization）** 和 **归一化（Normalization）**。\n",
    "\n",
    "标准化是把数据变成符合标准的正态分布，由 **中心极限定理** 可知，当数据量足够大时，无论原来的数据是何种分布，都可以通过下面的更新公式转变成正态分布：\n",
    "\n",
    "$$\n",
    "x_i := \\frac{x_i-\\mu}{\\delta}\n",
    "$$\n",
    "\n",
    "归一化对梯度下降算法很友好，可以让算法最终收敛并且提高训练速度和精度，归一化的更新公式为：\n",
    "\n",
    "$$\n",
    "x_i := \\frac{x_i-min(x_i)}{max(x_i)-min(x_i)}\n",
    "$$"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
