CategoryResourceRepost/极客时间专栏/数据分析实战45讲/第二模块:数据分析算法篇/36丨数据分析算法篇答疑.md
louzefeng d3828a7aee mod
2024-07-11 05:50:32 +00:00

210 lines
13 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<audio id="audio" title="36丨数据分析算法篇答疑" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/3a/dc/3a270c9d41162f04114d357a1dc5eedc.mp3"></audio>
算法篇更新到现在就算结束了,因为这一模块比较难,所以大家提出了形形色色的问题。我总结了同学们经常遇到的问题,精选了几个有代表性的来作为答疑。没有列出的问题,我也会在评论区陆续解答。
## 17-19篇决策树
### 答疑1在探索数据的代码中print(boston.feature_names)有什么作用?
boston是sklearn自带的数据集里面有5个keys分别是data、target、feature_names、DESCR和filename。其中data代表特征矩阵target代表目标结果feature_names代表data对应的特征名称DESCR是对数据集的描述filename对应的是boston这个数据在本地的存放文件路径。
针对sklearn中自带的数据集你可以查看下加载之后都有哪些字段。调用方法如下
```
boston=load_boston()
print(boston.keys())
```
通过boston.keys()你可以看到boston数据集的字段包括了[data, target, feature_names, DESCR, filename]。
### 答疑2决策树的剪枝在sklearn中是如何实现的
实际上决策树分类器以及决策树回归器对应DecisionTreeRegressor类都没有集成剪枝步骤。一般对决策树进行缩减常用的方法是在构造DecisionTreeClassifier类时对参数进行设置比如max_depth表示树的最大深度max_leaf_nodes表示最大的叶子节点数。
通过调整这两个参数,就能对决策树进行剪枝。当然也可以自己编写剪枝程序完成剪枝。
### 答疑3对泰坦尼克号的乘客做生存预测的时候Carbin字段缺失率分别为77%和78%Age和Fare字段有缺失值是如何判断出来的
首先我们需要对数据进行探索一般是将数据存储到DataFrame中使用df.info()可以看到表格的一些具体信息,代码如下:
```
# 数据加载
train_data = pd.read_csv('./Titanic_Data/train.csv')
test_data = pd.read_csv('./Titanic_Data/test.csv')
print(train_data.info())
print(test_data.info())
```
这是运行结果:
```
&lt;class 'pandas.core.frame.DataFrame'&gt;
RangeIndex: 891 entries, 0 to 890
Data columns (total 12 columns):
PassengerId 891 non-null int64
Survived 891 non-null int64
Pclass 891 non-null int64
Name 891 non-null object
Sex 891 non-null object
Age 714 non-null float64
SibSp 891 non-null int64
Parch 891 non-null int64
Ticket 891 non-null object
Fare 891 non-null float64
Cabin 204 non-null object
Embarked 889 non-null object
dtypes: float64(2), int64(5), object(5)
memory usage: 83.6+ KB
None
&lt;class 'pandas.core.frame.DataFrame'&gt;
RangeIndex: 418 entries, 0 to 417
Data columns (total 11 columns):
PassengerId 418 non-null int64
Pclass 418 non-null int64
Name 418 non-null object
Sex 418 non-null object
Age 332 non-null float64
SibSp 418 non-null int64
Parch 418 non-null int64
Ticket 418 non-null object
Fare 417 non-null float64
Cabin 91 non-null object
Embarked 418 non-null object
dtypes: float64(2), int64(4), object(5)
memory usage: 36.0+ KB
None
```
你可以关注下运行结果中Carbin的部分你能看到在训练集中一共891行数据Carbin有数值的只有204个那么缺失率为1-204/891=77%同样在测试集中一共有418行数据Carbin有数值的只有91个那么缺失率为1-91/418=78%。
同理你也能看到在训练集中Age字段有缺失值。在测试集中Age字段和Fare字段有缺失值。
### 答疑4在用pd.read_csv时报错“UnicodeDecodeError utf-8 codec cant decode byte 0xcf in position 15: invalid continuation byte”是什么问题
一般在Python中遇到编码问题尤其是中文编码出错是比较常见的。有几个常用的解决办法你可以都试一下
<li>
将read_csv中的编码改为gb18030代码为data = pd.read_csv(filename, encoding = gb18030)。
</li>
<li>
代码前添加# -**- coding: utf-8 -**-。
</li>
我说一下gb18030和utf-8的区别。utf-8是国际通用字符编码gb18030是新出的国家标准不仅包括了简体和繁体也包括了一些不常见的中文相比于utf-8更全容错率更高。
为了让编辑器对中文更加支持,你也可以在代码最开始添加# -**- coding: utf-8 -**- 的说明,再结合其他方法解决编码出错的问题。
## 第20-21篇朴素贝叶斯
### 答疑1在朴素贝叶斯中我们要统计的是属性的条件概率也就是假设取出来的是白色的棋子那么它属于盒子 A 的概率是 2/3。这个我算的是3/5跟老师的不一样老师可以给一下详细步骤吗
不少同学都遇到了这个问题,我来统一解答下。
这里我们需要运用贝叶斯公式(我在文章中也给出了),即:
<img src="https://static001.geekbang.org/resource/image/88/a1/88f2981f938fac38980f1325fe7046a1.png" alt=""><br>
假设A代表白棋子B1代表A盒B2代表B盒。带入贝叶斯公式我们可以得到
<img src="https://static001.geekbang.org/resource/image/63/8a/633e213385195fb958520f513a3d9f8a.png" alt=""><br>
其中$P(B_{1})$代表A盒的概率7个棋子A盒有4个所以$P(B_{1})$=4/7。
$P(B_{2})$代表B盒的概率7个棋子B盒有3个所以$P(B_{2})$=3/7。
最终求取出来的是白色的棋子,那么它属于 A盒的概率$P(B_{1}|A)$= 2/3。
## 22-23篇SVM算法
### 答疑1SVM多分类器是集成算法么
SVM算法最初是为二分类问题设计的如果我们想要把SVM分类器用于多分类问题常用的有一对一方法和一对多方法我在文章中有介绍到
集成学习的概念你这样理解:通过构造和使用多个分类器完成分类任务,也就是我们所说的博取众长。
以上是SVM多分类器和集成算法的概念关于SVM多分类器是否属于集成算法我认为你需要这样理解。
在SVM的多分类问题中不论是采用一对一还是一对多的方法都会构造多个分类器从这个角度来看确实在用集成学习的思想通过这些分类器完成最后的学习任务。
不过我们一般所说的集成学习,需要有两个基本条件:
<li>
每个分类器的准确率要比随机分类的好即准确率大于50%
</li>
<li>
每个分类器应该尽量相互独立,这样才能博采众长,否则多个分类器一起工作,和单个分类器工作相差不大。
</li>
所以你能看出在集成学习中虽然每个弱分类器性能不强但都可以独立工作完成整个分类任务。而在SVM多分类问题中不论是一对一还是一对多的方法每次都在做一个二分类问题并不能直接给出多分类的结果。
此外当我们谈集成学习的时候通常会基于单个分类器之间是否存在依赖关系进而分成Boosting或者Bagging方法。如果单个分类器存在较强的依赖关系需要串行使用也就是我们所说的Boosting方法。如果单个分类器之间不存在强依赖关系可以并行工作就是我们所说的Bagging或者随机森林方法Bagging的升级版
所以一个二分类器构造成多分类器是采用了集成学习的思路不过在我们谈论集成学习的时候通常指的是Boosing或者Bagging方法因为需要每个分类器弱分类器都有分类的能力。
## 26-27篇K-Means
### 答疑1我在给20支亚洲球队做聚类模拟的时候使用K-Means算法需要重新计算这三个类的中心点最简单的方式就是取平均值然后根据新的中心点按照距离远近重新分配球队的分类。对中心点的重新计算不太理解。
实际上是对属于这个类别的点的特征值求平均,即为新的中心点的特征值。
比如都属于同一个类别里面有10个点那么新的中心点就是这10个点的中心点一种简单的方式就是取平均值。比如文章中的足球队一共有3个指标每个球队都有这三个指标的特征值那么新的中心点就是取这个类别中的这些点的这三个指标特征值的平均值。
## 28-29篇EM聚类
### 答疑1关于EM聚类初始参数设置的问题初始参数随机设置会影响聚类的效果吗。会不会初始参数不对聚类就出错了呢
实际上只是增加了迭代次数而已。
EM算法的强大在于它的鲁棒性或者说它的机制允许初始化参数存在误差。
举个例子EM的核心是通过参数估计来完成聚类。如果你想要把菜平均分到两个盘子中一开始A盘的菜很少B盘的菜很多我们只要通过EM不断迭代就会让两个盘子的菜量一样多只是迭代的次数多一些而已。
另外多说一句我们学的这些数据挖掘的算法不论是EM、Adaboost还是K-Means最大的价值都是它们的思想。我们在使用工具的时候都会设置初始化参数比如在K-Means中要选择中心点即使一开始只是随机选择最后通过迭代都会得到不错的效果。所以说学习这些算法就是学习它们的思想。
## 30-31篇关联规则挖掘
### 答疑1看不懂构造FP树的过程面包和啤酒为什么会拆分呢
FP-Growth中有一个概念叫条件模式基。它在创建FP树的时候还用不上我们主要通过扫描整个数据和项头表来构造FP树。条件模式基用于挖掘频繁项。通过找到每个项item的条件模式基递归挖掘频繁项集。
### 答疑2不怎么会找元素的XPath路径。
XPath的作用大家应该都能理解具体的使用其实就是经验和技巧的问题。
我的方法就是不断尝试而且XPath有自己的规则绝大部分的情况下都是以//开头因为想要匹配所有的元素。我们也可以找一些关键的特征来进行匹配比如class='item-root的节点或者id='root都是很好的特征。通过观察id或class也可以自己编写XPath这样写的XPath会更短。总之都是要不断尝试才能找到自己想要找的内容寻找XPath的过程就是一个找规律的过程。
### 答疑3最小支持度可以设置小一些如果最小支持度小那么置信度就要设置得相对大一点不然即使提升度高也有可能是巧合。这个参数跟数据量以及项的数量有关。理解对吗
一般来说最小置信度都会大一些比如1.00.9或者0.8。最小支持度和数据集大小和特点有关可以尝试一些数值来观察结果比如0.10.5。
## 34-35篇AdaBoost算法
### 答疑1关于$Z_{k}$和$y_{i}$的含义
第 k+1 轮的样本权重,是根据该样本在第 k 轮的权重以及第 k 个分类器的准确率而定,具体的公式为:
<img src="https://static001.geekbang.org/resource/image/1c/cd/1c812efcf6173652cf152f2ad25987cd.png" alt=""><br>
其中$Z_{k}$, $y_{i}$代表什么呢?
$Z_{k}$代表规范化因子我们知道第K+1轮样本的权重为
<img src="https://static001.geekbang.org/resource/image/ce/c8/ce857425d5465209bf7cd2529e31e3c8.png" alt=""><br>
为了让样本权重之和为1我们需要除以规范化因子$Z_{k}$,所以:
<img src="https://static001.geekbang.org/resource/image/94/58/940d9b4b8889c668074e1dbaac275f58.png" alt=""><br>
$y_{i}$代表的是目标的结果我在AdaBoost工作原理之后列了一个10个训练样本的例子
<img src="https://static001.geekbang.org/resource/image/df/ed/df33bd6ee148b1333b531252e5a936ed.png" alt=""><br>
你能看到通常我们把X作为特征值y作为目标结果。在算法篇下的实战练习中我们一般会把训练集分成train_X和train_y其中train_X代表特征矩阵train_y代表目标结果。
我发现大家对工具的使用和场景比较感兴趣,所以最后留两道思考题。
第一道题是在数据挖掘的工具里我们大部分情况下使用的是sklearn它自带了一些数据集你能列举下sklearn自带的数据集都有哪些么我在第18篇使用print(boston.feature_names)来查看boston数据集的特征名称数据集特征矩阵的index名称你能查看下其他数据集的特征名称都是什么吗列举1-2个sklearn数据集即可。
第二个问题是对于数据挖掘算法来说基础就是数据集。Kaggle网站之所以受到数据科学从业人员的青睐就是因为有众多比赛的数据集以及社区间的讨论交流。你是否有使用过Kaggle网站的经历如果有的话可以分享下你的使用经验吗如果你是个数据分析的新人当看到Kaggle网站时能否找到适合初学者的kernels么(其他人在Kaggle上成功运行的代码分享)
欢迎你在评论区与我分享你的答案,也欢迎点击“请朋友读”,把这篇文章分享给你的朋友或者同事。