机器学习算法

发布时间:2023-05-29 17:00

监督(supervised)

分类(classification)

1.knn(k Nearest Neighbors)算法:

  关键公式:d=(∑(xi−xtest)2)12d=(∑(xi−xtest)2)12 
  伪代码(pseudo_code) 
  计算训练集中到该点的距离 
  选择距离最小的k个点 
  返回k个点出现频率最高的类别作为当前点的预测分类

def knn(in_x, data_set, labels, k):
  diff_mat = tile(in_x, (data_size,1)) - data_set
  sq_diff_mat = diff_mat**2
  distances = sq_diff_mat.sum(axis=1)**0.5
  sorted_dist_indicies = distances.argsort()
  for i in xrange(k):
    vote_label = labels[sorted_dist_indicies[i]]
    class_count[vote_label] = class_count.get(vote_label, 0) + 1
  sortedClassCount = sorted(classCount.iteritems(),
    key=operator.itemgetter(1), reverse=True)
  return sortedClassCount[0][0]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

2.决策树:

  关键公式:H(x)=−∑P(xi)log2(P(xi))H(x)=−∑P(xi)log2(P(xi)) 
  决策树中很重要的一点就是根据信息熵的大小选择一个属性进行分枝,因此要注意一下信息熵的计算公式,并深入理解它。 
  伪代码(pseudo_code) 
  检测数据集中的每个子项是否属于同一分类: 
    If so return 类标签; 
    Else 
      寻找划分数据集的最好特征 
      创建分支节点 
      for 每个划分的子集 
        调用函数createBranch并增加返回结果到分支节点中 
    return 分支节点 
  原则只有一个,尽量使得每个节点的样本标签尽可能少,注意上面伪代码中一句说:find the best feature to split the data,那么如何find thebest feature?一般有个准则就是尽量使得分支之后节点的类别纯一些,也就是分的准确一些。如(图一)中所示,从海洋中捞取的5个动物,我们要判断他们是否是鱼,先用哪个特征? 

图一 
(图一)


  为了提高识别精度,我们是先用“离开陆地能否存活”还是“是否有蹼”来判断?我们必须要有一个衡量准则,常用的有信息论、基尼纯度等,这里使用前者。我们的目标就是选择使得分割后数据集的标签信息增益最大的那个特征,信息增益就是原始数据集标签基熵减去分割后的数据集标签熵,换句话说,信息增益大就是熵变小,使得数据集更有序。熵(伟大的人物)计算如(公式一)所示: 


H=−∑ni=1p(xi)log2p(xi)H=−∑i=1np(xi)log2p(xi) 
(公式一)


  其中n代表有n个分类类别(比如假设是二类问题,那么n=2)。分别计算这2类样本在总样本中出现的概率p1p1p2p2,这样就可以计算出未选中属性分枝前的信息熵。

 

3. 朴素贝叶斯(Naive Bayes)

  关键公式:P(A|B)=P(A∩B)P(B)P(A|B)=P(A∩B)P(B) 
  为什么 
  机器学习的一个重要应用就是文档的自动分类。在文档分类中,整个文档(如一封电子邮件)是实例,而电子邮件中的某些元素则构成特征。我们可以观察文档中出现的词,并把每个词的出现或者不出现作为一个特征,这样得到的特征数目一样多。假设词汇表中有1000个单词。要得到好的概率分布,就需要足够的数据样本,假定样本数为N。由统计学知,如果每个特征需要N个样本,那么对于10个特征将需要N10个样本N10个样本,对于包含1000个特征的词汇表将需要N1000N1000个样本。可以看到,所需要的样本数会随着特征树木增大而迅速增长。 
  如果特征之间相互独立,那么样本树就可以从N1000N1000减少到1000∗N1000∗N。所谓独立(independence)指的是统计意义上的独立,即一个特征或者单词出现的可能性与它和其他单词相邻没有关系。举个例子讲,假设单词bacon出现在unhealthy后面与出现在delicious附近,而很少出现在unhealthy附近,这个假设正是朴素贝叶斯分类其中朴素(naive)一词的含义。朴素贝叶斯分类其中的另一个假设是,每个特征同等重要。其实这个假设也有问题。如果要判断留言板的留言是否得当,那么可能不需要看完所有的1000个单词,而只需要看10~20个特征就足以作出判断了。尽管上述假设存在一些瑕疵,但朴素贝叶斯的实际效果却很好。 
  是什么 
  朴素贝叶斯在概率图模型中被划为判别模型(Discriminative model),经典贝叶斯公式,如(公式一)所示: 

