假设空间:

 机器学习中可能的函数构成的空间称为“假设空间”。。监督学习的目的在于学习一个由输入到输出的映射,这一映射由模型来表示。换句话说,学习的目的就在于找到最好的这样的模型。模型属于由输入空间到输出空间的映射的集合,这个集合就是假设空间(hypothesis space)。假设空间的确定意味着学习的范围的确定。监督学习(supervised learning)的任务是学习一个模型,使模型能够对任意给定的输入,对其相应的输出做出一个好的预测。模型属于由输入空间到输出空间的映射的集合,这个集合就是假设空间(hypothesis space)。假设空间的确定意味着学习范围的确定。

  从特殊的训练样例中归纳出一般函数是机器学习的中心问题。那么什么是概念学习呢?给定某一类别的若干正例和反例,从中获得该类别的一般定义。概念学习也可以看做是一个搜索问题的过程,它在预定义的假设空间中搜索假设,使其与训练样例有最佳的拟合度。多数情形下,为了高效的搜索,可以利用假设空间中一种自然形成的结构——即一般到特殊偏序结构。

概念学习简介

  许多机器学习问题涉及到从特殊训练样例中得到一般概念。比如人们不断学习的一些一般概念和类别包括:鸟类、汽车、勤奋的学习等。每个概念可以被看做一个对象或者事件的集合,它是从更大的集合中选取的子集(如从动物的集合中选取鸟类),或者是在这个较大的集合中定义的不二函数(如在动物集合中定义的函数,它对鸟类产生ture,对其它动物产生false)。

  给定一样例集合以及每个样例是否属于某一概念的标注,怎样自动推断出该概念的一般定义。这一问题被称为概念学习,或者称从样例中逼近布尔值函数

概念学习的定义:

概念学习是指从有关某个布尔函数的输入输出训练样例中推断出该布尔函数。

概念学习任务

  我们有如下的例子,本例的目标概念是:“Aldo进行水上运动的日子”。表格描述了一系列日子的样例,每个样例表示为属性的集合。属性EnjiySport表示这一天Aldo是否乐于进行水上运动。这个任务的目的是基于某天的个属性,以预测出改天EnjoySport的值

EnjoySport概念学习任务

- 任务T:基于某天的属性,预测当天Aldo是否进行水上运动
- 性能标准P:预测的准确率
- 训练经验E:往日一系列日子的样例

目标概念EnjoySport的正例和反例(表1)

Example Sky AirTemp Humidity Wind Water Forecast EnjoySport
1 Sunny Warm Normal Strong Warm Same Yes
2 Sunny Warm High Strong Warm Same Yes
3 Rainy Cold High Strong Warm Change No
4 Sunny Warm High Strong Cool Change Yes

  在这种情况下,采取什么样的形式来表示假设呢?可以优先考虑一个较为简单的形式,即实例的各属性约束的合取式。在这里,可以令每个假设为6个约束的向量,这些约束指定了属性Sky、AirTemp、Humidity、Wind、Water、Forecast的值,每个属性可取值为:

  • 由“?”表示任意本属性可接受的值。
  • 明确指定的属性的值如(Warm)。
  • 由"∅\varnothing∅"表示不接受任何值。

  如果某些实例x满足假设h的所有约束,那么h将x分类为正例(h(x) = 1)。比如,为判定Aldo只在寒冷和超市的日子里进行水上运动(并且与其他属性无关),这样的假设可以表示为下面的表达式:
⟨?,Cold,High,?,?,?⟩\langle?,Cold,High,?,?,?\rangle⟨?,Cold,High,?,?,?⟩
  最一般的假设是每一天都是正例,可以表示为:
⟨?,?,?,?,?,?⟩\langle?,?,?,?,?,?\rangle⟨?,?,?,?,?,?⟩
  而最特殊的假设是每一天都是反例,可以表示为
⟨∅,∅,∅,∅,∅,∅⟩\langle\varnothing,\varnothing,\varnothing,\varnothing,\varnothing,\varnothing\rangle⟨∅,∅,∅,∅,∅,∅⟩
  综上所述,EnjoySport这个概念学习任务需要学习的是使EnjoySport=yes的日子,并将其表示为属性约束的合取式。一般说,任何概念学习任务能被描述为:实例的集合、实例集合上的目标函数、候选假设的集合以及训练样例的集合。以这种一般形式定义的EnjoySport概念学习任务可以表示为:

- 已知- 实例集X:可能的日子,每个日子由下面的属性描述:- Sky(可能取值为Sunny, Cloudy, Rainy)- AirTemp{可能取值为Warm, Cold)- Humidity(可能取值为Normal, High)- Wind(可能取值为Strong, Weak)- Water(可能取值为Warm, Cool)- Forecast(可能取值为Same, Change)- 假设集:每个假设描述为6个属性:Sky, AirTemp, Humidity, Wind, Water, Forecast的值约束的合取。约束可以为"?"(表示接受任意值), "∅"(表示拒绝所有值),或一特定值。- 目标概念c:EnjoySport:X→{0,1}- 训练样了集D:目标函数的正例和反例(表1)
- 求解:- H中的一假设h,使对于X中任意x, h(x) = c(x)

术语的定义

  概念定义在一个实例集合之上,这个集合表示为X。在本例中,X是所有可能的日子,每个日子由Sky, AirTemp, Humidity, Wind, Water, Forecast六个属性表示。待学习的概念或者函数称为目标概念,记作c。一般来说,c可以是定义在实例集X上的任意布尔函数,即c:X→{0,1}c:X\rightarrow\{0, 1\}c:X→{0,1}。在这个例子里,目标概念对应于属性EnjoySport的值,即当EnjoySport = Yes时,c(x) = 1,当EnjouSport = No时,c(x) = 0。

  在学习目标概念时,必须提供一套训练样例,每个样例为X中的一个实例x以及它的目标概念值c(x)。对于c(x) = 1的实例被称为正例,或者称为目标概念的成员。对于c(x) = 0的实例为反例,或者称为非目标概念的成员。经常可以用序偶⟨x,c(x)⟩\langle x,c(x)\rangle⟨x,c(x)⟩来描述训练样例,表示其包含了实例x和目标概念值c(x)。符号D用来表示训练样例的集合。

  一旦给定目标概念c的训练样例集,学习器面临的问题就是假设或者估计c。使用符号H来表示所有可能假设的集合,这个集合才是为确定目标概念所考虑的范围(即假设空间)。通常H依赖设计者所选择的假设表示而定。H中的每个假设h表示X上定义的布尔函数,即h:→{0,1}h:\rightarrow\{0,1\}h:→{0,1}。机器学习的目标就是寻找一个假设h,使对于X中的所有x,h(x) = c(x)。

