赞
踩
系统越有序,熵值越低;系统越混乱或者分散,熵值越高。
是度量样本集合纯度最常用的一种指标。
公式
其中:Ent(D) 的值越小,则 D 的纯度越高.
给定特征a条件下D的信息条件熵
公式
Gain(D,a),定义为**集合D的信息熵Ent(D)与给定特征a条件下D的信息条件熵Ent(D|a)Ent(D∣a)**之差
公式
信息增益准则对可取值数目较多的属性有所偏好,为减少这种偏好可能带来的不利影响,著名的 C4.5 决策树算法 [Quinlan, 1993J 不直接使用信息增益,而是使用"增益率" (gain ratio) 来选择最优划分属性.
**增益率:**增益率是用前面的信息增益Gain(D, a)和属性a对应的"固有值"(intrinsic value) [Quinlan , 1993J的比值来共同定义的。
公式
CART 决策树 [Breiman et al., 1984] 使用"基尼指数" (Gini index)来选择划分属性.
公式
名称 | 提出时间 | 分支方式 | 备注 |
---|---|---|---|
ID3 | 1975 | 信息增益 | ID3只能对离散属性的数据集构成决策树 |
C4.5 | 1993 | 信息增益率 | 优化后解决了ID3分支过程中总喜欢偏向选择值较多的 属性 |
CART | 1984 | Gini系数 | 可以进行分类和回归,可以处理离散属性,也可以处理连续属性 |
做出的改进(为什么使用C4.5要好)
(1) 用信息增益率来选择属性
(2) 可以处理连续数值型属性
(3)采用了一种后剪枝方法
(4)对于缺失值的处理
C4.5算法的优缺点
优点:
产生的分类规则易于理解,准确率较高。
缺点:
在构造树的过程中,需要对数据集进行多次的顺序扫描和排序,因而导致算法的低效。
此外,C4.5只适合于能够驻留于内存的数据集,当训练集大得无法在内存容纳时程序无法运行。
CART算法相比C4.5算法的分类方法,采用了简化的二叉树模型,同时特征选择采用了近似的基尼系数来简化计算。
C4.5不一定是二叉树,但CART一定是二叉树。
将任意数据(如文本或图像)转换为可用于机器学习的数字特征
sklearn.feature_extraction
作用:对字典数据进行特征值化
from sklearn.feature_extraction import DictVectorizer def dict_demo(): """ 对字典类型的数据进行特征抽取 :return: None """ data = [{'city': '北京','temperature':100}, {'city': '上海','temperature':60}, {'city': '深圳','temperature':30}] # 1、实例化一个转换器类 transfer = DictVectorizer(sparse=False) # 2、调用fit_transform data = transfer.fit_transform(data) print("返回的结果:\n", data) # 打印特征名字 print("特征名字:\n", transfer.get_feature_names()) return None
有无sparse=False参数的结果
无
返回的结果:
(0, 1) 1.0
(0, 3) 100.0
(1, 0) 1.0
(1, 3) 60.0
(2, 2) 1.0
(2, 3) 30.0
特征名字:
['city=上海', 'city=北京', 'city=深圳', 'temperature']
有
返回的结果:
[[ 0. 1. 0. 100.]
[ 1. 0. 0. 60.]
[ 0. 0. 1. 30.]]
特征名字:
['city=上海', 'city=北京', 'city=深圳', 'temperature']
作用:对文本数据进行特征值化
英文文本
from sklearn.feature_extraction.text import CountVectorizer def text_count_demo(): """ 对文本进行特征抽取,countvetorizer :return: None """ data = ["life is short,i like like python", "life is too long,i dislike python"] # 1、实例化一个转换器类 # transfer = CountVectorizer(sparse=False) # 注意,没有sparse这个参数 transfer = CountVectorizer() # 2、调用fit_transform data = transfer.fit_transform(data) print("文本特征抽取的结果:\n", data.toarray()) print("返回特征名字:\n", transfer.get_feature_names()) return None
结果
文本特征抽取的结果:
[[0 1 1 2 0 1 1 0]
[1 1 1 0 1 1 0 1]]
返回特征名字:
['dislike', 'is', 'life', 'like', 'long', 'python', 'short', 'too']
中文文本
需要进行分词处理
需要安装下jieba库
pip3 install jieba
例子
from sklearn.feature_extraction.text import CountVectorizer import jieba def cut_word(text): """ 对中文进行分词 "我爱北京天安门"————>"我 爱 北京 天安门" :param text: :return: text """ # 用结巴对中文字符串进行分词 text = " ".join(list(jieba.cut(text))) return text def text_chinese_count_demo2(): """ 对中文进行特征抽取 :return: None """ data = ["一种还是一种今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。", "我们看到的从很远星系来的光是在几百万年之前发出的,这样当我们看到宇宙时,我们是在看它的过去。", "如果只用一种方式了解某样事物,你就不会真正了解它。了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。"] # 将原始数据转换成分好词的形式 text_list = [] for sent in data: text_list.append(cut_word(sent)) print(text_list) # 1、实例化一个转换器类 # transfer = CountVectorizer(sparse=False) transfer = CountVectorizer() # 2、调用fit_transform data = transfer.fit_transform(text_list) print("文本特征抽取的结果:\n", data.toarray()) print("返回特征名字:\n", transfer.get_feature_names()) return None
结果
Building prefix dict from the default dictionary ...
Dumping model to file cache /var/folders/mz/tzf2l3sx4rgg6qpglfb035_r0000gn/T/jieba.cache
Loading model cost 1.032 seconds.
['一种 还是 一种 今天 很 残酷 , 明天 更 残酷 , 后天 很 美好 , 但 绝对 大部分 是 死 在 明天 晚上 , 所以 每个 人 不要 放弃 今天 。', '我们 看到 的 从 很 远 星系 来 的 光是在 几百万年 之前 发出 的 , 这样 当 我们 看到 宇宙 时 , 我们 是 在 看 它 的 过去 。', '如果 只用 一种 方式 了解 某样 事物 , 你 就 不会 真正 了解 它 。 了解 事物 真正 含义 的 秘密 取决于 如何 将 其 与 我们 所 了解 的 事物 相 联系 。']
Prefix dict has been built succesfully.
文本特征抽取的结果:
[[2 0 1 0 0 0 2 0 0 0 0 0 1 0 1 0 0 0 0 1 1 0 2 0 1 0 2 1 0 0 0 1 1 0 0 1 0]
[0 0 0 1 0 0 0 1 1 1 0 0 0 0 0 0 0 1 3 0 0 0 0 1 0 0 0 0 2 0 0 0 0 0 1 0 1]
[1 1 0 0 4 3 0 0 0 0 1 1 0 1 0 1 1 0 1 0 0 1 0 0 0 1 0 0 0 2 1 0 0 1 0 0 0]]
返回特征名字:
['一种', '不会', '不要', '之前', '了解', '事物', '今天', '光是在', '几百万年', '发出', '取决于', '只用', '后天', '含义', '大部分', '如何', '如果', '宇宙', '我们', '所以', '放弃', '方式', '明天', '星系', '晚上', '某样', '残酷', '每个', '看到', '真正', '秘密', '绝对', '美好', '联系', '过去', '还是', '这样']
用于分类需要用Tf-idf文本特征提取
如果某个词或短语在一篇文章中出现的概率高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。
用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。
例子
"""
假如一篇文章的总词语数是100个,而词语"非常"出现了5次,那么"非常"一词在该文件中的词频就是5/100=0.05。
而计算文件频率(IDF)的方法是以文件集的文件总数,除以出现"非常"一词的文件数。
所以,如果"非常"一词在1,0000份文件出现过,而文件总数是10,000,000份的话,
其逆向文件频率就是lg(10,000,000 / 1,0000)=3。
最后"非常"对于这篇文档的tf-idf的分数为0.05 * 3=0.15
"""
例子
from sklearn.feature_extraction.text import TfidfVectorizer import jieba def cut_word(text): """ 对中文进行分词 "我爱北京天安门"————>"我 爱 北京 天安门" :param text: :return: text """ # 用结巴对中文字符串进行分词 text = " ".join(list(jieba.cut(text))) return text def text_chinese_tfidf_demo(): """ 对中文进行特征抽取 :return: None """ data = ["一种还是一种今天很残酷,明天更残酷,后天很美好,但绝对大部分是死在明天晚上,所以每个人不要放弃今天。", "我们看到的从很远星系来的光是在几百万年之前发出的,这样当我们看到宇宙时,我们是在看它的过去。", "如果只用一种方式了解某样事物,你就不会真正了解它。了解事物真正含义的秘密取决于如何将其与我们所了解的事物相联系。"] # 将原始数据转换成分好词的形式 text_list = [] for sent in data: text_list.append(cut_word(sent)) print(text_list) # 1、实例化一个转换器类 # transfer = CountVectorizer(sparse=False) transfer = TfidfVectorizer(stop_words=['一种', '不会', '不要']) # 2、调用fit_transform data = transfer.fit_transform(text_list) print("文本特征抽取的结果:\n", data.toarray()) print("返回特征名字:\n", transfer.get_feature_names()) return None
结果
Building prefix dict from the default dictionary ... Loading model from cache /var/folders/mz/tzf2l3sx4rgg6qpglfb035_r0000gn/T/jieba.cache Loading model cost 0.856 seconds. Prefix dict has been built succesfully. ['一种 还是 一种 今天 很 残酷 , 明天 更 残酷 , 后天 很 美好 , 但 绝对 大部分 是 死 在 明天 晚上 , 所以 每个 人 不要 放弃 今天 。', '我们 看到 的 从 很 远 星系 来 的 光是在 几百万年 之前 发出 的 , 这样 当 我们 看到 宇宙 时 , 我们 是 在 看 它 的 过去 。', '如果 只用 一种 方式 了解 某样 事物 , 你 就 不会 真正 了解 它 。 了解 事物 真正 含义 的 秘密 取决于 如何 将 其 与 我们 所 了解 的 事物 相 联系 。'] 文本特征抽取的结果: [[ 0. 0. 0. 0.43643578 0. 0. 0. 0. 0. 0.21821789 0. 0.21821789 0. 0. 0. 0. 0.21821789 0.21821789 0. 0.43643578 0. 0.21821789 0. 0.43643578 0.21821789 0. 0. 0. 0.21821789 0.21821789 0. 0. 0.21821789 0. ] [ 0.2410822 0. 0. 0. 0.2410822 0.2410822 0.2410822 0. 0. 0. 0. 0. 0. 0. 0.2410822 0.55004769 0. 0. 0. 0. 0.2410822 0. 0. 0. 0. 0.48216441 0. 0. 0. 0. 0. 0.2410822 0. 0.2410822 ] [ 0. 0.644003 0.48300225 0. 0. 0. 0. 0.16100075 0.16100075 0. 0.16100075 0. 0.16100075 0.16100075 0. 0.12244522 0. 0. 0.16100075 0. 0. 0. 0.16100075 0. 0. 0. 0.3220015 0.16100075 0. 0. 0.16100075 0. 0. 0. ]] 返回特征名字: ['之前', '了解', '事物', '今天', '光是在', '几百万年', '发出', '取决于', '只用', '后天', '含义', '大部分', '如何', '如果', '宇宙', '我们', '所以', '放弃', '方式', '明天', '星系', '晚上', '某样', '残酷', '每个', '看到', '真正', '秘密', '绝对', '美好', '联系', '过去', '还是', '这样']
有些人比其他人更容易生存,例如妇女,儿童和上流社会。
运用机器学习工具来预测哪些乘客幸免于悲剧
import pandas as pd
import numpy as np
from sklearn.feature_extraction import DictVectorizer
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier, export_graphviz
# 1、获取数据
titan = pd.read_csv("http://biostat.mc.vanderbilt.edu/wiki/pub/Main/DataSets/titanic.txt")
2.数据基本处理
x = titan[["pclass", "age", "sex"]]
y = titan["survived"]
# 缺失值需要处理,将特征当中有类别的这些特征进行字典特征抽取
x['age'].fillna(x['age'].mean(), inplace=True)
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=22)
3.特征工程(字典特征抽取)
特征中出现类别符号,需要进行one-hot编码处理(DictVectorizer)
x.to_dict(orient=“records”) 需要将数组特征转换成字典数据
# 对于x转换成字典数据x.to_dict(orient="records")
# [{"pclass": "1st", "age": 29.00, "sex": "female"}, {}]
transfer = DictVectorizer(sparse=False)
x_train = transfer.fit_transform(x_train.to_dict(orient="records"))
x_test = transfer.fit_transform(x_test.to_dict(orient="records"))
决策树API当中,如果没有指定max_depth那么会根据信息熵的条件直到最终结束。这里我们可以指定树的深度来进行限制树的大小
# 4.机器学习(决策树)
estimator = DecisionTreeClassifier(criterion="entropy", max_depth=5)
estimator.fit(x_train, y_train)
# 5.模型评估
estimator.score(x_test, y_test)
estimator.predict(x_test)
决策树的结构是可以直接显示
export_graphviz(estimator, out_file="./data/tree.dot", feature_names=['age', 'pclass=1st', 'pclass=2nd', 'pclass=3rd', '女性', '男性'])
dot文件当中的内容如下
digraph Tree { node [shape=box] ; 0 [label="petal length (cm) <= 2.45\nentropy = 1.584\nsamples = 112\nvalue = [39, 37, 36]"] ; 1 [label="entropy = 0.0\nsamples = 39\nvalue = [39, 0, 0]"] ; 0 -> 1 [labeldistance=2.5, labelangle=45, headlabel="True"] ; 2 [label="petal width (cm) <= 1.75\nentropy = 1.0\nsamples = 73\nvalue = [0, 37, 36]"] ; 0 -> 2 [labeldistance=2.5, labelangle=-45, headlabel="False"] ; 3 [label="petal length (cm) <= 5.05\nentropy = 0.391\nsamples = 39\nvalue = [0, 36, 3]"] ; 2 -> 3 ; 4 [label="sepal length (cm) <= 4.95\nentropy = 0.183\nsamples = 36\nvalue = [0, 35, 1]"] ; 3 -> 4 ; 5 [label="petal length (cm) <= 3.9\nentropy = 1.0\nsamples = 2\nvalue = [0, 1, 1]"] ; 4 -> 5 ; 6 [label="entropy = 0.0\nsamples = 1\nvalue = [0, 1, 0]"] ; 5 -> 6 ; 7 [label="entropy = 0.0\nsamples = 1\nvalue = [0, 0, 1]"] ; 5 -> 7 ; 8 [label="entropy = 0.0\nsamples = 34\nvalue = [0, 34, 0]"] ; 4 -> 8 ; 9 [label="petal width (cm) <= 1.55\nentropy = 0.918\nsamples = 3\nvalue = [0, 1, 2]"] ; 3 -> 9 ; 10 [label="entropy = 0.0\nsamples = 2\nvalue = [0, 0, 2]"] ; 9 -> 10 ; 11 [label="entropy = 0.0\nsamples = 1\nvalue = [0, 1, 0]"] ; 9 -> 11 ; 12 [label="petal length (cm) <= 4.85\nentropy = 0.191\nsamples = 34\nvalue = [0, 1, 33]"] ; 2 -> 12 ; 13 [label="entropy = 0.0\nsamples = 1\nvalue = [0, 1, 0]"] ; 12 -> 13 ; 14 [label="entropy = 0.0\nsamples = 33\nvalue = [0, 0, 33]"] ; 12 -> 14 ; }
数据类型分两类:连续型数据和离散型数据
决策树分两类:
nsamples = 1\nvalue = [0, 1, 0]"] ;
9 -> 11 ;
12 [label=“petal length (cm) <= 4.85\nentropy = 0.191\nsamples = 34\nvalue = [0, 1, 33]”] ;
2 -> 12 ;
13 [label=“entropy = 0.0\nsamples = 1\nvalue = [0, 1, 0]”] ;
12 -> 13 ;
14 [label=“entropy = 0.0\nsamples = 33\nvalue = [0, 0, 33]”] ;
12 -> 14 ;
}
### 决策树优缺点总结【知道】 - 优点: - 简单的理解和解释,树木可视化。 - 缺点: - 决策树学习者可以创建不能很好地推广数据的过于复杂的树,容易发生过拟合。 - 改进: - 减枝cart算法 - 随机森林(集成学习的一种) ## 回归决策树 数据类型分两类:**连续型数据和离散型数据** 决策树分两类: - **分类决策树和回归决策树。** - **前者主要用于处理离散型数据,后者主要用于处理连续型数据。** ## 算法描述 - 输入:训练数据集D: - 输出:回归树f(x)*f*(*x*). - 在训练数据集所在的输入空间中,递归的将每个区域划分为两个子区域并决定每个子区域上的输出值,构建二叉决策树
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。