p(c|x)=p(x∩c)p(x)p(c|x)=p(x∩c)p(x) 
(公式一)


  根据后验概率来判断,选择p(ci|x)p(ci|x)最大值作为x的类别cici。 
  伪代码(pseudo_code) 
  计算每个类别中的文档数目 
  对每篇训练文档: 
    对每个类别: 
      如果词条出现在文档中→→增加该词条的计数值 
      增加所有词条的计数值 
    对每个类别: 
      对每个词条: 
        将该词条的数目除以总词条数目得到条件概率 
    返回每个类别的条件概率 
    比较每个类别的条件概率和的大小 
    返回条件概率和大的类别

 


  下面进入“正规”的机器学习,之所以“正规”是因为它开始要建立损失函数(cost function),接着优化价值函数求出权重,然后测试验证。这整套流程是机器学习必经环节。

4.Logistic回归

  关键公式:11+e−z11+e−z

5.支持向量机(SVM)

  理论参考机器学习理论与实战(五)支持向量机 
  伪代码(pseudo_code) 
  创建一个αα向量并将其初始化为0向量 
  当迭代次数小于最大迭代次数时(外循环) 
    对数据集中的每个数据向量(内循环): 
      如果该数据向量可以被优化: 
        随机选择另外一个数据向量 
        同时优化这两个向量 
        如果两个向量都不能被优化,退出内循环 
    如果所有向量都没被优化,增加迭代数目,继续下一次循环

6.利用AdaBoost元算法提高分类性能

  关键公式:α=12ln(1−ϵϵ) D(i+1)i=D(i)ie−α∑Diα=12ln(1−ϵϵ) Di(i+1)=Di(i)e−α∑Di 
  AdaBoost意为adaptive(自适应) boosting原理: 

图一 
(图一)


  (图一)是Adaboost的原理示意图,左边矩形表示数据集,中间表示根据特征阈值来做分类,这样每一个弱分类器都类似于一个单节点的决策树,其实就是阈值判断而已,右边的三角形对每个弱分类器赋予一个权重,最后根据每个弱分类器的加权组合来判断总体类别。要注意一下数据集从上到下三个矩形内的直方图不一样,这表示每个样本的权重也发生了变化,样本权重的一开始初始化成相等的权重,然后根据弱分类器的错误率来调整每个弱分类器的全总alpha,如(图一)中的三角形所示,alpha 的计算如(公式一)所示 

公式一 
(公式一)


  从(公式一)中也能感觉出来,弱分类器权重alpha和弱分类器分类错误率epsilon成反比,如果不能看出反比关系,分子分母同时除以epsilon就可以了,而ln是单调函数。这很make sense,当然分类器的错误率越高,越不能器重它,它的权重就应该低。同样的道理,样本也要区分对待,样本的权重要用弱分类器权重来计算,其实也是间接靠分类错误率,如(公式二)所示: 

图一 
(公式二)


  计算单层决策树伪代码(pseudo_code) 
  将最小错误率minErrorminError设为+∞+∞ 
  对数据集中的每一个特征(第一层循环): 
    对每个步长(第二层循环): 
      对每个不等号(第三层循环): 
        建立一棵单层决策树并利用加权数据集对它进行测试 
        如果错误率低于minErrorminError,则将当前单层树设为最佳单层决策树 
  返回最佳单层决策树

 

回归(regression)