归纳学习假设

  机器学习的任务是在整个实例集合X上确定与目标概念c相同的假设h,然而我们对于c仅有的信息只是它在训练样例上的值。因此,归纳学习算法那最多只能保证输出的假设能与训练样例相拟合。如果没有更多的信息,我们只能假定,对于未见实例最好的假设就是与训练数据最佳拟合的假设。这是归纳学习的一个基本假定。

归纳学习假设

 任一假设如果在足够大的训练样例集中很好地逼近目标函数,它也能在未见实
例中很好地逼近目标函数。

作为搜索的概念学习

  概念学习可以看做是一个搜索的过程,范围是假设的表示所隐含定义的整个空间。搜索的目标是为了寻找能最好地拟合训练样例的假设。必须注意到,当假设的表示形式选定后,那么也就隐含地为学习算法确定了所有假设的空间。这些假设是学习程序所能表示的,也是它能够学习的。考虑在EnjoySport学习任务中的实例集合X和假设集合H。如果属性Sky有3种可能的值,而AirTemp. Humidity, Wind, Water, Forecast都只有两种可能的值,则实例空间X包含了3×2×2×2×2×2=963\times2\times2\times2\times2\times2 = 963×2×2×2×2×2=96种不同的实例。类似的计算可得,在假设空间H中,有5×4×4×4×4×4=51205\times4\times4\times4\times4\times4=51205×4×4×4×4×4=5120种语法不同的假设(每一个属性除了特殊值外,还增加了"?", “∅\varnothing∅”)。然而,注意到包含有∅符号的假设代表空实例集合,即它们将每个实例都分类为反例。因此,语义不同的假设只有1+4×3×3×3×3×3=9731 + 4\times3\times3\times3\times3\times3=9731+4×3×3×3×3×3=973种。这里的EnjoySport例子是一个非常简单的学习任务,它的假设空间相对较小且有限。多数实际的学习任务包含更大的、有时是无限大的假设空间。

  如果把学习看作是一个搜索问题,那么很自然,对学习算法的研究需要考察假设空间搜索的不同策略。特别引起我们兴趣的算法应该能有效地搜索非常大的或者无限大的假设空间,以找到最佳拟合训练数据的假设。

假设的一般到特殊序

  许多概念学习算法中,搜索假设空间的方法依赖于一种针对任意概念学习都很有效的结构:假设的一般到特殊序关系。利用假设空间的这种自然结构,我们可以在无线的假设空间中进行彻底的搜索,而不需要明确地列举所有的假设。为说明一般到特殊序关系,考虑以下两个假设:
h1=⟨Sunny,?,?,Strong,?,?⟩h_1=\langle Sunny,?,?,Strong,?,?\rangleh1​=⟨Sunny,?,?,Strong,?,?⟩
h2=⟨Sunny,?,?,?,?,?⟩h_2=\langle Sunny,?,?,?,?,?\rangleh2​=⟨Sunny,?,?,?,?,?⟩
  哪些实例可被h1h_1h1​和h2h_2h2​划分为正例?由于h2h_2h2​包含的实例约束较少, 它划分出的正例也较多。实际上,任何被h1h_1h1​划分为正例的实例都会被h2h_2h2​划分为正例。因此,我们说h2h_2h2​比h1h_1h1​更一般。

  直观上的“比…更一般”这种关系可以有如下精确定义:首先,对X中的任意实例x和H中的任意假设h,我们说当且仅当h(x) = 1时x满足h。现在以实例集合的形式定义一个more_general_than_or_equal_to的关系:
给定假设hj和hk,hjmore_general_than_or_equal_tohk,当且仅当任意一个满足hk的实例同时也满足hj。给定假设h_j和h_k,h_j\ more\_general\_than\_or\_equal\_to\ h_k,当且仅当任意一个满足h_k的实例同时也满足h_j。给定假设hj​和hk​,hj​ more_general_than_or_equal_to hk​,当且仅当任意一个满足hk​的实例同时也满足hj​。

定义:
令hj和hk为在X上定义的布尔函数。称hjmore_general_than_or_equal_tohk(记作hj≥ghk),当且仅当(∀x∈X)[(hk(x)=1)→(hj(x)=1)]令h_j和h_k为在X上定义的布尔函数。称h_j\ more\_general\_than\_or\_equal\_to\ h_k(记作h_j\geq_gh_k),当且仅当(\forall x \in X)[(h_k(x)=1)\rightarrow (h_j(x) = 1)]令hj​和hk​为在X上定义的布尔函数。称hj​ more_general_than_or_equal_to hk​(记作hj​≥g​hk​),当且仅当(∀x∈X)[(hk​(x)=1)→(hj​(x)=1)]

  有必要考虑一假设严格地比另一假设更一般的情形。因此,我们说hj严格的more_general_thanhkh_j严格的more\_general\_than\ h_khj​严格的more_general_than hk​(写作hk>ghkh_k>_gh_khk​>g​hk​),当且仅当(hj≥ghk)∧(hk≱ghj)(h_j\geq_gh_k)\land(h_k\ngeq_gh_j)(hj​≥g​hk​)∧(hk​≱g​hj​)。最后,还可以定义逆向的关系“比…更特殊”为hjmore_specific_thanhkh_j\ more\_specific\_than\ h_khj​ more_specific_than hk​,当hkmore_general_thanhjh_k\ more\_general\_than\ h_jhk​ more_general_than hj​。

  ≥g\geq_g≥g​关系很重要,因为它在假设空间H上对任意概念学习问题提供了一种有效的结构。

FIND-S:寻找极大特殊假设

  如何使用more_general_thanmore\_general\_thanmore_general_than 偏序来搜索与训练样例一直的假设呢?一种办法是从H中最特殊的假设开始,然后在该假设覆盖正例失败时将其一般化(当以假设能正确地划分一个正例时,称该假设覆盖正例)。使用偏序实现FIND-S算法的精确描述如下:

  1. 将h初始化为H重最特殊假设
  2. 对每个正例x
    • 对h的每个属性约束aia_iai​
      如果x满足aia_iai​,那么不做任何处理,否则将h中aia_iai​替换为z满足的下一个更一般约束
  3. 输入假设h。

  为了说明这一算法,假定给予学习器的一系列训练样例如下表1所示。FIND-S的第一步是将h初始化为H重最特殊的假设:
