统计学习方法

目录:
1:kd树
2:k-邻近算法python
3:朴素贝叶斯
4:决策树
5:感知机模型
6:提升方法AdaBoost算法
7:提升树模型
8:EM算法
生成模型:朴素贝叶斯法,隐马尔科夫模型(EM算法)

判别模型:k近邻,感知机,决策树,logist回归,最大熵模型,支持向量机,
提升方法和条件随机场(CRF)
简单形象的介绍了生成模型和判别模型的区别:
http://blog.csdn.net/lk7688535/article/details/52353350
算是稍微强化版的生成模型和判别模型的解释吧,加了一点简单的例子:
http://blog.csdn.net/Fishmemory/article/details/51711114

一:kd树

目的:
k邻近算法实现时,需要计算所有点到目标点的距离,计算量有点大,是为了减少计算,发明了kd树这种存储方法:

划分原理:

  • 比如数据有k维,即每一个x都有k个数据,在第一个维度上找到中位数,以这个点为界限将数据分为两半,这个点作为根节点。
  • 再在第二个维度上分别在小区域上找中位数,又把第一步的两个小块又分为四块了,这两个节点作为二级节点。
  • 一直继续,直到k维分完之后,又从第一维接着来,直到分的小块里面没有目标点。

    实例:
    这里写图片描述

    这里写图片描述

搜寻最近点原理:

  • 给定一个目标点之后,按照树的条件,从上往下找(如:x1<7就往左,否则往右…….),找到对应的叶节点,暂时把该点作为最近点。
  • 判断与子节点的父节点的距离是不是
  • 找到当前结点的兄弟节点(即同一个父节点的另一个点),看是否和圆形相交(圆是什么就不说了吧),不相交的话就再上一级继续判断,相交的话就找有没有更近的点。
  • 找到更近的点之后,如果该点不是叶节点,我认为还要继续判断该“最近点”的子节点。

    这里写图片描述

总结:
方法不行啊,也许是问题有点难?不知道,反正感觉这个算法也挺复杂的(这
还只是找最近的,还有找K 个最近的呢),再看吧。或许是我没理解。

二 k-邻近算法python

def classify0(intx,dataset,labels,k):   #1
    datasetSize=dataset.shape[0]
    diffMat =tile(intx,(datasetSize,1))-dataset
    diffMat =diffMat**2
    Distance = diffMat.sum(axis=1)
    Diatance = Distance**0.5
    sortedDistIndicies=Distance.argsort()  #2
    classCount={}
    for i in range (k):
        voteIlabels=labels[sortedDistIndicies[i]]   #3
          classCount[voteIlabels]=classCount.get(voteIlabel,0)+1   #4
    sortedClassCount=sorted(classCount.iteritems(),key=operator.itemgetter(1),reverse=True)        #5
    return sortedClassCount[0],[0]
  1. inx为目标对象,即是需要判断类别的对象。dataset,label,k为确定需要判断前几个对象。
  2. Distance.argsort() 作用为返回Distance中从小到大排序的样本的索引值。例如a =[4,1,2],则返回[1,2,0 ]
  3. 取出距离最小的样本的label
  4. classCount为字典(有键值对),作用为统计每个类出现的次数,classCount.get(voteIlabel,0) 作用为取voteIlabel对应的值,如果字典中没有voteIlabel,则取零。
  5. sortedClassCount是一个list,classCount.iteritems()为迭代输出字典的键值对。key=operator.itemgetter(1)作用是按照第二列的值进行排序,operator.itemgetter(1)本质上是一个函数。reverse(倒退)=True表示按照降序排列,若为Ture则是升序排列。

三 朴素贝叶斯

朴素贝叶斯是基于贝叶斯定理和特征条件独立假设的分类方法。
有一组样本(Wn,Cn),其中Wn为i维向量,C为其所属的label(共有k种)。Wn=(Wn1,Wn2,Wn3- - -Wni),C取(C1,C2,C3- - - Ck)。计算方法是:
分别计算出P(C1)到P(Ck);
P(W1|C1),P(W2|C1)- - - P(Wi|C1);
P(W1|C2),P(W2|C2)- - - P(Wi|C2);
——
——
P(W1|Ck),P(W2|Ck)- - - P(Wi|Ck);

