参考资料:极客时间的《数据分析实战45讲》

本篇目录

  • 参考资料:极客时间的《数据分析实战45讲》
    • 一、决策树
      • I、ID3算法 (信息增益)
      • II、C4.5算法 (信息增益率)
      • III、CART算法 (基尼指数)
      • IV、泰坦尼克乘客生存预测实战
    • 二、贝叶斯
      • I. 基本原理
      • II、文档分类实战
    • 三、支持向量机(SVM)
      • I、基本原理
      • II、乳腺癌检测实战
    • 四、K最近邻(KNN)
      • I、基本原理
      • II、手写数字识别实战
    • 五、K均值聚类(K-Means)
      • I、基本原理
      • II、图像分割实战
    • 六、EM聚类
      • I、基本原理
      • II、王者荣耀角色聚类实战
    • 七、关联规则挖掘
      • I、基本原理
      • II、导演选择演员的偏好探索实战
    • 八、网页排名(PageRank)
      • I、基本原理
      • II、希拉里邮件中的人物关系分析实战
    • 九、增强学习(Adaboost)
      • I、基本原理
      • II、房价预测实战

一、决策树

在现实生活中,我们总会遇到需要各种抉择的场景,而抉择背后的逻辑结构图就是决策树。根据决策树在构建时所参考的指标的不同,决策树算法一共分为ID3算法、C4.5算法和CART算法等。

I、ID3算法 (信息增益)

1. 基本原理

通过以下公式的计算来获得决策树搭建所必需的指标:
Gain(D,a)=Entropy(D)−∑i=1k∣Di∣∣D∣Entropy(Di)(1)Entropy(D)=−∑i=0c−1p(Ci∣D)log2P(Ci∣D)(2)Gain(D,a)=Entropy(D)-\sum_{i=1}^{k} \frac{|D_i|}{|D|}Entropy(D_i) \qquad \qquad \qquad (1)\\ Entropy(D)=-\sum_{i=0}^{c-1}p(C_i|D)log_2^{P(C_i|D)} \qquad \qquad \qquad \qquad (2) Gain(D,a)=Entropy(D)−i=1∑k​∣D∣∣Di​∣​Entropy(Di​)(1)Entropy(D)=−i=0∑c−1​p(Ci​∣D)log2P(Ci​∣D)​(2)
其中D、a、k、Di、c、p(Ci∣D)D、a、k、D_i、c、p(C_i|D)D、a、k、Di​、c、p(Ci​∣D)分别代表的是当前数据集、特征、特征a的所有取值个数、划分后的子数据集、分类标签个数和在当前数据集中被划分为第i个分类标签的概率。

假设当前数据集如下:

天气 温度 湿度 狂风 是否打篮球
晴天
晴天
阴天
小雨
小雨
晴天
阴天

我们将整个数据集DDD作为根结点,运用公式来选择哪一个特征作为分支依据。假设初始数据集DDD被特征天气分成了三个子集合D1、D2、D3D_1、D_2、D_3D1​、D2​、D3​,那么

Entropy(D)=−(37log237+47log247)=0.985Entropy(D1)=−(13log213+23log223)=0.918Entropy(D2)=−(12log212+12log212)=1.0Entropy(D3)=−(13log213+23log223)=0.918Gain(D,天气)=Entropy(D)−∑i=13∣Di∣∣D∣Entropy(Di)=0.985−(3/7∗0.918+2/7∗1.0+2/7∗1.0)=0.020Entropy(D)=-(\frac{3}{7}log_2^{\frac{3}{7}}+\frac{4}{7}log_2^{\frac{4}{7}})=0.985 \\ Entropy(D_1)=-(\frac{1}{3}log_2^{\frac{1}{3}}+\frac{2}{3}log_2^{\frac{2}{3}})=0.918 \\ Entropy(D_2)=-(\frac{1}{2}log_2^{\frac{1}{2}}+\frac{1}{2}log_2^{\frac{1}{2}})=1.0 \\ Entropy(D_3)=-(\frac{1}{3}log_2^{\frac{1}{3}}+\frac{2}{3}log_2^{\frac{2}{3}})=0.918 \\ Gain(D,天气)=Entropy(D)-\sum_{i=1}^{3} \frac{|D_i|}{|D|}Entropy(D_i)=0.985-(3/7*0.918+2/7*1.0+2/7*1.0)=0.020 \\ Entropy(D)=−(73​log273​​+74​log274​​)=0.985Entropy(D1​)=−(31​log231​​+32​log232​​)=0.918Entropy(D2​)=−(21​log221​​+21​log221​​)=1.0Entropy(D3​)=−(31​log231​​+32​log232​​)=0.918Gain(D,天气)=Entropy(D)−i=1∑3​∣D∣∣Di​∣​Entropy(Di​)=0.985−(3/7∗0.918+2/7∗1.0+2/7∗1.0)=0.020
同理求出当前数据集下其余特征对应的信息增益值
Gain(D,温度)=0.128Gain(D,湿度)=0.020Gain(D,刮风)=0.020Gain(D,温度)=0.128 \\ Gain(D , 湿度)=0.020 \\ Gain(D , 刮风)=0.020 Gain(D,温度)=0.128Gain(D,湿度)=0.020Gain(D,刮风)=0.020
通过数值的对比,我们发现以温度为对象的信息增益最大,因此我们可以判断出在当前数据集中选择温度特征来进行数据集的划分是最好的。

随后将得到的三个集合再次当作原数据集执行上述步骤,最终得到完整的决策树。

之所以规定选择信息增益最大的特征来进行数据集的划分,这是因为通过公式一,我们可以发现所谓的信息增益不过是父子节点间的信息熵的差值,而选择信息增益最大的特征来进行创建分支,本质上是选择某一特征来展开枝干使得父节点所丢失的信息熵最大,如此一来就使逐渐搭建成的树的纯度更高。

2. 优势与缺陷

ID3 的算法规则相对简单,可解释性强。同样也存在缺陷,比如我们会发现 ID3 算法倾向于选择取值比较多的属性。如果我们把“编号”作为一个属性,那么“编号”将会被选为最优属性 ,但实际上“编号”是无关属性的。


II、C4.5算法 (信息增益率)

1. 基本原理

C4.5算法是ID3算法的改进版本,因此与ID3算法的步骤是基本一致的,其主要改进的部分在于以下几点:

  1. 采用信息增益率来作为决策树搭建的参考指标
  2. 采用悲观剪枝,减少模型过拟合从而导致容错能力低、泛化能力差、死板的可能
  3. 离散化处理连续属性
  4. 自定义了处理缺失值的方法
2. 优势与缺陷

C4.5 在 ID3 的基础上,用信息增益率代替了信息增益,解决了噪声敏感的问题,并且可以对构造树进行剪枝、处理连续数值以及数值缺失等情况,但是由于 C4.5 需要对数据集进行多次扫描,算法效率相对较低。


III、CART算法 (基尼指数)

1. 基本原理

通过以下公式的计算来获得决策树搭建所必需的指标:

