自己学习

决策树

  • 机器学习中分类和预测算法的评估

    • 准确率
    • 速度
    • 强壮性
    • 可规模性
    • 可解释性
  • 决策树/判定数

    • 类似于流程图的树结构:内部节点表示属性上的测试,每一个分支表示属性输出,树叶节点代表类或类分布

在这里插入图片描述

在这里插入图片描述

从上图可见,第一层根据天气分类
分类时需要设置阈值
Play 和 Don’t Play 表示是否游玩,共14个例子
最终把某一类变成全部Play或Don’t Play

  • 熵(entropy)
    • 信息量的度量等于不确定性的多少:越不确定的事情所需的信息量越大
    • 使用bit(值为0/1)来衡量信息的多少
    • 变量的不确定性越大,熵越大

在这里插入图片描述

上图为信息量/熵的计算公式
H(X)表示信息量
P(X)表示概率

决策树归纳算法

  • ID3算法
    • 选择属性判断节点
    • 信息获取量(information gain):Gain(A) = Info(D) - Info_A(D)
      • Gain(A) 表示A的信息获取量
      • Info(D) 表示数据集中没有A的信息量
      • Info_A(D) 根据A分类后的信息量

在这里插入图片描述

buys_compouter 表示是否买电脑 no不买 yes 买
得到信息量/熵 Info(D) = 0.74 bits
若A表示年龄,则 Info_A(D) 为 中年信息熵 + 青年信息熵 + 老年信息熵之和
及算法得到 Info_A(D) = 0.694
最后得到Gain(A) = 0.984 - 0.694 = 0.246
对比其他属性的信息获取量,Age属性的信息获取量最高,因此将Age最为第一节点分类

在这里插入图片描述

通过age分类,得到上述图片
重复上述的信息量计算,获得另一最高信息获取量属性,再分类

  • 总结步骤

    1. 树以代表训练样本的单个节点开始
    2. 如果样本都在同一个类,则该节点成为树叶,并用该类标号
    3. 否则,算法使用称为信息增益的基于熵的度量最为启发信息,选择能够组好的捋样本分类属性
      • 所有的属性都是分类的,即离散值。连续属性必须离散化
    4. 对测试属性和已知的值,创建一个分支,并划分样本
    5. 算法使用痒痛的过程,递归的形成每个划分上的样本判定树。一旦一个属性出现在一个节点上的值都相同,就不必再考虑该节点属性(例如:上图中Age分类之后,三大类的数据集的age属性都相同,往后就不再考虑age属性)
    6. 停止条件
      1. 给定节点和所有样本属于同一类(上图中,目标class都为yes)
      2. 没有剩余属性来划分样本,用多数表决分类
  • 其他算法

    • C4.5
    • Classifcation and Regression Tress(CART)
    • 相同点:贪心算法,从上往下
    • 区别:属性选择度量方法不同
  • 树剪枝叶(避免overfitting)

    • 先剪枝
    • 后剪枝
  • 决策树优点:直观、便于理解、小规模数据集有效

  • 决策树缺点:处理连续变量不好(因为属性必须离散化)、类别较多时错误增加的比较快、可归模型一般(数据量大的时候不适用,复杂度高)

决策树的应用

  • python 基础
  • python机器学习的库:scikit-learn
    • 特性
      • 简单高效的数据挖掘,机器学习分析
      • 基于numpy、Scipy和matplotlib
      • 开源
    • 覆盖领域问题
      • 分类
      • 回归
      • 具类
      • 降维
      • 模型选择
      • 预处理

pip install -U scikit-learn

安装 scikit learn 库

  • 安装Graphviz来讲dot文件转为pdf可视化决策树
RIDageincomestudentcredit_ratingclass_buys_computer
1youthhighnofairno
2youthhighnoexcellentno
3middle_agedhighnofairyes
4seniormediumnofairyes
5seniorlowyesfairyes
6seniorlowyesexcellentno
7middle_agedlowyesexcellentyes
8youthmediumnofairno
9youthlowyesfairyes
10seniormediumyesfairyes
11youthmediumyesexcellentyes
12middle_agedmediumnoexcellentyes
13middle_agedhighyesfairyes
14seniormediumnoexcellentno

上面为下面代码所用数据


#coding=utf-8
import numpy as np
from sklearn.feature_extraction import DictVectorizer
# sklearn对数据格式有要求,DicVectorizer来转换输入格式为sklearn可识别的格式
import csv
from sklearn import preprocessing
from sklearn import tree
from sklearn.externals.six import StringIO

