【机器学习实战】监督式学习-分类

分类

2. K-近邻算法(KNN)

2.1 KNN概述

把需要分类的数据与已分类数据(训练集)进行比较,在前k个最近的样本中,选取分类最多的类别作为该数据的类别。属于无监督学习

  • 优点:精度高、对异常值不敏感、无数据输入假定
  • 缺点:计算复杂度高、空间复杂度高、无法得到任何数据的基础结构信息
  • 适用数据范围:数值型和标称型。
2.2 举例1:改进约会网站配对效果
  1. 准备数据:从文本文件中解析数据
  2. 分析数据:用Matplotlib创建散点图
  3. 准备数据:归一化数值
    • normValue = (value - min) / (max - min)
  4. 测试算法:验证分类器
  5. 使用算法:构建完整可用系统
2.3 举例2:手写系统识别
2.4 算法实现
def createDataSet():
    group = np.array([[1,1.1], [1, 1], [0, 0], [0, 0.1]])
    labels = ["A", "A", "B", "B"]
    return group, labels

def classify0(inX, dataSet, labels, k):
    dataSetSize = dataSet.shape[0]
    diffMat = np.tile(inX, (dataSetSize, 1)) - dataSet
    sqDiffMat = diffMat ** 2
    sqDistances = sqDiffMat.sum(axis=1)
    distances = sqDistances ** 0.5
    
    sortedDistIndicies = distances.argsort()  ## array排序,返回index顺序
    classCount = dict()
    for i in range(k):
        voteILabel = labels[sortedDistIndicies[i]]
        classCount[voteILabel] = classCount.get(voteILabel, 0) + 1
    sortedClassCount = sorted(
        classCount.iteritems(),  # dict转换为tuple list 排序
        key=operator.itemgetter(1),  # 生成器? 
        reverse=True
        )

    return sortedClassCount[0][0]
group, labels = createDataSet()
classify0([0, 0], group, labels, 3)  # output: B

3. 决策树(ID3算法)

3.1 决策树的构造
  • 优点:计算复杂度低,对中间值的确实不敏感,可以处理不相关的特征数据
  • 缺点:可能会产生过度匹配问题
  • 适用数据类型:标称型和数值型(需要离散化)

一般流程:

  1. 收集数据
  2. 准备数据:如对数值型数据离散化
  3. 分析数据
  4. 训练算法:构造数的数据结构
  5. 测试算法:使用经验树计算错误率
  6. 使用算法
3.1.1 信息增益
  • 信息熵:信息所包含的不确定性
    l ( x i ) = − l o g 2 p ( x 1 ) l(x_i) = -log_2p(x_1) l(xi)=log2p(x1)

  • 信息增益:信息不确定性减小的程度
    H = − Σ i = 1 n p ( x 1 ) l o g 2 p ( x 1 ) H = -\Sigma_{i=1}^n{p(x_1)log_2p(x_1)} H=Σi=1np(x1)log2p(x1)

分别计算每个特征的信息增益,每次选取信息增益最大的特征进行划分。

3.1.2 划分数据集

根据信息增益选取最佳划分特性

  • 循环对每个特征的特征值提取子数据集
  • 计算信息增益返回最佳划分特征
3.1.3 递归构建决策树

每次选择最佳特征进行数据集划分,并在划分后的子数据集中继续递归划分,直至每个分支下所有的实例都属于同一个分类。若已处理完所有的属性类标签仍不唯一,通常采用多数表决的方法决定该叶子节点的分类。

3.2 在Python中使用matplotlib注解绘制树形图
3.3 测试和存储分类器

(unfinished)

3.3.1 测试算法

使用测试集对决策树进行测试,并评估模型

3.3.2 使用算法

使用pickle存储决策树,后续要使用的时候直接反序列化读取使用

3.4 示例:使用决策树预测隐形眼镜的类型

(unfinished)

3.5 决策树算法实现
from math import log

