文章目录

  • 线性回归
    • 1.1 专栏介绍
    • 1.2 单变量线性回归
      • 1.2.1 模型表示
      • 1.2.2 代价函数
      • 1.2.3 梯度下降法
    • 1.3 多变量线性回归
      • 1.3.1 多维特征
      • 1.3.2 多元梯度下降
      • 1.3.3 特征缩放
      • 1.3.4 关于学习率
      • 1.3.5 特征与多项式回归
      • 1.3.6 正规方程
    • 1.4 配套作业的Python实现
      • 1.4.1 单变量线性回归
      • 1.4.2 多变量线性回归
      • 1.4.3 正规方程
      • 1.4.4 线性回归的scikit-learn实现

线性回归

1.1 专栏介绍

  本专栏学习材料为吴恩达《机器学习》课程,希望自学吴恩达的课程后通过自己的语言对算法进行描述且加强自己对模型的理解,后续在本科课程系统学习机器学习课程后,会对自学的笔记进行修改和补充,同时希望大神们及时批评与指正。

1.2 单变量线性回归

1.2.1 模型表示

课程中吴恩达老师以房屋交易问题为例,训练集如图所示:

我们希望通过这些数据来预测房价,我们需要对一些符号进行定义。

符号 意义
mmm 训练集中实例个数
xxx 特征/输入变量
yyy 目标/输出变量
(x,y)(x, y)(x,y) 训练集中的实例
(x(i),y(i))(x^{(i)}, y^{(i)})(x(i),y(i)) 第iii个实例
hhh 学习算法的解决方案/假设

因为本例中的特征只有房屋大小,价格暂时只考虑与房屋大小有关,所以称此模型为单变量线性回归,而我们对数据的处理方法大概如下所示。