h←⟨∅,∅,∅,∅,∅,∅⟩h\leftarrow \langle\varnothing,\varnothing,\varnothing,\varnothing,\varnothing,\varnothing\rangleh←⟨∅,∅,∅,∅,∅,∅⟩

  在观察表1中第一个训练样例时,它刚好是个正例。这时的h太特殊了,h中的每一个∅\varnothing∅约束都不被该样例满足,因此,每个属性都被替换成能你和该例的下一个更一般的值约束,也就是这一样例的属性值本身:
h←⟨Sunny,Warm,Normal,Strong,Warm,Same⟩h\leftarrow\langle Sunny,Warm,Normal,Strong,Warm,Same\rangleh←⟨Sunny,Warm,Normal,Strong,Warm,Same⟩
  这个h仍旧太过特殊了,它把除了第一个样例以外的所有实例都划分为了反例。下一步,第二个训练样例(仍然为正例)迫使该算法进一步将h一般化。这次使用"?"代替h中不能被新样例满足的属性值,这样的假设变为:
h←⟨Sunny,Warm,?,Strong,Warm,Same⟩h\leftarrow\langle Sunny,Warm,?,Strong,Warm,Same\rangleh←⟨Sunny,Warm,?,Strong,Warm,Same⟩
  然后处理第三个训练样例,这是一个反例,因此h不变。实际上,FIND-S算法简单地忽略每一个反例,为什么呢?

  一般情况下,只要我们假定假设空间H确实包含真正的目标概念c,而且训练样例不包含错误,那么当前的假设h不需要因反例的出现而更改。原因在于当前假设h是H中与所观察到的正例相一致的最特殊的假设,由于假定目标概念c在H中,而且它一定是与所有正例一致的,那么c一定比h更一般,而目标概念c不会覆盖一个反例,因此h也不会覆盖一个反例。因此,对返利,h不需要做出任何的更改。

  接着完成FIND-S算法,第四个正例使得h更一般:
h←⟨Sunny,Warm,?,Strong,?,?⟩h\leftarrow\langle Sunny,Warm,?,Strong,?,?\rangleh←⟨Sunny,Warm,?,Strong,?,?⟩

  FIND-S算法演示了一种利用more_general_thanmore\_general\_thanmore_general_than 偏序来搜索假设空间的方法,这一搜索沿着偏序链,从较特殊的假设逐渐转移到较一般的假设。在每一步中,假设只在需要覆盖新的正例时被一般化。因此,每一步得到的假设都是在那一点上与训练样例一致的最特殊的假设。

FIND-S算法的重要特点是:对以属性约束的合取式描述的假设空间(如,EnjoySport中的H),FIND-S保证输出为H中与正例一致的最特殊的假设。只要正确的目标概念包含在H中并且训练数据都是正确的,最终的假设也与所有的反例一致。然而,这一学习算法仍然存在一些问题:

- 学习过程是否收敛到了正确的目标概念?虽然FIND-S找到了与训练数据一致的假设,但是没办法确定它是否找到了唯一合适的假设(即目标概念本身),或者说是否还有其它可能的假设。我们希望算法知道它能否收敛到目标概念,如果不能,至少要描述出这种不确定性。- 为什么要用最特殊的假设?如果有多个与训练样例一直的假设,FIND-S只能找到最特殊的。为什么我们偏好最特殊的假设,而不选最一般的假设,亦或者一般程介于二者之间的某个假设。- 训练样例是否相互一致?在多数实际的学习问题中,训练数据中常出现某些错误或者噪声,这样的不一致的训练集会严重破坏FIND-S算法,因为它忽略了所有的反例。我们期望的算法至少能检测出训练数据的不一致性,并且最好能容忍这样的错误。- 如果有多个极大特殊假设怎么办?在EnjoySport任务的假设语言H中,总有一个唯一的最特殊假设与训练数据一致。然而,对其他一些假设空间,可能有多个极大特殊假设。这种情况下,FIND-S必须被扩展,以允许其在选择怎样一般化假设的路径上回溯,以容纳目标假设位于偏序结构的另一分支上的可能性。更进一步,我们可以定义一个不存在极大特殊假设的假设空间。当然,这是一个理论问题而不是实践问题。

变形空间和候选消除算法

  概念学习的另一种途径即候选消除算法。FIND-S输出的假设只是H中能够你和训练样例的多个假设中的一个,而在候选消除算法中,输出的是与训练样例一致的所有假设的集合。候选算法在描述这一集合时不需要明确列举所有的成员,而这也归功于more_general_thanmore\_general\_thanmore_general_than 偏序结构。在这里需要维护一个一致假设集合的简洁表示,然后在遇到新的训练样例时逐步精化这一表示。

  然而,候选消除算法和FIND-S算法都有共同的缺点,那就是它们在训练数据含有噪声时性能较差。

候选消除算法的表示

  候选消除算法寻找与训练样例一致的所有假设。为精确描述这一算法,这里先引入一些基本定义。首先,当一个假设能够正确分类一组样例时,我们称这个假设是与这些样例一致的。

定义: 一个假设h与训练样例集合D一致,当且仅当对D中每一个样例⟨x,c(x)⟩\langle x, c(x)\rangle⟨x,c(x)⟩都有h(x)=c(x)h(x)=c(x)h(x)=c(x).
Consistent(h,D)≡(∀⟨x,c(x)⟩∈D)h(x)=c(x)Consistent(h,D)\equiv(\forall\lang x,c(x)\rang\in D)\ h(x) = c(x)Consistent(h,D)≡(∀⟨x,c(x)⟩∈D) h(x)=c(x)

  注意,这里定义的一致与前面定义的满足是不同的。一个样例x在h(x) = 1时称为满足假设h,不论x是目标概念的正例还是反例。然而,这一样例是否与h 一致 则与目标概念有关,即是否h(x) = c(x)。

  候选消除算法能够表示与训练样例一致的所有假设。在假设空间中的这一子集被称为关于假设空间H和训练样例集合D的变型空间,因为它包含了目标概念的所有合理的变型。

定义: 关于假设空间H和训练样例集合D的变型空间,标记为VSH,DVS_{H,D}VSH,D​,是H中与训练样例集D一致的所有假设构成的子集。
VSH,D≡{h∈H∣Consistent(h,D)}VS_{H,D} \equiv\{h\in H|Consistent(h,D)\}VSH,D​≡{h∈H∣Consistent(h,D)}