GINI(D,a)=∑i=1kDiDGINI(Di)GINI(D)=1−∑i=0c−1[p(Ci∣D)]2GINI(D,a)=\sum_{i=1}^{k}\frac{D_i}{D}GINI(D_i) \\ GINI(D)=1-\sum_{i=0}^{c-1}[p(C_i|D)]^2 GINI(D,a)=i=1∑k​DDi​​GINI(Di​)GINI(D)=1−i=0∑c−1​[p(Ci​∣D)]2
其中D、a、k、Di、c、p(Ci∣D)D、a、k、D_i、c、p(C_i|D)D、a、k、Di​、c、p(Ci​∣D)分别代表的是当前数据集、特征、特征a的所有取值个数、划分后的子数据集、分类标签个数和在当前数据集中被划分为第i个分类标签的概率。

假设当前数据集如下:

天气 温度 湿度 狂风 是否打篮球
晴天
晴天
阴天
小雨
小雨
晴天
阴天
晴天
小雨
小雨
晴天
晴天

我们将整个数据集作为根结点,运用公式来选择哪一个特征作为分支依据。假设初始数据集DDD被特征天气分成了三个子集合D1、D2D_1、D_2D1​、D2​,那么

GINI(D1)=1−1=0GINI(D2)=1−(0.52+0.52)=0.5GINI(D,狂风)=612GINI(D1)+612GINI(D2)=0+0.5∗0.5=0.25GINI(D_1)=1-1=0 \\ GINI(D_2)=1-(0.5^2+0.5^2)=0.5 \\ GINI(D,狂风)=\frac{6}{12}GINI(D_1)+\frac{6}{12}GINI(D_2)=0+0.5*0.5=0.25 GINI(D1​)=1−1=0GINI(D2​)=1−(0.52+0.52)=0.5GINI(D,狂风)=126​GINI(D1​)+126​GINI(D2​)=0+0.5∗0.5=0.25
同理可以求出当前数据集下其余特征对应的信息增益值。
GINI(D,天气)=⋯GINI(D,温度)=⋯GINI(D,湿度)=⋯GINI(D,天气)=\cdots \\ GINI(D,温度)=\cdots \\ GINI(D,湿度)=\cdots GINI(D,天气)=⋯GINI(D,温度)=⋯GINI(D,湿度)=⋯
通过数值的对比,假设我们发现以狂风为对象的基尼指标值最小,那么我们可以判断出在当前数据集中选择狂风特征来进行数据集的划分是最好的。

随后将得到的两个集合再次当作原数据集执行上述步骤,最终就可以得到完整的决策树。

2. Python代码实战
# encoding=utf-8
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_iris
# 准备数据集
iris=load_iris()
# 获取特征集和分类标识
features = iris.data
labels = iris.target
# 随机抽取33%的数据作为测试集,其余为训练集
train_features, test_features, train_labels, test_labels = train_test_split(features, labels, test_size=0.33, random_state=0)
# 创建CART分类树
clf = DecisionTreeClassifier(criterion='gini')
# 拟合构造CART分类树
clf = clf.fit(train_features, train_labels)
# 用CART分类树做预测
test_predict = clf.predict(test_features)
# 预测结果与测试集结果作比对
score = accuracy_score(test_labels, test_predict)
print("CART分类树准确率 %.4lf" % score)

IV、泰坦尼克乘客生存预测实战

给定某一乘客的相关信息,预测其是否生存。

1. 初始数据集

2. 数据获取
import pandas as pd
# 数据加载
train_data = pd.read_csv('./Titanic_Data/train.csv')
test_data = pd.read_csv('./Titanic_Data/test.csv')
3. 数据探索
# 数据探索
print(train_data.info())
print('-'*30)
print(train_data.describe())
print('-'*30)
print(train_data.describe(include=['O']))
print('-'*30)
print(train_data.head())
print('-'*30)
print(train_data.tail())
4. 数据清洗
# 使用平均年龄来填充年龄中的nan值
train_data['Age'].fillna(train_data['Age'].mean(),inplace=True)
test_data['Age'].fillna(test_data['Age'].mean(),inplace=True)
# 使用票价的均值填充票价中的nan值
train_data['Fare'].fillna(train_data['Fare'].mean(),inplace=True)
test_data['Fare'].fillna(test_data['Fare'].mean(),inplace=True)
# 使用登录最多的港口来填充登录港口的nan值
train_data['Embarked'].fillna('S', inplace=True)
test_data['Embarked'].fillna('S',inplace=True)
5. 特征选择

# 特征选择
features = ['Pclass', 'Sex', 'Age', 'SibSp', 'Parch', 'Fare', 'Embarked']
train_features = train_data[features]
train_labels = train_data['Survived']
test_features = test_data[features]
from sklearn.feature_extraction import DictVectorizer   【特征值里有一些是字符串,这样不方便后续的运算,需要转成数值类型。即宽边长方法】
dvec=DictVectorizer(sparse=False)
train_features=dvec.fit_transform(train_features.to_dict(orient='record'))
6. 模型搭建
from sklearn.tree import DecisionTreeClassifier
# 构造ID3决策树
clf = DecisionTreeClassifier(criterion='entropy')   【指定使用ID3算法搭建决策树模型】
# 决策树训练
clf.fit(train_features, train_labels)
7. 模型预测
test_features=dvec.transform(test_features.to_dict(orient='record'))
# 决策树预测
pred_labels = clf.predict(test_features)
8. 模型评估
# 得到决策树准确率
acc_decision_tree = round(clf.score(train_features, train_labels), 6)
print(u'score准确率为 %.4lf' % acc_decision_tree) 【使用训练集来评估,准确率的可信度较低。使用测试集或者K折交叉验证】
import numpy as np
from sklearn.model_selection import cross_val_score
# 使用K折交叉验证 统计决策树准确率
print(u'cross_val_score准确率为 %.4lf' % np.mean(cross_val_score(clf, train_features, train_labels, cv=10)))
9. 结果可视化

借用 Graphviz 可视化工具帮我们把决策树呈现出来


二、贝叶斯

I. 基本原理

初始数据集(离散型):

编号 身高 体重 鞋码 性别
1
2
3
4
5
6
7
8