#mermaid-svg-LrqNgoAQxXrwrFdn .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-LrqNgoAQxXrwrFdn .label text{fill:#333}#mermaid-svg-LrqNgoAQxXrwrFdn .node rect,#mermaid-svg-LrqNgoAQxXrwrFdn .node circle,#mermaid-svg-LrqNgoAQxXrwrFdn .node ellipse,#mermaid-svg-LrqNgoAQxXrwrFdn .node polygon,#mermaid-svg-LrqNgoAQxXrwrFdn .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-LrqNgoAQxXrwrFdn .node .label{text-align:center;fill:#333}#mermaid-svg-LrqNgoAQxXrwrFdn .node.clickable{cursor:pointer}#mermaid-svg-LrqNgoAQxXrwrFdn .arrowheadPath{fill:#333}#mermaid-svg-LrqNgoAQxXrwrFdn .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-LrqNgoAQxXrwrFdn .flowchart-link{stroke:#333;fill:none}#mermaid-svg-LrqNgoAQxXrwrFdn .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-LrqNgoAQxXrwrFdn .edgeLabel rect{opacity:0.9}#mermaid-svg-LrqNgoAQxXrwrFdn .edgeLabel span{color:#333}#mermaid-svg-LrqNgoAQxXrwrFdn .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-LrqNgoAQxXrwrFdn .cluster text{fill:#333}#mermaid-svg-LrqNgoAQxXrwrFdn div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-LrqNgoAQxXrwrFdn .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-LrqNgoAQxXrwrFdn text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-LrqNgoAQxXrwrFdn .actor-line{stroke:grey}#mermaid-svg-LrqNgoAQxXrwrFdn .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-LrqNgoAQxXrwrFdn .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-LrqNgoAQxXrwrFdn #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-LrqNgoAQxXrwrFdn .sequenceNumber{fill:#fff}#mermaid-svg-LrqNgoAQxXrwrFdn #sequencenumber{fill:#333}#mermaid-svg-LrqNgoAQxXrwrFdn #crosshead path{fill:#333;stroke:#333}#mermaid-svg-LrqNgoAQxXrwrFdn .messageText{fill:#333;stroke:#333}#mermaid-svg-LrqNgoAQxXrwrFdn .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-LrqNgoAQxXrwrFdn .labelText,#mermaid-svg-LrqNgoAQxXrwrFdn .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-LrqNgoAQxXrwrFdn .loopText,#mermaid-svg-LrqNgoAQxXrwrFdn .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-LrqNgoAQxXrwrFdn .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-LrqNgoAQxXrwrFdn .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-LrqNgoAQxXrwrFdn .noteText,#mermaid-svg-LrqNgoAQxXrwrFdn .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-LrqNgoAQxXrwrFdn .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-LrqNgoAQxXrwrFdn .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-LrqNgoAQxXrwrFdn .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-LrqNgoAQxXrwrFdn .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-LrqNgoAQxXrwrFdn .section{stroke:none;opacity:0.2}#mermaid-svg-LrqNgoAQxXrwrFdn .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-LrqNgoAQxXrwrFdn .section2{fill:#fff400}#mermaid-svg-LrqNgoAQxXrwrFdn .section1,#mermaid-svg-LrqNgoAQxXrwrFdn .section3{fill:#fff;opacity:0.2}#mermaid-svg-LrqNgoAQxXrwrFdn .sectionTitle0{fill:#333}#mermaid-svg-LrqNgoAQxXrwrFdn .sectionTitle1{fill:#333}#mermaid-svg-LrqNgoAQxXrwrFdn .sectionTitle2{fill:#333}#mermaid-svg-LrqNgoAQxXrwrFdn .sectionTitle3{fill:#333}#mermaid-svg-LrqNgoAQxXrwrFdn .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-LrqNgoAQxXrwrFdn .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-LrqNgoAQxXrwrFdn .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-LrqNgoAQxXrwrFdn .grid path{stroke-width:0}#mermaid-svg-LrqNgoAQxXrwrFdn .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-LrqNgoAQxXrwrFdn .task{stroke-width:2}#mermaid-svg-LrqNgoAQxXrwrFdn .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-LrqNgoAQxXrwrFdn .taskText:not([font-size]){font-size:11px}#mermaid-svg-LrqNgoAQxXrwrFdn .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-LrqNgoAQxXrwrFdn .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-LrqNgoAQxXrwrFdn .task.clickable{cursor:pointer}#mermaid-svg-LrqNgoAQxXrwrFdn .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-LrqNgoAQxXrwrFdn .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-LrqNgoAQxXrwrFdn .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-LrqNgoAQxXrwrFdn .taskText0,#mermaid-svg-LrqNgoAQxXrwrFdn .taskText1,#mermaid-svg-LrqNgoAQxXrwrFdn .taskText2,#mermaid-svg-LrqNgoAQxXrwrFdn .taskText3{fill:#fff}#mermaid-svg-LrqNgoAQxXrwrFdn .task0,#mermaid-svg-LrqNgoAQxXrwrFdn .task1,#mermaid-svg-LrqNgoAQxXrwrFdn .task2,#mermaid-svg-LrqNgoAQxXrwrFdn .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-LrqNgoAQxXrwrFdn .taskTextOutside0,#mermaid-svg-LrqNgoAQxXrwrFdn .taskTextOutside2{fill:#000}#mermaid-svg-LrqNgoAQxXrwrFdn .taskTextOutside1,#mermaid-svg-LrqNgoAQxXrwrFdn .taskTextOutside3{fill:#000}#mermaid-svg-LrqNgoAQxXrwrFdn .active0,#mermaid-svg-LrqNgoAQxXrwrFdn .active1,#mermaid-svg-LrqNgoAQxXrwrFdn .active2,#mermaid-svg-LrqNgoAQxXrwrFdn .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-LrqNgoAQxXrwrFdn .activeText0,#mermaid-svg-LrqNgoAQxXrwrFdn .activeText1,#mermaid-svg-LrqNgoAQxXrwrFdn .activeText2,#mermaid-svg-LrqNgoAQxXrwrFdn .activeText3{fill:#000 !important}#mermaid-svg-LrqNgoAQxXrwrFdn .done0,#mermaid-svg-LrqNgoAQxXrwrFdn .done1,#mermaid-svg-LrqNgoAQxXrwrFdn .done2,#mermaid-svg-LrqNgoAQxXrwrFdn .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-LrqNgoAQxXrwrFdn .doneText0,#mermaid-svg-LrqNgoAQxXrwrFdn .doneText1,#mermaid-svg-LrqNgoAQxXrwrFdn .doneText2,#mermaid-svg-LrqNgoAQxXrwrFdn .doneText3{fill:#000 !important}#mermaid-svg-LrqNgoAQxXrwrFdn .crit0,#mermaid-svg-LrqNgoAQxXrwrFdn .crit1,#mermaid-svg-LrqNgoAQxXrwrFdn .crit2,#mermaid-svg-LrqNgoAQxXrwrFdn .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-LrqNgoAQxXrwrFdn .activeCrit0,#mermaid-svg-LrqNgoAQxXrwrFdn .activeCrit1,#mermaid-svg-LrqNgoAQxXrwrFdn .activeCrit2,#mermaid-svg-LrqNgoAQxXrwrFdn .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-LrqNgoAQxXrwrFdn .doneCrit0,#mermaid-svg-LrqNgoAQxXrwrFdn .doneCrit1,#mermaid-svg-LrqNgoAQxXrwrFdn .doneCrit2,#mermaid-svg-LrqNgoAQxXrwrFdn .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-LrqNgoAQxXrwrFdn .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-LrqNgoAQxXrwrFdn .milestoneText{font-style:italic}#mermaid-svg-LrqNgoAQxXrwrFdn .doneCritText0,#mermaid-svg-LrqNgoAQxXrwrFdn .doneCritText1,#mermaid-svg-LrqNgoAQxXrwrFdn .doneCritText2,#mermaid-svg-LrqNgoAQxXrwrFdn .doneCritText3{fill:#000 !important}#mermaid-svg-LrqNgoAQxXrwrFdn .activeCritText0,#mermaid-svg-LrqNgoAQxXrwrFdn .activeCritText1,#mermaid-svg-LrqNgoAQxXrwrFdn .activeCritText2,#mermaid-svg-LrqNgoAQxXrwrFdn .activeCritText3{fill:#000 !important}#mermaid-svg-LrqNgoAQxXrwrFdn .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-LrqNgoAQxXrwrFdn g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-LrqNgoAQxXrwrFdn g.classGroup text .title{font-weight:bolder}#mermaid-svg-LrqNgoAQxXrwrFdn g.clickable{cursor:pointer}#mermaid-svg-LrqNgoAQxXrwrFdn g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-LrqNgoAQxXrwrFdn g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-LrqNgoAQxXrwrFdn .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-LrqNgoAQxXrwrFdn .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-LrqNgoAQxXrwrFdn .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-LrqNgoAQxXrwrFdn .dashed-line{stroke-dasharray:3}#mermaid-svg-LrqNgoAQxXrwrFdn #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-LrqNgoAQxXrwrFdn #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-LrqNgoAQxXrwrFdn #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-LrqNgoAQxXrwrFdn #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-LrqNgoAQxXrwrFdn #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-LrqNgoAQxXrwrFdn #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-LrqNgoAQxXrwrFdn #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-LrqNgoAQxXrwrFdn #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-LrqNgoAQxXrwrFdn .commit-id,#mermaid-svg-LrqNgoAQxXrwrFdn .commit-msg,#mermaid-svg-LrqNgoAQxXrwrFdn .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-LrqNgoAQxXrwrFdn .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-LrqNgoAQxXrwrFdn .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-LrqNgoAQxXrwrFdn g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-LrqNgoAQxXrwrFdn g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-LrqNgoAQxXrwrFdn g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-LrqNgoAQxXrwrFdn g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-LrqNgoAQxXrwrFdn g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-LrqNgoAQxXrwrFdn g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-LrqNgoAQxXrwrFdn .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-LrqNgoAQxXrwrFdn .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-LrqNgoAQxXrwrFdn .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-LrqNgoAQxXrwrFdn .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-LrqNgoAQxXrwrFdn .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-LrqNgoAQxXrwrFdn .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-LrqNgoAQxXrwrFdn .edgeLabel text{fill:#333}#mermaid-svg-LrqNgoAQxXrwrFdn .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-LrqNgoAQxXrwrFdn .node circle.state-start{fill:black;stroke:black}#mermaid-svg-LrqNgoAQxXrwrFdn .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-LrqNgoAQxXrwrFdn #statediagram-barbEnd{fill:#9370db}#mermaid-svg-LrqNgoAQxXrwrFdn .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-LrqNgoAQxXrwrFdn .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-LrqNgoAQxXrwrFdn .statediagram-state .divider{stroke:#9370db}#mermaid-svg-LrqNgoAQxXrwrFdn .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-LrqNgoAQxXrwrFdn .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-LrqNgoAQxXrwrFdn .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-LrqNgoAQxXrwrFdn .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-LrqNgoAQxXrwrFdn .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-LrqNgoAQxXrwrFdn .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-LrqNgoAQxXrwrFdn .note-edge{stroke-dasharray:5}#mermaid-svg-LrqNgoAQxXrwrFdn .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-LrqNgoAQxXrwrFdn .error-icon{fill:#522}#mermaid-svg-LrqNgoAQxXrwrFdn .error-text{fill:#522;stroke:#522}#mermaid-svg-LrqNgoAQxXrwrFdn .edge-thickness-normal{stroke-width:2px}#mermaid-svg-LrqNgoAQxXrwrFdn .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-LrqNgoAQxXrwrFdn .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-LrqNgoAQxXrwrFdn .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-LrqNgoAQxXrwrFdn .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-LrqNgoAQxXrwrFdn .marker{fill:#333}#mermaid-svg-LrqNgoAQxXrwrFdn .marker.cross{stroke:#333}:root { --mermaid-font-family: "trebuchet ms", verdana, arial;}#mermaid-svg-LrqNgoAQxXrwrFdn {color: rgba(0, 0, 0, 0.75);font: ;}

