03.md 16.7 KB
Newer Older
W
wizardforcel 已提交
1
# 三、大海捞针
W
wizardforcel 已提交
2 3 4

分析数据集以查找模式既是一门艺术,也是一门科学。 数据集可能有很多指标,您想在这堆干草堆中找到要害。 对于我们来说,针是我们在以前不知道的数据中寻找的洞察力。 在这里,洞察力可能指的是有关购买特定品牌牛奶以及购买其他品牌谷物的人们的重要信息。 然后,零售商店可以将产品彼此靠近堆叠。

W
wizardforcel 已提交
5
每当您尝试分析数据集时,都应该对它以及与它关联的域有详细的了解。 如果这是一个易于理解的简单数据集,则可以直接进行分析,但是如果该数据集与涡轮机的传感器数据相关,则对涡轮机如何工作以及对其功能至关重要的领域的领域理解将增加分析的丰富性。
W
wizardforcel 已提交
6 7 8 9 10 11 12 13 14 15 16 17 18

对域的理解就像北极星一样:它可以帮助您浏览分析。

在本章中,您将学习以下主题:

*   如何为数据挖掘构建分析
*   如何呈现您的分析
*   如何对泰坦尼克号幸存者数据集进行数据挖掘

![Finding a Needle in a Haystack](img/3450_03_01.jpg)

# 什么是数据挖掘?

W
wizardforcel 已提交
19
数据挖掘是使用机器学习,统计信息和数据库系统探索数据并在其中寻找模式的过程。 数据挖掘的最终目标是从数据中获取有用的信息,这些信息可用于通过某些应用来增加收入,降低成本甚至挽救生命。
W
wizardforcel 已提交
20 21 22 23 24

当您有一个需要挖掘的数据集时,使用在数据的每个列字段上可用的所有数据挖掘技术来获得洞察力是不可行的。 这将是一项繁琐的任务,并且需要很长时间才能得出任何有用的见解。

为了加快数据挖掘的过程,领域知识是一个很大的帮助。 有了这些知识,就可以了解数据代表什么以及如何分析数据以获取见解。

W
wizardforcel 已提交
25
开始数据挖掘的最佳方法是派生需要挖掘数据的主题。 如果您具有**快速消费品****FMCG**)公司的销售数据,则主题可能如下:
W
wizardforcel 已提交
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43

*   品牌行为
*   出口行为
*   产品成长
*   对产品的季节性影响

这些主题可为您提供指导,以探索数据并在其中寻找模式,从而为您提供帮助。

有了主题后,您需要在主题下提出问题以简化分析:

*   **品牌行为**:以下是用于简化分析的问题:

    *   哪些顶级品牌?
    *   哪些品牌覆盖率最高?
    *   哪些品牌蚕食了其他品牌的销量?

*   **店铺行为**:以下是用于简化分析的问题:

W
wizardforcel 已提交
44
    *   百分之八十的店铺占收入的 80%?
W
wizardforcel 已提交
45 46 47 48 49
    *   哪种网点的销售量最高?
    *   什么样的商店主要销售优质产品?

*   **产品增长**:以下是用于简化分析的问题:

W
wizardforcel 已提交
50
    *   就销售而言,哪些是增长最快的品牌?
W
wizardforcel 已提交
51 52 53 54 55
    *   就销量而言,哪些是增长最快的品牌?
    *   哪个品牌的增长趋于平稳?

*   **产品的季节性影响**:以下是用于简化分析的问题:

W
wizardforcel 已提交
56
    *   有几个品牌是季节性的?
W
wizardforcel 已提交
57 58 59 60 61 62 63 64 65
    *   在季节性和非季节性期间,销售方面有何不同?
    *   哪个假期为特定品牌带来了最大的销售额?

这些主题下的前面的问题为查找模式和进行分析提供了一些质量结果的精确指导。

可以通过以下流程图总结探索数据的过程:

![What is data mining?](img/B03450_03_02.jpg)

W
wizardforcel 已提交
66
# 执行分析
W
wizardforcel 已提交
67 68 69 70 71 72 73 74 75 76 77

