﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>语源科技BlogJava-Java, Only Java!</title><link>http://www.blogjava.net/zhuyuanxiang/</link><description /><language>zh-cn</language><lastBuildDate>Tue, 07 Apr 2026 05:26:21 GMT</lastBuildDate><pubDate>Tue, 07 Apr 2026 05:26:21 GMT</pubDate><ttl>60</ttl><item><title>Office 2010 经验总结</title><link>http://www.blogjava.net/zhuyuanxiang/archive/2019/09/20/434677.html</link><dc:creator>zYx.Tom</dc:creator><author>zYx.Tom</author><pubDate>Fri, 20 Sep 2019 01:41:00 GMT</pubDate><guid>http://www.blogjava.net/zhuyuanxiang/archive/2019/09/20/434677.html</guid><wfw:comment>http://www.blogjava.net/zhuyuanxiang/comments/434677.html</wfw:comment><comments>http://www.blogjava.net/zhuyuanxiang/archive/2019/09/20/434677.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhuyuanxiang/comments/commentRss/434677.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhuyuanxiang/services/trackbacks/434677.html</trackback:ping><description><![CDATA[<p>1. 如何设置蓝底白字？</p> <p>答：点击菜单项上的“页面布局”→“页面颜色”，就可以选择喜欢的页面颜色，字体颜色也会跟着发生改变。</p> <p>补充：如果不喜欢相应的页面颜色中系统自动设置的字体颜色，可以点击菜单项上的“开始”→“样式”→“正文”，设置“字体颜色”就可以了。</p> <p>&nbsp;</p> <p>2. 如何输入数学公式？</p> <p>答：使用Latex输入公式，不过语法与Latex稍有区别。Latex的“｛｝”功能使用“（）”替代了。熟悉Latex后，使用这个公式编辑器会觉得非常方便。对于数学公式的输入方法建议下载一个PDF文件《LATEX Mathematical Symbols》，里面都可以查到。</p> <p>❶开始输入公式：按住"Alt"再按"="，会出现了一个公式输入框，上方的工具栏也变成了公式编辑器栏。</p> <p>❷命令结构：命令是由反斜杠"\"开始的，紧跟着一串字符，以空格结束。例如：\alpha就会输入α。</p> <p>❸常见运算符：</p> <ul> <li>偏微分算子：“\partial”</li> <li>极限：“\limit”</li> <li>积分：“\int”</li> <li>求和：“\Sigma”</li> <li>梯度算子（也就是倒三角）：“\nabla ”</li> <li>点乘（如内积）：“\bullet”、“\cdot”</li> <li>叉乘（如外积、旋度）：“\times”</li> <li>字母上方的向量箭头："\hvec "。如果a是一个向量，那么"a\hvec&nbsp; "就能在a上方显示那个箭头，注意是两个空格！</li> <ul> <li>字母上方的其他符号（\bar, \check, \dot, \hat, \hvec, \vec, \tilde, etc…）</li></ul> <li>根号："\sqrt "</li></ul> <p>❹分式：就是普通的"/"，打完后按下空格就变上下格式了。为了保证将分母和分子都正确得框入，可以使用“（）”，括号打多了，系统会自动帮你去掉。 <ul> <li>如果输入(ab+c)/(d)。分子与分母的括号都会被自动去除。</li> <li>如果输入ab+c/d，那么得到的就是ab+(c/d)，括号是我添加为了区分含义的。</li></ul> <p>❺上下标：使用括号“（）”将需要上下标的内容包括起来。</p> <ul> <li>上标：“^”。</li> <li>下标：“_”。</li></ul> <p>❻符号连打：</p> <p>积分符号上下限，可以直接连着打"\int_a^b "。其中a为下限，b为上限。</p> <p>连续两个命令（或后面一个是运算符），可以直接连着打“\sqrt\pi”。 <p>❼对齐公式数组：可以使用<strong>@</strong>和<strong>&amp;</strong>来实现，如<code>\eqarray(x+1&amp;=2@1+2+3+y&amp;=z@3/x&amp;=6)&lt;space&gt;</code> <p>&nbsp; <p>❽数学公式转化成纯文本：选中数学公式，选择拷贝后，在记事本中粘贴，就可以得到公式的原始输入文本，就可以进行文本级别的数学公式修改了。 <ul> <li>MathML：数学标记语言，是一种基于X<em>ML</em>（标准通用标记语言的子集）的标准，用来在互联网上书写数学符号和公式的置标语言。</li> <li>线性格式：类似于Latex的文本，方便编辑。</li> <li>专业格式：显示成数学公式的方式，方便阅读。</li></ul> <p>&nbsp;</p> <p>自定义设置：点击菜单项中的“设计”→“公式”→“工具”就可以设置。</p> <ul> <li>自动将表达式转换到专业格式。缺点就是输入错误后不好再修改编辑，但是如果不自动更新，就需要自己写VBA对所有的数学公式进行全部更新。</li></ul><img src ="http://www.blogjava.net/zhuyuanxiang/aggbug/434677.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhuyuanxiang/" target="_blank">zYx.Tom</a> 2019-09-20 09:41 <a href="http://www.blogjava.net/zhuyuanxiang/archive/2019/09/20/434677.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《统计学习方法》的读书笔记</title><link>http://www.blogjava.net/zhuyuanxiang/archive/2019/09/17/434659.html</link><dc:creator>zYx.Tom</dc:creator><author>zYx.Tom</author><pubDate>Tue, 17 Sep 2019 01:39:00 GMT</pubDate><guid>http://www.blogjava.net/zhuyuanxiang/archive/2019/09/17/434659.html</guid><wfw:comment>http://www.blogjava.net/zhuyuanxiang/comments/434659.html</wfw:comment><comments>http://www.blogjava.net/zhuyuanxiang/archive/2019/09/17/434659.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhuyuanxiang/comments/commentRss/434659.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhuyuanxiang/services/trackbacks/434659.html</trackback:ping><description><![CDATA[<section class="page__content" itemprop="text"><aside class="sidebar__right sticky"><nav class="toc"><header> <h4 class="nav__title"><?XML:NAMESPACE PREFIX = "[default] http://www.w3.org/2000/svg" NS = "http://www.w3.org/2000/svg" /><svg role="img" aria-hidden="true" class="svg-inline--fa fa-book-reader fa-w-16" data-fa-i2svg="" viewbox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" data-icon="book-reader" data-prefix="fas"><path d="M352 96c0-53.02-42.98-96-96-96s-96 42.98-96 96 42.98 96 96 96 96-42.98 96-96zM233.59 241.1c-59.33-36.32-155.43-46.3-203.79-49.05C13.55 191.13 0 203.51 0 219.14v222.8c0 14.33 11.59 26.28 26.49 27.05 43.66 2.29 131.99 10.68 193.04 41.43 9.37 4.72 20.48-1.71 20.48-11.87V252.56c-.01-4.67-2.32-8.95-6.42-11.46zm248.61-49.05c-48.35 2.74-144.46 12.73-203.78 49.05-4.1 2.51-6.41 6.96-6.41 11.63v245.79c0 10.19 11.14 16.63 20.54 11.9 61.04-30.72 149.32-39.11 192.97-41.4 14.9-.78 26.49-12.73 26.49-27.06V219.14c-.01-15.63-13.56-28.01-29.81-27.09z" fill="currentColor"></path></svg><!-- <i class="fas fa-book-reader"></i> -->文章提纲</h4></header> <ul class="toc__menu"> <li><a href="#全书总评">全书总评</a>  <li><a href="#c01-统计学习方法概论">C01. 统计学习方法概论</a>  <ul> <li><a href="#统计学习">统计学习</a>  <ul> <li><a href="#统计学习导言">统计学习导言</a>  <li><a href="#统计学习的对象">统计学习的对象</a>  <li><a href="#统计学习的目的">统计学习的目的</a>  <li><a href="#统计学习的方法">统计学习的方法</a>  <li><a href="#统计学习的研究">统计学习的研究</a>  <li><a href="#统计学习的重要性">统计学习的重要性</a> </li></ul> <li><a href="#监督学习">监督学习</a>  <ul> <li><a href="#基本概念">基本概念</a>  <li><a href="#问题的形式化描述">问题的形式化描述</a> </li></ul> <li><a href="#统计学习三个要素">统计学习三个要素</a>  <ul> <li><a href="#模型">模型</a>  <li><a href="#策略">策略</a>  <li><a href="#算法">算法</a> </li></ul> <li><a href="#模型的评估与选择">模型的评估与选择</a>  <ul> <li><a href="#模型评估">模型评估</a>  <li><a href="#模型选择">模型选择</a> </li></ul> <li><a href="#正则化与交叉验证">正则化与交叉验证</a>  <ul> <li><a href="#正则化">正则化</a>  <li><a href="#交叉验证">交叉验证</a> </li></ul> <li><a href="#泛化能力">泛化能力</a>  <ul> <li><a href="#泛化误差">泛化误差</a>  <li><a href="#泛化误差的上界">泛化误差的上界</a> </li></ul> <li><a href="#生成模型与判别模型">生成模型与判别模型</a>  <li><a href="#分类问题">分类问题</a>  <li><a href="#标注问题">标注问题</a>  <li><a href="#回归问题">回归问题</a> </li></ul> <li><a href="#c02-感知机">C02. 感知机</a>  <li><a href="#c03--k-近邻法">C03. k 近邻法</a>  <li><a href="#c04-朴素-bayes-法">C04. 朴素 Bayes 法</a>  <li><a href="#c05-决策树-decision-tree">C05. 决策树 (decision tree)</a>  <li><a href="#c06-logistic-回归与最大熵模型">C06. Logistic 回归与最大熵模型</a>  <li><a href="#c07-支持向量机">C07. 支持向量机</a>  <li><a href="#c08-提升方法集成学习">C08. 提升方法（集成学习）</a>  <li><a href="#c09-em-算法及推广">C09. EM 算法及推广</a>  <li><a href="#c10-隐-markov-模型hmm的算法及推广">C10. 隐 Markov 模型（HMM）的算法及推广</a>  <li><a href="#c11-条件随机场crf的算法及推广">C11. 条件随机场（CRF）的算法及推广</a>  <li><a href="#c12-统计学习方法总结">C12. 统计学习方法总结</a>  <li><a href="#参考文献">参考文献</a>  <li><a href="#符号说明">符号说明</a> </li></ul></nav></aside> <h1 id="全书总评">全书总评</h1> <ul> <li>书本印刷质量：4 星。印刷清楚，排版合适，错误很少。  <li>著作编写质量：4 星。自学机器学习的必备。  <ul> <li>优点  <ul> <li>全书一直围绕着统计学习中的有监督学习描述，内容不深，基本算法都有所介绍；  <li>内容的组织是从抽象到具体的思维模式，比国外的教材易于理解；  <li>是自学统计学习和机器学习的推荐用书。 </li></ul> <li>缺点  <ul> <li>基础部分讲解缺少理论，学完后无法理解，不利用学以致用。例如：感知器的损失函数，应该是统计学习的核心思想，那么损失函数在整个算法中的位置，以及如何选择损失函数都需要说明清楚，才能够指导后面各种其他机器学习方法的理解。  <li>使用的方法没有导入的原因和出处，学习过程中会产生比较大的跳跃感，延续性不足。例如：随机梯度下降法，只是说明用于神经网络的优化需要用随机梯度下降，而实际上随机梯度下降是为了满足在线学习的需要，如果是批量学习可以直接使用梯度学习算法实现。 </li></ul> <li>总结：瑕不掩瑜，建议结合 “西瓜书” [周志华，2018] 一起看。 </li></ul> <li>笔记目的：记录重点，方便回忆。 </li></ul> <h1 id="c01-统计学习方法概论">C01. 统计学习方法概论</h1> <ul> <li>这一章都是概念和结论，如果读者能够透过概念就明白里面实际操作的内容，那就可以快速浏览此书，否则准备纸和笔认真精读方能收获。  <li>后面的各章内容相对独立，读者既可以连续学习，也可以仅选择自己感兴趣的内容。 </li></ul> <h2 id="统计学习">统计学习</h2> <h3 id="统计学习导言">统计学习导言</h3> <ul> <li>统计学习 (statistical learning): 计算机基于数据构建概率统计模型，并运用模型对数据进行预测与分析的一门学科。  <ul> <li>因此统计学习也称为统计机器学习 (statistical machine learning). </li></ul> <li>统计学习的主要特点  <ul> <li>理论基础  <ul> <li>数学基础：微积分、线性代数、概率论、统计学、计算理论、最优化理论  <li>其他基础：信息论、计算机科学及应用相关的科学等多个领域的交叉学科  <li>在发展中形成自己独立的理论体系与方法论。 </li></ul> <li>应用基础：计算机及网络；  <li>研究对象：数据，是数据驱动的学科；  <li>研究目的：对数据进行分类和预测；  <li>研究手段：通过统计学习方法构建模型，并应用模型进行分类和预测； </li></ul></li></ul> <h3 id="统计学习的对象">统计学习的对象</h3> <ul> <li>统计学习的对象是数据 (data)  <ul> <li>从数据出发，提取数据的 “特征” ，抽象出数据的 “模型” ，发现数据中的 “知识” ，又回到对数据的 “分类” 与 “预测” 中。  <li>数据的基本假设：同类数据具有一定的统计规律性，所以可以用概率统计方法加以处理。  <li>数据分类有 “连续型” 和 “离散型” 两种，本书主要关注的是 “离散型” 数据。 </li></ul></li></ul> <h3 id="统计学习的目的">统计学习的目的</h3> <ul> <li>模型：学习什么样的模型  <li>策略：如何学习模型 → 使模型能够对数据进行准确地分类和预测  <li>算法：如何提高模型的学习效率 </li></ul> <h3 id="统计学习的方法">统计学习的方法</h3> <ul> <li><strong>统计学习的方法分类</strong>  <ul> <li><strong>有监督学习 (supervised learning)</strong> （全书重点）  <ul> <li>从给定的、有限的、用于学习的训练数据 (training data) 集合出发；  <ul> <li>假设数据是独立同分布产生的； </li></ul> <li>假设要学习的模型属于某个函数的集合，称为假设空间 (hypothesis space);  <li>基于某个评价标准 (evaluation criterion), 从假设空间中选取一个最优的模型  <ul> <li>使模型在给定的评价准则下，对已知训练数据及未知测试数据 (test data) 都有最优的预测； </li></ul> <li>最优模型的选取都由算法实现。 </li></ul> <li>无监督学习 (unsupervised learning):  <li>半监督学习 (semi-supervised learning):  <li>强化学习 (reinforcement learning): </li></ul> <li>统计学习方法的三个要素  <ul> <li>模型 (model): 模型的假设空间；  <li>策略 (strategy): 模型选择的准则；  <li>算法 (algorithm): 模型学习的算法。 </li></ul> <li>实现统计学习方法的步骤  <ul> <li>得到一个有限的、用于训练的数据集合；  <li>模型的集合：确定包含所有可能的模型的假设空间；  <li>学习的策略：确定模型选择的准则；  <li>学习的算法：确定求解最优模型的算法；  <li>通过学习的方式选择出最优模型；  <li>利用学习的最优模型对新数据进行分类或预测。 </li></ul> <li>统计学习中的有监督学习根据 “解决的问题” 主要包括  <ul> <li><strong>分类问题</strong>：判别模型，处理离散数据  <li><strong>预测问题</strong>：回归模型，处理连续数据  <li>标注问题：既是分类问题的推广，又是预测问题的简化。 </li></ul></li></ul> <h3 id="统计学习的研究">统计学习的研究</h3> <ul> <li>统计学习方法 (statistical learning method): 开发新的学习方法；  <li>统计学习理论 (statistical learning theory): 探求统计学习方法的有效性与效率，以及统计学习的基本理论问题；  <li>统计学习应用 (application of statistical learning): 将统计学习方法应用到实际问题中去，解决实际问题。 </li></ul> <h3 id="统计学习的重要性">统计学习的重要性</h3> <ul> <li>是处理海量数据的有效方法；  <li>是计算机智能化的有效手段；  <li>是计算机科学发展的重要组成。 </li></ul> <h2 id="监督学习"><strong>监督学习</strong></h2> <ul> <li>监督学习的任务：是学习一个模型，使模型能够对任意给定的输入，及其相应的输出做出一个好的预测 </li></ul> <h3 id="基本概念">基本概念</h3> <ul> <li>输入空间：输入数据所有可能取值的集合；集合中元素的个数可以有限，也可以是整个空间；  <li>输出空间：输出数据所有可能取值的集合；集合中元素的个数可以有限，也可以是整个空间；  <li>假设空间：由输入空间到输出空间的映射的集合，即可供选择的模型构成的空间；  <li>特征空间：所有特征向量存在的空间。  <ul> <li>每个具体的输入是一个实例 (instance), 通常由特征向量 (feature vector) 表示。 </li></ul> <li>统计学习中的有监督学习根据 “输入变量” 和 “输出变量” 的不同主要包括  <ul> <li>分类问题：输出变量为有限个离散变量的预测问题；  <li>回归问题：输入变量与输出变量均为连续变量；  <li>标注问题：输入变量与输出变量均为变量序列的预测问题； </li></ul> <li>联合概率分布：输入变量与输出变量遵循联合分布； </li></ul> <h3 id="问题的形式化描述">问题的形式化描述</h3> <ul> <li>在学习过程中，学习系统（也就是学习算法）试图通过给定的训练数据集合中的样本带来的信息来学习得到模型。 </li></ul> <h2 id="统计学习三个要素">统计学习三个要素</h2> <ul> <li>统计学习方法 = 模型 + 策略 + 算法 </li></ul> <h3 id="模型">模型</h3> <ul> <li>主要问题：学习什么样的模型？  <li>模型的假设空间：包含所有可能的条件概率分布或决策函数，即由一个参数向量决定的函数族，也称为参数空间 (parameter space)。  <li>模型分类  <ul> <li>非概率模型：由决策函数表示的模型；  <li>概率模型：由条件概率表示的模型； </li></ul></li></ul> <h3 id="策略">策略</h3> <ul> <li>主要问题：按照什么样的准则，学习得到最优的模型，或者从假设空间中选择最优的模型。  <li>基本概念  <ul> <li>损失函数 (loss function) 或代价函数 (cost function): 度量模型一次预测的好坏；  <li>风险函数 (risk function) 或期望损失 (expected loss): 度量平均意义下模型预测的好坏。  <li>经验风险 (empirical risk) 或经验损失 (empirical loss): 表示模型与训练数据的破例程度，即模型训练样本集的平均损失，当样本容量趋于无穷时，经验风险逼近期望风险；  <li>结构风险 (structural risk): 表示模型先验知识，例如：模型复杂度的正则化项 (regularizer) 或惩罚项 (penalty term)。 </li></ul> <li>常用的损失函数  <ul> <li>0-1 损失函数  <li>平方损失函数  <li>绝对值损失函数  <li>对数损失函数或对数似然损失函数 </li></ul> <li>学习目标  <ul> <li>理想状态：就是选择期望风险或期望损失最小的模型，希望可以提供无限的数据训练；  <li>现实状态：就是选择经验风险或经验损失最小的模型，因为只能提供有限的数据训练； </li></ul> <li>经验风险矫正：当样本容量过小时，容易出现 “过拟合” 问题，所以需要对经验风险进行矫正，经验风险最小化 + 结构风险最小化  <ul> <li>经验风险最小化 (empirical risk minimization, ERM): 极大似然估计  <li>结构风险最小化 (structural risk minimization, SRM): 最大后验估计 </li></ul></li></ul> <h3 id="算法">算法</h3> <ul> <li>统计学习是基于训练数据集，根据学习策略，从假设空间中选择最优模型，最后需要考虑用什么样的计算方法求解最优模型。  <li><strong>算法</strong> 即计算方法。统计学习的算法就转化为求解最优化问题的算法。  <ul> <li>有显式的解析解的最优化问题；  <li>无显式的解析解的最优化问题，需要用数值计算的方法求解。  <ul> <li>如何保证找到全局最优解；  <li>如何保证求解的过程高效。 </li></ul></li></ul></li></ul> <h2 id="模型的评估与选择">模型的评估与选择</h2> <ul> <li>1.4~1.7, 与模型选择有关的问题。  <li>1.8~1.10, 与模型应用有关的问题。 </li></ul> <h3 id="模型评估">模型评估</h3> <ul> <li>学习方法评估的标准  <ul> <li>基于损失函数的模型的训练误差 (training error): 用来评估一个学习问题是否容易学习  <li>基于损失函数的模型的测试误差 (test error): 用来评估一个模型是否具备更有效的预测 </li></ul> <li>泛化能力 (generalization ability): 学习方法对未知数据的预测能力 </li></ul> <h3 id="模型选择">模型选择</h3> <ul> <li>过拟合 (over-fitting): 学习时选择的模型所包含的参数过多，以至于模型对已知数据预测较好，未知数据预测较差的问题  <li>模型选择的常用方法  <ul> <li>正则化  <li>交叉验证 </li></ul></li></ul> <h2 id="正则化与交叉验证">正则化与交叉验证</h2> <h3 id="正则化">正则化</h3> <ul> <li>正则化 (regularization): 结构风险最小化策略的实现，是在经验风险上加一个正则化项或惩罚项。  <ul> <li>正则化项一般是模型复杂度的单调递增函数。  <ul> <li>复杂度定义可以参考 Kolmogorov 复杂性理论 (complexity theory) [Haykin, 2011] P48 </li></ul> <li>Occam 剃刀原理：应用于模型选择时符合正则化的想法，即所有能够解释数据的模型中，复杂度越小越好。  <li>Bayes 估计：正则化项对应于模型的先验概率。数据较少时先验概率就可以抑制数据中噪声的干扰，防止出现过拟合问题。数据很多时，先验概率就让位于数据对模型的解释。  <li>正则化是优化学习算法，调整目标函数，增加先验知识的重要手段，是机器学习的核心之一。  <ul> <li>简单了解：[周志华，2018] P133  <li>深入理解：[Haykin, 2011] C07 </li></ul></li></ul></li></ul> <h3 id="交叉验证">交叉验证</h3> <ul> <li>交叉验证 (cross validation)  <ul> <li>在数据充足时，随机地将数据切分成三个部分：训练集、验证集和测试集。  <ul> <li>选择对验证集有最小预测误差的模型。 </li></ul> <li>训练集 (training set): 用来训练模型；  <li>验证集 (validation set): 用来选择模型；  <li>测试集 (test set): 用来评估模型。 </li></ul> <li>交叉验证的常用方法  <ul> <li>简单交叉验证：随机地将数据分成两个部分，70% 的数据为训练集，30% 的数据为测试集，选择测试误差最小的模型；  <li>S 折交叉验证  <ul> <li>随机地将数据分成 S 个互不相交的大小相同的部分  <li>然后利用 S-1 个部分的数据训练，1 个子集测试模型，  <li>再将这一个过程对所有可能的选择重复进行，  <li>最后选择 S 次评测中平均测试误差最小的模型。 </li></ul> <li>留一交叉验证：当 S=N 时采用的 S 折交叉验证，适用于数据极度缺乏的情况下。(N 为给定数据集的容量） </li></ul></li></ul> <h2 id="泛化能力">泛化能力</h2> <h3 id="泛化误差">泛化误差</h3> <ul> <li>泛化能力 (generalization ability): 是指学习方法学习到的模型对未知数据的预测能力  <li>泛化误差 (generalization error): 是指学到的模型对未知数据预测产生的误差，反映了学习方法的泛化能力。 </li></ul> <h3 id="泛化误差的上界">泛化误差的上界</h3> <ul> <li>泛化误差的上界 (generalization error bound): 泛化误差的概率上界，通过比较两种学习方法的泛化误差概率上界来确定优劣  <li>泛化误差上界的性质  <ul> <li>是样本容量的函数，当样本容量增加时，泛化上界趋向于 0;  <li>是假设空间的函数，当假设空间容量增加时，泛化误差上界就会变大，表示模型就更加难学。 </li></ul> <li><em>泛化误差上界定理及证明</em>（建议跳过） </li></ul> <h2 id="生成模型与判别模型">生成模型与判别模型</h2> <ul> <li>生成模型 (generative model): 模型表示了给定输入 X 产生输出 Y 的生成关系。  <ul> <li>特点  <ul> <li>还原出联合概率分布；  <li>学习收敛速度快；  <li>样本容量增加时，能够更好地逼近真实模型；  <li>存在隐变量时，仍然可以使用。 </li></ul> <li>应用：朴素 Bayes 方法和隐马尔可夫模型 (Hidden Markov Model, HMM);  <li>注：生成模型是比较难理解的概念，HMM 是理解生成模型比较好的途径，如果对 HMM 感兴趣可以参考  <ul> <li>简单了解：[周志华，2018] P320  <li>深入理解：[Rabiner, 1989] </li></ul></li></ul> <li>判别模型 (discriminative model): 由数据直接学习决策函数或者条件概率分布作为预测的模型  <ul> <li>特点  <ul> <li>直接学习得到条件概率分布或者决策函数；  <li>直接面对预测，学习的准确率更高；  <li>基于参数是直接学习得到的，因此可以对数据进行各种程度上的抽象、定义和使用特征，简化学习问题。 </li></ul> <li>应用：k 近邻法、感知机、决策树、Logistic 回归模型、最大熵模型、支持向量机、提升方法和条件随机场等 </li></ul></li></ul> <h2 id="分类问题">分类问题</h2> <ul> <li>分类器 (classifier): 监督学习从数据中学习得到的分类模型或分类决策函数。  <li>分类 (classification): 利用分类器对新输入的数据进行输出的预测。  <li>解决分类问题的两个过程  <ul> <li>学习过程：根据已知的训练数据集利用有效的“学习方法”得到一个分类器；  <li>分类过程：利用学习得到的分类器对新输入的实例进行分类。 </li></ul> <li>评价分类器性能的指标：分类准确率 (accuracy), 即对于给定的测试数据集，分类器正确分类的样本数与总样本数之比。  <ul> <li>二类分类问题常用的评价指标：精确率 (precision) 与召回率 (recall)。 </li></ul> <li>解决分类问题的常用方法：k 近邻法、感知机、朴素 Bayes 法，决策树、决策列表、Logistc 回归模型、支持向量机、提升方法等 </li></ul> <h2 id="标注问题">标注问题</h2> <ul> <li>标注问题：是分类问题的推广，也是更复杂的结构预测问题的简单形式。  <ul> <li>输入是一个观测序列；  <li>输出是一个标记序列或状态序列。  <li>目标是通过学习得到能够对观测序列给出标记序列作为预测的模型。 </li></ul> <li>解决标注问题的两个过程：学习过程 和 标注过程  <li>评价标注问题的指标：准确率、精确率和召回率。  <li>解决标注问题的常用方法：隐 Markov 模型和条件随机场。 </li></ul> <h2 id="回归问题">回归问题</h2> <ul> <li>回归 (regression): 用于预测输入变量（自变量）和输出变量（因变量）之间的关系。  <li>回归模型：表示从输入变量到输出变量之间的映射关系的函数。  <ul> <li>等价于：函数拟合。 </li></ul> <li>解决回归问题的两个过程：学习过程和预测过程。  <li>回归问题的分类  <ul> <li>按输入变量的个数：一元回归和多元回归；  <li>按输入变量和输出变量之间的关系：线性回归和非线性回归。 </li></ul> <li>回归学习最常用的损失函数：平方损失函数，求解平方损失函数可以用最小二乘法。 </li></ul> <h1 id="c02-感知机">C02. 感知机</h1> <ul> <li><strong>模型</strong>  <ul> <li>感知机，是根据输入实例的特征向量对其进行二类分类的线性分类模型，属于判别模型；  <li>模型参数包括：权值或权值向量，偏置。  <li>模型对应于输入空间（特征空间）中的分离超平面； </li></ul> <li><strong>策略</strong>  <ul> <li>假设：感知机学习的训练数据集是线性可分的；  <li>目标：求得一个能够将训练集正实例点和负实例点完全正确分开的分离超平面；  <li>策略：即定义（经验）损失函数，并将损失函数极小化；  <ul> <li>损失函数定义为：误分类点的总数，不易优化；  <li>损失函数定义为：误分类到分离超平面的总距离； </li></ul></li></ul> <li><strong>算法</strong>  <ul> <li>感知机学习算法是基于误差 - 修正的学习思想，是由误分类驱动的；  <li>学习算法的优化方法  <ul> <li>批量学习可以基于进行优化  <ul> <li>一阶：最速下降法或梯度下降法；  <li>二阶：牛顿法、共轭梯度法等等 </li></ul> <li>在线学习：基于随机梯度下降法的对损失函数进行最优化 [Goodfellow, 2017] P95, P180  <ul> <li>原始形式：算法简单且易于实现。先任意选取一个超平面，然后随机选择一个误分类点使其用梯度下降法极小化目标函数  <ul> <li><em>例 2.1</em>（比较简单，可以了解）  <li><em>定理 2.1</em>（过于简略，建议跳过） </li></ul> <li><em>对偶形式</em> （没看出与原始形式有何区别，也没从别的书上看到过这种说明方式，建议跳过） </li></ul></li></ul> <li>当训练数据集线性可分时，感知机学习算法是收敛的，且有无穷多个解。 </li></ul> <li><strong>学习总结</strong>  <ul> <li>感知机是神经网络的基础，本章只有单个神经元模型，深入学习参考 [Haykin, 2011]  <li>神经网络是深度学习的基础，深度学习参考 [Goodfellow, 2017]  <li>距离度量是几何的概念，理论可参考 [Duda, 2003] P154  <li>学习算法的优化是最优化理论，基本优化方法可参考 [Hyvarinen, 2007] P42 </li></ul></li></ul> <h1 id="c03--k-近邻法">C03. <strong>k</strong> <em>近邻法</em></h1> <ul> <li><strong>k</strong> 近邻法 (k-nearest neighbor, k-NN) 是一个基本且简单的方法，用于分类与回归。  <ul> <li>输入为实例的特征向量，对应于特征空间的点；  <li>输出为实例的类别，可以取多个类。 </li></ul> <li>基本思想  <ul> <li>假设给定一个训练数据集，其中的实例类别已经确定；  <li>对新输入的实例分类时，根据其 k 个最近邻的训练实例的类别，通过多数表决等方式进行预测。  <li>不具有显式的学习过程。  <li>实际上利用训练数据集对特征向量空间进行切分，并作为其分类的 “模型”。 </li></ul> <li><strong>k</strong> 近邻的模型  <ul> <li>对应于基于训练数据集对特征空间的一个划分。  <li>当训练集、距离度量、k 值及分类决策规则确定后，输入实例所属类别也唯一确定。 </li></ul> <li><strong>k</strong> 近邻法的三个要素  <ul> <li><strong>学习准则</strong>：距离度量，常用欧氏距离；（距离定义）[Duda, 2003]  <li>k 值的选择：反映了近似误差与估计误差之间的权衡。  <ul> <li>k 值越大时，近似误差会增大，估计误差会减小，模型也越简单；  <li>k 值越小时，近似误差会减少，估计误差会增大，模型也越复杂。  <li>可以用交叉验证的方式选择最优 k 值。 </li></ul> <li>分类决策规则：多数表决规则 (marjority voting rule), 等价于 经验风险最小化。 </li></ul> <li><strong>k</strong> <em>近邻法的实现基于 kd 树</em>。（了解即可，实际应用中大多使用的是已经成熟的软件包）  <ul> <li>kd 树是一种便于对 k 维空间中的数据进行快速检索的数据结构；  <li>kd 树是二叉树，表示对 k 维空间的一个划分；  <li>kd 树的每个圣战对应于 k 维空间划分中的一个超矩形区域；  <li>利用 kd 树可以省去对大部分数据点的搜索，从而减少搜索的计算量。 </li></ul> <li><strong>学习总结</strong>  <ul> <li>了解即可，因为面对高维问题效果很差，需要考虑降维操作。[周志华，2018] P225 </li></ul></li></ul> <h1 id="c04-朴素-bayes-法">C04. 朴素 Bayes 法</h1> <ul> <li>朴素 (naive) Bayes 法：是基于 Bayes 定理与所有特征都遵循条件独立性假设的分类方法。  <ul> <li>朴素 Bayes 法是 Bayes 分类法的一种，遵循 Bayes 定理建模。[Mitchell, 2003] P112  <li>朴素 Bayes 法基于的条件独立性假设是说用于分类的特征在类别确定的条件下都是条件独立的。简化了计算复杂度，牺牲了分类准确率。  <li>朴素 Bayes 法是生成学习方法。  <ul> <li>先验概率分布；  <li>条件概率分布；  <li>后验概率分布。后验概率最大化准则等价于期望风险最小化准则。  <li>目标：由训练数据学习联合概率分布； </li></ul> <li>朴素 Bayes 方法的<strong>概率参数估计</strong>方法：  <ul> <li><strong>极大似然估计</strong> : 概率估计常用的方法；  <li><strong>Bayes 估计</strong> : 重点在于了解与极大似然估计的差别，才可以正确使用。 </li></ul></li></ul> <li><strong>学习总结</strong>  <ul> <li>虽然不需要自己估计参数，但是对估计的理解很重要，书中的描述过于简单，具体内容请参考 [Duda, 2003] P67  <li>对于概念上的理解还可以参考 [周志华，2018] C07 </li></ul></li></ul> <h1 id="c05-决策树-decision-tree">C05. 决策树 (decision tree)</h1> <ul> <li><strong>决策树模型</strong>  <ul> <li>决策树是一种基本方法，用于分类与回归。  <ul> <li>本章主要讨论的是分类决策树。 </li></ul> <li>分类决策树模型  <ul> <li>定义：是基于特征对实例进行分类的树形结构。  <li>模型的组成结构  <ul> <li>结点 (node)  <ul> <li>内部结点 (internal node)  <li>叶结点 (leaf node) </li></ul> <li>有向边 (directed edge) </li></ul> <li>分类决策树可以转换成一个 if-then 规则的集合；  <ul> <li>决策树的根结点到叶结点的每一条路径构建一条规则；  <li>路径上内部结点的特征对应着规则的条件，而叶结点的类对应着规则的结论。  <li>重要的性质：互斥并且完备，即全覆盖。  <ul> <li>覆盖是指实例的特征与路径上的特征一致或实例满足规则的条件。 </li></ul></li></ul> <li>也可以看作是定义在特征空间与类空间上的条件概率分布。  <ul> <li>这个条件概率分布定义在特征空间的一个划分上，  <li>将特征空间划分为互不相交的单元或区域，  <li>并在每个单元定义一个类的概率分布就构成了一个条件概率分布。  <li>决策树分类时，将结点的实例分到条件概率大的类中。 </li></ul> <li>主要优点：可读性强，分类速度快。 </li></ul></li></ul> <li>决策树学习  <ul> <li>学习目的  <ul> <li>根据给定的训练数据集，构建一个与训练数据拟合很好，并且复杂度小的决策树，使之能够对实例进行正确的分类。  <li>决策树与训练数据的矛盾较小，同时还具有较好的泛化能力。  <li>也可以看作由训练数据集估计条件概率模型  <ul> <li>模型对训练数据拟合的效果很好；  <li>模型对未知数据有很好的预测。 </li></ul> <li>从所有可能的决策树中选取最优决策树是 NP 完全问题；  <ul> <li>现实中采用启发式方法学习次优的决策树。 </li></ul></li></ul> <li><strong>学习准则</strong>：损失函数最小化。  <ul> <li>损失函数是一种正则化的极大似然函数 </li></ul> <li><strong>学习算法</strong>  <ul> <li>递归地选择最优特征，并根据该特征对训练数据进行分割，使之对各个数据集有一个最好的分类的过程。 </li></ul></li></ul> <li>决策树的学习算法包括 3 个部分  <ul> <li>特征选择  <ul> <li>特征选择的目的在于选取对训练数据能够分类的特征，提高决策树学习的效率；  <li>特征选择的关键是其准则  <ul> <li>样本集合 D 对特征 A 的<strong>信息增益</strong> 最大  <ul> <li>信息增益定义为集合 D 的经验熵与特征 A 在给定条件下 D 的经验条件熵之差。  <ul> <li>熵：表示随机变量不确定性的度量。也称为经验熵。  <li>条件熵：定义为 X 给定条件下 Y 的条件概率分布的熵对 X 的数学期望。也称为经验条件熵。 </li></ul> <li>信息增益表示得知特征 X 的信息而使得类 Y 的信息的不确定性减少的程度。  <li>信息增益等价于训练数据集中类与特征的互信息。  <li>信息增益依赖于特征，信息增益大的特征具有更强的分类能力。 </li></ul> <li>样本集合 D 对特征 A 的<strong>信息增益比</strong> 最大  <ul> <li>为了避免信息增益对取值较多的特征的偏重，使用信息增益比来代替；  <li>信息增益比：特征 A 对训练数据集 D 的信息增益与训练数据集 D 关于特征 A 的值的熵之比。 </li></ul> <li>样本集合 D 的<strong>基尼指数</strong> 最小 </li></ul></li></ul> <li>树的生成  <ul> <li>计算指标，再根据准则选取最优切分点，从根结点开发，递归地产生决策树。  <li>通过不断地选择局部最优的特征，得到可能是全局次优的结果。 </li></ul> <li>树的剪枝：将已经生成的树进行简化的过程。  <ul> <li>目的：由于生成的决策树存在过拟合问题，需要对它进行剪枝，以简化学到的决策树。  <li>剪枝的准则：极小化决策树整体的损失函数或代价函数，等价于正则化的极大似然估计。  <li>剪枝的分类  <ul> <li>预剪枝：也叫分支停止准则。在决策树生成过程中，对每个结点在划分前先进行估计，若当前结点的划分不能带来决策树泛化性能提升，则停止划分并将当前结点标记为叶结点；  <li>后剪枝：先从训练集生成一棵完整的决策树，然后自底向上地对非叶结点进行考察，若将该结点对应的子树替换为叶结点能带来决策树泛化性能提升，则将该子树替换为叶结点。 </li></ul></li></ul> <li>常用的学习算法  <ul> <li>ID3: 在决策树的各个结点上应用信息增益准则选择特征，递归地构建决策树。相当于用极大似然法进行概率模型的选择。  <li>C4.5: 在决策树的各个结点上应用信息增益比准则选择特征，递归地构建决策树。  <li>CART: 既可用于分类，也可用于回归。  <ul> <li>等价于递归地二分每个特征，将输入空间即特征空间划分为有限个单元，并在这些单元上确定预测的概率分布，也就是在输入给定的条件下输出的条件概率分布。  <li>CART 算法的两个过程  <ul> <li>决策树生成：基于训练数据集生成决策树，要尽量大；  <ul> <li>回归树生成  <ul> <li>用平方误差最小准则求解每个单元上的最优输出值。  <li>回归树通常称为最小二乘回归树。 </li></ul> <li>分类树生成  <ul> <li>用基尼指数选择最优特征，并决定该特征的最优二值切分点。  <li>算法停止计算的条件  <ul> <li>结点中的样本个数小于预定阈值；  <li>样本集的基尼小于预定阈值； </li></ul></li></ul></li></ul> <li>决策树剪枝  <ul> <li>用验证数据集对已经生成的树进行剪枝，剪枝的标准为损失函数最小，基于标准选择最优子树。  <li>可以通过交叉验证法对用于验证的独立数据集上的子树序列进行测试，从中选择最优子树。 </li></ul> <li>[Duda, 2003] P320, CART 作为通用的框架，定义了 6 个问题 </li></ul></li></ul></li></ul></li></ul> <li>决策树的预测  <ul> <li>对新的数据，利用决策树模型进行分类。 </li></ul> <li><strong>学习总结</strong>  <ul> <li>算法 (5.1, 5.2, 5.6) + 例题 ( 5.1, 5.2, 5.3, 5.4 ) 通过算法和例题可以增强理解；  <li>损失函数的定义可以进一步参考 “不纯度” 指标 [Duda, 2003] P320, 或 “纯度” 指标 [周志华，2018] P75  <ul> <li>“不纯度” 指标是求极小值，可以跟梯度下降法等最优化理论结合。 </li></ul></li></ul></li></ul> <h1 id="c06-logistic-回归与最大熵模型">C06. Logistic 回归与最大熵模型</h1> <ul> <li>模型  <ul> <li>Logistic 回归模型，也称为对数几率回归模型，输入是的线性函数，输出的是对数几率模型  <ul> <li>基于 Logistic 分布建立的，表示条件概率的分类模型  <ul> <li>Logistic 分布是 Sigmoid 函数，<strong>定义 6.1</strong> </li></ul> <li>对数几率 (log odds) 或 logit 函数  <ul> <li>一个事件的几率 (odds) 是指该事件发生的概率与该事件不发生的概率的比值。 </li></ul> <li>二项 Logistic 回归模型是二类分类模型，<strong>定义 6.2</strong>  <li>多项 Logistic 回归模型是多类分类模型  <li>模型参数估计  <ul> <li>极大似然估计法 </li></ul></li></ul> <li>最大熵模型  <ul> <li>基于最大熵原理推导的，表示条件概率分布的分类模型，可以用于二类或多类分类。  <ul> <li>最大熵原理认为，在所有可能的概率模型（分布）的集合中，熵最大的模型是最好的模型。  <li><strong>准则</strong>：最大熵原理是概率模型学习或估计的一个准则。 </li></ul> <li>最大熵模型的学习  <ul> <li>最大熵模型的学习过程就是求解最大熵模型的过程  <li>最大熵模型的学习可以形式化为有约束的最优化问题（对偶问题）  <ul> <li>拉格朗日乘子参考附录 C </li></ul></li></ul> <li><strong>例 6.1, 6.2</strong> 方便理解最大熵模型的算法原理。 </li></ul></li></ul> <li><strong>算法</strong>  <ul> <li>学习采用极大似然估计或者正则化极大似然估计  <ul> <li>形式化为无约束最优化问题 </li></ul> <li>求解无约束最优化问题的算法  <ul> <li>迭代尺度法  <li>梯度下降法  <li>拟牛顿法 </li></ul></li></ul> <li><strong>学习总结</strong>  <ul> <li>Logistic 模型与最大熵模型都属于对数线性模型。[周志华，2018] C03  <li>极大似然估计：书里写的比较简单，没有原理性的说明，推荐（[周志华，2018] P149, [Duda, 2003] P67）  <li>模型学习的最优化算法：书里写的不太好理解。各种机器学习和模式识别的书里面都有介绍，推荐（[周志华，2018] P403, [Hagan, 2006] C09） </li></ul></li></ul> <h1 id="c07-支持向量机">C07. 支持向量机</h1> <ul> <li>支持向量机（Support Vector Machine， SVM）是一种二类分类模型。  <ul> <li>基本模型是定义在特征空间上的间隔最大的线性分类器  <li>基本概念  <ul> <li>支持向量决定了最优分享超平面  <ul> <li>最终判别时，只需要很少的“重要”训练样本，大幅减少计算量。 </li></ul> <li>间隔（看懂数学公式就可以理解间隔，判别在数据的维度上又增加了一个维度） </li></ul> <li>与其他模型的比较  <ul> <li>与感知机的区别：间隔最大化产生最优超平面；  <li>与线性模型的区别：使用核技巧成为非线性分类器。 </li></ul> <li>分类  <ul> <li>线性可分支持向量机，硬间隔支持向量机。  <li>线性支持向量机，软间隔支持向量机，是最基本的支持向量机。  <li>非线性支持向量机 </li></ul> <li>学习  <ul> <li>学习在特征空间进行的  <li>学习策略是间隔最大化 </li></ul></li></ul> <li>线性可分支持向量机 (linear support vector machine in linearly separable case)  <ul> <li>条件：训练数据线性可分；  <li>学习策略：硬间隔最大化  <ul> <li>求解能够正确划分训练数据集并且几何间隔最大的分离超平面  <li>对训练数据集找到几何间隔最大的超平面意味着以充分大的确信度对训练数据进行分类  <li>这样的超平面对未知原新实例有很好的分类预测能力 </li></ul> <li>解的特征  <ul> <li>最优解存在且唯一；（<em>唯一性证明</em>，建议跳过）  <li>支持向量由位于间隔边界上的实例点组成； </li></ul></li></ul> <li>线性支持向量机 (linear support vector machine)  <ul> <li>条件  <ul> <li>训练数据近似线性可分；  <li>训练数据中存在一些特异点 (outlier) </li></ul> <li>学习策略：软间隔最大化  <ul> <li>惩罚参数 C * 替代损失函数 f，表示误判的代价；  <ul> <li>hinge 损失（合页损失函数）：保持了稀疏性  <li>指数损失  <li>对率损失：相似于对率回归模型 </li></ul> <li>目标是使间隔尽量大，误分类点尽量少。 </li></ul> <li>解的特征  <ul> <li>权值唯一，偏置不唯一；  <li>支持向量由位于间隔边界上的实例点、间隔边界与分离超平面之间的实例点、分离超平面误分一侧的实例点组成；  <li>最优分享超平面由支持向量完全决定。 </li></ul></li></ul> <li>非线性支持向量机 (non-linear support vector machine)  <ul> <li>基本概念  <ul> <li>线性空间：满足线性性质的空间  <li>距离：是一种度量  <ul> <li>距离的集合 ⟶ 度量空间 + 线性结构 ⟶ 线性度量空间 </li></ul> <li>范数：表示某点到空间零点的距离  <ul> <li>范数的集合 ⟶ 赋范空间 + 线性结构 ⟶ 线性赋范空间 </li></ul> <li>内积空间：添加了内积运算的线性赋范空间  <ul> <li>线性赋范空间 + 内积运算 ⟶ 内积空间 </li></ul> <li>欧氏空间：有限维的内积空间  <li>希尔伯特空间：内积空间满足完备性，即扩展到无限维  <ul> <li>内积空间 + 完备性 ⟶ 希尔伯特空间 </li></ul> <li>巴拿赫空间：赋范空间满足完备性  <ul> <li>赋范空间 + 完备性 ⟶ 巴拿赫空间 </li></ul></li></ul> <li>条件：  <ul> <li>训练数据非线性可分；  <li>通过非线性变换（核函数）将输入空间（欧氏空间或离散集合）转化为某个高维特征空间（希尔伯特空间）中的线性可分；  <li>在高维特征空间中学习线性支持向量机。 </li></ul> <li>学习策略：核技巧 + 软间隔最大化 </li></ul> <li>最大间隔法  <ul> <li>间隔概念  <ul> <li>函数间隔：表示分类的正确性及确信度  <li>几何间隔：规范化后的函数间隔，实例点到超平面的带符号的距离 </li></ul> <li>分类  <ul> <li>硬间隔最大化 (hard margin maximization)  <li>软间隔最大化 (soft margin maximization) </li></ul> <li>间隔最大化的形式化  <ul> <li>求解凸二次规划问题  <ul> <li>最优化算法 </li></ul> <li>正则化的合页损失函数的最小化问题 </li></ul> <li>求解过程  <ul> <li>原始最优化问题应用拉格朗日对偶性；  <li>通过求解对偶问题得到原始问题的最优解。  <li>中间也可以根据需要自然引入核函数。 </li></ul></li></ul> <li>核技巧 (kernel method) 通用的机器学习方法  <ul> <li>应用条件  <ul> <li>非线性可分训练数据可以变换到线性可分特征空间；  <li>目标函数中的内积可以使用非线性函数的内积替换；  <li>非线性函数的内积可以使用核函数替换；  <li>核函数使非线性问题可解。 </li></ul> <li>常用的核函数  <ul> <li>线性核：对应于线性可分问题  <li>多项式核函数  <li>高斯核函数  <li>Sigmoid 核函数  <li>函数组合得到的核函数  <ul> <li>两个核函数的线性组合仍然是核函数，k1(x,z) 和 k2(x,z) 是核函数，c1 和 c2 是任意正数，则 k(x,z)=c1k1(x,z)+c2k2(x,z) 也是核函数。  <li>两个核函数的直积仍然是核函数，k1(x,z) 和 k2(x,z) 是核函数，则 k(x,z)=k1(x,z)k2(x,z) 也是核函数。  <li>k1(x,z) 是核函数，g(z) 是任意函数，则 k(x,z)=g(z)k1(x,z)g(z) 也是核函数。 </li></ul></li></ul></li></ul> <li>SMO 算法  <ul> <li>支持向量机学习的启发式快速算法  <li>流程  <ul> <li>将原二次规划问题分解为只有两个变量的二次规划子问题；  <ul> <li>第一个变量是违反 KKT 条件最严重的变量；  <li>第二个变量是使目标函数增长最快的变量；  <li>目标是使两个变量所对应样本之间的间隔最大。 </li></ul> <li>对子问题进行解析分解；  <li>直到所有变量满足 KKT 条件为止。 </li></ul></li></ul> <li><strong>学习总结</strong>  <ul> <li>支持向量机与神经网络是两大重要的机器学习算法；  <li>结合周老师的书一起看，对于理解支持向量机会有较大帮助。[周志华，2018] C06  <li>深入了解支持向量机的理论分析。[Haykin, 2011] C06 </li></ul></li></ul> <h1 id="c08-提升方法集成学习">C08. 提升方法（集成学习）</h1> <p>提升方法是一种统计学习方法，也是一种提升模型学习能力和泛化能力的方法，还是一种组合学习（集成学习）的方法，是统计学习中最有效的方法之一。</p> <ul> <li>为什么要将各种学习方法组合起来？  <ul> <li>强可学习方法与弱可学习方法的等价性；  <li>将各种弱可学习方法组合起来就可以提升 (boost) 为强可学习方法 </li></ul> <li>如何将各种学习方法组合起来？  <ul> <li>AdaBoost 算法  <ul> <li>是一种通用的组合算法，可以将各种分类算法进行组合。 </li></ul> <li>提升树  <ul> <li>以分类树或回归树为基本分类器的提升方法（组合算法）  <li>提升树是统计学习中性能最好的方法之一 </li></ul> <li>Bagging 算法（本章无介绍，了解请参考[周志华，2018] C8.3）  <ul> <li>随机森林 </li></ul></li></ul> <li>AdaBoost 算法  <ul> <li>模型：加法模型  <ul> <li>如何改变训练数据的权值和概率分布：采用 “分而治之” 的方法。提高那些被前一轮弱分类器错误分类的样本的权值，从而保证后一轮的弱分类器在学习过程中能够更多关注它们。  <li>如何将弱分类器组合成一个强分类器：采用 “加权多数表决” 的方法。加大分类误差率小的弱分类器的权值，从而保证它们在表决中起较大的作用。 </li></ul> <li>策略：指数损失函数极小化，即经验风险极小化。  <li>算法：前向分步算法来优化分步优化指数损失函数的极小化问题。  <li>算法的训练误差分析  <ul> <li>AdaBoost 能够在学习过程中不断减少训练误差，即减少训练数据集上的分类误差率。  <ul> <li>AdaBoost 的训练误差是以指数速率下降的。<em>定理与证明建议跳过</em> </li></ul></li></ul> <li>算法的优化过程分析  <ul> <li>因为学习的是加法模型，所以能够从前向后，每一步只学习一个基函数及基系数，逐步逼近优化目标函数，简化优化的复杂度。  <li><em>前向分步算法与 AdaBoost 的关系：定理与证明建议跳过。</em> </li></ul></li></ul> <li>提升树模型  <ul> <li>模型：加法模型，以决策树为基函数  <li>策略：损失函数  <ul> <li>分类问题：指数损失函数  <li>回归问题：平方误差函数  <li>一般决策问题：一般损失函数 </li></ul> <li>算法：前向分步算法  <ul> <li>梯度提升算法（GBDT）：解决离散数据的优化问题，原理参考、[Friedman, 2001] </li></ul></li></ul> <li><strong>学习总结</strong>  <ul> <li>学习基础  <ul> <li>熟悉重要的分类算法：神经网络和支持向量机  <li>熟悉常用的分类算法：k 近邻法和决策树 </li></ul> <li>学习目标  <ul> <li>组合各种分类算法，从而产生质量更好的学习能力和泛化能力模型 </li></ul> <li>胡思乱想  <ul> <li>全连接的深度神经网络就是理论上最完美的组合模型，问题在于维度灾难带来的计算复杂度问题。  <li>为了解决计算复杂度问题，就需要了解其他分类模型，因为其他分类模型就是具备了先验知识的神经网络模型，将那些分类模型转化为神经网络模型后就可以大幅减少连接的数量。  <li>概率近似正确 (probably approximately correct, PAC) 来自计算学习理论，可参考[周志华，2018] C12, [Mitchell, 2003] C07  <li>集成学习 (ensemble learning) 也被称为多分类器系统、基于委员会的学习等，可参考[周志华，2018] C08 </li></ul></li></ul></li></ul> <h1 id="c09-em-算法及推广">C09. EM 算法及推广</h1> <ul> <li>学习基础  <ul> <li>概率论：期望  <li>最大似然估计或极大后验估计  <li>梯度下降 </li></ul> <li>EM 算法是对含有隐变量的概率模型进行极大似然估计或者极大后验估计的迭代算法。  <ul> <li>E 步，求期望；利用数据和假设的初值，求得一个隐变量的条件概率分布的期望，即 “Q 函数”。（因为无法求得条件概率分布的具体值）  <li>M 步，求极值。利用 “Q 函数” 来求极值，这个极值可以帮助拟合的概率分布更加逼近真实分布。  <li><strong>Q 函数的定义</strong>（理解 Q 函数的涵义可以更好地推广到应用中，开始不理解也没关系，可以在应用中慢慢加深）  <li><strong>EM 算法的推导</strong>（如果书上的无法理解，还可以参考本文中的其他文献）  <ul> <li>EM 算法是收敛的，但是有可能收敛到局部最小值。  <li>EM 算法可以看成利用凸函数进行概率密度逼近；  <li>如果原概率密度函数有多个极值，初值的不同就可能逼近到不同的极值点，所以无法保证全局最优。 </li></ul> <li>EM 算法的应用（下面的两个应用都是重点，但是无法从本书中完全理解，可以在未来的应用继续探索）  <ul> <li><strong>高斯混合模型</strong>  <li><strong>HMM（隐 Markov 模型）</strong> 参考 C10 </li></ul> <li><em>EM 算法的推广</em>（建议跳过，对了解 EM 算法帮助不大，只有深入理解和研究 EM 算法才需要）  <ul> <li>F 函数的极大 - 极大算法  <li>广义 EM 算法（GEM） </li></ul></li></ul> <li><strong>学习总结</strong>  <li>EM算法的详细推导。[Borman, 2004], 或者Determined22的<a href="http://www.cnblogs.com/Determined22/p/5776791.html">EM算法简述及简单示例（三个硬币的模型）</a>  <li>EM算法的概率分析。[Friedman, 2001], 或者苏剑林的<a href="https://spaces.ac.cn/archives/4277">梯度下降和EM算法</a>  <li>EM算法的深入理解。可以参考史春奇的<a href="https://www.jianshu.com/p/bfa6b5947cd9">Hinton和Jordan理解的EM算法</a> </li></ul> <h1 id="c10-隐-markov-模型hmm的算法及推广">C10. <strong>隐 Markov 模型（HMM）的算法及推广</strong></h1> <ul> <li>学习基础  <ul> <li>随机过程：用于理解 Markov 链的数学含义  <li>EM 算法：用于计算 HMM 的学习问题 </li></ul> <li>Markov 链的定义  <ul> <li>随机过程  <ul> <li>研究对象是随时间演变的随机现象。[盛骤，2015] C12  <li>设 T 是一无限实数集，对依赖于参数 t（t 属于 T）的一族（无限多个）随机变量称为随机过程。  <li>我的理解  <ul> <li>随机过程在任一个时刻 t, 被观测到的状态是随机的，但是这个随机状态是由一个确定的函数控制的。  <li>例如：有 3 块金属放在箱子里面，任一个时刻 t 取出的金属是随机的，但是每块金属衰退的速度是由这块金属自身的函数控制的。  <li>随机变量刻画的是数值的随机性（某个数出现的概率），随机过程刻画的是函数的随机性（某个函数出现的概率） </li></ul></li></ul> <li>Markov 过程  <ul> <li>Markov 性或无后效性：过程（或系统）在时刻 t_0 所处的状态为已知的条件下，过程在时刻 t&gt;t_0 所处状态的条件分布与过程在时刻 t_0 之前所处的状态无关。即在已经知道过程“现在”的条件下，其“将来”不依赖于“过去”。[盛骤，2015] C13  <li>Markov 过程：具有 Markov 性的随机过程，称为 Markov 过程。 </li></ul> <li>Markov 链  <ul> <li>时间和状态都是离散的 Markov 过程称为 Markov 链，简称马氏链。  <li>深入理解可参考 [Rabiner, 1989] </li></ul> <li>HMM  <ul> <li>关于时序的概率模型  <li>用于描述一个被观测到的随机序列，这个随机序列是由不可观测的状态随机序列生成的，这个状态随机序列是由隐藏的 Markov 链随机生成的。  <ul> <li>状态序列 Q：隐藏的 Markov 链随机生成的状态序列；  <li>观测序列 O：每个状态生成一个观测，一个状态序列就会生成一个观测序列。  <li>序列的每一个位置都可以看作一个时刻。 </li></ul></li></ul></li></ul> <li>HMM 的基本假设  <ul> <li>齐次 Markov 假设，即假设隐藏的 Markov 链在任意时刻 t 的状态只依赖于前一个时刻的状态，而与其他时刻的状态及观测无关，也与时刻 t 无关；  <li>观测独立性假设，即假设任意时刻 t 的观测只依赖于该时刻的 Markov 链的状态，与其他观测与状态无关。 </li></ul> <li>HMM 的基本元素  <ul> <li>N，模型的状态数；  <li>M，每个状态生成的可观测的标志数；  <li>A，转移概率矩阵，a_{ij} 表示从状态 i 转移到状态 j 的概率；  <li>B，观测概率矩阵，b_{j} (k) 表示状态 j 产生标志 k 的概率；  <li>π，初始状态分布，π_i 表示一开始系统在状态 i 的概率。  <li>HMM 参数的数学表示：λ=(A, B, π) </li></ul> <li>HMM 的三个基本问题  <ul> <li>概率计算问题  <ul> <li>给定观测序列 O 和模型参数 λ，计算基于这个模型下观测序列出现的概率 P(O|λ) ； </li></ul> <li>预测问题  <ul> <li>给定观测序列 O 和模型参数 λ，寻找能够解释这个观测序列的状态序列，这个状态序列的可能性最大；  <li>除非是退化的模型，否则不会有“正确”的状态序列，因为每个状态序列都有可以生成观测序列；  <li>只可能是依据某个优化准则，使找到的状态序列尽可能的逼近真实的状态序列。 </li></ul> <li>学习问题  <ul> <li>给定观测序列 O，寻找能够解释这个观测序列的模型参数 λ，使得 P(O|λ) 最大。  <li>评测哪个模型能最好地解释观测序列。 </li></ul></li></ul> <li>HMM 的三个基本问题的解决方案  <ul> <li>概率计算问题：前向算法；  <ul> <li>先了解直接计算法，理解 HMM 需要计算的概率的方法和目的，同时明白直接计算法存在的问题；  <li>再了解前向算法，如果利用栅格方法叠加前面计算的成果，从而降低直接计算法的庞大计算量。 </li></ul> <li>预测问题：Viterbi 算法；  <li>学习问题：前向 + 后向算法 +EM 算法。  <ul> <li>利用前向 + 后向算法计算转移概率矩阵；  <li>再基于 MLE 理论构造 P(O|λ) 函数；  <li>因为函数中有三个参数不可知，无法直接计算得到，因为采用 EM 算法迭代求解。 </li></ul></li></ul> <li>HMM 的基本类型  <ul> <li>基本的 HMM 类型  <ul> <li>4 状态遍历 HMM；其他类型都是遍历 HMM 的特例。  <li>4 状态从左到右 HMM；  <li>6 状态从左到右并行路径 HMM。 </li></ul> <li>观测序列的密度是连续函数的 HMM：增加了混合高斯作为约束；  <li>自回归的 HMM：很适合语音处理；  <li>无输出的 HMM：即某些状态转移时无观测输出，主要用于语音识别；  <li>一组状态到另一组状态转换：组内状态无转移；  <li>优化准则：利用概率理论（ML）或信息理论（MMI，MDI）刻画；  <li>比较 HMM 模型：用于模型的测度和选择，常用的测度（交叉熵或散度或判别信息） </li></ul> <li>HMM 算法的具体实现方法  <ul> <li>观测数据的尺度化，方便计算机处理，防止溢出；  <li>HMM 模型的训练：通过多个观测序列进行训练，估计模型的参数；  <li>HMM 模型参数的初始值设定，没有形式化方法，只能凭借经验；  <li>观测数据数量过少，或者观测数据不完整  <ul> <li>扩大用于训练的观测集的大小（现实不可操作）；  <li>减少 HMM 模型的参数个数，即减小 HMM 模型的规模；  <li>利用插值的方法补齐或者增加数据。 </li></ul> <li>HMM 模型的选择  <ul> <li>确定 HMM 模型的状态（模型状态数，模型路径数）  <li>确定 HMM 观测的标志（连续还是离散，单个还是混合）  <li>无形式化方法，依赖于具体的应用。 </li></ul></li></ul> <li><strong>学习总结</strong>  <ul> <li>随机过程和 HMM 算法的基本概念的理解，特别是语音识别和语言处理方向的研究极为重要；  <li>HMM 算法的计算过程的了解，虽然可以调用成熟的模块，但是了解这个计算过程对于 HMM 计算的调优可能会有帮助；  <li>HMM 算法的学习极力推荐 [Rabiner, 1989]，本章的框架就是基于这篇文章写的。 </li></ul></li></ul> <h1 id="c11-条件随机场crf的算法及推广">C11. 条件随机场（CRF）的算法及推广</h1> <ul> <li>条件随机场（Conditional Random Field, CRF）的基本概念  <ul> <li>概率模型  <ul> <li>提供了一种描述框架，将学习任务归结于计算变量的概率分布。  <li>推断：利用已知变量推测未知变量的分布，核心是如何基于可观测变量推测出未知变量的条件分布。 </li></ul> <li>生成模型与判别模型  <ul> <li>生成 (generative) 模型  <ul> <li>考虑联合分布，是所有变量的全概率模型；  <li>由状态序列决定观测序列，因此可以模拟（“生成”）所有变量的值。  <li>具有严格的独立性假设；  <li>特征是事先给定的，并且特征之间的关系直接体现在公式中。  <li>优点  <ul> <li>处理单类问题比较灵活；  <li>模型变量之间的关系比较清楚；  <li>模型可以通过增量学习获得；  <li>可以应用于数据不完整的情况。 </li></ul> <li>缺点：模型的推导和学习比较复杂。  <li>应用  <ul> <li>n 元语法模型  <li>HMM  <li>Markov 随机场  <li>Naive Bayes 分类器  <li>概率上下文无关文法 </li></ul></li></ul> <li>判别 (discriminative) 模型  <ul> <li>考虑条件分布，认为由观测序列决定状态序列，直接对后验概率建模；  <li>从状态序列中提取特征，学习模型参数，使得条件概率符合一定形式的最优。  <li>特征可以任意给定，一般利用函数进行表示。  <li>优点：模型简单，容易建立与学习；  <li>缺点：描述能力有限，变量之间的关系不清晰，只能应用于有监督学习。  <li>应用  <ul> <li>最大熵模型  <li>条件随机场  <li>最大熵 Markov 模型 (maximum-entropy Markov model, MEMM)  <li>感知机 </li></ul></li></ul></li></ul> <li>概率图模型：是一类用图来表达变量相关关系的概率模型，  <ul> <li>有向图模型（Bayes 网）：使用有向无环图表示变量间的依赖关系，如：推导关系  <ul> <li>静态 Bayes 网络  <li>动态 Bayes 网络：适合处理一般图问题  <ul> <li>隐 Markov 模型：结构最简单的动态 Bayes 网，适合处理线性序列问题，可用于时序数据建模，主要应用领域为语音识别、自然语言处理等。 </li></ul></li></ul> <li>无向图模型（Markov 网）：使用无向图表示变量间的依赖关系，如：循环关系  <ul> <li>Markov 随机场：典型的 Makrov 网  <li>Boltzman 机  <li>通用条件随机场：适合处理一般图问题  <ul> <li>线性链式条件随机场：适合处理线性序列问题 </li></ul></li></ul></li></ul> <li>随机场： </li></ul> <li>概率图模型  <ul> <li>在概率模型的基础上，使用了基于图的方法来表示概率分布（或者概率密度、密度函数），是一种通用化的不确定性知识表示和处理的方法。  <li>图是表示工具  <ul> <li>结点表示一个或者一组随机变量  <li>结点之间的边表示变量间的概率依赖关系，即“变量关系图”。 </li></ul></li></ul> <li>Bayes 网络（信念网，信度网，置信网）  <ul> <li>目的：通过概率推理处理不确定性和不完整性问题  <li>构造 Bayes 网络的主要问题  <ul> <li>表示：在某一随机变量的集合上给出其联合概率分布。  <li>推断：因为模型完整描述了变量及其关系，可以推断变量的各种问题。  <ul> <li>精确推理方法：变量消除法和团树法  <li>近似推理方法：重要性抽样法、MCMC 模拟法、循环信念传播法和泛化信念传播法等 </li></ul> <li>学习：决定变量之间相互关联的量化关系，即储存强度估计。  <ul> <li>参数学习常用方法：MLE、MAP、EM 和 Bayes 估计法。  <li>结构学习： </li></ul></li></ul></li></ul> <li>Markov 随机场 (Markov Random Field, MRF)  <ul> <li>定义  <ul> <li>是一组有 Markov 性质的随机变量的联合概率分布模型，  <li>联合概率分布满足成对、局部和全局 Markov 性。  <li>由一个无向图 G 和定义 G 上的势函数组成。 </li></ul> <li>基本概念  <ul> <li>团 (clique)：是图中结点的一个子集，团内任意两个结点都有边相连。也称为完全子图 (complete subgraph)。  <li>极大团 (maximal clique)：若在一个团 C 中加入任何一个结点都不再形成团，就说那个团 C 是最大团。极大团就是不能被其他团所包含的团。  <li>因子分解 (factorization)：将概率无向图模型的联合概率分布表示为其最大团上的随机变量的函数的乘积形式的操作。  <li>分离集 (separating set)：若从结点集 A 中的结点到结点集 B 中的结点都必须经过结点集 C 中的结点，则称结点集 A 和 B 被结点集 C 所分离。  <li>全局 Markov 性：给定两个变量子集的分离集，则这两个变量子集条件独立  <ul> <li>局部 Markov 性：给定某变量的邻接变量，则该变量独立于其他变量  <li>成对 Markov 性：给定所有其他变量，两个非邻接变量条件独立 。 </li></ul> <li>势函数  <ul> <li>用于将模型进行参数化的参数化因子，称为团势能或者团势能函数，简称势函数。  <li>定义在变量子集上的非负实函数，主要用于定义概率分布函数，亦称“因子”。  <li>多个变量之间的联合概率可以基于团分解为多个因子的乘积。  <li>指数函数经常被用于定义势函数。 </li></ul></li></ul></li></ul> <li>条件随机场 (Conditional Random Field, CRF)  <ul> <li>用来处理标注和划分序列结构数据的概率化结构模型。  <li>是给定一组输入随机变量条件下另一组输出随机变量的条件概率分布模型  <ul> <li>假设输出随机变量构成 Makrov 随机场。 </li></ul> <li>线性链条件随机场  <ul> <li>输入序列对输出序列预测的判别模型  <li>形式为对数线性模型 </li></ul> <li>构造 CRF 的主要问题  <ul> <li>特征的选取  <li>参数训练  <li>解码 </li></ul> <li>优点：相比于 HMM 没有独立性要求，相比于条件 Markov 模型没有标识偏置问题。 </li></ul> <li><strong>学习总结</strong>  <ul> <li>本书的描述概念性内容过少，不利于理解，建议阅读 [周志华，2018] C14  <li>以概率图模型为基础来理解条件随机场会更加容易，也能够保证知识相互之间的联系，还可以加深对 HMM 的理解。  <li>CRF 的主要应用是自然语言处理，因此结合自然语言处理来理解概念也会更加深刻。 [宗成庆，2018] C06  <li>虽然国内几本书都写的不错，但是 CRF 都不是他们书中的重点，若想深入学习 CRF 还是请参考 [Sutton, 2012] </li></ul></li></ul> <h1 id="c12-统计学习方法总结">C12. 统计学习方法总结</h1> <p>10 种统计学习方法特点的概括总结</p> <table> <thead> <tr> <th><strong>方法</strong></th> <th><strong>适用问题</strong></th> <th><strong>模型特点</strong></th> <th><strong>模型类型</strong></th> <th><strong>学习策略</strong></th> <th><strong>学习的损失函数</strong></th> <th><strong>学习算法</strong></th></tr></thead> <tbody> <tr> <td>感知机</td> <td>二类分类</td> <td>分离超平面</td> <td>判别模型</td> <td>极小化误分点到超平面距离</td> <td>误分点到超平面距离</td> <td>随机梯度下降</td></tr> <tr> <td>K 近邻法</td> <td>多类分类，回归</td> <td>特征空间，样本点</td> <td>判别模型</td> <td>_<strong>__</strong>_</td> <td>_<strong>__</strong>_</td> <td>_<strong>__</strong>_</td></tr> <tr> <td>朴素贝叶斯</td> <td>多类分类</td> <td>特征与类别的联合概率分布区，条件独立假设</td> <td>生成模型</td> <td>极大似然估计，极大后验概率估计</td> <td>对数似然损失</td> <td>概率计算公式，EM 算法</td></tr> <tr> <td>决策树</td> <td>多类分类，回归</td> <td>分类树，回归树</td> <td>判别模型</td> <td>正则化的极大似然估计</td> <td>对数似然损失</td> <td>特征选择，生成，剪枝</td></tr> <tr> <td>逻辑斯蒂回归与最大熵模型</td> <td>多类分类</td> <td>特征条件下类别的条件概率分布，对数线性模型</td> <td>判别模型</td> <td>极大似然估计，正则化的极大似然估计</td> <td>逻辑斯蒂损失</td> <td>改进的迭代尺度算法，梯度下降，拟牛顿法</td></tr> <tr> <td>支持向量机</td> <td>二类分类</td> <td>分离超平面，核技巧</td> <td>判别模型</td> <td>极小化正则化的合页损失，软间隔最大化</td> <td>合页损失</td> <td>序列最小最优化算法 (SMO)</td></tr> <tr> <td>提升方法</td> <td>二类分类</td> <td>弱分类器的线形组合</td> <td>判别模型</td> <td>极小化加法模型的指数损失</td> <td>指数损失</td> <td>前向分布加法算法</td></tr> <tr> <td>EM 算法</td> <td>概率模型参数估计</td> <td>含隐变量概率模型</td> <td>_<strong>__</strong>_</td> <td>极大似然估计，极大后验概率估计</td> <td>对数似然损失</td> <td>迭代算法</td></tr> <tr> <td>隐马尔可夫模型</td> <td>标注</td> <td>观测序列与状态序列的联合概率分布模型</td> <td>生成模型</td> <td>极大似然估计，极大后验概率估计</td> <td>对数似然损失</td> <td>概率计算公式，EM 算法</td></tr> <tr> <td>条件随机场</td> <td>标注</td> <td>状态序列条件下观测序列的条件概率分布，对数线性模型</td> <td>判别模型</td> <td>极大似然估计，正则化极大似然估计</td> <td>对数似然损失</td> <td>改进的迭代尺度算法，梯度下降，拟牛顿法</td></tr></tbody></table> <h1 id="参考文献">参考文献</h1> <ul> <li>[Borman, 2004] Borman S. The expectation maximization algorithm-a short tutorial [J]. Submitted for publication, 2004, 41.  <li>[Charles, 2011] Charles Sutton and Andrew McCallum, An Introduction to Conditional Random Fields [J]. Machine Learning 4.4 (2011): 267-373.  <li>[Determined22, 2017] Determined22, <a href="http://www.cnblogs.com/Determined22/p/5776791.html">http://www.cnblogs.com/Determined22/p/5776791.html</a> , 2017.  <li>[Duda, 2003] Duda R O, Peter E Hart, etc. 李宏东等译。模式分类 [M]. 机械工业出版社。2003.  <li>[Friedman, 2001] Friedman, Jerome H. “Greedy Function Approximation: A Gradient Boosting Machine.” Annals of Statistics, vol. 29, no. 5, 2001, pp. 1189–1232.  <li>[Friedman, 2001] Friedman J, Hastie T, Tibshirani R. The elements of statistical learning [M]. New York: Springer series in statistics, 2001.  <li>[Goodfellow, 2017] Goodfellow I, Bengio Y, Courville A. 深度学习 [M]. 人民邮电出版社。2017.  <li>[Hagan, 2006] Martin T. Hagan. 戴葵等译。神经网络设计 [M]. 2002.  <li>[Haykin, 2011] Haykin S . 神经网络与机器学习 [M]. 机械工业出版社。2011.  <li>[Hyvarinen, 2007] Aapo Hyvarinen, Juha Karhunen. 周宗潭译 独立成分分析 [M]. 电子工业出版社。2007.  <li>[Mitchell, 2003] Tom M.Mitchell. 肖华军等译。机器学习 [M]. 机械工业出版社。2003  <li>[Rabiner, 1989] Rabiner L R. A tutorial on hidden Markov models and selected applications in speech recognition [J]. Proceedings of the IEEE, 1989, 77(2): 257-286.  <li>[Samuel, 2007] Samuel Karlin M.Taylor 著，庄兴无等译。 随机过程初级教程。 [M]. 人民邮电出版社， 2007.  <li>[Sutton, 2012] Sutton, Charles, and Andrew McCallum. “An introduction to conditional random fields.” Foundations and Trends® in Machine Learning 4.4 (2012): 267-373.  <li>[周志华，2018] 周志华 机器学习 [M]. 清华大学出版社。2018  <li>[苏剑林，2017] 苏剑林，<a href="https://spaces.ac.cn/archives/4277">https://spaces.ac.cn/archives/4277</a> , 2017.  <li>[盛骤，2015] 盛骤等编，概率论与数理统计（第四版）。 [M]. 高等教育出版社。 2015.  <li>[宗成庆，2018] 宗成庆著，统计自然语言处理（第二版）。 [M]. 清华大学出版社。 2018. </li></ul> <h1 id="符号说明">符号说明</h1> <ul> <li>Pxx，代表第 xx 页；  <li>Cxx，代表第 xx 章；  <li>[M]，代表图书；  <li>[J]，代表杂志； </li></ul></section><img src ="http://www.blogjava.net/zhuyuanxiang/aggbug/434659.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhuyuanxiang/" target="_blank">zYx.Tom</a> 2019-09-17 09:39 <a href="http://www.blogjava.net/zhuyuanxiang/archive/2019/09/17/434659.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《Python 数据科学实践指南》读书笔记</title><link>http://www.blogjava.net/zhuyuanxiang/archive/2019/03/19/433681.html</link><dc:creator>zYx.Tom</dc:creator><author>zYx.Tom</author><pubDate>Tue, 19 Mar 2019 04:51:00 GMT</pubDate><guid>http://www.blogjava.net/zhuyuanxiang/archive/2019/03/19/433681.html</guid><wfw:comment>http://www.blogjava.net/zhuyuanxiang/comments/433681.html</wfw:comment><comments>http://www.blogjava.net/zhuyuanxiang/archive/2019/03/19/433681.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhuyuanxiang/comments/commentRss/433681.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhuyuanxiang/services/trackbacks/433681.html</trackback:ping><description><![CDATA[<section class="page__content" itemprop="text"><aside class="sidebar__right sticky"><nav class="toc"><header> <h4 class="nav__title"><!-- <i class="fas fa-book-reader"></i> -->文章提纲</h4></header> <ul class="toc__menu"> <li><a href="#全书总评">全书总评</a>  <li><a href="#c01python-介绍">C01.Python 介绍</a>  <ul> <li><a href="#python-版本">Python 版本</a>  <li><a href="#python-解释器">Python 解释器</a>  <li><a href="#python-之禅">Python 之禅</a> </li></ul> <li><a href="#c02python-基础知识">C02.Python 基础知识</a>  <ul> <li><a href="#基础知识">基础知识</a>  <li><a href="#流程控制">流程控制：</a>  <li><a href="#函数及异常">函数及异常</a>  <ul> <li><a href="#函数">函数：</a>  <li><a href="#异常">异常</a> </li></ul> <li><a href="#字符串">字符串</a>  <ul> <li><a href="#获取键盘输入">获取键盘输入：</a>  <li><a href="#字符串处理">字符串处理</a>  <li><a href="#字符串操作">字符串操作</a>  <li><a href="#正则表达式">正则表达式</a> </li></ul></li></ul> <li><a href="#c05-容器container与集合collections">C05. 容器（Container）与集合（Collections）</a>  <ul> <li><a href="#元组tuple">元组（Tuple）</a>  <li><a href="#列表list">列表（List）</a>  <li><a href="#字典dictionary">字典（Dictionary）</a>  <li><a href="#集合collections">集合（Collections）</a> </li></ul> <li><a href="#c06python-标准库">C06.Python 标准库</a>  <ul> <li><a href="#数学模块math">数学模块：math</a>  <li><a href="#时间模块timedatetimecalendar">时间模块：time，datetime，calendar</a>  <li><a href="#随机数模块random">随机数模块：random</a>  <li><a href="#取样">取样：</a>  <li><a href="#文件处理glob-和-fileinput">文件处理：glob 和 fileinput</a>  <li><a href="#压缩bz2-和-gzip">压缩：bz2 和 gzip</a>  <li><a href="#漂亮打印pprint-模块">漂亮打印：pprint 模块</a>  <li><a href="#跟踪异常日志traceback-模块">跟踪异常日志：traceback 模块</a>  <li><a href="#网络数据传输json">网络数据传输：JSON</a> </li></ul> <li><a href="#c07-用-python-读写外部数据">C07. 用 Python 读写外部数据</a>  <ul> <li><a href="#csvcsv-模块">CSV，csv 模块</a>  <li><a href="#excelpandas-模块参考-c10">Excel，pandas 模块（参考 C10）</a>  <li><a href="#mysqlmysqldb-模块torndb-模块">MySQL，MySQLdb 模块，torndb 模块</a>  <li><a href="#postgresqlpsycopg2-模块">PostgreSQL，psycopg2 模块</a>  <li><a href="#mongodbpymongo-模块">MongoDB，pymongo 模块</a>  <li><a href="#elasticsearchelasticsearch-模块">ElasticSearch，elasticsearch 模块</a> </li></ul> <li><a href="#c08-用-python-解决统计问题">C08. 用 Python 解决统计问题</a>  <ul> <li><a href="#描述性统计">描述性统计</a>  <li><a href="#数据可视化">数据可视化</a> </li></ul> <li><a href="#c09-爬虫入门">C09. 爬虫入门</a>  <ul> <li><a href="#request-模块">request 模块</a>  <li><a href="#xpath-模块">Xpath 模块</a> </li></ul> <li><a href="#c10-数据科学的第三方库">C10. 数据科学的第三方库</a>  <ul> <li><a href="#numpy-模块">Numpy 模块</a> </li></ul> <li><a href="#从这里开始先弃了这本书适合了解了以后再来根据作者的实践角度查遗补缺">从这里开始，先弃了，这本书适合了解了以后，再来根据作者的实践角度查遗补缺。</a>  <ul> <li><a href="#pandas-模块">Pandas 模块</a>  <li><a href="#scikit-learn-模块">Scikit-Learn 模块</a>  <li><a href="#c11-图数据分析">C11. 图数据分析</a>  <li><a href="#图论基础">图论基础</a>  <li><a href="#networkx-模块">NetworkX 模块</a>  <li><a href="#利用-networkx-进行图分析">利用 NetworkX 进行图分析</a> </li></ul> <li><a href="#c12-大数据工具">C12. 大数据工具</a>  <ul> <li><a href="#hadoop">Hadoop</a>  <li><a href="#spark">Spark</a> </li></ul></li></ul></nav></aside> <h1 id="全书总评">全书总评</h1> <ul> <li>书本印刷质量：4 星。印刷清楚，排版合适，错误很少。  <li>著作编写质量：3 星。Python 入门和与数据处理相关的各种模块的入门，以及数据处理的入门。作者是原著，写的确实是自己的东西，不是东抄西抄。只是实践部分的内容实在太浅薄了些。  <li>代码质量：4星。Python入门这本书的IT功底不够，中间可能会碰到一些坑，最好有点Python基础以后，用这本书查遗补缺。<a href="https://github.com/magigo/data_science_tool_book_code">下载地址</a>  <li>阅读笔记：记录需要记住的重点，方便快速回忆。 </li></ul> <h1 id="c01python-介绍">C01.Python 介绍</h1> <h2 id="python-版本">Python 版本</h2> <ul> <li>Python 2.x：2001 年发布，有许多资料和库基于这个版本编写；  <li>Python 3.x：2009 年发布，与旧版本不兼容； </li></ul> <h2 id="python-解释器">Python 解释器</h2> <ul> <li>Python是开源的，因此它的解释器有许多种实现，主流的是<a href="https://www.python.org">官方的解释器</a>； </li></ul> <h2 id="python-之禅">Python 之禅</h2> <ul> <li>import this </li></ul> <h1 id="c02python-基础知识">C02.Python 基础知识</h1> <h2 id="基础知识">基础知识</h2> <ul> <li>基础数据类型：在 Python 中，所有的元素都是“对象”。  <ul> <li>None：表示什么都没有的类型；  <li>int：表示整数的类型；  <li>float：表示浮点数的类型；  <li>bool：表示布尔数值的类型；  <li>str：表示字符串的类型； </li></ul> <li>变量与赋值：Python 的书写规范（PEP8）  <ul> <li>序列解包 </li></ul> <li>操作符与表达式：  <ul> <li>算术操作符：  <li>位操作符：  <li>比较操作符：  <li>逻辑操作符：and，or，not </li></ul> <li>文本编辑器：  <ul> <li>文件编码：UTF-8 </li></ul></li></ul> <h2 id="流程控制">流程控制：</h2> <ul> <li>条件判断（if…elif…else…）：  <li>循环：  <ul> <li>while：  <li>for…in…： </li></ul> <li>缩进，空白与注释  <ul> <li>缩进：分割代码块；  <li>空白：没有任何意义，只为美观；  <li>注释：  <ul> <li>单行注释：“#”  <li>多行注释：”"”…””” </li></ul></li></ul></li></ul> <h2 id="函数及异常">函数及异常</h2> <h3 id="函数">函数：</h3> <ul> <li>函数定义：def func_name()  <li>参数定义：  <ul> <li>实参：  <li>形参：  <li>位置参数（参数绑定）：根据定义和调用函数时参数的位置进行参数的赋值；  <li>关键字参数：非关键字参数不能定义在关键字参数后面。  <li>可变数量的参数：def func(*args, **kwargs)  <ul> <li>*args：位置形参，表示任意数量的位置参数都会合并成一个元组，绑定到 args 上；  <li>**kwargs：关键字形参，表示任意数量的关键字参数都会合并成一个元组，绑定以 kwargs 上； </li></ul></li></ul> <li>递归：  <li>闭包（closure）：又称词法闭包（Lexical Closure）或函数闭包（Function Closure），是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在，即使已经离开了创建它的环境也不例外。 </li></ul> <h3 id="异常">异常</h3> <ul> <li>异常：（try…except…finally…） </li></ul> <h2 id="字符串">字符串</h2> <ul> <li>运算符：  <ul> <li>“+”：字符串拼接；  <li>“*”：字符串复制多份，然后拼接；  <li>切片 [start,stop,step]：  <li>len()：字符串长度； </li></ul></li></ul> <h3 id="获取键盘输入">获取键盘输入：</h3> <ul> <li>input(str)： </li></ul> <h3 id="字符串处理">字符串处理</h3> <ul> <li>字符集  <ul> <li>字符（Character）：是各种文字和符号的总称；  <li>字符集（Character Set）：是多个字符的集合，字符集的各类很多，每个字符集包含的字符个数也不同。  <li>字符编码（Character Encoding）：也称字集码，是把字符集中的字符编码按指定集合中的某一个对象，以便在计算机中存储和通过通信网络传递文本。 </li></ul> <li>ASCII 字符集和编码  <li>Unicode 字符集和 UTF-8 编码 </li></ul> <h3 id="字符串操作">字符串操作</h3> <ul> <li>基本操作：  <ul> <li>strip()：移除字符串两侧的所有空白符；  <li>capitalize()：使字符串的首字母大写；  <li>title()：使字符串中每个单词的首字母大写；  <li>lower()：使字符串的所有字母小写；  <li>upper()：使字符串的所有字母大写；  <li>isalnum()：字符串中包含字母或者数字时为 True；  <li>isdigit()：字符串中只包含数字时为 True； </li></ul> <li>分割：  <ul> <li>split(delimiter)：将字符串按指定分隔符分割；  <li>rsplit(delimiter)：将字符串从右边开始按指定分隔符分割； </li></ul> <li>格式化：  <ul> <li>%：print(‘%s’ %name)  <li>format()：print(‘{one} and {two}’.format(one=’1’,two=’2’)) </li></ul></li></ul> <h3 id="正则表达式">正则表达式</h3> <ul> <li>转义符：P55  <li>re 模块：  <ul> <li>re.compile()：匹配模式；  <ul> <li>match()：匹配字符串； </li></ul></li></ul></li></ul> <h1 id="c05-容器container与集合collections">C05. 容器（Container）与集合（Collections）</h1> <h2 id="元组tuple">元组（Tuple）</h2> <ul> <li>元组：与字符串一样，是有序的序列，不可以改变内容  <li>基本操作：连接、切片都与字符串保持一致；  <li>序列解包：也称多重赋值；  <li>支持迭代器协议，支持 for 循环 </li></ul> <h2 id="列表list">列表（List）</h2> <ul> <li>列表：也是序列类型的对象，但是可以改变列表中的内容；  <li>基本操作：连接、切片都与字符串保持一致；  <li>更改操作：  <ul> <li>pop()：删除列表中的数据，并将删除的数据返回；  <li>insert()：插入数据；  <li>append()：追加数据；  <li>extend()：拼接列表； </li></ul> <li>引用传递：所有的赋值都只是引用的传递，并没有创建新的数据；  <ul> <li>list[:]：浅拷贝，只拷贝第一层引用的数据；  <li>deepcopy()：深拷贝，拷贝所有引用的数据； </li></ul> <li>列表解析式：构造列表的方式，将一个函数作用到整个列表中每个元素的方式；[x for x in range(1,3)] </li></ul> <h2 id="字典dictionary">字典（Dictionary）</h2> <ul> <li>字典在其他语言中被称为散列表，由 key:value 对通过｛｝组成的无序结构。  <li>常用的函数：  <ul> <li>get(key)：通过 key 取得对应的 value；还可以通过链式调用取值；  <li>dict(list)：构建新的字典；  <li>dict.keys()：获取字典的 keys 迭代；  <li>dict.values()：获取字典的 values 迭代；  <li>dict.items()：获取字典的 key:value 对的迭代；  <li>dict.pop(key)：取出指定关键字的值；  <li>dict.update(key)：更新字典中对应的 key 中的 value； </li></ul></li></ul> <h2 id="集合collections">集合（Collections）</h2> <ul> <li>namedtuple()：具名元组。  <li>Counter()：累加器，可以用来做经典的 word count；  <li>defaultdict()：为字典设定一个默认值；  <li>OrderedDict()：使字典有序； </li></ul> <h1 id="c06python-标准库">C06.Python 标准库</h1> <h2 id="数学模块math">数学模块：math</h2> <ul> <li>常见常量：默认精度为 15 位，最多可以取得 48 位  <ul> <li>math.pi  <li>math.e </li></ul> <li>无穷大与无效数字：  <ul> <li>math.inf：表示“无穷大”，是 infinite 的缩写。math.inf*math.inf==math.inf  <li>math.nan：表示“无效数字”，是 Not a number 的缩写。math.inf/math.inf==math.nan  <li>int 的范围：在 3.5 中 int 长度理论上是无限的  <li>float 的范围：1e-309~1e+309 </li></ul> <li>浮点数转换为整数：  <ul> <li>math.trunc(f)：截掉浮点型小数点后面的数字；  <li>math.floor(f)：取最接近浮点型数字的整数；  <li>math.ceil(f)：取比当前浮点型数字大的整数； </li></ul> <li>绝对值和符号：  <ul> <li>math.fabs(f)：浮点数的绝对值；  <li>math.copysign(x,y)：符号函数，将 y 的符号传递给 x； </li></ul> <li>常用计算：  <ul> <li>math.fsum(values)：解决 sum(values) 不能精确计算的问题；  <li>math.factorial(x)：阶乘计算函数。 </li></ul> <li>指数和对数：  <ul> <li>math.pow(x,y)：x 的 y 次幂；  <li>math.log(x)：x 以 e 为底的对数；  <li>math.log10(x)：x 以 10 为底的对数； </li></ul></li></ul> <h2 id="时间模块timedatetimecalendar">时间模块：time，datetime，calendar</h2> <ul> <li>time 模块：基础的时间处理模块；  <ul> <li>time.time()：表示为数字时间戳，即从格林威治时间：1970-1-1，0：0：0（北京时间：1970-1-1，8：0：0）以来所经历过的秒数；  <li>time.ctime(x)：没有 x 则返回当前时间的字符串版本，有 x 则返回从时间戳开始经过了 x 秒后的时间的字符串。  <li>struct_time：具名元组，可以分别获得年 (tm_year)、月 (tm_mon)、当月第几日 (tm_mday)、时 (tm_hour)、分 (tm_min)、秒 (tm_sec)，星期几 (tm_way，星期一是 0)，当年第几天 (tm_yday)，是否夏令时 (tm_isdst，没有为 0)；  <ul> <li>time.gmtime()：格林威治下的 struct_time；  <li>time.localtime()：当前电脑所在时区的 struct_time；  <li>time.mktime(struct_time)：还原成数字时间戳的方式；  <li>time.strptime(string,format)：将字符串格式的时间按照格式转换成 struct_time 格式；  <li>time.strftime(format,struct_time)：将 struct_time 格式的时间元组转换成字符串格式； </li></ul></li></ul> <li>datetime 模块：针对年月日和时分秒分别进行处理；  <li>calendar 模块：处理万年历； </li></ul> <h2 id="随机数模块random">随机数模块：random</h2> <ul> <li>随机数生成器：  <ul> <li>random.random()：生成均匀分布的浮点随机数，在半开半闭区间 [0.0, 1.0)；  <li>random.seed()：设置随机数种子；  <li>random.randint(a,b)：返回整型随机数，在闭区间 [a,b]；  <li>random.randrange()：返回整型随机数，在半开半闭区间 [a,b)； </li></ul></li></ul> <h2 id="取样">取样：</h2> <ul> <li>random.shuffle(list)：按随机性质将列表重新排列顺序；  <li>random.choice(list)：按随机性质从列表中抽取数据；  <li>random.sample(list,k)：按随机性质从列表中抽取指定长度的数据； </li></ul> <h2 id="文件处理glob-和-fileinput">文件处理：glob 和 fileinput</h2> <ul> <li>open(filename,mode)：基于 mode 模式打开 filename 文件；还支持上下文管理器 with 模式；  <li>glob 模块：目录处理；  <li>fileinput 模块：批量文件读入；是一个帮助类； </li></ul> <h2 id="压缩bz2-和-gzip">压缩：bz2 和 gzip</h2> <ul> <li>不建议使用的压缩格式：  <ul> <li>rar：专门服务于 Windows 下，Python 需要第三方库才能打开；  <li>tar：只用于打包文件，不对文件进行压缩；  <li>zip：既可以压缩文件，还可以打包文件，因为自带打包功能，不适合用于对文件单独压缩； </li></ul> <li>建议使用的压缩格式  <ul> <li>bz2 模块：对单个文件可写可读，非常方便；  <li>gzip 模块：对单个文件可写可读，非常方便； </li></ul></li></ul> <h2 id="漂亮打印pprint-模块">漂亮打印：pprint 模块</h2> <h2 id="跟踪异常日志traceback-模块">跟踪异常日志：traceback 模块</h2> <h2 id="网络数据传输json">网络数据传输：JSON</h2> <ul> <li>json.loads()：将 JSON 转换成字典；  <li>json.dumps()：将字典转换成 JSON； </li></ul> <h1 id="c07-用-python-读写外部数据">C07. 用 Python 读写外部数据</h1> <h2 id="csvcsv-模块">CSV，csv 模块</h2> <ul> <li>csv.reader()：读取文件；  <li>csv.writer()：写入文件；  <li>csv.register_dialect()：delimiter= 注册分割符；  <li>csv.DictReader()：按照字典结构读取数据；* </li></ul> <h2 id="excelpandas-模块参考-c10">Excel，pandas 模块（参考 C10）</h2> <ul> <li>pandas.read_excel()：读取文件；  <li>pandas.to_excel()：写入文件；  <li>pandas.set_option()：设置属性值；  <li>pandas.DataFrame()：表格结构； </li></ul> <h2 id="mysqlmysqldb-模块torndb-模块">MySQL，MySQLdb 模块，torndb 模块</h2> <ul> <li>db=torndb.Connection(host,database,user,password)：建立数据库链接；  <li>db.insert(SQL),db.insertmany(SQL)：向数据库中插入单行数据，插入多行数据；  <li>db.query(SQL)：从数据库读取数据； </li></ul> <h2 id="postgresqlpsycopg2-模块">PostgreSQL，psycopg2 模块</h2> <h2 id="mongodbpymongo-模块">MongoDB，pymongo 模块</h2> <h2 id="elasticsearchelasticsearch-模块">ElasticSearch，elasticsearch 模块</h2> <h1 id="c08-用-python-解决统计问题">C08. 用 Python 解决统计问题</h1> <ul> <li>pandas 模块许多函数发生了改变；在 Python 3.7 下 read_excel() 运行有问题；统计都没办法测试了。 </li></ul> <h2 id="描述性统计">描述性统计</h2> <ul> <li>均值：  <li>中位数：  <li>方差：  <li>标准差： </li></ul> <h2 id="数据可视化">数据可视化</h2> <ul> <li>基本函数：  <ul> <li>plot()  <li>show()  <li>figure()  <li>title()  <li>xlabel()  <li>ylabel()  <li>legend() </li></ul> <li>图形：  <ul> <li>折线图：  <li>散点图：  <li>柱状图：bar()  <li>饼图：pie() </li></ul></li></ul> <h1 id="c09-爬虫入门">C09. 爬虫入门</h1> <h2 id="request-模块">request 模块</h2> <ul> <li>HTTP 协议：  <li>获取 HTML 内容： </li></ul> <h2 id="xpath-模块">Xpath 模块</h2> <ul> <li>解析 HTML 内容：  <li>这个模块已经没有匹配 Python3.7 的版本了，放弃这个学习。 </li></ul> <h1 id="c10-数据科学的第三方库">C10. 数据科学的第三方库</h1> <h2 id="numpy-模块">Numpy 模块</h2> <ul> <li>ndarray:  <ul> <li>创建：  <ul> <li>arange()  <li>linspace()：度量等宽  <li>random.random()：随机数 </li></ul> <li>属性：  <ul> <li>ndim：数组的维度；  <li>shape：数组的形状；  <li>dtype.name：数组中数据的类型；  <li>itemsize：数组类型占用的内存空间大小；  <li>size：数组中元素个数； </li></ul> <li>创建特定数组：  <ul> <li>zeros()：全零矩阵；  <li>ones()：全 1 矩阵；  <li>empty()：随机的小值组成的矩阵； </li></ul></li></ul> <li>基本运算：数组运算是基于元素计算的  <ul> <li>矩阵乘法：dot()  <li>迭代：与列表类似，直接迭代按行取数，flat() 可以把数组摊平为一维数组  <li>变形：resize() 原地修改数组；reshape() 输出一个变形后的数组，原数组不变；  <li>堆叠：hstack() 行数相同，水平堆叠；vstack() 列数相同，垂直堆叠； </li></ul> <li>高级运算  <ul> <li>transpose()：转置；  <li>linalg.inv()：取逆；  <li>eye()：单位阵；  <li>trace()：取迹；  <li>linalg.solve()：解线性方程；  <li>linalg.eig()：解特征方程； </li></ul></li></ul> <h1 id="从这里开始先弃了这本书适合了解了以后再来根据作者的实践角度查遗补缺">从这里开始，先弃了，这本书适合了解了以后，再来根据作者的实践角度查遗补缺。</h1> <h2 id="pandas-模块">Pandas 模块</h2> <h2 id="scikit-learn-模块">Scikit-Learn 模块</h2> <h2 id="c11-图数据分析">C11. 图数据分析</h2> <h2 id="图论基础">图论基础</h2> <h2 id="networkx-模块">NetworkX 模块</h2> <h2 id="利用-networkx-进行图分析">利用 NetworkX 进行图分析</h2> <h1 id="c12-大数据工具">C12. 大数据工具</h1> <h2 id="hadoop">Hadoop</h2> <h2 id="spark">Spark</h2></section><img src ="http://www.blogjava.net/zhuyuanxiang/aggbug/433681.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhuyuanxiang/" target="_blank">zYx.Tom</a> 2019-03-19 12:51 <a href="http://www.blogjava.net/zhuyuanxiang/archive/2019/03/19/433681.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《Python神经网络编程》的读书笔记</title><link>http://www.blogjava.net/zhuyuanxiang/archive/2019/03/19/433680.html</link><dc:creator>zYx.Tom</dc:creator><author>zYx.Tom</author><pubDate>Tue, 19 Mar 2019 04:03:00 GMT</pubDate><guid>http://www.blogjava.net/zhuyuanxiang/archive/2019/03/19/433680.html</guid><wfw:comment>http://www.blogjava.net/zhuyuanxiang/comments/433680.html</wfw:comment><comments>http://www.blogjava.net/zhuyuanxiang/archive/2019/03/19/433680.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhuyuanxiang/comments/commentRss/433680.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhuyuanxiang/services/trackbacks/433680.html</trackback:ping><description><![CDATA[<section class="page__content" itemprop="text"><aside class="sidebar__right sticky"><nav class="toc"><header> <h4 class="nav__title"><!-- <i class="fas fa-book-reader"></i> -->文章提纲</h4></header> <ul class="toc__menu"> <li><a href="#全书总评">全书总评</a>  <li><a href="#读书笔记">读书笔记</a>  <ul> <li><a href="#c01神经网络如何工作">C01.神经网络如何工作？</a>  <li><a href="#c02使用python进行diy">C02.使用Python进行DIY</a>  <li><a href="#c03开拓思维">C03.开拓思维</a>  <li><a href="#附录a微积分简介">附录A。微积分简介</a>  <li><a href="#附录b树莓派">附录B。树莓派</a> </li></ul></li></ul></nav></aside> <h1 id="全书总评">全书总评</h1> <ul> <li>书本印刷质量：4星。纸张是米黄色，可以保护眼睛；印刷清楚，文字排版整洁，基本没有排版过程中引入的错误，阅读不累眼睛。但是可能是Word排版，感觉数学公式的排版不是太好。  <li>著作编写质量：4星。简单，易懂，入门很好。可能是为了帮助读者克服对数学的恐惧，所以多用图来说明。但是，没有数学的神经网络本质上还是空中楼阁，过于淡化数学的作用反而使推导部分读起来费劲。  <li>著作翻译质量：3星。没有明显的问题，基本使用的都是业界常用词汇。其实给3~4星我都在犹豫，因为翻译本身没有错误，作者也不是靠机翻了事，但是作为一本入门图书，过于长的句子（英文表述的风格）使人经常会看着看着就从书中“出戏”了，影响思绪的连贯性。  <li>代码质量：4星。代码问题不大，还可以去GitHub下载。<a href="https://github.com/makeyourownneuralnetwork/makeyourownneuralnetwork">作者的GitHub</a>，热心读者的<a href="https://github.com/hzka/PythonNetworkBook">GitHub</a>和<a href="https://blog.csdn.net/weixin_38244174/article/details/85195851">CSDN-Blog</a>  <li>总结：如果还想进一步了解神经网络，请移步<a href="《神经网络与机器学习》-读书-笔记">《神经网络与机器学习》</a>；如果想进一步了解Python，请稳步<a href="Python-书籍-总结">Python书籍总结</a>。如果想进入机器学习的行业，还是找机会精读一遍《高等数学》、《线性代数》和《概率统计》吧，对于后期了解原理绝对是有好处的。 </li></ul> <h1 id="读书笔记">读书笔记</h1> <h2 id="c01神经网络如何工作">C01.神经网络如何工作？</h2> <ol> <li>计算机能干啥？打游戏、听音乐、看视频，还可以图像识别、知识推理等等。  <li>预测机能干啥？不是程序员教的知识，而通过学习得到的知识，用来处理未来的问题  <li>分类器能干啥？对数据进行区分，例如：苹果与香蕉，通过学习，找出它们的特征，从而学会分辨  <li>分类器如何训练（学习）？先学习正确的知识，如果结果不对就调整记忆，最终全部答对正确的知识  <li>分类器如何解决更为复杂的问题？多个学习单元一起学习  <li>神经元的基本原理：计算机的神经网络只是生物神经元的仿真，或者叫数学解释，或者叫计算机模拟。  <li>信号在神经网络中如何流动？  <li>怎样简化神经网络的表示：矩阵。  <li>使用矩阵乘法来表示三层神经网络的例子。  <li>神经元的权重如何学习？基本原理  <li>★反向传播误差算法（11~13）  <ul> <li>多层神经网络的误差是如何反向传播的？  <li>误差如何反向传播到更多层中？  <ul> <li>简单的3层神经网络：输入层+隐藏层+输出层，误差如何在隐藏层中传播来修改权重。 </li></ul> <li>如何使用矩阵乘法来描述反向传播误差？ </li></ul> <li>如何更新神经网络的权重？数学算法（梯度下降）  <li>权重更新的具体案例。  <li>神经网络训练的过程：输入（准备训练数据）、权重（随机初始化）、输出（误差函数优化） </li></ol> <h2 id="c02使用python进行diy">C02.使用Python进行DIY</h2> <ol> <li>Python是啥？一种非常利于阅读的编程语言，适合非计算机专业人员学习和使用  <li>IPython是啥？交互式Python。  <li>Python怎么用？就是帮你基本了解Python，方便后面看Python代码。  <li>使用Python制作神经网络：进入正题了，跟着作者输入一遍代码，可以加深理解。  <li>数据集MNIST：进入真正的实用项目了。  <ol> <li>输入完整的代码；（有地方看不懂，是因为书中给出的Python说明远远不够，但是别在意这些不懂，继续前进，先明白神经网络可以干啥）  <li>用小的数据集训练和测试神经网络，会发现对于复杂一点的样本就无法正常识别了；  <li>使用完整的数据集训练和测试神经网络，这次耗时有点长，但是准确率会大大提升，看样子多花点时间学习是值得的；  <li>一点改进：调整学习率，会发现效果不一样了，为什么呢？具体原理可以参考《神经网络与机器学习》  <li>一点改进：多次运行，同样的训练数据再学习一次还能够提高识别率，但是如果次数过多会出现过拟合，参考《神经网络与机器学习》；  <li>一点改变：调整隐藏层的节点数目，可能会影响识别率（P146，图），参考《神经网络与机器学习》； </li></ol></li></ol> <h2 id="c03开拓思维">C03.开拓思维</h2> <ol> <li>自己创造数据：用画图软件创造一个图片用于识别，图片大小必须是（28*28）像素格式的；  <li>神经网络的秘密：  <ol> <li>神秘的黑盒子：像人一样有冗余能力，少量的损失只会影响精度，不会完全失去能力；  <li>逆向查询：把输出变输入，输入变输出，可以发现神经网络到底从数据中学到了什么； </li></ol> <li>创建新的训练数据：真实情况下数字可能是扭曲的、旋转的、不规范的，创造这样的数据试试网络的识别率，想想识别不出的原因？ </li></ol> <h2 id="附录a微积分简介">附录A。微积分简介</h2> <p>如果你对大学数学心存恐惧，那么试着读读这本书中的微积分介绍，可能会帮助你理解极限和求导，甚至还有高阶的链式法则，至少让你心里觉得原来高等数学没有想像中的那么难。</p> <p>当然，学习数学依然还是考验毅力的一项活动，一本数学书看个一年都是常事，数学专业的同学常说“实变函数学十遍，泛函分析胆泛寒”。</p> <h2 id="附录b树莓派">附录B。树莓派</h2> <p>这个对于中国同学似乎用处不大，中国人民突然变得钱多多起来，电脑已经是上大学的标配了。当然如果有时间，试着玩玩还是很有趣的，而且树莓派的应用范围非常广泛，学了不吃亏。</p></section><img src ="http://www.blogjava.net/zhuyuanxiang/aggbug/433680.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhuyuanxiang/" target="_blank">zYx.Tom</a> 2019-03-19 12:03 <a href="http://www.blogjava.net/zhuyuanxiang/archive/2019/03/19/433680.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《软件开发与创新》的读书笔记</title><link>http://www.blogjava.net/zhuyuanxiang/archive/2019/03/19/433678.html</link><dc:creator>zYx.Tom</dc:creator><author>zYx.Tom</author><pubDate>Tue, 19 Mar 2019 03:57:00 GMT</pubDate><guid>http://www.blogjava.net/zhuyuanxiang/archive/2019/03/19/433678.html</guid><wfw:comment>http://www.blogjava.net/zhuyuanxiang/comments/433678.html</wfw:comment><comments>http://www.blogjava.net/zhuyuanxiang/archive/2019/03/19/433678.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhuyuanxiang/comments/commentRss/433678.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhuyuanxiang/services/trackbacks/433678.html</trackback:ping><description><![CDATA[<section class="page__content" itemprop="text"><aside class="sidebar__right sticky"><nav class="toc"><header> <h4 class="nav__title"><!-- <i class="fas fa-book-reader"></i> -->文章提纲</h4></header> <ul class="toc__menu"> <li><a href="#全书总评">全书总评</a>  <li><a href="#读书笔记">读书笔记</a>  <ul> <li><a href="#c3面向对象程序设计对象优于类">C3.面向对象程序设计：对象优于类</a>  <li><a href="#其他等需要的时候再看">其他等需要的时候再看。。。</a> </li></ul></li></ul></nav></aside> <h2 id="全书总评">全书总评</h2> <ul> <li>书本印刷质量：4星。纸张稍有点薄，当然印刷清楚，文字排版合适，基本没有排版过程中引入的错误，阅读不累眼睛。  <li>著作编写质量：4星。各位大牛应编书的需要，针对“软件开发与创新”这个方向，写了点自己的总结。主要包括：软件开发的语言、软件开发过程中的测试、软件开发中遇到的其他问题以及如何进行数据可视化。  <li>著作翻译质量：4星。都是行内人翻译的作品，本身又都是独立文集，因此翻译的工作量不算太大，因此质量还是可以保证的。  <li>代码质量：4星。其实里面没多少代码，只有些代码片断，也是用来说明文章的内容的。对那个语言的熟悉的同学，阅读起来没压力，不熟悉的话就只有跳过了。 </li></ul> <h2 id="读书笔记">读书笔记</h2> <h3 id="c3面向对象程序设计对象优于类">C3.面向对象程序设计：对象优于类</h3> <ul> <li>类关注：驱动力是以业务可识别的方式对领域进行建模。就是关注角色：人事经理、财务经理等等。  <li>对象关注：运行时和对象之间的关联与交互将成为设计背后的运动驱动力。就是关注责任：人事管理、财务管理等等。  <ul> <li>对象关注促使设计人员更主动地思考责任的归属是类还是对象，方便将不同的责任赋予同一个对象，例如：小的公司人事和财务管理都是一个人。  <li>对象关注驱动着对代码的测试。通过不断考虑运行时的场景，从而渐进地构建领域模型，实现领域驱动设计。  <li>对象关注使接口得到广泛应用，通过使用Mock框架可以实现角色分离的测试。参考<a href="">Mock Roles, Not Objects[FPMW04]</a>。  <li>对象关注促使考虑系统中是否多个对象彼此交互，确保每个对象都有活干，从而构建出一个健康的系统。（不要忙的忙死，闲的闲死） </li></ul></li></ul> <p>程序设计中典型安全就是Java的Calendar API，过多关注类导致笨重；大家喜欢Joda Time，更加简洁，更加面向对象。</p> <h3 id="其他等需要的时候再看">其他等需要的时候再看。。。</h3></section><img src ="http://www.blogjava.net/zhuyuanxiang/aggbug/433678.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhuyuanxiang/" target="_blank">zYx.Tom</a> 2019-03-19 11:57 <a href="http://www.blogjava.net/zhuyuanxiang/archive/2019/03/19/433678.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《神经网络算法与实现-基于Java语言》的读书笔记</title><link>http://www.blogjava.net/zhuyuanxiang/archive/2019/03/19/433677.html</link><dc:creator>zYx.Tom</dc:creator><author>zYx.Tom</author><pubDate>Tue, 19 Mar 2019 03:51:00 GMT</pubDate><guid>http://www.blogjava.net/zhuyuanxiang/archive/2019/03/19/433677.html</guid><wfw:comment>http://www.blogjava.net/zhuyuanxiang/comments/433677.html</wfw:comment><comments>http://www.blogjava.net/zhuyuanxiang/archive/2019/03/19/433677.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhuyuanxiang/comments/commentRss/433677.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhuyuanxiang/services/trackbacks/433677.html</trackback:ping><description><![CDATA[<section class="page__content" itemprop="text"><aside class="sidebar__right sticky"><nav class="toc"><header> <h4 class="nav__title"><!-- <i class="fas fa-book-reader"></i> -->文章提纲</h4></header> <ul class="toc__menu"> <li><a href="#全书总评">全书总评</a>  <li><a href="#读书笔记">读书笔记</a>  <ul> <li><a href="#c1初识神经网络">C1.初识神经网络</a>  <li><a href="#c2神经网络是如何学习的">C2.神经网络是如何学习的</a>  <li><a href="#c3有监督学习运用感知机">C3.有监督学习（运用感知机）</a>  <li><a href="#c4无监督学习自组织映射">C4.无监督学习（自组织映射）</a>  <li><a href="#rreferences参考文献">Rreferences（参考文献）</a> </li></ul></li></ul></nav></aside> <h2 id="全书总评">全书总评</h2> <ul> <li>书本印刷质量：5星。纸张很白，印刷清楚，文字排版合适，基本没有排版过程中引入的错误，阅读不累眼睛。  <li>著作编写质量：3星。入门书，看完后可能会对神经网络有个基本概念，但是也可能就只有个基本概念。基本概念描述还是清楚的，还给出了比较好的参考资料。几个例子讲的很浅，好处就是提供了代码，如果有开发方向的需要可以参考。深入学习神经网络还是参考<a href="https://book.douban.com/subject/5952531/">《神经网络和机器学习》</a>这本书吧。  <li>著作翻译质量：4星。用的都是常用词汇。对于不了解神经网络的读者，通过本书了解一些基本概念，为将来学习其他书籍打下基础；对于了解神经网络的读者不会造成概念混淆。  <li>代码质量：3星。基本没错误，但是思路跟书上不完全匹配。比如说：感知机一般都是单层的，就是一个神经元，一个偏置量，两个输入的值，一个输出的值，两个权值。但是作者在测试代码中放入两个输入权值，一个输出权值，不明白，后面都是这样的思路，于是只好弃了。 </li></ul> <h2 id="读书笔记">读书笔记</h2> <h3 id="c1初识神经网络">C1.初识神经网络</h3> <p>基本概念：人工神经元，激活函数，权值，偏置，层。</p> <p>神经网络结构：</p> <ul> <li>神经元连接  <ul> <li>单层神经网络：单层感知机，自适应机，自组织映射、Elman网络和Hopfield网络。  <li>多层神经网络：多层感知机，径向基函数。 </li></ul> <li>信号流  <ul> <li>前馈神经网络：多层感知机，径向基函数。  <li>反馈神经网络：单层的（Elman网络和Hopfield网络）和多层的（递归多层感知机和Echo网络）。 </li></ul></li></ul> <h3 id="c2神经网络是如何学习的">C2.神经网络是如何学习的</h3> <p>学习范式：</p> <ul> <li>有监督学习：  <ul> <li>描述：已知的数据集与学习得到的结果之间的误差最小，最小的评价基于某个代价函数。  <li>应用：图像分类，语音识别，函数逼近和趋势预测。 </li></ul> <li>无监督学习：  <ul> <li>描述：从已知的数据集提取知识，即将数据集分类，类间距离大，类内距离小，评价基于某个代价函数。  <li>应用：聚类分析，数据压缩，统计建模和语言建模。 </li></ul></li></ul> <p>学习算法：</p> <ul> <li>两个阶段：训练和测试。  <li>重要细节：参数。  <li>评价方式：误差度量和代价函数。  <li>例子：Perceptron 感知机和Delta规则。 </li></ul> <h3 id="c3有监督学习运用感知机">C3.有监督学习（运用感知机）</h3> <ul> <li>单层感知机的作用和局限性：解决线性可分问题，不能解决非线性问题。  <li>多层感知机（MLP）：  <ul> <li>层：  <ul> <li>输入层：  <li>隐藏层：激活函数一般选择双曲正切或者sigmoid，因为它们是可导的。  <li>输出层： </li></ul> <li>学习过程：  <ul> <li>反向传播：敏感性反向传播。收敛速度比较慢。  <li>Levenberg-Marquardt： </li></ul></li></ul></li></ul> <h3 id="c4无监督学习自组织映射">C4.无监督学习（自组织映射）</h3> <ul> <li>竞争学习或赢家通吃：产生最大值的神经元更新它的权值。  <li>Kohonen自组织映射（Self-Organization Map）：  <ul> <li>一维SOM：产生最大值的神经元更新它的权值，与之相邻的神经元以相对较低的学习率更新权值。  <li>二维SOM：领域函数判断相邻的神经元，使结构更“组织化”。 </li></ul></li></ul> <h3 id="rreferences参考文献">Rreferences（参考文献）</h3> <p>Bishop C M. Neural networks for pattern recognition[M]. Oxford university press, 1995. Duda R O, Hart P E, Stork D G. Unsupervised learning and clustering[J]. Pattern classification, 2001: 517-601. Freedman D A. Statistical models: theory and practice[M]. cambridge university press, 2009. Haykin S S, Haykin S S, Haykin S S, et al. Neural networks and learning machines[M]. Upper Saddle River: Pearson, 2009.</p></section><img src ="http://www.blogjava.net/zhuyuanxiang/aggbug/433677.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhuyuanxiang/" target="_blank">zYx.Tom</a> 2019-03-19 11:51 <a href="http://www.blogjava.net/zhuyuanxiang/archive/2019/03/19/433677.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Neuroph开发过程</title><link>http://www.blogjava.net/zhuyuanxiang/archive/2019/01/28/433623.html</link><dc:creator>zYx.Tom</dc:creator><author>zYx.Tom</author><pubDate>Sun, 27 Jan 2019 16:28:00 GMT</pubDate><guid>http://www.blogjava.net/zhuyuanxiang/archive/2019/01/28/433623.html</guid><wfw:comment>http://www.blogjava.net/zhuyuanxiang/comments/433623.html</wfw:comment><comments>http://www.blogjava.net/zhuyuanxiang/archive/2019/01/28/433623.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhuyuanxiang/comments/commentRss/433623.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhuyuanxiang/services/trackbacks/433623.html</trackback:ping><description><![CDATA[文章提纲  <h4></h4></header> <ul class="toc__menu"> <li><a href="#安装与配置">安装与配置</a>  <li><a href="#开发小结">开发小结</a>  <ul> <li><a href="#建立项目">建立项目</a>  <li><a href="#配置项目">配置项目</a>  <li><a href="#理解感知机的代码">理解感知机的代码</a> </li></ul></li></ul></nav></aside> <h2 id="安装与配置">安装与配置</h2> <ul> <li>JDK的安装：建议JRE 1.8以上；  <li>Neuroph安装：建议2.94的版本。<a href="http://neuroph.sourceforge.net/">下载地址</a>  <ul> <li>neuroph-core-2.94：开发的核心包  <li>neuroph-samples-2.94：使用这个框架的例子 </li></ul> <li>Eclipse的安装：建议是java 2018-09以上的版本  <ul> <li>配置“Windows→Preferences→Java→Build Path→User Libraries→New”一个“neuroph-2.94”，再“Add External Jars”就可以把相关的包全部定义在这个变量下面。  <li>也可以使用Maven配置。 </li></ul></li></ul> <h2 id="开发小结">开发小结</h2> <h3 id="建立项目">建立项目</h3> <ul> <li>在Eclipse中创建一个Java项目。 </li></ul> <h3 id="配置项目">配置项目</h3> <ul> <li>选中项目，“右键→Properties→Java Build Path→Libraries→Add Library→User Library→neuroph-2.94”即可把相关类包纳入到项目中。  <h3 id="理解感知机的代码">理解感知机的代码</h3> <li>单层感知机：neuroph-samples-2.94.jar中org.neuroph.samples.PerceptronSample.class  <div class="language-java highlighter-rouge"> <div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="nf">SinglePerceptronAND</span><span class="o">()</span> <span class="o">{</span>
  <span class="c1">// create training set (logical AND function)：创建训练集（符合逻辑与函数）</span>
  <span class="n">DataSet</span> <span class="n">trainingSet</span> <span class="o">=</span> <span class="k">new</span> <span class="n">DataSet</span><span class="o">(</span><span class="mi">2</span><span class="o">,</span> <span class="mi">1</span><span class="o">);</span><span class="n">trainingSet</span><span class="o">.</span><span class="na">addRow</span><span class="o">(...);</span>
  <span class="c1">// create perceptron neural network：创建感知机(两个入，一个出，就是最简单的单层一个神经元的神经网络)</span>
  <span class="n">NeuralNetwork</span> <span class="n">myPerceptron</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Perceptron</span><span class="o">(</span><span class="mi">2</span><span class="o">,</span> <span class="mi">1</span><span class="o">);</span>
  <span class="c1">// learn the training set：学习这个训练集，就是为了得到神经网络的参数</span>
  <span class="n">myPerceptron</span><span class="o">.</span><span class="na">learn</span><span class="o">(</span><span class="n">trainingSet</span><span class="o">);</span>
  <span class="c1">// test perceptron：测试这个感知机，检验它训练的参数是否正确</span>
  <span class="n">myPerceptron</span><span class="o">.</span><span class="na">setInput</span><span class="o">(</span><span class="n">trainingSet</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="mi">0</span><span class="o">).</span><span class="na">getInput</span><span class="o">());</span>
  <span class="n">myPerceptron</span><span class="o">.</span><span class="na">calculate</span><span class="o">();</span>
  <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">print</span><span class="o">(</span><span class="s">"Input: "</span> <span class="o">+</span> <span class="n">Arrays</span><span class="o">.</span><span class="na">toString</span><span class="o">(</span><span class="n">trainingElement</span><span class="o">.</span><span class="na">getInput</span><span class="o">()));</span>
  <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">" Output: "</span> <span class="o">+</span> <span class="n">Arrays</span><span class="o">.</span><span class="na">toString</span><span class="o">(</span><span class="n">networkOutput</span><span class="o">));</span>