现在我们想根据一条记录的特征值{身高=“高”,体重=“中”,鞋码=“中”}来预测拥有这些特征值的人的性别。
假设A1A_1A1​={身高=“高”}、A2A_2A2​={体重=“中”}、A3A_3A3​={鞋码=“中”},C1C_1C1​= 男性,C2C_2C2​= 女性。那么,根据贝叶斯公式
P(Cj∣A1A2A3)=P(A1A2A3∣Cj)P(Cj)P(A1A2A3)=P(A1∣Cj)P(A2∣Cj)P(A3∣Cj)P(Cj)P(A1)P(A2)P(A3)P(C_j|A_1A_2A_3)=\frac{P(A_1A_2A_3|C_j)P(C_j)}{P(A_1A_2A_3)} =\frac{P(A_1|C_j) P(A_2|C_j) P(A_3|C_j) P(C_j)}{P(A_1)P(A_2)P(A_3)}P(Cj​∣A1​A2​A3​)=P(A1​A2​A3​)P(A1​A2​A3​∣Cj​)P(Cj​)​=P(A1​)P(A2​)P(A3​)P(A1​∣Cj​)P(A2​∣Cj​)P(A3​∣Cj​)P(Cj​)​
可以直接获得分类概率,其中P(A1∣Cj)P(A_1|C_j)P(A1​∣Cj​)为在性别为CjC_jCj​的记录中满足A1A_1A1​记录的比例、P(Ai)P(A_i)P(Ai​)代表的是在初始数据中满足AiA_iAi​记录的占比。
由于对于任意一个jjj,P(Cj∣A1A2A3)P(C_j|A_1A_2A_3)P(Cj​∣A1​A2​A3​)的分母都是一样的,因此选取里面的最大值本质是选择分子最大的。经计算,
P(A1A2A3∣C1)=1/16P(A1A2A3∣C2)=0P(A_1A_2A_3|C_1)=1/16 \\ P(A_1A_2A_3|C_2)=0 P(A1​A2​A3​∣C1​)=1/16P(A1​A2​A3​∣C2​)=0
因为P(Ci)P(C_i)P(Ci​)是个非负数,因此可以推测出P(C1∣A1A2A3)P(C_1|A_1A_2A_3)P(C1​∣A1​A2​A3​)值是最大的,从而判断拥有{身高=“高”,体重=“中”,鞋码=“中”}特征的人的性别最大概率是男性。


初始数据集(连续型):

编号 身高(CM) 体重(斤) 鞋码(欧码) 性别
1 183 164 45
2 182 170 44
3 178 160 43
4 175 140 40
5 160 88 35
6 165 100 37
7 163 110 38
8 168 120 39

现在我们想根据一条记录的特征值{身高=“180”,体重=“120”,鞋码=“41”}来预测拥有这些特征值的人的性别。
同样的,我们假设A1A_1A1​={身高=“180”}、A2A_2A2​={体重=“120”}、A3A_3A3​={鞋码=“41”},C1C_1C1​= 男性,C2C_2C2​= 女性。
由于数据是连续型的,因此使用贝叶斯来实现分类需要另外的一些步骤,以方便我们计算各个概率的值,如P(Ai∣Cj)和P(Ai)P(A_i|C_j)和P(A_i)P(Ai​∣Cj​)和P(Ai​)。
在计算这些概率前,我们要先通过初始数据集确定各个的分布函数的参数,搭建身高、体重、鞋码、男性的身高、男性的体重、男性的鞋码、女性的身高、女性的体重、女性的鞋码的分布函数,最后通过各自的分布函数找到概率密度函数,从而计算出P(Ai)和P(Ai∣Cj)P(A_i)和P(A_i|C_j)P(Ai​)和P(Ai​∣Cj​),带入贝叶斯公式中,选择结果值最大的类别即可。


II、文档分类实战

根据输入文档,判断其文章类型,比如垃圾邮件等。

1. 初始数据集

文档 1:this is the bayes document;
文档 2:this is the second second document;
文档 3:and the third one;
文档 4:is this the document。

2. 对文档进行分词
import nltk
word_list = nltk.word_tokenize(text) #英文分词
nltk.pos_tag(word_list) #标注单词的词性import jieba
word_list = jieba.cut (text) #中文分词
3. 加载停用词表
stop_words = [line.strip().decode('utf-8') for line in io.open('stop_words.txt').readlines()] #停用词就是在分类中没有用的词,这些词一般词频 TF 高,但是 IDF 很低,起不到分类的作用
4. 计算单词的权重
tf = TfidfVectorizer(stop_words=stop_words, max_df=0.5)
features = tf.fit_transform(train_contents)  #得到TF-IDF特征空间 features
#词频TF=单词出现的次数/该文档的总单词数
#逆向文档频率IDF=log(文档总数/()该单词出现的文档树+1))
5. 生成朴素贝叶斯分类器
# 多项式贝叶斯分类器
from sklearn.naive_bayes import MultinomialNB
clf = MultinomialNB(alpha=0.001).fit(train_features, train_labels)
6. 使用生成的分类器做预测
test_tf = TfidfVectorizer(stop_words=stop_words, max_df=0.5, vocabulary=train_vocabulary)
test_features=test_tf.fit_transform(test_contents)
7. 计算准确率
from sklearn import metrics
print metrics.accuracy_score(test_labels, predicted_labels)

三、支持向量机(SVM)

I、基本原理

一般的分类算法,其本质都是在许多不同类别的点集中勾勒出一条线性直线,使得线性直线尽可能将点集划分成不同的区域,其中每个区域都是同样的类别,在得到新的输入点后可以通过该线性直线快速得将输入点划分到某一个相似类别区域,达成分类的效果。

但是如果碰到下面的分布情况,就很难以线性方程来描述曲线。


因此需要支持向量机来解决这种的非线性分类问题。它是通过将二维空间内无法通过直线轻易划分的问题转化成三维空间寻找最佳超平面(最优决策面)的问题,而升维是由支持向量机的核函数来实现。

更加细致的讲,SVM 就是帮我们找到一个超平面,这个超平面能将不同的样本划分开,同时使得样本集中的点到这个分类超平面的最小距离(即分类间隔)最大化。其中我们定义某类样本集到超平面的距离是这个样本集合内的样本到超平面的最短距离。支持向量就是离分类超平面最近的样本点,因此实际上如果确定了支持向量也就确定了这个超平面。
我们假设这个超平面的方程为
g(x)=wTx+b,w∈Rn,x∈Rng(x)=w^Tx+b,w\in R^n,x \in R^ng(x)=wTx+b,w∈Rn,x∈Rn
而点到平面的距离的数学表达式为
di=∣wxi+b∣∣∣w∣∣d_i=\frac{|wx_i+b|}{||w||}di​=∣∣w∣∣∣wxi​+b∣​
那么我们可以通过凸优化的知识来得到具体的w、bw、bw、b 的值,从而得到最佳决策面模型。

可以看到这种支持向量机只能实现二分类的问题,但在实际应用中总能碰到多分类需求,那么此时们该如何使用支持向量机来解决呢?
第一种,一对多方法。
假设我们要把物体分成 A、B、C、D 四种分类,那么我们可以先把其中的一类作为类别一,其他类统一归为类别二。
这样我们可以构造 4 种 SVM:
(1)样本 A 作为正集,B,C,D 作为负集
(2)样本 B 作为正集,A,C,D 作为负集
(3)样本 C 作为正集,A,B,D 作为负集
(4)样本 D 作为正集,A,B,C 作为负集
这种方法,针对 K 个分类,需要训练 K 个分类器,分类速度较快,但训练速度较慢。
第二种,一对一方法。
假设我们要把物体分成 A、B、C 三个类,那么我们可以在任意两类样本之间构造一个 SVM。
这样我们可以构造 3 个分类器:
(1)分类器 1:A、B
(2)分类器 2:A、C
(3)分类器 3:B、C
当对一个未知样本进行分类时,每一个分类器都会有一个分类结果,即为 1 票,最终得票最多的类别就是整个未知样本的类别。

