读书笔记-《机器学习实战:基于Scikit-LearnKeras和TensorFlow》 第2版(第一章)

Posted 帅到被人砍

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了读书笔记-《机器学习实战:基于Scikit-LearnKeras和TensorFlow》 第2版(第一章)相关的知识,希望对你有一定的参考价值。

第一章 机器学习概览

  • 因为本身对机器学习有一定的了解,所以直接回答本章节的课后习题
  • 本章节的课后习题都是必须要掌握的机器学习中的一些基本概念,注重理解。

章节练习

  1. 如何定义机器学习?

    广义概念:机器学习是让计算机具有学习的能力,无需进行明确编程。

    工程性概念:计算机程序利用经验E学习任务T,性能是P,如果针对任务T的性能P随着经验E不断增长,则称为机器学习。

  2. 机器学习可以解决的四类问题?

    图像分类,语音识别,语义分割,情感分析

  3. 什么是带标签的训练集?

    在监督学习中,标记训练集是具有可用目标的数据集。这意味着你想要预测的东西在训练之前就已经知道。

    例如:正常域名与恶意域名对应的标签(正常/恶意)组成的训练集。

  4. 最常见的两个监督任务是什么?

    分类问题:结果有限个,可以被分类

    回归问题:结果有无限个,是连续的

  5. 指出四个常见的非监督任务

    聚类、可视化、降维、异常检测等

  6. 让一个机器人在各种未知地形行走,你会采用什么机器学习算法?

    强化学习。对于能走的路激励,对于不能走的路惩罚,从而不断强化行走的能力。

  7. 对顾客进行分组,你会采用哪种算法?

    非监督算法进行聚类分析。

  8. 垃圾邮件检测是监督学习还是非监督学习?

    监督学习

  9. 什么是在线学习系统?

    在线学习系统在投入生产后会继续从新数据中学习,而批量学习模型在初始训练过程后就会停止学习

  10. 什么是核外学习?

    核外学习可以处理计算机主内存无法应对的大量数据。它将数据分割成小批量,然后使用在线学习技术从这些小批量中学习。当训练数据无法装入计算机的内存时,我们使用核心外学习。

  11. 什么学习算法使用相似度做预测?

    基于实例的模型,比如k近邻算法。

  12. 模型参数和学习算法的超参数区别是什么?

    模型有一个或多个参数,这些参数决定了模型对新的给定实例会做出怎样的预测(比如,线性模型的斜率)。学习算法试图找到这些参数的最佳值,使得该模型能够很好地泛化至新实例。超参数是学习算法本身的参数,不是模型的参数(比如,要应用的正则化数量)。你可以自己定义他们的数值。

  13. 基于模型的学习算法搜索的是什么?它们最常使用的策略是什么?它们如何做出预测?

    基于模型的学习算法搜索的是使模型泛化最佳的模型参数值。

    通常通过使成本函数最小化来训练这样的系统,成本函数衡量的是系统对训练数据的预测有多坏,如果模型有正则化,则再加上一个对模型复杂度的惩罚。

    学习算法最后找到的参数值就是最终得到的预测函数,只需要将实例特征提供给这个预测函数即可进行预测。

  14. 机器学习的四个主要挑战是什么?

    训练数据量不足、没有代表性数据、低质量数据、不相关特征、过拟合训练数据、欠拟合训练数据等

  15. 如果模型在训练集上表现好,但预测表现差,是什么原因?给出三种解决方案。

    如果模型在训练数据上表现很好,但是对新实例的泛化能力很差,那么该模型很可能过度拟合训练数据(或者在训练数据上运气太好)。

    可能的解决方案是:获取更多数据,简化模型(选择更简单的算法、减少使用的参数或特征数量、对模型正则化),或者是减少训练数据中的噪声。

  16. 什么是测试集,为什么要使用他?

    使用测试集来估算模型在实例上的泛化误差,评估模型的好坏并加以优化。

  17. 验证集目的什么?

    验证集可以用来比较不同模型。它可以用来选择最佳模型和调整超参数。

  18. 如果用测试集调节超参数,会发生什么?

    会有过度拟合测试集的风险,最后测量的泛化误差会过于乐观,导致最后模型比预期的要差。

  19. 什么是交叉验证?他为什么比验证集更好?

    通过交叉验证技术,可以不需要单独的验证集实现模型比较(用于模型选择和调整超参数)。这节省了宝贵的训练数据。

机器学习实战读书笔记基于概率论的分类方法:朴素贝叶斯

4.1 基于贝叶斯决策理论的分类方法

  朴素贝叶斯

  优点:在数据较少的情况下仍然有效,可以处理多类别问题

  缺点:对于输入数据的准备方式较为敏感

  适用数据类型:标称型数据

  贝叶斯决策理论的核心思想:选择具有最高概率的决策。

4.2 条件概率

4.3 使用条件概率来分类