列表后消除算法

  显然,表示变型空间的一种方法是列出其所有成员。这样可产生一个简单的算法,称为列表后消除算法,其定义如下:

  1. 变型空间VersionSpace←VersionSpace\leftarrowVersionSpace←包含了H中所有的假设
  2. 对每个训练样例⟨x,c(x)⟩\lang x,c(x)\rang⟨x,c(x)⟩,从变型空间中移除所有h(x)≠c(x)h(x)\ne c(x)h(x)​=c(x)的假设h
  3. 输出VersionSpace中的假设列表。

  列表后消除算法首先将变型空间初始化为包含H中所有的假设,然后从中去除与任一训练样例不一致的假设。包含候选假设的变型空间随着观察到的越来越多的样例而缩减,直到剩下一个(理想情况下)与所有样例一致的假设,这可能就是所要的目标概念。如果没有充足的数据使变型空间缩减到只有一个假设,那么该算法将输出一个集合,这个集合中所有的假设训练样例都一致。

  原则上,只要假设空间是有限的,就可以使用列表后消除算法。它具有很多的有点,如能得到与训练数据一致的所有假设。但是,这一算法要求非常繁琐地列出H中所有假设,这对于大多数实际的假设空间是不现实的要求。

变型空间的更简洁表示

  候选消除算法那与上面的列表后消除算法遵循着同样的原则。然而,它使用一种更简洁的变型空间表示法。在此,变型空间被表示为它的极大一般和极大特殊的成员。这些成员形成了一般和特殊边界的集合。这些边界在整个偏序结构中划分出变型空间。

  未说明变型空间的这种表示,再一次考虑EnjoySport概念学习问题。对于表1中给定的4个训练样例,FIND-S输出假设:
h=⟨Sunny,Warm,?,Strong,?,?⟩h=\lang Sunny,Warm,?,Strong,?,?\rangh=⟨Sunny,Warm,?,Strong,?,?⟩

  实际上,这只是H中与训练样例一致的所有六个假设之一。
⟨Sunny,Warm,?,Strong,?,?⟩\lang Sunny,Warm,?,Strong,?,?\rang⟨Sunny,Warm,?,Strong,?,?⟩

⟨Sunny,?,?,Strong,?,?⟩\lang Sunny,?,?,Strong,?,?\rang⟨Sunny,?,?,Strong,?,?⟩

⟨Sunny,Warm,?,?,?,?⟩\lang Sunny,Warm,?,?,?,?\rang⟨Sunny,Warm,?,?,?,?⟩

⟨?,Warm,?,Strong,?,?⟩\lang ?,Warm,?,Strong,?,?\rang⟨?,Warm,?,Strong,?,?⟩

⟨Sunny,?,?,?,?,?⟩\lang Sunny,?,?,?,?,?\rang⟨Sunny,?,?,?,?,?⟩

⟨?,Warm,?,?,?,?⟩\lang ?,Warm,?,?,?,?\rang⟨?,Warm,?,?,?,?⟩

这6个假设构成了与该数据集合和假设表示相对应的变型空间。变型空间包含了所有
6个假设,但是可以简单地用S和G来表示。箭头表示实例间的more_general_than关
系。

  候选消除算法通过使用极大一般成员(G)和极大特殊成员(S)来表示变型空间。之给定这两个集合S和G,就可以列举出变形空间中的所有成员,方法是使用一般到特殊偏序结构来生成S和G集合之间的所有假设。

  可以直观地看出,使用极大一般和极大特殊集合表示变型空间的作法是合理的。下面我们精确地定义S和G这两个边界集合,并且证明它们确实代表了变型空间。