数据集
学习算法
h 假设函数
输入
输出

在此例中,我们该如何选择hhh呢?
因为该例只有一个特征,即房屋尺寸大小,所以我们可将假设函数设为
hθ(x)=θ0+θ1xh_\theta(x) = \theta_0 +\theta_1x hθ​(x)=θ0​+θ1​x
hhh表示一个函数,输入的是房屋的尺寸大小,hhh 根据输入的 xxx 值来得出 yyy 值,yyy 值对应房屋出售价格,因此,hhh 是一个从 xxx 到 yyy 的函数映射。

1.2.2 代价函数

  在设计假设函数 hθ(x)=θ0+θ1xh_\theta(x) = \theta_0 +\theta_1xhθ​(x)=θ0​+θ1​x 的过程也是直线拟合散点图的过程。确定假设函数也就是我们需要选择合适的 θ0\theta_0θ0​ 与 θ1\theta_1θ1​ ,也就是图像上直线的截距与斜率。我们选择的参数决定了我们得到的直线相对于我们的训练集的准确程度,模型预测值与实际值的差距也就是建模误差。

  我们的目标便是选择出可以使得建模误差的平方和能够最小的模型参数。在这里我们命名一种代价函数来表示模型误差。
minimizeJ(θ0,θ1)=12m∑i=1m(hθ(x(i))−y(i))2minimize\quad J(\theta_0,\theta_1)=\frac{1}{2m}\sum_{i=1}^m(h_\theta(x^{(i)})-y^{(i)})^2 minimizeJ(θ0​,θ1​)=2m1​i=1∑m​(hθ​(x(i))−y(i))2
  代价函数又叫平方误差函数,解决回归问题,平方误差函数是一种常用手段。我们可以编程将参数θ0\theta_0θ0​ 、 θ1\theta_1θ1​与代价函数JJJ的关系可视化。

  可以看出,会有一组参数 (θ0,θ1)(\theta_0, \theta_1)(θ0​,θ1​) 使得 JJJ 处于最低点,也就是我们希望的误差最小的参数对。幸运的是,可以通过数学证明线性回归的代价函数总为凸函数,需要用到引理:二阶可微函数为严格凸函数的充要条件为黑塞矩阵为正定矩阵,因此我们总能在线性回归的代价函数找到唯一的极小值点。接下来我们需要探索一种可以自动找到最佳参数的方法。

1.2.3 梯度下降法

  梯度下降是一个用来求函数最小值的算法,我们会用该算法对本例假设函数进行最小化处理。该算法的思想大致为:首先随机选择一个参数组合(θ0,θ1,…,θn)(\theta_0, \theta_1, …, \theta_n)(θ0​,θ1​,…,θn​),计算代价函数,接着寻找下一个能让代价函数下降最多的参数组合,直到找到局部最低点为止。而我们不能确定该局部最低点是否为全局最低点,且不同的初始参数组合可能会有不同的局部最低点。

批量梯度下降(batch gradient descent)算法的公式为:
repeatuntilconvergence:θj=θj−α⋅∂∂θjJ(θ0,θ1)(forj=0andj=1)repeat\ until\ convergence:\\ \theta_j = \theta_j -\alpha \cdot \frac{\partial }{\partial \theta_j}J(\theta_0, \theta_1)(for\ j=0 \ and\ j=1) repeat until convergence:θj​=θj​−α⋅∂θj​∂​J(θ0​,θ1​)(for j=0 and j=1)
  其中 α\alphaα 为学习率,它决定代价函数下降程度最大方向向下迈出的步子有多大。在批量梯度下降中,我们每一次迭代让所有参数减去学习率乘代价函数的导数,直至 θ\thetaθ 收敛。
注意: 我们需要同时更新所有参数 θ\thetaθ

temp0=θ0−α⋅∂∂θ0J(θ0,θ1)temp0 = \theta_0 -\alpha \cdot \frac{\partial}{\partial \theta_0}J(\theta_0,\theta_1)temp0=θ0​−α⋅∂θ0​∂​J(θ0​,θ1​)
temp1=θ1−α⋅∂∂θ1J(θ0,θ1)temp1 = \theta_1 -\alpha \cdot \frac{\partial}{\partial \theta_1}J(\theta_0,\theta_1)temp1=θ1​−α⋅∂θ1​∂​J(θ0​,θ1​)
θ0=temp0\theta_0 = temp0θ0​=temp0
θ1=temp1\theta_1 = temp1θ1​=temp1

  我们对 α\alphaα 有一定要求,若 α\alphaα 过大,可能导致其无法收敛甚至发散,若 α\alphaα 过小,则收敛速度会很慢。若已到达局部极值点,∂∂θJ(θ0,θ1)=0\frac{\partial}{\partial \theta}J(\theta_0,\theta_1)=0∂θ∂​J(θ0​,θ1​)=0,θ\thetaθ不再改变。
  让我们把梯度下降法利用在线性回归上,则有如下公式:
repeatuntilconvergence:θ0=θ0−α⋅1m∑i=1m(hθ(x(i))−y(i))θ1=θ1−α⋅1m∑i=1m[(hθ(x(i))−y(i))⋅x(i)]updateθ0andθ1simultaneouslyrepeat\ until\ convergence:\\ \theta_0 = \theta_0 -\alpha \cdot \frac{1}{m}\sum_{i=1}^m(h_\theta(x^{(i)})-y^{(i)})\\ \theta_1 = \theta_1 -\alpha \cdot \frac{1}{m}\sum_{i=1}^m[(h_\theta(x^{(i)})-y^{(i)})\cdot x^{(i)}]\\ update\ \theta_0 \ and\ \theta_1\ simultaneously repeat until convergence:θ0​=θ0​−α⋅m1​i=1∑m​(hθ​(x(i))−y(i))θ1​=θ1​−α⋅m1​i=1∑m​[(hθ​(x(i))−y(i))⋅x(i)]update θ0​ and θ1​ simultaneously

1.3 多变量线性回归

1.3.1 多维特征

  目前为止,我们探讨了单变量特征房屋大小对房价的影响,然而实际上有更多的特征会对房价造成影响,我们需要构建一个含有多个特征变量的模型,模型特征为(x1,x2,x3,…,xn)(x_1,x_2,x_3,…,x_n)(x1​,x2​,x3​,…,xn​),我们有新的训练集如下:

  同样地,我们需要对新的符号进行定义

符号 意义
nnn 特征数量
x(i)x^{(i)}x(i) 第iii个训练实例向量
xj(i)x^{(i)}_jxj(i)​ 第iii个训练实例的第jjj个特征

  此时支持多变量的假设函数hhh为:
hθ(x)=θ0+θ1x1+θ2x2+…+θnxnh_\theta(x)=\theta_0+\theta_1x_1+\theta_2x_2+…+\theta_nx_n hθ​(x)=θ0​+θ1​x1​+θ2​x2​+…+θn​xn​
  这个公式有n+1个参数和n个变量,为了使公式更加简单,我们可以引入新变量 x0=1x_0=1x0​=1 ,则公式转化为:
hθ(x)=θ0x0+θ1x1+θ2x2+…+θnxnh_\theta(x)=\theta_0x_0+\theta_1x_1+\theta_2x_2+…+\theta_nx_n hθ​(x)=θ0​x0​+θ1​x1​+θ2​x2​+…+θn​xn​
  此时模型中的参数 θ\thetaθ 是一个n+1维向量,而训练实例 xxx 也是n+1维向量,有如下表示:
θ=[θ0θ1θ2…θn]\theta= \begin{bmatrix} \theta_0\\ \theta_1\\ \theta_2\\ …\\ \theta_n \end{bmatrix} θ=⎣⎢⎢⎢⎢⎡​θ0​θ1​θ2​…θn​​⎦⎥⎥⎥⎥⎤​
X=[x0x1x2…xm]X= \begin{bmatrix} x_0\\ x_1\\ x_2\\ …\\ x_m\\ \end{bmatrix} X=⎣⎢⎢⎢⎢⎡​x0​x1​x2​…xm​​⎦⎥⎥⎥⎥⎤​
  故假设函数 hhh 可简化为:
hθ(x)=θTXh_\theta(x)=\theta^TX hθ​(x)=θTX
  其中上标T表示矩阵转置.

1.3.2 多元梯度下降

  与单变量线性回归类似,在多变量线性回归中,我们同样构建一个代价函数,则这个代价函数是所有建模误差的平方和,即:
minimizeJ(θ0,θ1,…,θn)=12m∑i=1m(hθ(x(i))−y(i))2minimize\quad J(\theta_0,\theta_1,…,\theta_n)=\frac{1}{2m}\sum_{i=1}^m(h_\theta(x^{(i)})-y^{(i)})^2 minimizeJ(θ0​,θ1​,…,θn​)=2m1​i=1∑m​(hθ​(x(i))−y(i))2
其中 hθ(x)=θTX=θ0+θ1x1+θ2x2+…+θnxnh_\theta(x)=\theta^TX=\theta_0+\theta_1x_1+\theta_2x_2+…+\theta_nx_nhθ​(x)=θTX=θ0​+θ1​x1​+θ2​x2​+…+θn​xn​.
  我们的目标与单变量线性回归时一样,找到使得代价函数最小的参数。多变量线性回归的算法为:
repeatuntilconvergence:θj=θj−α⋅1m∑i=1m(hθ(x(i))−y(i))⋅x(i)simultaneouslyupdateθjforj=0,1,…,nrepeat\ until\ convergence:\\ \theta_j=\theta_j-\alpha\cdot \frac{1}{m}\sum_{i=1}^m(h_\theta(x^{(i)})-y^{(i)})\cdot x^{(i)}\\ simultaneously\ update\ \theta_j \ for \ j=0,1,…,n repeat until convergence:θj​=θj​−α⋅m1​i=1∑m​(hθ​(x(i))−y(i))⋅x(i)simultaneously update θj​ for j=0,1,…,n
  注意上式的 jjj 从0开始,因为我们引入了 x0=1x_0=1x0​=1 ,使得算法对每一个参数 θ\thetaθ 都成立.

1.3.3 特征缩放

  在我们面对多维特征问题的时候,我们要保证这些特征都具有相近的尺度,这将帮助梯度下降算法更快地收敛。
  以房价问题为例,假设我们使用两个特征,房屋的尺寸和房间的数量,尺寸的值为 0-2000 平方英尺,而房间数量的值则是 0-5,两个特征绝对值取值差异非常的大,以两个参数分别为横纵坐标,绘制代价函数的等高线图能,看出图像会显得很扁,梯度下降算法需要非常多次的迭代才能收敛。
  我们解决的方法为尽量使得每个特征的取值范围为-1到1之间.

  更一般的情况,我们会利用标准差标准化公式:
xn=xn−μnsnx_n=\frac{x_n-\mu_n}{s_n} xn​=sn​xn​−μn​​
  其中 μn\mu_nμn​ 为平均值,sns_nsn​为标准差.

1.3.4 关于学习率

  我们不能提前预知梯度下降法的迭代次数,但可以通过可视化,找到代价函数 J(θ)J(\theta)J(θ) 与 迭代次数的关系,帮助我们判断是否接近收敛。我们希望代价函数 J(θ)J(\theta)J(θ) 在每一次迭代后都会下降。
  与此同时,有一种可自动判断收敛的方法,即如果代价函数 J(θ)J(\theta)J(θ) 在一次迭代后下降少于ε\varepsilonε,则其收敛。这种方法的 ε\varepsilonε 较小,比如10−310^{-3}10−3,但因 ε\varepsilonε 不好取值,因此可视化判断收敛程度更佳。
  在单变量线性回归中,我们讨论过学习率对于梯度下降收敛的影响,如果 α\alphaα 过小,则达到收敛所需要的迭代次数会非常高;若 α\alphaα 过大,每次迭代可能不会减小代价函数,可能会越过局部最小值导致无法收敛。
  通常可以尝试一些学习率:0.01,0.03,0.1,0.3,1,3……

1.3.5 特征与多项式回归

  有时候训练集给出的特征并不能很好地表现出与目标变量的影响,需要我们自己处理过后得到新的特征变量来描述关系。比如房价预测问题中,训练集给出房子的长度和宽度两个特征,不如直接用其乘积得到面积来体现与房价的关系,从而减少参数也更加直接。使得原本的假设函数hθ(x)=θ0+θ1⋅width+θ2⋅lengthh_\theta(x)=\theta_0 + \theta_1\cdot width+\theta_2\cdot lengthhθ​(x)=θ0​+θ1​⋅width+θ2​⋅length
变为

hθ(x)=θ0+θ1⋅areah_\theta(x)=\theta_0 + \theta_1\cdot areahθ​(x)=θ0​+θ1​⋅area
  有时线性回归并不适用于所有数据,有时更需要曲线来进行拟合,此时可以利用多项式回归这一思想,比如用二次函数来拟合。通常我们需要先可视化观察散点图后再判断准备用什么模型去尝试,之后对该模型进行转换,可化为线性模型。

  同样地,我们仍以房屋大小为特征变量,房价为目标变量为例。当我们想用三次函数模型时,可以令x0=1,x1=x,x2=x2,x3=x3x_0=1,x_1=x,x_2=x^2,x_3=x^3x0​=1,x1​=x,x2​=x2,x3​=x3,这样就又化为我们的线性回归模型。
  根据训练集所构建的散点图,我们还可以使:
hθ(x)=θ0+θ1⋅size+θ2⋅sizeh_\theta(x)= \theta_0+\theta_1\cdot size+\theta_2\cdot \sqrt{size} hθ​(x)=θ0​+θ1​⋅size+θ2​⋅size​
注意:在多项式回归时,我们利用平方关系、立方关系作为新的特征变量,此时变量取值差异十分明显,应更注重特征缩放这一环节。

1.3.6 正规方程

  我们之前在寻找最合适的参数 θ\thetaθ 时,所用的算法是梯度下降法,但在有的时候有一种叫做正规方程的方法可以不需要迭代更快地解出 θ\thetaθ.
  正规方程法通过求解∂∂θJ(θ)=0\frac{\partial}{\partial \theta}J(\theta)=0∂θ∂​J(θ)=0,得到合适的 θ\thetaθ.假设我们的训练集特征矩阵为 XXX (包含了x0=1x_0=1x0​=1),目标向量为 yyy,则利用正规方程解出向量
θ=(XTX)−1XTy\theta = (X^TX)^{-1}X^Ty θ=(XTX)−1XTy
  我们对此进行以下简单推导:
由已知可得,J(θ)=12m∑i=1m(hθ(x(i))−y(i))2其中,hθ(x)=θTX=θ0x0+θ1x1+…+θnxn由已知可得,J(\theta)=\frac{1}{2m}\sum_{i=1}^{m}(h_\theta(x^{(i)})-y^{(i)})^2 \\ 其中,h_\theta(x)=\theta^TX=\theta_0x_0+\theta_1x_1+…+\theta_nx_n \\ 由已知可得,J(θ)=2m1​i=1∑m​(hθ​(x(i))−y(i))2其中,hθ​(x)=θTX=θ0​x0​+θ1​x1​+…+θn​xn​
  将标量形式转化为矩阵形式,有
J(θ)=12m(Xθ−y)2=12m(Xθ−y)T(Xθ−y)=12m(θTXT−yT)(Xθ−y)=12m(θTXTXθ−θTXTy−yTXθ+yTy)\begin{alignedat}{1} J(\theta) &=\frac{1}{2m}(X\theta - y)^2\\ &=\frac{1}{2m}(X\theta - y)^T(X\theta - y)\\ &=\frac{1}{2m}(\theta^TX^T-y^T)(X\theta - y)\\ &=\frac{1}{2m}(\theta^TX^TX\theta-\theta^TX^Ty-y^TX\theta+y^Ty) \end{alignedat} J(θ)​=2m1​(Xθ−y)2=2m1​(Xθ−y)T(Xθ−y)=2m1​(θTXT−yT)(Xθ−y)=2m1​(θTXTXθ−θTXTy−yTXθ+yTy)​
  接下来对 J(θ)J(\theta)J(θ) 求偏导,需要用到以下矩阵求导法则
dABdB=ATdBTAdB=AdxTAxdx=(A+AT)x\begin{alignedat}{1} \frac{dAB}{dB}&=A^T\\ \frac{dB^TA}{dB}&=A\\ \frac{dx^TAx}{dx}&=(A+A^T)x \end{alignedat} dBdAB​dBdBTA​dxdxTAx​​=AT=A=(A+AT)x​
  利用以上法则,继续对 J(θ)J(\theta)J(θ) 求偏导,且令其为0