7.回归:预测数值型数据

  关键公式: 
  J(θ)=12m∑mi=1(hθ(x(i))−y(i))2 → w^=(XTX)−1XTyJ(θ)=12m∑i=1m(hθ(x(i))−y(i))2 → w^=(XTX)−1XTy

  回归意为数据进行曲线拟合。 
  损失函数:J(θ)=12m∑mi=1(hθ(x(i))−y(i))2J(θ)=12m∑i=1m(hθ(x(i))−y(i))2

  • 线性回归 
      即经典最小二乘法,说到最小二乘法就不得说下线性代数,因为一般说线性回归只通过计算一个公式就可以得到答案,如(公式一)所示,其中“w帽”为当y投影到X的列空间后的估计参数: 


    w^=(XTX)−1XTyw^=(XTX)−1XTy 
    (公式一)


      其中XX是表示样本特征组成的矩阵,yy表示对应的值,比如房价,股票走势等。如何记忆公式一呢?

     

      ∵Xw=y∵Xw=y maybe no solution 
      ∴(XT)Xw^=(XT)y ⇒ w^=(XTX)−1XTy∴(XT)Xw^=(XT)y ⇒ w^=(XTX)−1XTy

      如何解得公式一呢,这里给出投影解法,后续几个回归类推。首先,咱们先来了解误差函数(公式二) 

    e=∑i=1m(yi−xTiw)2e=∑i=1m(yi−xiTw)2

     

     

    公式二


      要使公式二最小是不是寻找(图一)中的e,即垂直于WX的垂线,因为只有垂直时e才最小。 

    图一 
    (图一)


    ∵a⊥e and e=b−p and p=Xa∵a⊥e and e=b−p and p=Xa 
    ∴aTe=0→aT(b−Xa)=0→X=(aTa)−1aTb (公式三)∴aTe=0→aT(b−Xa)=0→X=(aTa)−1aTb (公式三)

     

      这下(公式三)和(公式一)完全一样了图中a相当于公式一中X,b相当于式中的y,X相当于式中的w^w^,基于最小二乘法的线性回归也就推导完成了

  • 逻辑回归 
      逻辑回归一般用来做预测,也可以用来做分类,即预测是某个类别!线性回归想比大家都不陌生了,y=kx+b,给定一堆数据点,拟合出k和b的值就行了,下次给定X时,就可以计算出y,这就是回归。而逻辑回归跟这个有点区别,它是一种非线性函数,拟合功能颇为强大,而且它是连续函数,可以对其求导,这点很重要,如果一个函数不可求导,那它在机器学习用起来很麻烦,早期的海维赛德(Heaviside)阶梯函数就因此被sigmoid函数取代,因为可导意味着我们可以很快找到其极值点,这就是优化方法的重要思想之一:利用求导,得到梯度,然后用梯度下降法更新参数。 
      下面来看看逻辑回归的sigmoid函数,如(图一)所示: 

    图一 
    (图一)


      (图一)中上图是sigmoid函数在定义域[-5,5] 上的形状,而下图是在定义域[-60,60]上的形状,由这两个图可以看出,它比较适合做二类的回归,因为严重两级分化。Sigmoid函数的如(公式一)所示: 

    σ(z)=11+e−zσ(z)=11+e−z 
    sigmoid的由来 
    (公式一)


      随机梯度下降 伪代码(pseudo_code): 
      每个回归系数初始化为1 
      重复R次: 
        计算整个数据集的梯度 
        使用α∗gradientα∗gradient更新回归系数的向量 
      返回回归系数值
  • 局部加权线性回归 
      局部加权回归其实只是相当于对不同样本之间的关系给出了一个权重,所以叫局部加权,如(公式七)所示:
  • 岭回归 

    w^=(XTX+λI)−1XTyw^=(XTX+λI)−1XTy 
    公式七


      岭回归主要是解决的问题就是当XX’无法求逆时,比如当特征很多,样本很少,矩阵X不是满秩矩阵,此时求逆会出错,但是通过加上一个对角为常量lambda的矩阵,就可以很巧妙的避免这个计算问题,因此会多一个参数lambda,lambda的最优选择由交叉验证(cross-validation)来决定,加上一个对角不为0的矩阵很形象的在对角上抬高了,因此称为岭。不同的lambda会使得系数缩减,如(图六)所示: 

    图六 
    (图六)


      说到系数缩减大家可能会觉得有奇怪,感觉有点类似于正则,但是这里只是相当于在(公式六)中增大分母,进而缩小系数,另外还有一些系数缩减的方法,比如直接增加一些约束,如(公式十)和(公式十一)所示: 


    ∑nk=1w2k≤λ∑k=1nwk2≤λ 
    公式十

     


    ∑nk=1|wk|≤λ∑k=1n|wk|≤λ 
    公式十一


      当线性回归增加了(公式十)的约束变得和岭回归差不多,系数缩减了,而如果增加了(公式十一)的约束时就是lasso回归,系数有一些0。
  • 前向逐步回归 
      有了约束后,求解起来就不像上面那样直接计算个矩阵运算就行了,回顾第五节说中支持向量机原理,需要使用二次规划求解,不过仍然有一些像SMO算法一样的简化求解算法,比如前向逐步回归方法(属于一种贪心算法): 
      伪代码(pseudo_code) 
      数据标准化,使其分布满足0均值和单位方差 
      在每轮迭代过程中: 
        设置当前最小误差lowestError为正无穷 
        对每个特征: 
          增大或缩小: 
            改变一个系数得到一个新的W 
            计算新W下的误差 
            如果误差Error小于当前最小误差lowestError:设置Wbest等于当前的W 
          将W设置为新的Wbest 
            