在执行分析之后,您需要提供一些观察结果。 为此,最常用的媒体是通过 Microsoft PowerPoint 演示文稿。 分析的结果可以是图表或表格形式的构造。 介绍这些结构时,应将某些信息添加到幻灯片中。 这是最常用的模板之一:

![Presenting an analysis](img/3450_03_03.jpg)

以下是上图的不同部分:

*   **问题**:模板的最顶部应描述特定分析试图解决的问题说明。
*   **观察结果**:此处,在垂直栏中列出了来自构建体的观察结果。 有时,可以使用箭头标记或对话框在结构上标记观察结果。
*   **关键点**:在图像底部,您可以描述图表得出的结论。

W
wizardforcel 已提交
78
# 研究泰坦尼克
W
wizardforcel 已提交
79

W
wizardforcel 已提交
80
为了执行数据分析,我们将使用来自 Kaggle 的泰坦尼克数据集。
W
wizardforcel 已提交
81 82 83 84 85 86 87

该数据集易于理解,不需要任何领域的知识即可得出见解。

该数据集包含泰坦尼克号上每位乘客的详细信息,以及他们是否幸存。

以下是字段描述:

W
wizardforcel 已提交
88
| 字段 | 说明 |
W
wizardforcel 已提交
89
| --- | --- |
W
wizardforcel 已提交
90 91
| `survival` | 生存(`0`:否,`1`:是) |
| `pclass` | 旅客舱位(`1`:1,`2`:2,`3`:3) |
W
wizardforcel 已提交
92 93 94 95 96 97 98
| `name` | 旅客姓名 |
| `sex` | 旅客性别 |
| `age` | 乘客年龄 |
| `sibsp` | 兄弟姐妹/配偶人数 |
| `parch` | 父母/子女人数 |
| `ticket` | 票号 |
| `fare` | 旅客票价 |
W
wizardforcel 已提交
99 100
| `cabin` | 舱号 |
| `embarked` | 登船港口(`C`:瑟堡,`Q`:皇后镇,`S`:南安普敦) |
W
wizardforcel 已提交
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175

由于数据非常易于理解,因此我们将生存分析作为可用于数据分析的主要主题。 我们将对这些主题附加问题。

这些是我们将要回答的问题:

*   哪个旅客类别的幸存者人数最多?
*   基于性别,不同阶级之间幸存者的分布是什么?
*   非幸存者在船上有亲属的阶级之间的分布是什么?
*   不同年龄段的存活率是多少?

## 哪个旅客类别的幸存者人数最多?

为了回答这个问题,我们将构建一个简单的条形图,分别显示每个类别中幸存者的数量和幸存者的百分比。 您可以使用以下命令执行此操作:

```py
>>> import pandas as pd
>>> import pylab as plt
>>> import numpy as np

>>> df = pd.read_csv('Data/titanic data.csv')

>>> df['Pclass'].isnull().value_counts()
>>> False    891
>>> dtype: int64

>>> df['Survived'].isnull().value_counts()
>>> False    891
>>> dtype: int64

>>> #Passengers survived in each class
>>> survivors = df.groupby('Pclass')['Survived'].agg(sum)

>>> #Total Passengers in each class
>>> total_passengers = df.groupby('Pclass')['PassengerId'].count()
>>> survivor_percentage = survivors / total_passengers

>>> #Plotting the Total number of survivors
>>> fig = plt.figure()
>>> ax = fig.add_subplot(111)
>>> rect = ax.bar(survivors.index.values.tolist(), survivors, color='blue', width=0.5)
>>> ax.set_ylabel('No. of survivors')
>>> ax.set_title('Total number of survivors based on class')
>>> xTickMarks = survivors.index.values.tolist()
>>> ax.set_xticks(survivors.index.values.tolist())
>>> xtickNames = ax.set_xticklabels(xTickMarks)
>>> plt.setp(xtickNames, fontsize=20)
>>> plt.show()

```

![Which passenger class has the maximum number of survivors?](img/3450_03_04.jpg)