II、乳腺癌检测实战

根据患者乳腺肿块经过细针穿刺 (FNA) 后的数字化图像来判断是否患有乳腺癌

1. 初始数据集


2. 数据加载和探索
# 加载数据集,你需要把数据放到目录中
data = pd.read_csv("./data.csv")
# 数据探索
# 因为数据集中列比较多,我们需要把dataframe中的列全部显示出来
pd.set_option('display.max_columns', None)
print(data.columns)
print(data.head(5))
print(data.describe())
3. 数据清洗
# 将特征字段分成3组
features_mean= list(data.columns[2:12])
features_se= list(data.columns[12:22])
features_worst=list(data.columns[22:32])
# 数据清洗
# ID列没有用,删除该列
data.drop("id",axis=1,inplace=True)
# 将B良性替换为0,M恶性替换为1
data['diagnosis']=data['diagnosis'].map({'M':1,'B':0})
4. 特征选择
# 将肿瘤诊断结果可视化
sns.countplot(data['diagnosis'],label="Count")
plt.show()
# 用热力图呈现features_mean字段之间的相关性
corr = data[features_mean].corr()
plt.figure(figsize=(14,14))
# annot=True显示每个方格的数据
sns.heatmap(corr, annot=True)
plt.show()# 特征选择
features_remain = ['radius_mean','texture_mean', 'smoothness_mean','compactness_mean','symmetry_mean', 'fractal_dimension_mean']
5. 数据准备
# 抽取30%的数据作为测试集,其余作为训练集
train, test = train_test_split(data, test_size = 0.3)# in this our main data is splitted into train and test
# 抽取特征选择的数值作为训练和测试数据
train_X = train[features_remain]
train_y=train['diagnosis']
test_X= test[features_remain]
test_y =test['diagnosis']# 采用Z-Score规范化数据,保证每个特征维度的数据均值为0,方差为1
ss = StandardScaler()
train_X = ss.fit_transform(train_X)
test_X = ss.transform(test_X)
6. 模型搭建、预测和评估
# 创建SVM分类器
model = svm.SVC()
# 用训练集做训练
model.fit(train_X,train_y)
# 用测试集做预测
prediction=model.predict(test_X)
print('准确率: ', metrics.accuracy_score(test_y,prediction))

四、K最近邻(KNN)

I、基本原理

初始数据集:

电影名称 打斗次数 接吻次数 电影类型
《战狼》 100 5 动作
《红海行动》 95 3 动作
《碟中谍6》 105 31 动作
《前任3》 2 59 爱情
《春娇救志明》 3 60 爱情
《泰坦尼克号》 10 80 爱情

我们可以把打斗次数看成 X 轴,接吻次数看成 Y 轴,将每条记录看成一个个点在坐标系上标记,我们可以看出这些点集会根据各自的特征而聚集在不同的区域上,自动形成分类模型。此时对于一个输入点,我们只需要看其附近的K个点大部分处于哪个类别,就能评估出其大概率属于哪个类别。

II、手写数字识别实战

对值为0~9的图像进行计算机识别并给出其对应的数字

1. 初始数据集

sklearn 自带的MNIST 数据集,它只包括了 1797 幅数字图像,每幅图像大小是 8*8 像素,分别对应于0~9的值

2. 数据加载和探索
# 加载数据
digits = load_digits()
data = digits.data
# 数据探索
print(data.shape)
# 查看第一幅图像
print(digits.images[0])
# 第一幅图像代表的数字含义
print(digits.target[0])
# 将第一幅图像显示出来
plt.gray()
plt.imshow(digits.images[0])
plt.show()
3. 数据处理
# 分割数据,将25%的数据作为测试集,其余作为训练集(你也可以指定其他比例的数据作为训练集)
train_x, test_x, train_y, test_y = train_test_split(data, digits.target, test_size=0.25, random_state=33)
# 采用Z-Score规范化
ss = preprocessing.StandardScaler()
train_ss_x = ss.fit_transform(train_x)
test_ss_x = ss.transform(test_x)
4. 模型搭建、预测与评估
# 创建KNN分类器
knn = KNeighborsClassifier()
knn.fit(train_ss_x, train_y)
predict_y = knn.predict(test_ss_x)
print("KNN准确率: %.4lf" % accuracy_score(test_y, predict_y))
5. KNN、SVM、贝叶斯和决策树的表现对比
from sklearn.model_selection import train_test_split
from sklearn import preprocessing
from sklearn.metrics import accuracy_score
from sklearn.datasets import load_digits
from sklearn.neighbors import KNeighborsClassifier
from sklearn.svm import SVC
from sklearn.naive_bayes import MultinomialNB
from sklearn.tree import DecisionTreeClassifier
import matplotlib.pyplot as plt
# 创建SVM分类器
svm = SVC()
svm.fit(train_ss_x, train_y)
predict_y=svm.predict(test_ss_x)
print('SVM准确率: %0.4lf' % accuracy_score(test_y, predict_y))
# 采用Min-Max规范化
mm = preprocessing.MinMaxScaler()
train_mm_x = mm.fit_transform(train_x)
test_mm_x = mm.transform(test_x)
# 创建Naive Bayes分类器
mnb = MultinomialNB()
mnb.fit(train_mm_x, train_y)
predict_y = mnb.predict(test_mm_x)
print("多项式朴素贝叶斯准确率: %.4lf" % accuracy_score(test_y, predict_y))
# 创建CART决策树分类器
dtc = DecisionTreeClassifier()
dtc.fit(train_mm_x, train_y)
predict_y = dtc.predict(test_mm_x)
print("CART决策树准确率: %.4lf" % accuracy_score(test_y, predict_y))

五、K均值聚类(K-Means)

I、基本原理

初始数据集:

首先我们将每条记录映射成一个多维空间内的点,并随机选择K个点作为中心点,随后通过遍历各点分别计算距离中日韩三点的距离,选择距离最近的对应中心点作为归属类别,这样我们得到了就是以K个中心点为基础扩展而来的K个点集,接下来我们再以平均值的形式计算K个点集中的新的中心点,并不断重复上述的步骤,直至每一个点的分类结果不改变。
具体而言,我们需要先对初始数据集中记录的每一个特征进行规范化,得

计算每一个点到中国、日本和韩国中心点的距离,并进行分类划分。

在得到的多个类别点集中,再次计算出各点集的新中心点。重复操作,直至分类结果不变,亦或者中心点位置不变,得到最终的聚类结果。

II、图像分割实战

1. 初始数据集