<span class="o">}</span>
</code></pre></div></div></li></ul><img src ="http://www.blogjava.net/zhuyuanxiang/aggbug/433623.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhuyuanxiang/" target="_blank">zYx.Tom</a> 2019-01-28 00:28 <a href="http://www.blogjava.net/zhuyuanxiang/archive/2019/01/28/433623.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>HelloHibernate的创建过程</title><link>http://www.blogjava.net/zhuyuanxiang/archive/2019/01/25/433622.html</link><dc:creator>zYx.Tom</dc:creator><author>zYx.Tom</author><pubDate>Fri, 25 Jan 2019 03:19:00 GMT</pubDate><guid>http://www.blogjava.net/zhuyuanxiang/archive/2019/01/25/433622.html</guid><wfw:comment>http://www.blogjava.net/zhuyuanxiang/comments/433622.html</wfw:comment><comments>http://www.blogjava.net/zhuyuanxiang/archive/2019/01/25/433622.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhuyuanxiang/comments/commentRss/433622.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhuyuanxiang/services/trackbacks/433622.html</trackback:ping><description><![CDATA[文章提纲  <h4></h4></header> <ul class="toc__menu"> <li><a href="#安装与配置">安装与配置</a>  <li><a href="#开发小结">开发小结</a>  <ul> <li><a href="#建立项目">建立项目</a>  <li><a href="#配置项目">配置项目</a>  <li><a href="#创建代码">创建代码</a> </li></ul> <li><a href="#执行项目">执行项目</a> </li></ul></nav></aside> <h2 id="安装与配置">安装与配置</h2> <ul> <li>JDK的安装：建议使用JRE 1.8以上；  <li>SQL Server 2000的安装：建议SQL Server 2000 SP3以上；  <ul> <li>主要是简单好用，而且资源到处都找得到。  <li>SQL Server的“安全性→身份验证”中必须包括SQL Server验证，必须提供sa用户，不需要密码，否则需要修改Hibernate的配置文件。 </li></ul> <li>Eclipse的安装：建议是javaee 2018-09以上的版本  <ul> <li>配置“Windows→Preferences→Java→Build Path→User Libraries→New”一个“Hibernate3”，再“Add External Jars”就可以把相关的包全部定义在这个变量下面。  <li>SQL Server2000的JAR包安装：  <ul> <li>去<a href="http://jtds.sourceforge.net/">jTDS</a>就可以下载到支持SQL Server的JAR包文件，比微软出的SQL Server 2K的JAR包还好（微软的包会报错）。  <li>配置“Windows→Preferences→Java→Build Path→User Libraries→New”一个“jTDS”，再“Add External Jars”就可以把相关的包全部定义在这个变量下面。 </li></ul> <li>Hibernate Tools的安装：  <ul> <li>可以去JBoss的网站下载完整的安装包；  <li>建议在Eclipse JavaEE中安装，如果在Eclipse Java中安装需要下载许多新的插件，而网络环境不好就安装不成功。 </li></ul></li></ul></li></ul> <h2 id="开发小结">开发小结</h2> <h3 id="建立项目">建立项目</h3> <ul> <li>在Eclipse中创建一个Java项目。  <ul> <li>说明：Hibernate不仅用在Web项目中，也可以在Java项目中使用，只是安装建议参考前面的说明； </li></ul> <li>在SQL Server的“企业管理器”中创建一个名字叫“Hibernate”的数据库。  <li>在“Hibernate”数据库中创建一个“MESSAGE”的表。 </li></ul> <div class="language-sql highlighter-rouge"> <div class="highlight"><pre class="highlight"><code><span class="k">CREATE</span> <span class="k">TABLE</span> <span class="p">[</span><span class="n">dbo</span><span class="p">].[</span><span class="n">MESSAGE</span><span class="p">]</span> <span class="p">(</span>
    <span class="p">[</span><span class="n">MESSAGE</span><span class="p">]</span> <span class="p">[</span><span class="n">char</span><span class="p">]</span> <span class="p">(</span><span class="mi">10</span><span class="p">)</span> <span class="k">COLLATE</span> <span class="n">Chinese_PRC_CI_AS</span> <span class="k">NULL</span> 
    <span class="p">)</span> <span class="k">ON</span> <span class="p">[</span><span class="k">PRIMARY</span><span class="p">]</span>