```py
>>> #Plotting the percentage of survivors in each class

>>> fig = plt.figure()
>>> ax = fig.add_subplot(111)

>>> rect = ax.bar(survivor_percentage.index.values.tolist(), survivor_percentage, color='blue', width=0.5)
>>> ax.set_ylabel('Survivor Percentage')
>>> ax.set_title('Percentage of survivors based on class')
>>> xTickMarks = survivors.index.values.tolist()
>>> ax.set_xticks(survivors.index.values.tolist())
>>> xtickNames = ax.set_xticklabels(xTickMarks)
>>> plt.setp(xtickNames, fontsize=20)
>>> plt.show()

```

![Which passenger class has the maximum number of survivors?](img/3450_03_05.jpg)

在前面的代码中,我们对使用的字段上的空值进行了初步检查。 此后,我们计算了每个类别中幸存者的数量和幸存者的百分比。 然后,我们绘制了两个条形图,表示幸存者总数和幸存者百分比。

这些是我们的观察结果:

W
wizardforcel 已提交
176 177
*   幸存者的最大和最小人数分别是一等和三等
*   对于每个舱位的乘客总数,一等舱的幸存者最多,约为 61%
W
wizardforcel 已提交
178
*   对于每个舱位的乘客总数,三等舱的幸存者人数最少,约为 25%
W
wizardforcel 已提交
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254

这是我们的主要收获:

*   显然,倾向于在船只溺水时从头等舱救出来。 它也有最大的幸存者百分比

## 在不同类别中,基于性别的幸存者分布是什么?

为了回答这个问题,我们将使用以下代码绘制并排的条形图,以比较男性和女性相对于他们所处的阶层的存活率和百分比。

```py
>>> #Checking for any null values
>>> df['Sex'].isnull().value_counts()
>>> False    891
>>> dtype: int64

>>> # Male Passengers survived in each class
>>> male_survivors = df[df['Sex'] == 'male'].groupby('Pclass')['Survived'].agg(sum)

>>> #Total Male Passengers in each class
>>> male_total_passengers = df[df['Sex'] == 'male'].groupby('Pclass')['PassengerId'].count()
>>> male_survivor_percentage = male_survivors / male_total_passengers

>>> # Female Passengers survived in each class
>>> female_survivors = df[df['Sex'] == 'female'].groupby('Pclass')['Survived'].agg(sum)

>>> #Total Female Passengers in each class
>>> female_total_passengers = df[df['Sex'] == 'female'].groupby('Pclass')['PassengerId'].count()
>>> female_survivor_percentage = female_survivors / female_total_passengers

>>> #Plotting the total passengers who survived based on Gender
>>> fig = plt.figure()
>>> ax = fig.add_subplot(111)
>>> index = np.arange(male_survivors.count())
>>> bar_width = 0.35
>>> rect1 = ax.bar(index, male_survivors, bar_width, color='blue', label='Men')
>>> rect2 = ax.bar(index + bar_width, female_survivors, bar_width, color='y', label='Women')
>>> ax.set_ylabel('Survivor Numbers')
>>> ax.set_title('Male and Female survivors based on class')
>>> xTickMarks = male_survivors.index.values.tolist()
>>> ax.set_xticks(index + bar_width)
>>> xtickNames = ax.set_xticklabels(xTickMarks)
>>> plt.setp(xtickNames, fontsize=20)
>>> plt.legend()
>>> plt.tight_layout()
>>> plt.show()

```

![What is the distribution of survivors based on gender among the various classes?](img/3450_03_06.jpg)

```py
>>> #Plotting the percentage of passengers who survived based on Gender
>>> fig = plt.figure()
>>> ax = fig.add_subplot(111)
>>> index = np.arange(male_survivor_percentage.count())
>>> bar_width = 0.35
>>> rect1 = ax.bar(index, male_survivor_percentage, bar_width, color='blue', label='Men')
>>> rect2 = ax.bar(index + bar_width, female_survivor_percentage, bar_width, color='y', label='Women')
>>> ax.set_ylabel('Survivor Percentage')
>>> ax.set_title('Percentage Male and Female of survivors based on class')
>>> xTickMarks = male_survivor_percentage.index.values.tolist()
>>> ax.set_xticks(index + bar_width)
>>> xtickNames = ax.set_xticklabels(xTickMarks)
>>> plt.setp(xtickNames, fontsize=20)
>>> plt.legend()
>>> plt.tight_layout()
>>> plt.show()

```