allElectronicsData = open(r'./resources/AllElectronics.csv', 'rb')
reader = csv.reader(allElectronicsData)
headers = reader.next()
# 读取csv文件,reader.next()表示读取一行并将指针移动至下一行
# 因为第一行是标头,所以使用headers存储表头

featureList = []
labelList = []

for row in reader:
    labelList.append(row[len(row)-1])
    rowDict = {}
    for i in range(1, len(row)-1):
        rowDict[headers[i]] = row[i]
    featureList.append(rowDict)

# 这里将每行数据按存入字典中,再将字典存入到列表中

vec = DictVectorizer()
dummyX = vec.fit_transform(featureList) .toarray()

print("dummyX: " + str(dummyX))
print(vec.get_feature_names())

print("labelList: " + str(labelList))

# vectorize class labels
lb = preprocessing.LabelBinarizer()
dummyY = lb.fit_transform(labelList)
print("dummyY: " + str(dummyY))

# 使用DictVectorizer转换数据

clf = tree.DecisionTreeClassifier(criterion='entropy')
# 指定决策树算法 criterion='entropy' 为信息熵算法
clf = clf.fit(dummyX, dummyY)
print("clf: " + str(clf))

# Visualize model
with open("./resources/allElectronicInformationGainOri.dot", 'w') as f:
    f = tree.export_graphviz(clf, feature_names=vec.get_feature_names(), out_file=f)

# 上面建立好决策树


oneRowX = dummyX[0, :]
print("oneRowX: " + str(oneRowX))
# oneRowX: [0. 0. 1. 0. 1. 1. 0. 0. 1. 0.]

# 下面修改旧数据做成新数据,使用上面的决策树来预测

newRowX = oneRowX
newRowX[0] = 1
newRowX[2] = 0
print("newRowX: " + str(newRowX)) 
# newRowX: [1. 0. 0. 0. 1. 1. 0. 0. 1. 0.]

predictedY = clf.predict(np.array(newRowX).reshape(1, -1))
print("predictedY: " + str(predictedY)) # 1

DictVectorizer()转换字典为scikit-learn可识别数据格式
例如:一列只有三种值:mid、small、big,则DictVectorizer转换001表示small、010表示mid,100表示big

跑出来的allElectronicInformationGainOri.dot文件使用 dot -T pdf allElectronicInformationGainOri.dot -o output.pdf来转换成决策树图

安装 graphlab creator

  • 安装anaconda
  • 官网注册认证
  • 官网下载
  • windows下
    • activate gl-env进入虚拟环境
    • ipython notebook启动notebook
      • enter是换行
      • ctrl + enter 是运行当前框

可能遇到的问题:https://blog.csdn.net/u013569000/article/details/53886656
修改conda国内镜像:conda config --add channels https://mirrors.ustc.edu.cn/anaconda/pkgs/free/
修改pip国内镜像:-i https://pypi.tuna.tsinghua.edu.cn/simple

在graphlab中使用python

  • people.csv 内容如下
First NameLast NameCountryage
BobSmithUS24
AliceWiliCandata25
MalJoneEngland26
FelixBorwnUSA27
ALexCoooperPOland28
TodCamUS29
DerekWardSitzerland30

import graphlab
# 读取文件
sf = graphlab.SFrame('people.csv')
sf
# 查看前几行
sf.head
# 查看尾几行
sf.tail
# GraphLab Canvas,在Graphlab中对数据有个直观的了解
sf.show()
# 将GraphLab Canvas输出重定向到本页面,就不会跳转页面这么麻烦了
graphlab.canvas.set_target("ipynb"); # 将输出显示到ipynb中
sf['age'].show(view='Categorical') # 年龄显示,分类比例
# 操作列数据
sf['Country']
sf['age']
# 列上的简单运算
sf['age'].mean() # 计算平均值
sf['age'].max() # 计算最大值
# 新增列
sf['FUll Name'] = sf['First Name'] + " "+ sf['Last Name'] # 新增全称列,定义全程列为first name 加上 last name
sf
# 列元素运算
sf['age'] + 2 # 所有age列元素都加上2
sf['age'] * sf['age']
sf
# 应用apply函数来转换数据,实现逐行应用某一个给定函数的功能
# 这里假设 US和 表示相同的国家,但是很明显程序认为US和USA表示不同国家,因此需要手动书写代码让USA和US表示相同国家
def transform_country(country):
    if country == 'USA':
        return "US"
    else :
        return country