新样本(w1,w2,w3- - - wi)属于Cj的概率是:
P(Cj)=P(Cj)x P(W1|Cj)x P(W2|Cj)x ……..x P(Wi|Cj);
分别计算出属于每个类的概率,然后取最大的那个作为最后结果。

朴素贝叶斯的主要优点有

    1)朴素贝叶斯模型发源于古典数学理论,有稳定的分类效率。

    2)对小规模的数据表现很好,能个处理多分类任务,适合增量式训练,尤其是数据量超出内存时,我们可以一批批的去增量训练。

    3)对缺失数据不太敏感,算法也比较简单,常用于文本分类。

朴素贝叶斯的主要缺点有:   

    1) 理论上,朴素贝叶斯模型与其他分类方法相比具有最小的误差率。但是实际上并非总是如此,这是因为朴素贝叶斯模型给定输出类别的情况下,假设属性之间相互独立,这个假设在实际应用中往往是不成立的,在属性个数比较多或者属性之间相关性较大时,分类效果不好。而在属性相关性较小时,朴素贝叶斯性能最为良好。对于这一点,有半朴素贝叶斯之类的算法通过考虑部分关联性适度改进。

    2)需要知道先验概率,且先验概率很多时候取决于假设,假设的模型可以有很多种,因此在某些时候会由于假设的先验模型的原因导致预测效果不佳。

    3)由于我们是通过先验和数据来决定后验的概率从而决定分类,所以分类决策存在一定的错误率。

    4)对输入数据的表达形式很敏感。

用朴素贝叶斯判断一个句子是不是辱骂等不良信息:

#该代码是创建一个data,里面有六个句子及其所属的label(1代表不好的句子,0正常)
def loadDataSet():
    postingList=[['my', 'dog', 'has', 'flea', 'problems', 'help', 'please'],       #给出的里面有重复
                 ['maybe', 'not', 'take', 'him', 'to', 'dog', 'park', 'stupid'],#postingList是个list
                 ['my', 'dalmation', 'is', 'so', 'cute', 'I', 'love', 'him'],
                 ['stop', 'posting', 'stupid', 'worthless', 'garbage'],
                 ['mr', 'licks', 'ate', 'my', 'steak', 'how', 'to', 'stop', 'him'],
                 ['quit', 'buying', 'worthless', 'dog', 'food', 'stupid']]
    classVec = [0,1,0,1,0,1]    #1 is abusive, 0 not
    return postingList,classVec
#求总共需要检测的检测单词,本例将检验所有的单词,取并可以去除重复的单词,set中不能包含重复的元素
def createVocabList(dataSet):
    vocabSet = set()  #create empty 
    for document in dataSet:
        vocabSet = vocabSet | set(document) #union of the two sets,交只是set能用
    return list(vocabSet)
#将输入的句子转化为向量的形式
def setOfWords2Vec(vocabList, inputSet):
    returnVec = [0]*len(vocabList)
    for word in inputSet:
        if word in vocabList:
            returnVec[vocabList.index(word)] = 1       #vocabList.index(word)为找出word所在的索引
        else: print "the word: %s is not in my Vocabulary!" % word
    return returnVec
#计算相应的概率
def trainNBO(trainMatrix,trainCategroy):
    numTrainDocs=len(trainMatrix)
    numWords=len(trainMatrix[0])
    pAbusive=sum(trainCategroy)/float(numTrainDocs)
    p0Num=ones(numWords);p1Num=ones(numWords)   #创建numWords个零,后变为1,参考统计学习方法,
                                                #是拉普拉斯平滑,目的是为了去除零的影响
    p0Denom=2.0;p1Denom=2.0    #denom的意思为分母,后2.0(等于样本中每个特征能取到的类别数,本例中一个单词有1和0两个状态,再乘上拉姆达,即2*上面的0)
    for i in range (numTrainDocs):
        if trainCategroy[i]==1:
            p1Num+=trainMatrix[i]              #1*n维向量
            p1Denom +=sum(trainMatrix[i])        #分母
        else:
            p0Num+=trainMatrix[i]
            p0Denom +=sum(trainMatrix[i])
    p1Vect=log(p1Num/p1Denom)              #每个单词出现的概率,
                                    #后加log为一是为防止多个接近零的数相乘是系统将零作为结果的情况
    p0Vect=log(p0Num/p0Denom)              
    return p0Vect,p1Vect,pAbusive     #p0Vect是一个概率向量,代表概率为零的样本中各
                                      #个单词出现的概率,所有概率和为1.p1Vect同理。pAbusive代表所
                                      #有样本中正样本的概率

