《机器学习实战》——读书笔记1

前言
在大学里,最好的方面不是你研修的课程或从事的研究,而是一些外围活动:与人会面、参加研讨会、加入组织、旁听课程,以及学习未知的知识。
一个机构会雇佣一些理论家(思考者)以及一些做实际工作的人(执行者)。前者可能会将大部分时间花在学术工作上,他们的日常工作就是基于论文产生思路,然后通过高级工具或教学进行建模。后者则通过编写代码与真实世界交互,处理非理想世界中的瑕疵,比如崩溃的及其或带噪声的数据。并不能完全区分两类人。

第一部分 分类

前两部分主要探讨监督学习。监督学习一般使用两种类型的目标变量:标称型(有限目标集)和数值型(无限的数值集合)。

第 1 章 机器学习基础

机器学习能让我们自数据集中受到启发,换句话说,我们会利用计算机来彰显数据背后的真实含义。

1.1 何谓机器学习

机器学习就是把无数的数据转换成有用的信息。
机器学习横跨计算机科学、工程技术和统计学等多个学科,对于任何需要解释并操作数据的领域都有所裨益。
机器学习用到了统计学知识,因为现实世界中很多例子我们无法位置简历精确的数学模型,所以需要统计学工具。

1.1.1 传感器和海量数据

互联网有大量的非人为数据,举了地震预测的例子,讲述了移动计算和传感器产生海量数据。

1.1.2 机器学习非常重要

大量的经济活动都依赖于信息,我们不能再海量的数据中迷失,机器学习将有助于我们穿越数据雾霭,从中抽取出有用的信息。

1.2 关键术语

特征、分类、训练集、目标变量、测试数据、知识表示

1.3 机器学习的主要任务

监督学习:分类和回归。无监督学习:聚类和密度估计。
这里写图片描述

1.4 如何选择合适的算法

必须考虑两个问题:一、使用机器学习算法的目的,想要算法完成何种任务。二、需要分析或收集的数据是什么。

1.5 开发机器学习应用程序的步骤

1、收集数据
2、准备输入数据
3、分析输入数据
4、训练算法
5、测试算法
6、使用算法

1.6 Python语言的优势

三个原因:(1)Python的语法清晰;(2)易于操作纯文本文件;(3)使用广泛,存在大量的开发文档。

1.6.1 可执行伪代码

Python具有清晰的语法结构,并且语言处理和操作文本文件非常简单。

1.6.2 Python比较流行

1.6.3 Python语言的特色

和MATLAB相比是免费的,其插件是开源的。
和Java、C相比,不需要编写大量冗余的代码。

1.6.4 Python语言的缺点

运行效率不高。

1.7 NumPy函数库基础

几个命令random.rand(4,4)产生4*4的随机数组。
randMat=mat(random.rand(4*4))产生矩阵

矩阵与数组的区别~

randMat.I 矩阵的逆 eye(n)n阶单位阵

1.8 本章小结

机器学习广泛应用于日常生活中,每天处理的数据不断增加,能够深入理解数据背后的真实含义,是数据驱动产业必须具备的基本技能。

第 2 章 k-近邻算法

知乎大神的相关笔记!
首先,我们将探讨k-近邻算法的基本理论,以及如何使用距离测量的方法分类物品;其次我们将使用Python从文本文件中导入并解析数据;再次,本书讨论了当存在许多数据来源时,如何避免计算距离时可能碰到的一些常见错误;最后,利用实际的例子讲解如何是所有k-近邻算法改进约会网站和手写数字识别系统。

2.1 k-近邻算法概述

简单地说,k-近邻算法采用测量不同特征值之间的距离方法进行分类。
k-近邻算法
优点:精度高、对异常值不敏感,无数据输入假定
缺点:计算复杂度高、空间复杂度高
使用数据范围:数值型和标称型

k-近邻算法的工作原理:在训练样本集中,每个数据都存在标签,即我们知道样本集中每一数据与所属分类的对应关系。输入没有标签的新数据后,将新数据的每个特征与样本集中数据对应的特征进行比较,然后算法提取样本集中特征最相似数据(最近邻)的分类标签。一般来说,我们只选择样本数据即中前k(通常k<20)个最相似的数据。最后选择k个最相似数据中出现次数最多的分类,作为新数据的分类。

k-近邻算法的一般流程
1、收集数据:可以使用任何方法
2、准备数据:距离计算所需要的数值,最好是结构化的数据格式
3、分修数据:可以使用任何方法
4、训练算法:此步骤不适用于k-近邻算法
5、测试算法:计算错误率
6、使用算法:首先需要输入样本数据和结构化的输出结果,然后运行k-近邻算法判定输入数据分别术语哪个分类,最后应用对计算出的分类执行后续的处理。

2.1.1 准备:使用Python导入数据

这里写图片描述

2.1.2 实施kNN算法

这里写图片描述

2.1.3 如何测试分类器

使用已知答案的数据。

2.2 示例:使用k-近邻算法改进约会网站的配对效果

