个性化阅读
专注于IT技术分析

精酿啤酒探索性数据分析:数据剖析

本文概述

编者按:让·尼古拉斯·霍尔德(Jean-Nicholas Hould)是蒙特利尔英特尔安全公司的数据科学家, 他在其博客上教如何入门数据科学。

探索性数据分析(EDA)是一种统计方法, 旨在发现和汇总数据集。在数据科学过程的这一步, 你想探索数据集的结构, 变量及其关系。

在本文中, 你将重点研究探索性数据分析的一个方面:数据概要分析。

数据分析就是通过描述性统计数据汇总数据集。你想使用过多的度量值来更好地理解你的数据集。在分析数据集时, 数据类型, 缺失值, 均值, 中位数和标准偏差只是你需要收集的许多元素中的一部分。数据概要分析的目的是对数据有扎实的了解, 以便以后可以开始以各种方式查询和可视化数据。

知道数据来自何处

在跳入任何EDA之前, 你应该尽可能多地了解要分析的数据的来源。你需要了解如何收集数据以及如何处理数据。数据上是否有任何过去的转换会影响你的分析?

你应该能够在数据集上回答这些问题:

  • 它是如何收集的?
  • 是样品吗?
  • 采样是否正确?
  • 数据集是否以任何方式转换?
  • 数据集中是否存在一些已知问题?

如果你不了解数据的来源, 那么将很难从数据集中得出有意义的结论。你也有犯非常重要的分析错误的风险。

此外, 你应确保数据集以标准化的方式构造。推荐的格式是第三种标准格式, 也称为整洁数据。 “整洁”的数据集具有以下属性:

  • 每个变量组成一列并包含值
  • 每个观察结果排成一行
  • 每种观察单位组成一个表格

尊重这种标准化格式可以加快你的分析速度, 因为它与许多工具和库兼容。

数据剖析

在本文中, 你将使用CraftCans网站上的Craft Beers数据集。该数据集仅包含来自美国啤酒厂的罐装啤酒的数据。网站上尚不清楚该数据集是否报告了在美国酿造的每种罐装啤酒。为了安全起见, 你将认为此数据集是一个可能包含偏差的样本。

这是你将使用的数据集的结构:

啤酒:

  • ID:啤酒的唯一标识符。
  • 名称:啤酒的名称。
  • ABV:按啤酒量计算的酒精含量。
  • IBU:啤酒的国际苦味股。
  • 风格:啤酒的风格。
  • 盎司:啤酒。

啤酒厂:

  • ID:啤酒厂的唯一标识符。
  • 名称:啤酒厂的名称。
  • 城市:啤酒厂所在的城市。
  • 州:啤酒厂所在的州。

数据类型

第一步是了解数据集的组成。

你要处理什么变量?

通常, 你可以将数据拟合为以下类别之一:

  • 数值型
  • 分类的
  • 文本
  • 日期

首先, 你将使用pandas的from_csv函数导入可在此存储库中找到的数据集。你还将啤酒和啤酒厂的数据集结合在一起, 以方便进行后续分析。


import pandas as pd

beers = pd.DataFrame.from_csv("https://raw.githubusercontent.com/nickhould/craft-beers-dataset/master/data/craftcans_beers.csv")
breweries = pd.DataFrame.from_csv("https://raw.githubusercontent.com/nickhould/craft-beers-dataset/master/data/craftcans_breweries.csv")

beers_and_breweries = pd.merge(beers, breweries, how='inner', left_on="brewery_id", right_on="id", sort=True, suffixes=('_beer', '_brewery'))

使用pandas库, 你可以运行dtypes函数列出每一列及其数据类型。


beers.dtypes

得到以下结果:


abv           float64
ibu           float64
id              int64
name           object
style          object
brewery_id      int64
ounces        float64
dtype: object

如上所见, 该功能无法对不同的数据类型进行干净的分组。我们不希望将各种数值数据类型(float64和int64)分组为一个类别。另外, 有些列被列为对象, 这不是很有帮助。

要解决此问题, 你可以构建自己的函数, 该函数将确定DataFrame中每一列的类别。


def get_var_category(series):
    unique_count = series.nunique(dropna=False)
    total_count = len(series)
    if pd.api.types.is_numeric_dtype(series):
        return 'Numerical'
    elif pd.api.types.is_datetime64_dtype(series):
        return 'Date'
    elif unique_count==total_count:
        return 'Text (Unique)'
    else:
        return 'Categorical'