这里写图片描述
我感觉这里还是有问题,不知道我想的对不对,以后再回来看看吧

#给一个样本判断label
def classifyNB(vec2classify,p0Vect,p1Vect,pAbusive):
    p1=sum(vec2classify*p1Vect)+log(pAbusive)
    p0=sum(vec2classify*p0Vect)+log(1-pAbusive)
    if p1>p0:
        return 1
    else:
        return 0
#将前面的集合到一起
def testingNB():
    listOPosts,listClasses=loadDataSet()
    myVocabList = createVocabList(listOPosts)
    trainMat=[]
    for poatinDoc in listOPosts:
        trainMat.append(setOfWords2Vec(myVocabList, poatinDoc))     #
    p0V,p1V,pAb =trainNBO(trainMat,listClasses)                        #暂定没加array
    testEntry=["love","my","dalmation"]
    thisDoc=setOfWords2Vec(myVocabList, testEntry)                      #还没加#
    print testEntry,'classified as',classifyNB(thisDoc,p0V,p1V,pAb)   
    testEntry=["stupid","garbage"]
    thisDoc=array(setOfWords2Vec(myVocabList, testEntry))     #还没加#
    print testEntry,'classified as',classifyNB(thisDoc,p0V,p1V,pAb)

四 决策树

问题:

  • 分类和回归两种情况下的应用
  • 划分决策树的依据
  • 评价的指标
  • 过拟合的处理(决策树的剪枝)

    决策树的内部节点表示特征或属性,叶节点表示一个类。
    特征选择的准则是信息增益或信息增益比
    这里写图片描述

其中0<=H(x)<=log|x|
当X全部属于某一类时等于零,当X是均匀分布时等于log|X|。也就是说,当X服从均匀分布时,熵最大。
在服从条件约束的条件下,选择最优模型(未知条件等可能)。

这里写图片描述

CART(classification and regression tree)算法:
- 每个节点上最多有两个子节点
- 用验证数据集进行剪枝

一 决策树的生成:
对回归树用平方误差最小化准则,对分类树用基尼指数最小化准则。
二 决策树的剪枝:
首先从生成算法产生的决策树T底端开始不断剪枝,直到T的根节点,形成一个子树序列;然后通过交叉验证法在独立的验证数据集上对子树序列进行测试,从中选择最优子树。

五 感知机模型:

感知机是根据输入实例的特征向量x对其进行二类分类的线性分类模型。本章只考虑线性可分的情况,是对支持向量机的简化。求解是利用梯度下降方法,详细方法可以分为两种:原始形式和对偶形式。
感知机的损失函数是误分类的点到分隔平面的距离之和,这个损失函数关于参数连续可导。

感知机与SVM的区别:感知机只是一个线性可分的二分类问题,并且只要求正确分类就行,有好多个正确的解;SVM除了线性可分还有不可分情况,还有多分类情况,并且要求必须是最佳分类,即分离平面在最中间的位置,只有一种解。

原始形式求解:
损失函数:损失函数
梯度下降规则:梯度下降规则
对偶形式求解:
对偶形式的主要思想:将参数w和b表示为实例的线性组合形式,通过求解其系数而求得参数w和b。
这里写图片描述这里写图片描述
这里erfa是一个三维向量,因为一共有三个训练数据,用来表示这三个数据的线性组合。求出这个向量后,再求参数w。(需要注意对偶形式下判断误分类的式子,还有这里有Gram矩阵的计算这个)