</code></pre></div></div>
<h3 id="配置项目">配置项目</h3>
<ul>
<li>选中项目，“右键→Properties→Java Build Path→Libraries→Add Library→User Library→Hibernate 3”即可把相关类包纳入到项目中。 
<li>选中项目，“右键→Properties→Java Build Path→Libraries→Add Library→User Library→jTDS”即可把相关类包纳入到项目中。 
<h3 id="创建代码">创建代码</h3>
<li>创建一个新的类Message 
<div class="language-java highlighter-rouge">
<div class="highlight"><pre class="highlight"><code><span class="kn">package</span> <span class="n">sample</span><span class="o">.</span><span class="na">entity</span><span class="o">;</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">Message</span> <span class="o">{</span>
  <span class="kd">private</span> <span class="n">String</span> <span class="n">message</span><span class="o">;</span>
  <span class="kd">public</span> <span class="nf">Message</span><span class="o">(</span><span class="n">String</span> <span class="n">message</span><span class="o">)</span> <span class="o">{</span>
      <span class="k">this</span><span class="o">.</span><span class="na">message</span> <span class="o">=</span> <span class="n">message</span><span class="o">;}</span>
  <span class="kd">public</span> <span class="n">String</span> <span class="nf">getMessage</span><span class="o">()</span> <span class="o">{</span>
      <span class="k">return</span> <span class="n">message</span><span class="o">;}</span>
  <span class="kd">public</span> <span class="kt">void</span> <span class="nf">setMessage</span><span class="o">(</span><span class="n">String</span> <span class="n">message</span><span class="o">)</span> <span class="o">{</span>
      <span class="k">this</span><span class="o">.</span><span class="na">message</span> <span class="o">=</span> <span class="n">message</span><span class="o">;}</span>