8.树回归(Classification And Regression Trees)

  前一节的回归是一种全局回归模型,它设定了一个模型,不管是线性还是非线性的模型,然后拟合数据得到参数,现实中会有些数据很复杂,肉眼几乎看不出符合哪种模型,因此构建全局的模型就有点不合适。这节介绍的树回归就是为了解决这类问题,它通过构建决策节点把数据切分成区域,然后局部区域进行回归拟合。先来看看分类回归树(CART,Classification And Regression Trees),这个模型优点就是上面所说,可以对复杂和非线性的数据进行建模,缺点就是得到的数据不容易理解。顾名思义,它既可以做分类也可以做回归,至于分类前面已经说过了,这里略过。直接看伪代码吧。 
  伪代码(poseudo_code): 
  对每个特征: 
    对每个特征之: 
      将数据急切分成两份 
      计算切分的误差 
      如果当前误差小于当前最小误差,那么将当前切分设定为最佳切分并更新最小误差 
  返回最佳切分的特征和阈值 
  下面就是无监督学习方法,所谓无监督学习也就是没有标签,对样本进行聚类分析、关联分析,这两大类都可以说的很简单也可以说很复杂,学术的东西本身就一直在更新着。

无监督(unsupervised)

9.利用k-均值聚类对未标注数据分组

  k-均值聚类可以扩展一下形成层次聚类(Hierarchical Clustering),也可以进入概率分布空间进行聚类。而关联分析又是另外一个比较有力的工具,它又称为购物篮分析,我们可以大概体会它的用途,挖掘之间的关系,经典故事就是啤酒和尿布的关联。另外提一下,google搜索的两大核心技术:深度学习和知识图。深度学习就不说了,知识图就是挖掘关系。找到了关系就是找到了金矿,关系也可以用复杂网络(complex network)来建模。好今天就聊到这里,来看看k-Means的伪代码: 
  创建k个点作为起始质心(经常是随机选择) 
  当任意一个点的蔟分配结果发生改变时 
    对数据集中的每个数据点 
      对每个质心 
        计算质心与数据点之间的距离 
      将数据点分配到据其最近的蔟 
    对每一个蔟,计算蔟中所有点的均值并将其做为质心

10.利用Apriori算法进行关联分析

  《机器学习实战》的最后的两个算法对我来说有点陌生,但学过后感觉蛮好玩,了解了一般的商品数据关联分析和搜索引擎智能提示的工作原理。先来看看关联分析(association analysis)吧,它又称关联规则学习(association rule learning),它的主要工作就是快速找到经常在一起的频繁项,比如著名的“啤酒”和“尿布”。试想一下,给我们一堆交易数据,每次的交易数据中有不同的商品,要我们从中发掘哪些商品经常被一起购买?当然穷举法也可以解决,但是计算量很大,这节的算法Apriori就是解决此类问题的快速算法。Apriori在拉丁语中表示“from before”(来自以前)的意思,在这里就是来自于子集的频繁信息咯,不懂,别着急。下面给出几个简单的交易数据,如(图一)所示: 

