├── README.md ├── SUMMARY.md ├── assets ├── 538px-Derivative_-_geometric_meaning.svg.png ├── Binary_entropy_plot.svg.png ├── Gradient_descent.png ├── KDTree-animation.gif ├── PLA.PNG ├── PLA3.PNG ├── Scalarproduct.gif ├── activation-function.png ├── blog_animal_classification.png ├── cnn-1.png ├── cnn-2.png ├── cnn-3.png ├── cnn-4.png ├── cnn-5.png ├── cos-functionGIF.GIF ├── kd-tree.png ├── kd-tree3.png ├── kd-tree4.png ├── kd-tree5.png ├── kd-tree6.png ├── knn-concept.png ├── lenses_decision_tree.png ├── linear_bgd_1.png ├── linear_bgd_2.png ├── linear_normal_equations.png ├── linear_sgd_1.png ├── linear_sgd_2.png ├── logistic_1.png ├── logistic_2.png ├── logistic_bgd_1.png ├── logistic_bgd_2.png ├── logistic_bgd_3.png ├── logistic_gd.PNG ├── logistic_sgd_1.png ├── logistic_sgd_2.png ├── logistic_sgd_3.png ├── logistic_tidu.PNG ├── lp_distance_1.png ├── mp-neuron.png ├── network-architecture.PNG ├── network-bp-pic.png ├── network-bp-w.png ├── network-cost-function.png ├── network-definition.png ├── network-delta-z.png ├── network-eye-subquestions.PNG ├── network-face-subquestions.PNG ├── nn-dropout.png ├── nn-initial-weight-compare.png ├── nn-initial-weight-z.png ├── nn-initial-weight-z2.png ├── nn-initial-weight.png ├── peception-xo2r.PNG ├── peception-xor.PNG ├── perceptron.png ├── pla-figure.png ├── prunning.jpeg ├── sigmoid_function.png ├── 感知机模型.jpg └── 方向导数2.png ├── book.json ├── fu-hao-biao.md ├── gan-zhi-ji-xue-xi-suan-fa.md ├── gan-zhi-ji.md ├── gan-zhi-xue-xi-ji.md ├── jian-du-shi-xue-xi.md ├── jue-ce-shu.md ├── jue-ce-shu ├── jue-ce-shu-sheng-cheng-he-jian-zhi.md ├── mo-xing-yu-xue-xi.md ├── pythonshi-xian.md └── te-zheng-xuan-ze.md ├── kjin-lin-fa.md ├── kjin-lin-fa ├── kdshu-fang-fa.md ├── kdshu-python-shi-xian.md ├── kjin-lin-mo-xing.md └── knnshi-li.md ├── logistichui-gui.md ├── logistichui-gui ├── logisticfen-bu.md ├── logistichui-gui-mo-xing.md └── suan-fa-python-shi-xian.md ├── po-su-bei-xie-si-fa.md ├── po-su-bei-xie-si-fa ├── can-shu-gu-ji.md ├── po-su-bei-xie-si-fa-de-xue-xi-he-fen-lei.md └── suan-fa-he-shi-xian.md ├── shen-jing-wang-luo.md ├── shen-jing-wang-luo ├── fan-xiang-chuan-bo-suan-fa.md ├── fan-xiang-chuan-bo-suan-fa │ ├── dai-ma-shi-xian.md │ ├── fan-xiang-chuan-bo-zheng-ming.md │ ├── ji-yu-ju-zhen-de-bp-ji-suan.md │ └── suan-fa-dai-ma.md ├── gai-jin-shen-jing-wang-luo-de-xue-xi-fang-fa.md ├── gai-jin-shen-jing-wang-luo-de-xue-xi-fang-fa │ ├── jiao-cha-shang-dai-jia-han-shu.md │ ├── quan-zhong-chu-shi-hua.md │ ├── regularization.md │ └── softmax.md ├── juan-ji-shen-jing-wang-luo.md ├── juan-ji-shen-jing-wang-luo │ └── ji-ben-jie-shao.md ├── shen-jing-wang-luo-de-ju-zhen-biao-da.md ├── shen-jing-wang-luo.md └── shen-jing-yuan-mo-xing.md ├── shu-xue-ji-chu.md ├── shu-xue-ji-chu ├── gai-lv-tong-ji.md ├── gai-lv-tong-ji │ ├── tong-ji-liang.md │ ├── xian-yan-hou-yan-gai-lv.md │ └── yang-ben-tong-ji-liang.md ├── wei-ji-fen.md ├── wei-ji-fen │ ├── ti-du-xia-jiang-fa.md │ ├── ti-du.md │ └── xiang-liang-nei-ji.md ├── xian-xing-dai-shu.md ├── xian-xing-dai-shu │ └── te-zheng-zhi-he-te-zheng-xiang-liang.md ├── xin-xi-lun.md └── xin-xi-lun │ ├── hu-xin-xi.md │ ├── shang.md │ ├── tiao-jian-shang.md │ └── xiang-dui-shang-he-jiao-cha-shang.md ├── suan-fa-python-shi-xian.md ├── xian-xing-hui-gui.md ├── xian-xing-hui-gui ├── suan-fa-python-shi-xian.md └── xian-xing-hui-gui-mo-xing.md └── zhi-chi-xiang-liang-ji.md /README.md: -------------------------------------------------------------------------------- 1 | # Machine Learning 2 | 3 | 本书是个人机器学习基础的笔记,包含算法原理,公式推导,python代码实现。 4 | 5 | 本书github地址:[https://github.com/zhjunqin/MachineLearning](https://github.com/zhjunqin/MachineLearning) 6 | 7 | 本书legacy gitbook地址:[https://zhjunqin.gitbooks.io/machinelearning/content/](https://zhjunqin.gitbooks.io/machinelearning/content/) 8 | 9 | 本书新的gitbook地址:https://zhjunqin.gitbook.io/machine-learning/ 10 | 11 | 本书参考了: 12 | 13 | 《统计学习方法》,李航 著 14 | 15 | 《机器学习实战》,Peter Harrington 著,李悦 李鹏 曲亚东 王斌 译 16 | 17 | 《机器学习》,周志华 著 18 | 19 | 《机器学习基石》课程,林轩田 20 | 21 | 《机器学习》课程,Andrew ng 22 | 23 | 《神经网络与机器学习》, Michael Nielsen 著, Xiaohu Zhu 和 Freeman Zhang 译 24 | 25 | 《概率论与数理统计》 ,高等教育出版社 26 | 27 | 以及参考一些网络上博客,如果参考了,在每一篇内都会给出链接。 28 | 29 | -------------------------------------------------------------------------------- /SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | ## 机器学习 4 | 5 | * [前言](README.md) 6 | * [符号表](fu-hao-biao.md) 7 | * [监督式学习](jian-du-shi-xue-xi.md) 8 | * [感知机](gan-zhi-ji.md) 9 | * [感知机模型](gan-zhi-xue-xi-ji.md) 10 | * [感知机学习算法](gan-zhi-ji-xue-xi-suan-fa.md) 11 | * [算法python实现](suan-fa-python-shi-xian.md) 12 | * [Logistic回归](logistichui-gui.md) 13 | * [Logistic分布](logistichui-gui/logisticfen-bu.md) 14 | * [Logistic回归模型](logistichui-gui/logistichui-gui-mo-xing.md) 15 | * [算法python实现](logistichui-gui/suan-fa-python-shi-xian.md) 16 | * [线性回归](xian-xing-hui-gui.md) 17 | * [线性回归模型](xian-xing-hui-gui/xian-xing-hui-gui-mo-xing.md) 18 | * [算法python实现](xian-xing-hui-gui/suan-fa-python-shi-xian.md) 19 | * [K近邻法](kjin-lin-fa.md) 20 | * [k近邻模型](kjin-lin-fa/kjin-lin-mo-xing.md) 21 | * [kd树方法](kjin-lin-fa/kdshu-fang-fa.md) 22 | * [kd树python实现](kjin-lin-fa/kdshu-python-shi-xian.md) 23 | * [knn实例](kjin-lin-fa/knnshi-li.md) 24 | * [朴素贝叶斯法](po-su-bei-xie-si-fa.md) 25 | * [模型和原理](po-su-bei-xie-si-fa/po-su-bei-xie-si-fa-de-xue-xi-he-fen-lei.md) 26 | * [参数估计](po-su-bei-xie-si-fa/can-shu-gu-ji.md) 27 | * [算法和实现](po-su-bei-xie-si-fa/suan-fa-he-shi-xian.md) 28 | * [决策树](jue-ce-shu.md) 29 | * [模型与学习](jue-ce-shu/mo-xing-yu-xue-xi.md) 30 | * [特征选择](jue-ce-shu/te-zheng-xuan-ze.md) 31 | * [生成算法和剪枝](jue-ce-shu/jue-ce-shu-sheng-cheng-he-jian-zhi.md) 32 | * [python实现](jue-ce-shu/pythonshi-xian.md) 33 | * [支持向量机](zhi-chi-xiang-liang-ji.md) 34 | * [神经网络](shen-jing-wang-luo.md) 35 | * [神经元模型和感知机](shen-jing-wang-luo/shen-jing-yuan-mo-xing.md) 36 | * [神经网络](shen-jing-wang-luo/shen-jing-wang-luo.md) 37 | * [神经网络的矩阵表达](shen-jing-wang-luo/shen-jing-wang-luo-de-ju-zhen-biao-da.md) 38 | * [反向传播算法](shen-jing-wang-luo/fan-xiang-chuan-bo-suan-fa.md) 39 | * [算法证明](shen-jing-wang-luo/fan-xiang-chuan-bo-suan-fa/fan-xiang-chuan-bo-zheng-ming.md) 40 | * [算法代码](shen-jing-wang-luo/fan-xiang-chuan-bo-suan-fa/suan-fa-dai-ma.md) 41 | * [基于矩阵的计算](shen-jing-wang-luo/fan-xiang-chuan-bo-suan-fa/ji-yu-ju-zhen-de-bp-ji-suan.md) 42 | * [改进神经网络的学习方法](shen-jing-wang-luo/gai-jin-shen-jing-wang-luo-de-xue-xi-fang-fa.md) 43 | * [交叉熵代价函数](shen-jing-wang-luo/gai-jin-shen-jing-wang-luo-de-xue-xi-fang-fa/jiao-cha-shang-dai-jia-han-shu.md) 44 | * [softmax](shen-jing-wang-luo/gai-jin-shen-jing-wang-luo-de-xue-xi-fang-fa/softmax.md) 45 | * [regularization](shen-jing-wang-luo/gai-jin-shen-jing-wang-luo-de-xue-xi-fang-fa/regularization.md) 46 | * [权重初始化](shen-jing-wang-luo/gai-jin-shen-jing-wang-luo-de-xue-xi-fang-fa/quan-zhong-chu-shi-hua.md) 47 | * [卷积神经网络](shen-jing-wang-luo/juan-ji-shen-jing-wang-luo.md) 48 | * [基本介绍](shen-jing-wang-luo/juan-ji-shen-jing-wang-luo/ji-ben-jie-shao.md) 49 | * [数学基础](shu-xue-ji-chu.md) 50 | * [线性代数](shu-xue-ji-chu/xian-xing-dai-shu.md) 51 | * [特征值和特征向量](shu-xue-ji-chu/xian-xing-dai-shu/te-zheng-zhi-he-te-zheng-xiang-liang.md) 52 | * [概率统计](shu-xue-ji-chu/gai-lv-tong-ji.md) 53 | * [随机变量的特征](shu-xue-ji-chu/gai-lv-tong-ji/tong-ji-liang.md) 54 | * [样本统计量](shu-xue-ji-chu/gai-lv-tong-ji/yang-ben-tong-ji-liang.md) 55 | * [先验后验概率](shu-xue-ji-chu/gai-lv-tong-ji/xian-yan-hou-yan-gai-lv.md) 56 | * [微积分](shu-xue-ji-chu/wei-ji-fen.md) 57 | * [向量内积](shu-xue-ji-chu/wei-ji-fen/xiang-liang-nei-ji.md) 58 | * [方向导数和梯度](shu-xue-ji-chu/wei-ji-fen/ti-du.md) 59 | * [梯度下降法](shu-xue-ji-chu/wei-ji-fen/ti-du-xia-jiang-fa.md) 60 | * [信息论](shu-xue-ji-chu/xin-xi-lun.md) 61 | * [熵](shu-xue-ji-chu/xin-xi-lun/shang.md) 62 | * [相对熵和交叉熵](shu-xue-ji-chu/xin-xi-lun/xiang-dui-shang-he-jiao-cha-shang.md) 63 | * [条件熵](shu-xue-ji-chu/xin-xi-lun/tiao-jian-shang.md) 64 | * [互信息](shu-xue-ji-chu/xin-xi-lun/hu-xin-xi.md) 65 | 66 | -------------------------------------------------------------------------------- /assets/538px-Derivative_-_geometric_meaning.svg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/538px-Derivative_-_geometric_meaning.svg.png -------------------------------------------------------------------------------- /assets/Binary_entropy_plot.svg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/Binary_entropy_plot.svg.png -------------------------------------------------------------------------------- /assets/Gradient_descent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/Gradient_descent.png -------------------------------------------------------------------------------- /assets/KDTree-animation.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/KDTree-animation.gif -------------------------------------------------------------------------------- /assets/PLA.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/PLA.PNG -------------------------------------------------------------------------------- /assets/PLA3.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/PLA3.PNG -------------------------------------------------------------------------------- /assets/Scalarproduct.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/Scalarproduct.gif -------------------------------------------------------------------------------- /assets/activation-function.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/activation-function.png -------------------------------------------------------------------------------- /assets/blog_animal_classification.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/blog_animal_classification.png -------------------------------------------------------------------------------- /assets/cnn-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/cnn-1.png -------------------------------------------------------------------------------- /assets/cnn-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/cnn-2.png -------------------------------------------------------------------------------- /assets/cnn-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/cnn-3.png -------------------------------------------------------------------------------- /assets/cnn-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/cnn-4.png -------------------------------------------------------------------------------- /assets/cnn-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/cnn-5.png -------------------------------------------------------------------------------- /assets/cos-functionGIF.GIF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/cos-functionGIF.GIF -------------------------------------------------------------------------------- /assets/kd-tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/kd-tree.png -------------------------------------------------------------------------------- /assets/kd-tree3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/kd-tree3.png -------------------------------------------------------------------------------- /assets/kd-tree4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/kd-tree4.png -------------------------------------------------------------------------------- /assets/kd-tree5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/kd-tree5.png -------------------------------------------------------------------------------- /assets/kd-tree6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/kd-tree6.png -------------------------------------------------------------------------------- /assets/knn-concept.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/knn-concept.png -------------------------------------------------------------------------------- /assets/lenses_decision_tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/lenses_decision_tree.png -------------------------------------------------------------------------------- /assets/linear_bgd_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/linear_bgd_1.png -------------------------------------------------------------------------------- /assets/linear_bgd_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/linear_bgd_2.png -------------------------------------------------------------------------------- /assets/linear_normal_equations.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/linear_normal_equations.png -------------------------------------------------------------------------------- /assets/linear_sgd_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/linear_sgd_1.png -------------------------------------------------------------------------------- /assets/linear_sgd_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/linear_sgd_2.png -------------------------------------------------------------------------------- /assets/logistic_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/logistic_1.png -------------------------------------------------------------------------------- /assets/logistic_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/logistic_2.png -------------------------------------------------------------------------------- /assets/logistic_bgd_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/logistic_bgd_1.png -------------------------------------------------------------------------------- /assets/logistic_bgd_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/logistic_bgd_2.png -------------------------------------------------------------------------------- /assets/logistic_bgd_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/logistic_bgd_3.png -------------------------------------------------------------------------------- /assets/logistic_gd.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/logistic_gd.PNG -------------------------------------------------------------------------------- /assets/logistic_sgd_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/logistic_sgd_1.png -------------------------------------------------------------------------------- /assets/logistic_sgd_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/logistic_sgd_2.png -------------------------------------------------------------------------------- /assets/logistic_sgd_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/logistic_sgd_3.png -------------------------------------------------------------------------------- /assets/logistic_tidu.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/logistic_tidu.PNG -------------------------------------------------------------------------------- /assets/lp_distance_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/lp_distance_1.png -------------------------------------------------------------------------------- /assets/mp-neuron.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/mp-neuron.png -------------------------------------------------------------------------------- /assets/network-architecture.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/network-architecture.PNG -------------------------------------------------------------------------------- /assets/network-bp-pic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/network-bp-pic.png -------------------------------------------------------------------------------- /assets/network-bp-w.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/network-bp-w.png -------------------------------------------------------------------------------- /assets/network-cost-function.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/network-cost-function.png -------------------------------------------------------------------------------- /assets/network-definition.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/network-definition.png -------------------------------------------------------------------------------- /assets/network-delta-z.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/network-delta-z.png -------------------------------------------------------------------------------- /assets/network-eye-subquestions.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/network-eye-subquestions.PNG -------------------------------------------------------------------------------- /assets/network-face-subquestions.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/network-face-subquestions.PNG -------------------------------------------------------------------------------- /assets/nn-dropout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/nn-dropout.png -------------------------------------------------------------------------------- /assets/nn-initial-weight-compare.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/nn-initial-weight-compare.png -------------------------------------------------------------------------------- /assets/nn-initial-weight-z.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/nn-initial-weight-z.png -------------------------------------------------------------------------------- /assets/nn-initial-weight-z2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/nn-initial-weight-z2.png -------------------------------------------------------------------------------- /assets/nn-initial-weight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/nn-initial-weight.png -------------------------------------------------------------------------------- /assets/peception-xo2r.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/peception-xo2r.PNG -------------------------------------------------------------------------------- /assets/peception-xor.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/peception-xor.PNG -------------------------------------------------------------------------------- /assets/perceptron.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/perceptron.png -------------------------------------------------------------------------------- /assets/pla-figure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/pla-figure.png -------------------------------------------------------------------------------- /assets/prunning.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/prunning.jpeg -------------------------------------------------------------------------------- /assets/sigmoid_function.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/sigmoid_function.png -------------------------------------------------------------------------------- /assets/感知机模型.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/感知机模型.jpg -------------------------------------------------------------------------------- /assets/方向导数2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/assets/方向导数2.png -------------------------------------------------------------------------------- /book.json: -------------------------------------------------------------------------------- 1 | { 2 | "language" : "zh-hans", 3 | "plugins": ["katex"] 4 | } -------------------------------------------------------------------------------- /fu-hao-biao.md: -------------------------------------------------------------------------------- 1 | ## **符号表** 2 | 3 | $$R$$ 实数集 4 | 5 | $$R^n$$ $$n$$维实数向量空间,$$n$$维欧式空间 6 | 7 | $$X$$ 输入空间 8 | 9 | $$Y$$ 输出空间 10 | 11 | $$x \in X$$ 输入,实例 12 | 13 | $$y\in Y$$ 输出,标记 14 | 15 | $$T=\{(x^{(1)},y^{(1)}),(x^{(2)},y^{(2)}),...,(x^{(m)},y^{(m)})\}$$ 训练数据集,个数为$$m$$ 16 | 17 | $$N$$ 样本容量 18 | 19 | $$(x^{(i)},y^{(i)})$$ 第$$i$$个训练数据点 20 | 21 | $$x=(x_1,x_2,...,x_n)^T$$ 输入向量,$$n$$维实数向量 22 | 23 | $$x_j^{(i)}$$ 输入向量$$x^{(i)}$$的第$$j$$个分量 24 | 25 | $$w=(w_1,w_2,...,w_n)^T$$ 权值向量 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /gan-zhi-ji-xue-xi-suan-fa.md: -------------------------------------------------------------------------------- 1 | # 感知机学习算法 2 | 3 | 感知机学习问题转化为求解损失函数的最优化问题,最优化的方法就是随机梯度下降法。 4 | 5 | ### 1. 学习算法的原始形式 6 | 7 | 给定一个训练数据集$$T=\{(x^{(1)},y^{(1)}),(x^{(2)},y^{(2)}),...,(x^{(m)},y^{(m)})\}$$,其中,$$x^{(i)}\in X= R^n$$,$$y^{(i)}\in Y=\lbrace+1,-1\rbrace$$,$$i=1,2,...,m$$,求参数$$w$$,$$b$$,使得其为以下损失函数极小化的解: 8 | 9 | 10 | $$ 11 | \min_{w,b}L(w,b)=-\displaystyle\sum_{x^{(i)}\in M}y^{(i)}(w\cdot x^{(i)}+b) 12 | $$ 13 | 14 | 15 | 其中$$M$$为**误分类点**的集合。 16 | 17 | 假设误分类点集合$$M$$是固定的,那么损失函数$$L(w,b)$$的梯度由 18 | 19 | 20 | $$ 21 | \nabla_w L(w,b)=-\displaystyle\sum_{x^{(i)}\in M}y^{(i)} x^{(i)} 22 | $$ 23 | 24 | 25 | 26 | $$ 27 | \nabla_b L(w,b)=-\displaystyle\sum_{x^{(i)}\in M}y^{(i)} 28 | $$ 29 | 30 | 31 | 给出。 32 | 33 | #### 1.1 **随机梯度下降算法**: 34 | 35 | **输入:**训练数据集$$T=\{(x^{(1)},y^{(1)}),(x^{(2)},y^{(2)}),...,(x^{(m)},y^{(m)})\}$$,其中,$$x^{(i)}\in X= R^n$$,$$y^{(i)}\in Y=\lbrace+1,-1\rbrace$$,$$i=1,2,...,m$$,学习率为$$ \eta(0<\eta\leqslant1)$$ 36 | 37 | **输出:**$$w,b$$:感知机模型$$f(x)=sign(w\cdot x+b)$$ 38 | 39 | 1. 选取初始值$$w_0,b_0$$ 40 | 2. 在训练集中选取数据$$(x^{(i)},y^{(i)})$$ 41 | 3. 如果$$y^{(i)}(w\cdot x^{(i)}+b)\leqslant0$$,则$$w \gets w+\eta y^{(i)} x^{(i)}$$,$$b \gets b+\eta y^{(i)}$$ 42 | 4. 转至步骤\(2\),直至训练集里面的每个点都不是误分类点,这个过程中训练集中的点可能会被重复的选中并计算。 43 | 44 | #### 1.2 **直观的解释** 45 | 46 | 当出现误分类点时,则调整$$w,b$$,更正超平面的方向,使其稍微转向正确的方向。 47 | 48 | ![](/assets/PLA.PNG) 49 | 50 | #### 1.3 算法的收敛性 51 | 52 | 可以证明,对于**线性可分**的数据集,感知机学习算法经过**有限次迭代**可以得到一个将训练数据集完全正确划分的分离超平面及感知机模型。 53 | 54 | ![](/assets/PLA3.PNG) 55 | 56 | ### 2.学习算法的对偶形式 57 | 58 | 对偶形式的基本想法是,将$$w$$和$$b$$表示为实例向量$$x^{(i)}$$和标记$$y^{(i)}$$的线性组合的形式,通过求解其系数而求得$$w$$和$$b$$。 59 | 60 | 从上面的算法中可假设初始值$$w_0,b_0$$均为0。对某个误分类点$$(x^{(i)},y^{(i)})$$经过$$w \gets w+\eta y^{(i)} x^{(i)}$$和$$b \gets b+\eta y^{(i)}$$迭代修改,假设修改了$$k$$次后,$$w,b$$ 关于该误分类点的最后的总增量为$$\alpha_i y^{(i)}x^{(i)}$$和$$\alpha_iy^{(i)}$$,这里$$\alpha_i=k_i\eta$$。对于训练集中的每一个点都有$$\alpha_i$$,所有的训练数据点的分量构成向量$$\alpha =(\alpha_1,\alpha_2,...,\alpha_m)^T$$,这样最后得到的$$w,b$$可以分别表示为(有的$$\alpha_i$$可能为0): 61 | 62 | 63 | $$ 64 | w = \displaystyle\sum_{i=1}^m\alpha_iy^{(i)}x^{(i)}=\displaystyle\sum_{i=1}^mk_i\eta y^{(i)}x^{(i)} 65 | $$ 66 | 67 | 68 | 69 | $$ 70 | b = \displaystyle\sum_{i=1}^m\alpha_iy^{(i)} = \displaystyle\sum_{i=1}^mk_i\eta y^{(i)} 71 | $$ 72 | 73 | 74 | #### 2.1 算法的对偶形式 75 | 76 | **输入**:线性可分的数据集$$T=\{(x^{(1)},y^{(1)}),(x^{(2)},y^{(2)}),...,(x^{(m)},y^{(m)})\}$$,其中$$x^{(i)}\in X= R^n$$,$$y^{(i)}\in Y=\lbrace+1,-1\rbrace$$,$$i=1,2,...,m$$,学习率$$ \eta(0<\eta\leqslant1)$$ 77 | 78 | **输出**:$$\alpha,b$$;感知机模型$$f(x)=sign(\displaystyle\sum_{j=1}^m\alpha_jy^{(j)}x^{(j)}\cdot x+b)$$,其中$$\alpha=(\alpha_1,\alpha_2,...\alpha_m)^T$$ 79 | 80 | 1. 选取初始值$$\alpha =(0,0,...,0), b=0$$ 81 | 2. 在训练集中选取数据$$(x^{(i)},y^{(i)})$$ 82 | 3. 如果$$y^{(i)}(\displaystyle\sum_{j=1}^m\alpha_jy^{(j)}x^{(j)}\cdot x^{(i)}+b)\leqslant0$$,则$$\alpha_i \gets \alpha_i+\eta $$,$$b \gets b+\eta y^{(i)}$$,也就是每次只更新向量$$\alpha$$的第$$i$$个分量 83 | 4. 转至步骤\(2\),直到没有误分类点为止。 84 | 85 | 观察可以看到步骤3中每次更新的$$x^{(j)}\cdot x^{(i)}$$可以事先计算好并以矩阵的形式存储,那么就不需要每次都计算, 86 | 87 | 这样的矩阵称为Gram矩阵\(Gram matrix\): 88 | 89 | 90 | $$ 91 | G=[x^{(i)}\cdot x^{(j)}]_{m\times m} 92 | $$ 93 | 94 | 95 | 96 | $$ 97 | G= \begin{bmatrix} 98 | x^{(1)}\cdot x^{(1)} & x^{(1)}\cdot x^{(2)} & x^{(1)}\cdot x^{(3)} & ... & x^{(1)}\cdot x^{(m)}\\ 99 | x^{(2)}\cdot x^{(1)} & x^{(2)}\cdot x^{(2)} & x^{(2)}\cdot x^{(3)} & ... & x^{(2)}\cdot x^{(m)} \\ 100 | x^{(3)}\cdot x^{(1)} & x^{(3)}\cdot x^{(2)} & x^{(3)}\cdot x^{(3)} & ... & x^{(3)}\cdot x^{(m)} \\ 101 | ... \\ 102 | x^{(m)}\cdot x^{(1)} & x^{(m)}\cdot x^{(2)} & x^{(m)}\cdot x^{(3)} & ... & x^{(m)}\cdot x^{(m)} 103 | \end{bmatrix} 104 | $$ 105 | 106 | 107 | 则关于$$\displaystyle\sum_{j=1}^m\alpha_jy^{(j)}x^{(j)}\cdot x^{(i)}$$的计算,$$\displaystyle\sum_{j=1}^m\alpha_jy^{(j)}x^{(j)}\cdot x^{(i)} = \displaystyle\sum_{j=1}^m\alpha_jy^{(j)}G[i,j]= \sum \alpha \circ y \circ G[i]$$,即三个向量中每个元素相乘再做和运算。 108 | 109 | > 参考:林轩田,机器学习基石 110 | 111 | 112 | 113 | -------------------------------------------------------------------------------- /gan-zhi-ji.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/gan-zhi-ji.md -------------------------------------------------------------------------------- /gan-zhi-xue-xi-ji.md: -------------------------------------------------------------------------------- 1 | # **感知机** 2 | 3 | 感知机\(Peceptron\)是二类分类的线性分类模型,其输入为实例的特征向量,输出为实例的类别,取$$+1$$和$$-1$$二值。感知机将对应于输入空间(特征空间)中将实例划分为正负的分离超平面,属于判别模型。 4 | 5 | ### 1. 定义 6 | 7 | 假设输入空间(特征空间)是$$X \subseteq R^n$$,输出空间是$$Y=\lbrace+1,-1\rbrace$$。输入$$x\in X$$表示实例的特征向量,对应于输入空间(特征空间)的点;输出$$y\in Y$$表示实例的类别。由输入空间到输出空间的如下函数: 8 | 9 | 10 | $$ 11 | f(x)=sign(w\cdot x+b) 12 | $$ 13 | 14 | 15 | 称为感知机。其中,$$w$$和$$b$$为感知模型参数,$$w\in R^n$$叫做权值\(weight\)或权值向量\(weight vector\),$$b\in R$$ 叫做偏置,$$w\cdot x$$表示向量$$w$$和向量$$x$$的内积。$$sign$$是符号函数,即 16 | 17 | 18 | $$ 19 | sign(x) = \begin{cases} 20 | +1 &\text{if } x>=0 \\ 21 | -1 &\text{if } x<0 22 | \end{cases} 23 | $$ 24 | 25 | 26 | 感知机是一种线性分类模型,属于判别模型。 27 | 28 | 感知模型的假设空间是定义在特征空间中的所有线性分类模型\(linear classification model\)或线性分类器\(linear classifier\),即函数集合$$\{f\vert f(x)=w\cdot x+b\}$$。 29 | 30 | ### 2.几何解释 31 | 32 | 线性方程$$w\cdot x+b=0$$对应于特征空间$$R^n$$中的一个超平面$$S$$,其中$$w$$是超平面的法向量,$$b$$是超平面的截距。这个超平面将特征空间划分为两部分。位于两部分的点(特征向量)分别被分为正负两类,因此,超平面$$S$$称为分离超平面\(separating hyperplane\),如图所示。 33 | 34 | ![](/assets/感知机模型.jpg) 35 | 36 | 其中超平面上的任意两个向量,比如为$$x^{(i)}$$,$$x^{(j)}$$满足方程(这里用上标表示不同的向量,下标用来表示向量中的分量,跟原书不同) 37 | 38 | $$w\cdot x^{(i)} = -b$$ 39 | 40 | $$w\cdot x^{(j)} = -b$$ 41 | 42 | 则$$w\cdot (x^{(i)}-x^{(j)})=0$$,也就是超平面上任意两个向量相减构成的向量与$$w$$的内积为$$0$$,则互相垂直。对于超平面来讲$$w$$的方向并不重要,只需要垂直于超平面即可。 43 | 44 | 满足$$w\cdot x+b>0$$的的向量$$x $$位于超平面跟$$w$$的方向一致的一面,满足$$w\cdot x+b<0$$的向量$$x$$位于超平面跟$$w$$方向相反的一面。因为取超平面上任意一个向量假设为$$x^{(1)}$$,则超平面外的任何一向量$$x^{(0)}$$满足$$w\cdot (x^{(0)}-x^{(1)})>0$$,则说明这两向量相减构成的向量跟$$w$$的夹角小于90度,反之小于0,则夹角大于90度。 45 | 46 | 超平面外的任意一个点$$x^{(0)}$$到超平面$$S$$的距离为 47 | 48 | 49 | $$ 50 | \dfrac{|w\cdot x^{(0)}+b|}{||w||} 51 | $$ 52 | 53 | 54 | 其中$$||w||$$是$$w$$的$$L_2$$范数,也就是欧式距离$$||w||=\sqrt{w_1^2 +w_2^2+...+w_n^2}$$. 55 | 56 | ### 3. 感知机的学习策略 57 | 58 | 为了确定感知机模型参数$$w$$和$$b$$,需要确定一个学习策略,即定义(经验 )损失函数并将损失函数最小化。 59 | 60 | 损失函数的一个自然选择是**误分类点**的总数,但是这样的损失函数不是参数$$w$$和$$b$$的连续可导函数,不易优化。另外一种选择是所有**误分类点**到超平面的总距离。其次,对于**误分类点**的数据$$(x^{(i)},y^{(i)})$$来说,满足$$-y^{(i)}(w\cdot x^{(i)}+b)>0$$,因为当$$w\cdot x^{(i)}+b>0$$时,$$y^{(i)} = -1$$,而当$$-y^{(i)}(w\cdot x^{(i)}+b)<0$$时,$$y^{(i)} = 1$$。因此误分类点$$x^{(i)}$$到超平面$$S$$的距离是 61 | 62 | 63 | $$ 64 | -y^{(i)} \dfrac{w\cdot x^{(i)}+b}{||w||} 65 | $$ 66 | 67 | 68 | 这样,假设所有超平面$$S$$的**误分类点**结合为$$M$$,那么所有**误分类点**到超平面$$S$$的总距离为 69 | 70 | 71 | $$ 72 | -\dfrac{1}{||w||}\displaystyle\sum_{x^{(i)}\in M}y^{(i)}(w\cdot x^{(i)}i+b) 73 | $$ 74 | 75 | 76 | 不考虑$$\dfrac{1}{||w||}$$,则我们得到感知机的损失函数:$$-\displaystyle\sum_{x^{(i)}\in M}y^{(i)}(w\cdot x^{(i)}+b)$$。(这里个人理解为任意一个超平面的法向量$$w$$都可以经过缩放成为单位向量) 77 | 78 | 给定训练数据集合$$T=\{(x^{(1)},y^{(1)}),(x^{(2)},y^{(2)}),...,(x^{(m)},y^{(m)})\}$$,其中$$x^{(i)}\in X= R^n$$,$$y^{(i)}\in Y=\lbrace+1,-1\rbrace$$,$$i=1,2,...,m$$。感知学习机$$sign(w\cdot x+b)$$的损失函数定义为 79 | 80 | 81 | $$ 82 | L(w,b)=-\displaystyle\sum_{x^{(i)}\in M}y^{(i)}(w\cdot x^{(i)}+b) 83 | $$ 84 | 85 | 86 | 这个损失函数就是感知学习机的**经验风险函数**。它是$$w$$,$$b$$的连续可导函数。显然它是非负函数。如果没有误分类点,则损失函数为0,而且误分类点越少,误分类点离超平面越近,损失函数越小。 87 | 88 | > 参考文献: 89 | > 90 | > 统计学习方法,李航 91 | > 92 | > [http://blog.csdn.net/wangxin1982314/article/details/73529499](http://blog.csdn.net/wangxin1982314/article/details/73529499) 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /jian-du-shi-xue-xi.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/jian-du-shi-xue-xi.md -------------------------------------------------------------------------------- /jue-ce-shu.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/jue-ce-shu.md -------------------------------------------------------------------------------- /jue-ce-shu/jue-ce-shu-sheng-cheng-he-jian-zhi.md: -------------------------------------------------------------------------------- 1 | ## 1. 决策树生成算法 2 | 3 | ### ID3算法 4 | 5 | ID3算法的核心是在决策树各个节点上应用**信息增益**准则选择特征,递归地构建决策树。 6 | 7 | 具体方法是:从根节点开始,对节点计算所有可能的特征的信息增益,选择信息增益最大的特征作为节点的特征,由该节点的不同取值建立子节点。再对子节点递归使用同样的方法,构建决策树,直到所有特征的信息增益均很小或者没有特征可以选择为止。 8 | 9 | 输入:训练数据集$$D$$,特征集$$A$$,阈值$$\varepsilon$$; 10 | 11 | 输出:决策树$$T$$ 12 | 13 | 1)若$$D$$中所有实例属于同一类$$C_k$$,则$$T$$为单节点树,并将类$$C_k$$作为该节点的类标记,返回$$T$$。 14 | 15 | 2)若$$A$$为空,则$$T$$为单节点树,并将$$D$$中实例树最大的类$$C_k$$作为该节点的类标记,返回$$T$$。 16 | 17 | 3)否则,计算$$A$$中各个特征对$$D$$的信息增益,选择信息增益最大的特征$$A_g$$ 18 | 19 | 4)如果$$A_g$$的信息增益小于阈值$$\varepsilon$$,则置$$T$$为单节点树,并将$$D$$中实例数最大的类$$C_k$$作为该节点的类标记,返回$$T$$ 20 | 21 | 5)否则,对$$A_g$$的每一个可能值$$\alpha_i$$,按照$$A_g$$的可能取值将$$D$$分割成若干个非空子集$$D_i$$,构造子节点,对于第$$i$$个子节点,以$$D_i$$为训练集,以$$A-\{A_g\}$$为特征集,递归得进行步骤1-5,返回$$T_i$$。 22 | 23 | ### C4.5算法 24 | 25 | C4.5算法与ID3算法类似,只是C4.5在生成过程中,用**信息增益比**来选择特征。 26 | 27 | ## 2. 决策树的剪枝 28 | 29 | 决策树生成算法递归地产生决策树,一直到不能继续下去为止,这样产生的决策树对训练数据的分类很准确,但是对于未知的测试数据的分类却没有那么准确,即产生过拟合现象。 30 | 31 | 过拟合的原因在于学习时过多地考虑如何提高对训练数据的正确分类,从而构造出过于复杂的决策树。 32 | 33 | 在决策树学习中将生成的树进行简化的过程称为剪枝(prunning),具体地剪枝从已生成的树上减掉一些子树或叶节点,并将其根节点或父节点作为新的叶子节点,从而简化分类模型。 34 | 35 | 决策树的剪枝通过极小化决策树整体的损失函数(loss function)或代价函数(cost function)来实现。 36 | 37 | 设树$$T$$的叶节点的个数为$$|T|$$,$$t$$是树$$T$$的叶节点,该叶节点有$$N_t$$个样本点,其中$$k$$类的样本点有$$N_{tk}$$个,$$k=1,2,...,K$$,$$H_t(T)$$为叶节点上的经验熵,则决策树学习的损失函数可以定义为: 38 | 39 | 40 | $$ 41 | C_\alpha(T)=\displaystyle\sum_{t=1}^{|T|}N_tH_t(T)+\alpha|T| 42 | $$ 43 | 44 | 45 | 其中$$\alpha \geqslant0$$,经验熵$$H_t(T)$$为 46 | 47 | 48 | $$ 49 | H_t(T)=-\displaystyle\sum_{k=1}^K \dfrac{N_{tk}}{N_t}\mathrm{log}_2 {\dfrac{N_{tk}}{N_t}} 50 | $$ 51 | 52 | 53 | 于是可以将上面的式子转化为 54 | 55 | 56 | $$ 57 | C_\alpha(T)=-\displaystyle\sum_{t=1}^{|T|}\displaystyle\sum_{k=1}^K N_{tk}\mathrm{log}_2 {\dfrac{N_{tk}}{N_t}}+\alpha|T|=C(T)+\alpha |T| 58 | $$ 59 | 60 | 61 | $$C(T)$$表示模型对训练数据的预测误差,即模型与训练数据的拟合程度,$$|T|$$表示模型复杂度,参数$$\alpha$$控制两者之间的影响,可以理解为正则化参数。较大的$$\alpha$$表示选择简单的模型,较小的$$\alpha$$表示选择较复杂的模型。 62 | 63 | ### 决策树的剪枝算法 64 | 65 | 输入:生成算法产生的整个树$$T$$,参数$$\alpha$$ 66 | 67 | 输出:修剪后的子树$$T_{\alpha}$$ 68 | 69 | 1)计算每个节点的经验熵 70 | 71 | 2)递归地从树的叶节点向上回溯,假定一组叶节点回溯到父节点之前与之后的整体树分别为$$T_B$$与$$T_A$$,其对应的损失函数分别为$$C_\alpha(T_B)$$与$$C_\alpha(T_A)$$,如果$$C_\alpha(T_A)\leqslant C_\alpha(T_B)$$,则进行剪枝,即其父节点变为新的叶子节点。 72 | 73 | 3)返回步骤2,一直到不能继续位置,最后得到剪枝后的损失函数最小的子树$$T_\alpha$$。 74 | 75 | 剪枝算法可以由一种动态规划的算法实现。 76 | 77 | ![](/assets/prunning.jpeg) 78 | 79 | -------------------------------------------------------------------------------- /jue-ce-shu/mo-xing-yu-xue-xi.md: -------------------------------------------------------------------------------- 1 | 决策树(decision tree)是一种基本的分类与回归方法。决策树模型呈树形结构。通常包含3个步骤:特征选择、决策树的生成和决策树的修剪。 2 | 3 | ### 决策树模型 4 | 5 | 分类决策树树模型是一种描述对实例进行分类的树形结构。决策树由节点(node)和有向边(directed edge)组成。节点有两种类型:内部节点(internal node)和叶节点。内部节点表示一个特征或属性,叶节点表示一个类。 6 | 7 | 用决策树分类,从根节点开始,对实例的某个特征进行测试,根据测试的结果,将实例分别到其子节点;这时每个子节点对于着该特征的一个取值,如此递归直到叶节点,最后将实例分到叶节点的类中去。示例: 8 | 9 | ![](/assets/blog_animal_classification.png) 10 | 11 | > pic source:[http://funhacks.net/2015/05/05/Decision-tree/](http://funhacks.net/2015/05/05/Decision-tree/) 12 | 13 | ### 决策树学习 14 | 15 | 假定给定训练数据集 16 | 17 | 18 | $$ 19 | T=\{(x^{(1)},y^{(1)}),(x^{(2)},y^{(2)}),...,(x^{(m)},y^{(m)})\} 20 | $$ 21 | 22 | 23 | 其中$$x^{(i)}=(x_1, x_2, ..., x_n)^T$$为输入实例(特征向量),$$n$$为特征个数,$$y^{(i)}\in \{1,2,...,k\}$$为类标记,$$i=1,2,...,m$$,$$m$$为样本容量。学习的目标是根据给定的训练数据集构建一个决策树模型,使它能够对实例进行正确的分类。 24 | 25 | 决策树学习的损失函数通常是正则化的极大似然函数,决策树学习的策略是以损失函数为目标函数的最小化。当损失函数确定后,学习问题就变为在损失函数意义下选择最优决策树的问题。但是从所有的决策时中选取最优决策树是NP完全问题,所以现实中通常采用启发式方法,近似求解这一最优化问题,得到次最优的解。 26 | 27 | 学习的算法通常是一个递归地选择最优特征,并根据该特征对训练数据进行分割,使得各个子数据集有个最好的分类,这个过程对应着特征空间划分,也对应着决策树的构建。 28 | 29 | 开始时,将所有训练数据都放在根节点,然后选择一个最优特征,然后将数据集分割成子集,如果某个子集里面的数据能够被基本正确分类,则构建叶节点;如果某个子集不能被正确分类,则继续选择一个新的最优特征,继续分割数据,一直递归下去,直到所有的数据集被正确分类,或没有合适的特征为止。 30 | 31 | 以上方法对未知的数据未必有好的分类能力,可能发生过拟合现象,需要对生成的决策树进行剪枝,使得它有更好的泛化能力。 32 | 33 | 总结下来,学习算法包括 **特征选择**->**决策树生成**->**决策时剪枝**的过程。 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /jue-ce-shu/pythonshi-xian.md: -------------------------------------------------------------------------------- 1 | ### ID3算法python实现 2 | 3 | 数据集来源《机器学习实战》:[https://github.com/apachecn/MachineLearning/blob/master/input/3.DecisionTree/lenses.txt](https://github.com/apachecn/MachineLearning/blob/master/input/3.DecisionTree/lenses.txt) 4 | 5 | ``` 6 | young myope no reduced no lenses 7 | young myope no normal soft 8 | young myope yes reduced no lenses 9 | young myope yes normal hard 10 | young hyper no reduced no lenses 11 | young hyper no normal soft 12 | young hyper yes reduced no lenses 13 | young hyper yes normal hard 14 | pre myope no reduced no lenses 15 | pre myope no normal soft 16 | pre myope yes reduced no lenses 17 | pre myope yes normal hard 18 | pre hyper no reduced no lenses 19 | pre hyper no normal soft 20 | pre hyper yes reduced no lenses 21 | pre hyper yes normal no lenses 22 | presbyopic myope no reduced no lenses 23 | presbyopic myope no normal no lenses 24 | presbyopic myope yes reduced no lenses 25 | presbyopic myope yes normal hard 26 | presbyopic hyper no reduced no lenses 27 | presbyopic hyper no normal soft 28 | presbyopic hyper yes reduced no lenses 29 | presbyopic hyper yes normal no lenses 30 | ``` 31 | 32 | 数据集的特征从左到右为 \['age', 'prescript', 'astigmatic', 'tearRate'\],最后一个为类别,类别包含三种类型\['no lenses', 'hard', 'soft' \]。 33 | 34 | 基本思路:构建一个树形结构的输出,选择信息增益最大的特征作为节点,非叶子节点都是特征,节点上的特征将数据集分成各个子集,然后再递归。 35 | 36 | ``` 37 | # -*- coding: utf-8 -*- 38 | 39 | from math import log 40 | from collections import Counter 41 | 42 | class DecisionTree(object): 43 | def __init__(self, input_data, labels): 44 | pass 45 | 46 | def create_decision_tree(self, data_set, labels): # 输出树形结构 47 | class_list = [data[-1] for data in data_set] 48 | if class_list.count(class_list[0]) == len(class_list): # 如果剩下的数据集的类别都一样 49 | return class_list[0] 50 | if len(data_set[0]) == 1: # 如果数据集没有特征,只剩下类别,选择类别最多的输出 51 | major_label = Counter(data_set).most_common(1)[0] 52 | return major_label 53 | 54 | feature_index = self.get_feature_with_biggest_gain(data_set, labels) # 获取最大信息增益的特征 55 | feature_name = labels[feature_index] 56 | del labels[feature_index] 57 | 58 | feature_set = set([ data[feature_index] for data in data_set ]) # 找到该特征的所有可能取值 59 | decision_tree = {feature_name: {}} 60 | for i in feature_set: 61 | # 遍历该特征的所有取值,将数据集分割成各个子集,然后递归对各个子集进行同样的特征选择 62 | feature_data_list = [ data for data in data_set if data[feature_index] == i ] # 满足 63 | new_data_list = [] 64 | for j in feature_data_list: # 移除已经选择的特征,获取子集 65 | new_data = j[:] 66 | del new_data[feature_index] 67 | new_data_list.append(new_data) 68 | #print(i, new_data_list) 69 | new_lables = labels[:] 70 | decision_tree[feature_name][i] = self.create_decision_tree(new_data_list, new_lables) 71 | 72 | return decision_tree 73 | 74 | def cal_data_set_entropy(self, data_set): # 计算数据集的经验熵 75 | total_num = len(data_set) 76 | class_list = [data[-1] for data in data_set] 77 | class_dict = dict() 78 | for i in class_list: 79 | ck_num = class_dict.get(i, 0) 80 | class_dict[i] = ck_num + 1 81 | 82 | entropy = 0 83 | for k in class_dict: 84 | ck_rate = float(class_dict[k])/total_num 85 | entropy -= ck_rate * log(ck_rate, 2) 86 | return entropy 87 | 88 | def get_feature_with_biggest_gain(self, data_set, labels): #获取最大信息增益的特征 89 | feature_num = len(labels) 90 | data_entropy = self.cal_data_set_entropy(data_set) 91 | biggest_gain_index = None 92 | biggest_gain = 0 93 | for i in range(feature_num): 94 | # 遍历所有特征,找出最大的信息增益特征 95 | condition_entroy = self.cal_feature_condition_entropy(data_set, i) 96 | gain = data_entropy - condition_entroy 97 | if gain > biggest_gain: 98 | biggest_gain_index = i 99 | biggest_gain = gain 100 | #print(labels[biggest_gain_index], biggest_gain) 101 | return biggest_gain_index 102 | 103 | def cal_feature_condition_entropy(self, data_set, index): # 计算某个特征的条件熵 104 | total_num = len(data_set) 105 | feature_list = [data[index] for data in data_set] 106 | feature_dict = dict() 107 | for i in feature_list: 108 | feature_num = feature_dict.get(i, 0) 109 | feature_dict[i] = feature_num + 1 110 | 111 | condition_entropy = 0 112 | for k in feature_dict: 113 | feature_rate = float(feature_dict[k])/total_num 114 | feature_data_set = [data for data in data_set if data[index] == k] 115 | entropy = self.cal_data_set_entropy(feature_data_set) 116 | condition_entropy += feature_rate * entropy 117 | return condition_entropy 118 | 119 | train_data = "*/input/3.DecisionTree/lenses.txt" 120 | with open(train_data) as f: 121 | lenses = [line.strip().split('\t') for line in f.readlines()] # 特征之间用tab键隔离开 122 | labels = ['age', 'prescript', 'astigmatic', 'tearRate'] 123 | 124 | #[['young', 'myope', 'no', 'reduced', 'no lenses'], 125 | # ['young', 'myope', 'no', 'normal', 'soft'] 126 | dTree = DecisionTree(lenses, labels) 127 | print(dTree.create_decision_tree(lenses, labels)) 128 | ``` 129 | 130 | ``` 131 | {'tearRate': {'reduced': 'no lenses', 132 | 'normal': {'astigmatic': {'yes': {'prescript': {'hyper': {'age': {'pre': 'no lenses', 133 | 'presbyopic': 'no lenses', 134 | 'young': 'hard'}}, 135 | 'myope': 'hard'}}, 136 | 'no': {'age': {'pre': 'soft', 137 | 'presbyopic': {'prescript': {'hyper': 'soft', 138 | 'myope': 'no lenses'}}, 139 | 'young': 'soft'}} 140 | } 141 | } 142 | } 143 | } 144 | ``` 145 | 146 | 如果画成树形结构: 147 | 148 | ![](/assets/lenses_decision_tree.png) 149 | 150 | 树形结构代码参考:[https://github.com/apachecn/MachineLearning/blob/master/src/py3.x/3.DecisionTree/decisionTreePlot.py](https://github.com/apachecn/MachineLearning/blob/master/src/py3.x/3.DecisionTree/decisionTreePlot.py) 151 | 152 | -------------------------------------------------------------------------------- /jue-ce-shu/te-zheng-xuan-ze.md: -------------------------------------------------------------------------------- 1 | 特征选择在于选取对训练集有分类能力的特征,这样可以提高决策树学习的效率。 2 | 3 | 通常特征选择的准则是信息增益或信息增益比。 4 | 5 | ### 1. 信息增益 6 | 7 | 信息增益(information gain)表示得知特征$$X$$的信息而使得类$$Y$$的信息不确定性减少量。 8 | 9 | 特征$$A$$对训练数据集$$D$$的信息增益$$g(D,A)$$,定义为集合$$D$$的经验熵$$H(D)$$与特征$$A$$在给定条件下$$D$$的经验条件熵$$H(D|A)$$之差,即 10 | 11 | 12 | $$ 13 | g(D,A)=H(D)-H(D|A) 14 | $$ 15 | 16 | 17 | 一般地,熵$$H(X)$$与条件熵$$H(Y|X)$$之差称为互信息\(mutual information\)。 18 | 19 | 关于[熵](/shu-xue-ji-chu/xin-xi-lun/shang.md)、[[条件熵](/shu-xue-ji-chu/xin-xi-lun/shang.md)](/shu-xue-ji-chu/xin-xi-lun/tiao-jian-shang.md)、[互信息](/shu-xue-ji-chu/xin-xi-lun/hu-xin-xi.md)参考链接。关于信息增益和互信息之间的差别,参考[https://www.zhihu.com/question/39436574](https://www.zhihu.com/question/39436574。)。 20 | 21 | 在给定训练数据集$$D$$和特征$$A$$,经验熵$$H(D)$$表示对数据集$$D$$进行分类的不确定性。而经验条件熵$$H(D|A)$$表示在特征$$A$$给定的条件下对数据集$$D$$进行分类的不确定性,那么它们的差就表示由于特征$$A$$而使得对数据集$$D$$的分类的不确定性减少的程度。信息增益大的特征具有更强的分类能力。 22 | 23 | #### 信息增益的算法 24 | 25 | 假设训练数据集为$$D$$,$$|D|$$表示样本容量,即样本个数。设有$$K$$个类$$C_k$$,$$k=1,2,...,K$$,$$|C_k|$$为属于类$$C_k$$的样本个数,$$\displaystyle\sum_{k=1}^K|C_k|=|D|$$。 26 | 27 | 设特征$$A$$有$$n$$个不同的取值$${a_1,a_2,...,a_n}$$,根据特征$$A$$的取值将$$D$$划分为$$n$$个子集$$D_1,D_2,...,D_n$$,$$|D_i|$$为$$D_i$$的样本个数,$$\displaystyle\sum_{i=1}^n|D_k|=|D|$$。记子集$$D_i$$中属于类$$C_k$$的样本集合为$$D_{ik}$$,$$|D_{ik}|$$为$$D_{ik}$$的样本个数。 28 | 29 | **算法:** 30 | 31 | 输入:训练数据集$$D$$和特征$$A$$ 32 | 33 | 输出:特征$$A$$对训练数据集$$D$$的信息增益$$g(D,A)$$ 34 | 35 | 1)计算数据集$$D$$的经验熵$$H(D)$$ 36 | 37 | 38 | $$ 39 | H(D)=-\displaystyle\sum_{k=1}^K \dfrac{|C_k|}{|D|}\mathrm{log}_2 {\dfrac{|C_k|}{|D|}} 40 | $$ 41 | 42 | 43 | 2)计算特征$$A$$对数据集$$D$$的经验条件熵$$H(D|A)$$ 44 | 45 | 46 | $$ 47 | H(D|A)=\displaystyle\sum_{i=1}^n \dfrac{|D_i|}{|D|}H(D_i)=-\displaystyle\sum_{i=1}^n \dfrac{|D_i|}{|D|}\displaystyle\sum_{k=1}^K \dfrac{|D_{ik}|}{|D_i|}\mathrm{log}_2 {\dfrac{|D_{ik}|}{|D_i|}} 48 | $$ 49 | 50 | 51 | 3)计算信息增益 52 | 53 | 54 | $$ 55 | g(D,A)=H(D)-H(D|A) 56 | $$ 57 | 58 | 59 | 示例: 60 | 61 | 贷款申请样本数据表: 62 | 63 | | ID | 年龄 | 有工作 | 有自己的房子 | 信贷情况 | 类别 | 64 | | :--- | :--- | :--- | :--- | :--- | :--- | 65 | | 1 | 青年 | 否 | 否 | 一般 | 否 | 66 | | 2 | 青年 | 否 | 否 | 好 | 否 | 67 | | 3 | 青年 | 是 | 否 | 好 | 是 | 68 | | 4 | 青年 | 是 | 是 | 一般 | 是 | 69 | | 5 | 青年 | 否 | 否 | 一般 | 否 | 70 | | 6 | 中年 | 否 | 否 | 一般 | 否 | 71 | | 7 | 中年 | 否 | 否 | 好 | 否 | 72 | | 8 | 中年 | 是 | 是 | 好 | 是 | 73 | | 9 | 中年 | 否 | 是 | 非常好 | 是 | 74 | | 10 | 中年 | 否 | 是 | 非常好 | 是 | 75 | | 11 | 老年 | 否 | 是 | 非常好 | 是 | 76 | | 12 | 老年 | 否 | 是 | 好 | 是 | 77 | | 13 | 老年 | 是 | 否 | 好 | 是 | 78 | | 14 | 老年 | 是 | 否 | 非常好 | 是 | 79 | | 15 | 老年 | 否 | 否 | 一般 | 否 | 80 | 81 | 1)计算经验熵$$H(D)$$,样本中“是”有9个,“否”有6个 82 | 83 | 84 | $$ 85 | H(D)=-\dfrac{9}{15}\mathrm{log}_2\dfrac{9}{15}-\dfrac{6}{15}\mathrm{log}_2\dfrac{6}{15}=0.971 86 | $$ 87 | 88 | 89 | 2)计算各个特征对数据集的信息增益,$$A_1$$:年龄,$$A_2$$:有工作,$$A_3$$:有房子,$$A_4$$:信贷情况 90 | 91 | $$H(D|A_1)=\dfrac{5}{15}H(D_1)+\dfrac{5}{15}H(D_2)+\dfrac{5}{15}H(D_3)$$ 92 | 93 | $$=\dfrac{5}{15}(-\dfrac{2}{5}\mathrm{log}_2\dfrac{2}{5}-\dfrac{3}{5}\mathrm{log}_2\dfrac{3}{5})+\dfrac{5}{15}(-\dfrac{3}{5}\mathrm{log}_2\dfrac{3}{5}-\dfrac{2}{5}\mathrm{log}_2\dfrac{2}{5})+\dfrac{5}{15}(-\dfrac{4}{5}\mathrm{log}_2\dfrac{4}{5}-\dfrac{1}{5}\mathrm{log}_2\dfrac{1}{5})=0.888$$ 94 | 95 | $$H(D|A_2)=\dfrac{5}{15}H(D_1)+\dfrac{10}{15}H(D_2)$$ 96 | 97 | $$H(D|A_3)=\dfrac{6}{15}H(D_1)+\dfrac{9}{15}H(D_2)$$ 98 | 99 | $$H(D|A_4)=\dfrac{5}{15}H(D_1)+\dfrac{6}{15}H(D_2)+\dfrac{4}{15}H(D_3)$$ 100 | 101 | 3)计算信息增益: 102 | 103 | $$g(D,A_1)=H(D)-H(D|A_1)=0.971-0.888=0.083$$ 104 | 105 | $$g(D,A_2)=H(D)-H(D|A_2)=0.971-0.647=0.324$$ 106 | 107 | $$g(D,A_3)=H(D)-H(D|A_3)=0.971-0.551=0.420$$ 108 | 109 | $$g(D,A_4)=H(D)-H(D|A_4)=0.971-0.608=0.363$$ 110 | 111 | 其中$$g(D,A_3)$$最大,因此先选择特征$$A_3$$。 112 | 113 | ### 2. 信息增益比 114 | 115 | 以信息增益比作为划分训练数据集的特征,存在偏向于选择取值较多的特征的问题。 116 | 117 | 使用信息增益比\(information gain ratio\)可以对这个问题进行校正。 118 | 119 | 特征$$A$$对训练数据集$$D$$的信息增益比$$g_{\small R}(D,A)$$定义为信息增益$$g(D,A)$$与训练数据集$$D$$关于特征$$A$$的值的熵$$H_A(D)$$之比,即 120 | 121 | 122 | $$ 123 | g_{\small R}(D,A)=\dfrac{g(D,A)}{H_A(D)} 124 | $$ 125 | 126 | 127 | 其中$$H_A(D)=-\displaystyle\sum_{i=1}^n \dfrac{|D_i|}{|D|}\mathrm{log}_2 {\dfrac{|D_i|}{|D|}}$$,$$n$$是特征$$A$$的取值个数。 128 | 129 | ### 3. 基尼指数 130 | 131 | 分类问题中,假设有$$K$$个类,样本点属于第$$k$$类的概率为$$p_k$$,则概率分布的基尼指数定义为 132 | 133 | 134 | $$ 135 | Gini(p)=\displaystyle\sum_{k=1}^K p_k(1-p_k)=1-\displaystyle\sum_{k=1}^Kp^2_k 136 | $$ 137 | 138 | 139 | 对于二分类问题,若样本属于第一个类的概率为$$p$$,则概率分布的基尼指数为 140 | 141 | 142 | $$ 143 | Gini(p)=2p(1-p) 144 | $$ 145 | 146 | 147 | 对于给定的样本集合$$D$$,其基尼指数为 148 | 149 | 150 | $$ 151 | Gini(D)=1-\displaystyle\sum_{k=1}^K \dfrac{|C_k|^2}{|D|^2} 152 | $$ 153 | 154 | 155 | 这里$$C_k$$是$$D$$中属于第$$k$$类的样本子集,$$K$$是类的个数。 156 | 157 | 如果样本集合$$D$$根据特征$$A$$是否取某一个可能的$$\alpha$$被分割成$$D_1$$和$$D_2$$两部分,即 158 | 159 | 160 | $$ 161 | D_1= \{(x,y)\in D|A(x)=\alpha\},\ \ \ D_2=D-D_1 162 | $$ 163 | 164 | 165 | 则在特征$$A$$的条件下,集合$$D$$的基尼指数定义为: 166 | 167 | 168 | $$ 169 | Gini(D,A)=\dfrac{|D_1|}{|D|}Gini(D_1)+\dfrac{|D_2|}{|D|}Gini(D_2) 170 | $$ 171 | 172 | 173 | 基尼指数$$Gini(D)$$表示集合$$D$$的不确定性,基尼指数$$Gini(D,A)$$表示经过$$A=\alpha$$分割后集合$$D$$的不确定性。基尼指数越大,样本集合的不确定性也越大,这一点与熵相似。在选择特征的时候,选择基尼指数最小(也就是不确定性最小)的特征及其对应的切分点作为最优特征和切分点。 174 | 175 | 根据上表计算基尼指数: 176 | 177 | $$A_1$$:年龄(1,2,3分别表示青,中,老年), 178 | 179 | $$Gini(D,A_1=1)=\dfrac{5}{15}(2\cdot\dfrac{2}{5}\cdot (1-\dfrac{2}{5}))+\dfrac{10}{15}(2\cdot\dfrac{7}{10}\cdot (1-\dfrac{7}{10}))=0.44$$ 180 | 181 | $$Gini(D,A_1=2)=0.48$$ 182 | 183 | $$Gini(D,A_1=3)=0.44$$ 184 | 185 | 由于$$Gini(D,A_1=1)$$和$$Gini(D,A_1=1)$$相等且最小,所以$$A_1=1,A_1=3$$都可以作为$$A_1$$的最优切分点。 186 | 187 | $$A_2$$:有工作(1,2分别表示有,无工作), 188 | 189 | $$Gini(D,A_2=1)=0.32$$ 190 | 191 | $$A_3$$:有房子(1,2分别表示有,无房子) 192 | 193 | $$Gini(D,A_3=12)=0.27$$ 194 | 195 | $$A_2$$和$$A_3$$只有一个切分点,所以它们就是最优切分点。 196 | 197 | $$A_4$$:信贷情况(1,2,3分别表示信贷非常好,好,一般) 198 | 199 | $$Gini(D,A_4=1)=0.36$$,$$Gini(D,A_4=2)=0.47$$,$$Gini(D,A_4=3)=0.32$$ 200 | 201 | $$Gini(D,A_4=3)$$最小,所以为$$A_4$$的最优切分点。 202 | 203 | 在$$A_1,A_2,A_3,A_4$$中,$$Gini(D,A_3=12)=0.27$$最小,所以选择特征$$A_3$$为最优特征,且$$A_3=1$$为最优切分点。 204 | 205 | -------------------------------------------------------------------------------- /kjin-lin-fa.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/kjin-lin-fa.md -------------------------------------------------------------------------------- /kjin-lin-fa/kdshu-fang-fa.md: -------------------------------------------------------------------------------- 1 | ### kd树方法 2 | 3 | $$kd$$树是一种对$$k$$维空间中的实例点进行存储以便对其进行快速检索的树形结构。它是二叉树,表示对$$k$$维空间的一个划分(partition)。构造$$kd$$树相当于不断地用垂直于坐标轴的超平面将$$k$$维空间划分,构成一列的$$k$$维超矩形区域。$$kd$$树的每个节点对应于一个$$k$$维超矩形区域。 4 | 5 | ![](/assets/kd-tree.png) 6 | 7 | > pic source: [http://homes.sice.indiana.edu/yye/lab/teaching/spring2014-C343/moretrees.php](http://homes.sice.indiana.edu/yye/lab/teaching/spring2014-C343/moretrees.php) 8 | 9 | #### 1. 构造平衡$$kd$$树算法 10 | 11 | **输入:**$$k$$维空间数据集$$T=\{x^{(1)},x^{(2)},...,x^{(m)}\}$$,其中$$x^{(i)}=(x_1, x_2, ..., x_k)^T$$,$$i=1,2,...,m$$ 12 | 13 | **输出:**kd树 14 | 15 | 1)开始:构造根节点,根节点对应于包含$$T$$的$$k$$维空间的超矩形区域。 16 | 17 | 选择$$x_1$$为坐标轴,以$$T$$中所有实例的$$x_1$$坐标的中位数为切分点,将根节点对应的超矩形区域切分为两个子区域。切分由通过切分点并与坐标轴$$x_1$$垂直的超平面实现。 18 | 19 | 由根节点生成深度为1的左右子树:左子树对应于坐标$$x_1$$的值小于切分点的子区域,右子树对应于坐标$$x_1$$的值大于切分点的子区域。 20 | 21 | 将落在切分超平面上的实例点保存在根节点。 22 | 23 | 2)重复:对于深度为$$l$$的节点,选择$$x_j$$为切分的坐标轴,$$j=l\pmod k+1$$,举例来讲就是第一次切分选择坐标$$x_1$$,第二次选择坐标$$x_2$$,第三次选择坐标$$x_3$$,当$$k$$维后,返回到$$x_1$$继续作为切分坐标。切分由通过切分点并与轴$$x_j$$垂直的超平面实现。 24 | 25 | 对于左右子树,以$$x_j$$坐标的中位数为切分点,并保存为子树的根节点,然后同样分成两个子树。 26 | 27 | 3)直到两个子区域没有实例存在时停止,从而形成$$kd$$树的区域划分。 28 | 29 | #### 2. kd树的最近邻搜索 30 | 31 | **输入:**已经构造好的$$kd$$树;目标点$$x$$ 32 | 33 | **输出:**$$x $$的最近邻 34 | 35 | 1)首先在$$kd$$树中找出包含目标点$$x$$的叶节点。方法是从根节点出发,递归地向下访问$$kd$$树,若目标点$$x$$当前维的坐标小于切分点的坐标,则往左子树查找,否则往右子树查找,一直到叶节点为止。 36 | 37 | 2)以此叶节点为“当前最邻近点” 38 | 39 | 3)递归往上回退,在每个节点上进行如下操作 40 | 41 | * 如果该节点的实例比当前保存的最近点的距离更近,则以该节点为“当前最邻近点” 42 | * 检查另一边子树有没有更近的点,如果有则从该节点往下找 43 | * 即检查当前节点的超平面是否跟以目标节点$$x $$为圆心,目标节点$$x$$与“当前最邻近点”的距离为半径构成的圆体相交。 44 | * 如果相交,可能在超平面的另外一侧有节点离目标节点更近,因此移动到超平面的另外一侧的递归执行搜索 45 | * 如果不相交,则向上回退 46 | 47 | 4)当回退到根节点时(根节点已经完成了步骤3 的操作),搜索结束,最后的“当前最近点”即为$$x$$的最邻近点。 48 | 49 | 如果实例点是随机分布的,则$$kd$$树搜索的平均计算复杂度是$$O(logN)$$。$$kd$$树更适用于训练实例数远大于空间维数的情况,如果训练实例数接近空间维数,则效率退化为线性扫描。 50 | 51 | #### 3. 例子 52 | 53 | **示例1:** 54 | 55 | > pic source: [http://blog.csdn.net/baimafujinji/article/details/52928203](http://blog.csdn.net/baimafujinji/article/details/52928203) 56 | 57 | ![](/assets/kd-tree3.png) 58 | 59 | ![](/assets/kd-tree4.png) 60 | 61 | ![](/assets/kd-tree5.png) 62 | 63 | ![](/assets/kd-tree6.png) 64 | 65 | 66 | 67 | **示例2:** 68 | 69 | 维基百科上的一个动画例子([https://en.wikipedia.org/wiki/K-d\_tree)](https://en.wikipedia.org/wiki/K-d_tree)) 70 | 71 | ![](/assets/KDTree-animation.gif) 72 | 73 | > By User A1 at English Wikipedia, CC BY-SA 3.0, [https://commons.wikimedia.org/w/index.php?curid=16242339](https://commons.wikimedia.org/w/index.php?curid=16242339) 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /kjin-lin-fa/kdshu-python-shi-xian.md: -------------------------------------------------------------------------------- 1 | ### kd树python实现 2 | 3 | #### 1. 首先在构造kd树的时需要寻找中位数,因此用快速排序来获取一个list中的中位数 4 | 5 | ``` 6 | import matplotlib.pyplot as plt 7 | import numpy as np 8 | 9 | class QuickSort(object): 10 | "Quick Sort to get medium number" 11 | 12 | def __init__(self, low, high, array): 13 | self._array = array 14 | self._low = low 15 | self._high = high 16 | self._medium = (low+high+1)//2 # python3中的整除 17 | 18 | def get_medium_num(self): 19 | return self.quick_sort_for_medium(self._low, self._high, 20 | self._medium, self._array) 21 | 22 | def quick_sort_for_medium(self, low, high, medium, array): #用快速排序来获取中位数 23 | if high == low: 24 | return array[low] # find medium 25 | if high > low: 26 | index, partition = self.sort_partition(low, high, array); 27 | #print array[low:index], partition, array[index+1:high+1] 28 | if index == medium: 29 | return partition 30 | if index > medium: 31 | return self.quick_sort_for_medium(low, index-1, medium, array) 32 | else: 33 | return self.quick_sort_for_medium(index+1, high, medium, array) 34 | 35 | def quick_sort(self, low, high, array): #正常的快排 36 | if high > low: 37 | index, partition = self.sort_partition(low, high, array); 38 | #print array[low:index], partition, array[index+1:high+1] 39 | self.quick_sort(low, index-1, array) 40 | self.quick_sort(index+1, high, array) 41 | 42 | def sort_partition(self, low, high, array): # 用第一个数将数组里面的数分成两部分 43 | index_i = low 44 | index_j = high 45 | partition = array[low] 46 | while index_i < index_j: 47 | while (index_i < index_j) and (array[index_j] >= partition): 48 | index_j -= 1 49 | if index_i < index_j: 50 | array[index_i] = array[index_j] 51 | index_i += 1 52 | while (index_i < index_j) and (array[index_i] < partition): 53 | index_i += 1 54 | if index_i < index_j: 55 | array[index_j] = array[index_i] 56 | index_j -= 1 57 | array[index_i] = partition 58 | return index_i, partition 59 | ``` 60 | 61 | #### 2. 构造kd树 62 | 63 | ``` 64 | class KDTree(object): 65 | 66 | def __init__(self, input_x, input_y): 67 | self._input_x = np.array(input_x) 68 | self._input_y = np.array(input_y) 69 | (data_num, axes_num) = np.shape(self._input_x) 70 | self._data_num = data_num 71 | self._axes_num = axes_num 72 | self._nearest = None #用来存储最近的节点 73 | return 74 | 75 | def construct_kd_tree(self): 76 | return self._construct_kd_tree(0, 0, self._input_x) 77 | 78 | def _construct_kd_tree(self, depth, axes, data): 79 | if not data.any(): 80 | return None 81 | axes_data = data[:, axes].copy() 82 | qs = QuickSort(0, axes_data.shape[0]-1, axes_data) 83 | medium = qs.get_medium_num() #找到轴的中位数 84 | 85 | data_list = [] 86 | left_data = [] 87 | right_data = [] 88 | data_range = range(np.shape(data)[0]) 89 | for i in data_range: # 跟中位数相比较 90 | if data[i][axes] == medium: #相等 91 | data_list.append(data[i]) 92 | elif data[i][axes] < medium: 93 | left_data.append(data[i]) 94 | else: 95 | right_data.append(data[i]) 96 | 97 | left_data = np.array(left_data) 98 | right_data = np.array(right_data) 99 | left = self._construct_kd_tree(depth+1, (axes+1)% self._axes_num, left_data) 100 | right = self._construct_kd_tree(depth+1, (axes+1)% self._axes_num, right_data) 101 | #[树的深度,轴,中位数,该节点的数据,左子树,右子树] 102 | root = [depth, axes, medium, data_list, left, right] 103 | return root 104 | 105 | def print_kd_tree(self, root): #打印kd树 106 | if root: 107 | [depth, axes, medium, data_list, left, right] = root 108 | print('{} {}'.format(' '*depth, data_list[0])) 109 | if root[4]: 110 | self.print_kd_tree(root[4]) 111 | if root[5]: 112 | self.print_kd_tree(root[5]) 113 | ``` 114 | 115 | 测试代码: 116 | 117 | ``` 118 | input_x = [[2,3], [6,4], [9,6], [4,7], [8,1], [7,2]] 119 | input_y = [1, 1, 1, 1, 1, 1] 120 | kd = KDTree(input_x, input_y) 121 | tree = kd.construct_kd_tree() 122 | kd.print_kd_tree(tree) 123 | 124 | #得到结果: 125 | [7 2] 126 | [6 4] 127 | [2 3] 128 | [4 7] 129 | [9 6] 130 | [8 1] 131 | ``` 132 | 133 | #### 3. 搜索kd树 134 | 135 | 在类中继续添加如下函数,基本的思想是将路径上的节点依次入栈,再逐个出栈。 136 | 137 | ``` 138 | def _get_distance(self, x1, x2): #计算两个向量之间的距离 139 | x = x1-x2 140 | return np.sqrt(np.inner(x, x)) 141 | 142 | def _search_leaf(self, stack, tree, target): #以tree为根节点,一直搜索到叶节点,并添加到stack中 143 | travel_tree = tree 144 | while travel_tree: 145 | [depth, axes, medium, data_list, left, right] = travel_tree 146 | if target[axes] >= medium: 147 | next_node = right 148 | next_direction = 'right' # 记录被访问过的子树的方向 149 | elif target[axes] < medium: 150 | next_node = left 151 | next_direction = 'left' # 记录被访问过的子树的方向 152 | stack.append([travel_tree, next_direction]) #保存方向,用来记录哪个子树被访问过 153 | travel_tree = next_node 154 | 155 | def _check_nearest(self, current, target): # 判断当前节点跟目标的距离 156 | d = self._get_distance(current, target) 157 | if self._nearest: 158 | [node, distance] = self._nearest 159 | if d < distance: 160 | self._nearest = [current, d] 161 | else: 162 | self._nearest = [current, d] 163 | 164 | def search_kd_tree(self, tree, target): #搜索kd树 165 | stack = [] 166 | self._search_leaf(stack, tree, target) # 一直搜索到叶节点,并将路径入栈 167 | self._nearest = [] 168 | while stack: 169 | [[depth, axes, medium, data_list, left, right], next_direction] = stack.pop() #出栈 170 | [data] = data_list 171 | self._check_nearest(data, target) #检查当前节点的距离 172 | 173 | if left is None and right is None: #如果当前节点为叶节点,继续下一个循环 174 | continue 175 | [node, distance] = self._nearest 176 | if abs(data[axes] - node[axes]) < distance: #<*> 当前节点的轴经过圆 177 | if next_direction == 'right': # 判断哪个方向被访问过,转向相反方向 178 | try_node = left 179 | else: 180 | try_node = right 181 | self._search_leaf(stack, try_node, target) #往相反的方向搜索叶节点 182 | print(self._nearest) 183 | ``` 184 | 185 | 测试代码: 186 | 187 | ``` 188 | kd.search_kd_tree(tree, [7.1, 4.1]) 189 | > [array([6, 4]), 1.1045361017187258] 190 | 191 | kd.search_kd_tree(tree, [9, 2]) 192 | > [array([8, 1]), 1.4142135623730951] 193 | 194 | kd.search_kd_tree(tree, [6, 2]) 195 | > [array([7, 2]), 1.0] 196 | ``` 197 | 198 | #### 4. 寻找k个最近节点 199 | 200 | 如果要寻找k个最近节点,则需要保存k个元素的数组,并在函数`_check_nearest`中与k个元素做比较,然后在标记`<*>`的地方跟k个元素的最大值比较。其他代码略。 201 | 202 | ``` 203 | def _check_nearest(self, current, target, k): 204 | d = self._get_distance(current, target) 205 | #print current, d 206 | l = len(self._nearest) 207 | if l < k: 208 | self._nearest.append([current, d]) 209 | else: 210 | farthest = self._get_farthest()[1] 211 | if farthest > d: 212 | # 将最远的节点移除 213 | new_nearest = [i for i in self._nearest if i[1] [[array([7, 2]), 2.1023796041628633], [array([6, 4]), 1.1045361017187258]] 233 | 234 | kd.search_kd_tree(tree, [9, 2], k=2) 235 | > [[array([8, 1]), 1.4142135623730951], [array([7, 2]), 2.0]] 236 | 237 | kd.search_kd_tree(tree, [6, 2], k=2) 238 | > [[array([6, 4]), 2.0], [array([7, 2]), 1.0]] 239 | ``` 240 | 241 | #### 5.其他 242 | 243 | 这里的算法没有考虑到下面的情况: 244 | 245 | * 多个数据点在同一个超平面上 246 | * 有多个数据点跟目标节点的距离相同 247 | 248 | 249 | 250 | -------------------------------------------------------------------------------- /kjin-lin-fa/kjin-lin-mo-xing.md: -------------------------------------------------------------------------------- 1 | ### k近邻模型 2 | 3 | $$k$$近邻(k-Nearest Neighbor,简称kNN)学习是一种常用的监督式学习方法,其工作机制非常简单: 4 | 5 | 给定测试样本,基于某种距离度量找出训练集中与其最靠近的$$k$$个训练样本,然后基于这$$k$$个“邻居”的信息来进行预测。通常,在分类任务中可使用“投票法”,即选择这$$k$$个样本中出现最多的类别标记作为预测结果;在回归任务中可以使用“平均法”,即将这$$k$$个样本的实值输出标记的平均值作为预测结果;还可以基于距离远近进行加权平均或加权投票,距离越近的样本权重越大。 6 | 7 | $$k$$近邻有个明显的不同之处:它似乎没有显示的训练过程。事实上,它是“懒惰学习”(lazy learning)的著名代表,此类学习技术在训练阶段仅仅是把样本保存起来,训练时间开销为0,待收到测试样本后再进行处理,这种称为“急切学习”。 8 | 9 | ![](/assets/knn-concept.png) 10 | 11 | > pic source: [https://helloacm.com/a-short-introduction-to-k-nearest-neighbors-algorithm/](https://helloacm.com/a-short-introduction-to-k-nearest-neighbors-algorithm/) 12 | 13 | #### 1.距离度量 14 | 15 | 特征空间中两个实例点的距离是两个实例点的相似度的反映。$$k$$近邻模型的特征空间一般是$$n$$维实数向量空间$$R^n$$。使用的距离是欧式距离,但也可以使其他距离,比如更一般的$$L_p$$距离($$L_p$$ distance),或Minkowski距离。 16 | 17 | 设特征空间$$X$$是$$n$$维实数向量空间$$R^n$$,$$x^{(i)},x^{(j)}\in X$$,$$x=(x_0, x_1, x_2, ..., x_n)^T$$,$$x^{(i)},x^{(j)}$$的$$L_p$$距离定义为: 18 | 19 | 20 | $$ 21 | L_p(x^{(i)},x^{(j)})=\big( \displaystyle\sum_{k=1}^n|x^{(i)}_k-x^{(j)}_k|^p\big)^{\frac{1}{p}} 22 | $$ 23 | 24 | 25 | 这里$$p \geqslant 1$$。当$$p=2$$时,称为**欧式距离**(Euclidean distance),即 26 | 27 | 28 | $$ 29 | L_2(x^{(i)},x^{(j)})=\big( \displaystyle\sum_{k=1}^n|x^{(i)}_k-x^{(j)}_k|^2\big)^{\frac{1}{2}} 30 | $$ 31 | 32 | 33 | 当$$p=1$$时,称为**曼哈顿距离**(Manhanttan distance),即 34 | 35 | 36 | $$ 37 | L_1(x^{(i)},x^{(j)})=\displaystyle\sum_{k=1}^n|x^{(i)}_k-x^{(j)}_k| 38 | $$ 39 | 40 | 41 | 当$$p=\infty$$时,它是各个坐标距离的最大值,即: 42 | 43 | 44 | $$ 45 | L_\infty(x^{(i)},x^{(j)})=\max_k|x^{(i)}_k-x^{(j)}_k| 46 | $$ 47 | 48 | 49 | 下图给出了$$p$$取不同值时,与原点的$$L_p$$距离为$$1$$($$L_p=1$$)的图形。 50 | 51 | ![](/assets/lp_distance_1.png) 52 | 53 | #### 2. k近邻算法 54 | 55 | 输入:训练集 56 | 57 | 58 | $$ 59 | T=\{(x^{(1)},y^{(1)}),(x^{(2)},y^{(2)}),...,(x^{(m)},y^{(m)})\} 60 | $$ 61 | 62 | 63 | 其中$$x^{(i)}\in X= R^n$$为实例的特征向量,$$y^{(i)}\in Y=\{c_1, c_2, ...,c_t\}$$为实例的类别,$$i=1,2,...,m$$。某个实例特征向量$$x$$。 64 | 65 | 输出:实例$$x$$的所属类别$$y$$ 66 | 67 | 1)根据给定的距离度量,在训练集$$T$$中找出与$$x$$最邻近的$$k$$个点,涵盖这$$k$$个点的邻域记作$$N_k (x)$$; 68 | 69 | 2)在$$N_k (x)$$中根据分类决策规则(如多数表决)决定$$x$$的类别: 70 | 71 | 72 | $$ 73 | y=arg \max_{c_j} \displaystyle\sum_{x_i\in N_k (x)} I(y_i=c_j) 74 | $$ 75 | 76 | 77 | 其中$$i=1,2,...,m$$,$$j=1,2,...,t$$,$$I$$为指示函数,即当$$y_i=c_j$$时为$$1$$,否则为$$0$$。 78 | 79 | $$k$$近邻的特殊情况是$$k=1$$的情形,称为最近邻算法。对于输入的实例点$$x$$,最近邻算法将训练数据集中与$$x $$最近的类作为$$x $$的类。 80 | 81 | $$k$$值的选择会对$$k$$近邻法的结果产生重大影响。 82 | 83 | 如果选择较小的$$k$$值,“学习”的估计误差(estmation error)会增大,预测的结果会对近邻的节点比较敏感。 84 | 85 | 如果寻则较大的$$k$$值,“学习”的近似误差(approximation error)会增大,与输入实例较远的训练实例也会对预测起作用,使预测发生错误。 86 | 87 | 实际中,$$k$$一般取一个比较小的数值,并采用交叉验证法来选取最优的$$k$$值。 88 | 89 | k近邻法最简单的办法就是线性扫描(linear scan),这时要计算输入实例和每一个训练实例的距离,当训练集很大时,非常耗时,这种方法不可行。 90 | 91 | 下面介绍$$kd$$树($$kd$$ tree)方法。 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /kjin-lin-fa/knnshi-li.md: -------------------------------------------------------------------------------- 1 | ### 用k近邻算法识别手写数字 2 | 3 | 本例来自《机器学习实战》第二章,采用直接计算两点之间距离的方式来找出k最近邻 4 | 5 | 判断手写的数字,数据被转成32x32(=128)的0-1数字矩阵 6 | 7 | ``` 8 | 00000000000001100000000000000000 9 | 00000000000011111100000000000000 10 | 00000000000111111111000000000000 11 | 00000000011111111111000000000000 12 | 00000001111111111111100000000000 13 | 00000000111111100011110000000000 14 | 00000001111110000001110000000000 15 | 00000001111110000001110000000000 16 | 00000011111100000001110000000000 17 | 00000011111100000001111000000000 18 | 00000011111100000000011100000000 19 | 00000011111100000000011100000000 20 | 00000011111000000000001110000000 21 | 00000011111000000000001110000000 22 | 00000001111100000000000111000000 23 | 00000001111100000000000111000000 24 | 00000001111100000000000111000000 25 | 00000011111000000000000111000000 26 | 00000011111000000000000111000000 27 | 00000000111100000000000011100000 28 | 00000000111100000000000111100000 29 | 00000000111100000000000111100000 30 | 00000000111100000000001111100000 31 | 00000000011110000000000111110000 32 | 00000000011111000000001111100000 33 | 00000000011111000000011111100000 34 | 00000000011111000000111111000000 35 | 00000000011111100011111111000000 36 | 00000000000111111111111110000000 37 | 00000000000111111111111100000000 38 | 00000000000011111111110000000000 39 | 00000000000000111110000000000000 40 | ``` 41 | 42 | 数据源 [https://github.com/apachecn/MachineLearning/tree/python-2.7/input/2.KNN](https://github.com/apachecn/MachineLearning/tree/python-2.7/input/2.KNN) 43 | 44 | 数据源被分成两个部分,一部分是训练数据,一部分是测试数据 45 | 46 | ``` 47 | # -*- coding: utf-8 -*- 48 | 49 | import matplotlib.pyplot as plt 50 | import numpy as np 51 | import operator as op 52 | import os 53 | 54 | class KNN(object): 55 | 56 | def get_k_nearest(self, input_x, input_y, target, k): 57 | # 计算目标跟所有数据的距离,找出最近的几个,并将数量最多的标签输出 58 | nearest = [] 59 | (data_num, axes_num) = np.shape(input_x) 60 | repeat_target = np.tile(target, (data_num, 1)) # 将目标向量扩展成数据集一样数量的矩阵 61 | diff_matrix = repeat_target - input_x # 相减后,矩阵中的每个元素为 x1-y1 62 | square = np.multiply(diff_matrix, diff_matrix) # 每个元素做平方 63 | distance = square.sum(axis=1) # 计算距离 (x1-x21)^2 + x 64 | sorted_distance = distance.argsort() # 排序 65 | class_count = {} 66 | for i in range(k): 67 | lable = input_y[sorted_distance[i]] 68 | class_count[lable] = class_count.get(lable, 0) + 1 69 | sorted_class = sorted(class_count.iteritems(), 70 | key=op.itemgetter(1), # 依照第二个元素排序 71 | reverse=True) # 找出k个中最大 72 | return sorted_class[0][0] 73 | 74 | def digit_test(self, train_dir, test_dir): # 查找近似的数字 75 | def img_to_vector(file_name): # 将单个数字的数据存为向量 76 | return_vector = np.zeros(1024) 77 | f = open(file_name) 78 | sequence = range(32) 79 | for i in sequence: 80 | line = f.readline() 81 | for j in sequence: 82 | return_vector[32*i + j] = int(line[j]) 83 | return return_vector 84 | 85 | input_y = [] 86 | input_x = [] 87 | train_files = os.listdir(train_dir) 88 | for i in train_files: # 将所有文件的数据都存为矩阵 89 | lable = int(i.split('_')[0]) 90 | input_y.append(lable) 91 | input_x.append(img_to_vector('{}/{}'.format(train_dir,i))) 92 | 93 | input_x = np.array(input_x) 94 | input_y = np.array(input_y) 95 | test_files = os.listdir(test_dir) 96 | error = 0 97 | for i in test_files: 98 | lable = int(i.split('_')[0]) 99 | test_vector = img_to_vector('{}/{}'.format(test_dir,i)) 100 | predict_lable = self.get_k_nearest(input_x, input_y, test_vector, 3) # 执行knn 101 | #print("origin {}, predict {}".format(lable, predict_lable)) 102 | if predict_lable == lable: 103 | continue 104 | error += 1 105 | print("error number is {}".format(error)) 106 | 107 | knn = KNN() 108 | train_dir = "path/to/input/2.KNN/trainingDigits/" 109 | test_dir = "path/to/input/2.KNN/testDigits/" 110 | knn.digit_test(train_dir, test_dir) 111 | ``` 112 | 113 | 结果: 114 | 115 | ``` 116 | error number is 12 117 | ``` 118 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /logistichui-gui.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/logistichui-gui.md -------------------------------------------------------------------------------- /logistichui-gui/logisticfen-bu.md: -------------------------------------------------------------------------------- 1 | ### Logistic分布 2 | 3 | Logistic分布的定义:设$$X$$是连续随机变量,$$X$$服从Logistic分布是指具有下列分布函数和密度函数: 4 | 5 | 6 | $$ 7 | F(x)=P(X\leqslant x)= \dfrac{1}{1+e^{-(x-\mu)/\gamma}} 8 | $$ 9 | 10 | 11 | 12 | $$ 13 | f(x)=F'(X\leqslant x)= \dfrac{e^{-(x-\mu)/\gamma}}{\gamma(1+e^{-(x-\mu)/\gamma})^2} 14 | $$ 15 | 16 | 17 | 其中,$$\mu$$为位置参数,$$\gamma \gt0$$为形状参数。 18 | 19 | 概率分布函数如下($$\mu$$是位置函数,改变它可以平移图形): 20 | 21 | ![](/assets/logistic_1.png) 22 | 23 | 分布函数属于Logistic函数,是一条S形曲线(sigmoid curve)。该曲线以点$$(\mu, \dfrac{1}{2})$$为中心对称,即满足 24 | 25 | 26 | $$ 27 | F(-x+\mu)- \dfrac{1}{2} = -F(x+\mu) + \dfrac{1}{2} 28 | $$ 29 | 30 | 31 | 曲线在中心附近增长速度比较快,两端增长速度比较慢。形状参数$$\gamma$$的值越小,曲线在中心附近增长的越快。 32 | 33 | 概率密度函数: 34 | 35 | ![](/assets/logistic_2.png) 36 | 37 | -------------------------------------------------------------------------------- /logistichui-gui/logistichui-gui-mo-xing.md: -------------------------------------------------------------------------------- 1 | ## Logistic回归模型 2 | 3 | 二项Logistic回归模型(binomial logistic regression model)是一种分类模型,由条件概率分布$$P(Y|X)$$表示,形式为参数化的logistic分布。 4 | 5 | #### 一、模型定义 6 | 7 | 模型是如下的条件概率分布: 8 | 9 | 10 | $$ 11 | P(Y=1|X)=\dfrac{e^{w\cdot x+b}}{1+e^{w\cdot x+b}} 12 | $$ 13 | 14 | 15 | 16 | $$ 17 | P(Y=0|X)=1-P(Y=1|X)=\dfrac{1}{1+e^{w\cdot x+b}} 18 | $$ 19 | 20 | 21 | 这里$$x\in R^n$$,$$Y\in {0, 1}$$,$$w \in R^n$$和$$b\in R$$是参数,$$w$$称为权值,$$b$$称为偏置。 22 | 23 | 给定输入实例$$x$$计算得到$$P(Y=1|x)$$和$$P(Y=0|x)$$,然后比较两个条件概率的大小,将实例$$x$$分到概率值较大的那一类。 24 | 25 | 为了方便,将权值向量和输入向量加以扩展,即令$$w_0=b$$,$$x_0=1$$,扩展为 26 | 27 | 28 | $$ 29 | w=(w_0,w_1, w_2, ..., w_n)^T 30 | $$ 31 | 32 | 33 | 34 | $$ 35 | x=(x_0, x_1, x_2, ..., x_n)^T 36 | $$ 37 | 38 | 39 | 这样,上面的模型变成: 40 | 41 | 42 | $$ 43 | P(Y=1|X)=\dfrac{e^{w\cdot x}}{1+e^{w\cdot x}} 44 | $$ 45 | 46 | 47 | 48 | $$ 49 | P(Y=0|X)=1-P(Y=1|X)=\dfrac{1}{1+e^{w\cdot x}} 50 | $$ 51 | 52 | 53 | ### 二、发生比 54 | 55 | 在统计和概率理论中,一个事件或者一个陈述的发生比(英语:Odds)是该事件发生和不发生的比率,公式为: 56 | 57 | 58 | $$ 59 | odds(p)=\dfrac{p}{1-p} 60 | $$ 61 | 62 | 63 | 其中$$p$$是该事件发生的概率,$$odds(p)$$是关于$$p$$的递增函数。 64 | 65 | 例如,如果一个人随机选择一星期7天中的一天,选择星期日的发生比是: $$\dfrac{1/7}{1-1/7}=1/6$$。不选择星期日的发生比是 $$6/1$$。 66 | 67 | 对odds取对数\(成为log of odds\),也就是$$log\dfrac{p}{1-p}$$,称为对数几率,这个在正式的数学文献中会记为$$logit(p)$$,即: 68 | 69 | 70 | $$ 71 | logit(p)=log\dfrac{p}{1-p} 72 | $$ 73 | 74 | 75 | 该函数还是关于$$p$$的递增函数。 76 | 77 | 在Logistic回归中,对于某个实例$$x$$: 78 | 79 | 80 | $$ 81 | log\dfrac{p}{1-p}=log\dfrac{P(Y=1|x)}{1-P(Y=1|x)}=w\cdot x 82 | $$ 83 | 84 | 85 | 也就是实例$$x $$输出$$Y=1$$的对数几率是$$x $$的线性函数。 86 | 87 | ### 三、极大似然估计 88 | 89 | 给定训练数据集$$T=\{(x^{(1)},y^{(1)}),(x^{(2)},y^{(2)}),...,(x^{(m)},y^{(m)})\}$$,其中,$$x^{(i)}=(1, x_1, x_2, ..., x_n)^T\in X= R^{n+1}$$,$$y^{(i)}\in Y=\{0, 1\}$$,应用极大似然估计发估计模型参数,从而得到Logistic回归模型。 90 | 91 | 设:$$P(Y=1|x)=\pi(x)=\dfrac{e^{w\cdot x}}{1+e^{w\cdot x}}$$,$$P(Y=0|x)=1-\pi(x)=\dfrac{1}{1+e^{w\cdot x}}$$ 92 | 93 | 则似然函数为: 94 | 95 | 96 | $$ 97 | \displaystyle\prod_{i=1}^m[\pi(x^{(i)})]^{y^{(i)}}[1-\pi(x^{(i)})]^{1-y^{(i)}} 98 | $$ 99 | 100 | 101 | 对数似然函数为: 102 | 103 | 104 | $$ 105 | L(w)=\displaystyle\sum_{i=1}^m[y^{(i)}ln\pi(x^{(i)})+(1-y^{(i)})ln(1-\pi(x^{(i)}))] 106 | $$ 107 | 108 | 109 | 110 | $$ 111 | =\displaystyle\sum_{i=1}^m[y^{(i)}ln\dfrac{\pi(x^{(i)})}{1-\pi(x^{(i)})}+ln(1-\pi(x^{(i)}))] 112 | $$ 113 | 114 | 115 | 116 | $$ 117 | =\displaystyle\sum_{i=1}^m[y^{(i)}(w\cdot x^{(i)})-ln(1+e^{w\cdot x^{(i)}})] 118 | $$ 119 | 120 | 121 | 该函数是高阶可导函数,对$$L(w)$$求极大值,即令每个样本的概率越大越好,得到$$w$$的估计值。 122 | 123 | 变换成求极小值: 124 | 125 | 126 | $$ 127 | \min_{w} L(w)=-\displaystyle\sum_{i=1}^m[y^{(i)}(w\cdot x^{(i)})-ln(1+e^{w\cdot x^{(i)}})] 128 | $$ 129 | 130 | 131 | 这样问题就变成了以对数似然函数为目标函数的最小值优化问题,Logistic回归学习中通常采用的方法是梯度下降和拟牛顿法。 132 | 133 | 计算梯度: 134 | 135 | 136 | $$ 137 | \dfrac{\partial L(w)}{\partial w_j}=-\dfrac{\partial \displaystyle\sum_{i=1}^m[y^{(i)}(w\cdot x^{(i)})-ln(1+e^{w\cdot x^{(i)}})]}{\partial w_j} 138 | $$ 139 | 140 | 141 | 142 | $$ 143 | = \displaystyle-\sum_{i=1}^m(y^{(i)}x^{(i)}_j)+\displaystyle\sum_{i=1}^m\dfrac{\partial ln(1+e^{w\cdot x^{(i)}})}{\partial w_j} 144 | $$ 145 | 146 | 147 | 148 | $$ 149 | = \displaystyle-\sum_{i=1}^m(y^{(i)}x^{(i)}_j)+\displaystyle\sum_{i=1}^m\dfrac{1}{1+e^{w\cdot x^{(i)}}}\dfrac{\partial e^{w\cdot x^{(i)}}}{\partial w_j} 150 | $$ 151 | 152 | 153 | 154 | $$ 155 | = \displaystyle-\sum_{i=1}^my^{(i)}x^{(i)}_j+\displaystyle\sum_{i=1}^m\dfrac{e^{w\cdot x^{(i)}}}{1+e^{w\cdot x^{(i)}}}x^{(i)}_j 156 | $$ 157 | 158 | 159 | 160 | $$ 161 | = \displaystyle\sum_{i=1}^m\big(\dfrac{e^{w\cdot x^{(i)}}}{1+e^{w\cdot x^{(i)}}}-y^{(i)}\big)x^{(i)}_j 162 | $$ 163 | 164 | 165 | 166 | $$ 167 | = \displaystyle\sum_{i=1}^m\big(\theta(w\cdot x^{(i)})-y^{(i)}\big)x^{(i)}_j 168 | $$ 169 | 170 | 171 | 其中$$\theta(x)=\dfrac{e^{x}}{1+e^{x}}=\dfrac{1}{1+e^{-x}}$$,也称为$$sigmoid$$函数,然后得到: 172 | 173 | 174 | $$ 175 | \nabla L(w)= \displaystyle\sum_{i=1}^m\big(\theta(w\cdot x^{(i)})-y^{(i)}\big)x^{(i)} 176 | $$ 177 | 178 | 179 | 假定: 180 | 181 | $$X= \begin{bmatrix} 182 | (x^{(1)})^T \\ 183 | (x^{(2)})^T \\ 184 | (x^{(3)})^T \\ 185 | ... \\ 186 | ( x^{(m)} )^T 187 | \end{bmatrix} = \begin{bmatrix} 188 | 1 & x^{(1)}_1 & x^{(1)}_2 & ... & x^{(1)}_n \\ 189 | 1 & x^{(2)}_1 & x^{(2)}_2 & ... & x^{(2)}_n \\ 190 | 1 & x^{(3)}_1 & x^{(3)}_2 & ... & x^{(3)}_n \\ 191 | ... \\ 192 | 1 & x^{(m)}_1 & x^{(m)}_2 & ... & x^{(m)}_n 193 | \end{bmatrix}$$,$$Y=\begin{bmatrix} 194 | y^{(1)} \\ 195 | y^{(2)} \\ 196 | y^{(3)} \\ 197 | ... \\ 198 | y^{(m)} 199 | \end{bmatrix}$$,$$w=\begin{bmatrix} 200 | w_0 \\ 201 | w_1 \\ 202 | w_2 \\ 203 | ... \\ 204 | w_n 205 | \end{bmatrix}$$ 206 | 207 | 则: 208 | 209 | 210 | $$ 211 | X\cdot w= \begin{bmatrix} 212 | 1 & x^{(1)}_1 & x^{(1)}_2 & ... & x^{(1)}_n \\ 213 | 1 & x^{(2)}_1 & x^{(2)}_2 & ... & x^{(2)}_n \\ 214 | 1 & x^{(3)}_1 & x^{(3)}_2 & ... & x^{(3)}_n \\ 215 | ... \\ 216 | 1 & x^{(m)}_1 & x^{(m)}_2 & ... & x^{(m)}_n 217 | \end{bmatrix}\cdot \begin{bmatrix} 218 | w_0 \\ 219 | w_1 \\ 220 | w_2 \\ 221 | ... \\ 222 | w_n 223 | \end{bmatrix}=\begin{bmatrix} 224 | (x^{(1)})^T\cdot w \\ 225 | (x^{(2)})^T\cdot w \\ 226 | (x^{(3)})^T\cdot w \\ 227 | ... \\ 228 | (x^{(m)})^T\cdot w 229 | \end{bmatrix}=\begin{bmatrix} 230 | w^T \cdot x^{(1)} \\ 231 | w^T \cdot x^{(2)} \\ 232 | w^T \cdot x^{(3)} \\ 233 | ... \\ 234 | w^T \cdot x^{(m)} 235 | \end{bmatrix} 236 | $$ 237 | 238 | 239 | 240 | $$ 241 | \theta(X\cdot w)-Y=\begin{bmatrix} 242 | {\theta}(w^T \cdot x^{(1)})-y^{(1)} \\ 243 | {\theta}(w^T \cdot x^{(2)})-y^{(2)} \\ 244 | {\theta}(w^T \cdot x^{(3)})-y^{(3)} \\ 245 | ... \\ 246 | {\theta}(w^T \cdot x^{(m)})-y^{(m)} 247 | \end{bmatrix} 248 | $$ 249 | 250 | 251 | 252 | $$ 253 | X^T= \begin{bmatrix} 254 | x^{(1)} & x^{(2)} & x^{(3)} & ... & x^{(m)} 255 | \end{bmatrix} 256 | $$ 257 | 258 | 259 | 260 | $$ 261 | X^T\cdot \big(\theta(X\cdot w)-Y\big) = \displaystyle\sum_{i=1}^m\big(\theta(w\cdot x^{(i)})-y^{(i)}\big)x^{(i)} 262 | $$ 263 | 264 | 265 | 最终得到: 266 | 267 | 268 | $$ 269 | \nabla L(w)= X^T\cdot \big(\theta(X\cdot w)-Y\big) 270 | $$ 271 | 272 | 273 | 同时也可以得到: 274 | 275 | 276 | $$ 277 | L(w)=-\displaystyle\sum_{i=1}^m[y^{(i)}(w\cdot x^{(i)})-ln(1+e^{w\cdot x^{(i)}})]=-(X\cdot w)^T\cdot Y+ln(1+e^{X\cdot w })\cdot I 278 | $$ 279 | 280 | 281 | 其中$$I$$为全$$1$$向量。 282 | 283 | ### 四、梯度下降法 284 | 285 | #### 1.批量梯度下降(Batch Gradient Descent) 286 | 287 | 输入:训练数据集$$T=\{(x^{(1)},y^{(1)}),(x^{(2)},y^{(2)}),...,(x^{(m)},y^{(m)})\}$$,其中$$x^{(i)}\in X= R^n$$,$$y^{(i)}\in Y=\lbrace0,1\rbrace$$,$$i=1,2,...,m$$,学习率$$\eta(0<\eta\leqslant1)$$; 288 | 289 | 输出:$$w$$,$$b$$,其中$$w=(w_1, w_2, ..., w_n)^T$$,模型$$P(y=1|x)=sigmoid ( w\cdot x+b)$$ 290 | 291 | **1)**将输入的每个$$x$$转换成$$x=(1, x_1, x_2,...x_n)$$,令$$w_0 =b$$,输出为$$w=(w_0, w_1, w_2, ..., w_n)^T$$ 292 | 293 | **2)**选取初始$$w^{(0)}=(w_0, w_1, w_2, ..., w_n)^T$$ 294 | 295 | **3)**计算梯度$$X^T\cdot \big(\theta(X\cdot w^{(j)})-Y\big)$$,其中$$w^{(j)}$$为第$$j$$次迭代的结果,则第$$j+1$$次为: 296 | 297 | 298 | $$ 299 | w^{(j+1)} \gets w^{(j)} - \eta X^T\cdot \big(\theta(X\cdot w^{(j)})-Y\big) 300 | $$ 301 | 302 | 303 | **4)**转到步骤(3),一直到$$ L(w)$$满足一定条件,或者迭代到足够的次数。 304 | 305 | 在批量梯度下降算法中,每一步的迭代都需要计算所有样本,当样本数较大时,计算量会很大。 306 | 307 | **时间复杂度:** 308 | 309 | 每次迭代更新$$X\cdot w^{(j)}=Y^{'}$$的计算次数为$$m\times n$$,$$\theta(Y^{'})-Y = Z$$的计算次数为$$n$$次,$$X^T \cdot Z$$的计算次数为$$m\times n$$,则每次迭代的时间复杂度为$$O(m\times n)$$,假定迭代次数为$$k$$次,则总时间复杂度为$$O(k\times m\times n)$$。 310 | 311 | #### 2.随机梯度下降(Stochastic Gradient Descent) 312 | 313 | 将上面的步骤(3)改为: 314 | 315 | **3)**随机选取某个样本$$x^{(i)}$$,则: 316 | 317 | 318 | $$ 319 | w^{(j+1)} \gets w^{(j)}-\eta \big(\theta(w^{(j)}\cdot x^{(i)})-y^{(i)}\big)x^{(i)} 320 | $$ 321 | 322 | 323 | 一直到迭代到足够的次数。 324 | 325 | **时间复杂度:** 326 | 327 | 每次迭代更新$$w^{(j)}\cdot x^{(i)}=y^{'}$$的计算次数为$$n$$,$$\theta(y^{'})-y^{(i)}=z$$的计算次数为$$1$$,$$zx^{(i)}$$的计算次数为$$n$$,则每次迭代的时间复杂度为$$O(n)$$,假设迭代次数为$$k$$,则总时间复杂度为$$O(k\times n)$$。 328 | 329 | > 参考: 330 | > 331 | > [https://zh.wikipedia.org/wiki/发生比](https://zh.wikipedia.org/wiki/发生比) 332 | > 333 | > [http://vividfree.github.io/机器学习/2015/12/13/understanding-logistic-regression-using-odds](http://vividfree.github.io/机器学习/2015/12/13/understanding-logistic-regression-using-odds) 334 | > 335 | > [http://blog.csdn.net/bitcarmanlee/article/details/51473567](http://blog.csdn.net/bitcarmanlee/article/details/51473567) 336 | 337 | 338 | 339 | -------------------------------------------------------------------------------- /logistichui-gui/suan-fa-python-shi-xian.md: -------------------------------------------------------------------------------- 1 | ### Logistic回归python实现 2 | 3 | #### 1.算法python代码 4 | 5 | ``` 6 | # -*- coding: utf-8 -*- 7 | 8 | import matplotlib.pyplot as plt 9 | import numpy as np 10 | 11 | class Logistic(object): 12 | 13 | def __init__(self): 14 | self._history_w = [] 15 | self._likelihood = [] 16 | 17 | def load_input_data(self, data_file): 18 | with open(data_file) as f: 19 | input_x = [] 20 | input_y = [] 21 | for line in f: 22 | [x1, x2, y] = line.split() 23 | input_x.append([1.0, float(x1), float(x2)]) 24 | input_y.append(int(y)) 25 | self._input_x = np.array(input_x, dtype=np.float128) 26 | self._input_y = np.array(input_y, dtype=np.float128).T 27 | 28 | def sigmoid(self, x, w): # sigmoid函数 29 | return 1.0/(1+ np.exp(-np.inner(w,x))) 30 | 31 | def likelihood_function(self, w): # 目标极大似然函数 32 | temp = np.inner(self._input_x, w) 33 | a = np.inner(temp.T, self._input_y) 34 | b = np.sum(np.log(1+np.exp(temp))) 35 | return b-a 36 | 37 | def batch_gradient_descent(self, iter_num, iter_rate): #批量梯度下降 38 | (data_num, features) = np.shape(self._input_x) 39 | w = np.ones(features) #初始化w为全1向量 40 | for i in range(iter_num): 41 | theta = self.sigmoid(self._input_x, w) 42 | delta = theta - self._input_y 43 | w = w - iter_rate * np.inner(self._input_x.T, delta) # 迭代更新w 44 | self._history_w.append(w) 45 | self._likelihood.append(self.likelihood_function(w)) 46 | self._final_w = w 47 | return w 48 | 49 | def stochastic_gradient_descent(self, iter_num, iter_rate): #随机梯度下降 50 | (data_num, features) = np.shape(self._input_x) 51 | w = np.ones(features) #初始化w为全1向量 52 | iter_range = range(iter_num) 53 | data_range = range(data_num) 54 | for i in range(iter_num): 55 | for j in data_range: 56 | iter_rate = 4/(1.0+j+i) + 0.01 # 学习率随着迭代的次数而不断变小 57 | theta = self.sigmoid(self._input_x[j], w) 58 | delta = theta - self._input_y[j] 59 | w = w - iter_rate * delta* self._input_x[j] # 迭代更新w 60 | self._history_w.append(w) 61 | self._likelihood.append(self.likelihood_function(w)) 62 | self._final_w = w 63 | return w 64 | ``` 65 | 66 | #### 2. python数据显示 67 | 68 | 在类中添加如下函数: 69 | 70 | ``` 71 | def draw_result(self, title): 72 | total_data = np.shape(self._input_y)[0] 73 | self._nagtive_x = [] 74 | self._positive_x = [] 75 | for i in range(total_data): 76 | if self._input_y[i] > 0: 77 | self._positive_x.append(self._input_x[i]) 78 | else: 79 | self._nagtive_x.append(self._input_x[i]) 80 | 81 | plt.figure(1) 82 | x1 = [x[1] for x in self._positive_x] 83 | x2 = [x[2] for x in self._positive_x] 84 | plt.scatter(x1, x2, label='positive', color='g', s=20, marker="o") # 显示值为1的数据 85 | x1 = [x[1] for x in self._nagtive_x] 86 | x2 = [x[2] for x in self._nagtive_x] 87 | plt.scatter(x1, x2, label='nagtive', color='r', s=20, marker="x") # 显示值为0的数据 88 | plt.xlabel('x1') 89 | plt.ylabel('x2') 90 | def f(x): 91 | return -(self._final_w[0] + self._final_w[1]*x)/self._final_w[2] 92 | x = np.linspace(-4, 4, 10, endpoint=True) # 显示学习到的直线 93 | plt.plot(x, f(x), 'b-', lw=1) 94 | plt.title(title) 95 | plt.legend() 96 | plt.show() 97 | 98 | def draw_w_history(self, title): 99 | f, (ax1, ax2, ax3) = plt.subplots(3, 1, sharex=True) 100 | x = np.arange(len(self._history_w)) 101 | w0 = [w[0] for w in self._history_w] 102 | w1 = [w[1] for w in self._history_w] 103 | w2 = [w[2] for w in self._history_w] 104 | ax1.set_title(title+ ' w trend') 105 | ax1.set_ylabel('w[0]') 106 | ax1.scatter(x, w0, label='w[0]', color='b', s=10, marker=".") 107 | ax2.set_ylabel('w[1]') 108 | ax2.scatter(x, w1, label='w[1]', color='g', s=10, marker=".") 109 | ax3.set_ylabel('w[2]') 110 | ax3.scatter(x, w2, label='w[2]', color='r', s=10, marker=".") 111 | plt.show() 112 | 113 | def draw_likelihood_function(self, title): 114 | plt.figure(1) 115 | x = np.arange(len(self._likelihood)) 116 | plt.scatter(x, self._likelihood, label='Likelihood', color='g', s=10, marker=".") 117 | plt.xlabel('x') 118 | plt.ylabel('Likelihood function') 119 | plt.title(title + ' Likelihood trend') 120 | plt.legend() 121 | plt.show() 122 | ``` 123 | 124 | #### 3.数据集测试 125 | 126 | > 数据集来自《机器学习实战》 127 | > 128 | > [https://github.com/apachecn/MachineLearning/blob/python-2.7/input/5.Logistic/TestSet.txt](https://github.com/apachecn/MachineLearning/blob/python-2.7/input/5.Logistic/TestSet.txt) 129 | 130 | ##### 3.1批量梯度下降 131 | 132 | ``` 133 | log = Logistic() 134 | log.load_input_data("test.txt") 135 | log.batch_gradient_descent(iter_num=300, iter_rate=0.001) 136 | title = "Batch Gradient Descent" 137 | log.draw_result(title) 138 | log.draw_w_history(title) 139 | log.draw_likelihood_function(title) 140 | ``` 141 | 142 | 总计算时间复杂度为300\*100\*3 143 | 144 | ![](/assets/logistic_bgd_1.png) 145 | 146 | ![](/assets/logistic_bgd_2.png) 147 | 148 | ![](/assets/logistic_bgd_3.png) 149 | 150 | ##### 3.2随机梯度下降 151 | 152 | ``` 153 | log = Logistic() 154 | log.load_input_data("test.txt") 155 | log.stochastic_gradient_descent(iter_num=100, iter_rate=0.001) 156 | title = "Stochastic Gradient Descent" 157 | log.draw_result(title) 158 | log.draw_w_history(title) 159 | log.draw_likelihood_function(title) 160 | ``` 161 | 162 | 总计算时间复杂度为100(外循环)\*100(内循环)\*3 163 | 164 | ![](/assets/logistic_sgd_1.png)![](/assets/logistic_sgd_2.png) 165 | 166 | ![](/assets/logistic_sgd_3.png) 167 | 168 | > 参考: 169 | > 170 | > 《机器学习实战》第五章 171 | 172 | 173 | 174 | -------------------------------------------------------------------------------- /po-su-bei-xie-si-fa.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/po-su-bei-xie-si-fa.md -------------------------------------------------------------------------------- /po-su-bei-xie-si-fa/can-shu-gu-ji.md: -------------------------------------------------------------------------------- 1 | ### 朴素贝叶斯法的参数估计 2 | 3 | 朴素贝叶斯法需要估计参数$$P(Y=c_k)$$和$$P(X_j=x_j|Y=c_k)$$ 4 | 5 | 6 | $$ 7 | y=f(x)=\arg \max_{c_k}\prod_{j=1}^n P(X_j=x_j|Y=c_k)P(Y=c_k) 8 | $$ 9 | 10 | 11 | 假定数据集$$T=\{(x^{(1)},y^{(1)}),(x^{(2)},y^{(2)}),...,(x^{(m)},y^{(m)})\}$$,其中$$x\in \mathcal{X}\subseteq R^n$$,$$y\in \mathcal{Y}=\{c_1, c_2,...,c_K\}$$。$$X$$是定义在输入空间$$\mathcal{X}$$上的$$n$$维随机向量,$$Y$$是定义在输出空间$$\mathcal{Y}$$上的随机变量。 12 | 13 | #### 1. 极大似然估计 14 | 15 | 应用极大似然估计法估计相应参数。 16 | 17 | **先验概率**$$P(Y=c_k)$$的极大似然估计是: 18 | 19 | 20 | $$ 21 | P(Y=c_k)=\dfrac{\displaystyle\sum_{i=1}^mI(y^{(i)}=c_k)}{m},\ k=1,2,...,K 22 | $$ 23 | 24 | 25 | 其中$$I(y_i=c_k)$$是指示函数,当$$y_i=c_k$$时值为1,其他情况下为0。$$m$$为数据集里的数据量。 26 | 27 | 假定输入的$$n$$维特征向量$$x$$的第$$j$$维可能的取值为$$\{x_{j1},x_{j2},...x_{js_{j}}\}$$,则**条件概率**$$P(X_j=x_{jl}|Y=c_k)$$的极大似然估计是: 28 | 29 | 30 | $$ 31 | P(X_j=x_{jl}|Y=c_k)=\dfrac{\displaystyle\sum_{i=1}^mI(x_j^{(i)}=x_{jl},y^{(i)}=c_k)}{\displaystyle\sum_{i=1}^mI(y^{(i)}=c_k)} 32 | $$ 33 | 34 | 35 | 36 | $$ 37 | j=1,2,...,n;\ l=1,2,...,s_j;\ k=1,2,...,K 38 | $$ 39 | 40 | 41 | 其中$$x_j^{(i)}$$是第$$i$$个样本的第$$j$$个特征,$$x_{jl}$$是第$$j$$个特征的可能取的第$$l$$个值,$$I$$为指示函数。 42 | 43 | 这里证明一下先验概率$$P(Y=c_k)$$的极大似然估计(参考 [https://www.zhihu.com/question/33959624](https://www.zhihu.com/question/33959624)。) )。 44 | 45 | 令参数$$P(Y=c_k)=\theta_k,\ k=1,2,...,K$$。则随机变量$$Y$$的概率可以用参数来表示为$$P(Y)=\displaystyle\sum_{k=1}^K\theta_kI(Y=c_k)$$,其中$$I$$是指示函数。极大似然函数 46 | 47 | 48 | $$ 49 | L(\theta_k;y^{(1)},y^{(2)},...,y^{(m)})=\displaystyle\prod_{i=1}^mp(y^{(i)})=\displaystyle\prod_{k=1}^K\theta_k^{t_k} 50 | $$ 51 | 52 | 53 | 其中$$m$$是样本总数,$$t_k$$为样本中$$Y=c_k$$的样本数目,满足$$\displaystyle\sum_{k=1}^Kt_k=m$$。取对数得到 54 | 55 | 56 | $$ 57 | ln(L(\theta_k))=\displaystyle\sum_{k=1}^Kt_kln\theta_k 58 | $$ 59 | 60 | 61 | 要求该函数的最大值,同时有约束条件$$\displaystyle\sum_{k=1}^K\theta_k=1$$。利用拉格朗日乘子法, 62 | 63 | 64 | $$ 65 | l(\theta_k,\lambda)=\displaystyle\sum_{k=1}^Kt_kln\theta_k+\lambda(\displaystyle\sum_{k=1}^K\theta_k-1) 66 | $$ 67 | 68 | 69 | 求导可以得到 70 | 71 | 72 | $$ 73 | \dfrac{\partial l(\theta_k,\lambda)}{\partial \theta_k}=\dfrac{t_k}{\theta_k}+\lambda=0 74 | $$ 75 | 76 | 77 | 得到: 78 | 79 | 80 | $$ 81 | t_k=-\lambda{\theta_k},\ k=1,2,...,K 82 | $$ 83 | 84 | 85 | 将所有的$$K$$个式子加起来,得到$$\displaystyle\sum_{k=1}^Kt_k=-\displaystyle\sum_{k=1}^K\lambda{\theta_k}$$,同时结合约束条件$$\displaystyle\sum_{k=1}^K\theta_k=1$$,可得$$\lambda=-m$$。最终可得 86 | 87 | 88 | $$ 89 | P(Y=c_k)=\theta_k=\dfrac{t_k}{m} 90 | $$ 91 | 92 | 93 | 证明完毕。其他更多的详细证明请参考以上链接。 94 | 95 | #### 2. 贝叶斯估计 96 | 97 | 用极大似然估计可能出现所要估计的参数值为0的情况,这会影响到连乘时的值直接为0,使分类结果产生偏差。解决这一问题的方法是采用贝叶斯估计。 98 | 99 | **条件概率**的贝叶斯估计是 100 | 101 | 102 | $$ 103 | P_{\lambda}(X_j=x_{jl}|Y=c_k)=\dfrac{\displaystyle\sum_{i=1}^mI(x_j^{(i)}=x_{jl},y^{(i)}=c_k)+\lambda}{\displaystyle\sum_{i=1}^mI(y^{(i)}=c_k)+s_j\lambda} 104 | $$ 105 | 106 | 107 | 式中$$\lambda \geqslant0$$,$$s_j$$是特征向量的第$$j$$维可能的取值数量。显然$$P_{\lambda}(X_j=x_{jl}|Y=c_k)>0$$,且$$\displaystyle\sum_{l=1}^{s_j}P_{\lambda}(X_j=x_{jl}|Y=c_k)=1$$。 108 | 109 | 这等价于在随机变量各个取值的频数上赋予一个正数$$\lambda>0$$。当$$\lambda=0$$时,就是极大似然估计。常取$$\lambda=1$$,这时称为**拉布普拉斯平滑**(Laplace smoothing)。 110 | 111 | 先验概率的贝叶斯估计是 112 | 113 | 114 | $$ 115 | P_{\lambda}(Y=c_k)=\dfrac{\displaystyle\sum_{i=1}^mI(y^{(i)}=c_k)+\lambda}{m+K\lambda} 116 | $$ 117 | 118 | 119 | 同样$$\lambda \geqslant0$$。 120 | 121 | #### 示例 122 | 123 | 由下表的训练数据学习一个朴素贝叶斯分类器并确定$$x=(2,S)^T$$的类标记$$y$$。 124 | 125 | 表中$$X_1$$,$$X_2$$为特征,取值的集合分别为$$A_1=\{1,2,3\}$$,$$A_2=\{S,M,L\}$$,$$Y$$为类标记,$$Y\in C=\{1,-1\}$$。 126 | 127 | | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 128 | | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | 129 | | X1 | 1 | 1 | 1 | 1 | 1 | 2 | 2 | 2 | 2 | 2 | 3 | 3 | 3 | 3 | 3 | 130 | | X2 | S | M | M | S | S | S | M | M | L | L | L | M | M | L | L | 131 | | Y | -1 | -1 | 1 | 1 | -1 | -1 | -1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | -1 | 132 | 133 | **极大似然估计**: 134 | 135 | $$P(Y=1)=\dfrac{9}{15}$$,$$P(Y=-1)=\dfrac{6}{15}$$ 136 | 137 | $$P(X_1=1|Y=1)=\dfrac{2}{9}$$,$$P(X_1=2|Y=1)=\dfrac{3}{9}$$,$$P(X_1=3|Y=1)=\dfrac{4}{9}$$ 138 | 139 | $$P(X_2=S|Y=1)=\dfrac{1}{9}$$,$$P(X_2=M|Y=1)=\dfrac{4}{9}$$,$$P(X_2=L|Y=1)=\dfrac{4}{9}$$ 140 | 141 | $$P(X_1=1|Y=-1)=\dfrac{3}{6}$$,$$P(X_1=2|Y=-1)=\dfrac{2}{6}$$,$$P(X_1=3|Y=-1)=\dfrac{1}{6}$$ 142 | 143 | $$P(X_2=S|Y=-1)=\dfrac{3}{6}$$,$$P(X_2=M|Y=-1)=\dfrac{2}{6}$$,$$P(X_2=L|Y=-1)=\dfrac{1}{6}$$ 144 | 145 | 对于给定的$$x=(2,S)^T$$计算: 146 | 147 | $$P(Y=1)P(X_1=2|Y=1)P(X_2=S|Y=1)=\dfrac{9}{15}\cdot \dfrac{3}{9} \cdot \dfrac{1}{9}=\dfrac{1}{45}$$ 148 | 149 | $$P(Y=-1)P(X_1=2|Y=-1)P(X_2=S|Y=-1)=\dfrac{6}{15}\cdot \dfrac{2}{6} \cdot \dfrac{3}{6}=\dfrac{1}{15}$$ 150 | 151 | 当$$Y=-1$$时比较大,所以$$y=-1$$。 152 | 153 | **拉普拉斯平滑估计**($$\lambda=1$$): 154 | 155 | $$P(Y=1)=\dfrac{10}{17}$$,$$P(Y=-1)=\dfrac{7}{17}$$ 156 | 157 | $$P(X_1=1|Y=1)=\dfrac{3}{12}$$,$$P(X_1=2|Y=1)=\dfrac{4}{12}$$,$$P(X_1=3|Y=1)=\dfrac{5}{12}$$ 158 | 159 | $$P(X_2=S|Y=1)=\dfrac{2}{12}$$,$$P(X_2=M|Y=1)=\dfrac{5}{12}$$,$$P(X_2=L|Y=1)=\dfrac{5}{12}$$ 160 | 161 | $$P(X_1=1|Y=-1)=\dfrac{4}{9}$$,$$P(X_1=2|Y=-1)=\dfrac{3}{9}$$,$$P(X_1=3|Y=-1)=\dfrac{2}{9}$$ 162 | 163 | $$P(X_2=S|Y=-1)=\dfrac{4}{9}$$,$$P(X_2=M|Y=-1)=\dfrac{3}{9}$$,$$P(X_2=L|Y=-1)=\dfrac{2}{9}$$ 164 | 165 | 对于给定的$$x=(2,S)^T$$计算 166 | 167 | $$P(Y=1)P(X_1=2|Y=1)P(X_2=S|Y=1)=\dfrac{10}{17}\cdot \dfrac{4}{12} \cdot \dfrac{2}{12}=\dfrac{5}{153}=0.03$$ 168 | 169 | $$P(Y=-1)P(X_1=2|Y=-1)P(X_2=S|Y=-1)=\dfrac{7}{17}\cdot \dfrac{3}{9} \cdot \dfrac{4}{9}=\dfrac{28}{459}=0.06$$ 170 | 171 | 由于$$Y=-1$$时,比较大,所以$$y=-1$$。 172 | 173 | -------------------------------------------------------------------------------- /po-su-bei-xie-si-fa/po-su-bei-xie-si-fa-de-xue-xi-he-fen-lei.md: -------------------------------------------------------------------------------- 1 | ### 朴素贝叶斯法 2 | 3 | 朴素贝叶斯(native Bayes)法是基于贝叶斯定理与特征条件独立假设的分类方法。 4 | 5 | 对于给定的训练集,首先基于特征条件独立假设学习输入/输出的联合概率分布;然后基于此模型,对于给定的输入$$x $$,利用贝叶斯定理求出后验概率最大的输出$$y$$。 6 | 7 | #### 1. 基本方法 8 | 9 | 假设输入空间$$\mathcal{X}\subseteq R^n$$为$$n$$维向量的集合,输出空间为类标记集合$$\mathcal{Y}=\{c_1, c_2,...,c_K\}$$。输入为特征向量$$x\in \mathcal{X}$$,输出为类标记$$y\in \mathcal{Y}$$。$$X$$是定义在输入空间$$\mathcal{X}$$上的随机向量,$$Y$$是定义在输出空间$$\mathcal{Y}$$上的随机变量。$$P(X,Y)$$是$$X$$和$$Y$$的联合概率分布。训练数据集$$T=\{(x^{(1)},y^{(1)}),(x^{(2)},y^{(2)}),...,(x^{(m)},y^{(m)})\}$$是由$$P(X,Y)$$独立同分布产生的,其中每个$$x=(x_1, x_2,...,x_n)$$是$$n$$维向量。 10 | 11 | 朴素贝叶斯法通过对给定的输入$$x$$,通过学习到的模型计算**后验概率分布**$$P(Y=c_k|X=x)$$,然后将**后验概率最大**的类作为$$x $$的输出。计算后验概率: 12 | 13 | 14 | $$ 15 | P(Y=c_k|X=x)=\dfrac{P(Y=c_k, X=x)}{P(X=x)}=\dfrac{P(X=x|Y=c_k)P(Y=c_k)}{\displaystyle\sum_{k=1}^KP(X=x|Y=c_k)P(Y=c_k)} 16 | $$ 17 | 18 | 19 | 其中$$k=1,2,...,K$$,可以看到分母对于所有的类标记$$c_k$$都是相同的,则可以得到输出 20 | 21 | 22 | $$ 23 | y=\arg \max_{c_k}P(X=x|Y=c_k)P(Y=c_k) 24 | $$ 25 | 26 | 27 | 其中 28 | 29 | 30 | $$ 31 | P(Y=c_k), \ k=1,2,...,K 32 | $$ 33 | 34 | 35 | 是**先验概率**分布。 36 | 37 | 38 | $$ 39 | P(X=x|Y=c_k)=P(X_1=x_1, X_2=x_2,...,X_n=x_n|Y=c_k), \ k=1,2,...,K 40 | $$ 41 | 42 | 43 | 是条件概率分布(**似然函数**)。假定条件概率分布中的每个特征是**条件独立**的,则 44 | 45 | 46 | $$ 47 | P(X=x|Y=c_k)=\prod_{j=1}^n P(X_j=x_j|Y=c_k) 48 | $$ 49 | 50 | 51 | 这一假设使得朴素贝叶斯法变得简单,但是会牺牲一定的分类准确率。 52 | 53 | 于是代入,可以得到: 54 | 55 | 56 | $$ 57 | y=f(x)=\arg \max_{c_k}\prod_{j=1}^n P(X_j=x_j|Y=c_k)P(Y=c_k) 58 | $$ 59 | 60 | 61 | 朴素贝叶斯法属于**生成模型**(模型给定了输入$$X$$产生输出$$Y$$的生成关系,区别于**判别模型**) 62 | 63 | #### 2. 模型的原理 64 | 65 | 首先,定义0-1损失函数: 66 | 67 | 68 | $$ 69 | L(Y,f(X)) = \begin{cases} 70 | 1 &\text{if }Y{\neq}f(X) \\ 71 | 0 &\text{if }Y{=}f(X) 72 | \end{cases} 73 | $$ 74 | 75 | 76 | 其中$$f(X)$$是分类决策函数的**预测值**,$$Y$$是**真实值**。这时,损失函数的期望是 77 | 78 | 79 | $$ 80 | R_{exp}(f)=E[L(Y,f(X))] 81 | $$ 82 | 83 | 84 | 对于输入$$X=x$$,计算$$X=x$$条件下的期望损失函数,即条件期望 85 | 86 | 87 | $$ 88 | E[L(Y,f(X=x))|X=x]=\displaystyle\sum_{k=1}^KL(c_k, f(X=x))P(c_k|X=x) 89 | $$ 90 | 91 | 92 | 则在$$X=x$$条件下,求得期望风险最小化, 93 | 94 | 95 | $$ 96 | f(x)=\arg\min_{y\in \mathcal{Y}}\displaystyle\sum_{k=1}^KL(c_k, y)P(c_k|X=x) 97 | $$ 98 | 99 | 100 | 也就是计算每一个$$y\in \mathcal{Y}$$,计算其条件期望,并找出其中的最小值时的$$y$$作为输出。 101 | 102 | 同时$$y=c_k$$时,$$L(c_k, y)=0$$,则 103 | 104 | 105 | $$ 106 | f(x)=\arg\min_{y\in \mathcal{Y}}\displaystyle\sum_{c_k\neq y}P(c_k|X=x) 107 | $$ 108 | 109 | 110 | 然后条件概率对于所有可能的类标签总和为1,即$$\displaystyle\sum_{k=1}^KP(c_k|X=x)=1$$,于是得到: 111 | 112 | 113 | $$ 114 | f(x)=\arg\min_{c_k\in \mathcal{Y}}\big(1-P(c_k|X=x)\big) 115 | $$ 116 | 117 | 118 | 转换成求最大: 119 | 120 | 121 | $$ 122 | f(x)=\arg\max_{c_k\in \mathcal{Y}}P(c_k|X=x) 123 | $$ 124 | 125 | 126 | 这样便是在0-1损失函数的情况下,期望风险最小化准则得到了**后验概率最大化**准则,即朴素贝叶斯法的原理。 127 | 128 | -------------------------------------------------------------------------------- /po-su-bei-xie-si-fa/suan-fa-he-shi-xian.md: -------------------------------------------------------------------------------- 1 | #### 朴素贝叶斯算法 2 | 3 | 给定数据集$$T=\{(x^{(1)},y^{(1)}),(x^{(2)},y^{(2)}),...,(x^{(m)},y^{(m)})\}$$,其中$$x\in \mathcal{X}\subseteq R^n$$,$$y\in \mathcal{Y}=\{c_1, c_2,...,c_K\}$$,$$X$$是定义在输入空间$$\mathcal{X}$$上的随机向量,$$Y$$是定义在输出空间$$\mathcal{Y}$$上的随机变量,则对于输入$$x$$,计算如下的到输出$$ y$$。 4 | 5 | 6 | $$ 7 | y=f(x)=\arg \max_{c_k}\prod_{j=1}^n P(X_j=x_j|Y=c_k)P(Y=c_k) 8 | $$ 9 | 10 | 11 | 式中的$$P(\cdot)$$值小于1,多个小于1的值连乘在python中执行会导致下溢,因此可以取对数,可以将乘法改为加法。而且对数函数是递增函数并不影响结果。则: 12 | 13 | 14 | $$ 15 | y=f(x)=\arg \max_{c_k}ln\big(\prod_{j=1}^n P(X_j=x_j|Y=c_k)P(Y=c_k)\big) 16 | $$ 17 | 18 | $$ 19 | =\arg \max_{c_k}\big(lnP(Y=c_k)+\displaystyle\sum_{i=1}^nln(P(X_j=x_j|Y=c_k)\big) 20 | $$ 21 | 22 | 23 | #### 算法实现 24 | 25 | > 数据源:[https://github.com/apachecn/MachineLearning/tree/python-2.7/input/4.NaiveBayes/email](https://github.com/apachecn/MachineLearning/tree/python-2.7/input/4.NaiveBayes/email) 26 | 27 | 例子里面中的基本步骤如下: 28 | 29 | 1. 将数据集切分称训练数据集和测试数据集。 30 | 2. 预先提取出所有的数据里面单词构成单词向量。 31 | 3. 然后分别将训练数据集和测试数据集的输入,分词,并转换称单词向量。 32 | 4. 然后进行训练,训练时计算各个单词的数量,然后除以总单词树,并使用lamda=1。 33 | 5. 然后进行测试,采样log的加和来使得避免连乘溢出。 34 | 35 | ``` 36 | # -*- coding: utf-8 -*- 37 | 38 | import matplotlib.pyplot as plt 39 | import numpy as np 40 | import os 41 | import re 42 | import random 43 | 44 | class NativeBayes(object): 45 | 46 | def __init__(self): 47 | self._train_x = [] # 训练数据x 48 | self._train_y = [] # 训练数据y 49 | self._test_x = [] # 测试数据x 50 | self._test_y = [] # 测试数据y 51 | self._all_words = None # 所有的单词 52 | self._all_words_num = 0 # 所以单词数量 53 | 54 | def split_to_word(self, text): # 将文本切分称单词 55 | words = re.split(r'\W*', text) 56 | #return [word.lower() for word in words if len(word) > 2] 57 | return [word.lower() for word in words if len(word) > 2 and re.match(r'[a-zA-Z]', word)] 58 | 59 | def words_to_vector(self, words): # 将切分后的单词转换称单词向量 60 | vector = [0]*self._all_words_num 61 | for word in words: 62 | if word in self._all_words: 63 | vector[self._all_words.index(word)] += 1 64 | return vector 65 | 66 | def load_data(self, positive_dir, nagetive_dir): 67 | train_files = os.listdir(positive_dir) 68 | input_x = [] 69 | input_y = [] 70 | all_input_x = [] 71 | for i in train_files: 72 | with open('{}/{}'.format(positive_dir,i)) as f: 73 | text = f.read() 74 | words = self.split_to_word(text) 75 | input_x.append(words) 76 | all_input_x.extend(words) 77 | input_y.append(1) 78 | 79 | train_files = os.listdir(nagetive_dir) 80 | for i in train_files: 81 | with open('{}/{}'.format(nagetive_dir,i)) as f: 82 | text = f.read() 83 | words = self.split_to_word(text) 84 | input_x.append(words) 85 | all_input_x.extend(words) 86 | input_y.append(-1) 87 | 88 | self._all_words = list(set(all_input_x)) # 获得数据里面所有的单词列表 89 | self._all_words_num = len(self._all_words) # 单词列表里面的单词数量 90 | 91 | total = len(input_y) 92 | test_x = [] 93 | test_y = [] 94 | for i in range(10): # 将数据集分为训练数据和测试数据 95 | index = random.randint(0, total-1) 96 | test_x.append(input_x[index]) 97 | test_y.append(input_y[index]) 98 | del(input_x[index]) 99 | del(input_y[index]) 100 | total -= 1 101 | 102 | self._train_x = [] 103 | self._train_y = input_y 104 | train_num = len(input_y) 105 | print('train data num', train_num) 106 | for i in range(train_num): # 将训练数据单词列表转换称单词向量 107 | vector = self.words_to_vector(input_x[i]) 108 | self._train_x.append(vector) 109 | 110 | self._test_x = [] 111 | self._test_y = test_y 112 | test_num = len(test_y) 113 | print('test data num', test_num) 114 | for i in range(test_num): # 将测试数据单词列表转换称单词向量 115 | vector = self.words_to_vector(test_x[i]) 116 | self._test_x.append(vector) 117 | 118 | def train(self): 119 | train_data_num = len(self._train_y) 120 | p_positive = np.ones(self._all_words_num) # 贝叶斯估计,所有单词初始化lamda=1 121 | p_negative = np.ones(self._all_words_num) # 贝叶斯估计,lamda=1 122 | positive_words_total = self._all_words_num # 同时所有的单词数量响应增加 123 | negative_words_total = self._all_words_num # 原书中此处为0,应该是错误的 124 | total_positive = 0 125 | for i in range(train_data_num): 126 | if self._train_y[i] == 1: 127 | p_positive += self._train_x[i] 128 | positive_words_total += sum(self._train_x[i]) 129 | total_positive += 1 130 | else: 131 | p_negative += self._train_x[i] 132 | negative_words_total += sum(self._train_x[i]) 133 | p_positive = np.log(p_positive/positive_words_total) # 计算各个单词的条件概率 134 | p_negative = np.log(p_negative/negative_words_total) 135 | positive_class = total_positive/float(train_data_num) # 计算分类概率 136 | print('train positive percent',positive_class) 137 | return p_positive,p_negative,positive_class 138 | 139 | def classify(self, p_positive, p_negative, positive_class, vector): 140 | # 分别计算各个子类的概率 141 | positive = np.sum(p_positive*vector) + np.log(positive_class) 142 | nagative = np.sum(p_negative*vector) + np.log(1 - positive_class) 143 | print(positive,nagative) 144 | if positive > nagative: 145 | return 1 146 | else: 147 | return -1 148 | 149 | def test_data(self): 150 | p_positive,p_negative,positive_class = self.train() 151 | total_test = len(self._test_y) 152 | error_num = 0 153 | for i in range(total_test): 154 | vector = self._test_x[i] 155 | predict = self.classify(p_positive, p_negative, positive_class, vector) 156 | if predict != self._test_y[i]: 157 | error_num += 1 158 | print('predict error num', error_num) 159 | 160 | bayes = NativeBayes() 161 | postive = "/path_to/input/4.NaiveBayes/email/ham/" 162 | nagative = "/path_to/input/4.NaiveBayes/email/spam/" 163 | bayes.load_data(postive, nagative) 164 | bayes.test_data() 165 | ``` 166 | 167 | 测试结果: 168 | 169 | ``` 170 | ('train data num', 40) 171 | ('test data num', 10) 172 | ('train positive percent', 0.5) 173 | (-219.22174839643606, -225.29558562436705) 174 | (-131.2753894915964, -150.43783388899158) 175 | (-173.14800355833415, -180.89949078604346) 176 | (-195.48666534835462, -193.29700989614457) 177 | (-110.31437440519804, -93.453134060488026) 178 | (-217.98906102300515, -156.13376765308851) 179 | (-68.80147262518193, -76.076316158541744) 180 | (-80.416051743878654, -65.808185492417721) 181 | (-146.34615733070959, -156.19156326594504) 182 | (-105.51819039117207, -114.69496509329458) 183 | ('predict error num', 1) 184 | ``` 185 | 186 | 187 | 188 | -------------------------------------------------------------------------------- /shen-jing-wang-luo.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/shen-jing-wang-luo.md -------------------------------------------------------------------------------- /shen-jing-wang-luo/fan-xiang-chuan-bo-suan-fa.md: -------------------------------------------------------------------------------- 1 | ### 反向传播算法 2 | 3 | 我们希望有个算法,能够让我们找到权重和偏置,以至于神经网络的输出$$y(x)$$能够拟合所有的训练输入$$x$$。为了量化我们如何实现这个目标,我们定义一个代价函数: 4 | 5 | 6 | $$ 7 | C(w,b)=\frac{1}{2n}\displaystyle\sum_{x}||y(x)-a^L(x)||^2 8 | $$ 9 | 10 | 11 | 这里$$w$$表示所有网络中权重的集合,$$b$$是所有的偏置,$$n$$是训练输入数据的个数,$$L$$表示网络的层数,$$a^L=a^L(x)$$是表示当输入为$$x$$时的网络输出的激活值向量,求和则是在总的训练输出$$x $$上进行的。符号$$||v||$$是指向量$$v$$的模。我们把$$C$$称为**二次代价函数**;有时也别称为**均方误差**或者**MSE**。 12 | 13 | 代价函数$$C(w,b)$$是非负的,因为求和公式中的每一项都是非负的。此外,当对于所有的训练输入$$x $$,$$y(x)$$接近于输出$$a$$时,代价函数的值相当小,即$$C(w,b)\approx0$$。 14 | 15 | 反向传播算法给出了一个计算代价函数梯度的的方法: 16 | 17 | 1. 输入$$x$$:为输入层设置对应的激活值$$a^1$$ 18 | 2. 前向传播:对每个$$l=2,3,...,L$$计算相应的的$$z^l=w^l\cdot a^{(l-1)} + b^l$$和$$a^l = \sigma(z^l)$$ 19 | 3. 输出层误差$$\delta^L$$:计算向量$$\delta^L=\nabla_aC \bigodot\sigma'(z^L)$$ 20 | 4. 反向误差传播:对每个$$l= L-1, L-2, ..., 2$$,计算$$\delta^l=(({w^{(l+1)}}^T)\delta^{(l+1)})\bigodot\sigma'(z^L)$$ 21 | 5. 输出:代价函数的梯度由$$\frac{\partial C}{\partial W^l_{jk}}=a^{l-1}_k\delta^l_j$$和$$\frac{\partial C}{\partial b^l_{j}}=\delta^l_j$$得出。 22 | 23 | ### 反向传播算法的证明 24 | 25 | #### 两个假设 26 | 27 | 反向传播算法的目标是计算代价函数$$C$$分别关于$$w$$和$$b$$的偏导数$$\frac{\partial C}{\partial W^l_{jk}}$$和$$\frac{\partial C}{\partial b^l_{j}}$$。为了让方向传播可行,我们需要做出关于代价函数的两个主要假设。 28 | 29 | 第一个假设就是代价函数可以被写成一个在每个训练样本$$x$$上的代价函数$$C_x$$的均值$$C=\frac{1}{n}\displaystyle\sum_{x}C_x$$。对于二次代价函数,每个独立的训练样本的代价是$$C_x=\frac{1}{2}||y(x)-a^L(x)||^2$$,这个假设对于其他的代价函数也必须满足。需要这个假设的原因是反向传播实际上是对一个独立的训练样本计算了$$\frac{\partial C_x}{\partial w}$$和$$\frac{\partial C_x}{\partial b}$$,然后通过在所有的训练样本上进行平均化获得$$\frac{\partial C}{\partial w}$$和$$\frac{\partial C}{\partial b}$$。 30 | 31 | 第二个假设就是代价可以写成神经网络输出的函数 32 | 33 | ![](/assets/network-cost-function.png) 34 | 35 | 如图所示,将代价函数$$C$$看成仅有输出激活值$$a^L$$的函数。 36 | 37 | #### Hadamard乘积 38 | 39 | Hadamard 乘积是按元素乘法的运算 40 | 41 | 42 | $$ 43 | \begin{bmatrix} 44 | 1 \\ 45 | 2 46 | \end{bmatrix} \odot \begin{bmatrix} 47 | 3 \\ 48 | 4 49 | \end{bmatrix}=\begin{bmatrix} 50 | 1*3 \\ 51 | 2*4 52 | \end{bmatrix} =\begin{bmatrix} 53 | 3 \\ 54 | 8 55 | \end{bmatrix} 56 | $$ 57 | 58 | 59 | 假设$$s$$和$$t$$是两个相同维度的向量,那么我们使用$$s \odot t $$来表示按元素的乘积。所以$$s \odot t $$的元素就是$$(s \odot t )_j=s_jt_j$$。 60 | 61 | #### 反向传播的四个基本方程 62 | 63 | 反向传播其实是对权重和偏置变化影响代价函数过程的理解。最终的含义就是计算偏导数$$\frac{\partial C}{\partial W^l_{jk}}$$和$$\frac{\partial C}{\partial b^l_{j}}$$。为了计算这些值,我们先引入一个中间量$$\delta^l_j$$,这个称之为在$$l^{th}$$的第$$j^{th}$$个神经元上的误差。反向传播将给出计算误差$$\delta^l_j$$的流程,然后将其关联到计算上面两个偏导数上面。 64 | 65 | 假定在$$l^{th}$$层的第$$j^{th}$$神经元上,对神经元的带权输入增加很小的变化$$\Delta z^l_j$$,这使得神经元的输出由$$\sigma(z^l_j)$$变成$$\sigma(z^l_j+\Delta z^l_j)$$,这个变化会向网络后的层进行传播,最终导致整个代价产生$$\frac{\partial C}{\partial z^l_j} \Delta z^l_j$$的改变。 假如$$\frac{\partial C}{\partial z^l_j}$$是一个很大的值(或正或负),那么可以通过选择与其相反的符号的$$\Delta z^l_j$$来降低代价。相反如果$$\frac{\partial C}{\partial z^l_j}$$是一个接近于$$0$$的值,这时候并不能通过调整输入$$z^l_j$$来改善多少代价。所以这里有个启发式的认识,$$\frac{\partial C}{\partial z^l_j}$$是神经元的误差度量。 66 | 67 | ![](/assets/network-delta-z.png) 68 | 69 | 按照上面的描述,我们定义$$l^{th}$$层的第$$j^{th}$$个神经元的上的误差$$\delta^l_j$$为 70 | 71 | 72 | $$ 73 | \delta^l_j=\frac{\partial C}{\partial z^l_j} 74 | $$ 75 | 76 | 77 | 我们使用$$\delta^l$$表示关联于$$l$$层的误差向量。 78 | 79 | 接下来我们介绍四个基本方程。 80 | 81 | -------------------------------------------------------------------------------- /shen-jing-wang-luo/fan-xiang-chuan-bo-suan-fa/dai-ma-shi-xian.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/shen-jing-wang-luo/fan-xiang-chuan-bo-suan-fa/dai-ma-shi-xian.md -------------------------------------------------------------------------------- /shen-jing-wang-luo/fan-xiang-chuan-bo-suan-fa/fan-xiang-chuan-bo-zheng-ming.md: -------------------------------------------------------------------------------- 1 | 下面介绍反向传播基于的四个方程。 2 | 3 | ### 1. 输出层误差的方程 4 | 5 | 第$$L$$层为输出层,该层得分误差向量$$\delta^L$$中每一个元素定义如下: 6 | 7 | 8 | $$ 9 | \delta^L_j= \frac{\partial C}{\partial z^L_j}=\frac{\partial C}{\partial a^L_j}\sigma'(z^L_j) 10 | $$ 11 | 12 | 13 | 右式第一项$$\frac{\partial C}{\partial a^L_j}$$表示代价随着$$j^{th}$$输出激活值的变化而变化的速度,第二项$$\sigma'(z^L_j)$$刻画了在$$z^L_j$$处激活函数$$\sigma$$的变化速度。 14 | 15 | 证明:应用链式法则我们可以就输出激活值的偏导数的形式重新表示上面的偏导数: 16 | 17 | 18 | $$ 19 | \delta^L_j= \frac{\partial C}{\partial z^L_j}=\displaystyle\sum_{k}\frac{\partial C}{\partial a^L_k}\frac{\partial a^L_k}{\partial z^L_j} 20 | $$ 21 | 22 | 23 | 这里的求和是在输出层的所有神经元上运行的,当$$k \ne j$$时$$\frac{\partial a^L_k}{\partial z^L_j}=0$$,于是,我们可以简化方程为: 24 | 25 | 26 | $$ 27 | \delta^L_j=\frac{\partial C}{\partial a^L_j}\frac{\partial a^L_j}{\partial z^L_j} 28 | $$ 29 | 30 | 31 | 然后$$a^L_j=\sigma(z^L_j)$$,于是,可以写成 32 | 33 | 34 | $$ 35 | \delta^L_j=\frac{\partial C}{\partial a^L_j}\sigma'(z^L_j) 36 | $$ 37 | 38 | 39 | 以矩阵的形式重写方程,其中每个元素$$\frac{\partial C}{\partial a^L_j}$$构成的向量表示成$$\nabla_aC$$,每个元素$$\sigma'(z^L_j)$$构成的向量表示成$$\sigma'(z^L)$$,于是得到 40 | 41 | 42 | $$ 43 | \delta^{L}= \begin{bmatrix} 44 | \delta^L_{1} \\ 45 | \delta^L_{2} \\ 46 | \delta^L_{3} \\ 47 | ... \\ 48 | \delta^L_{n} 49 | \end{bmatrix}=\begin{bmatrix} 50 | \frac{\partial C}{\partial a^L_1}\sigma'(z^L_1) \\ 51 | \frac{\partial C}{\partial a^L_2}\sigma'(z^L_2) \\ 52 | \frac{\partial C}{\partial a^L_3}\sigma'(z^L_3) \\ 53 | ... \\ 54 | \frac{\partial C}{\partial a^L_n}\sigma'(z^L_n) 55 | \end{bmatrix}=\nabla_aC \odot \sigma'(z^L) 56 | $$ 57 | 58 | 59 | ### 2. 使用下一层的误差$$\delta^{l+1}$$来表示当前层误差$$\delta^l$$ 60 | 61 | 特别的, 62 | 63 | 64 | $$ 65 | \delta^l =((w^{l+1})^T\delta^{l+1}) \odot\sigma'(z^l) 66 | $$ 67 | 68 | 69 | 其中$$(w^{l+1})^T$$是$$(l+1)^{th}$$层权重矩阵$$w^{l+1}$$的转置。这个公式看过去有点复杂,但是每个元素都有很好得分解释,假设我们知道$$(l+1)^{th}$$的误差向量$$\delta^{l+1}$$,当我们应用转置的权重矩阵$$(w^{l+1})^T$$,我们可以把它看做是沿着网络反向移动误差,给了我们度量在$$l^{th}$$层的误差的方法。然后进行Hadamard乘积运算$$\sigma'(z^l)$$,这会让误差通过$$l$$层的激活函数反向传递回来并给出在第$$l$$层的带权输入误差向量$$\delta^l$$。 70 | 71 | 根据该公式,我们可以首先根据第一个公式得到输出层的误差$$\delta^L$$,然后得到第$$(L-1)^{th}$$层的误差,如此一步步地方向传播完整个网络。 72 | 73 | 证明:根据链式法则,我们可以将$$\delta^l_j= \frac{\partial C}{\partial z^l_j}$$写成: 74 | 75 | 76 | $$ 77 | \delta^l_j= \frac{\partial C}{\partial z^l_j}=\displaystyle\sum_{k}\frac{\partial C}{\partial z^{l+1}_{k}}\frac{\partial z^{l+1}_k}{\partial z^l_j}=\displaystyle\sum_{k}\frac{\partial z^{l+1}_k}{\partial z^l_j}\delta^{l+1}_k 78 | $$ 79 | 80 | 81 | 这里我们将最后一个式子交换了两边的项,并用$$\delta^{l+1}_k$$代入。然后 82 | 83 | 84 | $$ 85 | z^{l+1}_k=\displaystyle\sum_{j}w^{l+1}_{kj}a^l_j+b^{l+1}_k=\displaystyle\sum_{j}w^{l+1}_{kj}\sigma(z^{l}_j)+b^{l+1}_k 86 | $$ 87 | 88 | 89 | 做微分,我们得到 90 | 91 | 92 | $$ 93 | \frac{\partial z^{l+1}_k}{\partial z^l_j}=w^{l+1}_{kj}\sigma'(z^{l}_j) 94 | $$ 95 | 96 | 97 | 代入上式,得到 98 | 99 | 100 | $$ 101 | \delta^l_j=\displaystyle\sum_{k}w^{l+1}_{kj}\sigma'(z^{l}_j)\delta^{l+1}_k=(\displaystyle\sum_{k}w^{l+1}_{kj}\delta^{l+1}_k) \sigma'(z^{l}_j) 102 | $$ 103 | 104 | 105 | 将公式进行矩阵化,最后得到第一个公式。 106 | 107 | 举例来说,如下图: 108 | 109 | ![](/assets/network-bp-pic.png) 110 | 111 | 当我们已经计算得到了第$$3$$层的误差向量$$\delta^{3}= \begin{bmatrix} 112 | \delta^3_{1} \\ 113 | \delta^3_{2} 114 | \end{bmatrix}$$,这时计算第$$2$$层的误差向量$$\delta^2$$,我们先计算$$\delta^2_3$$,根据上面的公式可以得到 115 | 116 | 117 | $$ 118 | \delta^2_3=(\displaystyle\sum_{k}w^{3}_{k3}\delta^3_k) \sigma'(z^{3}_3)=(w^{3}_{13}\delta^3_1+w^{3}_{23}\delta^3_2) \sigma'(z^{2}_3)=(\begin{bmatrix} 119 | w^3_{13} \\ 120 | w^3_{23} 121 | \end{bmatrix}^T \cdot \begin{bmatrix} 122 | \delta^3_{1} \\ 123 | \delta^3_{2} 124 | \end{bmatrix})\sigma'(z^{2}_3) 125 | $$ 126 | 127 | 128 | 也就是图中两条绿色的线所标识的权重与误差的乘积和。 129 | 130 | ### 3. 代价函数关于网络中任意偏置的改变率 131 | 132 | 133 | $$ 134 | \frac{\partial C}{\partial b^l_j}=\delta^l_j 135 | $$ 136 | 137 | 138 | 也就是误差$$\delta^l_j$$和$$\frac{\partial C}{\partial b^l_j}$$完全一致。 139 | 140 | 证明:根据链式法则,其中$$z^l_j = \displaystyle\sum_{k}w^l_{jk} a^{l-1}_k + b^l_j$$,最终可以得到 141 | 142 | 143 | $$ 144 | \frac{\partial C}{\partial b^l_j} = \frac{\partial C}{\partial z^l_{j}}\frac{\partial z^l_j}{\partial b^l_j}=\frac{\partial C}{\partial z^l_{j}} 145 | $$ 146 | 147 | 148 | 用矩阵表示,可以表示成: 149 | 150 | 151 | $$ 152 | \frac{\partial C}{\partial b^l}=\delta^l 153 | $$ 154 | 155 | 156 | ### 4. 代价函数关于任何一个权重的改变率 157 | 158 | 159 | $$ 160 | \frac{\partial C}{\partial w^l_{jk}}=a^{l-1}_k\delta^l_j 161 | $$ 162 | 163 | 164 | 证明:根据链式法则,其中$$z^l_j = \displaystyle\sum_{k}w^l_{jk} a^{l-1}_k + b^l_j$$,最终可以得到 165 | 166 | 167 | $$ 168 | \frac{\partial C}{\partial w^l_{jk}} = \frac{\partial C}{\partial z^l_{j}}\frac{\partial z^l_j}{\partial b^l_j}=\frac{\partial C}{\partial z^l_{j}} a^{l-1}_j=a^{l-1}_k\delta^l_j 169 | $$ 170 | 171 | 172 | 举例来说: 173 | 174 | ![](/assets/network-bp-w.png) 175 | 176 | 上面图中,想要计算$$\frac{\partial C}{\partial w^3_{13}}$$,则$$\frac{\partial C}{\partial w^3_{13}}=a^2_3\delta^3_1$$。也可以理解成: 177 | 178 | 179 | $$ 180 | \frac{\partial C}{\partial w}=a_{in}\delta_{out} 181 | $$ 182 | 183 | 184 | 其中$$a_{in}$$是输入给权重$$w$$的神经元的激活值,$$\delta_{out}$$是输出自权重$$w$$的神经元的误差。 185 | 186 | 用矩阵表示,可以表示成(其中第$$(l-1)^{th}$$层神经元有$$m$$个,第$$l^{th}$$层神经元有$$n$$个) 187 | 188 | 189 | $$ 190 | \frac{\partial C}{\partial w^l} = \partial C/\partial \begin{bmatrix} 191 | w^l_{11} & w^l_{12} & w^l_{13} & ... & w^l_{1m} \\ 192 | w^l_{21} & w^l_{22} & w^l_{23} & ... & w^l_{1m} \\ 193 | w^l_{31} & w^l_{12} & w^l_{13} & ... & w^l_{1m} \\ 194 | ... \\ 195 | w^l_{n1} & w^l_{n2} & w^l_{n3} & ... & w^l_{nm} 196 | \end{bmatrix}=\begin{bmatrix} 197 | a^{l-1}_1 \delta^l_1 & a^{l-1}_2 \delta^l_1 & a^{l-1}_3 \delta^l_1 & ... & a^{l-1}_m \delta^l_1 \\ 198 | a^{l-1}_1 \delta^l_2 & a^{l-1}_2 \delta^l_2 & a^{l-1}_3 \delta^l_2 & ... & a^{l-1}_m \delta^l_2 \\ 199 | a^{l-1}_1 \delta^l_3 & a^{l-1}_2 \delta^l_3 & a^{l-1}_3 \delta^l_3 & ... & a^{l-1}_m \delta^l_3 \\ 200 | ... \\ 201 | a^{l-1}_1 \delta^l_n & a^{l-1}_2 \delta^l_n & a^{l-1}_3 \delta^l_n & ... & a^{l-1}_m \delta^l_n 202 | \end{bmatrix} 203 | $$ 204 | 205 | 206 | 于是得到: 207 | 208 | 209 | $$ 210 | \frac{\partial C}{\partial w^l}= \begin{bmatrix} 211 | \delta_1^{l} \\ 212 | \delta_2^{l} \\ 213 | \delta_3^{l} \\ 214 | ... \\ 215 | \delta_n^{l} 216 | \end{bmatrix}\cdot [a^{l-1}_1, a^{l-1}_2, ..., a^{l-1}_m] 217 | $$ 218 | 219 | 220 | 其中$$[\delta^l_1, \delta^l_2, ..., \delta^l_n]$$是$$n * 1$$,$$[a^{l-1}_1, a^{l-1}_2, ..., a^{l-1}_m]$$是$$1 * m$$,最终得到$$n*m$$的权重矩阵。 221 | 222 | -------------------------------------------------------------------------------- /shen-jing-wang-luo/fan-xiang-chuan-bo-suan-fa/ji-yu-ju-zhen-de-bp-ji-suan.md: -------------------------------------------------------------------------------- 1 | 上面一章的 \`update\_mini\_batch\` 函数是每个数据集独立计算后向传播,后面再做平均值, 2 | 3 | def update_mini_batch(self, mini_batch, eta): 4 | """Update the network's weights and biases by applying 5 | gradient descent using backpropagation to a single mini batch. 6 | The ``mini_batch`` is a list of tuples ``(x, y)``, and ``eta`` 7 | is the learning rate.""" 8 | # 初始化梯度值矩阵为 0 9 | # Nabla算子,在中文中也叫向量微分算子、劈形算子、倒三角算子 10 | nabla_b = [np.zeros(b.shape) for b in self.biases] 11 | nabla_w = [np.zeros(w.shape) for w in self.weights] 12 | for x, y in mini_batch: 13 | # 迭代计算梯度矩阵和 14 | # 获取当前样本通过反向传播算法得到的 delta 梯度值 15 | delta_nabla_b, delta_nabla_w = self.backprop(x, y) 16 | # 把 mini_batch 里面每个数据算出来的梯度做加和,后面再取平均 17 | nabla_b = [nb+dnb for nb, dnb in zip(nabla_b, delta_nabla_b)] 18 | nabla_w = [nw+dnw for nw, dnw in zip(nabla_w, delta_nabla_w)] 19 | # 把梯度值取平均,并乘以系数 eta,然后更新权重和偏置矩阵 20 | self.weights = [w-(eta/len(mini_batch))*nw for w, nw in zip(self.weights, nabla_w)] 21 | self.biases = [b-(eta/len(mini_batch))*nb for b, nb in zip(self.biases, nabla_b)] 22 | 23 | 这里介绍一下如何通过矩阵的方式直接计算一个 mini batch 的梯度值向量。代码来源:[https://github.com/hindSellouk/Matrix-Based-Backpropagation/blob/master/Network1.py](https://github.com/hindSellouk/Matrix-Based-Backpropagation/blob/master/Network1.py) 24 | 25 | ``` 26 | import random 27 | from os import access 28 | 29 | import numpy as np 30 | import time 31 | 32 | class Network(object): 33 | 34 | def __init__(self, sizes): 35 | self.num_layers = len(sizes) 36 | self.sizes = sizes 37 | self.biases = [np.random.randn(y, 1) for y in sizes[1:]] 38 | self.weights = [np.random.randn(y, x) 39 | for x, y in zip(sizes[:-1], sizes[1:])] 40 | 41 | 42 | def SGD(self, training_data, epochs, mini_batch_size, eta, 43 | test_data=None): 44 | if test_data: n_test = len(test_data) 45 | n = len(training_data) 46 | for j in xrange(epochs): 47 | start_time = time.time() 48 | random.shuffle(training_data) 49 | mini_batches = [ 50 | training_data[k:k+mini_batch_size] 51 | for k in xrange(0, n, mini_batch_size)] 52 | for mini_batch in mini_batches: 53 | self.update_mini_batch(mini_batch, eta) 54 | print("--- %s seconds elapsed---" % (time.time() - start_time)) 55 | if test_data: 56 | print "Epoch {0}: {1} / {2}".format( 57 | j, self.evaluate(test_data), n_test) 58 | else: 59 | print "Epoch {0} complete".format(j) 60 | 61 | def update_mini_batch(self, mini_batch, eta): 62 |   # mini batch 是一个 list,list 里面每个元素是一个 tuple (x, y) 63 | matrix_X=mini_batch[0][0] 64 | matrix_Y=mini_batch[0][1] 65 | #create matrix_X of examples and a matrix_Y of labels 66 | for x,y in mini_batch[1:]: 67 | # 将 mini batch 里面的每个数据拼接起来,成一个 matrix 68 | matrix_X = np.concatenate((matrix_X,x), axis=1) 69 | matrix_Y = np.concatenate((matrix_Y,y), axis=1) 70 | 71 | nabla_b, nabla_w = self.backprop(matrix_X,matrix_Y) 72 | # 下面将返回的权重和偏置梯度值做平均 73 | self.weights = [w - (eta / len(mini_batch)) * nw 74 | for w, nw in zip(self.weights, nabla_w)] 75 | self.biases = [b - (eta / len(mini_batch)) * nb 76 | for b, nb in zip(self.biases, nabla_b) ] 77 | 78 | 79 | def backprop(self, x, y): 80 | # 这里 x 和 y 就都是一个 matrix,包括一个 batch 大小的数据 81 | nabla_b = [np.zeros(b.shape) for b in self.biases] 82 | nabla_w = [np.zeros(w.shape) for w in self.weights] 83 | # feedforward 84 | activation = x 85 | activations = [x] # list to store all the activation matrices, layer by layer 86 | zs = [] # list to store all the "sum of weighted inputs z" matrices, layer by layer 87 | i=0 88 | for b, w in zip(self.biases, self.weights): 89 | z = np.dot(w, activation) + b 90 | zs.append(z) 91 | activation = sigmoid(z) 92 | activations.append(activation) 93 | # 这里 delta 就是一个矩阵,如果 batch 为 10 大小的话 94 | # ('backprop delta', (10, 10), ) 95 | delta = self.cost_derivative(activations[-1], y) * \ 96 | sigmoid_prime(zs[-1]) 97 | # 这里先将上面的 delta 矩阵做了加和,变成了 98 | # (10,), ) 99 | # 然后做了扩展,变成如下 100 | # ('nabla_b[-1]', (10, 1), ) 101 | nabla_b[-1] = np.expand_dims(np.sum(delta,axis=1),axis=1) 102 | # 最后一层的权重矩阵 103 | # ('nabla_w[-1]', (10, 30), ) 104 | # 这里 np.dot 将 batch 的所有权重做了线性和 105 | nabla_w[-1] = np.dot(delta, activations[-2].transpose()) 106 | 107 | for l in xrange(2, self.num_layers): 108 | z = zs[-l] 109 | sp = sigmoid_prime(z) 110 | # 10 * 10 111 | delta = np.dot(self.weights[-l + 1].transpose(), delta) * sp 112 | # 这里 np.sum 将 batch 的所有误差做了线性和 113 | nabla_b[-l] = np.expand_dims(np.sum(delta,axis=1),axis=1) 114 | # 这里 np.dot 将 batch 的所有权重做了线性和 115 | # 原来 delta 是 n * 1, activations[-l - 1].transpose() 是 1 * m 116 | # batch 的情况下,delta 是 n * batch size, activations[-l - 1].transpose() 是 batch size * m 117 | nabla_w[-l] = np.dot(delta, activations[-l - 1].transpose()) 118 | 119 | return (nabla_b, nabla_w) 120 | 121 | def feedforward(self, a): 122 | for b, w in zip(self.biases, self.weights): 123 | a = sigmoid(np.dot(w, a)+b) 124 | return a 125 | def evaluate(self, test_data): 126 | test_results = [(np.argmax(self.feedforward(x)), y) 127 | for (x, y) in test_data] 128 | return sum(int(x == y) for (x, y) in test_results) 129 | 130 | def cost_derivative(self, output_activations, y): 131 | return (output_activations-y) 132 | 133 | 134 | 135 | def sigmoid(z): 136 | return 1.0/(1.0+np.exp(-z)) 137 | 138 | def sigmoid_prime(z): 139 | return sigmoid(z)*(1-sigmoid(z)) 140 | ``` 141 | 142 | 执行代码: 143 | 144 | ``` 145 | import mnist_loader 146 | training_data, validation_data, test_data = mnist_loader.load_data_wrapper() 147 | import network1 148 | net = network1.Network([784, 30, 10]) 149 | from datetime import datetime as datetime 150 | print(datetime.now()) 151 | net.SGD(training_data, 30, 10, 3.0, test_data=test_data); 152 | print(datetime.now()) 153 | ``` 154 | 155 | 基于矩阵运算的算法一个 Epoch 大约为 3 秒: 156 | 157 | ``` 158 | --- 3.12179398537 seconds elapsed--- 159 | Epoch 0: 9061 / 10000 160 | --- 3.03969407082 seconds elapsed--- 161 | Epoch 1: 9177 / 10000 162 | --- 3.00676393509 seconds elapsed--- 163 | Epoch 2: 9261 / 10000 164 | ``` 165 | 166 | 不基于矩阵运算的算法一个 Epoch 大约为 11 秒: 167 | 168 | ``` 169 | --- 11.0207378864 seconds elapsed--- 170 | Epoch 0: 9079 / 10000 171 | --- 11.092361927 seconds elapsed--- 172 | Epoch 1: 9247 / 10000 173 | --- 11.0678529739 seconds elapsed--- 174 | Epoch 2: 9326 / 10000 175 | ``` 176 | 177 | 178 | 179 | -------------------------------------------------------------------------------- /shen-jing-wang-luo/fan-xiang-chuan-bo-suan-fa/suan-fa-dai-ma.md: -------------------------------------------------------------------------------- 1 | ### 反向传播算法代码 2 | 3 | 给定一个大小为$$m$$的小批量数据,在小批量数据的基础上应用梯度下降学习算法: 4 | 5 | 1. **输入训练样本的集合** 6 | 2. **对于每个训练样本**$$x$$:设置对应的输入激活$$a^{x,1}$$,并执行下面的步骤 7 | 1. **前向传播**:对于每一个$$l=2,3,...,L$$,计算$$z^{x,l}=w^l a^{x,l-1} + b^l$$和$$a^{x,l}=\sigma(z^{x,l})$$ 8 | 9 | 1. **输出误差**$$\delta^{x,L}$$:计算向量$$\delta^{x,L}=\nabla_a C_x \odot \sigma'(z^{x,L})$$ 10 | 11 | 2. **反向传播误差**:对于每一个$$l=L-1,L-2,...,2$$计算$$\delta^{x,l}=((w^{l+1})^T \delta^{x, l+1}) \odot \sigma'(z^{x,l})$$ 12 | 13 | 3. **梯度下降**:对于每一个$$l=L-1, L-2, ..., 2$$根据$$w^l\to w^l - \frac{\eta}{m}\displaystyle\sum_{x}\delta^{x,l} (a^{x,l-1})^T$$和$$b^l\to b^l - \frac{\eta}{m}\displaystyle\sum_{x}\delta^{x,l} $$更新权重和偏置。 14 | 15 | #### 二次代价函数及sigmoid函数 16 | 17 | 如果使用二次代价函数,则每个训练样本的成本函数是$$C_x=\frac{1}{2}||y(x)-a^L(x)||^2$$,则$$\nabla_a C_x = y(x)-a(x)$$ 18 | 19 | sigmoid 激活函数$$\sigma(z) = \frac{1}{1+e^{-z}}$$的导数$$\sigma'(z) = \frac{1}{1+e^{-z}}(1-\frac{1}{1+e^{-z}})=\sigma(z) (1-\sigma(z))$$ 20 | 21 | ### Python 代码 22 | 23 | 这里的代码来自 [https://github.com/mnielsen/neural-networks-and-deep-learning](https://github.com/mnielsen/neural-networks-and-deep-learning) 24 | 25 | ```py 26 | """ 27 | mnist_loader 28 | ~~~~~~~~~~~~ 29 | 30 | A library to load the MNIST image data. For details of the data 31 | structures that are returned, see the doc strings for ``load_data`` 32 | and ``load_data_wrapper``. In practice, ``load_data_wrapper`` is the 33 | function usually called by our neural network code. 34 | """ 35 | 36 | #### Libraries 37 | # Standard library 38 | import cPickle 39 | import gzip 40 | 41 | # Third-party libraries 42 | import numpy as np 43 | 44 | def load_data(): 45 | """Return the MNIST data as a tuple containing the training data, 46 | the validation data, and the test data. 47 | 48 | The ``training_data`` is returned as a tuple with two entries. 49 | The first entry contains the actual training images. This is a 50 | numpy ndarray with 50,000 entries. Each entry is, in turn, a 51 | numpy ndarray with 784 values, representing the 28 * 28 = 784 52 | pixels in a single MNIST image. 53 | 54 | The second entry in the ``training_data`` tuple is a numpy ndarray 55 | containing 50,000 entries. Those entries are just the digit 56 | values (0...9) for the corresponding images contained in the first 57 | entry of the tuple. 58 | 59 | The ``validation_data`` and ``test_data`` are similar, except 60 | each contains only 10,000 images. 61 | 62 | This is a nice data format, but for use in neural networks it's 63 | helpful to modify the format of the ``training_data`` a little. 64 | That's done in the wrapper function ``load_data_wrapper()``, see 65 | below. 66 | """ 67 | f = gzip.open('../data/mnist.pkl.gz', 'rb') 68 | training_data, validation_data, test_data = cPickle.load(f) 69 | f.close() 70 | return (training_data, validation_data, test_data) 71 | 72 | def load_data_wrapper(): 73 | """Return a tuple containing ``(training_data, validation_data, 74 | test_data)``. Based on ``load_data``, but the format is more 75 | convenient for use in our implementation of neural networks. 76 | 77 | In particular, ``training_data`` is a list containing 50,000 78 | 2-tuples ``(x, y)``. ``x`` is a 784-dimensional numpy.ndarray 79 | containing the input image. ``y`` is a 10-dimensional 80 | numpy.ndarray representing the unit vector corresponding to the 81 | correct digit for ``x``. 82 | 83 | ``validation_data`` and ``test_data`` are lists containing 10,000 84 | 2-tuples ``(x, y)``. In each case, ``x`` is a 784-dimensional 85 | numpy.ndarry containing the input image, and ``y`` is the 86 | corresponding classification, i.e., the digit values (integers) 87 | corresponding to ``x``. 88 | 89 | Obviously, this means we're using slightly different formats for 90 | the training data and the validation / test data. These formats 91 | turn out to be the most convenient for use in our neural network 92 | code.""" 93 | tr_d, va_d, te_d = load_data() 94 | training_inputs = [np.reshape(x, (784, 1)) for x in tr_d[0]] 95 | training_results = [vectorized_result(y) for y in tr_d[1]] 96 | training_data = zip(training_inputs, training_results) 97 | validation_inputs = [np.reshape(x, (784, 1)) for x in va_d[0]] 98 | validation_data = zip(validation_inputs, va_d[1]) 99 | test_inputs = [np.reshape(x, (784, 1)) for x in te_d[0]] 100 | test_data = zip(test_inputs, te_d[1]) 101 | # training_data 是一个 list 包含 5000 个元素,每个元素是一个 tuple (x, y),其中 102 | # x 是一个 784 * 1 的向量 103 | # y 是一个 10 * 1 的向量,向量中某个位置为非 0 表示的是0-9的某个数字 104 | # validation_data 和 test_data 都是 list 包含 1000 个元素,每个元素是一个 tuple (x, y),其中 105 | # x 是一个 784 * 1 的向量 106 | # y 是一个 0-9 的数字 107 | return (training_data, validation_data, test_data) 108 | 109 | def vectorized_result(j): 110 | """Return a 10-dimensional unit vector with a 1.0 in the jth 111 | position and zeroes elsewhere. This is used to convert a digit 112 | (0...9) into a corresponding desired output from the neural 113 | network.""" 114 | e = np.zeros((10, 1)) 115 | e[j] = 1.0 116 | return e 117 | ``` 118 | 119 | #!/usr/bin/env python 120 | # -*- coding: utf-8 -*- 121 | """ 122 | network.py 123 | ~~~~~~~~~~ 124 | 125 | A module to implement the stochastic gradient descent learning 126 | algorithm for a feedforward neural network. Gradients are calculated 127 | using backpropagation. Note that I have focused on making the code 128 | simple, easily readable, and easily modifiable. It is not optimized, 129 | and omits many desirable features. 130 | """ 131 | 132 | #### Libraries 133 | # Standard library 134 | import random 135 | 136 | # Third-party libraries 137 | import numpy as np 138 | 139 | class Network(object): 140 | 141 | def __init__(self, sizes): 142 | """The list ``sizes`` contains the number of neurons in the 143 | respective layers of the network. For example, if the list 144 | was [2, 3, 1] then it would be a three-layer network, with the 145 | first layer containing 2 neurons, the second layer 3 neurons, 146 | and the third layer 1 neuron. The biases and weights for the 147 | network are initialized randomly, using a Gaussian 148 | distribution with mean 0, and variance 1. Note that the first 149 | layer is assumed to be an input layer, and by convention we 150 | won't set any biases for those neurons, since biases are only 151 | ever used in computing the outputs from later layers.""" 152 | # size 是一个 list ,该长度表示了神经网络的总层数 153 | # list 里面每一个元素的值表示的是神经元的个数 154 | # 举例来说,输入 size=[784, 30, 10],则神经网络层数有3层 155 | # 第一层有 784 个神经元,第二层有 30 个,第三层有 10 个 156 | self.num_layers = len(sizes) 157 | self.sizes = sizes 158 | # biases 是一个 list,每个元素是 (n * 1) 的向量,表示的神经网络对应层的偏置个数 159 | # 第一层输入,所以偏置从第二层开始 160 | # 举例来说,输入 size=[784, 30, 10] 161 | # 则,biases list 有两个元素,第一个元素是 (30 * 1 ),第二个元素是 (10 * 1) 162 | self.biases = [np.random.randn(y, 1) for y in sizes[1:]] 163 | # weights 是一个list, 每个元素是 (n * m)的矩阵, 164 | # 其中 n 是下一层网络的神经元个数,m 是上一层网络的神经元个数 165 | # 举例来说,输入 size=[784, 30, 10] 166 | # 则, weights 有两个元素,第一个元素是 (30 * 784)的矩阵,第二个元素是 (10 * 30)的矩阵 167 | self.weights = [np.random.randn(y, x) for x, y in zip(sizes[:-1], sizes[1:])] 168 | 169 | def feedforward(self, a): 170 | """Return the output of the network if ``a`` is input.""" 171 | for b, w in zip(self.biases, self.weights): 172 | a = sigmoid(np.dot(w, a)+b) 173 | return a 174 | 175 | def SGD(self, training_data, epochs, mini_batch_size, eta, test_data=None): 176 | """Train the neural network using mini-batch stochastic 177 | gradient descent. The ``training_data`` is a list of tuples 178 | ``(x, y)`` representing the training inputs and the desired 179 | outputs. The other non-optional parameters are 180 | self-explanatory. If ``test_data`` is provided then the 181 | network will be evaluated against the test data after each 182 | epoch, and partial progress printed out. This is useful for 183 | tracking progress, but slows things down substantially.""" 184 | if test_data: n_test = len(test_data) 185 | n = len(training_data) 186 | for j in xrange(epochs): 187 | random.shuffle(training_data) 188 | mini_batches = [training_data[k:k+mini_batch_size] 189 | for k in xrange(0, n, mini_batch_size)] 190 | for mini_batch in mini_batches: 191 | self.update_mini_batch(mini_batch, eta) 192 | if test_data: 193 | print "Epoch {0}: {1} / {2}".format(j, self.evaluate(test_data), n_test) 194 | else: 195 | print "Epoch {0} complete".format(j) 196 | 197 | def update_mini_batch(self, mini_batch, eta): 198 | """Update the network's weights and biases by applying 199 | gradient descent using backpropagation to a single mini batch. 200 | The ``mini_batch`` is a list of tuples ``(x, y)``, and ``eta`` 201 | is the learning rate.""" 202 | # 初始化梯度值矩阵为 0 203 | nabla_b = [np.zeros(b.shape) for b in self.biases] 204 | nabla_w = [np.zeros(w.shape) for w in self.weights] 205 | for x, y in mini_batch: 206 | # 迭代计算梯度矩阵和 207 | # 获取当前样本通过反向传播算法得到的 delta 梯度值 208 | delta_nabla_b, delta_nabla_w = self.backprop(x, y) 209 | # 把 mini_batch 里面每个数据算出来的梯度做加和,后面再取平均 210 | nabla_b = [nb+dnb for nb, dnb in zip(nabla_b, delta_nabla_b)] 211 | nabla_w = [nw+dnw for nw, dnw in zip(nabla_w, delta_nabla_w)] 212 | # 把梯度值取平均,并乘以系数 eta,然后更新权重和偏置矩阵 213 | self.weights = [w-(eta/len(mini_batch))*nw for w, nw in zip(self.weights, nabla_w)] 214 | self.biases = [b-(eta/len(mini_batch))*nb for b, nb in zip(self.biases, nabla_b)] 215 | 216 | def backprop(self, x, y): 217 | """ 218 | 返回一个 tuple,里面包含 (nabla_b, nabla_w) 219 | 其中 nabla_b 是一个 list,每一个元素又是一个 arrays,包含的是网络中每一个 Layer 的 b 梯度值 220 | 其中 nabla_w 是一个 list,每一个元素又是一个 arrays,包含的是网络中每一个 Layer 的 w 梯度值 221 | Return a tuple ``(nabla_b, nabla_w)`` representing the 222 | gradient for the cost function C_x. ``nabla_b`` and 223 | ``nabla_w`` are layer-by-layer lists of numpy arrays, similar 224 | to ``self.biases`` and ``self.weights``. 225 | """ 226 | nabla_b = [np.zeros(b.shape) for b in self.biases] 227 | nabla_w = [np.zeros(w.shape) for w in self.weights] 228 | # feedforward 229 | activation = x 230 | activations = [x] # list to store all the activations, layer by layer 231 | zs = [] # list to store all the z vectors, layer by layer 232 | # 通过前向传播,计算神经网络所有层的线性输入值和激活输出 233 | for b, w in zip(self.biases, self.weights): 234 | z = np.dot(w, activation)+b 235 | zs.append(z) 236 | activation = sigmoid(z) 237 | activations.append(activation) 238 | # backward pass 239 | # 计算最后一层的输出误差 240 | # cost_derivative 是二次代价函数的导数 241 | # sigmoid_prime 是 sigmode 激活函数的导数 242 | # * 运算是按照每个元素的 Hadamard 乘积 243 | # 结果的 delta 是一个向量,大小为 (最后一层的神经元个数, 1) 244 | delta = self.cost_derivative(activations[-1], y) * sigmoid_prime(zs[-1]) 245 | # 偏置的改变率和偏差值相同 246 | nabla_b[-1] = delta 247 | # 权重的改变率是下一层的偏差和前一层的激活值向量內积 248 | nabla_w[-1] = np.dot(delta, activations[-2].transpose()) 249 | # Note that the variable l in the loop below is used a little 250 | # differently to the notation in Chapter 2 of the book. Here, 251 | # l = 1 means the last layer of neurons, l = 2 is the 252 | # second-last layer, and so on. It's a renumbering of the 253 | # scheme in the book, used here to take advantage of the fact 254 | # that Python can use negative indices in lists. 255 | for l in xrange(2, self.num_layers): 256 | z = zs[-l] 257 | sp = sigmoid_prime(z) 258 | # 计算第 l-1 层的误差向量 259 | # 权重矩阵和误差的矩阵乘积 260 | delta = np.dot(self.weights[-l+1].transpose(), delta) * sp 261 | nabla_b[-l] = delta 262 | nabla_w[-l] = np.dot(delta, activations[-l-1].transpose()) 263 | return (nabla_b, nabla_w) 264 | 265 | def evaluate(self, test_data): 266 | """Return the number of test inputs for which the neural 267 | network outputs the correct result. Note that the neural 268 | network's output is assumed to be the index of whichever 269 | neuron in the final layer has the highest activation.""" 270 | # np.argmax 获取到神经网络输出的向量中最大值的 index,也就是 0-9 271 | test_results = [(np.argmax(self.feedforward(x)), y) for (x, y) in test_data] 272 | # 计算所有输出和测试数据相同的样本数量 273 | return sum(int(x == y) for (x, y) in test_results) 274 | 275 | def cost_derivative(self, output_activations, y): 276 | """Return the vector of partial derivatives \partial C_x / 277 | \partial a for the output activations.""" 278 | # 二次代价函数的导数 279 | return (output_activations-y) 280 | 281 | #### Miscellaneous functions 282 | def sigmoid(z): 283 | """The sigmoid function.""" 284 | return 1.0/(1.0+np.exp(-z)) 285 | 286 | def sigmoid_prime(z): 287 | """Derivative of the sigmoid function.""" 288 | return sigmoid(z)*(1-sigmoid(z)) 289 | 290 | 执行算法: 291 | 292 | ``` 293 | import mnist_loader 294 | training_data, validation_data, test_data = mnist_loader.load_data_wrapper() 295 | import network 296 | net = network.Network([784, 30, 10]) 297 | from datetime import datetime as datetime 298 | print(datetime.now()) 299 | net.SGD(training_data, 30, 10, 3.0, test_data=test_data); 300 | print(datetime.now()) 301 | ``` 302 | 303 | 输出: 304 | 305 | ``` 306 | Epoch 0: 9040 / 10000 307 | Epoch 1: 9156 / 10000 308 | Epoch 2: 9256 / 10000 309 | ... 310 | ``` 311 | 312 | 313 | 314 | -------------------------------------------------------------------------------- /shen-jing-wang-luo/gai-jin-shen-jing-wang-luo-de-xue-xi-fang-fa.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/shen-jing-wang-luo/gai-jin-shen-jing-wang-luo-de-xue-xi-fang-fa.md -------------------------------------------------------------------------------- /shen-jing-wang-luo/gai-jin-shen-jing-wang-luo-de-xue-xi-fang-fa/jiao-cha-shang-dai-jia-han-shu.md: -------------------------------------------------------------------------------- 1 | ### 二次代价函数的问题 2 | 3 | 当使用二次代价函数的时候, 4 | 5 | 6 | $$ 7 | C=\frac{(y-a)^2}{2} 8 | $$ 9 | 10 | 11 | 其中$$a$$时神经元的输出,$$a=\sigma(z)$$,其中$$z=wx+b$$。这时计算偏导数 12 | 13 | 14 | $$ 15 | \frac{\partial C}{\partial w}= (a-y)\sigma'(z)x 16 | $$ 17 | 18 | 19 | 20 | $$ 21 | \frac{\partial C}{\partial b}=(a-y)\sigma'(z) 22 | $$ 23 | 24 | 25 | 我们来看一下$$sigmoid$$函数的图形 26 | 27 | ![](/assets/sigmoid_function.png) 28 | 29 | 从图中可以看出,当神经元的输出接近于1的时候,曲线变得相当平,所以$$\sigma'(z)$$就很小,于是$$\frac{\partial C}{\partial w}$$和$$\frac{\partial C}{\partial b}$$也会很小,这个会导致在梯度下降过程中学习变得缓慢。 30 | 31 | ### 引入交叉熵代价函数 32 | 33 | 定义交叉熵代价函数: 34 | 35 | 36 | $$ 37 | C= -\frac{1}{n}\displaystyle\sum_{x}[y\mathrm{ln}a+(1-y)\mathrm{ln}(1-a))] 38 | $$ 39 | 40 | 41 | 交叉熵有一个比代价函数更好的特性就是它避免了学习速度下降的问题。 42 | 我们来计算交叉熵函数的偏导数,将$$a = \sigma(z)$$ 代入上式,并求偏导数 43 | 44 | 45 | $$ 46 | \frac{\partial C}{\partial w_j}= -\frac{1}{n}\displaystyle\sum_{x}\big(\frac{y}{\sigma(z)}-\frac{1-y}{1-\sigma(z)}\big)\frac{\partial \sigma(z)}{\partial w_j} 47 | $$ 48 | 49 | 50 | 51 | $$ 52 | =-\frac{1}{n}\displaystyle\sum_{x}\big(\frac{y}{\sigma(z)}-\frac{1-y}{1-\sigma(z)}\big)\sigma'(z)x_j 53 | $$ 54 | 55 | 56 | 57 | $$ 58 | =-\frac{1}{n}\displaystyle\sum_{x}\frac{\sigma(z)-y}{\sigma(z)(1-\sigma(z))}\sigma'(z)x_j 59 | $$ 60 | 61 | 62 | 其中$$\sigma(z)=\frac{1}{1+e^{-x}}$$,计算可得$$\sigma'(z)=\sigma(z)(1-\sigma(z))$$,于是得到 63 | 64 | 65 | $$ 66 | \frac{\partial C}{\partial w_j}=-\frac{1}{n}\displaystyle\sum_{x}(\sigma(z)-y)x_j 67 | $$ 68 | 69 | 70 | 这里权重的学习速度受到$$\sigma(z)-y$$的影响,也就是输出中的误差的控制。更大的误差会有更大的学习速度。 71 | 72 | 同样的,我们可以得到关于偏置的偏导数 73 | 74 | 75 | $$ 76 | \frac{\partial C}{\partial b}=-\frac{1}{n}\displaystyle\sum_{x}(\sigma(z)-y) 77 | $$ 78 | 79 | 80 | **交叉熵函数扩展到多神经元的多层神经网络上** 81 | 82 | 假设$$y=y1,y2,...$$是输出神经元上的目标值,而$$a^L_1,a^L_2,...$$时实际的输出值,那么我们定义交叉熵如下 83 | 84 | 85 | $$ 86 | C= -\frac{1}{n}\displaystyle\sum_{x}\displaystyle\sum_{y}[y_j\mathrm{ln}a^L_j+(1-y_j)\mathrm{ln}(1-a^L_j))] 87 | $$ 88 | 89 | 90 | **那么我们应该在什么时候用交叉熵来替换二次代价函数?** 91 | 92 | 实际上,如果输出神经元是S型时,交叉熵函数一般都是更好的选择。为什么?考虑一下我们初始化网络的权重和偏置时,通常使用某种随机方法。可能会发生这样的情况,这些初始选择会对某些训练输入的误差相当明显,比如说,目标输出是1,而实际值是0,或者完全反过来。如果使用二次代价函数,那么就会导致学习速度下降。 93 | 94 | ### 改进交叉熵函数代码 95 | 96 | class QuadraticCost(object): 97 | 98 | @staticmethod 99 | def fn(a, y): 100 | """Return the cost associated with an output ``a`` and desired output 101 | ``y``. 102 | 103 | """ 104 | return 0.5*np.linalg.norm(a-y)**2 105 | 106 | @staticmethod 107 | def delta(z, a, y): 108 | """Return the error delta from the output layer.""" 109 | return (a-y) * sigmoid_prime(z) 110 | 111 | 112 | class CrossEntropyCost(object): 113 | 114 | @staticmethod 115 | def fn(a, y): 116 | """Return the cost associated with an output ``a`` and desired output 117 | ``y``. Note that np.nan_to_num is used to ensure numerical 118 | stability. In particular, if both ``a`` and ``y`` have a 1.0 119 | in the same slot, then the expression (1-y)*np.log(1-a) 120 | returns nan. The np.nan_to_num ensures that that is converted 121 | to the correct value (0.0). 122 | 123 | """ 124 | return np.sum(np.nan_to_num(-y*np.log(a)-(1-y)*np.log(1-a))) 125 | 126 | @staticmethod 127 | def delta(z, a, y): 128 | """Return the error delta from the output layer. Note that the 129 | parameter ``z`` is not used by the method. It is included in 130 | the method's parameters in order to make the interface 131 | consistent with the delta method for other cost classes. 132 | 133 | """ 134 | return (a-y) 135 | 136 | 其中 QuadraticCost 是二次代价函数,CrossEntropyCost 是交叉熵代价函数。 137 | 138 | -------------------------------------------------------------------------------- /shen-jing-wang-luo/gai-jin-shen-jing-wang-luo-de-xue-xi-fang-fa/quan-zhong-chu-shi-hua.md: -------------------------------------------------------------------------------- 1 | ### 权重初始化 2 | 3 | 创建了神经网络之后,我们需要进行权重和偏置的初始化,之前的方式是根据独立高斯随机变量来选择权重和偏置,其被归一化均值为$$0$$,标准差为$$1$$。 4 | 5 | 我们来看看这样的初始化的网络。假设我们有一个使用大量输入神经元的网络,比如1000个,假设我们已经使用归一化的高斯分布初始化了连接第一个隐藏层的权重。现在我们将注意力集中在这一层的连接权重上,忽略网络的其他部分。 6 | 7 | ![](/assets/nn-initial-weight.png) 8 | 9 | 为了简化,假设我们使用训练输入$$x$$,其中一半的输入神经元为$$1$$,另一半的神经元输入为$$0$$,让我们考察隐藏神经元的输入带权和: 10 | 11 | 12 | $$ 13 | z=\displaystyle\sum_{j} w_j x_j +b 14 | $$ 15 | 16 | 17 | 其中500个项消去了,所以$$z$$是遍历总共501个归一化的高斯随机变量和,其中包含500个权重项和额外的1个偏置项。因此$$z$$本身是一个均值为0,标准差为$$\sqrt{501} \approx 22.4$$的高斯分布。$$z$$其实是一个非常宽的高斯分布: 18 | 19 | ![](/assets/nn-initial-weight-z.png) 20 | 21 | 我们可以从图中看出$$|z|$$变得非常大,这样的话,隐藏神经元的输出$$\sigma(z)$$就会接近于$$1$$或$$0$$,也就表示我们的隐藏神经元会饱和。所以当出现这样的情况时,在权重中进行微小的调整仅仅会给隐藏神经元的激活值带来极其微弱的改变。而这种微弱的改变也会影响剩下的神经元,然后会带来相应的代价函数的改变。结果就是,这些权重在我们进行梯度下降算法时,学习的非常缓慢。 22 | 23 | 如何避免这种类型的饱和,最终避免学习速度的下降? 24 | 25 | 假设我们有$$n_{in}$$个输入权重的神经元,我们会使用均值为$$0$$,标准差为$$1/\sqrt{n_{in}}$$的高斯随机分布初始化这些**权重**。也就是说,我们会向下挤压高斯分布,让我们的神经元更不可能饱和。我们会继续使用均值为0,标准差为1的高斯分布来对**偏置**进行初始化。有了这些设定,带权和 26 | 27 | 28 | $$ 29 | z=\displaystyle\sum_{j} w_j x_j +b 30 | $$ 31 | 32 | 33 | 仍然是一个均值为0,不过有尖锐峰值的高斯分布。假设我们有500个值为0的输入和500个值为1的输入,那么可以证明$$z$$是服从均值为0,标准差为$$\sqrt{3/2} = 1.22...$$的高斯分布。($$ \sqrt{500 * (1/1000) + 1}$$) 34 | 35 | ![](/assets/nn-initial-weight-z2.png) 36 | 37 | 这样的一个神经元不可能饱和,因此也不太可能遇到学习速度下降的问题。 38 | 39 | 下面是两种方式的比较: 40 | 41 | ![](/assets/nn-initial-weight-compare.png) 42 | 43 | ### 44 | 45 | ### 改进后的权重初始化代码对比 46 | 47 | ``` 48 | def default_weight_initializer(self): 49 | """Initialize each weight using a Gaussian distribution with mean 0 50 | and standard deviation 1 over the square root of the number of 51 | weights connecting to the same neuron. Initialize the biases 52 | using a Gaussian distribution with mean 0 and standard 53 | deviation 1. 54 | 55 | Note that the first layer is assumed to be an input layer, and 56 | by convention we won't set any biases for those neurons, since 57 | biases are only ever used in computing the outputs from later 58 | layers. 59 | 60 | """ 61 | self.biases = [np.random.randn(y, 1) for y in self.sizes[1:]] 62 | self.weights = [np.random.randn(y, x)/np.sqrt(x) 63 | for x, y in zip(self.sizes[:-1], self.sizes[1:])] 64 | 65 | def large_weight_initializer(self): 66 | """Initialize the weights using a Gaussian distribution with mean 0 67 | and standard deviation 1. Initialize the biases using a 68 | Gaussian distribution with mean 0 and standard deviation 1. 69 | 70 | Note that the first layer is assumed to be an input layer, and 71 | by convention we won't set any biases for those neurons, since 72 | biases are only ever used in computing the outputs from later 73 | layers. 74 | 75 | This weight and bias initializer uses the same approach as in 76 | Chapter 1, and is included for purposes of comparison. It 77 | will usually be better to use the default weight initializer 78 | instead. 79 | 80 | """ 81 | self.biases = [np.random.randn(y, 1) for y in self.sizes[1:]] 82 | self.weights = [np.random.randn(y, x) 83 | for x, y in zip(self.sizes[:-1], self.sizes[1:])] 84 | ``` 85 | 86 | 其中 large\_weight\_initializer 是改进前,default\_weight\_initializer 是改进后,只是多了除以 np.sqrt\(x\) 87 | 88 | -------------------------------------------------------------------------------- /shen-jing-wang-luo/gai-jin-shen-jing-wang-luo-de-xue-xi-fang-fa/regularization.md: -------------------------------------------------------------------------------- 1 | ### Regularization 规范化,正则化 2 | 3 | #### L2 规范化 4 | 5 | regularization(规范化,正则化)有时候被称为权重衰减(weight decay) 6 | 7 | L2规范化的想法是增加一个额外的项到代价函数上,这个项叫做规范化项。 8 | 9 | 10 | $$ 11 | C= -\frac{1}{n}\displaystyle\sum_{x}\displaystyle\sum_{y}[y_j\mathrm{ln}a^L_j+(1-y_j)\mathrm{ln}(1-a^L_j))] + \frac{\lambda}{2n} \displaystyle\sum_{w} w^2 12 | $$ 13 | 14 | 15 | 其中第一项就是常规的交叉熵d额表达式,第二项是所有权重的平方和。然后用一个因子$$\frac{\lambda}{2n}$$进行量化调整,其中$$\lambda$$称为规范化参数,而$$n$$就是训练集合的大小。需要注意的是,规范化项里面不包含偏置。 16 | 17 | 也可以对其他代价函数进行规范化,比如二次代价函数 18 | 19 | 20 | $$ 21 | C= -\frac{1}{n}\displaystyle\sum_{x}||y-a^L||^2 + \frac{\lambda}{2n} \displaystyle\sum_{w} w^2 22 | $$ 23 | 24 | 25 | 两者都可以写成 26 | 27 | 28 | $$ 29 | C= C_0 + \frac{\lambda}{2n} \displaystyle\sum_{w} w^2 30 | $$ 31 | 32 | 33 | 其中$$C_0$$就是原始的代价函数。 34 | 35 | 计算对网络中所有权重和偏置的偏导数 36 | 37 | 38 | $$ 39 | \frac{\partial C}{\partial w }=\frac{\partial C_0}{\partial w}+\frac{\lambda}{n} w 40 | $$ 41 | 42 | 43 | 44 | $$ 45 | \frac{\partial C}{\partial b }=\frac{\partial C_0}{\partial b} 46 | $$ 47 | 48 | 49 | 在反向传播中,梯度下降的偏置学习规则不会发生变化,权重的学习规则发生了变化。 50 | 51 | 52 | $$ 53 | b \rightarrow b - \eta \frac{\partial C_0}{\partial b} 54 | $$ 55 | 56 | 57 | 58 | $$ 59 | w \rightarrow w - \eta \frac{\partial C_0}{\partial w} -\eta \frac{\lambda}{n} w 60 | $$ 61 | 62 | 63 | 64 | $$ 65 | = (1- \eta \frac{\lambda}{n} )w - \eta \frac{\partial C_0}{\partial w} 66 | $$ 67 | 68 | 69 | 这个和通常的梯度下降学习规则相同,除了通过一个因子$$ (1- \eta \frac{\lambda}{n} )$$重新调整了权重,这种调整有时候被称为权重衰减,因为它使权重变小。 70 | 71 | 如果使用平均$$m$$个训练样本的小批量的数据来估计权重,则为了随机梯度下降的规范化学习规则就变成了 72 | 73 | 74 | $$ 75 | w \rightarrow (1- \eta \frac{\lambda}{n} )w -\frac{ \eta}{m} \displaystyle\sum_{x} \frac{\partial C_x}{\partial w} 76 | $$ 77 | 78 | 79 | 80 | $$ 81 | b \rightarrow b - \frac{ \eta}{m} \displaystyle\sum_{x} \frac{\partial C_x}{\partial b} 82 | $$ 83 | 84 | 85 | 其中后一项是在训练样本的小批量数据上进行的。 86 | 87 | #### L1 规范化 88 | 89 | 这个方法是在非规范化的代价函数上加一个权重绝对值的和: 90 | 91 | 92 | $$ 93 | C= C_0 + \frac{\lambda}{n} \displaystyle\sum_{w} |w| 94 | $$ 95 | 96 | 97 | 凭直觉的看,这个和L2规范化相似,惩罚大的权重,倾向于让网络优先选择小的权重,当然,L1规范化和L2规范化并不相同,所以我们不应该期望从L1规范化得到完全相同的行为,让我们试着理解使用L1规范化训练的网络和L2规范化训练的网络所不同的行为。 98 | 99 | 求代价函数的偏导数,我们得到 100 | 101 | 102 | $$ 103 | \frac{\partial C}{\partial w }=\frac{\partial C_0}{\partial w}+\frac{\lambda}{n} \mathrm{sign}(w) 104 | $$ 105 | 106 | 107 | 其中$$\mathrm{sign}(w)$$就是$$w$$的正负号,即$$w$$为正时为$$+1$$,为负数时为$$-1$$,得到随机梯队下降的学习规则 108 | 109 | 110 | $$ 111 | w \rightarrow w - \eta \frac{\lambda}{n} \mathrm{sign}(w) -\frac{ \eta}{m} \displaystyle\sum_{x} \frac{\partial C_x}{\partial w} 112 | $$ 113 | 114 | 115 | 对比L2的更新规则可以发现,两者权重缩小的方式不同。在L1规范化中,权重通过一个常量向$$0$$进行缩小,在L2规范化中,权重通过一个和$$w$$成比例的量进行缩小。所以当一个特定的权重绝对值$$|w|$$很大时,L1规范化的权重缩小的要比L2规范化小的多。相反,当yi个特定的权重绝对值$$|w|$$很小时,L1规范化的权重缩小得要比L2规范化大得多。最终的结果是:L1规范化倾向于聚集网络的权重在相对少量的高重要度连接上,而其他权重就会被驱使向$$0$$接近。 116 | 117 | 在$$w=0$$时,偏导数$$\frac{\partial C}{\partial w }$$未定义,原因在于函数$$|w|$$在$$0$$时,是一个直角,我们约定这时$$\frac{\partial C}{\partial w }=0$$。 118 | 119 | #### 弃权(Dropout) 120 | 121 | 弃权(Dropout)是一种相当激进的技术,相比于L1,L2规范化不同,弃权技术并不依赖对代价函数的修改。而是在弃权中我们改变了网络的本身。使用弃权技术时,我们会从随机(临时)地删除网络中的一半神经元开始,同时让输入层和输出层的神经元保持不变。 122 | 123 | ![](/assets/nn-dropout.png) 124 | 125 | 我们前向传播输入$$x$$,通过修改后网络,然后反向传播,同样通过这个修改后的网络。在一个小批量数据上进行这个步骤后,我们有关的的权重和偏置进行更新。然后重复这个过程。首先恢复被弃权的神经元,然后选择一个新的随机的隐藏神经元的子集进行删除,计算对一个不同的小批量数据的梯度,然后更新权重和偏置。 126 | 127 | 通过不断地重复,我们的网络学习到一个权重和偏置的集合。当然这些权重和偏置也是在一半的隐藏神经元被弃权的情况下学习到的。当我们实际运行整个网络时,两倍的隐藏神经元被激活,为了补偿这个,我们将隐藏神经元的出去的权重进行减半处理。 128 | 129 | ### L2 改进前后代码对比: 130 | 131 | def update_mini_batch(self, mini_batch, eta, lmbda, n): 132 | """Update the network's weights and biases by applying gradient 133 | descent using backpropagation to a single mini batch. The 134 | ``mini_batch`` is a list of tuples ``(x, y)``, ``eta`` is the 135 | learning rate, ``lmbda`` is the regularization parameter, and 136 | ``n`` is the total size of the training data set. 137 | 138 | """ 139 | nabla_b = [np.zeros(b.shape) for b in self.biases] 140 | nabla_w = [np.zeros(w.shape) for w in self.weights] 141 | for x, y in mini_batch: 142 | delta_nabla_b, delta_nabla_w = self.backprop(x, y) 143 | nabla_b = [nb+dnb for nb, dnb in zip(nabla_b, delta_nabla_b)] 144 | nabla_w = [nw+dnw for nw, dnw in zip(nabla_w, delta_nabla_w)] 145 | self.weights = [(1-eta*(lmbda/n))*w-(eta/len(mini_batch))*nw 146 | for w, nw in zip(self.weights, nabla_w)] 147 | self.biases = [b-(eta/len(mini_batch))*nb 148 | for b, nb in zip(self.biases, nabla_b)] 149 | 150 | 改进后的代码只是在梯度下降更新权重的时候多加了' \(1-eta\*\(lmbda/n\)\)\*w' 151 | 152 | -------------------------------------------------------------------------------- /shen-jing-wang-luo/gai-jin-shen-jing-wang-luo-de-xue-xi-fang-fa/softmax.md: -------------------------------------------------------------------------------- 1 | ### Softmax 2 | 3 | 除了使用交叉熵来解决学习缓慢的问题外,还可以使用基于柔性最大值(softmax)神经元层。 4 | 5 | 柔性最大值的想法其实就是为神经网络定义一种新式的输出层。开始时和和S型层一样,首先计算带权输入 6 | 7 | 8 | $$ 9 | z^L_j=\displaystyle\sum_{k}(w_{jk}^L a_k^{L-1}) + b_j^L 10 | $$ 11 | 12 | 13 | 然后应用 softmax 函数在$$z^L_j$$上,根据这个函数,第$$j$$个神经元的激活值就是 14 | 15 | 16 | $$ 17 | a^L_j = \frac{e^{z^L_j}}{\displaystyle\sum_{k}e^{z^L_k}} 18 | $$ 19 | 20 | 21 | 其中分母的求和是在所有的输出神经元上进行的。而且所有输出的激活值加起来正好为1,同样保证输出激活值都是正数。而且柔性最大值层的输出可以被看做是一个概率分布。 22 | 23 | 下面计算$$a^L_j$$对$$z_i^L$$的导数 24 | 25 | 如果$$j=i$$: 26 | 27 | 28 | $$ 29 | \frac{\partial a_j^L}{\partial z_i^L} = \frac{\partial }{\partial z_i^L}(\frac{e^{z^L_j}}{\displaystyle\sum_{k}e^{z^L_k}}) 30 | $$ 31 | 32 | 33 | 34 | $$ 35 | =\frac{(e^{z^L_j})'\cdot\displaystyle\sum_{k}e^{z^L_k} - e^{z^L_j}\cdot e^{z^L_j} }{(\displaystyle\sum_{k}e^{z^L_k})^2} 36 | $$ 37 | 38 | 39 | 40 | $$ 41 | =\frac{e^{z^L_j}}{\displaystyle\sum_{k}e^{z^L_k}}-\frac{e^{z^L_j}}{\displaystyle\sum_{k}e^{z^L_k}} \cdot \frac{e^{z^L_j}}{\displaystyle\sum_{k}e^{z^L_k}} 42 | $$ 43 | 44 | 45 | 46 | $$ 47 | =a_j (1-a_j) 48 | $$ 49 | 50 | 51 | 如果$$j \neq i$$: 52 | 53 | 54 | $$ 55 | \frac{\partial a_j^L}{\partial z_i^L}=\frac{\partial }{\partial z_i^L}(\frac{e^{z^L_j}}{\displaystyle\sum_{k}e^{z^L_k}}) 56 | $$ 57 | 58 | 59 | 60 | $$ 61 | =\frac{0\cdot\displaystyle\sum_{k}e^{z^L_k} - e^{z^L_j}\cdot e^{z^L_i} }{(\displaystyle\sum_{k}e^{z^L_k})^2} 62 | $$ 63 | 64 | 65 | 66 | $$ 67 | =-\frac{e^{z^L_j}}{\displaystyle\sum_{k}e^{z^L_k}} \cdot \frac{e^{z^L_i}}{\displaystyle\sum_{k}e^{z^L_k}} 68 | $$ 69 | 70 | 71 | 72 | $$ 73 | = - a_j a_i 74 | $$ 75 | 76 | 77 | ### 对数似然损失函数 78 | 79 | 其对数似然损失函数为: 80 | 81 | 82 | $$ 83 | C=-\displaystyle\sum_{k}y_k \mathrm{log}a_k 84 | $$ 85 | 86 | 87 | 其中$$a_k$$为第$$k$$个神经元的输出值,$$y_k$$表示第$$k$$个神经元的真实值,取值为$$0$$或$$1$$。 88 | 89 | 这个代价的简单含义是:只有一个神经元对应了该样本的正确分类,若这个神经元的输出概率越高,则其产出的代价越小,反之则代价越高。 90 | 91 | 则计算损失函数对权重和偏置的偏导数: 92 | 93 | 94 | $$ 95 | \frac{\partial C}{\partial b_j^L} = \frac{\partial C }{\partial z_j^L}\cdot \frac{\partial z_j^L }{\partial b_j^L} 96 | $$ 97 | 98 | 99 | 100 | $$ 101 | = \frac{\partial C }{\partial z_j^L}\cdot \frac{\partial \displaystyle\sum_{k}(w_{jk}^L a_k^{L-1}) + b_j^L }{\partial b_j^L} = \frac{\partial C }{\partial z_j^L} 102 | $$ 103 | 104 | 105 | 106 | $$ 107 | = \frac{\partial}{\partial z_j^L}( -\displaystyle\sum_{k}y_k \mathrm{log}a_k^L ) 108 | $$ 109 | 110 | 111 | 112 | $$ 113 | =-\displaystyle\sum_{k}y_k \cdot \frac{1 }{a_k^L} \cdot \frac{\partial a_k^L}{\partial z_j^L} 114 | $$ 115 | 116 | 117 | 118 | $$ 119 | =-y_j \cdot \frac{1 }{a_j^L} \cdot \frac{\partial a_j^L}{\partial z_j^L}-\displaystyle\sum_{k \neq j}y_k \cdot \frac{1 }{a_k^L} \cdot \frac{\partial a_k^L}{\partial z_j^L} 120 | $$ 121 | 122 | 123 | 124 | $$ 125 | =-y_j \cdot \frac{1 }{a_j^L} \cdot a_j^L (1-a_j^L)-\displaystyle\sum_{k \neq j}y_k \cdot \frac{1 }{a_k^L} \cdot -a_j^L a_k^L 126 | $$ 127 | 128 | 129 | 130 | $$ 131 | =-y_j + y_j a_j^L +\displaystyle\sum_{k \neq j}y_k \cdot a_j^L 132 | $$ 133 | 134 | 135 | 136 | $$ 137 | =a_j^L-y_j 138 | $$ 139 | 140 | 141 | 同样可得: 142 | 143 | 144 | $$ 145 | \frac{\partial C}{\partial w_{jk}}=a^{L-1}(a_j^L-y_j) 146 | $$ 147 | 148 | 149 | 因此可以确保不会遇到学习缓慢的问题。事实上把一个具有对数似然代价的柔性最大值输出层,看作与一个具有交叉熵代价函数的S型输出层非常相似。在很多应用场景中,这两种方式的效果都不错。 150 | 151 | 参考:[https://blog.csdn.net/niuniuyuh/article/details/61926561](https://blog.csdn.net/niuniuyuh/article/details/61926561) 152 | 153 | -------------------------------------------------------------------------------- /shen-jing-wang-luo/juan-ji-shen-jing-wang-luo.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/shen-jing-wang-luo/juan-ji-shen-jing-wang-luo.md -------------------------------------------------------------------------------- /shen-jing-wang-luo/juan-ji-shen-jing-wang-luo/ji-ben-jie-shao.md: -------------------------------------------------------------------------------- 1 | ### 卷积神经网络的介绍 2 | 3 | 卷积 (convolutional)神经网络采用了三个基本概念:局部感受野(local receptive fields),共享权重(shared weights),和混合(pooling)。让我们逐个看一下: 4 | 5 | #### 局部感受野 6 | 7 | 第一个隐藏层的每个神经元会连接到一个输入神经元的一个小区域,例如一个 5x5 的区域,对应于25个输入像素。 8 | 9 | ![](/assets/cnn-1.png) 10 | 11 | 这个输入图像的区域被称为隐藏神经元的**局部感受野**。它是输入像素上的一个小窗口,每个连接学习一个权重。而隐藏神经元同时也学习一个总的偏置。可以把这个特定的隐藏神经元看作是在学习分析它的局部感受野。 12 | 13 | 然后在整个输入图像上交叉移动局部感受野。对于每一个局部感受野,在第一个隐藏层中有一个不同的隐藏神经元。如果有一个28x28的输入图像,5x5的局部感受野,那么隐藏层中就会有24x24个神经元。这个是因为我们只能把局部感受野横向移动23个神经元。 14 | 15 | 局部感受野有时候会用不同的跨距。 16 | 17 | #### 共享权重和偏置 18 | 19 | 上面每个隐藏神经元都使用同一个权重和偏置。换句话说,对于第$$j, k$$个隐藏神经元,输出为: 20 | 21 | 22 | $$ 23 | \sigma(b+\displaystyle\sum_{l=0}^4\displaystyle\sum_{m=0}^4 w_{l,m} a_{j+l,k+m}) 24 | $$ 25 | 这里$$\sigma$$是神经元的激活函数,$$b$$是偏置的共享值。$$w_{l,m}$$是一个共享权重的5x5数组,我们使用$$a_{x,y}$$表示位置为$$x ,y$$的输入激活值。这意味着第一个隐藏层的所有神经元检测完全相同的特征,只是在输入图像的不同位置。 26 | 27 | 我们有时候把从输入层到隐藏层的映射称为一个**特征映射**。定义特征映射的权重称为共享权重,偏置称为共享偏置。共享权重和偏置经常被称为一个**卷积核**或者**滤波器**。 28 | 29 | 为了完成图像识别,我们需要超过一个特征映射。所以一个完整的卷积层由几个不同的特征映射组成。 30 | 31 | ![](/assets/cnn-2.png) 32 | 33 | 上面的例子中有3个特征映射。在实践中卷积网络可能使用很多的特征映射。 34 | 35 | #### 混合层 36 | 37 | 混合层通常紧接在卷积层之后,它做的是简化从卷积层输出的信息。详细的说,一个混合层取得从卷积层输出的每一个特征映射并从它们准备一个凝缩的特征映射。 38 | 39 | 例如:混合层的每个单元可能概括了前一层的比如2x2的区域。一个常见的混合的程序称为**最大值混合**(max pooling),在最大值混合中,一个混合单元简单地输出其2x2输入区域d额最大激活值。 40 | 41 | ![](/assets/cnn-3.png) 42 | 43 | 卷积层有24x24个神经元输出,混合后我们得到12x12个神经元。 44 | 45 | 卷积层通常包含超过一个特征映射,我们将最大值混合分别应用于每个特征映射,所以如果有三个特征映射,组合在一起的卷积层和最大混合层看起来像这样: 46 | 47 | ![](/assets/cnn-4.png) 48 | 49 | **最后综合在一起:**我们现在可以把这些思想都放在以一起构建一个完整的卷积神经网络,它包含一个额外的一层10个输出神经元,对应于10个可能的数字。网络最后连接的层是一个全连接层。 50 | 51 | ![](/assets/cnn-5.png) 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /shen-jing-wang-luo/shen-jing-wang-luo-de-ju-zhen-biao-da.md: -------------------------------------------------------------------------------- 1 | ### 神经网络中符号的定义 2 | 3 | 我们首先给出网络中权重、偏置和激活值的符号定义。 4 | 5 | 我们用 $$l$$ 来表示神经网络的层数,第一次层是输入的值,最后一层是输出的值。 6 | 7 | **权重**:$$w_{jk}^l$$表示的是从$$(l-1)^{th}$$层的第$$k^{th}$$个神经元到$$l^{th}$$层的第$$j^{th}$$个神经元的链接上的权重。 8 | 9 | **偏置**:$$b_j^l$$表示在$$l^{th}$$层的第$$j^{th}$$个神经元的偏置。 10 | 11 | **激活值的输入**:$$z^l_j$$表示在第$$l^{th}$$的第$$j^{th}$$神经元激活值的输入。也就是 12 | 13 | 14 | $$ 15 | z^l_j=\displaystyle\sum_{k}w^l_{jk} a^{l-1}_k + b^l_j 16 | $$ 17 | 18 | 19 | **激活值**:$$a_j^l$$表示在$$l^{th}$$层的第$$j^{th}$$个神经元的激活值。也就是 20 | 21 | 22 | $$ 23 | a^l_j=\sigma(z^l_j)=\sigma(\displaystyle\sum_{k}w^l_{jk} a^{l-1}_k + b^l_j) 24 | $$ 25 | 26 | 27 | ![](/assets/network-definition.png) 28 | 29 | 上面的图中 $$a_3^2 = \sigma(w_{31}^2 \cdot x_1 + w_{32}^2 \cdot x_2 + w_{33}^2 \cdot x_3 + b_3^2)$$。 也就是 30 | 31 | 32 | $$ 33 | a_j^l = \sigma(\displaystyle\sum_{k} w_{jk}^l \cdot a_k^{l-1}+ b_j^l)=\sigma(w_{j}^l \cdot a^{l-1} + b_j^l) 34 | $$ 35 | 36 | 37 | 其求和是在第$$(l-1)^{th}$$上的所有$$k$$个神经元上进行,其中$$w_{j}^l$$表示的是第$$(l-1)^{th}$$层到第$$l^{th}$$层的第$$j$$个神经元的权重向量。 38 | 39 | 我们先将每一层用矩阵表达,假定第$$(l-1)^{th}$$有$$m$$个神经元,第$$l^{th}$$层有$$n$$个神经元,那么从第$$(l-1)^{th}$$到第$$l^{th}$$层的权重个数有$$m \times n$$个,偏置个数有$$n$$个。则: 40 | 41 | 第$$(l-1)^{th}$$的神经元向量为$$a^{l-1}= \begin{bmatrix} 42 | a_1^{l-1} \\ 43 | a_2^{l-1} \\ 44 | a_3^{l-1} \\ 45 | ... \\ 46 | a_m^{l-1} 47 | \end{bmatrix}$$,第$$l^{th}$$层的神经元向量为$$a^{l}= \begin{bmatrix} 48 | a_1^{l} \\ 49 | a_2^{l} \\ 50 | a_3^{l} \\ 51 | ... \\ 52 | a_n^{l} 53 | \end{bmatrix}$$, 54 | 55 | 偏置向量为$$b^{l}= \begin{bmatrix} 56 | b_1^{l} \\ 57 | b_2^{l} \\ 58 | b_3^{l} \\ 59 | ... \\ 60 | b_n^{l} 61 | \end{bmatrix}$$,权重矩阵为:$$W^l= \begin{bmatrix} 62 | w_{11} & w_{12} & w_{13} & ... & w_{1m} \\ 63 | w_{21} & w_{22} & w_{23} & ... & w_{1m} \\ 64 | w_{31} & w_{12} & w_{13} & ... & w_{1m} \\ 65 | ... \\ 66 | w_{n1} & w_{n2} & w_{n3} & ... & w_{nm} 67 | \end{bmatrix} = \begin{bmatrix} 68 | w_1^{l} \\ 69 | w_2^{l} \\ 70 | w_3^{l} \\ 71 | ... \\ 72 | w_n^{l} 73 | \end{bmatrix}$$ 74 | 75 | 也就是: 76 | 77 | 78 | $$ 79 | a^{l}= \begin{bmatrix} 80 | a_1^{l} \\ 81 | a_2^{l} \\ 82 | a_3^{l} \\ 83 | ... \\ 84 | a_n^{l} 85 | \end{bmatrix}= \begin{bmatrix} 86 | \sigma(w_1^l \cdot a^{l-1} + b_1^l) \\ 87 | \sigma(w_2^l \cdot a^{l-1} + b_2^l) \\ 88 | \sigma(w_3^l \cdot a^{l-1} + b_3^l) \\ 89 | ... \\ 90 | \sigma(w_n^l \cdot a^{l-1} + b_n^l) 91 | \end{bmatrix} 92 | $$ 93 | 94 | 95 | 最后可以得到: 96 | 97 | 98 | $$ 99 | a^l = \sigma(W^l \cdot a^{l-1} + b^l ) 100 | $$ 101 | 102 | 103 | 这个表达式给出了一个更加全局的思考每层的激活值和前一层激活值的关联方式,我们仅仅用权重矩阵作用在激活值上,然后加上一个偏置向量,最后作用$$\sigma$$函数。 104 | 105 | -------------------------------------------------------------------------------- /shen-jing-wang-luo/shen-jing-wang-luo.md: -------------------------------------------------------------------------------- 1 | ### 神经网络的架构 2 | 3 | 假设我们有这样的网络,这个网络最左边的成为**输入层**,其中的神经元称为**输入神经元**。最右边的,即**输出层**包含**输出神经元**。**中间层**,这些层中的神经元既不是输入也不是输出,被称为**隐藏层**。“隐藏”这个术语实际上仅仅意味着“既非输入也非输出”的含义。比如下面的4层网络有两个隐藏层。 4 | 5 | ![](/assets/network-architecture.PNG) 6 | 7 | 设计网络的输入输出层通常是比较直接的。例如,假设我们尝试确定一张手写数字的图像上是否写着“9”。很自然地,我们可以将图片的像素的强度进行编码作为输入神经元来设计网络。如果图像是一个64 x 64的灰度图像,那么我们需要4096=64 x 64 个输入神经元,每个强度取0和1之间合适的值。输出层只需要包含一个神经元,当输出值小于 0.5 时表示“输入的图像不是一个9”,大于0.5时表示“输入的图像是一个9”。 8 | 9 | 相比较于神经网络中输入输出层的直观设计,隐藏层的设计堪称一门艺术。特别是,通过一些简单的经验法则来总结隐藏层的设计流程是不可行的。相反,神经网络的研究人员已经为隐藏层开发了许多优秀的最优法则,这有助于网络的行为能符合人们期望的那样。 10 | 11 | 目前为止,我们讨论的神经网络,都是以上一层的输出作为下一层的输入。这种网络被称为**前馈神经网络**。这意味着网络中是没有回路的,信息总是向前传播,从不反向反馈。 12 | 13 | 然而也有一些神经网络的模型,其中反馈环路是可行的,这些模型被称为**递归神经网络**。 14 | 15 | #### 神经网络的一般含义 16 | 17 | 神经网络的权重和偏置是被自动学习到的,这样神经网络对我们来说不透明,人们希望在构建人工智能的过程中,也同时能帮助我们理解智能背后的机制。 18 | 19 | 假设我们要确定一张图是否显示人脸,假定我们要设计一个网络,并为它选择合适的权重和偏置,我们要怎么样做呢?暂时先忘掉神经网络,我们受到启发的一个想法是将这个问题分解成子问题:图像的左上角有一个眼睛吗?右上角有一个眼睛吗?下面中央有一个嘴吗?上面有头发吗?诸如此类。 20 | 21 | 如果一些问题的回答是“是”,或者仅仅是“可能是”,那么我们可以做出结论这个图像可能是一张脸。相反,如果大多数问题的回答是“不是”,那么这张图可能不是一张脸。 22 | 23 | 这个想法表明了如果我们能用神经网络来解决这些子问题,那么我们或许可以通过将这些解决子问题的网络结合起来,构成一个人脸检测的神经网络。下面是一个可能的结构。 24 | 25 | ![](/assets/network-face-subquestions.PNG) 26 | 27 | 子网络也可以被继续分解。 28 | 29 | ![](/assets/network-eye-subquestions.PNG) 30 | 31 | 这些子问题也同样可以继续被分解,并通过多个网络层传递得越来越远。最终我们的子网络可以回答那些只包含若干个像素点的简单问题。 32 | 33 | 最终我们设计出一个网络,它将一个复杂问题,分解成单像素层面上就可以回答的简单问题。它通过一系列多层结结构来完成,在前面的网络层,它回答关于输入图像非常简单的问题,在后面的网络层,它建立了一个更加复杂和抽象的层级结构,包含这种多层结构——两层或更多隐藏层——的网络被称为**深度神经网络**。 34 | 35 | -------------------------------------------------------------------------------- /shen-jing-wang-luo/shen-jing-yuan-mo-xing.md: -------------------------------------------------------------------------------- 1 | ### 神经元模型 2 | 3 | 神经网络是由具有适应性的简单单元组成的广泛并行互连的网络,它的组织能够模拟生物神经系统对真实世界物体所作出的交互反应。 4 | 5 | 神经网络中最基本的成分是神经元(neuron)模型,即上述定义中的“简单单元”。在生物神经网络中,每个神经元与其他神经元相连,当它“兴奋”时,就会向相连的神经元发送化学物质,从而改变这些神经元内的电位;如果某神经元的电位超过一个“阈值”(threshold),那么它就会被激活,即“兴奋”起来,向其他神经元发送化学物质。 6 | 7 | 1943年,McMulloch 和 Pitts 将上述情形抽象为下图所示的简单模型,这就是一直沿用至今的“M-P神经元模型”。 8 | 9 | ![](/assets/mp-neuron.png) 10 | 11 | > pic source:[https://www.jianshu.com/p/c46b6d890790](https://www.jianshu.com/p/c46b6d890790) 12 | 13 | 在这个模型中,神经元接收到来自$$n$$个其他神经元传递过来的输入信号,这些输入信号通过带权重的连接(connection)进行传递,神经元接收到总输入将与神经元的阈值进行比较,然后通过“激活函数”(activation function)处理以产生神经元的输出。 14 | 15 | 理想中的激活函数是如图a的阶跃函数,它将输入值映射为输出值为“0”或“1”,“1”对应于神经元兴奋,“0”对应于神经元抑制。但是阶跃函数具有不连续、不光滑等不太好的性质,因此实际常用$$Sigmoid$$函数作为激活函数。 16 | 17 | ![](/assets/activation-function.png) 18 | 19 | > pic source:[https://www.jianshu.com/p/c46b6d890790](https://www.jianshu.com/p/c46b6d890790) 20 | 21 | ### 感知机 22 | 23 | 感知机(Perceptron)由两层神经元组成,输入层接收外界输入的信号后传递给输出层,输出层是M-P神经元,也称为“阈值逻辑单元”(threshold logic unit)。 24 | 25 | ![](/assets/perceptron.png) 26 | 27 | 感知机能容易地实现逻辑与、或、非运算。$$y=f(\displaystyle\sum_{i=1}^nw_ix_i-\theta)$$,假如$$f$$是上面的阶跃函数,则 28 | 29 | * 与运算 30 | 31 | 令$$w_1=w_2=1$$,$$\theta = 2$$,则$$y=f(1 \cdot x_1 + 1\cdot x_2 -2)$$,仅在$$x_1=x_2=1$$时,$$y=1$$,其他时候$$y=0$$。 32 | 33 | * 或运算 34 | 35 | 令$$w_1=w_2=1$$,$$\theta = 0.5$$,则 $$y=f(1 \cdot x_1 + 1 \cdot x_2 -0.5)$$,当$$x_1 =1 $$或$$x_2=1$$的时候$$y=1$$。 36 | 37 | * 非运算 38 | 39 | 令$$w_1 = -0.6$$,$$w_2 = 0$$,$$\theta = -0.5$$,则$$y=f(-0.6 \cdot x_1 + 0 \cdot x_2 +0.5)$$,当$$x_1=1$$时$$y=0$$;当$$x_2=0$$时,$$y=1$$。 40 | 41 | 实际上,我们能用感知机网络来计算任何逻辑功能,原因是上面的与或非是通用运算,那样我们可以在多个通用的运算上构建出任何运算。下面是构建一个异或运算。 42 | 43 | | A | B | Y1=NOT And\(A,B\) | Y2=OR\(A,B\) | Y=XOR\(A,B\)=AND\(Y1,Y2\) | 44 | | :--- | :--- | :--- | :--- | :--- | 45 | | 0 | 0 | 1 | 0 | 0 | 46 | | 0 | 1 | 1 | 1 | 1 | 47 | | 1 | 0 | 1 | 1 | 1 | 48 | | 1 | 1 | 0 | 1 | 0 | 49 | 50 | ![](/assets/peception-xor.PNG) 51 | 52 | 多层网络可以完成对更复杂函数的模拟。 53 | 54 | ![](/assets/peception-xo2r.PNG) 55 | 56 | ### S 型神经元 57 | 58 | 上面的感知机中一个权重或偏置的微小改动有时候会引起那个感知机的输出完全翻转,比如0变到1,那样的翻转可能接下来引起其余网络的行为以极其复杂的方式改变。因此在调整网络的参数的时候,有些输出被正确分类,其他的行为很可能以一些很难控制的方式被完全改变。 59 | 60 | 我们引入一种称之为S型神经元来克服这个问题。 S型神经元和感知机类似,但是被修改的权重和偏置只会引起输出的微小变化,这对让神经元网络学习起来很关键。 61 | 62 | 正如一个感知机,S型神经元有多个输入,$$x_1,x_2,...x_n$$。对每个输入有权重,$$w_1,w_2,...,w_n$$和一个总的偏置$$b$$。但是它的输出不是0或1,它现在是$$\sigma( w \cdot x +b)$$,这里$$\sigma$$被称之为S型函数。定义为: 63 | 64 | 65 | $$ 66 | \sigma(z) = \frac{1}{1+e^{-z}} 67 | $$ 68 | 69 | 70 | 也就是: 71 | 72 | 73 | $$ 74 | \sigma(z) = \frac{1}{1+\mathrm{exp}(-\displaystyle\sum_{i=1}^nw_ix_i-b)} 75 | $$ 76 | 77 | 78 | $$\sigma$$的平滑特性意味着权重和偏置的微小变化,即$$\Delta w_i$$和$$\Delta b$$,会从神经元产生一个微小的输出变化$$\Delta \mathrm{output}$$,实际上,微积分告诉我们输出变化可以很好的近似表示为(一阶泰勒展开): 79 | 80 | 81 | $$ 82 | \Delta \mathrm{output} \approx \displaystyle\sum_{i=1}\frac{\partial \mathrm{output}}{\partial w_i}\Delta w_i + \frac{\partial \mathrm{output}}{\partial b}\Delta b 83 | $$ 84 | 85 | 86 | 上面的式子表明,$$\Delta \mathrm{output}$$是一个反映权重和偏置变化($$\Delta w_i$$和$$\Delta b$$)的线性函数,这一线性使得选择权重和偏置的微小变化来达到输出的微小变化变得很容易。 87 | 88 | -------------------------------------------------------------------------------- /shu-xue-ji-chu.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/shu-xue-ji-chu.md -------------------------------------------------------------------------------- /shu-xue-ji-chu/gai-lv-tong-ji.md: -------------------------------------------------------------------------------- 1 | 期望 2 | 3 | 方差 4 | 5 | 标准差 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /shu-xue-ji-chu/gai-lv-tong-ji/tong-ji-liang.md: -------------------------------------------------------------------------------- 1 | ### 期望: 2 | 3 | **1. 定义:** 4 | 5 | 设**离散型随机变量**$$X$$的分布律为:$$P\{X=x_i\}=p_k, k=1,2,...$$,若级数$$\displaystyle\sum_{k=1}^{\infty} x_k p_k$$绝对收敛,则称该级数的和为随机变量$$X$$的**数学期望(**mean**)**,记为$$E(X)$$。即 6 | 7 | 8 | $$ 9 | E(X)=\displaystyle\sum_{k=1}^{\infty} x_k p_k 10 | $$ 11 | 12 | 13 | 设**连续型随机变量**$$X$$的概率密度为$$f(x)$$,若积分$$\textstyle{\Large\int}_{-\infty}^{\infty}xf(x)dx$$绝对收敛,则称该积分的值为随机变量$$X$$的**数学期望**,记为$$E(x)$$,即 14 | 15 | 16 | $$ 17 | E(x)=\textstyle{\Large\int}_{-\infty}^{\infty}xf(x)dx 18 | $$ 19 | 20 | 21 | 数学期望简称为**期望**,又称为**均值。** 22 | 23 | 数学期望$$E(x)$$完全由随机变量$$X$$的概率密度所确定,若$$X$$服从某一分布,也称$$E(X)$$是这一分布的数学期望。 24 | 25 | **2. 期望的性质** 26 | 27 | * 设$$C$$是常数,则有$$E(C)=C$$ 28 | * 设$$X$$是一个随机变量,$$C$$是常数,则有$$E(CX)=CE(X)$$ 29 | * 设$$X$$,$$Y$$是两个随机变量,则有$$E(X+Y)=E(x)+E(Y)$$ 30 | * 设$$X$$,$$Y$$是**相互独立**的随机变量,则有$$E(XY)=E(X)E(Y)$$ 31 | 32 | ### 方差 33 | 34 | **1. 定义** 35 | 36 | 设$$X$$是一个随机变量,若$$E\{[X-E(X)]^2\}$$存在,则称其为$$X$$的**方差(**variance**)**记为$$D(X)$$或$$Var(X)$$,即: 37 | 38 | 39 | $$ 40 | D(X)=Var(X)=E\{[X-E(X)]^2\} 41 | $$ 42 | 43 | 44 | 在应用上还引入量$$\sqrt{D(X)}$$,记为$$\sigma(X)$$,称为**标准差**或**均方差**。 45 | 46 | 随机变量$$X$$的方差表达了$$X$$的取值与其数学期望的偏离程度,若$$D(X)$$较小意味着$$X$$的取值比较集中在$$E(X)$$附近;反之若$$D(X)$$较大则意味着$$X$$的取值比较分散。因此$$D(X)$$是刻画$$X$$取值分散度的一个量,它是衡量$$X$$取值分散程度的一个尺度。 47 | 48 | 对于离散型随机变量, 49 | 50 | 51 | $$ 52 | D(X)=\displaystyle\sum_{k=1}^{\infty}[x_k-E(X)]^2 p_k 53 | $$ 54 | 55 | 56 | 其中$$P\{X=x_i\}=p_k, k=1,2,...$$是$$X$$的分布律 57 | 58 | 对于连续型的随机变量, 59 | 60 | 61 | $$ 62 | D(X)=\textstyle{\Large\int}_{-\infty}^{\infty}[x-E(X)]^2f(x)dx 63 | $$ 64 | 65 | 66 | 其中$$f(x)$$是$$X$$的概率密度。 67 | 68 | 随机变量$$X$$的方差也可以按照下列公式计算: 69 | 70 | 71 | $$ 72 | D(X)=E(X^2)-[E(X)]^2 73 | $$ 74 | 75 | 76 | **2. 方差的性质** 77 | 78 | * 设$$C$$是常量,则$$D(C)=0$$ 79 | * 设$$X$$是随机变量,$$C$$是常数,则$$D(CX)=C^2D(X)$$,$$D(X+C)=D(X)$$ 80 | * 设$$X$$,$$Y$$是随机变量,则有 81 | 82 | 83 | $$ 84 | D(X+Y)=D(X)+D(Y)+2E\{[X-E(X)][Y-E(Y)]\} 85 | $$ 86 | 87 | 88 | 特别地,如果$$X$$,$$Y$$相互独立,则有 89 | 90 | 91 | $$ 92 | D(X+Y)=D(X)+D(Y) 93 | $$ 94 | 95 | 96 | ### 协方差 97 | 98 | **1. 定义** 99 | 100 | 量$$E\{[X-E(X)][Y-E(Y)]$$称为随机变量$$X$$和$$Y$$的**协方差(**Covariance**)**。记为$$Cov(X,Y)$$,即 101 | 102 | 103 | $$ 104 | Cov(X,Y)=E\{[X-E(X)][Y-E(Y)] 105 | $$ 106 | 107 | 108 | 而 109 | 110 | 111 | $$ 112 | \rho_{XY}=\dfrac{Cov(X,Y)}{\sqrt{D(X)}\sqrt{D(Y)}} 113 | $$ 114 | 115 | 116 | 称为随机变量$$X$$与$$Y$$的**相关系数**。 117 | 118 | 由定义可知:$$Cov(X,Y)=Cov(Y,X)$$,$$Cov(X,X)=D(X)$$ 119 | 120 | 方差也可以表达成 121 | 122 | 123 | $$ 124 | D(X+Y)=D(X)+D(Y)+2Cov(X,Y) 125 | $$ 126 | 127 | 128 | **2. 协方差的性质** 129 | 130 | * $$Cov(aX,bY)=abCov(X,Y)$$,$$a,b$$是常数 131 | * $$Cov(X_1+X_2,Y)=Cov(X_1,Y)+Cov(X_2,Y)$$ 132 | 133 | **3. 相关系数的性质** 134 | 135 | * $$|\rho_{XY}|\leqslant 1$$ 136 | * $$|\rho_{XY}|= 1$$的充要条件是存在常数$$a,b$$使得$$P\{Y=a+bX\}=1$$,即当$$|\rho_{XY}|= 1$$时,$$X$$,$$Y$$之间以概率1存在着**线性关系**。 137 | * $$|\rho_{XY}|=0$$时,称$$X$$和$$Y$$**不线性相关。** 138 | 139 | $$\rho_{XY}$$是一个可以用来表征$$X$$,$$Y$$之间**线性关系**紧密程度的量,当$$|\rho_{XY}|$$较大时,二者的线性相关程度较好,当$$|\rho_{XY}|$$较小时,二者的线性相关程度较差。 140 | 141 | **4. “不相关”和“相互独立”** 142 | 143 | $$X$$和$$Y$$**不线性相关**,并不表示$$X$$和$$Y$$**相互独立**,二者直接可能存在**非线性关系**,比如平方的关系。相关是就线性关系来说的。 144 | 145 | 特殊地,对于服从**正态分布**的随机变量,$$X$$和$$Y$$不相关和相互独立是等价的。 146 | 147 | ### 协方差矩阵 148 | 149 | **定义** 150 | 151 | $$n$$维随机变量$$(X_1,X_2,...,X_n)$$,任意二维随机变量的协方差 152 | 153 | 154 | $$ 155 | c_{ij}=Cov(X_i,X_j)=E\{[X_i-E(X_i)][X_j-E(X_j)] 156 | $$ 157 | 158 | 159 | 其中$$i,j=1,2,...,n$$,都存在,则称矩阵: 160 | 161 | 162 | $$ 163 | C=\begin{bmatrix} 164 | c_{11} & c_{12} & ... & c_{1n} \\ 165 | c_{21} & c_{22} & ... & c_{2n} \\ 166 | \vdots & \vdots & & \vdots \\ 167 | c_{n1} & c_{n2} & ... & c_{nn} 168 | \end{bmatrix} 169 | $$ 170 | 171 | 172 | 为$$n$$维随机变量的**协方差矩阵**。由于$$c_{ij}=c_{ji}$$,因此协方差矩阵是一个**对称矩阵**。 173 | 174 | 175 | 176 | -------------------------------------------------------------------------------- /shu-xue-ji-chu/gai-lv-tong-ji/xian-yan-hou-yan-gai-lv.md: -------------------------------------------------------------------------------- 1 | ### 先验概率、后验概率、似然函数 2 | 3 | > 参考: 4 | > 5 | > [https://zh.wikipedia.org/wiki/先验概率](https://zh.wikipedia.org/wiki/先验概率) 6 | > 7 | > [https://zh.wikipedia.org/wiki/后验概率](https://zh.wikipedia.org/wiki/后验概率) 8 | > 9 | > [https://zh.wikipedia.org/wiki/似然函数](https://zh.wikipedia.org/wiki/似然函数) 10 | > 11 | > [https://www.zhihu.com/question/24261751](#) 12 | 13 | #### 先验概率: 14 | 15 | 在贝叶斯统计中,某一不确定量p的先验概率分布是在考虑"观测数据"前,能表达p不确定性的概率分布。它旨在描述这个不确定量的不确定程度,而不是这个不确定量的随机性。这个不确定量可以是一个参数,或者是一个隐含变量(英语:latent variable)。 16 | 17 | #### 后验概率: 18 | 19 | 在贝叶斯统计中,一个随机事件或者一个不确定事件的**后验概率**是在考虑和给出相关证据或数据后所得到的条件概率。同样,后验概率分布是一个未知量(视为随机变量)基于试验和调查后得到的概率分布。“后验”在本文中代表考虑了被测试事件的相关证据。 20 | 21 | #### 似然函数: 22 | 23 | 在数理统计学中,似然函数是一种关于统计模型中的参数的函数,表示模型参数中的似然性。似然函数在统计推断中有重大作用,如在最大似然估计和费雪信息之中的应用等等。“似然性”与“或然性”或“概率”意思相近,都是指某种事件发生的可能性,但是在统计学中,“似然性”和“或然性”或“概率”又有明确的区分。概率用于在已知一些参数的情况下,预测接下来的观测所得到的结果,而似然性则是用于在已知某些观测所得到的结果时,对有关事物的性质的参数进行估计。 24 | 25 | --- 26 | 27 | **先验**——根据若干年的统计(经验)或者气候(常识),某地方下雨的概率; 28 | 29 | **似然**——下雨(果)的时候有乌云(因 or 证据 or 观察的数据)的概率,即已经有了果,对证据发生的可能性描述; 30 | 31 | **后验**——根据天上有乌云(原因或者证据 or 观察数据),下雨(结果)的概率; 32 | 33 | 后验 ~ 先验\*似然 : 存在下雨的可能(先验),下雨之前会有乌云(似然)~ 通过现在有乌云推断下雨概率(后验); 34 | 35 | --- 36 | 37 | 贝叶斯公式中: 38 | 39 | 40 | $$ 41 | p(\theta | x)=\dfrac{p(x|\theta)p(\theta)}{p(x)} 42 | $$ 43 | 44 | 45 | $$x$$:观察得到的数据(结果) 46 | 47 | $$\theta$$:决定数据分布的参数(原因) 48 | 49 | $$p(\theta)$$:先验 50 | 51 | $$p(\theta|x)$$:后验 52 | 53 | $$p(x|\theta)$$:似然 54 | 55 | -------------------------------------------------------------------------------- /shu-xue-ji-chu/gai-lv-tong-ji/yang-ben-tong-ji-liang.md: -------------------------------------------------------------------------------- 1 | ### 统计量 2 | 3 | 设$$X_1$$,$$X_2$$,...,$$X_n$$是来自总体$$X$$(随机变量)的一个样本,它们相互独立,$$g(X_1,X_2,...,X_n)$$是$$X_1$$,$$X_2$$,...,$$X_n$$的函数,若$$g$$中不含未知参数,则称$$g(X_1,X_2,...,X_n)$$是一**统计量**。 4 | 5 | 因为$$X_1$$,$$X_2$$,...,$$X_n$$都是随机变量,而统计量是随机变量的函数,因此统计量是一个随机变量。设$$x_1,x_2,...,x_n$$是相应于样本$$X_1$$,$$X_2$$,...,$$X_n$$的样本值,则称$$g(x_1,x_2,...,x_3)$$是$$g(X_1,X_2,...,X_n)$$的**观察值**。 6 | 7 | **样本均值**: 8 | 9 | 10 | $$ 11 | \overline{X}=\frac{1}{n}\displaystyle\sum_{i=1}^{n} X_i 12 | $$ 13 | 14 | 15 | **样本方差(无偏估计)**: 16 | 17 | 18 | $$ 19 | S^2=\frac{1}{n-1}\displaystyle\sum_{i=1}^{n} (X_i-\overline{X})^2=\frac{1}{n-1}(\displaystyle\sum_{i=1}^{n} X_i^2-n\overline{X}^2) 20 | $$ 21 | 22 | 23 | **样本标准差**: 24 | 25 | 26 | $$ 27 | S=\sqrt{S^2}=\sqrt{\frac{1}{n-1}\displaystyle\sum_{i=1}^{n} (X_i-\overline{X})^2} 28 | $$ 29 | 30 | 31 | **样本**$$k$$**阶(原点)距**: 32 | 33 | 34 | $$ 35 | A_k=\frac{1}{n}\displaystyle\sum_{i=1}^{n} X_i^k 36 | $$ 37 | 38 | 39 | **样本**$$k$$**阶中心距**: 40 | 41 | 42 | $$ 43 | A_k=\frac{1}{n}\displaystyle\sum_{i=1}^{n} (X_i-\overline{X})^k 44 | $$ 45 | 46 | 47 | **样本的协方差:** 48 | 49 | 50 | $$ 51 | Cov(X,Y)=\frac{1}{n-1}\displaystyle\sum_{i=1}^{n} (X_i-\overline{X})(Y_i-\overline{Y}) 52 | $$ 53 | 54 | 55 | 其中$$X_1$$,$$X_2$$,...,$$X_n$$是来自总体$$X$$的一个样本,$$Y_1$$,$$Y_2$$,...,$$Y_n$$是来自总体$$Y$$的一个样本。 56 | 57 | **样本协方差矩阵:** 58 | 59 | 假定$$X_1$$,$$X_2$$,...,$$X_n$$是多维随机变量 60 | 61 | 62 | $$ 63 | c_{ij}=Cov(X_{i},X_{j})=\frac{1}{n-1}\displaystyle\sum_{k=1}^{n} (X_{ik}-\overline{X_i})(X_{jk}-\overline{X_j}) 64 | $$ 65 | 66 | $$ 67 | C=\begin{bmatrix} 68 | c_{11} & c_{12} & ... & c_{1n} \\ 69 | c_{21} & c_{22} & ... & c_{2n} \\ 70 | \vdots & \vdots & & \vdots \\ 71 | c_{n1} & c_{n2} & ... & c_{nn} 72 | \end{bmatrix} 73 | $$ 74 | 75 | 76 | > 为什么样本方差是除以$$n-1$$,而不是$$n$$? 77 | > 78 | > “均值已经用了$$n$$个数的平均来做估计,在求方差时,只有$$n-1$$个数和均值信息是不相关的。而第$$n$$个数已经可以由前$$n-1$$个数和均值来唯一确定,实际上没有信息量,所以在计算方差时,只除以$$n-1$$“ 79 | > 80 | > (详细请参考 [https://www.zhihu.com/question/20099757)](https://www.zhihu.com/question/20099757)) 81 | 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /shu-xue-ji-chu/wei-ji-fen.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /shu-xue-ji-chu/wei-ji-fen/ti-du-xia-jiang-fa.md: -------------------------------------------------------------------------------- 1 | ### 梯度下降法 2 | 3 | 梯度下降法(Gradient descent)或最速下降法(steepest descent)是求解无约束最优化问题的一种常用方法。 4 | 5 | 假设$$f(x)$$是$$R^n$$上具有一阶连续偏导数的函数。要求解的无约束最优化问题是: 6 | 7 | 8 | $$ 9 | \displaystyle\min_{x\in R^n} f(x) 10 | $$ 11 | 12 | 13 | $$x^*$$表示目标函数的极小值点。 14 | 15 | 梯度下降是一种迭代算法。选取适当的初始值$$x^{(0)}$$,不断迭代,更新$$x$$的值,进行目标函数的极小化,直到收敛。 16 | 17 | 梯度的相反方向是使得函数下降最快的方向,因此在迭代的每一步,以负梯度的方向更新$$x$$的值,从而达到减少函数值的目的。 18 | 19 | 由于$$f(x)$$具有一阶连续偏导数,若第$$k$$次迭代的值为$$x^{(k)}$$,则可将$$f(x)$$在$$x^{(k)}$$附件进行一阶泰勒展开: 20 | 21 | 22 | $$ 23 | f(x)=f(x^{(k)})+g^T_k(x-x^{(k)}) 24 | $$ 25 | 26 | 27 | 这里$$g_k=g(x^{(k)}=\nabla f(x^{(k)})$$为$$f(x)$$在$$x^{(k)}$$的梯度。 28 | 29 | 这里求出第$$k+1$$次迭代值$$x^{(k+1)}$$: 30 | 31 | 32 | $$ 33 | x^{(k+1)}\gets x^{(k)}+\lambda_k p_k 34 | $$ 35 | 36 | 37 | 其中$$p_k$$是搜索方向,取负梯度方向$$p_k=-\nabla f(x^{(k)})$$,$$\lambda_k>0$$是步长。 38 | 39 | 在梯度下降法过程中,可以设置迭代的次数,或者迭代后的精度来决定是否结束迭代。 40 | 41 | ![](/assets/Gradient_descent.png) 42 | 43 | > pic source: [https://zh.wikipedia.org/wiki/梯度下降法](https://zh.wikipedia.org/wiki/梯度下降法) 44 | 45 | 图片示例了这一过程,这里假设函数$$f(x,y)$$定义在平面上,并且函数图像是一个碗形。蓝色的曲线是等高线(水平集),即函数$$f(x,y)$$为常数的集合构成的曲线。红色的箭头指向该点梯度的反方向。(一点处的梯度方向与通过该点的等高线垂直)。沿着梯度下降方向,将最终到达碗底,即函数$$f(x,y)$$值最小的点。 46 | 47 | 当目标函数是凸函数时,梯度下降法的解是全局最优解,一般情况下,其解不能保证是全局最优解。梯度下降法的收敛速度也未必是最快的,其他的方法有牛顿法(根据二阶连续偏导数求极值)等。 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /shu-xue-ji-chu/wei-ji-fen/ti-du.md: -------------------------------------------------------------------------------- 1 | ### 方向导数 2 | 3 | 定义:若二元函数$$z=f(x,y)$$在点$$P(x_0,y_0)$$处沿着$$\vec{l}$$(方向角为$$\alpha$$,$$\beta$$)存在下列极限 4 | 5 | 6 | $$ 7 | \dfrac{\partial f}{\partial l}=\lim\limits_{\rho\to 0}\dfrac{f(x+\Delta x, y+\Delta y)-f(x,y)}{\rho} 8 | $$ 9 | 10 | 11 | 12 | $$ 13 | =f_x(x_0,y_0)\cos \alpha+f_y(x_0,y_0)\cos\beta 14 | $$ 15 | 16 | 17 | 其中$$\rho=\sqrt{(\Delta x)^2+(\Delta y)^2}$$,$$\Delta x=\rho\cos\alpha$$,$$\Delta y=\rho\cos\beta$$,则称$$\dfrac{\partial f}{\partial l}$$为函数在点$$P$$处沿着方向$$\vec{l}$$的方向导数。方向导数$$\dfrac{\partial f}{\partial l}$$也就是函数$$z=f(x,y)$$在点$$P$$上沿着$$\vec{l}$$的变化率。 18 | 19 | ![](/assets/方向导数2.png) 20 | 21 | > pic source: [http://www.cnblogs.com/hithink/p/7380838.html](http://www.cnblogs.com/hithink/p/7380838.html) 22 | 23 | ### 梯度 24 | 25 | 方向导数公式$$\dfrac{\partial f}{\partial l}=\dfrac{\partial f}{\partial x}\cos \alpha+\dfrac{\partial f}{\partial y}cos\beta$$,令向量$$\vec{G}=(\dfrac{\partial f}{\partial x}, \dfrac{\partial f}{\partial y})$$,向量$$\vec{l}=(\cos\alpha, \cos\beta)$$ 26 | 27 | 则$$\dfrac{\partial f}{\partial l}=\vec{G}\cdot\vec{l} =\vec{l} \cos(\vec{G}, \vec{l})$$,当$$\vec{G}$$与$$\vec{l}$$方向一致时,内积最大,方向导数取最大值。 28 | 29 | 定义**向量**$$\vec{G}$$为函数$$f(P)$$在$$P$$处的**梯度**(gradient)记作$$\mathrm{grad}f(P)$$,或$$\nabla f(P)$$,即 30 | 31 | 32 | $$ 33 | \mathrm{grad}f(P)=\nabla f(P)=(\dfrac{\partial f}{\partial x}, \dfrac{\partial f}{\partial y}) 34 | $$ 35 | 36 | 37 | 其中$$\nabla=(\dfrac{\partial }{\partial x}, \dfrac{\partial }{\partial y})$$,称为向量微分算子或Nabla算子。 38 | 39 | ### 梯度的几何意义 40 | 41 | 函数在点$$P$$处的沿着梯度向量的方向导数取最大值,那么也就是该方向的变化率最大,增长速度最快。 42 | 43 | 为什么梯度的方向是函数增长的方向?个人理解这要从导数(或偏导数)的定义开始。 44 | 45 | ![](/assets/538px-Derivative_-_geometric_meaning.svg.png) 46 | 47 | > pic source: 48 | > 49 | > [https://commons.wikimedia.org/w/index.php?curid=21999275](https://commons.wikimedia.org/w/index.php?curid=21999275) 50 | > 51 | > [https://zh.wikipedia.org/wiki/导数](https://zh.wikipedia.org/wiki/导数) 52 | 53 | 函数在某一点可导,得到的切线的斜率为导数,而切线的斜率定义为跟$$x$$轴正方向的夹角。即 54 | 55 | 一条直线与某平面直角坐标系横轴正半轴方向的夹角的正切值即该直线相对于该坐标系的斜率。 ([https://baike.baidu.com/item/直线的斜率)](https://baike.baidu.com/item/直线的斜率)) 56 | 57 | 斜率是标量,没有方向,但是如果以斜率的大小作为方向的一个分量,上面图中斜率的方向为$$(\Delta x, \alpha \Delta x)$$,其中$$\alpha > 0$$,则因此沿着斜率的方向是函数增长的方向。偏导数同理,因此偏导数构成的向量是函数增长的方向。 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /shu-xue-ji-chu/wei-ji-fen/xiang-liang-nei-ji.md: -------------------------------------------------------------------------------- 1 | ### 向量内积 2 | 3 | 在数学中,点积(Dot Product)又称数量积,是一个接受两个等长度的数字序列(通常是向量坐标),然后返回单个数字的代数运算。在欧几里德几何中,两个笛卡尔坐标向量的点积常称为内积(Inner Product)。 4 | 5 | 从代数的角度看,先对两个数字序列中的每组对应元素求积,再对所有积求和,结果即为点积。 6 | 7 | 从几何角度看,点积则是两个向量的长度与它们的夹角的余弦的积。 8 | 9 | **代数定义:** 10 | 11 | 两个向量 $$\vec{a}=[a_1, a_2, ..., a_n]$$ 和 $$\vec{b}=[b_1, b_2, ..., b_n]$$ 的点积定义为: 12 | 13 | 14 | $$ 15 | \vec{a} \cdot \vec{b} = \displaystyle\sum_{i=1}^n a_ib_i= a_1b_1+a_2b_2+...+ a_nb_n 16 | $$ 17 | 18 | 19 | **几何定义:** 20 | 21 | 在欧几里德空间中,点积可以直观的定义为: 22 | 23 | 24 | $$ 25 | \vec{a} \cdot \vec{b} =|{a}||{b} | \mathrm{cos}\theta 26 | $$ 27 | 28 | 29 | 这里$$|\vec{x}|$$表示向量$$\vec{x}$$的模的长度,$$\theta$$表示两个向量的角度。 30 | 31 | 当两个向量互相垂直时点积总是为零。因为$$\mathrm{cos} 90 = 0$$。当两个向量方向相同时,角度为$$0$$,内积为正的最大;当两个向量方向相反时,角度为$$180$$,内积为负的最大。 32 | 33 | ![](/assets/cos-functionGIF.GIF) 34 | 35 | 若$${a}$$和$${b}$$都是单位向量(长度为1),它们的点积就是它们的夹角的余弦。那么给定两个向量,它们之间的夹角可以通过下列公式得到: 36 | 37 | 38 | $$ 39 | \mathrm{cos} \theta =\frac{ \vec{a} \cdot \vec{b} }{ |{a}| |{b}|} 40 | $$ 41 | 42 | 43 | ![](/assets/Scalarproduct.gif) 44 | 45 | 向量的内积可以理解为向量A在向量B上的投影跟向量B的长度的乘积。 46 | 47 | > source: [https://zh.wikipedia.org/wiki/点积](https://zh.wikipedia.org/wiki/点积) 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /shu-xue-ji-chu/xian-xing-dai-shu.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/shu-xue-ji-chu/xian-xing-dai-shu.md -------------------------------------------------------------------------------- /shu-xue-ji-chu/xian-xing-dai-shu/te-zheng-zhi-he-te-zheng-xiang-liang.md: -------------------------------------------------------------------------------- 1 | 特征值 2 | 3 | -------------------------------------------------------------------------------- /shu-xue-ji-chu/xin-xi-lun.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/shu-xue-ji-chu/xin-xi-lun.md -------------------------------------------------------------------------------- /shu-xue-ji-chu/xin-xi-lun/hu-xin-xi.md: -------------------------------------------------------------------------------- 1 | 互信息 2 | 3 | > 参考:[https://zh.wikipedia.org/zh-hans/互信息](https://zh.wikipedia.org/zh-hans/互信息) 4 | 5 | 两个随机变量的互信息(Mutual Information,简称MI)是两个变量相互依赖性的量度。 6 | 7 | 8 | $$ 9 | I(X,Y)=H(Y)-H(Y|X)=H(X)-H(X|Y)=H(X)+H(Y)-H(X,Y) 10 | $$ 11 | 12 | 13 | 直观地说,如果把熵$$H(Y)$$ 看作一个随机变量不确定度的量度,那么 $$H(Y|X)$$ 就是随机变量$$X$$ 没有涉及到的随机比变量$$Y$$的部分的不确定度的量度。这就是“在$$X$$ 已知之后$$Y$$ 的剩余不确定度的量”,于是第一个等式的右边就可以读作“$$Y$$的不确定度,减去在 X 已知之后 Y 的剩余不确定度的量”,此式等价于“移除知道 X 后 Y 的不确定度的量”。这证实了互信息的直观意义为知道其中一个变量提供的另一个的信息量(即不确定度的减少量)。 14 | 15 | -------------------------------------------------------------------------------- /shu-xue-ji-chu/xin-xi-lun/shang.md: -------------------------------------------------------------------------------- 1 | ### 熵 2 | 3 | > 参考:[https://zh.wikipedia.org/wiki/熵\_\(信息论\](https://zh.wikipedia.org/wiki/熵_%28信息论%29\) 4 | 5 | 在信息论中**熵**(entropy)是接收的每条消息中包含的信息的平均量,又被称为**信息熵**、**信源熵**、**平均自信息量**。 6 | 7 | 熵也可以理解为不确定性的量度,因为越随机的信源的熵越大。这里的想法是,比较不可能发生的事情,当它发生了,会提供更多的信息。 8 | 9 | 如果有一个系统$$S$$内存在多个事件$$S = \{E_1,E_2,...,E_n\}$$,每个事件的概率分布$$P = \{p_1,p_2, ..., p_n\}$$,则每个事件本身的讯息(自信息)为: 10 | 11 | $$I_e=- \mathrm{log}_2 {p_i}$$(对数以2为底,单位是比特(bit)) 12 | 13 | $$I_e=- \mathrm{ln} {p_i}$$(对数以$$e$$为底,单位是纳特/nats) 14 | 15 | 如英语有26个字母,假如每个字母在文章中出现次数平均的话,每个字母的信息量为: 16 | 17 | $$I_e=- \mathrm{log}_2 {\dfrac{1}{26}}=4.7$$ 18 | 19 | 而汉字常用的有2500个,假如每个汉字在文章中出现次数平均的话,每个汉字的信息量为: 20 | 21 | $$I_e=- \mathrm{log}_2 {\dfrac{1}{2500}}=11.3$$ 22 | 23 | 实际上每个字母和每个汉字在文章中出现的次数并不平均,比方说较少见字母(如z)和罕用汉字就具有相对高的信息量。但上述计算提供了以下概念:使用书写单元越多的文字,每个单元所包含的讯息量越大。 24 | 25 | 熵是整个系统的**平均信息量:** 26 | 27 | 28 | $$ 29 | H_s=\displaystyle-\sum_{i=1}^np_i\mathrm{log}_2p_i 30 | $$ 31 | 32 | 33 | 若$$p_i=0$$,则定义$$0log0=0$$。通常对数以2为底或以$$e$$为底,这时熵的单位分别作为比特(bit)或奈特(nat)。 34 | 35 | 熵越大,随机变量的不确定性越大。 36 | 37 | **极值性** 38 | 39 | 当所有事件有相同机会出现的情况下,熵达到最大值(所有可能的事件同等概率时不确定性最高) 40 | 41 | 42 | $$ 43 | 0\leqslant H_n(p_1,p_2,...,p_n)\leqslant H_n(\dfrac{1}{n},\dfrac{1}{n},...,\dfrac{1}{n})=\mathrm{log}n 44 | $$ 45 | 46 | 47 | 举例来说,当随机变量只取两个值时,例如1和0,则随机变量$$X$$的分布为 48 | 49 | $$P(X=1)=p$$,$$P(X=0)=1-p$$,$$0\leqslant p \leqslant 1$$ 50 | 51 | 熵为$$H(p)=-p\mathrm{log}_2p-(1-p)\mathrm{log}_2(1-p)$$ 52 | 53 | 这时熵随着概率$$p$$变化的曲线如图,当$$p=0.5$$时熵取值最大,系统的不确定性最大。 54 | 55 | ![](/assets/Binary_entropy_plot.svg.png) 56 | 57 | #### 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /shu-xue-ji-chu/xin-xi-lun/tiao-jian-shang.md: -------------------------------------------------------------------------------- 1 | ### 条件熵 2 | 3 | > 参考 [https://zh.wikipedia.org/wiki/条件熵](https://zh.wikipedia.org/wiki/条件熵) 4 | 5 | 假设有随机变量$$(X,Y)$$,其联合概率分布为:$$P(X=x_i, Y=y_i)=p_{ij}$$ 6 | 7 | $$P(X=x_i, Y=y_j)=p_{ij}$$,$$i=1,2,...,n; j=1,2,...,m$$ 8 | 9 | 条件熵描述了在已知随机变量$$X$$的值的前提下,随机变量$$Y$$ 的信息熵还有多少。同其它的信息熵一样,条件熵也用Sh、nat、Hart等信息单位表示。基于$$X$$ 条件的$$Y$$ 的信息熵,用$$H(Y|X)$$表示。 10 | 11 | $$H(Y|X=x)$$为随机变量$$Y$$在$$X$$取特定值$$x $$下的熵,那么$$H(Y|X)$$就是$$H(Y|X=x)$$在$$X$$取遍所有可能$$x$$后取平均期望的结果。 12 | 13 | 给定随机变量$$X \in \mathcal{X}$$,$$Y\in \mathcal{Y}$$,在给定$$X$$条件下$$Y$$的条件熵定义为: 14 | 15 | 16 | $$ 17 | H(Y|X)=\displaystyle\sum_{x\in \mathcal{X}}p(x)H(Y|X=x) 18 | $$ 19 | 20 | 21 | 22 | $$ 23 | =-\displaystyle\sum_{x\in \mathcal{X}}p(x)\displaystyle\sum_{y\in \mathcal{Y}}p(y|x)\mathrm{log}p(y|x) 24 | $$ 25 | 26 | 27 | 28 | $$ 29 | =-\displaystyle\sum_{x\in \mathcal{X}}\displaystyle\sum_{y\in \mathcal{Y}}p(x,y)\mathrm{log}p(y|x) 30 | $$ 31 | 32 | 33 | 34 | $$ 35 | =-\displaystyle\sum_{x\in \mathcal{X},y\in \mathcal{Y}}p(x,y)\mathrm{log}\dfrac{p(x,y)}{p(x)} 36 | $$ 37 | 38 | 39 | 40 | $$ 41 | =-\displaystyle\sum_{x\in \mathcal{X},y\in \mathcal{Y}}p(x,y)\mathrm{log}\dfrac{p(x,y)}{p(x)} 42 | $$ 43 | 44 | 45 | 46 | $$ 47 | =\displaystyle\sum_{x\in \mathcal{X},y\in \mathcal{Y}}-p(x,y)\mathrm{log}p(x,y)-\displaystyle\sum_{x\in \mathcal{X}}-p(x)\mathrm{log}p(x) 48 | $$ 49 | 50 | 51 | 52 | $$ 53 | =H(X,Y)-H(X) 54 | $$ 55 | 56 | 57 | 即$$H(Y|X)=H(X,Y)-H(X)$$,同样$$H(X|Y)=H(X,Y)-H(Y)$$ 58 | 59 | -------------------------------------------------------------------------------- /shu-xue-ji-chu/xin-xi-lun/xiang-dui-shang-he-jiao-cha-shang.md: -------------------------------------------------------------------------------- 1 | ### 交叉熵 2 | 3 | 在信息论中,基于相同事件测度的两个概率分布$$p$$和$$q$$的交叉熵是指,当基于一个“非自然”(相对于“真实”分布$$p$$而言)的概率分布$$q$$进行编码时,在事件集合中唯一标识一个事件所需要的平均比特数。 4 | 5 | 基于概率分布$$p$$和$$q$$的交叉熵定义为: 6 | 7 | 8 | $$ 9 | H(p,q)=E_p[-\mathrm{log}q] 10 | $$ 11 | 12 | 13 | 对于离散分布$$p$$和$$q$$: 14 | 15 | 16 | $$ 17 | H(p,q)=-\displaystyle\sum_{x\in \mathcal{X}}p(x)\mathrm{log}q(x) 18 | $$ 19 | 20 | 21 | 或: 22 | 23 | 24 | $$ 25 | H(p,q)=\displaystyle\sum_{x\in \mathcal{X}}p(x)\mathrm{log}\frac{1}{q(x)} 26 | $$ 27 | 28 | 29 | 特别地,当随机变量只取两个值时,$$P(X=1)=p$$,$$P(X=0)=1-p$$,$$0\leqslant p \leqslant 1$$,则 30 | 31 | 32 | $$ 33 | H(p,q)=-\displaystyle\sum_{x\in \mathcal{X}}p(x)\mathrm{log}q(x) 34 | $$ 35 | 36 | 37 | 38 | $$ 39 | = -[P_p(x=1)\mathrm{log}P_q(x=1) + P_p(x=0)\mathrm{log}P_q(x=0)] 40 | $$ 41 | 42 | 43 | 44 | $$ 45 | = -[p\mathrm{log}q + (1-p)\mathrm{log}q] 46 | $$ 47 | 48 | 49 | ### 相对熵 50 | 51 | 相对熵(relative entropy)又称KL散度(Kullback-Leibler divergence),KL距离,是两个随机分布间距离的度量,记为$$D_{KL}(p||q)$$。它度量当真实分布为$$p$$时,假设分布$$q$$的无效性。 52 | 53 | 54 | $$ 55 | D_{KL}(p||q)=E_p[\mathrm{log}\frac{p(x)}{q(x)}]=\displaystyle\sum_{x\in \mathcal{X}}p(x)\mathrm{log}\frac{p(x)}{q(x)} 56 | $$ 57 | 58 | 59 | 60 | $$ 61 | =\displaystyle\sum_{x\in \mathcal{X}}[p(x)\mathrm{log}p(x)-p(x)\mathrm{log}q(x)] 62 | $$ 63 | 64 | 65 | 66 | $$ 67 | =\displaystyle\sum_{x\in \mathcal{X}}p(x)\mathrm{log}p(x)-\displaystyle\sum_{x\in \mathcal{X}}p(x)\mathrm{log}q(x) 68 | $$ 69 | 70 | 71 | 72 | $$ 73 | = -H(p)--\displaystyle\sum_{x\in \mathcal{X}}p(x)\mathrm{log}q(x) 74 | $$ 75 | 76 | 77 | 78 | $$ 79 | =-H(p)-E_p[\mathrm{log}q(x)] 80 | $$ 81 | 82 | 83 | 84 | $$ 85 | =H_p(q)-H(p) 86 | $$ 87 | 88 | 89 | 其中$$H_p(q)$$即是交叉熵。 90 | 91 | 当$$p=q$$时,两者之间的相对熵$$D_{KL}(p||q)=0$$。 92 | 93 | 因此$$D_{KL}(p||q)$$的含义就是:真实分布为$$p$$的前提下,使用$$q$$分布进行编码相对于使用真实分布$$p$$进行编码所多出来的比特数。 94 | 95 | -------------------------------------------------------------------------------- /suan-fa-python-shi-xian.md: -------------------------------------------------------------------------------- 1 | # 感知机算法python实现 2 | 3 | ### 1.python代码实现 4 | 5 | 包含算法的原始形式和对偶形式 6 | 7 | ``` 8 | # -*- coding: utf-8 -*- 9 | 10 | import numpy as np 11 | 12 | class Perceptron(object): 13 | 14 | def __init__(self, input_x, feature_num, input_y, learn_rate=1): 15 | self._input_x = np.array(input_x) # 输入数据集中的X 16 | self._input_y = np.array(input_y) # 输入数据集中的Y 17 | self._feature_num = feature_num # 总共有多少个特征 18 | self._rate = learn_rate # 学习速率 19 | self._final_w = 0 # 最后学习到的w 20 | self._final_b = 0 # 最后学习到的b 21 | 22 | def sgd_train(self): #算法原始形式 23 | total = len(self._input_y) 24 | feature_num = range(self._feature_num) 25 | data_num = range(total) 26 | w = np.zeros(self._feature_num) #初始化向量w 27 | b = 0 28 | 29 | while True: 30 | separted = True 31 | for i in data_num: # 遍历数据集,查找误分类点 32 | inner = np.inner(w, self._input_x[i]) 33 | if self._input_y[i] * (inner+b) <= 0: # 误分类点 34 | separted = False 35 | w = w + self._rate * self._input_y[i] * self._input_x[i] 36 | b = b + self._rate * self._input_y[i] 37 | if separted: 38 | break 39 | else: 40 | continue 41 | self._final_w = w 42 | self._final_b = b 43 | print(self._final_w, self._final_b) 44 | 45 | def pair_sgd_train(self): # 对偶形式 46 | total = len(self._input_y) 47 | feature_num = range(self._feature_num) 48 | data_num = range(total) 49 | gram_matrix = self._input_x.dot(self._input_x.T) # Gram 矩阵 50 | alpha = np.random.random(size=total) # 这里初始化alpha向量为随机值 51 | b = 0 52 | 53 | while True: 54 | separted = True 55 | for i in data_num: 56 | inner = np.sum(alpha * self._input_y * gram_matrix[i]) 57 | if self._input_y[i] * (inner+b) <= 0: # 误分类点 58 | separted = False 59 | alpha[i] = alpha[i] + self._rate # 对偶形式只更新alpha向量中的一个分量 60 | b = b + self._rate * self._input_y[i] 61 | if separted: 62 | break 63 | else: 64 | continue 65 | self._final_w = (alpha * self._input_y.T).dot(self._input_x) 66 | self._final_b = b 67 | print(self._final_w, self._final_b) 68 | 69 | input_x = [[3,3], [4,3], [1,1], [2,3]] 70 | input_y = [1,1,-1,-1] 71 | 72 | pla = Perceptron(input_x, 2, input_y, 1) 73 | pla.sgd_train() 74 | pla.pair_sgd_train() 75 | ``` 76 | 77 | ### 2. 图形显示 78 | 79 | 用matplotlib将结果用图形画出来,在类中添加如下函数 80 | 81 | ``` 82 | def draw_result(self): 83 | total = len(self._input_y) 84 | self._positive_x = [] 85 | self._nagtive_x = [] 86 | 87 | for i in range(total): 88 | if self._input_y[i] >= 0: 89 | self._positive_x.append(self._input_x[i]) 90 | else: 91 | self._nagtive_x.append(self._input_x[i]) 92 | 93 | plt.figure(1) 94 | x1 = [x[0] for x in self._positive_x] 95 | x2 = [x[1] for x in self._positive_x] 96 | plt.scatter(x1, x2, label='positive', color='g', s=30, marker="o") # 正数据集 97 | x1 = [x[0] for x in self._nagtive_x] 98 | x2 = [x[1] for x in self._nagtive_x] 99 | plt.scatter(x1, x2, label='nagtive', color='r', s=30, marker="x") # 负数据集 100 | plt.xlabel('x1') 101 | plt.ylabel('x2') 102 | plt.axis([0, 5, 0, 5]) 103 | def f(x): 104 | return -(self._final_b + self._final_w[0]*x)/self._final_w[1] 105 | x = np.array([0,1,2,3,4,5]) 106 | plt.plot(x, f(x), 'b-', lw=2) # 将最后的直线画出 107 | plt.title('Perceptron') 108 | plt.legend() 109 | plt.show() 110 | 111 | pla = Perceptron(input_x, 2, input_y, 1) 112 | pla.pair_sgd_train() 113 | pla.draw_result() 114 | ``` 115 | 116 | 测试 117 | 118 | ``` 119 | input_x = [[3,3], [4,3], [1,1], [2,3]] 120 | input_y = [1,1,-1,-1] 121 | 122 | pla = Perceptron(input_x, 2, input_y, 1) # 2个特征,学习速率为1 123 | pla.pair_sgd_train() 124 | pla.draw_result() 125 | ``` 126 | 127 | ![](/assets/pla-figure.png) 128 | 129 | > 参考文献: 130 | > 131 | > [http://blog.csdn.net/wangxin1982314/article/details/73529499](http://blog.csdn.net/wangxin1982314/article/details/73529499) 132 | 133 | 134 | 135 | -------------------------------------------------------------------------------- /xian-xing-hui-gui.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/xian-xing-hui-gui.md -------------------------------------------------------------------------------- /xian-xing-hui-gui/suan-fa-python-shi-xian.md: -------------------------------------------------------------------------------- 1 | ### 线性回归python实现 2 | 3 | #### 1.算法python代码 4 | 5 | 包含Normal Equations,批量梯度下降和随机梯度下降,这里的代码跟Logistic回归的代码类似 6 | 7 | ``` 8 | # -*- coding: utf-8 -*- 9 | 10 | import matplotlib.pyplot as plt 11 | import numpy as np 12 | 13 | class LinearRegression(object): 14 | 15 | def __init__(self): 16 | self._history_w = [] 17 | self._cost = [] 18 | 19 | def load_input_data(self, data_file): 20 | with open(data_file) as f: 21 | input_x = [] 22 | input_y = [] 23 | for line in f: 24 | [x0, x1, y] = line.split() 25 | input_x.append([float(x0), float(x1)]) 26 | input_y.append(float(y)) 27 | self._input_x = np.array(input_x) 28 | self._input_y = np.array(input_y).T 29 | 30 | def normal_equations(self): # 用矩阵的计算直接得到w 31 | xtx = np.dot(self._input_x.T, self._input_x) 32 | xtx_inverse = np.linalg.inv(xtx) 33 | tmp = np.dot(xtx_inverse, self._input_x.T) 34 | self._final_w = np.inner(tmp, self._input_y) # (X^T * X)^-1 * X^T * Y 35 | return self._final_w 36 | 37 | def cost_function(self, w): # 成本函数 38 | tmp = np.inner(self._input_x, w) 39 | tmp = tmp - self._input_y 40 | return np.inner(tmp.T, tmp) 41 | 42 | def batch_gradient_descent(self, iter_num, iter_rate): #批量梯度下降 43 | (data_num, features) = np.shape(self._input_x) 44 | w = np.ones(features) 45 | for i in range(iter_num): 46 | inner = np.inner(self._input_x, w) 47 | delta = inner - self._input_y 48 | w = w - iter_rate * np.inner(self._input_x.T, delta) #w的迭代 49 | self._history_w.append(w) 50 | self._cost.append(self.cost_function(w)) 51 | self._final_w = w 52 | return w 53 | 54 | def stochastic_gradient_descent(self, iter_num, iter_rate): # 随机梯度下降 55 | (data_num, features) = np.shape(self._input_x) 56 | w = np.ones(features) 57 | data_range = range(data_num) 58 | for i in range(iter_num): 59 | for j in data_range: 60 | iter_rate = 4/(1.0+j+i) + 0.01 61 | inner = np.inner(self._input_x[j], w) 62 | delta = inner - self._input_y[j] 63 | w = w - iter_rate * delta* self._input_x[j] #w的迭代 64 | self._history_w.append(w) 65 | self._cost.append(self.cost_function(w)) 66 | self._final_w = w 67 | return w 68 | ``` 69 | 70 | #### 2. python数据显示 71 | 72 | 在同一个类中添加如下代码 73 | 74 | ``` 75 | def draw_result(self, title): 76 | plt.figure(1) 77 | x1 = [x[1] for x in self._input_x] 78 | plt.scatter(x1, self._input_y, color='b', s=20, marker=".") 79 | plt.xlabel('x') 80 | plt.ylabel('x') 81 | def f(x): 82 | return (self._final_w[0] + self._final_w[1]*x) 83 | x2 = np.array([self._input_x.min(axis=0)[1], self._input_x.max(axis=0)[1]]) 84 | plt.plot(x2, f(x2), 'b-', lw=1) 85 | plt.title(title) 86 | plt.show() 87 | 88 | def draw_cost_function(self, title): 89 | plt.figure(1) 90 | x = np.arange(len(self._cost)) 91 | plt.scatter(x, self._cost, label='Cost', color='g', s=10, marker=".") 92 | plt.xlabel('x') 93 | plt.ylabel('Cost function') 94 | plt.title(title + ' Cost trend') 95 | plt.ylim(-0.5, 100) #限定y轴显示的区间 96 | plt.legend() 97 | plt.show() 98 | ``` 99 | 100 | #### 3.数据集测试 101 | 102 | > 数据集来自《机器学习实战》 103 | > 104 | > [https://github.com/apachecn/MachineLearning/blob/python-2.7/input/8.Regression/data.txt](https://github.com/apachecn/MachineLearning/blob/python-2.7/input/8.Regression/data.txt) 105 | 106 | **3.1 Normal Equations** 107 | 108 | ``` 109 | linear = LinearRegression() 110 | linear.load_input_data("test.txt") 111 | linear.normal_equations() 112 | title = "Normal Equations" 113 | linear.draw_result(title) 114 | ``` 115 | 116 | ![](/assets/linear_normal_equations.png) 117 | 118 | **3.2 批量梯度下降** 119 | 120 | ``` 121 | linear = LinearRegression() 122 | linear.load_input_data("test.txt") 123 | linear.batch_gradient_descent(iter_num=100, iter_rate=0.001) 124 | title = "Batch Gradient Descent" 125 | linear.draw_result(title) 126 | linear.draw_cost_function(title) 127 | ``` 128 | 129 | ![](/assets/linear_bgd_1.png) 130 | 131 | ![](/assets/linear_bgd_2.png) 132 | 133 | **3.2 随机梯度下降** 134 | 135 | ``` 136 | linear = LinearRegression() 137 | linear.load_input_data("test.txt") 138 | linear.stochastic_gradient_descent(iter_num=5, iter_rate=0.001) 139 | title = "Stochastic Gradient Descent" 140 | linear.draw_result(title) 141 | linear.draw_cost_function(title) 142 | ``` 143 | 144 | ![](/assets/linear_sgd_1.png) 145 | 146 | ![](/assets/linear_sgd_2.png) 147 | 148 | -------------------------------------------------------------------------------- /xian-xing-hui-gui/xian-xing-hui-gui-mo-xing.md: -------------------------------------------------------------------------------- 1 | ### 线性回归模型(linear regression) 2 | 3 | #### 1.模型定义 4 | 5 | 给定数据集,$$T=\{(x^{(1)},y^{(1)}),(x^{(2)},y^{(2)}),...,(x^{(m)},y^{(m)})\}$$,其中$$x^{(i)}=(1, x_1, x_2, ..., x_n)^T\in X= R^{n+1}$$,$$y^{(i)}\in Y=R$$,线性回归模型试图学到一个通过属性的线性组合来进行预测的函数,即 6 | 7 | 8 | $$ 9 | f(x)=w_1x_1+w_2x_2+...+w_nx_n+b 10 | $$ 11 | 12 | 13 | 一般用向量写成: 14 | 15 | 16 | $$ 17 | f(x)=w^T\cdot x+b 18 | $$ 19 | 20 | 21 | 其中$$w=(w_1, x_2, ..., w_n)^T\in R^{n}$$,$$b\in R$$,使得$$f(x)\simeq y$$。 22 | 23 | 如何确定$$w$$和$$b$$呢,显然关键在于如何衡量$$f(x)$$与$$y$$之间的差别。均方误差是最常用的性能度量,因此我们可以试图让均方误差最小化,即: 24 | 25 | 26 | $$ 27 | \min_{w,b} L(w,b)=\displaystyle\sum_{i=1}^m(f(x^{(i)})-y^{(i)})^2 28 | $$ 29 | 30 | 31 | 32 | $$ 33 | =\displaystyle\sum_{i=1}^m(w^T\cdot x^{(i)}+b-y^{(i)})^2 34 | $$ 35 | 36 | 37 | 均方误差有非常好的几何意义,它对应了常用的欧几里得距离或简称“**欧氏距离**”(Euclidean distance)。基于均方误差最小化来进行模型求解的方法称为“**最小二乘法**”(least square method)。在线性回归中,最小二乘法是试图找到一条直线,使得所有样本到直线上的欧氏距离之和最小。 38 | 39 | 求解$$w$$和$$b$$,使$$ L(w,b)=\displaystyle\sum_{i=1}^m(f(x^{(i)})-y^{(i)})^2$$最小化的过程,称为线性回归模型的最小二乘“参数估计”(parameter estimation)。令$$w_0=b$$,$$x_0=1$$,则$$w=(w_0,w_1, w_2, ..., w_n)^T$$,$$x=(x_0, x_1, x_2, ..., x_n)^T$$,原式转换为: 40 | 41 | 42 | $$ 43 | f(x)=w^T\cdot x 44 | $$ 45 | 46 | 47 | 48 | $$ 49 | \min_{w} L(w)=\displaystyle\sum_{i=1}^m(w^T\cdot x^{(i)}-y^{(i)})^2 50 | $$ 51 | 52 | 53 | 对其求导,可得: 54 | 55 | 56 | $$ 57 | \dfrac{\partial L(w,b)}{\partial w_j}=\dfrac{\partial \displaystyle\sum_{i=1}^m(w^T\cdot x^{(i)}-y^{(i)})^2}{\partial w_j} 58 | $$ 59 | 60 | 61 | 62 | $$ 63 | =\displaystyle\sum_{i=1}^m2(w^T\cdot x^{(i)}-y^{(i)})x^{(i)}_j 64 | $$ 65 | 66 | 67 | 得到梯度向量: 68 | 69 | 70 | $$ 71 | \nabla L(w)= \displaystyle\sum_{i=1}^m(w^T\cdot x^{(i)}-y^{(i)})x^{(i)} 72 | $$ 73 | 74 | 75 | 假定: 76 | 77 | $$X= \begin{bmatrix} 78 | (x^{(1)})^T \\ 79 | (x^{(2)})^T \\ 80 | (x^{(3)})^T \\ 81 | ... \\ 82 | ( x^{(m)} )^T 83 | \end{bmatrix} = \begin{bmatrix} 84 | 1 & x^{(1)}_1 & x^{(1)}_2 & ... & x^{(1)}_n \\ 85 | 1 & x^{(2)}_1 & x^{(2)}_2 & ... & x^{(2)}_n \\ 86 | 1 & x^{(3)}_1 & x^{(3)}_2 & ... & x^{(3)}_n \\ 87 | ... \\ 88 | 1 & x^{(m)}_1 & x^{(m)}_2 & ... & x^{(m)}_n 89 | \end{bmatrix}$$,$$Y=\begin{bmatrix} 90 | y^{(1)} \\ 91 | y^{(2)} \\ 92 | y^{(3)} \\ 93 | ... \\ 94 | y^{(m)} 95 | \end{bmatrix}$$,$$w=\begin{bmatrix} 96 | w_0 \\ 97 | w_1 \\ 98 | w_2 \\ 99 | ... \\ 100 | w_n 101 | \end{bmatrix}$$ 102 | 103 | 则: 104 | 105 | 106 | $$ 107 | X\cdot w= \begin{bmatrix} 108 | 1 & x^{(1)}_1 & x^{(1)}_2 & ... & x^{(1)}_n \\ 109 | 1 & x^{(2)}_1 & x^{(2)}_2 & ... & x^{(2)}_n \\ 110 | 1 & x^{(3)}_1 & x^{(3)}_2 & ... & x^{(3)}_n \\ 111 | ... \\ 112 | 1 & x^{(m)}_1 & x^{(m)}_2 & ... & x^{(m)}_n 113 | \end{bmatrix}\cdot \begin{bmatrix} 114 | w_0 \\ 115 | w_1 \\ 116 | w_2 \\ 117 | ... \\ 118 | w_n 119 | \end{bmatrix}=\begin{bmatrix} 120 | (x^{(1)})^T\cdot w \\ 121 | (x^{(2)})^T\cdot w \\ 122 | (x^{(3)})^T\cdot w \\ 123 | ... \\ 124 | (x^{(m)})^T\cdot w 125 | \end{bmatrix}=\begin{bmatrix} 126 | w^T \cdot x^{(1)} \\ 127 | w^T \cdot x^{(2)} \\ 128 | w^T \cdot x^{(3)} \\ 129 | ... \\ 130 | w^T \cdot x^{(m)} 131 | \end{bmatrix} 132 | $$ 133 | 134 | 135 | 136 | $$ 137 | X\cdot w-Y =\begin{bmatrix} 138 | w^T \cdot x^{(1)}-y^{(1)} \\ 139 | w^T \cdot x^{(2)}-y^{(2)} \\ 140 | w^T \cdot x^{(3)}-y^{(3)} \\ 141 | ... \\ 142 | w^T \cdot x^{(m)}-y^{(m)} 143 | \end{bmatrix} 144 | $$ 145 | 146 | 147 | 148 | $$ 149 | X^T\cdot (X\cdot w-Y )=\begin{bmatrix} 150 | x^{(1)} & x^{(2)} & x^{(3)} & ... & x^{(m)} 151 | \end{bmatrix}\cdot \begin{bmatrix} 152 | w^T \cdot x^{(1)}-y^{(1)} \\ 153 | w^T \cdot x^{(2)}-y^{(2)} \\ 154 | w^T \cdot x^{(3)}-y^{(3)} \\ 155 | ... \\ 156 | w^T \cdot x^{(m)}-y^{(m)} 157 | \end{bmatrix} 158 | $$ 159 | 160 | 161 | 于是得到: 162 | 163 | 164 | $$ 165 | \nabla L(w)=2 X^T\cdot (X\cdot w-Y ) 166 | $$ 167 | 168 | 169 | 令一方面$$L(w)$$也可以表示成: 170 | 171 | 172 | $$ 173 | L(w)=(X\cdot w-Y)^T\cdot (X\cdot w-Y)=(w^T X^TX w -2w^TX^TY+Y^T Y) 174 | $$ 175 | 176 | 177 | 对$$w$$求导,同样可以得到梯度。 178 | 179 | 欲求的最优解,令梯度为0, 180 | 181 | 182 | $$ 183 | \nabla L(w)=2 X^T\cdot X\cdot w-2 X^T\cdot Y =0 184 | $$ 185 | 186 | 187 | 则得到: 188 | 189 | 190 | $$ 191 | w=(X^T\cdot X)^{-1}\cdot X^T\cdot Y 192 | $$ 193 | 194 | 195 | 于是最终得到线性模型: 196 | 197 | 198 | $$ 199 | f(x)=w^T\cdot x=x^T\cdot (X^T\cdot X)^{-1}\cdot X^T\cdot Y 200 | $$ 201 | 202 | 203 | 令$$X^\dagger =(X^T\cdot X)^{-1}\cdot X^T$$,称为**伪逆\(**seudo-inverse\),代入得到。 204 | 205 | 206 | $$ 207 | f(x) = x^T\cdot X^\dagger\cdot Y 208 | $$ 209 | 210 | 211 | ### 2.学习算法 212 | 213 | #### 2.1 Normal Equations 214 | 215 | 计算$$w=(X^T\cdot X)^{-1}\cdot X^T\cdot Y$$,直接得到模型$$f(x)=w^T\cdot x$$ 216 | 217 | 但是计算矩阵的逆是非常费时的事情,$$X^T_{n\times m}\cdot X_{m\times n}=Z_{n\times n}$$,因此当特征数量比较多时,偏向于用梯度下降法。 218 | 219 | #### 2.2 批量梯度下降(Batch Gradient Descent) 220 | 221 | **输入:**训练数据集$$T=\{(x^{(1)},y^{(1)}),(x^{(2)},y^{(2)}),...,(x^{(m)},y^{(m)})\}$$,其中$$x^{(i)}\in X= R^n$$,$$y^{(i)}\in Y=R^n$$,$$i=1,2,...,m$$,学习率$$\eta(0<\eta\leqslant1)$$; 222 | 223 | **输出:**$$w=(w_1, w_2, ..., w_n)^T$$和$$b$$,模型$$f(x)=w^T\cdot x+b$$ 224 | 225 | **1)**将输入的每个$$x^{(i)}$$转换成$$x^{(i)}=(1, x_1, x_2,...x_n)$$,令$$w_0=b$$,则输出为$$w=(w_0, w_1, w_2, ..., w_n)^T$$ 226 | 227 | **2)**选取初始$$w^{(0)}=(w_0, w_1, w_2, ..., w_n)^T$$ 228 | 229 | **3)**计算梯度$$X^T\cdot (X\cdot w^{(j)}-Y )$$,这里略去系数2,其中$$w^{(j)}$$为第$$j$$次迭代的结果,则第$$j+1$$迭代: 230 | 231 | 232 | $$ 233 | w^{(j+1)} \gets w^{(j)} - \eta X^T\cdot (X\cdot w^{(j)}-Y ) 234 | $$ 235 | 236 | 237 | **4)**转到步骤(3),一直到满足一定条件,或者迭代到足够的次数。 238 | 239 | 在批量梯度下降算法中,每一步的迭代都需要计算所有样本,当样本数较大时,计算量会很大。 240 | 241 | #### 2.3 随机梯度下降(Stochastic Gradient Descent) 242 | 243 | 将上面的步骤(3)改为: 244 | 245 | **3)** 随机选取某个样本$$x^{(i)}$$,则: 246 | 247 | 248 | $$ 249 | w^{(j+1)} \gets w^{(j)} - \eta ((w^{(j)})^T\cdot x^{(i)}-y^{(i)})x^{(i)} 250 | $$ 251 | 252 | 253 | 一直到迭代到足够的次数。 254 | 255 | -------------------------------------------------------------------------------- /zhi-chi-xiang-liang-ji.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhjunqin/MachineLearning/d2825a9fbcd9aed8e1f431ab18aa5dbba69bc986/zhi-chi-xiang-liang-ji.md --------------------------------------------------------------------------------