<span class="o">}</span>
</code></pre></div></div>
<li>创建一个测试类 
<div class="language-java highlighter-rouge">
<div class="highlight"><pre class="highlight"><code><span class="kn">package</span> <span class="n">sample</span><span class="o">.</span><span class="na">entity</span><span class="o">;</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">PopulateMessages</span> <span class="o">{</span>

  <span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span>
      <span class="n">SessionFactory</span> <span class="n">factory</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Configuration</span><span class="o">().</span><span class="na">configure</span><span class="o">().</span><span class="na">buildSessionFactory</span><span class="o">();</span>
      <span class="n">Session</span> <span class="n">session</span> <span class="o">=</span> <span class="n">factory</span><span class="o">.</span><span class="na">openSession</span><span class="o">();</span>
      <span class="n">session</span><span class="o">.</span><span class="na">beginTransaction</span><span class="o">();</span>

      <span class="n">Message</span> <span class="n">message</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Message</span><span class="o">(</span><span class="s">"Hibernated"</span><span class="o">);</span>
      <span class="n">session</span><span class="o">.</span><span class="na">save</span><span class="o">(</span><span class="n">message</span><span class="o">);</span>
      <span class="n">session</span><span class="o">.</span><span class="na">getTransaction</span><span class="o">().</span><span class="na">commit</span><span class="o">();</span>
      <span class="n">session</span><span class="o">.</span><span class="na">close</span><span class="o">();</span>
  <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<li>创建一个Hibernate的配置文件：“New→Other→Hibernate Configuration File→hibernate.cfg.xml” </li></ul>