∂J(θ)∂θ=12m(2XTXθ−XTy−XTy−0)=1m(XTXθ−XTy)=0\begin{alignedat}{1} \frac{\partial J(\theta)}{\partial\theta}&=\frac{1}{2m}(2X^TX\theta-X^Ty-X^Ty-0)\\ &=\frac{1}{m}(X^TX\theta-X^Ty)\\ &=0 \end{alignedat} ∂θ∂J(θ)​​=2m1​(2XTXθ−XTy−XTy−0)=m1​(XTXθ−XTy)=0​
  解得
θ=(XTX)−1XTy\theta = (X^TX)^{-1}X^Ty θ=(XTX)−1XTy
  关于矩阵求导公式及原理,可浏览其他博主的文章,本文便不再详述。可以看出,正规方程法对小数据集处理起来是非常快捷有效的。让我们将梯度下降与正规方程二者做个对比。

梯度下降法 正规方程法
需考虑特征缩放 不需要
需要选择学习率 α\alphaα 不需要
需要多次迭代 不需要
当特征数量 nnn 较大时仍有效 需要计算 (XTX)−1(X^TX)^{-1}(XTX)−1,nnn 较大时计算时间成本高,求逆时间复杂度为O(n3)O(n^3)O(n3),一般 n<10000n<10000n<10000可以接受
适用于各种模型 只适用于线性模型,逻辑回归等不适用

  除此之外,还需要注意一点:如果 XTXX^TXXTX 不可逆,这种情况一般很少发生,那么有可能是因为训练集内有相似特征变量或者训练集内特征变量过多(比如n>mn>mn>m),对于前者我们需要保证特征变量的线性无关性,后者可以删除一些特征或者使用正则化方法来找到参数。而且在Octave中的pinv()可以求解矩阵的伪逆,一样可以求解参数 θ\thetaθ.

1.4 配套作业的Python实现

1.4.1 单变量线性回归

1. 问题背景:
  假如你是一个连锁餐厅的CEO,已有不同城市的人口与利润数据集(ex1data1.txt),第一列为人口,第二列为利润,请你使用一个变量实施线性回归来预测连锁餐厅利润。
2. 代码实现:

  导入所需要的包

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

  导入数据集,一定要把数据文件ex1data1.txt放在和程序同一个文件夹里,否则需要使用绝对路径访问文件

path = 'ex1data1.txt'
data = pd.read_csv(path, header=None, names=['Population', 'Profit'])
print(data.head())  # 预览数据

print(data.describe())


  数据可视化,绘制散点图
  可利用matplotlib库将Dataframe转为数组后plt.scatter

data_x = data["Population"].values
data_y = data["Profit"].values
plt.figure(figsize=(12,8))
plt.scatter(data_x, data_y)
plt.xlabel("Population")
plt.ylabel("Profit")
plt.show()

  也可以直接用Pandas直接作图

data.plot(kind="scatter", x="Population", y="Profit", figsize=(12, 8))
plt.show()


  梯度下降法,以实现最小化代价函数。首先需要创建代价函数J(θ0,θ1)=12m∑i=1m(hθ(x(i))−y(i))2J(\theta_0,\theta_1)=\frac{1}{2m}\sum_{i=1}^m(h_\theta(x^{(i)})-y^{(i)})^2J(θ0​,θ1​)=2m1​i=1∑m​(hθ​(x(i))−y(i))2

def compute_cost(X, y, theta):inner = np.power((X * theta.T)-y, 2)cost = np.sum(inner)/(2*len(X))return cost

  函数设计思路:因为hθ(x)=θ0+θ1xh_\theta(x) = \theta_0 +\theta_1xhθ​(x)=θ0​+θ1​x,可利用矩阵形式批量计算误差后平方累和最后除以2倍样本数。这里的矩阵形式是因为theta的维度是一个(1,2)的行向量,而y是(97,1)的列向量,因此需要把theta取转置。
  由前文可知,引入x0=1x_0=1x0​=1后将更方便利用矩阵处理代价函数与梯度,因此我们需要在DataFrame中引入该列。

data.insert(0, 'Ones', 1)

  创建好代价函数之后,我们需要处理DataFrame中的数据,使其可以直接传入compute_cost中,也就是得到所需的X,y,theta。

cols = data.shape[1]
X = data.iloc[:, 0:cols-1]  # X是所有行,去掉最后一列
y = data.iloc[:, cols-1:cols]  # y是所有行,最后一列
print(X.head())
print(y.head())

  我们利用切片处理数据时记得检查是否该数据是我们所需要的。

  检查完毕后,将这些Pandas数据类型转化为可传入函数的矩阵类型。

X = np.matrix(X.values)
y = np.matrix(y.values)
theta = np.matrix(np.array([0, 0]))

  转化完毕后可查看各矩阵的维度是否满足传入函数的条件。

print(X.shape, y.shape, theta.shape)

(97, 2) (97, 1) (1, 2)

  可以看出,果然与前文描述的一样,y为列向量,theta为行向量需要在函数内转置才可运算。接下来便可执行compute_cost函数,观察在
θ0=0,θ1=0\theta_0=0,\ \theta_1=0θ0​=0, θ1​=0 的条件下的代价函数值。

print(compute_cost(X, y, theta))

32.072733877455676

  接下来是批量梯度下降的代码实现,是本节最重要的知识之一。
repeatuntilconvergence:θj=θj−α⋅1m∑i=1m(hθ(x(i))−y(i))⋅x(i)simultaneouslyupdateθjforj=0,1,…,nrepeat\ until\ convergence:\\ \theta_j=\theta_j-\alpha\cdot \frac{1}{m}\sum_{i=1}^m(h_\theta(x^{(i)})-y^{(i)})\cdot x^{(i)}\\ simultaneously\ update\ \theta_j \ for \ j=0,1,…,n repeat until convergence:θj​=θj​−α⋅m1​i=1∑m​(hθ​(x(i))−y(i))⋅x(i)simultaneously update θj​ for j=0,1,…,n