4.4 使用朴素贝叶斯进行文档分类

  朴素贝叶斯的一般过程:

  1.收集数据

  2.准备数据

  3.分析数据

  4.训练算法

  5.测试算法

  6.使用算法

  朴素贝叶斯分类器中的另一个假设是,每个特征同等重要。

4.5 使用Python进行文本分类

4.5.1 准备数据:从文本中构建词向量

  建立bayes.py文件

def loadDataSet():
    postingList=[[my, dog, has, flea, problems, help, please],
                 [maybe, not, take, him, to, dog, park, stupid],
                 [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
                 
def createVocabList(dataSet): 
    vocabSet = set([])  #create empty set
    for document in dataSet:
        vocabSet = vocabSet | set(document) #union of the two sets
    return list(vocabSet)

def setOfWords2Vec(vocabList, inputSet):
    returnVec = [0]*len(vocabList)
    for word in inputSet:
        if word in vocabList:
            returnVec[vocabList.index(word)] = 1
        else: print "the word: %s is not in my Vocabulary!" % word
    return returnVec
import bayes
listOPosts,listClasses=bayes.loadDataSet() #
myVocabList=bayes.createVocabList(listOPosts)
bayes.setOfWords2Vec(myVocabList,listOPosts[0])
bayes.setOfWords2Vec(myVocabList,listOPosts[3])

4.5.2 训练算法,从词向量计算概率

  改写贝叶斯,使用以下公式:

  技术分享

  w为向量,p(w|ci)可以展开为p(w0,w1...wN|ci),假设所有词相互独立 ,那么该假设也称作条件独立性假设,这表示可以使用p(w0|ci)p(w1|ci)...p(wn|ci)计算上述概率。

  该函数伪代码如下:

  计算每个类别中的文档数目

  对每篇训练文档:

    对每个类别:

      如果词条出现在文档中->增加该词条的计数值

      增加所有词条的计数值

    对每个类别:

      对每个词条:

        将该词条的数目除以总词条数目得到条件概率

    返回每个类别的条件概率  

def trainNB0(trainMatrix,trainCategory):
    numTrainDocs = len(trainMatrix)
    numWords = len(trainMatrix[0])
    pAbusive = sum(trainCategory)/float(numTrainDocs)
    p0Num = zeros(numWords); p1Num = zeros(numWords)      #change to ones() 
    p0Denom = 0.0; p1Denom = 0.0                        #change to 2.0
    for i in range(numTrainDocs):
        if trainCategory[i] == 1:
            p1Num += trainMatrix[i]
            p1Denom += sum(trainMatrix[i])
        else:
            p0Num += trainMatrix[i]
            p0Denom += sum(trainMatrix[i])
    p1Vect = p1Num/p1Denom          #change to log()
    p0Vect = p0Num/p0Denom          #change to log()
    return p0Vect,p1Vect,pAbusive
trainMat=[]
for postinDoc in listOPosts:
    trainMat.append(bayes.setOfWords2Vec(myVocabList,postinDoc))
p0V,p1V,pAb=bayes.trainNB0(trainMat,listClasses)

4.5.3 测试算法:根据现实情况修改分类器

  利用贝叶斯分类器对文档进行分类时,要计算多个概率的乘积以获得文档属于某个类别的概率,即计算p(w0|1)p(w1|1)...,如果其中一个概率值为0,那么最后乘积也为0。为降低这种影响,可以将所有词的出现数初始化为1,并将分母初始化为2.

  修改TrainNB0()  

def trainNB0(trainMatrix,trainCategory):
    numTrainDocs = len(trainMatrix)
    numWords = len(trainMatrix[0])
    pAbusive = sum(trainCategory)/float(numTrainDocs)
    p0Num = ones(numWords); p1Num = ones(numWords)      #change to ones() 
    p0Denom = 2.0; p1Denom = 2.0                        #change to 2.0
    for i in range(numTrainDocs):
        if trainCategory[i] == 1:
            p1Num += trainMatrix[i]
            p1Denom += sum(trainMatrix[i])
        else:
            p0Num += trainMatrix[i]
            p0Denom += sum(trainMatrix[i])
    p1Vect = p1Num/p1Denom          #change to log()
    p0Vect = p0Num/p0Denom          #change to log()
    return p0Vect,p1Vect,pAbusive

  另一个遇到的问题是下溢出,这是由于太多很小的数相乘造成的。当计算p(w0|1)p(w1|1)...时,由于大部分因子都很小,所以程序会下溢出或得到不正确的答案。一种解决办法是对乘积取自然对数。在代数中有ln(a*b)=ln(a)+ln(b),于是通过求对数可以避免下溢出或者浮点数舍入导致的错误。同时,采用自然对数进行处理不会有任何损失。因此,修改TrainNB0

def trainNB0(trainMatrix,trainCategory):
    numTrainDocs = len(trainMatrix)
    numWords = len(trainMatrix[0])
    pAbusive = sum(trainCategory)/float(numTrainDocs)
    p0Num = ones(numWords); p1Num = ones(numWords)      #change to ones() 
    p0Denom = 2.0; p1Denom = 2.0                        #change to 2.0
    for i in range(numTrainDocs):
        if trainCategory[i] == 1:
            p1Num += trainMatrix[i]
            p1Denom += sum(trainMatrix[i])
        else:
            p0Num += trainMatrix[i]
            p0Denom += sum(trainMatrix[i])
    p1Vect = log(p1Num/p1Denom)          #change to log()
    p0Vect = log(p0Num/p0Denom)          #change to log()
    return p0Vect,p1Vect,pAbusive

  编写分类函数

def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):
    p1 = sum(vec2Classify * p1Vec) + log(pClass1)    #element-wise mult
    p0 = sum(vec2Classify * p0Vec) + log(1.0 - pClass1)
    if p1 > p0:
        return 1
    else: 
        return 0
    
def bagOfWords2VecMN(vocabList, inputSet):
    returnVec = [0]*len(vocabList)
    for word in inputSet:
        if word in vocabList:
            returnVec[vocabList.index(word)] += 1
    return returnVec

def testingNB():
    listOPosts,listClasses = loadDataSet()
    myVocabList = createVocabList(listOPosts)
    trainMat=[]
    for postinDoc in listOPosts:
        trainMat.append(setOfWords2Vec(myVocabList, postinDoc))
    p0V,p1V,pAb = trainNB0(array(trainMat),array(listClasses))
    testEntry = [love, my, dalmation]
    thisDoc = array(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)
bayes.testingNB()

4.5.4 准备数据:文档词袋模型

  词集模型:每个词出现一次。

  词袋模型:每个词在文档中出现不止一次。

  把setOfWords2Vec()改为bagOfWords2Vec()

def bagOfWords2VecMN(vocabList, inputSet):
    returnVec = [0]*len(vocabList)
    for word in inputSet:
        if word in vocabList:
            returnVec[vocabList.index(word)] += 1
    return returnVec

4.6 使用朴素贝叶斯过滤垃圾邮件

  1.收集数据:提供文本文件

  2.准备数据:将文本文件解析成词条向量

  3.分析数据:检查词条确保解析的正确性

  4.训练算法:使用我们之前建立的trainNB0()函数

  5.测试算法:使用classifyNB(),并且构建一个新的测试函数来计算文档集的错误率

  6.使用算法:构建一个完整的程序对一组文档进行分类,将错分的文档输出到屏幕上

4.6.1 准备数据:切分文本

4.6.2 测试算法:使用朴素贝叶斯进行交叉验证

  

def textParse(bigString):    #input is big string, #output is word list
    import re
    listOfTokens = re.split(r\W*, bigString)
    return [tok.lower() for tok in listOfTokens if len(tok) > 2] 
    
def spamTest():
    docList=[]; classList = []; fullText =[]
    for i in range(1,26):
        wordList = textParse(open(email/spam/%d.txt % i).read())
        docList.append(wordList)
        fullText.extend(wordList)
        classList.append(1)
        wordList = textParse(open(email/ham/%d.txt % i).read())
        docList.append(wordList)
        fullText.extend(wordList)
        classList.append(0)
    vocabList = createVocabList(docList)#create vocabulary
    trainingSet = range(50); testSet=[]           #create test set
    for i in range(10):
        randIndex = int(random.uniform(0,len(trainingSet)))
        testSet.append(trainingSet[randIndex])
        del(trainingSet[randIndex])  
    trainMat=[]; trainClasses = []
    for docIndex in trainingSet:#train the classifier (get probs) trainNB0
        trainMat.append(bagOfWords2VecMN(vocabList, docList[docIndex]))
        trainClasses.append(classList[docIndex])
    p0V,p1V,pSpam = trainNB0(array(trainMat),array(trainClasses))
    errorCount = 0
    for docIndex in testSet:        #classify the remaining items
        wordVector = bagOfWords2VecMN(vocabList, docList[docIndex])
        if classifyNB(array(wordVector),p0V,p1V,pSpam) != classList[docIndex]:
            errorCount += 1
            print "classification error",docList[docIndex]
    print the error rate is: ,float(errorCount)/len(testSet)
    #return vocabList,fullText

  以上程序,随机选择10篇作测试集,如果全部判对输出错误率0.0,若有错误则输出错分文档的词表。

4.7 未完成

  

以上是关于读书笔记-《机器学习实战:基于Scikit-LearnKeras和TensorFlow》 第2版(第一章)的主要内容,如果未能解决你的问题,请参考以下文章

机器学习实战读书笔记Logistic回归

读书笔记机器学习-周志华 & 机器学习实战(Python)

机器学习实战读书笔记——机器学习概览

机器学习实战读书笔记——端到端的机器学习项目

《机器学习实战》读书笔记2:K-近邻(kNN)算法

《深度学习之图像识别:核心技术与案例实战》读书笔记