<div class="language-xml highlighter-rouge">
<div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</span>
<span class="cp">&lt;!DOCTYPE hibernate-configuration PUBLIC 
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"&gt;</span>
<span class="nt">&lt;hibernate-configuration&gt;</span>
<span class="nt">&lt;session-factory</span> <span class="na">name=</span><span class="s">"Hibernate"</span><span class="nt">&gt;</span>
    <span class="nt">&lt;property</span> <span class="na">name=</span><span class="s">"hibernate.connection.driver_class"</span><span class="nt">&gt;</span>net.sourceforge.jtds.jdbc.Driver<span class="nt">&lt;/property&gt;</span>
    <span class="nt">&lt;property</span> <span class="na">name=</span><span class="s">"hibernate.connection.url"</span><span class="nt">&gt;</span>jdbc:jtds:sqlserver://127.0.0.1:1433;DatabaseName=hibernate<span class="nt">&lt;/property&gt;</span>
    <span class="nt">&lt;property</span> <span class="na">name=</span><span class="s">"hibernate.connection.username"</span><span class="nt">&gt;</span>sa<span class="nt">&lt;/property&gt;</span>
    <span class="nt">&lt;property</span> <span class="na">name=</span><span class="s">"hibernate.dialect"</span><span class="nt">&gt;</span>org.hibernate.dialect.SQLServerDialect<span class="nt">&lt;/property&gt;</span>
    <span class="nt">&lt;property</span> <span class="na">name=</span><span class="s">"hibernate.show_sql"</span><span class="nt">&gt;</span>true<span class="nt">&lt;/property&gt;</span>
    <span class="nt">&lt;mapping</span> <span class="na">resource=</span><span class="s">"sample/entity/Message.hbm.xml"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;/session-factory&gt;</span>