def print_categories(df):
    for column_name in df.columns:
        print(column_name, ": ", get_var_category(df[column_name]))

啤酒变量


print_categories(beers)

上面的命令为你提供以下结果:


abv :  Numerical
ibu :  Numerical
id :  Numerical
name :  Categorical
style :  Categorical
brewery_id :  Numerical
ounces :  Numerical

啤酒厂变量


print_categories(breweries)

得到以下结果:


name :  Categorical
city :  Categorical
state :  Categorical
id :  Numerical

有了这些信息, 你就可以更好地了解我们的数据集。你知道你只在处理分类和数字数据。数值变量可用于提取许多不同的度量值, 例如平均值, 标准偏差等。分类变量通常是对数据进行分段和分组的有趣方式。例如, 你可能想了解IBU在各种啤酒类型之间的差异。

描述性统计

在本部分中, 你将遍历各种描述性统计数据, 这些统计数据可用于更好地理解我们的数据。你会注意到, 单独进行这些测量并不是很有帮助。这些不同的度量值的组合是你可以获取最大价值的地方。

你将重点关注IBU变量, 因为它是一个数字变量。与分类变量相比, 这种类型的变量提供了更广泛的测量范围。你仍然可以对分类变量进行测量, 但会受到更多限制。

长度

len函数计算系列中观测值的数量。该函数将计算所有观察值, 无论值是否缺失或为空。


length = len(beers["ibu"])
print(length)

在本系列中, 我们总共有2410个观测值。

计数

计数功能将返回系列中非NA /非空观测值的数量。


count = beers["ibu"].count()
print(count)

如你所见, 系列中有1405个非空观测值。

缺失值

使用”长度”和”计数”, 我们现在能够计算缺失值的数量。缺失值的数量是”长度”和”计数”之间的差。


number_of_missing_values = length - count
pct_of_missing_values = float(number_of_missing_values / length)
pct_of_missing_values = "{0:.1f}%".format(pct_of_missing_values*100)
print(pct_of_missing_values)

要以百分比形式输出缺失值, 只需将缺失值的数量除以观测值的总数即长度即可。浮点函数用于确保在除法中捕获小数。格式化功能用于将数字很好地格式化为百分比。

在这种情况下, 你将丢失几乎42%的IBU变量。这对你来说很重要, 因为它会影响你的分析。大多数描述性统计信息将忽略那些缺失的值, 这肯定会引起偏差。

最小值/最大值

使用系列上的min和max函数可以轻松获得数据集的最小值和最大值。


print("Minimum value: ", beers["ibu"].min())
print("Maximum value: ", beers["ibu"].max())

最小值/最大值有助于了解变量中的值范围。在这种情况下, IBU的范围是4到138。

模式

模式是数据集中最频繁的值。可以使用系列的模式功能获得。


print(beers["ibu"].mode())

在正态分布中, 众数等于均值和中位数。

在这种情况下, IBU变量的模式为20。这是数据集中最常见的IBU。

意思

均值是集中趋势的度量。它代表值的总和除以非缺失观测值的数量。

可以通过Series上的均值函数获得。


mean = beers["ibu"].mean()

均值容易受到异常值的影响。一些极值可以极大地改变平均值, 将其向上或向下拖动。

中位数

中位数也是衡量集中趋势的指标。它是恰好在数值的有序列表中间的数字。


median = beers["ibu"].median()

在偏态分布的情况下, 中位数比集中度更好地衡量了集中趋势。

对于IBU分布, 均值和中位数处于相同数量级。

标准偏差

标准偏差是色散的量度。高标准偏差表示数据点分布在很大的值范围内。标准偏差以与值相同的单位表示。


standarddev = beers["ibu"].std()

在这种情况下, 标准偏差为〜26。 25.954065911259324是准确的如果IBU的分布是正态分布, 你会知道〜68%的观测值在平均值的一个标准偏差内。

分位数统计

分位数是切分点, 它们将分布拆分成相等的大小。许多分位数都有自己的名称。如果将分布分为四个相等的组, 则创建的分位数称为四分位数。你可以使用系列上的分位数功能轻松创建分位数。你可以将具有不同分位数的数组传递给该函数以进行计算。在以下情况下, 我们要将分布分为四个相等的组。


quantile = beers["ibu"].quantile([.25, .5, .75])
0.25 21.0
0.50 35.0
0.75 64.0
姓名:妈妈, dtype:float64