示例:在约会网站上使用k-近邻算法
(1) 收集数据:提供文本文件。
(2) 准备数据:使用Python解析文本文件。
(3) 分析数据:使用Matplotlib画二维扩散图。
(4) 训练算法:此步骤不适用于k-近邻算法。
(5) 测试算法:使用海伦提供的部分数据作为测试样本。
测试样本和非测试样本的区别在于:测试样本是已经完成分类的数据,如果预测分类与实际类别不同,则标记为一个错误。
(6) 使用算法:产生简单的命令行程序,然后海伦可以输入一些特征数据以判断对方是否为自己喜欢的类型。

2.2.1 准备数据:从文本文件中解析数据

在将特征数据输入到分类器之前,必须将待处理数据的格式改变为分类器可以接受的格式。

Numpy数组和Python数组
由于NumPy库提供的数组操作并不支持Python自带的数组类型,因此在编写代码时要注意不要使用错误的数组类型。

2.2.2 分析数据:使用Matplotlib创建散点图

具体可见Matplotlib简明教程

import matplotlib
import matplotlib.pyplot as plt
fig=plt.figure()
ax=fig.add_subplot(111)
ax.scatter(datingDataMat[:,1],datingDataMat[:,2]
#或者 ax.scatter(datingDataMat[:,1],datingDataMat[:,2],15.0*array(datingLabels),15.0*array(datingLabels))
plt.show()

2.2.3 准备数据:归一化数值

def autoNorm(dataSet):
    minVals=dataSet.min(0)#对于dataSet这个矩阵返回每一列的最小值
    maxVals=dataSet.max(0)
    ranges=maxVals-minVals
    normDataSet=zeros(shape(dataSet))
    m=dataSet.shape[0]
    normDataSet=dataSet-tile(minVals,(m,1))
    normDataSet=normDataSet/tile(ranges,(m,1))
    return normDataSet,ranges,minVals

2.2.4 测试算法:作为完整程序验证分类器

随机选择一些数据测试分类器。

def datingClassTest():
    hoRatio=0.10
    datingDataMat,datingLabels=file2matrix('datingTestSet2.txt')
    normMat,ranges,minVals=autoNorm(datingDataMat)
    m=normMat.shape[0]
    numTestVecs=int(m*hoRatio)
    errorCount=0.0
    for i in range(numTestVecs):
        classifierResult=classify0(normMat[i,:],normMat[numTestVecs:m,:],datingLabels[numTestVecs:m],3)
        print "the classifier came back with %d, the real answer is: %d" %(classifierResult,datingLabels[i])
        if (classifierResult!=datingLabels[i]): errorCount+=1.0
    print "the total error rate is: %f"%(errorCount/float(numTestVecs))

2.2.5 使用算法:构建完整可用系统

def classifyPerson():
    resultList=['not at all','in small doses','in large doses']
    percentTats=float(raw_input("percentage of time spent playing video games?"))
    ffMiles=float(raw_input(("frequent flier miles earned per year?")))
    iceCream=float(raw_input("liters of ice cream consumed per year?"))
    datingDataMat,datingLabels=file2matrix('datingTestSet2.txt')
    normMat, ranges, minVals = autoNorm(datingDataMat)
    inArr=array([ffMiles,percentTats,iceCream])
    classifierResult=classify0((inArr-minVals)/ranges,normMat,datingLabels,3)
    print "You will probably like this person: ",resultList[classifierResult-1]

2.3 示例:手写识别系统

识别数字0-9

2.3.1 准备数据:将图像转换为测试向量

编写img2vector,创建1*1024的NumPyt数组,然后打开指定文件,将文件存储到NumPy数组中,返回数组。

def img2vector(filename):
    returnVect=zeros((1,1024))
    fr=open(filename)
    for i in range(32):
        lineStr=fr.readline()
        for j in range(32):
            returnVect[0,32*i+j]=int(lineStr[j])
    return returnVect

2.3.2 测试算法:使用k-近邻算法识别手写数字

from os import listdir 从os模块中导入函数listdir,列出给定目录的文件名。

def handwritingClassTest():
    hwLabels=[]
    trainingFileList=listdir('trainingDigits')
    m=len(trainingFileList)
    trainingMat=zeros((m,1024))
    for i in range(m):
        fileNameStr=trainingFileList[i]
        fileStr=fileNameStr.split('.')[0]
        classNumStr=int(fileStr.split('_')[0])
        hwLabels.append(classNumStr)
        trainingMat[i,:]=img2vector('trainingDigits/%s'%fileNameStr)
    testFileList=listdir('testDigits')
    errorCount=0.0
    mTest=len(testFileList)
    for i in range(mTest):
        fileNameStr=testFileList[i]
        fileStr=fileNameStr.split('.')[0]
        classNumStr=int(fileStr.split('_')[0])
        vectorUnderTest=img2vector('testDigits/%s'%fileNameStr)
        classifierResult=classify0(vectorUnderTest,trainingMat,hwLabels,3)
        print "the classifier came back with: %d, the real answer is: %d"% (classifierResult,classNumStr)
        if (classifierResult!=classNumStr):errorCount+=1.0
    print "\n the total number of errors is: %d"% errorCount
    print "\n the total error rate is: %f"%(errorCount/float(mTest))

2.4 本章小结

k-近邻算法是分类数据最简单最有效的算法。k-近邻算法是基于实力的学习,使用算法时我们必须有接近实际数据的训练样本数据。k-近邻算法必须保存全部数据集,如果训练数据集很大,必须使用大量的存储空间。此外,由于必须对数据集中每个数据计算距离值,实际使用可能非常耗时。
k-近邻算法的另一个缺陷是它无法给出任何数据的基础结构信息,因此我们无法知晓平均实例样本和典型实例样本具有什么特征。概率测量方法可以解决该问题。

第 3 章 决策树

k-近邻算法可以完成很多分类任务,但最大的缺点在于无法给出数据的内在含义,决策树的主要优势就在于数据形式非常容易理解。

3.1 决策树的构造

决策树
优点:计算复杂度不高,输出结果易于理解,对中间值的缺失不敏感,可以处理不相关特征数据。
确定:可能会产生过度匹配问题
使用数据类型:数值型和标称型
首先我们讨论数学上如何使用信息论划分数据集,然后编写代码将理论应用到具体的数据集上,最后编写代码构建决策树。
首先要解决的问题:评估每个特征,找到决定性的特征。
决策树的一般流程
1、收集数据:可以使用任何方法。
2、准备数据:树构造算法只适用于标称型数据,因此数值型数据必须离散化。
3、分析数据:可以使用任何方法,构造树完成之后,我们应该检查图形是否符合预期。
4、训练算法:构造树的数据结构
5、测试算法:使用经验树计算错误率。
6、使用算法:此步骤可以适用于任何监督学习算法,而使用决策树可以更好地理解数据的内在含义。
本书使用ID3算法划分数据集。

3.1.1 信息增益

划分数据集的大原则:将无序的数据变得更加有序。
组织杂乱无章数据的一种方法就是使用信息论度量信息。
在划分数据集之前之后信息发生的变化成为信息增益。集合信息的度量方式成为香农熵或熵。
如果待分类的事务可能划分在多个分类之中,则符号 xi 的信息定义为

l(xi)=log2p(xi)

其中 p(xi) 是选择该分类的概率。
所有类别所有可能值包含的信息期望值
H=i=1np(xi)log2p(xi)

其中n是分类的数目。

from math import log
def calcShannonEnt(dataSet):
    numEntries=len(dataSet)
    labelCounts={}
    for featVec in dataSet:
        currentLabel=featVec[-1]
        if currentLabel not in labelCounts.keys():
            labelCounts[currentLabel]=0
        labelCounts[currentLabel]+=1
        shannonEnt=0.0
    for key in labelCounts:
        prob =float(labelCounts[key])/numEntries
        shannonEnt-=prob*log(prob,2)
    return shannonEnt

得到熵之后,按照获取最大信息增益的方法划分数据集。
另一个度量集合无序程度的方法是基尼不纯度,简单地说是从一个数据集中随机玄子子项,度量其被错误分类到其他分组里的概率。

3.1.2 划分数据集

除了需要测量信息熵,还需要划分数据集,度量划分数据集的熵,以便判断当前是否正确地划分了数据集。

def splitDataSet(dataSet,axis,value):
    retDataSet=[]
    for featVec in dataSet:
        if featVec[axis]==value:
            reducedFeatVec=featVec[:axis]
            reducedFeatVec.extend(featVec[axis+1:])
            retDataSet.append(reducedFeatVec)
    return retDataSet

遍历整个数据集,循环计算香农熵和splitDataSet()函数,找到最好的特征划分方式。

def chooseBestFeatureToSplit(dataSet):
    #选取特征,划分数据集,计算得出最好的特征
    numFeatures=len(dataSet[0])-1
    baseEntropy=calcShannonEnt(dataSet)
    bestInfoGain=0.0;bestFeature=-1
    for i in range(numFeatures):
        featList=[example[i] for example in dataSet]
        uniqueVals=set(featList)
        newEntropy=0.0
        for value in uniqueVals:
            subDataSet=splitDataSet(dataSet,i,value)
            prob=len(subDataSet)/float(len(dataSet))
            newEntropy+=prob*calcShannonEnt(subDataSet)
        infoGain=baseEntropy-newEntropy
        #信息增益是熵的减少,或数据无序度的减少。
        if (infoGain>bestInfoGain):
            bestInfoGain=infoGain
            bestFeature=i
    return bestFeature

3.1.3 递归构建决策树

工作原理如下:得到原始数据集,然后基于最好的属性值划分数据集,由于特征值可能多于两个,因此可能存在大于两个分支的数据集划分。第一次划分之后,数据将被向下传递到树分支的下一个节点,在这个节点上,我们可以再次划分数据。因此我们可以采用递归的原则处理数据集。
递归结束的条件是,程序遍历完所有划分数据集的属性,或者每个分支下的所有实例都具有相同的分类。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值