36丨数据分析算法篇答疑

算法篇更新到现在就算结束了,因为这一模块比较难,所以大家提出了形形色色的问题。我总结了同学们经常遇到的问题,精选了几个有代表性的来作为答疑。没有列出的问题,我也会在评论区陆续解答。

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 中自带的数据集,你可以查看下加载之后,都有哪些字段。调用方法如下:

1
2
3

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() 可以看到表格的一些具体信息,代码如下:

1
2
3
4
5
6

# 数据加载
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())

这是运行结果:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

<class 'pandas.core.frame.DataFrame'>
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
<class 'pandas.core.frame.DataFrame'>
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 can’t decode byte 0xcf in position 15: invalid continuation byte”是什么问题?

一般在 Python 中遇到编码问题,尤其是中文编码出错,是比较常见的。有几个常用的解决办法,你可以都试一下:

将 read_csv 中的编码改为 gb18030,代码为:data = pd.read_csv(filename, encoding = ‘gb18030’)。

代码前添加 # -- coding: utf-8 --。

我说一下 gb18030 和 utf-8 的区别。utf-8 是国际通用字符编码,gb18030 是新出的国家标准,不仅包括了简体和繁体,也包括了一些不常见的中文,相比于 utf-8 更全,容错率更高。

为了让编辑器对中文更加支持,你也可以在代码最开始添加 # -- coding: utf-8 -- 的说明,再结合其他方法解决编码出错的问题。

第 20-21 篇:朴素贝叶斯

答疑 1:在朴素贝叶斯中,我们要统计的是属性的条件概率,也就是假设取出来的是白色的棋子,那么它属于盒子 A 的概率是 2/3。这个我算的是 3/5,跟老师的不一样,老师可以给一下详细步骤吗?

不少同学都遇到了这个问题,我来统一解答下。

这里我们需要运用贝叶斯公式(我在文章中也给出了),即:

假设 A 代表白棋子,B1 代表 A 盒,B2 代表 B 盒。带入贝叶斯公式,我们可以得到:

其中 P(B1)P(B1) 代表 A 盒的概率,7 个棋子,A 盒有 4 个,所以