2. 数据加载
# 加载图像,并对数据进行规范化
def load_data(filePath):# 读文件f = open(filePath,'rb')data = []# 得到图像的像素值img = image.open(f)# 得到图像尺寸width, height = img.sizefor x in range(width):for y in range(height):# 得到点(x,y)的三个通道值c1, c2, c3 = img.getpixel((x, y))data.append([c1, c2, c3])f.close()# 采用Min-Max规范化mm = preprocessing.MinMaxScaler()data = mm.fit_transform(data)return np.mat(data), width, height# 加载图像,得到规范化的结果img,以及图像尺寸
img, width, height = load_data('./weixin.jpg')
3. 模型搭建
# 用K-Means对图像进行2聚类
kmeans =KMeans(n_clusters=2)
kmeans.fit(img)
label = kmeans.predict(img)
# 将图像聚类结果,转化成图像尺寸的矩阵
label = label.reshape([width, height])
4. 结果二颜色可视化
# 创建个新图像pic_mark,用来保存图像聚类的结果,并设置不同的灰度值
pic_mark = image.new("L", (width, height))
for x in range(width):for y in range(height):# 根据类别设置图像灰度, 类别0 灰度值为255, 类别1 灰度值为127pic_mark.putpixel((x, y), int(256/(label[x][y]+1))-1)
pic_mark.save("weixin_mark.jpg", "JPEG")
5. 结果十六颜色可视化

from skimage import color
# 将聚类标识矩阵转化为不同颜色的矩阵
label_color = (color.label2rgb(label)*255).astype(np.uint8)
label_color = label_color.transpose(1,0,2)
images = image.fromarray(label_color)
images.save('weixin_mark_color.jpg')

六、EM聚类

I、基本原理

通常,我们可以假设样本是符合高斯分布的,每个高斯分布都属于这个模型的组成部分,要分成 K 类就相当于是 K 个组成部分。
这样我们可以先初始化每个组成部分的高斯分布的参数,然后再看来每个样本是属于哪个组成部分。这也就是 E 步骤。
再通过得到的这些隐含变量结果,反过来求每个组成部分高斯分布的参数,即 M 步骤。反复 EM 步骤,直到每个组成部分的高斯分布参数不变为止,得到最终的聚类结果。

EM 算法相当于一个框架(最大似然估计法),可以采用不同的模型来进行聚类,比如 GMM(高斯混合模型),或者 HMM(隐马尔科夫模型)来进行聚类。

II、王者荣耀角色聚类实战

收集王者荣耀不同英雄的基本特征数据集,并在该数据集中实现聚类的效果。

# -*- coding: utf-8 -*-
import pandas as pd
import csv
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.mixture import GaussianMixture
from sklearn.preprocessing import StandardScaler# 数据加载,避免中文乱码问题
data_ori = pd.read_csv('./heros7.csv', encoding = 'gb18030')
features = [u'最大生命',u'生命成长',u'初始生命',u'最大法力', u'法力成长',u'初始法力',u'最高物攻',u'物攻成长',u'初始物攻',u'最大物防',u'物防成长',u'初始物防', u'最大每5秒回血', u'每5秒回血成长', u'初始每5秒回血', u'最大每5秒回蓝', u'每5秒回蓝成长', u'初始每5秒回蓝', u'最大攻速', u'攻击范围']
data = data_ori[features]# 对英雄属性之间的关系进行可视化分析
# 设置plt正确显示中文
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
# 用热力图呈现features_mean字段之间的相关性
corr = data[features].corr()
plt.figure(figsize=(14,14))
# annot=True显示每个方格的数据
sns.heatmap(corr, annot=True)
plt.show()# 相关性大的属性保留一个,因此可以对属性进行降维
features_remain = [u'最大生命', u'初始生命', u'最大法力', u'最高物攻', u'初始物攻', u'最大物防', u'初始物防', u'最大每5秒回血', u'最大每5秒回蓝', u'初始每5秒回蓝', u'最大攻速', u'攻击范围']
data = data_ori[features_remain]
data[u'最大攻速'] = data[u'最大攻速'].apply(lambda x: float(x.strip('%'))/100)
data[u'攻击范围']=data[u'攻击范围'].map({'远程':1,'近战':0})
# 采用Z-Score规范化数据,保证每个特征维度的数据均值为0,方差为1
ss = StandardScaler()
data = ss.fit_transform(data)
# 构造GMM聚类
gmm = GaussianMixture(n_components=30, covariance_type='full')
gmm.fit(data)
# 训练数据
prediction = gmm.predict(data)
print(prediction)
# 将分组结果输出到CSV文件中
data_ori.insert(0, '分组', prediction)
data_ori.to_csv('./hero_out.csv', index=False, sep=',')

七、关联规则挖掘

I、基本原理

初始数据集:

我们先计算单个商品的支持度,支持度是指某个商品组合出现的次数与总次数之间的比例,也就是说支持度越高,代表这个组合出现的概率越大。

商品项集 支持度
牛奶 4/5
面包 4/5
尿布 5/5
可乐 2/5
啤酒 3/5
鸡蛋 1/5

进一步筛选,筛选的阀值这里假设为0.5,也就是最小支持度,筛选后的结果只有支持度大于等于这个值的集合。

商品项集 支持度
牛奶 4/5
面包 4/5
尿布 5/5
啤酒 3/5

在这个基础上,我们再将商品两两组合,得到 k=2 项的支持度。

商品项集 支持度
牛奶 、面包 3/5
牛奶、尿布 1/5
牛奶、啤酒 2/5
面包、尿布 4/5
面包、啤酒 2/5
尿布、啤酒 3/5

再次筛掉小于最小值支持度的商品组合。

商品项集 支持度
牛奶 、面包 3/5
面包、尿布 4/5
尿布、啤酒 3/5

再对商品进行K=3项的组合。

商品项集 支持度
牛奶 、面包、尿布 3/5
面包、尿布、啤酒 2/5
牛奶、面包、啤酒 1/5

再次筛选。

商品项集 支持度
牛奶 、面包、尿布 3/5

发现进行K=4的商品组合的支持度计算,结果为空,此时算法结束。

上述每一个经过筛选的结果项集都是频繁项集,频繁项集就是支持度大于等于最小支持度 (Min Support) 阈值的项集,因此Apriori 算法其实就是查找频繁项集 (frequent itemset) 的过程。
其中,除了支持度这个概念,关联规则还涉及置信度和提升度。置信度是一个条件概率,就是在 A 发生的情况下,B 发生的概率是多少。而提升度代表的是“商品 A 的出现,对商品 B 的出现概率提升了多少”。

II、导演选择演员的偏好探索实战