定义: 假设空间H和训练数据D的一般边界G是在H中与D相一致的极大一般成员的集合
G≡{g∈H∣Consistent(g,D)∧(¬∃g′∈H)[(g′>gg)∧Consistent(g′,D)]}G\equiv\{g\in H|Consistent(g,D)\land(\lnot\exists g'\in H)[(g'>_gg)\land Consistent(g',D)]\}G≡{g∈H∣Consistent(g,D)∧(¬∃g′∈H)[(g′>g​g)∧Consistent(g′,D)]}

定义: 假设空间H和训练数据D的特殊边界S是在H中与D相一致的极大特殊成员的集合
G≡{s∈H∣Consistent(s,D)∧(¬∃s′∈H)[(s>gs′)∧Consistent(s′,D)]}G\equiv\{s\in H|Consistent(s,D)\land(\lnot\exists s'\in H)[(s>_gs')\land Consistent(s',D)]\}G≡{s∈H∣Consistent(s,D)∧(¬∃s′∈H)[(s>g​s′)∧Consistent(s′,D)]}

  只要集合G和S被良好地鼎娱乐,它们就完全规定了变型空间。这里还可以证明,变型空间的确切组成是:G中包含的假设,S中包含的假设以及G和S之间偏序结构所规定的假设。

候选消除学习算法

  候选消除算法计算出的变型空间,包含H中与训练样例的观察序列一致的所有假设。开始,变型空间被初始化为H中所有假设的集合。即将G边界集合初始化为H重最一般的假设:
G0←{⟨?,?,?,?,?,?⟩}G_0\leftarrow\{\lang?,?,?,?,?,?\rang\}G0​←{⟨?,?,?,?,?,?⟩}
  并将S边界集合初始化为最特殊的假设:
S0←{⟨∅,∅,∅,∅,∅,∅⟩}S_0\leftarrow\{\lang\varnothing,\varnothing,\varnothing,\varnothing,\varnothing,\varnothing\rang\}S0​←{⟨∅,∅,∅,∅,∅,∅⟩}

  这两个边界集合包含了整个假设空间。因为H中与训练样例的观察序列一致的所有假设都比S0S_0S0​更一般,且比G0G_0G0​更特殊。算法在处理每个训练养老时,S和G边界集合分别被一般化和特殊化,从变型空间中逐步消去与样例不一致的假设。在所有训练样例处理完后,得到的变型空间就包含了所有与样例一致的假设,而且只包含这样的假设。算法描述如下:

将G集合初始化为H中极大一般假设
将S集合初始化为H中极大特殊假设对每个训练样例d,进行以下操作:
- 如果d是正例- 从G中一曲所有与d不一致的假设- 对S中每个与d不一致的假设- 从s中移去- 把s的所有极小一般化式h加入到S中,其中h满足- h与d一致,且G的某个成员比h更一般- 从S中移去所有这样的假设:它比S中的另一假设更一般- 如果d是反例- 从S中移去所有与d不一致的假设- 对G中每个与d不一致的假设g- 从G中移去g- 把g的所有技校特殊化式加入到G中,其中h满足- h与d一致,而且S的某个成员比h更特殊- 从G中移去所有这样的假设:它比G中另一假设更特殊

  注意算法汇总的操作,包括对给定假设的极小一般化式和极小特殊化式的计算,和确定那些非极小和非极大的假设。具体的实现当然依赖于实例和假设的表示方法。然而,只要这些操作被良好地定义了,该算法就可应用于任意概念学习和任意假设空间。

算法过程图解

S0:{⟨∅,∅,∅,∅,∅,∅⟩}S_0:\{\lang\varnothing,\varnothing,\varnothing,\varnothing,\varnothing,\varnothing\rang\}S0​:{⟨∅,∅,∅,∅,∅,∅⟩}

S1:{⟨Sunny,Warm,Normal,Strong,Warm,Same⟩}S_1:\{\lang Sunny,Warm,Normal,Strong,Warm,Same\rang\}S1​:{⟨Sunny,Warm,Normal,Strong,Warm,Same⟩}

S2:{⟨Sunny,Warm,?,Strong,Warm,Same⟩}S_2:\{\lang Sunny,Warm,?,Strong,Warm,Same\rang\}S2​:{⟨Sunny,Warm,?,Strong,Warm,Same⟩}

G0,G1,G2:{⟨?,?,?,?,?,?⟩}G_0,G_1,G_2:\{\lang?,?,?,?,?,?\rang\}G0​,G1​,G2​:{⟨?,?,?,?,?,?⟩}

训练样例
1.⟨Sunny,Warm,Normal,Strong,Warm,Same⟩,EnjoySport=Yes\lang Sunny,Warm,Normal,Strong,Warm,Same\rang,EnjoySport=Yes⟨Sunny,Warm,Normal,Strong,Warm,Same⟩,EnjoySport=Yes
2.⟨Sunny,Warm,High,Strong,Warm,Same⟩,EnjoySport=Yes\lang Sunny,Warm,High,Strong,Warm,Same\rang,EnjoySport=Yes⟨Sunny,Warm,High,Strong,Warm,Same⟩,EnjoySport=Yes

S0S_0S0​和G0G_0G0​为最初的边界集合,分别对应最特殊和最一般假设。训练样例1和2是的S边界变得更加一般,如FIND-S算法中的一样,这些样例对G边界没有影响。

S2,S3:{⟨Sunny,Warm,?,Strong,Warm,Same⟩}S_2,S_3:\{\lang Sunny,Warm,?,Strong,Warm,Same\rang\} S2​,S3​:{⟨Sunny,Warm,?,Strong,Warm,Same⟩}

G2:{⟨?,?,?,?,?,?⟩}G_2:\{\lang?,?,?,?,?,?\rang\}G2​:{⟨?,?,?,?,?,?⟩}
↓\downarrow↓
G3:{⟨Sunny,?,?,?,?,?⟩,⟨?,Warm,?,?,?,?⟩,⟨?,?,?,?,?,Same⟩}G_3:\{\lang Sunny,?,?,?,?,?\rang,\lang ?,Warm,?,?,?,?\rang,\lang?,?,?,?,?,Same\rang\}G3​:{⟨Sunny,?,?,?,?,?⟩,⟨?,Warm,?,?,?,?⟩,⟨?,?,?,?,?,Same⟩}

训练样例:
3.⟨Rainy,Cold,High,Warm,Change⟩,EnjoySport=No\lang Rainy,Cold,High,Warm,Change\rang,EnjoySport = No⟨Rainy,Cold,High,Warm,Change⟩,EnjoySport=No

样例3是一反例,它把G2G_2G2​边界特殊化为G3G_3G3​。

S3:{⟨Sunny,Warm,?,Strong,Warm,Same⟩}S_3:\{\lang Sunny,Warm,?,Strong,Warm,Same\rang\}S3​:{⟨Sunny,Warm,?,Strong,Warm,Same⟩}
↓\downarrow↓
S4:{⟨Sunny,Warm,?,Strong,?,?⟩}S_4:\{\lang Sunny,Warm,?,Strong,?,?\rang\}S4​:{⟨Sunny,Warm,?,Strong,?,?⟩}

G3:{⟨Sunny,?,?,?,?,?⟩,⟨?,Warm,?,?,?,?⟩,⟨?,?,?,?,?,Same⟩}G_3:\{\lang Sunny,?,?,?,?,?\rang,\lang ?,Warm,?,?,?,?\rang,\lang?,?,?,?,?,Same\rang\}G3​:{⟨Sunny,?,?,?,?,?⟩,⟨?,Warm,?,?,?,?⟩,⟨?,?,?,?,?,Same⟩}
↓\downarrow↓
G4:{⟨Sunny,?,?,?,?,?⟩,⟨?,Warm,?,?,?,?⟩}G_4:\{\lang Sunny,?,?,?,?,?\rang,\lang?,Warm,?,?,?,?\rang\}G4​:{⟨Sunny,?,?,?,?,?⟩,⟨?,Warm,?,?,?,?⟩}

训练样例:
4.⟨Sunny,Warm,High,Strong,Cool,Change⟩\lang Sunny,Warm,High,Strong,Cool,Change\rang⟨Sunny,Warm,High,Strong,Cool,Change⟩,EnjoySport = Yes

正例使S边界更一般,从S3S_3S3​变为了S4S_4S4​.G3G_3G3​的一个成员也必须删除,因为它不再比S4S_4S4​边界更一般。

关于变型空间和候选消除的说明

候选消除算法是否会收敛到正确的假设

  由候选消除算法得到的变型空间能够收敛到描述目标概念的假设条件是:

1)在训练样例中没有错误
2)H中确实包含描述目标概念的正确假设。实际上,如果遇到新的训练样例,可以监测变型空间以判定其与真正的目标概念之间是否还有分歧,以及为精确确定目标概念还需要多少训练样例、当S和G边界集合收敛到单个的可确定的假设时,目标概念才真正获得。

  如果训练数据中包含错误会怎么样?假设第二个样例被错误地标记为一反例。在这种情况下,算法肯定会从变型空间中删除正确的目标概念。因为它会删除所有与样例不一致的假设,所以在遇到这一错误的反例时,算法将从变型空间中移去正确的概念。当然,如果训练数据足够大的话,我们会发现,最终S和G边界收敛到一个空的变型空间,我们从而得知训练数据有误。空的变型空间表示H中没有假设能够与样例一致。相似的情况会出现在另一个环境中:训练样例正确,但是目标概念不能由假设表示方法所描述(比如目标概念是某几个属性特种的析取,而假设空间只支持合取的形式)。

下一步需要什么样子的训练数据

  之前我们都假定训练样例由某个外部的施教者提供。倘若学习器可以主宰实验进程,下一步它要自己选择一个实例,然后从外界(自然界或者施教者)获得该实例的正确分类结果。这一场景可分为两种情况,一种是学习器在自然界中进行试验(如建造一座桥梁,然后让自然界来决定它是否牢固),或者在施教者的指导下学习(提出一座新桥梁的设计方案,让施教者来判断其是否牢固)。这里我们用查询来代表学习器建立的这个实例,然后由外界来对其进行分类。

  我们考虑目前从EnjoySport的4个样例上学习到的变型空间。这时学习器该如何提出一个较好的查询呢?一般情况下怎样去才采取一种好的查询策略?显然,学习器应试图在当前变型空间中选择假设,以进一步划分该空间。因此,需要选择的实例需满足:它能被变型空间中的一些假设划分为正例,另一些划分为反例。如
⟨Sunny,Warm,Normal,Light,Warm,Same⟩\lang Sunny,Warm,Normal,Light,Warm,Same\rang⟨Sunny,Warm,Normal,Light,Warm,Same⟩
  这一实例满足变型空间中6个假设的3个。如果施教者将实例划分为正例,变型空间的S边界就需要被一般化。相反,如果施教者划分其为反例,G边界就需要被特殊化。无论哪种情况,机器将能够学到更多的知识,以确定目标概念并将变型空间缩小到原来的一半。

  一般来说,概念学习的最优查询策略,是产生实例以满足当前变型空间中大约半数的假设,这样,变型空间的大小可以在遇到每个新的样例时减半,正确的目标概念就可在只用[log⁡2∣VS∣][\log_2|VS|][log2​∣VS∣]次实验后可以得到。然而,在一般情况下,可能无法构造出这样的精确分半的实例,这样查询的次数可能会大于[log⁡2∣VS∣][\log_2|VS|][log2​∣VS∣]次。

怎样去使用不完全学习的概念

  在EnjoySport的预测任务中,我们除了4个样例之外没有别的训练样例了,但是我们需要机器对未见过的实例进行分类。虽然此时变型空间仍然包含着多个假设,目标概念仍然没有学习到,但是它仍然有可能对新的样例进行一定可信度的分类。我们假定机器需要对下面四个实例进行分类。
待分类的数据(表2)

Example Sky AirTemp Humidity Wind Water Forecast EnjoySport
A Sunny Warm Normal Strong Cool Change ?
B Rainy Cold Normal Light Warm Same ?
C Sunny Warm Normal Light Warm Same ?
D Sunny Cold Normal Strong Warm Same ?

  我们可以观察到,虽然实例A不在训练样例中,但当前变型空间中每个假设都将其分为正例。由于变型空间的所有假设一致同意实例A为正例,因此学习器将其划分为正例的可信度,与只有单个的目标概念时一样。不管变型空间中哪个假设最终成为目标概念,它都会将A划分为正例。

  进一步讲,我们不需要列举变型空间的所有假设,便知道每个假设都会将其划分为正例,这一条件当且仅当实例满足S的每个成员时成立。原因是变型空间中的其他每个假设都至少比S的某个成员更一般。由我们的more_general_thanmore\_general\_thanmore_general_than 定义,如果新的实例满足S的所有成员,它也一定满足这些更一般的假设。

  同样,实例B被变型空间中的每个假设划分为反例,所以这个实例可以放心的被划分为反例,即使概念学习是不完全的。对这一条件进行测试的有效方法是,判断实例不满足G中的所有成员。原因是变型空间中的其它每个假设都至少比S的某个成员更特殊。由我们的more_specific_thanmore\_specific\_thanmore_specific_than 定义,如果新的实例不满足G的所有成员,它也一定不满足这些更特殊的假设。

  实例C的情况有所不同。变型空间中半数的假设划分其为正例,半数划分为反例。因此,学习器无法可信地分类这一样例,除非提供更多的训练样例。可以注意到,实例C与前面提出的最优查询相同。因此我们可以这么说,最优分类歧义的实例也一定最能提供新的分类信息

  最后,实例D在变型空间中被两个假设分为正例,被其它4个假设分为反例。这个例子的分类可信度要比实例A和B小。投票选举要倾向于反例分类,所以我们可以输出拥有最大票数的分类,还可以附带一个可信度比例以表明投票的倾向程度。事实上,如果假定H中所有假设由相等的先验概率,那么投票的方法能得到新实例的最可能分类。进一步说,投正例票假设所占的比例可被看作在给定训练数据时,实例为正例的可能性。

归纳偏置

  在给定正确的训练样例并且保证初始假设空间包含目标概念时,候选消除算法可以收敛到目标概念。如果目标概念不在假设空间怎么办?是否可以设计一个包含所有假设的空间来解决这一困难?假设空间的大小对于算法推广到未见实例的能力有什么影响?假设空间的大小对所需训练样例的数量有什么影响?这些都是归纳推理中的一些基本问题。我们将在候选消除算法中分析这些问题,而在分析中得到的结论可以应用于任意的概念学习系统。

一个有偏的假设空间

  如果想保证假设空间包含目标概念,一个明显的方法是扩大假设空间,使每个可能的假设都被包含在内。再一次使用EnjoySport这个例子,其中我们将假设空间限制为只包含属性值的合取。由于这一限制,假设空间不能够表示最简单的析取形式的目标概念。如“Sky = Sunny或者Sky = Cloudy”。实际上,如果给定以下三个训练样例,它们来自于该析取式假设,我们的算法将得到一个空的变型空间
另一组实例(表3)

Example Sky AirTemp Humidity Wind Water Forecast EnjoySport
1 Sunny Warm Normal Strong Cool Change Yes
2 Cloudy Warm Normal Strong Cool Change Yes
3 Rainy Warm Normal Strong Cool Change No

  之所以不存在与这3个样例一致的假设的原因是,与前两个样例一致,并且能在给定假设空间H中表示的最特殊的假设是:
S2:⟨?,Warm,Normal.Strong,Cool,Change⟩S_2:\lang?,Warm,Normal.Strong,Cool,Change\rangS2​:⟨?,Warm,Normal.Strong,Cool,Change⟩
  这一假设虽然是H中与样例一致的最特殊的假设,它仍然太过于一般化看:它将第3个样例错误的划分为了正例。问题在于,我们使学习器偏向于只考虑合取的假设,这里需要表示能力更强的假设空间。

无偏的学习器

  很显然,为了保证目标概念在假设空间中,需要提供一个假设看空间,它能表达所有的可教授概念。换言之,它能够表达实例集X的所有可能的子集。一般我们把集合X的所有子集的集合称为X的幂集

  例如在EnjoySport学习任务中,使用6种属性描述的实例空间X的大小为96。在这一实例集合上可以定义多少概念?换而言之,X的幂集大小是什么?一般来说,在集合X上定义的相异子集数目(即X幂集的大小)为2∣X∣2^{|X|}2∣X∣,其中|X|是X的元素数目。因此在这一实例空间上可定义2962^{96}296,或者大约是102810^{28}1028个不同的目标概念,这也是学习器所需要学习的目标概念数目。而合取假设空间只能表示973个假设——实在是一个偏置很大的假设空间。

  现在将EnjoySport学习任务重新定义为一种无偏的形式。方法是定义一个心的假设空间H’,它能表示实例的每一个子集,也就是把H’对应到X的幂集。定义H’的一种方法是,允许使用前面的假设的任意析取、合取和否定式。例如目标概念“Sky = Cloudy或Sky = Sunny”可以被描述为:
⟨Sunny,?,?,?,?,?⟩∨⟨Cloudy,?,?,?,?,?⟩\lang Sunny,?,?,?,?,?\rang\lor\lang Cloudy,?,?,?,?,?\rang⟨Sunny,?,?,?,?,?⟩∨⟨Cloudy,?,?,?,?,?⟩

  给定这样的假设空间,我们就可以安全地使用候选消除算法,而不必担心无法表达目标概念。然而,虽然这个假设空间排除了表达能力的问题,它又产生了一个新的、同样困难的问题:概念学习算法将完全无法从训练样例中泛化!其原因如下,假定我们给学习器提供了3个正例(x1,x2,x3)(x_1,x_2,x_3)(x1​,x2​,x3​)以及两个反例(x4,x5)(x_4,x_5)(x4​,x5​)。这时,变型空间的S边界包含的假设正好是三个正例的析取:
S:{(x1∨x3∨x3)}S:\{(x_1\lor x_3\lor x_3)\}S:{(x1​∨x3​∨x3​)}
  因为这时能覆盖3个正例的最特殊的假设。相似的,G边界将由那些刚好能排除掉反例的那些假设组成。
G:{¬(x4∨x5)}G:\{\lnot(x_4\lor x_5)\}G:{¬(x4​∨x5​)}

  然而,问题在于,在这一非常具有表达力的假设表示方法中,S边界总是所有正例的析取式,G边界总是所有反例的析取的否定式。这样能够由S和G无歧义地分类的,只有已见到的训练样例本身。要想获得单个目标概念,就必须提供X中所有的实例作为训练样例。

  我们可能想到,避免这一问题的方法可以使用此部分学习的变型空间,有变型空间的所有成员投票决定分类。然而,能够产生一致投票的只有那些已经见过的训练样例。对于其它实例,投票没有任何效果:每一个未见过的实例都会被变型空间中刚好半数的假设划分为正例,而被另一半划分为反例。原因如下,若H是X的幂集,而x是某个未出现过的实例,则对于变型空间中覆盖x的假设h,必然存在另一假设h’,它与h几乎相等,只不过对x的分类不同。而且,如果h在变型空间中,那么h’也在,因为它对于以往训练样例的划分与h完全一样。

无偏学习的无用性

  以上的讨论说明了归纳推理的一个基本属性:学习器如果不对目标概念的形式做预先的假定,它从根本上无法对未见实例进行分类。实际上在我们原来的EnjoySport任务中,候选消除算法能够从训练样例中泛化,其唯一的原因就是它是有偏的,它隐含假定了目标概念由属性值的合取来表示。如果这一假定正确并且训练数据没有错误,那么对于新实例的分类也会是正确的。但是如果这个假定不正确,候选消除算法肯定会错误地分类X中的某些实例。

  由于归纳偏置学习需要某种形式的预先假定,或成为归纳偏置,我们可以用归纳偏置来描述不同学习方法的特征。现在来精确地定义归纳偏置。这里要获取的关键思想在于,学习器在从训练样例中泛化并推断新实例的分类过程中所采用的策略。因此考虑一般情况下任意的学习算法L以及为任意目标概念c提供的任意训练数据Dc={⟨x,c(x)⟩}D_c = \{\lang x,c(x)\rang\}Dc​={⟨x,c(x)⟩}。训练过程结束后,L需要对新的实例xix_ixi​进行分类。令L(xi,Dc)L(x_i,D_c)L(xi​,Dc​)表示在对训练数据DcD_cDc​学习后L赋予xix_ixi​的分类(正例或者反例),我们可以如下描述L所进行的这一归纳推理过程:
(Dc∧xi)≻L(xi,Dc)(D_c\land x_i)\succ L(x_i,D_c)(Dc​∧xi​)≻L(xi​,Dc​)
  这里的记号y≻zy\succ zy≻z表示z从y归纳推理得到。例如,如果令L为候选消除算法,DcD_cDc​为表1中的训练数据,xix_ixi​为表2中第一个实例,啧归纳推理可得到结论
L(x1,Dc)=(EnjoySport=Yes)L(x_1,D_c)=(EnjoySport = Yes)L(x1​,Dc​)=(EnjoySport=Yes)
  由于L是以归纳学习算法,则一般情况下L(xi,Dc)L(x_i,D_c)L(xi​,Dc​)这一推论出的结果正确性无法证明;也就是说,分类L(xi,Dc)L(x_i,D_c)L(xi​,Dc​)并非从训练数据DcD_cDc​接新实例xix_ixi​中演绎派生。然而问题是,需要再(Dc∧xi)(D_c\land x_i)(Dc​∧xi​)上附加怎样的前提,以使L(xi,Dc)L(x_i,D_c)L(xi​,Dc​)能派生演绎。我们定义归纳偏置为这些附加前提的集合。更精确地说,我们定义L的归纳偏置为前提集合B,使所有的新实例xix_ixi​满足:
(B∧Dc∧xi)⊢L(xi,Dc)(B\land D_c\land x_i)\vdash L(x_i,D_c)(B∧Dc​∧xi​)⊢L(xi​,Dc​)
  这里的记号y⊢zy\vdash zy⊢z表示z从y中演绎派生(或者z可以由y证明得出)。这样,我们定义学习器的归纳偏置为附加的前提集合B,通过B使归纳推理充分地由演绎推理来论证。下面是该定义的总结:
定义: 考虑对于实例集合X的概念学习算法L。令c为X上定义的任一概念,并令Dc={⟨x,c(x)⟩}D_c=\{\lang x,c(x)\rang\}Dc​={⟨x,c(x)⟩}为c的任意训练样例集合。令L(xi,Dc)L(x_i,D_c)L(xi​,Dc​)表示经过数据DcD_cDc​的训练后L赋予实例xix_ixi​的分类。L的归纳偏置是最小断言集合B,它使任意目标概念c和相应的训练样例DcD_cDc​满足:
(∀xi∈X)[(B∧Dc∧xi)⊢L(xi,Dc)}(\forall x_i\in X)[(B\land D_c\land x_i)\vdash L(x_i,D_c)\}(∀xi​∈X)[(B∧Dc​∧xi​)⊢L(xi​,Dc​)}
  候选消除算法的归纳偏置是什么呢?首先确定这一算法的L(xi,Dc)L(x_i,D_c)L(xi​,Dc​):给定数据集DcD_cDc​,候选消除算法首先计算变型空间VSH,DCVS_{H,D_C}VSH,DC​​,然后在变型空间所包含的假设中投票,进行新实例xix_ixi​的分类。这里假定产生xix_ixi​的分类的条件是投票一致为正或为负,否则不进行分类。现在来回答什么是候选消除算法L(xi,Dc)L(x_i,D_c)L(xi​,Dc​)的归纳偏置的问题:很简单,就是c∈Hc\in Hc∈H这个前提。有了这一前提,候选算法所执行的每一归纳推理都可以被演绎论证。

概念学习和一般到特殊序相关推荐

  1. 《机器学习》读书笔记,第二章概念学习和一般到特殊序

    本章展示了几种概念学习算法,并讨论了这些算法能收敛到正确假设的条件.这里还分析了归纳学习的本质以及任意程序能从训练数据中泛华的理由. 2.1概念学习: 从有关某个布尔函数的输入输出训练样例中推断出该布 ...

  2. 计算机科学丛书收藏,计算机科学丛书:机器学习

    计算机科学丛书:机器学习 语音 编辑 锁定 讨论 上传视频 <计算机科学丛书:机器学习>展示了机器学习中核心的算法和理论,并阐明了算法的运行过程.综合了许多的研究成果,例如统计学.人工智能 ...

  3. Machine Learning 机器学习

    本书展示了机器学习中核心的算法和理论,并阐明了算法的运行过程.本书综合了许多的研究成果,例如统计学.人工智能.哲学.信息论.生物学.认知科学.计算复杂性和控制论等,并以此来理解问题的背景.算法和其中的 ...

  4. c语言消隐的作用是什么,【C语言程序设计最终版材料】

    C语言程序设计(最终版) <C语言程序设计.doc>由会员分享,可免费在线阅读全文,更多与<C语言程序设计(最终版)>相关文档资源请在帮帮文库(www.woc88.com)数亿 ...

  5. 伍六七带你学算法 入门篇 ——最大子序和

    力扣 53. 最大子序和 难度简单 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和. 示例: 输入: [-2,1,-3,4,-1,2,1,-5,4 ...

  6. 二叉树的前序、中序、后序非递归遍历 python实现

    前言 python中二叉树的定义: class TreeNode:def __init__(self, x):self.val = xself.left = Noneself.right = None ...

  7. python实现二叉树的重建2 之由中序遍历和后序遍历重建

    前言 通过上一节对python实现二叉树的重建1 之由前序遍历和中序遍历重建,我相信我们再来做这个问题就不难了,完全可以照猫画虎的来实现,具体的原理几乎是一样的,直接上代码了 code # 通用解法d ...

  8. python实现二叉树的重建1 之由前序遍历和中序遍历重建

    前言 此题是关于树的面试题目的常见题型,题目的含义很清晰,这个就不用多说了 解法 关于这道题的解法有很多不同的样式,通用的解法是这样的: 假如现在我们有如下两个遍历的情况 preorder: [1, ...

  9. 通过前序遍历和中序遍历构建二叉树 python实现

    前言 通过前序遍历和中序遍历构建二叉树的原理,主要是找前序遍历根节点在中序遍历中的位置,然后将二叉树而成左子树和右子树,然后依次进行这样的操作,思路还是比较简单的 代码 class Node:def ...

  10. 【剑指Offer】23、二叉搜索树的后序遍历序列

      题目描述:   输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字都互不相同.   解题思路:   对于后续遍历序列,序 ...

最新文章

  1. delphi中等待外部应用程序执行完成后,再继续执行自有代码段
  2. php获得帮助类数据_PHP实现的一个时间帮助类
  3. leetcode word break java,Word Break leetcode java
  4. HDU 2222 ac自动机模板
  5. 全国计算机准考证打印2015年,甘肃2015下半年全国计算机等级考试准考证打印时间...
  6. Android网络编程Socket【实例解析】
  7. 清华大学软件工程课程总结
  8. 在线播放m3u8和ts的方法
  9. 计算机一级大学生一定要考吗,关于大学大学生要考计算机一级吗
  10. vs项目文件夹进行分类管理
  11. 【C语言蓝桥杯每日一题】—— 单词分析
  12. 用CSS3制作一个风车
  13. Android版疯狂填字第三关,iOS/安卓版《疯狂填字》答案攻略第三十八关
  14. 使用Python编写程序,输入一个大于 2 的自然数,然后输出小于该数字的所有素数组成的集合。
  15. Spring的IOC/DI
  16. 3.2 有界线性泛函及其表示 有限维赋范线性空间
  17. WebStorm2018破解(2018年10月9日  16:13实测有效)
  18. opensuse常用软件安装
  19. 火狐浏览器如何添加Xpath扩展
  20. 用Flutter做桌上弹球?聊聊绘图(CanvasCustomPaint)API

热门文章

  1. 【转】告诉你外语学习的真实方法及误区分析(精编版)-part 3
  2. 云手机如何打破Wintel、Apple和Google的生态的垄断
  3. 初测ONES项目管理工具,寻求与众不同
  4. 20182319《数据结构与面向对象程序设计》实验二报告
  5. 蛋白组学搜库分析软件 MaxQuant使用教程
  6. 基于web的大数据可视化平台
  7. 基于Java swing+mysql+eclipse的【图书管理系统】
  8. 麦克林排名计算机,麦克林9大热门大学专业院校排名出炉!启德为您解读
  9. 随身助手API接口网站PHP源码v1.0
  10. 小米笔记本Air13.3扩充硬盘