def gradientDescent(X, y, theta, alpha, iters):temp = np.matrix(np.zeros(theta.shape))parameters = int(theta.ravel().shape[1])cost = np.zeros(iters)for i in range(iters):error = (X * theta.T) - yfor j in range(parameters):term = np.multiply(error, X[:, j])temp[0, j] = theta[0, j] - alpha / len(X) * np.sum(term)theta = tempcost[i] = compute_cost(X, y, theta)return theta, cost

  这里运用到的temp变量是为了保证每个 θ\thetaθ 同时更新,先把算出来的 θj\theta_jθj​存起来,再把它们一起赋值给theta向量。细心的读者可以发现,这个批量梯度下降算法实际上可以直接处理多变量线性回归问题。接着,我们需要初始化学习率与迭代次数。

alpha = 0.01
iters = 1000

  最后让我们用梯度下降算法得到最新的参数 θ\thetaθ.

new_theta, cost = gradientDescent(X, y, theta, alpha, iters)
print(new_theta)

[[-3.24140214 1.1272942 ]]

3. 可视化
  得到迭代出的参数 θ\thetaθ 后,便可以将线性模型可视化在散点图中观察拟合效果。

x = np.linspace(data.Population.min(), data.Population.max(), 100)
f = new_theta[0, 0] + (new_theta[0, 1] * x)fig, ax = plt.subplots(figsize=(12, 8))
ax.plot(x, f, 'r', label='Prediction')
ax.scatter(data.Population, data.Profit, label='Traning Data')
ax.legend(loc=2)
ax.set_xlabel('Population')
ax.set_ylabel('Profit')
ax.set_title('Predicted Profit vs. Population Size')
plt.show()


  有了结果之后,自然还可以做很多有意思的检验,做很多有趣的可视化,比如代价函数值随迭代次数的变化,观察学习率 α\alphaα 是否设置合理,是否每一次迭代后都有所下降以及其收敛程度。

fig, ax = plt.subplots(figsize=(12,8))
ax.plot(np.arange(iters), cost, 'r')
ax.set_xlabel('Iterations')
ax.set_ylabel('Cost')
ax.set_title('Error vs. Training Epoch')
plt.show()


  还可以作出不同参数 θ\thetaθ 对代价函数的影响的三维图与等高线图。

theta_0 = np.linspace(-10, 10, 50)
theta_1 = np.linspace(-1, 4, 50)
Theta_0, Theta_1 = np.meshgrid(theta_0, theta_1)
Cost = np.zeros((50, 50))
for i in range(len(theta_0)):for j in range(len(theta_1)):Theta = np.matrix([theta_0[i], theta_1[j]])Cost[j][i] = compute_cost(X, y, Theta)
ax = plt.axes(projection='3d')
ax.plot_surface(Theta_0, Theta_1, Cost, cmap="viridis")
ax.set_xlabel("$\\theta_0$")
ax.set_ylabel("$\\theta_1$")
ax.set_zlabel("$J(\\theta)$")
plt.show()

theta_0 = np.linspace(-10, 10, 100)
theta_1 = np.linspace(-1, 4, 100)
[Theta_0, Theta_1] = np.meshgrid(theta_0, theta_1)
print(Theta_1)
Cost = np.zeros((100, 100))
for i in range(len(theta_0)):for j in range(len(theta_1)):Theta = np.matrix([theta_0[i], theta_1[j]])Cost[j, i] = compute_cost(X, y, Theta)
plt.contour(Theta_0, Theta_1, Cost, np.linspace(5, 20, 5))
plt.xlabel("$\\theta_0$")
plt.ylabel("$\\theta_1$")
plt.scatter(new_theta[0, 0], new_theta[0, 1], marker="x")
plt.show()

1.4.2 多变量线性回归

1. 问题背景

  你想要卖你的房子,你想知道什么是好的市场价格。我们收集了最近售出房屋的信息,实现一个多变量线性回归的模型。数据集为ex1data2.txt,里面包含了俄勒冈州波特兰市的房价信息,其中第一列为房子的大小(以平方英尺为单位),第二列为卧室数,第三列为房价。

2. 代码实现

  此问与第一问不同的是,该数据集的特征有两个,为多变量线性回归问题。我们依然选择使用批量梯度下降算法来解决该问题。首先仍是导入数据集ex1data2.txt.

path = 'ex1data2.txt'
data2 = pd.read_csv(path, header=None, names=['Size', 'Bedrooms', 'Price'])
print(data2.head())


  观察该数据集,我们很容易发现上文提到的特征缩放问题,卧室数与房价的范围差距太大了,因此我们需要对该数据集进行数据预处理——特征归一化。

data2 = (data2 - data2.mean()) / data2.std()
print(data2.head())


  现在我们重复第一问单变量线性回归的步骤,对数据进行预处理。

data2.insert(0, 'Ones', 1)
cols = data2.shape[1]
X2 = data2.iloc[:, 0:cols-1]
y2 = data2.iloc[:, cols-1:cols]
X2 = np.matrix(X2.values)
y2 = np.matrix(y2.values)
theta2 = np.matrix(np.array([0, 0, 0]))

  同样地应用批量梯度下降算法,得到合适的 θ\thetaθ 与 J(θ)minJ(\theta)_{min}J(θ)min​.

alpha = 0.01
iters = 1000
new_theta2, cost2 = gradientDescent(X2, y2, theta2, alpha, iters)
print(compute_cost(X2, y2, new_theta2))
print(new_theta2)

0.1307033696077189
[[-1.10910099e-16 8.78503652e-01 -4.69166570e-02]]

3. 可视化

  同样地,我们也可以将训练进程可视化。

fig, ax = plt.subplots(figsize=(12,8))
ax.plot(np.arange(iters), cost2, 'r')
ax.set_xlabel('Iterations')
ax.set_ylabel('Cost')
ax.set_title('Error vs. Training Epoch')
plt.show()

1.4.3 正规方程

  对此问题我们依然使用第二问数据集ex1data2.txt.正规方程为
θ=(XTX)−1XTy\theta = (X^TX)^{-1}X^Ty θ=(XTX)−1XTy

def normalEqn(X, y):theta = np.linalg.inv(X.T@X)@X.T@yreturn theta
final_theta = normalEqn(X2, y2)
print(final_theta.T)