1. 数据抓取
# -*- coding: utf-8 -*-
# 下载某个导演的电影数据集
from efficient_apriori import apriori
from lxml import etree
import time
from selenium import webdriver
import csv
driver = webdriver.Chrome()
# 设置想要下载的导演 数据集
director = u'宁浩'
# 写CSV文件
file_name = './' + director + '.csv'
base_url = 'https://movie.douban.com/subject_search?search_text='+director+'&cat=1002&start='
out = open(file_name,'w', newline='', encoding='utf-8-sig')
csv_write = csv.writer(out, dialect='excel')
flags=[]
# 下载指定页面的数据
def download(request_url):driver.get(request_url)time.sleep(1)html = driver.find_element_by_xpath("//*").get_attribute("outerHTML")html = etree.HTML(html)# 设置电影名称,导演演员 的XPATHmovie_lists = html.xpath("/html/body/div[@id='wrapper']/div[@id='root']/div[1]//div[@class='item-root']/div[@class='detail']/div[@class='title']/a[@class='title-text']")name_lists = html.xpath("/html/body/div[@id='wrapper']/div[@id='root']/div[1]//div[@class='item-root']/div[@class='detail']/div[@class='meta abstract_2']")# 获取返回的数据个数num = len(movie_lists)if num > 15: #第一页会有16条数据# 默认第一个不是,所以需要去掉movie_lists = movie_lists[1:]name_lists = name_lists[1:]for (movie, name_list) in zip(movie_lists, name_lists):# 会存在数据为空的情况if name_list.text is None: continue# 显示下演员名称print(name_list.text)names = name_list.text.split('/')# 判断导演是否为指定的directorif names[0].strip() == director and movie.text not in flags:# 将第一个字段设置为电影名称names[0] = movie.textflags.append(movie.text)csv_write.writerow(names)print('OK') # 代表这页数据下载成功print(num)if num >= 14: #有可能一页会有14个电影# 继续下一页return Trueelse:# 没有下一页return False# 开始的ID为0,每页增加15
start = 0
while start<10000: #最多抽取1万部电影request_url = base_url + str(start)# 下载数据,并返回是否有下一页flag = download(request_url)if flag:start = start + 15else:break
out.close()
print('finished')

2. 模型搭建,输出频繁项集和频繁规则
# -*- coding: utf-8 -*-
from efficient_apriori import apriori
import csv
director = u'宁浩'
file_name = './'+director+'.csv'
lists = csv.reader(open(file_name, 'r', encoding='utf-8-sig'))
# 数据加载
data = []
for names in lists:name_new = []for name in names:# 去掉演员数据中的空格name_new.append(name.strip())data.append(name_new[1:])
# 挖掘频繁项集和关联规则
itemsets, rules = apriori(data, min_support=0.5,  min_confidence=1)
print(itemsets)
print(rules)


可以看出,宁浩导演喜欢用徐峥和黄渤,并且有徐峥的情况下,一般都会用黄渤。

八、网页排名(PageRank)

I、基本原理

当我们在搜索引擎填写关键字得到的结果页面中,页面之间的排序顺序主要是由这个页面的影响力来决定的,一般而言,页面的影响力越大排名越在前面。
页面的影响力的计算公式如下:
PR(u)=∑v∈BuPR(v)L(v)PR(u)=\sum_{v \in B_u}{\frac{PR(v)}{L(v)}}PR(u)=v∈Bu​∑​L(v)PR(v)​
其中,uuu 为待评估的页面,BuBuBu​ 为页面uuu 的入链集合。针对入链集合中的任意页面 vvv,它能给 uuu带来的影响力是其自身的影响力PR(v)PR(v)PR(v)除以vvv页面的出链数量,即页面 vvv把影响力PR(v)PR(v)PR(v) 平均分配给了它的出链。

具体而言的话,假设我们现在有四个页面,它们之间的相互引用关系如下:

我们可以知道当用户访问 A 的时候,跳转到 B、C 或者 D 的可能性均为 1/3,同理对B、C和D也能分别得到一个4X1的矩阵,将这些矩阵进行列拼接可以得到这四个页面的转移矩阵MMM。
,


我们再假设每个页面的初始影响力都是平均的,即都是1/4,那么我么可以得到一个4X1的页面影响力矩阵 W0W_0W0​。

,

将两个矩阵进行相乘,得到第一次转移后各页面的影响力。

不断用新的wiw_iwi​来乘以MMM直至 wiw_iwi​的值不再发生变化,此时wiw_iwi​的值就是各页面最终平衡状态下的影响力,在这里结果为(0.3333,0.2222,0.2222,0.2222)(0.3333,0.2222,0.2222,0.2222)(0.3333,0.2222,0.2222,0.2222)。
根据结果可知,A页面的影响力相对较大,因此其在排名中应位于最靠前的位置上。

II、希拉里邮件中的人物关系分析实战

通过 PageRank 算法计算每个人物在邮件关系网络中的权重,最后筛选出来最有价值的人物来进行关系网络图的绘制。

1. 初始数据集

Alises.csv:别名和人物的对应关系
Emails.csv:所有公开邮件的内容,发送者和接收者的信息
Persons.csv: 邮件中所有人物的姓名及对应的 ID

2. 代码实现
# -*- coding: utf-8 -*-
# 用 PageRank 挖掘希拉里邮件中的重要任务关系
import pandas as pd
import networkx as nx
import numpy as np
from collections import defaultdict
import matplotlib.pyplot as plt
# 数据加载
emails = pd.read_csv("./input/Emails.csv")
# 读取别名文件
file = pd.read_csv("./input/Aliases.csv")
aliases = {}
for index, row in file.iterrows():aliases[row['Alias']] = row['PersonId']
# 读取人名文件
file = pd.read_csv("./input/Persons.csv")
persons = {}
for index, row in file.iterrows():persons[row['Id']] = row['Name']
# 针对别名进行转换
def unify_name(name):# 姓名统一小写name = str(name).lower()# 去掉, 和 @后面的内容name = name.replace(",","").split("@")[0]# 别名转换if name in aliases.keys():return persons[aliases[name]]return name
# 画网络图
def show_graph(graph, layout='spring_layout'):# 使用 Spring Layout 布局,类似中心放射状if layout == 'circular_layout':positions=nx.circular_layout(graph)else:positions=nx.spring_layout(graph)# 设置网络图中的节点大小,大小与 pagerank 值相关,因为 pagerank 值很小所以需要 *20000nodesize = [x['pagerank']*20000 for v,x in graph.nodes(data=True)]# 设置网络图中的边长度edgesize = [np.sqrt(e[2]['weight']) for e in graph.edges(data=True)]# 绘制节点nx.draw_networkx_nodes(graph, positions, node_size=nodesize, alpha=0.4)# 绘制边nx.draw_networkx_edges(graph, positions, edge_size=edgesize, alpha=0.2)# 绘制节点的 labelnx.draw_networkx_labels(graph, positions, font_size=10)# 输出希拉里邮件中的所有人物关系图plt.show()
# 将寄件人和收件人的姓名进行规范化
emails.MetadataFrom = emails.MetadataFrom.apply(unify_name)
emails.MetadataTo = emails.MetadataTo.apply(unify_name)
# 设置遍的权重等于发邮件的次数
edges_weights_temp = defaultdict(list)
for row in zip(emails.MetadataFrom, emails.MetadataTo, emails.RawText):temp = (row[0], row[1])if temp not in edges_weights_temp:edges_weights_temp[temp] = 1else:edges_weights_temp[temp] = edges_weights_temp[temp] + 1
# 转化格式 (from, to), weight => from, to, weight
edges_weights = [(key[0], key[1], val) for key, val in edges_weights_temp.items()]
# 创建一个有向图
graph = nx.DiGraph()
# 设置有向图中的路径及权重 (from, to, weight)
graph.add_weighted_edges_from(edges_weights)
# 计算每个节点(人)的 PR 值,并作为节点的 pagerank 属性
pagerank = nx.pagerank(graph)
# 将 pagerank 数值作为节点的属性
nx.set_node_attributes(graph, name = 'pagerank', values=pagerank)
# 画网络图
show_graph(graph)# 将完整的图谱进行精简
# 设置 PR 值的阈值,筛选大于阈值的重要核心节点
pagerank_threshold = 0.005
# 复制一份计算好的网络图
small_graph = graph.copy()
# 剪掉 PR 值小于 pagerank_threshold 的节点
for n, p_rank in graph.nodes(data=True):if p_rank['pagerank'] < pagerank_threshold: small_graph.remove_node(n)
# 画网络图,采用circular_layout布局让筛选出来的点组成一个圆
show_graph(small_graph, 'circular_layout')