![What is the distribution of survivors based on gender among the various classes?](img/3450_03_07.jpg)

在前面的代码中,计算了男性和女性幸存者的数量,然后绘制了并排的条形图。 此后,计算出中男性和女性幸存者相对于各自类别中男女总数的百分比,然后作图。

这些是我们的观察:

W
wizardforcel 已提交
255
*   所有舱位中大多数幸存者是女性
W
wizardforcel 已提交
256
*   头等舱和二等舱中超过 90% 的女性乘客幸存
W
wizardforcel 已提交
257 258 259 260 261 262
*   在头等舱和三等舱中幸存下来的男性乘客百分比是可比的

此是我们的主要收获:

*   女乘客被优先选择救生艇,而大多数人获救。

W
wizardforcel 已提交
263
## 在船上有家人的各个舱位中,非幸存者的分布是什么?
W
wizardforcel 已提交
264

W
wizardforcel 已提交
265
为了回答这个问题,我们将使用以下代码再次绘制条形图,使用每个类别中每个都有家人的非幸存者的总数以及相对于乘客总数的百分比:
W
wizardforcel 已提交
266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319

```py
>>> #Checking for the null values
>>> df['SibSp'].isnull().value_counts()
>>> False    891
>>> dtype: int64

>>> #Checking for the null values
>>> df['Parch'].isnull().value_counts()
>>> False    891
>>> dtype: int64

>>> #Total number of non-survivors in each class
>>> non_survivors = df[(df['SibSp'] > 0) | (df['Parch'] > 0) & (df['Survived'] == 0)].groupby('Pclass')['Survived'].agg('count')
>>> #Total passengers in each class
>>> total_passengers = df.groupby('Pclass')['PassengerId'].count()
>>> non_survivor_percentage = non_survivors / total_passengers
>>> #Total number of non survivors with family based on class
>>> fig = plt.figure()
>>> ax = fig.add_subplot(111)
>>> rect = ax.bar(non_survivors.index.values.tolist(), non_survivors, color='blue', width=0.5)
>>> ax.set_ylabel('No. of non survivors')
>>> ax.set_title('Total number of non survivors with family based on class')
>>> xTickMarks = non_survivors.index.values.tolist()
>>> ax.set_xticks(non_survivors.index.values.tolist())
>>> xtickNames = ax.set_xticklabels(xTickMarks)
>>> plt.setp(xtickNames, fontsize=20)
>>> plt.show()

```

![What is the distribution of nonsurvivors among the various classes who have family aboard the ship?](img/3450_03_08.jpg)

```py
>>> #Plot of percentage of non survivors with family based on class
>>> fig = plt.figure()
>>> ax = fig.add_subplot(111)
>>> rect = ax.bar(non_survivor_percentage.index.values.tolist(), non_survivor_percentage, color='blue', width=0.5)
>>> ax.set_ylabel('Non Survivor Percentage')
>>> ax.set_title('Percentage of non survivors with family based on class')
>>> xTickMarks = non_survivor_percentage.index.values.tolist()
>>> ax.set_xticks(non_survivor_percentage.index.values.tolist())
>>> xtickNames = ax.set_xticklabels(xTickMarks)
>>> plt.setp(xtickNames, fontsize=20)
>>> plt.show()

```

![What is the distribution of nonsurvivors among the various classes who have family aboard the ship?](img/3450_03_09.jpg)

这里的代码与前面的问题中使用的代码非常相似。 在这里,我们可以获取有一个家庭的非幸存者的数量,然后执行通常的条形图。

这些是我们的观察结果:

W
wizardforcel 已提交
320 321
*   三等舱中有很多非幸存者
*   二等舱中带亲属的非幸存者人数最少
W
wizardforcel 已提交
322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368
*   就乘客总数而言,拥有亲属的头等舱的非幸存者比例最高,而三等舱的非幸存者比例最低。

这是我们的主要收获:

*   尽管三等舱的非幸存者中有亲属的人数最多,但主要是因为乘客没有船上的亲戚,而三等舱中的大多数人中都有亲戚。

## 不同年龄段的存活率是多少?

对于这个问题,我们将使用以下代码绘制饼图,以比较幸存者在数量和百分比方面相对于不同年龄段的比例:

```py
>>> #Checking for null values
>>> df['Age'].isnull().value_counts()
>>> False    714
>>> True     177
>>> dtype: int64

>>> #Defining the age binning interval
>>> age_bin = [0, 18, 25, 40, 60, 100]
>>> #Creating the bins
>>> df['AgeBin'] = pd.cut(df.Age, bins=age_bin)
>>> #Removing the null rows
>>> d_temp = df[np.isfinite(df['Age'])]  # removing all na instances
>>> #Number of survivors based on Age bin
>>> survivors = d_temp.groupby('AgeBin')['Survived'].agg(sum)
>>> #Total passengers in each bin
>>> total_passengers = d_temp.groupby('AgeBin')['Survived'].agg('count')
>>> #Plotting the pie chart of total passengers in each bin
>>> plt.pie(total_passengers, labels=total_passengers.index.values.tolist(),autopct='%1.1f%%', shadow=True, startangle=90)
>>> plt.title('Total Passengers in different age groups')
>>> plt.show()

```

![What was the survival percentage among different age groups?](img/3450_03_10.jpg)

```py
>>> #Plotting the pie chart of percentage passengers in each bin
>>> plt.pie(survivors, labels=survivors.index.values.tolist(),
 autopct='%1.1f%%', shadow=True, startangle=90)
>>> plt.title('Survivors in different age groups')
>>> plt.show()

```

![What was the survival percentage among different age groups?](img/3450_03_11.jpg)

W
wizardforcel 已提交
369
在代码中,我们使用`age_bin`变量定义了箱子,然后添加了一个名为`AgeBin`的列,其中使用`cut`函数填充了箱子值。 此后,我们过滤掉了年龄设置为`null`的所有行。 此后,我们创建了两个饼图:一个用于每个年龄组的乘客总数,另一个用于每个年龄组的幸存者数量。
W
wizardforcel 已提交
370 371 372 373 374 375 376 377 378 379 380

这些是我们的观察:

*   25-40 岁年龄段的乘客人数最多,0-18 岁年龄段的乘客人数第二多
*   在幸存的人中,18-25 岁年龄段的幸存者人数第二高
*   60-100 岁年龄段的幸存者比例较低

这是我们的主要收获:

*   与其他年龄组相比,年龄在 25-40 岁之间的幸存者人数最多,而且年龄较大的人要么不够幸运,要么被年轻人带到救生艇上。

W
wizardforcel 已提交
381
# 总结
W
wizardforcel 已提交
382 383 384 385 386 387 388 389 390

在本章中,我们了解了数据挖掘的含义。 我们了解了领域知识在执行分析以及如何以系统方式进行数据挖掘中的重要性。 我们还学习了如何呈现数据挖掘的结果。 最后,我们举了一个例子,并进行了一些分析以提取有用的信息。

在下一章中,您将学习如何在数据上创建可视化以及在何处应用各种可视化。

### 提示

**下载示例代码**

W
wizardforcel 已提交
391
您可以从[这个页面](http://www.packtpub.com)下载从帐户购买的所有 Packt 图书的示例代码文件。 如果您在其他地方购买了此书,则可以访问[这个页面](http://www.packtpub.com/support)并注册以将文件直接通过电子邮件发送给您。
W
wizardforcel 已提交
392

W
wizardforcel 已提交
393
该代码包中提供的代码同时适用于 IPython 笔记本和 Python 2.7。 在本章中,遵循了 Python 约定。