<span class="nt">&lt;/hibernate-configuration&gt;</span>
</code></pre></div></div>
<ul>
<li>创建一个Hibernate的映射文件：“New→Other→Hibernate XML Mapping File”，把多余的文件和目录移除，“Add Class→Message→Finish”就可以了。 </li></ul>
<div class="language-xml highlighter-rouge">
<div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?xml version="1.0"?&gt;</span>
<span class="cp">&lt;!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"&gt;</span>
<span class="c">&lt;!-- Generated 2019-1-23 19:49:53 by Hibernate Tools 3.5.0.Final --&gt;</span>
<span class="nt">&lt;hibernate-mapping&gt;</span>
    <span class="nt">&lt;class</span> <span class="na">name=</span><span class="s">"sample.entity.Message"</span> <span class="na">table=</span><span class="s">"MESSAGE"</span><span class="nt">&gt;</span>
        <span class="nt">&lt;id</span> <span class="na">name=</span><span class="s">"message"</span> <span class="na">type=</span><span class="s">"java.lang.String"</span><span class="nt">&gt;</span>
            <span class="nt">&lt;column</span> <span class="na">name=</span><span class="s">"MESSAGE"</span> <span class="nt">/&gt;</span>
            <span class="nt">&lt;generator</span> <span class="na">class=</span><span class="s">"assigned"</span> <span class="nt">/&gt;</span>
        <span class="nt">&lt;/id&gt;</span>
    <span class="nt">&lt;/class&gt;</span>