九、增强学习(Adaboost)

I、基本原理

初始数据集:

X 0 1 2 3 4 5 6 7 8 9
Y 1 1 1 -1 -1 -1 1 1 1 -1

假设第一轮训练中,我们得到10个样本的权重都是均匀的,那么整个样本集的权重矩阵D1=(0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1)D_1=(0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1)D1​=(0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1),同时假设我们已经获得了三个基础分类器fi(x)f_i(x)fi​(x).
f1(x)={1,x≤2.5−1,x>2.5;f2(x)={−1,x≤5.51,x>5.5;f3(x)={1,x≤8.5−1,x>8.5f_1(x)= \left\{ \begin{array}{ll} 1, & x \leq 2.5\\ -1, & x > 2.5 \end{array} \right. \quad;\quad f_2(x)= \left\{ \begin{array}{ll} -1, & x \leq 5.5\\ 1, & x > 5.5 \end{array} \right. \quad ;\quad f_3(x)= \left\{ \begin{array}{ll} 1, & x \leq 8.5\\ -1, & x > 8.5 \end{array} \right. f1​(x)={1,−1,​x≤2.5x>2.5​;f2​(x)={−1,1,​x≤5.5x>5.5​;f3​(x)={1,−1,​x≤8.5x>8.5​
依次将X值带入分类器中,使得到的结果与实际对应的Y值对比,可以知道f1、f2、f3f_1、f_2、f_3f1​、f2​、f3​的错误率分别为0.3、0.4和0.3,此时我们选择错误率最小的f1、f3f_1、f_3f1​、f3​中任选一个作为最优分类器,这里我们选择f1f_1f1​,即G1=f1G_1=f_1G1​=f1​,并通过下面的公式计算该最优分类器的权重α1=0.4236\alpha_1=0.4236α1​=0.4236。
αi=12log1−eiei\alpha_i=\frac{1}{2}log{\frac{1-e_i}{e_i}} αi​=21​logei​1−ei​​
再进一步利用下面的公式更新每一个样本的权重,即最新的样本集权重矩阵D2=(0.0715,0.0715,0.0715,0.0715,0.0715,0.0715,0.1666,0.1666,0.1666,0.0715)D_2=(0.0715, 0.0715, 0.0715, 0.0715, 0.0715, 0.0715, 0.1666, 0.1666, 0.1666, 0.0715)D2​=(0.0715,0.0715,0.0715,0.0715,0.0715,0.0715,0.1666,0.1666,0.1666,0.0715)。

Dk+1=(wk+1,1,wk+1,2,…,wk+1,N)wk+1,i=wk,iZkexp(−αkyiGk(xi)),i=1,2,…,ND_{k+1}=(w_{k+1,1},w_{k+1,2},\dots,w_{k+1,N}) \\ w_{k+1,i}=\frac{w_{k,i}}{Z_k}exp(-\alpha_ky_iG_k(x_i)),i=1,2,\dots,N Dk+1​=(wk+1,1​,wk+1,2​,…,wk+1,N​)wk+1,i​=Zk​wk,i​​exp(−αk​yi​Gk​(xi​)),i=1,2,…,N
其中wk+1,iw_{k+1,i}wk+1,i​指的是在k+1k+1k+1轮训练中第iii个样本的权重。
接下来开始第二轮训练,重复上述的操作,f1、f2、f3f_1、f_2、f_3f1​、f2​、f3​的错误率分别为0.16663、 0.07154和0.0715*3,此时我们选择错误率最小的f3f_3f3​作为最优分类器,即G2=f3G_2=f_3G2​=f3​,并计算出了α2=0.6496\alpha_2=0.6496α2​=0.6496、D3=(0.0455,0.0455,0.0455,0.1667,0.1667,0.01667,0.1060,0.1060,0.1060,0.0455)D_3=(0.0455,0.0455,0.0455,0.1667, 0.1667,0.01667,0.1060, 0.1060, 0.1060, 0.0455)D3​=(0.0455,0.0455,0.0455,0.1667,0.1667,0.01667,0.1060,0.1060,0.1060,0.0455)。
开始第三轮,仍然是重复操作,得到G3=f2、α3=0.7514G_3=f_2、\alpha_3=0.7514G3​=f2​、α3​=0.7514。此时得到最终的强分类器G(x)=0.4236G1(x)+0.6496G2(x)+0.7514G3(x)G(x) = 0.4236G1(x) + 0.6496G2(x)+0.7514G3(x)G(x)=0.4236G1(x)+0.6496G2(x)+0.7514G3(x)。

II、房价预测实战

1. 初始数据集

2. 代码实现
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
from sklearn.datasets import load_boston
from sklearn.ensemble import AdaBoostRegressor
# 加载数据
data=load_boston()
# 分割数据
train_x, test_x, train_y, test_y = train_test_split(data.data, data.target, test_size=0.25, random_state=33)
# 使用AdaBoost回归模型
regressor=AdaBoostRegressor()
regressor.fit(train_x,train_y)
pred_y = regressor.predict(test_x)
mse = mean_squared_error(test_y, pred_y)
print("房价预测结果 ", pred_y)
print("均方误差 = ",round(mse,2))# 使用决策树回归模型
dec_regressor=DecisionTreeRegressor()
dec_regressor.fit(train_x,train_y)
pred_y = dec_regressor.predict(test_x)
mse = mean_squared_error(test_y, pred_y)
print("决策树均方误差 = ",round(mse,2))
# 使用KNN回归模型
knn_regressor=KNeighborsRegressor()
knn_regressor.fit(train_x,train_y)
pred_y = knn_regressor.predict(test_x)
mse = mean_squared_error(test_y, pred_y)
print("KNN均方误差 = ",round(mse,2))
3. 模型的对比
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.metrics import zero_one_loss
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import  AdaBoostClassifier
# 设置AdaBoost迭代次数
n_estimators=200
# 使用
X,y=datasets.make_hastie_10_2(n_samples=12000,random_state=1)
# 从12000个数据中取前2000行作为测试集,其余作为训练集
train_x, train_y = X[2000:],y[2000:]
test_x, test_y = X[:2000],y[:2000]
# 弱分类器
dt_stump = DecisionTreeClassifier(max_depth=1,min_samples_leaf=1)
dt_stump.fit(train_x, train_y)
dt_stump_err = 1.0-dt_stump.score(test_x, test_y)
# 决策树分类器
dt = DecisionTreeClassifier()
dt.fit(train_x,  train_y)
dt_err = 1.0-dt.score(test_x, test_y)
# AdaBoost分类器
ada = AdaBoostClassifier(base_estimator=dt_stump,n_estimators=n_estimators)
ada.fit(train_x,  train_y)
# 三个分类器的错误率可视化
fig = plt.figure()
# 设置plt正确显示中文
plt.rcParams['font.sans-serif'] = ['SimHei']
ax = fig.add_subplot(111)
ax.plot([1,n_estimators],[dt_stump_err]*2, 'k-', label=u'决策树弱分类器 错误率')
ax.plot([1,n_estimators],[dt_err]*2,'k--', label=u'决策树模型 错误率')
ada_err = np.zeros((n_estimators,))
# 遍历每次迭代的结果 i为迭代次数, pred_y为预测结果
for i,pred_y in enumerate(ada.staged_predict(test_x)):# 统计错误率ada_err[i]=zero_one_loss(pred_y, test_y)
# 绘制每次迭代的AdaBoost错误率
ax.plot(np.arange(n_estimators)+1, ada_err, label='AdaBoost Test 错误率', color='orange')
ax.set_xlabel('迭代次数')
ax.set_ylabel('错误率')
leg=ax.legend(loc='upper right',fancybox=True)
plt.show()


从图中可以看出,弱分类器的错误率最高,只比随机分类结果略好,准确率稍微大于 50%。决策树模型的错误率明显要低很多。 AdaBoost 模型在迭代次数超过 25 次之后,错误率有了明显下降,经过 125 次迭代之后错误率的变化形势趋于平缓。

整理总结:机器学习常用九大算法相关推荐

  1. 机器学习九大算法---支持向量机

    机器学习九大算法---支持向量机 出处:结构之法算法之道blog. 前言 动笔写这个支持向量机(support vector machine)是费了不少劲和困难的,原因很简单,一者这个东西本身就并不好 ...

  2. DL之DNN:基于Tensorflow框架对神经网络算法进行参数初始化的常用九大函数及其使用案例

    DL之DNN:基于Tensorflow框架对神经网络算法进行参数初始化的常用九大函数及其使用案例 目录 基于Tensorflow框架对神经网络算法进行初始化的常用函数及其使用案例 1.初始化的常用函数

  3. 基于Spark的机器学习实践 (九) - 聚类算法

    0 相关源码 1 k-平均算法(k-means clustering)概述 1.1 回顾无监督学习 ◆ 分类.回归都属于监督学习 ◆ 无监督学习是不需要用户去指定标签的 ◆ 而我们看到的分类.回归算法 ...

  4. 常用十大算法_回溯算法

    回溯算法 回溯算法已经在前面详细的分析过了,详见猛击此处. 简单的讲: 回溯算法是一种局部暴力的枚举算法 循环中,若条件满足,进入递归,开启下一次流程,若条件不满足,就不进行递归,转而进行上一次流程. ...

  5. 常用十大算法_KMP算法

    KMP算法 FBI提示:KMP算法不好理解, 建议视频+本文+其他博客,别走马观花 KMP算法是用于文本匹配的算法,属于模式搜索(pattern Searching)问题的一种算法,在讲KMP算法之前 ...

  6. 常用十大算法(七)— 克鲁斯卡尔算法

    常用十大算法(七)- 克鲁斯卡尔算法 博客说明 文章所涉及的资料来自互联网整理和个人总结,意在于个人学习和经验汇总,如有什么地方侵权,请联系本人删除,谢谢! 介绍 克鲁斯卡尔(Kruskal)算法,是 ...

  7. 数据挖掘与机器学习的十大算法

    机器学习与数据挖掘中的十大经典算法 背景: top10算法的前期背景是吴教授在香港做了一个关于数据挖掘top10挑战的一个报告,会后有一名内地的教授提出了一个类似的想法.吴教授觉得非常好,开始着手解决 ...

  8. 常用十大算法 非递归二分查找、分治法、动态规划、贪心算法、回溯算法(骑士周游为例)、KMP、最小生成树算法:Prim、Kruskal、最短路径算法:Dijkstra、Floyd。

    十大算法 学完数据结构该学什么?当然是来巩固算法,下面介绍了十中比较常用的算法,希望能帮到大家. 包括:非递归二分查找.分治法.动态规划.贪心算法.回溯算法(骑士周游为例).KMP.最小生成树算法:P ...

  9. 【机器学习】十大算法之一 “PCA”

    作者主页:爱笑的男孩.的博客_CSDN博客-深度学习,活动,python领域博主爱笑的男孩.擅长深度学习,活动,python,等方面的知识,爱笑的男孩.关注算法,python,计算机视觉,图像处理,深 ...

最新文章

  1. 11项重大发布!百度大脑语言与知识技术峰会全程高能
  2. 这次终于不再为 iptables 犯迷糊了!
  3. Leangoo英文版来了~
  4. java struts2配置_Struts2初始化配置的问题
  5. 插入排序-by-Python
  6. 使用Java客户端操作elasticsearch--设置mappings、添加文档、查询数据
  7. 如何给 SAP Spartacus Storefront 创建新的页面
  8. 趣话题:git三部曲(二)-拆分历史提交记录reset
  9. Android应用开发提高篇(2)-----文本朗读TTS(TextToSpeech)
  10. C++第五章课后习题13
  11. 1. Window环境下 - 开发环境的配置: (安装Android Studio 2.1)
  12. 电脑只有.exe文件不显示后缀名
  13. python超清壁纸_Python爬取5K分辨率超清唯美壁纸
  14. 华为q1设置虚拟服务器,华为路由Q1上网设置【图文】教程 | 192路由网
  15. 区块链普惠云签扶持计划 京东数科助力中小企业复工复产
  16. iPhone升级系统 死机了怎么办
  17. 2022年制冷与空调设备运行操作考试模拟100题及答案
  18. 最小绝对偏差(LAD)
  19. krpano 全景图在微信里面被屏蔽的解决办法
  20. Mac安装升级truffle

热门文章

  1. nginx配置移动端与PC端访问规则
  2. 通过UserAgent判断是手机访问还是PC访问
  3. Jetson Orin 踩坑指南
  4. 论文阅读——《动态规划》 作者 方奇
  5. 20155314 2016-2017-2 《Java程序设计》第9周学习总结
  6. Android 开发 Tip 3 -- that was originally added here
  7. 表字段加了索引但是查询依然很慢
  8. 3分钟了解什么是期权—行权?
  9. linux用户解锁pam_tally,多次登录失败用户被锁定及使用Pam_Tally2解锁
  10. 托勒密定理 圆的内接四边形