[[-1.10910099e-16 8.78503652e-01 -4.69166570e-02]] # 梯度下降
[[-1.11022302e-16 8.84765988e-01 -5.31788197e-02]] # 正规方程

  可以发现,梯度下降的结果与正规方程有一定差距,原因可能是迭代次数不够等等。

1.4.4 线性回归的scikit-learn实现

  我们利用第一问的数据集ex1data1.txt,使用scikit-learn库实现。

from sklearn import linear_model
model = linear_model.LinearRegression()
model.fit(X, y)x = np.array(X[:, 1].A1)
f = model.predict(X).flatten()fig, ax = plt.subplots(figsize=(12,8))
ax.plot(x, f, 'r', label='Prediction')
ax.scatter(data.Population, data.Profit, label='Traning Data')
ax.legend(loc=2)
ax.set_xlabel('Population')
ax.set_ylabel('Profit')
ax.set_title('Predicted Profit vs. Population Size')
plt.show()


  以上,便是DS的machine learning学习笔记的第一节:线性回归的全部内容,由于是自学吴恩达课程,会有不严谨甚至错误的地方,欢迎大家指出。在本科系统学习《机器学习》课程后会对该节进行修改更新。下一节内容为逻辑回归。

【机器学习】DS的基础学习笔记1:线性回归相关推荐

  1. 【Python】DS的基础学习笔记7:文件、异常和模块

    文章目录 文件.异常和模块 7.1 文件的读写 7.1.1 文件的打开 1. 文件路径 2. 打开模式 3. 字符编码 7.1.2 文件的读取 1. 读取整个内容--f.read() 2. 逐行进行读 ...

  2. 【Python】DS的基础学习笔记3:组合数据类型

    文章目录 组合数据类型 3.1 列表 3.1.1 列表的表达 3.1.2 列表的性质 3.1.3 列表的操作符 3.1.4 列表的操作方法 1 增加元素 2 删除元素 3 查找元素 4 修改元素 5 ...

  3. 【Python】DS的基础学习笔记2:基本数据类型

    文章目录 基本数据类型 2.1 数字类型 2.1.1 数字类型的组成 1 整数--不同进制的转换 2 浮点数--不确定性 3 复数--a+bj 2.1.2 数字运算操作符(a 操作符 b) 2.1.3 ...

  4. 百度飞桨2021李宏毅机器学习特训营学习笔记之回归及作业PM2.5预测

    百度飞桨2021李宏毅机器学习特训营学习笔记之回归及作业PM2.5预测 前言 回归 什么是回归(Regression)? 怎么做回归? 线性回归(Linear Regression) 训练集与验证集 ...

  5. 机器学习框架ML.NET学习笔记【1】基本概念与系列文章目录

    一.序言 微软的机器学习框架于2018年5月出了0.1版本,2019年5月发布1.0版本.期间各版本之间差异(包括命名空间.方法等)还是比较大的,随着1.0版发布,应该是趋于稳定了.之前在园子里也看到 ...

  6. Python基础学习笔记之(一)

    Python基础学习笔记之(一) zouxy09@qq.com http://blog.csdn.net/zouxy09 前段时间参加微软的windows Azure云计算的一个小培训,其中Pytho ...

  7. 数据挖掘学习笔记 5 线性回归知识及预测糖尿病实例

    #2018-03-21 16:45:01 March Wednesday the 12 week, the 080 day SZ SSMR http://blog.csdn.net/eastmount ...

  8. 8. SpringBoot基础学习笔记

    SpringBoot基础学习笔记 课程前置知识说明 1 SpringBoot基础篇 1.1 快速上手SpringBoot SpringBoot入门程序制作 1.2 SpringBoot简介 1.2.1 ...

  9. 【1】机器学习实战peter Harrington——学习笔记

    机器学习实战peter Harrington--学习笔记 综述 数据挖掘十大算法 本书结构 一.机器学习基础 1.1 机器学习 1.2 关键术语 1.3 机器学习主要任务 1.4 如何选择合适的算法 ...

最新文章

  1. C#编程总结--总目录
  2. 第二批重磅嘉宾已就位,邀你共探AI行业新机遇 | MEET2022智能未来大会
  3. iOS控件之UILabel
  4. 虽然现在没有闲也没有钱,还是建立了自己的BLOG,因为心里很痒
  5. oracle是堆屎山,Oracle NUMBER 类型细讲
  6. 'adb' 不是内部或外部命令,也不是可运行的程序或批处理文件
  7. 页面的div中有滚动条,js实现刷新页面后回到记录时滚动条的位置
  8. 前端学习(2935):v-for案例
  9. 请查收,一份让你年薪突破20W的Python爬虫笔记!
  10. 青海贵德黄河岸边现雾凇奇观
  11. Linux虚拟机之间实现密钥登陆
  12. mysql多库备份_Mysql 之多库备份
  13. 红外条码扫描器的另类使用C#版
  14. Linux学习(一)——常用命令
  15. springboot毕业设计管理系统(带论文)
  16. 找到某个关键字 同义词词林 python_3.6 什么是LSI关键字?为什么它对SEO很重要?...
  17. 密码编码学与网络安全(第五版)答案
  18. 深度学习:用生成对抗网络(GAN)来恢复高分辨率(高精度)图片 (附源码,模型与数据集)
  19. openresty实现隧道代理
  20. 南京周边城市两日游方案

热门文章

  1. 大学生如何白嫖并使用腾讯云mysql云数据库
  2. 台式计算机主板能换吗,可以更换台式机CPU吗?将台式计算机更改为CPU的步骤
  3. AD控制器默认账户Domain Admins
  4. MyBatis梳理27题1-10
  5. IntelliJ 中自动生成get/set方法
  6. bzoj 1024 生日快乐 暴力搜索
  7. 用JAVA做一个物理动画_运用Java3D实现三维实时物理模拟动画
  8. 超级火爆的“量化交易”到底是什么?
  9. 64位程序连接32位oracle,通过ODBC-ADO方式
  10. creo服务器缓存位置,creo2.0配置文件把trail的文件保存路径换到别的文件夹里