如上所示, 50%的分位数等于中位数。它是将数据集分成两半的值。你还可以注意到, 有75%的观测值等于或低于64 IBU。此外, 分布的50%位于21和64 IBU之间。请务必注意, 这些指标未考虑缺失值。

分布图

可视化在探索性数据分析中非常有用。在本文中, 我们将不讨论主题可视化。但是, 我们不能不谈数据配置, 而不必提及频率分布图的重要性。它是最简单但功能最强大的可视化之一。它展示了我们数据集中每个值的频率。

为了创建这种可视化效果, 我们使用了带展示功能的seaborn库。该函数期望aSeries`不会缺少任何值。


import seaborn as sns
sns.set(color_codes=True)
sns.set_palette(sns.color_palette("muted"))

sns.distplot(beers["ibu"].dropna());
精酿啤酒探索性数据分析:数据剖析1

在此分布图中, 你可以清楚地看到一些我们先前计算的值。最小值接近0 IBU, 最大值接近140 IBU。你清楚地看到最频繁的值接近20 IBU。除此信息外, 我们现在看到接近60 IBU的峰值。

为什么在此分布中有两个峰值?

有什么可以解释的?这是我们在探索性数据分析的第二阶段中可以探索的一个方面。

相关性

关联是发现数值变量之间关系的好方法。有多种计算相关性的方法。皮尔逊相关系数是一种广泛使用的方法, 用于测量两个变量之间的线性相关性。相关系数的范围是-1至1。相关系数1是总正相关, 相关系数-1是总负相关, 而相关系数0是非线性相关。我们可以使用Series上的corr函数执行该计算。默认情况下, 此函数将使用Pearson相关系数计算。通过此功能可以使用不同的计算方法。


beers[["abv", "ibu", "ounces"]].corr()
抗体 妈妈 盎司
抗体 1 0.670621 0.172529
妈妈 0.670621 1 0.054691
盎司 0.172529 0.054691 1

如上所示, IBU与自身之间的相关性为1。显然, 数值变量与自身之间具有完美的相关性。更有趣的是, 你可以看到ABV和IBU的相关性等于0.670621。虽然这不是总的正相关, 但仍然是高度相关。这是一个有趣的方面, 我们可以进一步探索。

关于非数值变量的一些注意事项

先前提取的度量标准仅适用于数值。如果你正在处理其他类型的数据(例如分类数据), 则仍可以收集一些有趣的度量。你可以计算数据集中每个值的频率。

DataFrame有一个名为describe的函数, 用于汇总数据集。如果你的DataFrame仅具有分类或文本值, 则摘要将专门针对此类数据进行调整。


beers[["name", "style"]].describe()
名称 样式
计数 2410 2405
独特 2305 99
最佳 直达跳车 美国IPA
频率 12 424

分析库

如上所述, 收集描述性统计信息可能是一个乏味的过程。很高兴地发现, 有一些可以为你执行所有数据处理的库。他们输出的数据非常清晰。熊猫分析是其中之一。该库提供了数据集的现成统计分析。由于我们使用的数据集是整齐和标准化的, 因此我们可以立即在我们的数据集上使用该库。


import pandas_profiling 

pandas_profiling.ProfileReport(beers_and_breweries)

更多问题

通常, 一旦对数据集进行了概要分析, 就会比最初提出更多的问题。很好, 因为这些新问题将助你进行探索性数据分析。

在进行此概要分析时, 我们收集了以下几个问题:

  • 41.7%的IBU值丢失。这是为什么?这如何影响我们的分析?
  • IBU分布有两个高峰。是什么解释了这一点?
  • 是什么解释了IBU和ABV之间的关系?啤酒风格在这种关联中有什么影响?
  • 地理区域之间的IBU, ABV或样式是否有差异?东海岸vs西海岸呢?

数据分析不是线性过程。在对数据集进行过滤和细分时, 你将回到数据集并收集有关数据子组的描述性统计信息。

下一步

在本文中, 你已经了解了如何分析数据集。现在, 你知道如何将变量归因于特定的数据类型组。你还计算了数据集上的不同描述统计量, 并且了解了如何解释这些度量。最后, 你已经看到有一些库可以帮助你进行处理以分析数据集。更重要的是, 你产生了比以往更多的问题来推动你的探索性数据分析。

赞(0)
未经允许不得转载:srcmini » 精酿啤酒探索性数据分析:数据剖析

评论 抢沙发

评论前必须登录!