## 1. 计算香农熵
def calcShannonEnt(dataSet):	
	"""	
	计算香农熵
	"""
    numEntries = len(dataSet)
    labelCountDict = {
   }
    ## 统计分类数
    for featVec in dataSet:
        currentLabel = featVec[-1]
        if currentLabel not in labelCountDict:
            labelCountDict[currentLabel] = 0
        labelCountDict[currentLabel] += 1
    ## 计算熵
    shannonEnt = 0
    for label, count in labelCountDict.items():
        prob = 1.0 * count / numEntries
        shannonEnt -= prob * log(prob, 2)
    return shannonEnt

## 2. 根据信息增益选择最佳划分特征
def splitDataSet(dataSet, axis, value):
    """
    按照给定的特征值抽取数据集
    """
    retDataSet = list()
    for featVec in dataSet:
        if featVec[axis] == value:
            reducedFeatVec = featVec[:axis]
            reducedFeatVec.extend(featVec[axis+1:])
            retDataSet.append(reducedFeatVec)
    return retDataSet

def chooseBestFeatureToSplit(dataSet):
    """
    选择最佳划分数据集
    """
    numFeatures = len(dataSet[0]) - 1
    baseEntropy = calcShannonEnt(dataSet)
    bestInfoGain = 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 = 1.0 * len(subDataSet) / len(dataSet)
            newEntropy += prob * calcShannonEnt(subDataSet)
        infoGain = baseEntropy - newEntropy    # 计算信息增益:总信息熵-特征信息熵
        if (infoGain > bestInfoGain):
            bestInfoGain = infoGain
            bestFeature = i
    return bestFeature
    
## 3. 构建递归决策树
def majorityCnt(classList):
    """
    投票表决
    """
    classCount = dict()
    for vote in classList:
        if vote not in classCount:
            classCount[vote] = 0
        classCount[vote] += 1
    sortedClassCount = sorted(classCount.iteritems(), key=lambda x: x[1], reverse=True)
    return sortedClassCount[0][0]

def createTree(dataSet, labels):
    """
    递归构建回归树
    """
    classList = [r[-1] for r in dataSet]
    if len(set(classList)) == 1:   # 只剩一个分类
        return classList[0]
    if len(dataSet[0]) == 1:    #用完所有的特征,只剩类别标签
        return majorityCnt(classList)
    
    bestFeat = chooseBestFeatureToSplit(dataSet)
    bestFeatLabel = labels[bestFeat]
    myTree = {
   bestFeatLabel: {
   }}
    del labels[bestFeat]
    featValues = [r[bestFeat] for r in dataSet]
    uniqueVals = set(featValues)
    for value in uniqueVals:
        subLablels = labels[:]     # 拷贝列表
        myTree[bestFeatLabel][value] = createTree(
        splitDataSet(dataSet, bestFeat, value), 
        subLablels
        )
    return myTree

## 4. 创建决策树
def createDataSet():
    dataSet = [
        [1, 1, 'y'],
        [1, 1, 'y'],
        [1, 0, 'n'],
        [0, 1, 'n'],
        [0, 1, 'n'],
              ]
    labels = ["A", "B"]
    return dataSet, labels

dataSet, labels = createDataSet()
myTree = createTree(dataSet, labels)
myTree # output:{'A': {0: 'n', 1: {'B': {0: 'n', 1: 'y'}}}}

## 5. 根据决策树测试算法
def classify(inputTree, featLabels, testVec):
    firstStr = inputTree.keys()[0]
    secondDict = inputTree[firstStr]
    featIndex = featLabels.index(firstStr)
    for k, v in secondDict.items():
        if testVec[featIndex] == k:
            if isinstance(v, dict):
                classLabel = classify(v, featLabels, testVec)
            else:
                classLabel = v
    return classLabel
    
classify(myTree, ["A", "B"], [1, 1])  # output:yes

4. 基于概率论的分类方法:朴素贝叶斯(Navie Bayes)

朴素:在分类器学习过程只做最原始、最简单的假设, 如假设各特征出现的概率是独立的(独立性假设)。

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

朴素贝叶斯:

  • 优点:在数据较少的情况下仍然有效,可以处理
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值