<span class="nt">&lt;/hibernate-mapping&gt;</span>
</code></pre></div></div>
<h2 id="执行项目">执行项目</h2>
<ul>
<li>运行PopulateMessages就可以看到结果了。 </li></ul><img src ="http://www.blogjava.net/zhuyuanxiang/aggbug/433622.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhuyuanxiang/" target="_blank">zYx.Tom</a> 2019-01-25 11:19 <a href="http://www.blogjava.net/zhuyuanxiang/archive/2019/01/25/433622.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《测试驱动开发》的读书笔记</title><link>http://www.blogjava.net/zhuyuanxiang/archive/2019/01/18/433616.html</link><dc:creator>zYx.Tom</dc:creator><author>zYx.Tom</author><pubDate>Fri, 18 Jan 2019 15:25:00 GMT</pubDate><guid>http://www.blogjava.net/zhuyuanxiang/archive/2019/01/18/433616.html</guid><wfw:comment>http://www.blogjava.net/zhuyuanxiang/comments/433616.html</wfw:comment><comments>http://www.blogjava.net/zhuyuanxiang/archive/2019/01/18/433616.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhuyuanxiang/comments/commentRss/433616.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhuyuanxiang/services/trackbacks/433616.html</trackback:ping><description><![CDATA[<li><a href="#测试驱动开发的读书笔记">《测试驱动开发》的读书笔记</a>  <ul> <li><a href="#学习基础">学习基础：</a>  <li><a href="#学习过程">学习过程：</a>  <li><a href="#学习目的">学习目的：</a>  <li><a href="#学习感悟">学习感悟：</a>  <li><a href="#学习代码">学习代码：</a> </li></ul> <li><a href="#测试驱动开发的规则">测试驱动开发的规则</a>  <li><a href="#测试程序开发周期的阶段">测试程序开发周期的阶段</a>  <ul></ul></nav></aside> <h2 id="测试驱动开发的读书笔记">《测试驱动开发》的读书笔记</h2> <h3 id="学习基础">学习基础：</h3> <p>熟悉《设计模式》的基本概念，熟悉《重构》的基本概念，熟悉基本的Java语法，熟悉Eclipse和JUnit的使用，有相对较好的英语基础。</p> <h3 id="学习过程">学习过程：</h3> <ul> <li>第1部分，手工输入实例程序，了解TDD的方法和过程。重点是理解TDD的思路，最好的理解方式就是通过实践的方式理解。  <li>第2部分，教你如何用Python实现一个符合xUnit的测试框架。  <li>第3部分，TDD的模式，这些模式展现TDD如何与其他重要思想（例如：设计模式、重构等等）一起工作的。 </li></ul> <h3 id="学习目的">学习目的：</h3> <p>编写正确的代码。</p> <h3 id="学习感悟">学习感悟：</h3> <ul> <li>道理很简单，操作也很简单，但是我仍然无法明了作者许多重构操作的意图，只是感觉作者可能是从直觉出发写出代码，再通过重构推进测试代码与产品代码之间的解耦。（知其然，不知其所以然）  <li>可以先跳过第2部分，了解xUnit如何实现固然重要，但是为此变成先学Python就有点跑题了  <li>还可以跳过第3部分，这部分都是作者从思想上对TDD的总结，俗话说“不吃亏不涨记性”，等自己在项目中吃够了亏再来回顾别人的经验，才会真正共鸣吧。 </li></ul> <h3 id="学习代码">学习代码：</h3> <p>代码很简单，不需要再提供，反而最重要的是自己一定要手工跟一遍，否则无法领会作者的意图。至少，我在豆瓣上看了几个评论，大部分都是看懂了，没感觉。</p> <h2 id="测试驱动开发的规则">测试驱动开发的规则</h2> <ol> <li>（P4）明确设计目标，完善测试代码  <ul> <li>消除重复设计即是消除依赖关系（测试代码与产品代码之间的依赖关系）；  <li>测试驱动开发不是通过一小步一小步来完成的，而是培养一小步一小步开发软件的能力。因为简单的问题可以走快点，复杂的问题就可以走慢点。 </li></ul> <li>（P12）完善产品代码  <ul> <li>完成知道怎么做的产品代码；  <li>补充不知道怎么做的产品伪代码。 </li></ul> <li>（P14）寻找隐含的开发目标，完善测试代码  <ul> <li>利用三角法发现产品代码中的问题（ 三角法：当例子不止1个的时候才完善代码。可以在没有设计思路的时候，换个角度思考问题）  <li>利用重构解决发现的问题 </li></ul> <li>（P17）通过开发的功能来重构测试代码  <li>（P33）不打断自己已经在做的工作，如果非要打断也不要在新的工作中花太长的时间，并且不能再次打断这个新的工作。（事不过三）  <li>（P34）找到自己的开发节奏。（一开始慢一点，慢慢加快，再调整回慢，直到找到自己最合适的节奏感）  <li>（P42）删除不需要的子类，会发现测试代码中存在的不需要的测试也可以删除（放弃不需要的东西，会帮助你发现你还需要什么）  <li></li></ol> <h2 id="测试程序开发周期的阶段">测试程序开发周期的阶段</h2> <ol> <li>写一个测试程序；  <li>让测试程序编译通过；  <li>运行测试程序，发现不能运行；  <li>让测试程序可以运行；  <li>消除重复设计，优化设计结构。 </li></ol> </li><img src ="http://www.blogjava.net/zhuyuanxiang/aggbug/433616.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhuyuanxiang/" target="_blank">zYx.Tom</a> 2019-01-18 23:25 <a href="http://www.blogjava.net/zhuyuanxiang/archive/2019/01/18/433616.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>《单元测试之道Java版》的读书笔记</title><link>http://www.blogjava.net/zhuyuanxiang/archive/2019/01/16/433606.html</link><dc:creator>zYx.Tom</dc:creator><author>zYx.Tom</author><pubDate>Wed, 16 Jan 2019 09:57:00 GMT</pubDate><guid>http://www.blogjava.net/zhuyuanxiang/archive/2019/01/16/433606.html</guid><wfw:comment>http://www.blogjava.net/zhuyuanxiang/comments/433606.html</wfw:comment><comments>http://www.blogjava.net/zhuyuanxiang/archive/2019/01/16/433606.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhuyuanxiang/comments/commentRss/433606.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhuyuanxiang/services/trackbacks/433606.html</trackback:ping><description><![CDATA[<li><a href="#总览">总览</a>  <li><a href="#第2章-首个单元测试">第2章 首个单元测试</a>  <li><a href="#第3章-使用junit编写测试">第3章 使用JUnit编写测试</a>  <ul> <li><a href="#31-构建单元测试">3.1 构建单元测试</a>  <li><a href="#32-junit的各种断言">3.2 JUnit的各种断言</a>  <li><a href="#33-junit框架">3.3 JUnit框架</a> </li></ul> <li><a href="#4-测试什么">4. 测试什么？</a>  <li><a href="#5correct正确的边界条件">5.CORRECT（正确的）边界条件</a>  <li><a href="#6使用mock对象">6.使用Mock对象</a>  <li><a href="#7-好的测试所具有的品质a-trip">7. 好的测试所具有的品质(A-TRIP)</a>  <li><a href="#8-在项目中进行测试">8. 在项目中进行测试</a>  <li><a href="#9-设计话题">9. 设计话题</a>  <ul></ul></nav></aside> <h2 id="总览">总览</h2> <p>这是本相对简单的书，书中采用的JUnit的版本也是旧的，但是在新的JUnit4下稍做修改依然可以运行。重要的是通过这本书了解JUnit在Java的单元测试中是如何使用的。</p> <h2 id="第2章-首个单元测试">第2章 首个单元测试</h2> <p>计划你的测试：测试不是无中生有的，也不是意想天开的。是根据需要一点点添加的，帮助自己尽早地发现思考上的误区。参看这章给出的例子，原来理所当然正确的，结果不一定是正确的。</p> <h2 id="第3章-使用junit编写测试">第3章 使用JUnit编写测试</h2> <h3 id="31-构建单元测试">3.1 构建单元测试</h3> <p>测试代码必须要做的几件事情：</p> <ul> <li>准备测试的条件（创建对象、分配资源等等）  <li>调用测试的方法  <li>验证测试方法的行为与期望是否相符  <li>测试结束后清理现场（释放资源等等）  <h3 id="32-junit的各种断言">3.2 JUnit的各种断言</h3> <p>断言：JUnit提供的辅助函数，帮助你确认被测试函数是否正确运行。</p></li></ul> <p>后面还介绍了（3.5 JUnit的自定义断言）</p> <h3 id="33-junit框架">3.3 JUnit框架</h3> <p>这章是基于JUnit3.x写的，建议了解就可以了，因为JUnit4的变化较大，使用也更方便直观，因此直接参考<a href="http://www.cnblogs.com/eggbucket/archive/2012/02/02/2335697.html">JUnit4的帮助</a>。</p> <table> <thead> <tr> <th>框架运行顺序</th> <th>对应于标签</th></tr></thead> <tbody> <tr> <td>setUpBeforeClass()</td> <td>@BeforeClass</td></tr> <tr> <td>&nbsp;</td> <td>&nbsp;</td></tr> <tr> <td>setUp()</td> <td>@Beofre</td></tr> <tr> <td>testMethod1()</td> <td>&nbsp;</td></tr> <tr> <td>tearDown()</td> <td>@After</td></tr> <tr> <td>&nbsp;</td> <td>&nbsp;</td></tr> <tr> <td>setUp()</td> <td>@Before</td></tr> <tr> <td>testMethod2()</td> <td>&nbsp;</td></tr> <tr> <td>tearDown()</td> <td>@After</td></tr> <tr> <td>&nbsp;</td> <td>&nbsp;</td></tr> <tr> <td>tearDownAfterClass()</td> <td>@AfterClass</td></tr></tbody></table> <h2 id="4-测试什么">4. 测试什么？</h2> <p>6个需要测试的地方（Right-BICEP）：</p> <ul> <li>Right：结果是否正确（Right）；  <li>B：边界（Boundary）条件是否正确(CORRECT)；参考第5章  <li>I：能否检查反向（Inverse）关系；  <li>C：进行交叉检查（Cross-Check）的其他手段；  <li>E：强制错误（Error）条件发生；使用Mock对象实现，参考第6章  <li>P：满足性能（Performance）的要求。 </li></ul> <p>测试内容较多时，可以使用测试数据文件进行准备。但是使用文件后就没有测试代码看起来那么直观了，因此除非测试内容非常复杂，否则没有必要采用这样的方式。并且如果测试文件出现错误（作者书中就出现了数据错误），还会导致测试不通过，增加了维护的成本。</p> <h2 id="5correct正确的边界条件">5.CORRECT（正确的）边界条件</h2> <ul> <li>一致性（Conformance）：值是否符合预期的格式；  <li>有序性（Ordering）：一组值是否符合对排序的要求（有序性、无序性）；  <li>区间性（Range）：值是否在合理取值范围内（在最小值与最大值之间）；  <li>引用（Reference）-耦合性：代码是否引用了不受代码本身直接控制的外部因素；  <li>存在性（Existence）：值是否存在（例如：非NULL，非零，包含于某个集合等等）  <li>基数性（Cardinality）：是否恰好有足够的值；（也称为集合的势，即集合里面包含的元素个数）  <li>时间性（Time）-绝对时间和相对时间：所有的事情是否按照顺序发生？是否在正确的时间发生？是否及时发生？ </li></ul> <h2 id="6使用mock对象">6.使用Mock对象</h2> <p>Mock对象解决的问题：</p> <ul> <li>真实对象具有不可确定的行为（如：股票行情）；  <li>真实对象很难被创建；  <li>真实对象的某些行为很难被触发（如：网络错误）；  <li>真实对象令程序的运行速度很慢；  <li>真实对象有用户界面或者就是用户界面；  <li>真实对象需要被询问它是如何被调用的（如：验证某个回调函数是否被调用）；  <li>真实对象实际上不存在（如：其他开发小组的接口、或者某个没有的硬件产品）。 </li></ul> <p>Mock对象解决的步骤：</p> <ul> <li>使用一个接口来描述这个对象；  <li>为产品代码实现这个接口；  <li>以测试为目的，在Mock对象中实现这个接口。 </li></ul> <p>注：这里的Mock不是网上已经形成框架的Mock工具，是Mock的实现原理。作者推荐的Mock工具是<a href="http://easymock.org/">EasyMock</a>。其他的Mock工具可以参考《[使用Mock进行单元测试]》(https://blog.csdn.net/u011393781/article/details/52669772)</p> <h2 id="7-好的测试所具有的品质a-trip">7. 好的测试所具有的品质(A-TRIP)</h2> <ul> <li>自动化（Automatic）：自动化地调用测试和检查结果；<a href="https://www.testwo.com/article/1170">常用的持续集成工具</a>  <li>彻底的（Thorough）：测试了所有需求关注的情况；<a href="https://blog.csdn.net/ohcezzz/article/details/78239927">常用的代码覆盖工具</a>  <li>可重复（Repeatable）：每个测试应该独立于其他所有的测试，还必须独立于环境，从而可以重复地执行，并且产生相同的结果。  <li>独立的（Independent）：确保一个函数只针对一样测试，并且这个测试不依赖于其他测试。  <li>专业的（Professional）：测试代码应该与产品代码的编码风格和编写质量相同 </li></ul> <p>如何确保测试代码是正确的呢？</p> <ul> <li>对产品代码中的Bug进行修改的时候也改进测试代码；（因为这个Bug是测试代码没有发现的）  <li>在产品代码中引入Bug来验证测试代码的正确性。（确保可能会发生的错误被测试代码捕捉到了） </li></ul> <h2 id="8-在项目中进行测试">8. 在项目中进行测试</h2> <ul> <li>把测试代码与产品代码放在一个目录下；  <li>与别人共享代码的时候，需要确保你的代码可以通过所有测试；  <li>测试的时间点：  <ul> <li>编写新的函数；  <li>修正Bug；  <li>每次成功编译之后；  <li>每次对版本控制的提交；  <li>持续不断地由专门的机器来运行完整的构建和测试。 </li></ul> <li>测试别人的项目代码：其实就是维护别人的项目绝对是个大问题，同时也是个必须面对的问题。需要理性的态度（不批评别人的代码）、冷静的手段（不随便修改别人的代码）、持久的耐心（先从测试代码开始，慢慢重构项目代码，使之重新回到健康状态）、真正的智慧（知道什么样的项目应该达到什么样的目标，不执着于重构成一个完美的状态，也不简单放弃随之自生自灭。）  <li>测试与评审：三个臭皮匠顶个诸葛亮，放下自我的执着，接纳各种不同的意见，才能做出令自己满意的项目。 </li></ul> <h2 id="9-设计话题">9. 设计话题</h2> <ul> <li>面向测试的设计：不方便测试的设计不是好的设计；说明设计过于僵化或者臃肿，需要简化或者修改使之更利用未来的扩展和维护。  <li>面向测试的重构：不方便测试的代码不是好的代码；说明业务混杂在一起，无法实现一个函数只针对一样测试，需要修改设计使业务分离。  <li>测试类的不变性：就是对类的断言必须为真。  <ul> <li>有序性。例如：sorted list类的不变性就是无论发生什么，结果都应该是有序的。  <li>结构化。例如：订单系统中每个条目必须属于一个订单，一个订单拥有一个或多个条目。  <li>数学不变性。例如：银行账号的的借贷必须平衡。  <li>数据一致性。例如：商品总数=库存数+销售数。 </li></ul> <li>测试驱动的设计。使你作为产品代码的用户在编码，而不是产品开发者在编码，开发结果更能反应用户的需求。  <li>测试无效的参数。当你作为产品代码的用户时，你才能真正确定哪些责任应该你来承担，而哪些是不需要的。例如：无效的参数应该由哪个函数来承担检查责任呢？ </li></ul> </li><img src ="http://www.blogjava.net/zhuyuanxiang/aggbug/433606.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhuyuanxiang/" target="_blank">zYx.Tom</a> 2019-01-16 17:57 <a href="http://www.blogjava.net/zhuyuanxiang/archive/2019/01/16/433606.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>