图一 
(图一)


  我们的目标就是找到经常在一起出现的频繁子集,集合哦。我们用大括号“{}”来表示集合。为了表示某个子集是否是频繁子集,我们需要用一些量化方法,光计数也不行,因为不同量的交易数据出现的次数差别很大,一般用支持度(support)和置信度(confident)这两个指标来量化频繁子集、关联规则。这两个指标的计算都很简单:

 

  支持度=(包含该子集的交易数目)/总交易数目

  比如{豆奶}的支持度为4/5,有四条交易数据都有豆奶,而{豆奶,尿布}的支持度为3/5。

  置信度只是针对像{尿布}->{葡萄酒}的关联规则来定义的: 
  尿布到葡萄酒的置信度=支持度({尿布,葡萄酒})/支持度(尿布)

  比如在(图一)中,{尿布,葡萄酒}的支持度为3/5,而尿布的支持度为4/5,那么尿布->葡萄酒的可信度为3/4=0.75。 

图二 
(图二)


  (图二)中只有四种商品{0,1,2,3},而其子集则有2^4-1=15个(空子集除外),每计算一个子集的两个指标都需要遍历一下数据,要遍历15次,如果有100种商品,则有1.26*10^30个子集,这个计算量很大,所幸的是研究人员发现了一种Apriori原理:Apriori原理是说如果某个子集不是频繁的,那么包含它的所有超集也不是频繁的,这样一下就砍掉了一大半,如(图三)所示: 

图三 
(图三)


  (图三)中{2,3}不是频繁的,那么所有包含它的超子集都不是频繁的,有了这个原则,就使得我们计算频繁子集的变成可行的。有了Apriori原理作为指导,我们还需要一些trick 来实现代码,这些trick就构成了Apriori(a priori一个先验)算法伪代码: 
  当集合中项的个数大于0时 
    构建一个k个项组成的候选项集的列表 
    检查数据已确认每个项集都是频繁的 
    保留频繁项集并构建k+1项组成的候选项集的列表

 

11.利用FP-grownth算法来高效发现频繁项集

  FP-growth算法只需要对数据库进行两次扫描,而Apriori算法对于每个潜在的频繁项集都会扫描数据集判定给定模式是否频繁,FP-growth比Apriori算法快。缺点:实现复杂 

图三 
(图三)


  伪代码(poseudo_code): 
  procedure FP_growth(Tree, a) 
  if Tree 含单个路径P then{ 
    for 路径P中结点的每个组合(记作b) 
    产生模式b U a,其支持度support = b 中结点的最小支持度; 
  } else { 
    for each aiai 在Tree的头部(按照支持度由低到高顺序进行扫描){ 
      产生一个模式b = aiai U a,其支持度support = aiai .support; 
      构造b的条件模式基,然后构造b的条件FP-树Treeb; 
      if Treeb 不为空 then 
        调用 FP_growth (Treeb, b); 
    } 
  }

 

分布式(distributed)

12.大数据和MapReduce

  为什么 
  当运算需求超出了当前资源的运算能力,可以考虑购买更好的机器。另一个情况是,运算需求超出了合理价位下所能够买到的机器的运算能力。其中一个解决办法是将计算转成并行的作业,MapReduce就提供了这种方案的一个具体实施框架。在MapReduce中,作业被分成map阶段和reduce阶段。 
  是什么 
  一个点行的作业流程是先使用map阶段并行处理数据,之后将这些数据在reduce阶段合并。这种多对一的模式很经典,但不是唯一的流程方式。mapper和reducer之间传输数据的形势是key/value对。一般地,map阶段后数据还会按照key值进行排序。Hadoop是一个流行的可运行MapReduce作业的Java项目,它同时也提供非Java作业的运行支持,叫做Hadoop流。 
  怎么做 
  Amazon 网络服务(AWS)允许用户按时长租借计算资源。弹性MapReduce(EMR)是Amazon网络服务上的一个常用工具,可以帮组用户在AWS上运行Hadoop流作业。简单的单步MapReduce任务可以在EMR管理控制台上实现并运行。更复杂的任务则需要额外的工具。其中一个相对新的开源工具是mrjob,使用该工具可以顺序地执行大量的MapReduce作业。经过很少的配置,mrjob就可以自动完成AWS上的各种繁杂步骤。 
  很多机器学习算法都可以很容易地写成MapReduce作业。而另一些机器学习算法需要经过创新性的修改,才能在MapReduce上运行。SVM是一个强大的文本分类工具,在大量文档上训练一个分类器需要耗费巨大的计算资源,而Pegasos算法可以分布式地训练SVM分类器。像Pegasos算法一样,需要多次MapReduce昨夜的机器学习算法可以很方便地使用mrjob来实现。

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号