六 提升方法AdaBoost算法

1 基本思路

强可学习:是指在概率近似正确学习的框架中,一个概念(一个类),如果存在一个多项式算法能够学习它,并且正确率很高,那么就称这个概率是强可学习的。
弱可学习:是指在概率近似正确学习的框架中,一个概念(一个类),如果存在一个多项式算法能够学习它,学习的正确率仅仅比随机猜测略好,那么就称这个概率是弱可学习的。
后来证明了强可学习和弱可学习是等价的,那么AdaBoost的思路就是将弱可学习提升为强可学习。由于弱分类器的学习比较容易,所以可以由一系列的弱可学习,组合得到一个强可学习。
对于提升问题来说有两个问题需要解决:
1:在每一轮如何改变训练数据的权值或概率分布。
AdaBoost的做法是提高那些被前一轮分类器错误分类的样本的权值,降低那些被前一轮分类器分类正确的样本的权值。权值的大小代表了被下一轮分类器重视的程度。
2:如何将弱分类器组合成强分类器。
AdaBoost采用加权多数表决的方法,具体的,加大分类正确率高的分类器的权值,减小分类正确率低的分类器的权值。
下面贴出AdaBoost算法的定义图:
这里写图片描述这里写图片描述

    首先平均的初始化各个样本的权重,然后学习一个弱分类器,计算其在样本上的分类误差率(这里的误差率是指错误分类的样本的权重之和,所有样本的权重总和为1),在计算该分类器在最终分类器中所占的权值(误差率越大,权值越小),接下来更新样本中的权重(正确分类的权重减小,错误分类的权重增大,权重总和仍为一)。最后构建最终的分类器。
    Zm是一个规范化因子,目的是保证权重和为一,原权重乘以exp(-权重*Yi*Gm(Xi)),其中Gm(Xi)表示使用当前分类器预测的结果,其与Yi相乘目的就是判断预测结果是不是一致,若一致,则权重减小,若不一致,则权重增大。

AdaBoost模型是加法模型,损失函数是指数损失,算法是前向分步算法

接下来贴出一个例子来说明AdaBoost算法:
这里写图片描述这里写图片描述这里写图片描述
错误率是分类错误的样本的权重的和,即后面几个根据调整后的权重提出分类器的根据是:使得分类错误的样本的权重的和最小。

AdaBoost算法应用于人脸检测

里面简要的介绍了AdaBoost算法和其在人脸识别中的应用:
https://wenku.baidu.com/view/134b39f18bd63186bcebbcc7.html
原理:利用Haar特征构造弱分类器,组合出来的强分类器用cascade结构连级用来进行人脸检测。
Haar特征概述:http://blog.csdn.net/lanxuecc/article/details/52222369
论文rapid object detection using a Boosted cascade of simple feature里面检测人脸的算法:
face
feature:特征f;threshold:阈值theta;polarity:判断不等号方向的意思p
这里写图片描述
AdaBoost算法的优点:
1 AdaBoost是一种有很高精度的分类器。
2 可以使用各种方法构建子分类器,AdaBoost算法提供的是一个框架。
3 当使用简单分类器时,计算出的结果是可以理解的。
4 弱分类器的构造极其简单,不用做特征删选。
5 不担心overfitting(过度拟合)!
自己瞎猜:相对于深度学习,AdaBoost算法有体积小,需要的数据少,容易在小的设备(便携式设备)上实现。

七 提升树模型

整体思路和上面的AdaBoost方法差不多,实际上AdaBoost就是一个提升树。二分类问题的提升树算法是AdaBoost的特殊情况。下面主要叙述回归问题的提升树
废话不多说,直接上算法:
这里写图片描述这里写图片描述

提升树的一个例子:

这里写图片描述这里写图片描述这里写图片描述这里写图片描述这里写图片描述

八 EM算法

如果概率模型的变量都是观测变量,那么给定数据,可以直接用极大似然估计法,或贝叶斯估计法估计模型参数。但是,当含有隐变量时,就不能简单地使用这些方法。EM算法就是含有隐变量的概率模型参数的极大似然估计法,或极大后验概率估计法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值