sf['Country'].apply(transform_country) # 将所有的USA都转换成了US,但是没有赋值回去改变数据集
sf['Country'] = sf['Country'].apply(transform_country) # 赋值回去sf

在这里插入图片描述

上述代码逐行运行

回归

  • 计算残差平法和最小的 y = ax + b

在这里插入图片描述

  • 加入影响因素:单纯的一条直线可能不能够模拟房价,需要加入其他因素
    • 可能使用二次函数、三次等,同样需要计算残差平法和
    • 但不管如何都是线性回归

在这里插入图片描述

上图为极端情况,使用的是十三次函数,使得残差平方和降为0
这样看起来很好,但是这样称为过度拟合,即所计算出来的曲线是不真实存在的
过拟合计算出来的曲线可以完美适配你提供的训练数据,但是一旦加入新的数据则无法匹配

  • 选择合适的模型阶数/复杂度

    • 模拟预测:将数据集中的部分数据去除,将剩余数据进行拟合,当拟合模型完毕后与之前去除的数据进行比较
    • 用于拟合的数据称为训练集,被去除的数据成为u测试集
  • 训练/测试误差

在这里插入图片描述

  • 加入其他特征
    • 上述曲线仅仅通过房屋面积来模拟价格
    • 现实状况是:面积、地段、房屋设置、布局……都是考虑范围

使用回归模型预测房价

在这里插入图片描述

分类模型

  • 判断邮件是否为垃圾邮件、判断文本关于什么等

  • 我想吃寿司,一家店的评论

    • 寿司真好吃
    • 拉面不好吃
    • 我老婆喜欢这家店的寿司
  • 构建餐厅评价系统

    • 获得餐厅的所有评论
    • 把所有评论拆分成句子
    • 句子情感分类器:分离语句情感判断评论好坏

在这里插入图片描述

除开评论,垃圾邮箱、网页内容、图片分类等也可以使用分类器

  • 分类器的问题

    • 如何得到正面/负面的单词列表
    • 词语的情感问题不同:Great和Good强度不同;考虑单词的情感程度
    • 单独的单词不够:not 和 good 组合一起是负面的含义
    • 词语的权重
  • 线性分类器:

单词权重
good1.0
great1.5
awesome2.7
bad-1.0
terrible-2.1
awful-3.3
we,the,that0
// 通过上述权重分析下面一条评论
Sushi was great.
the food was awesome.
but the service was terrible

Score = 1.5 + 2.7 - 2.1 > 0 // 得出改评论是正面的
  • 决策边界

  • 训练和评估分类器

    • 训练分类器=学习权重
    • 误差 = 错误数 / 句子样本数
    • 精度 = 正确数 / 句子样本数
      • 好的精度:
        • 最差的情况下,分类器至少要比随机猜测好。即二元分类大于1/2的正确率,三元分类大于1/3
        • 具体情况具体分析,多数类预测:分类器能分出90%的垃圾邮件,但实际上全是90%的邮件都是垃圾邮件,所以90%的精度并不够高
        • 对报告出的的精度问题进行深度研究

在这里插入图片描述

  • 误差(错误的种类)
    • 混淆矩阵

在这里插入图片描述

True 表示预测正确,False表示预测错误
False Positive 和 False Negative所代表的都是错误
但是两个造成的影响却不相同:
如果是垃圾邮件被认为是正常邮件那就是邮箱多了个垃圾邮件而已
如果是重要邮件被识别为垃圾邮件那么就失去了重要邮件

在这里插入图片描述

通过真实标签可知健康人数:70 感冒:20 流感 10
通过预测标签可知 精度为 (60 + 12 + 8) / 100 = 0.8
可以说这个分类器容易将:
健康人误诊为感冒、也有可能误诊为流感
感冒人误诊为:健康和流感都有可能
流感有可能误诊为感冒

  • 学习曲线:模型到底需要多少数据
    • 在数据质量有保证的前提下是越多越好的
    • 理论结果通常对对需要的数据定义一个界限
      • 对于实际应用来说,界限通常太松
      • 可以作为一个指导
    • 在实践中
      • 越复杂的模型 需要更多的数据
      • 经验分析可以作为指导

在这里插入图片描述

分类器实践

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值