TowardsDataScience-博客中文翻译-2022-二-

TowardsDataScience 博客中文翻译 2022(二)

原文:TowardsDataScience

协议:CC BY-NC-SA 4.0

使用三种常用工具进行三种常用数据分析操作

原文:https://towardsdatascience.com/3-common-data-analysis-operations-with-3-common-tools-9288ce61a40f

熊猫,数据表和 SQL

杰克·亨特在 Unsplash 上的照片

我们分析数据以提取见解,找到有价值的信息,或者发现仅仅通过浏览看不见的东西。数据分析过程的复杂程度取决于数据的特征和结构。

但是,有一些基本操作是经常做的。这些可以被认为是数据分析的基础:

  • 分组
  • 过滤
  • 整理

在本文中,我们将学习如何使用 3 种最常用的数据分析工具来完成这些操作:

  • 熊猫换蟒蛇
  • R 的数据表
  • 结构化查询语言

我们的目标不是比较这些工具,也不是将一个工具归类为优于其他工具。在您的数据科学职业生涯中,您可能需要使用它们中的任何一个或全部,因为这些工具被许多公司使用。

像往常一样,我们将通过做例子来学习,所以我们需要一个数据集来处理。我用模拟数据准备了一个销售数据集。你可以从我的 GitHub 页面上的数据集库中下载。叫做“销售 _ 数据 _ 与 _ 商店”。以下是该数据集的前 5 行:

sales_data_with_stores(作者图片)

分组

在探索性数据分析中,通常根据一列或多列中的不同值或类别对数据点(即表格数据中的行)进行分组。

(图片由作者提供)

通过分组可以计算出一些东西:

  • 各品牌平均汽车价格
  • 每月平均收入
  • 一周中销售量最高的一天

回到我们的数据集,我们可以找到每个商店上周的平均销售额,如下所示:

熊猫

我们使用 groupby 和 mean 函数。首先,按照商店列对行进行分组。然后,我们选择要聚合的列,并应用相关的函数。

import pandas as pddf = pd.read_csv("sales_data_with_stores.csv")df.groupby("store")["last_week_sales"].mean()# output
store
Daisy     66.544681
Rose      64.520000
Violet    99.206061
Name: last_week_sales, dtype: float64

数据表

数据表包的语法比熊猫简单一点。要执行的操作用逗号分隔在方括号中,如下所示:

数据表语法结构(图片由作者提供)

library(data.table)dt <- fread("sales_data_with_stores.csv")dt[, mean(last_week_sales), store]# output
    store       V1
1: Violet 99.20606
2:   Rose 64.52000
3:  Daisy 66.54468

SQL

假设我们有一个名为 sales 的表,其中包含我们的数据集中的数据。我们使用 select 和 group by 语句如下:

SELECT
   store,
   AVG(last_week_sales)
FROM sales
GROUP BY store

输出将与其他示例中的相同。

在所有的例子中,聚集的列没有一个自解释的列名,这不是理想的情况,尤其是在与其他人一起工作时。让我们再做一系列例子,找出每个商店的平均产品价格和总库存数量。我们还将为聚合列分配名称。

熊猫

我们将使用 agg 函数。要聚合的列和聚合函数写在元组中,如下所示:

df.groupby("store").agg(

    avg_price = ("price", "mean"),
    total_stock = ("stock_qty", "sum"))# output

(图片由作者提供)

数据表

语法的结构是相同的,但是有一些小的改动。聚合写在前面带点的括号内。

dt[, 
   .(
     avg_price = mean(price),
     total_stock = sum(stock_qty)
     ),
   store
   ]

SQL

它与另一个 SQL 示例非常相似。我们只需要添加列名。

SELECT
   store,
   AVG(price) AS avg_price,
   SUM(stock_qty) AS total_stock
FROM sales
GROUP BY store

过滤

过滤是数据分析中另一种常见的操作。大多数工具都提供了基于字符串、数字和日期值过滤原始数据的函数和方法。

我们将做一个包含字符串和数字过滤器的例子。让我们选择数据点(即行),其中:

  • 商店是紫色的
  • 产品组是 PG1、PG3 或 PG5
  • 上个月销售额超过 100 英镑

熊猫

我们把过滤条件写在方括号内。在有多个条件的情况下,每个条件都写在括号内,并且条件用适当的逻辑运算符组合(例如& for end,| for or logic)。

df[
    (df["store"] == "Violet") &
    (df["product_group"].isin(["PG1","PG3","PG5"])) & 
    (df["last_month_sales"] > 100)
]

这段代码的输出是一个数据帧,其中的行符合给定的一组条件。

数据表

逻辑也差不多。在这种情况下,我们使用 and 运算符组合多个条件。

dt[
    store == "Violet" &
    product_group %in% c("PG1","PG3", "PG5") &
    last_month_sales > 100
  ]

SQL

条件在 where 语句中指定。在这种情况下,我们使用 and 关键字来组合多个条件。

SELECT *
FROM sales
WHERE store = "Violet" AND
      product_group in ("PG1", "PG3", "PG5") AND
      last_month_sales > 100

整理

我们有时需要根据一列或多列中的值对行进行排序。例如,我们可能希望根据价格对产品进行降序排序。

熊猫

sort_values 函数用于此任务。我们只需要编写将用于排序的列。默认情况下,Pandas 按升序排序,但是可以使用 ascending 参数改变这种行为。

df_sorted = df.sort_values(by="price", ascending=False)

数据表

使用了 order 函数。要从升序改为降序,我们只需要在列名前面加一个减号。

dt_sorted <- dt[order(-price)]

SQL

order by 语句在 SQL 中用于对行进行排序。像 data.table 和 Pandas 一样,这些行按升序排序。我们可以使用 desc 关键字进行降序排序。

SELECT *
FROM sales
ORDER BY price DESC

我们已经学习了如何使用数据科学生态系统中的 3 种常用工具进行 3 种基本的数据分析操作。我们已经讨论了简单的情况,但是所使用的函数和方法也能够完成更复杂的任务。在学习细节之前,最好先掌握基本知识。

你可以成为 媒介会员 解锁我的全部写作权限,外加其余媒介。如果你已经是了,别忘了订阅https://sonery.medium.com/subscribe如果你想在我发表新文章时收到电子邮件。

感谢您的阅读。如果您有任何反馈,请告诉我。

机器学习中的 3 个常见建模错误

原文:https://towardsdatascience.com/3-common-modeling-mistakes-in-machine-learning-4551829a8fd1

探索可能妨碍模型性能的简单缺陷

Unsplash 上由 Austin Distel 拍摄的照片

建模可以说是机器学习任务中最有趣的部分。

在这里,您可以使用经过精心处理和转换的数据来构建一个可以生成预测的模型。

尽管与数据预处理和特征工程相比,模型构建所需的时间更少,但很容易做出看似无害的决定,从而导致模型性能不佳。

在这里,我们探讨一些常见的错误,这些错误不利于用户训练和调整一个可靠的模型。

典型的例子

与数据预处理和特征工程相比,建模阶段相对容易执行。

例如,让我们使用 Scikit 学习包中的一个玩具数据集。

假设我们正在寻找创建一个梯度推进分类器,可以用这些数据生成预测。用于定型和调整模型的代码可能如下所示:

仅通过这个片段,我们就可以:

  • 具有不同超参数值的测试模型
  • 实施交叉验证分割策略以避免过度拟合
  • 使用性能最佳的模型生成预测

用这么少的代码做了这么多的工作。这就是 Scikit 学习包的强大之处。

从表面上看,这种方法似乎完美无缺,但是存在一些缺陷,可能会影响模型的性能。让我们来看看机器学习任务中常见的几个错误。

错误 1:没有使用基线模型

在建模阶段,许多人急于直接使用会带来更多复杂性的算法。毕竟,复杂性通常与有效性联系在一起。

可惜,多不一定好。复杂模型产生与简单算法相同的性能(如果不是更差的话)是很常见的。

有可能感兴趣的算法的基本假设不适合数据。也许用来训练模型的数据集一开始就没有太多的预测能力。

为了说明这种情况,能够将调优模型的结果放在上下文中是很重要的。用户可以通过建立基线模型来恰当地评估他们复杂模型的性能。

基线模型是一个简单的模型,作为一个复杂的模型建立方法是否真正获益的指示器。

总的来说,在准备好数据后立即构建复杂的模型可能很诱人,但是您构建的第一个模型应该始终是基线模型。

要快速了解基线模型,请查看以下文章:

错误 2:使用小范围的超参数

超参数调优的一个常见缺陷是只探索小范围的超参数值。

超参数调整应使用户能够确定产生最佳结果的超参数值。然而,只有当被测试的值的范围足够大时,这个过程才能达到它的目的。

如果值甚至不在搜索空间中,调优过程如何识别最佳超参数值?

在前面的例子中,learning_rate超参数的搜索空间仅包括 0.1 和 10 之间的 3 个值。如果最佳值超出此范围,则在调整过程中不会被检测到。

对于许多机器学习算法,模型性能严重依赖于某些超参数。因此,用小范围的值来调优模型是不可取的。

用户可以选择使用更小范围的超参数值,因为更大数量的值将需要更多的计算,并将导致更长的运行时间。

对于这种情况,最好不要使用较小范围的值,而是切换到需要较少时间和计算量的超参数调优方法。

网格搜索是一种有效的超参数调整方法,但也有其他合适的替代方法。

如果您有兴趣探索超参数调整的其他替代方法,请查看以下文章:

错误 3:使用错误的评估标准

看到一个评分很高的模特总是很开心。不幸的是,基于错误的评估度量训练的模型是无用的。

用户在使用默认值scoring参数的同时执行网格搜索并不罕见。网格搜索中默认的评分标准是准确性,这在很多情况下并不理想。

例如,对于不平衡的数据集,精度度量是一个很差的评估度量。精确度、召回率或 f1 值可能更合适。

也就是说,即使像 f-1 分数这样的稳健指标也可能不理想。f-1 分数同等地权衡精确度和召回率。然而,在许多应用中,假阴性可能比假阳性更有害,反之亦然。

在这种情况下,用户可以根据业务案例定制自己的评估指标。这样,用户将能够调整他们的模型,以实现所需类型的性能。

纠正以前的错误

这里有一个用代码解决这些错误的简单例子。

首先,我们可以创建一个基线模型,它将被用来衡量训练模型的性能。具有默认参数的简单 K-最近邻模型就足够了。

现在我们可以继续使用 GridSearchCV 对象来训练和调整梯度增强分类器。这一次,我们将考虑更大范围的learning_rate超参数值。

此外,不使用准确性作为评估度量,让我们假设我们想要考虑精确度和召回率,同时对召回率给予更大的权重(即,更多地惩罚假阴性)。

一个解决方案是在 Scikit Learn 中用make_scorer包装器创建一个自定义指标,这使我们能够在网格搜索中使用 f-beta 分数(beta=2)作为评估指标。

利用改进的超参数搜索空间和评估度量,我们现在可以执行网格搜索并调整梯度推进分类器。

结论

UnsplashPrateek Katyal 拍摄的照片

机器学习任务的建模阶段比预处理和特征工程阶段耗时少得多,但在此阶段仍然容易出错,这可能会妨碍整体模型性能。

谢天谢地,Python 强大的机器学习框架完成了大部分繁重的工作。只要您将优化模型的结果与基线联系起来,考虑各种超参数值,并使用适合应用的评估指标,您的模型就更有可能产生令人满意的结果。

我祝你在数据科学的努力中好运!

衡量 NLP 模型中偏差的 3 种常用策略(2022)

原文:https://towardsdatascience.com/3-common-strategies-to-measure-bias-in-nlp-models-2022-b948a671d257

负责任人工智能语言模型中偏差的量化策略

在过去的几年里,构建(公平、可审计和透明)机器学习的话题已经从一个边缘话题发展成为主导会议现场的话题。

对于自然语言处理来说尤其如此,有偏见的 ML 的影响非常明显。

其中一个广受欢迎的话题是测量偏差。在数据科学中,偏差是一个被过度使用的术语,但是在本文中,我们将它定义为:

偏差:产生一种伤害的偏斜

虽然这个定义很简单,但实际上测量和量化这种危害是极其困难的。尽管许多人以各种各样的观点对这一不断发展的领域做出了贡献,但有一个主张几乎得到了普遍认同:

Bia 没有单一的衡量标准。您必须根据您的型号和应用仔细选择您的偏差标准。

即使这样,你也必须深思熟虑,意识到你的测量究竟是什么……测量。

语言模型非常有用,但如果评估不当,可能会产生意想不到的后果

希望在这篇文章结束时,你会对你的模型需要什么样的方法来减少算法偏差有一个很好的理解。🚀

本文所有图片和图表,除特别注明外,均由作者创作。

有相当多的方法可以测量语言模型中的偏差。我已经强调了我认为每个人都应该知道的几个关键方法。

以下是 NLP 模型的常见应用,以及与之相关的偏差测量。

方法 1:精选数据集

测量偏差的常用方法是利用数据集设计来检测特定问题的偏差。

这些数据集的目标是针对模型可能具有的潜在偏差,并由选择来解析这些偏差的示例组成。这些数据集是由研究人员手工制作的,虽然肯定无法扩展到所有模型和所有应用程序(稍后将详细介绍),但如果这些数据集对您的应用程序非常有用。

让我们来看看由曹等人在中策划的可能歧义代词(MAP)数据集。

该数据集的目标是:

群体注释和现有共指消解系统中的询问偏差

(共指消解, 顺便说一下, 是确定一个文本中哪些表达式指代同一个实体的过程;前任。短语“California”、“CA”、“Cali”和“黄金之州”都指同一个实体——美国加利福尼亚州。)

我们可以通过编写一个名为pull_map.py的文件从 github repo 中提取 csv 来查看地图数据集:

import requestscsv_url = "https://raw.githubusercontent.com/TristaCao/into_inclusivecoref/mast$req = requests.get(csv_url)
url_content = req.content
csv_file = open('map.csv', 'wb')csv_file.write(url_content)
csv_file.close()

地图数据集的屏幕截图。知识共享许可下的数据

full-text是一系列的句子,通常很长,有点令人困惑,引用了几个实体。这里有一个重点:

共指消解模型的目标是确定代词“她”(用橙色突出显示)是否指…

  1. 萨尔曼(A)

2.萨尔曼或法拉·可汗(甲或乙)

3.法拉·可汗(B)

4.既不是萨尔曼也不是法拉·可汗

以上数字对应 *Answer* 中的数值

使用这个精选数据集的目的不仅是这些例子通常很难,它们还提供了不同代词、性别和身份的更多表示。看看代词,我们可以看到代词的范围很广,包括:

作者制作的图表

您可以使用代码片段来验证上面的图表:

import matplotlib.pyplot as pltmap_pd.groupby("Pronoun").count()[['id']].sort_values('id').plot.barh(figsize=(15, 10))plt.title("Number of Examples with certain pronouns")
plt.xlabel("Num. of Examples")plt.gca().spines['top'].set_visible(False)
plt.gca().spines['right'].set_visible(False)

这个数据集的一个很好的方面是,你可以看到人类是如何解释这些句子的,从而产生有趣的见解以及比挑战性问题 100%准确更现实的黄金标准。

其他值得注意的策划数据集:

  • wino bias&wino gender创建 Winograd 模式,研究共指消解模型中的性别刻板印象
  • 性别模糊代词(GAP) 数据集,包含具有模糊代词-名词对的维基百科传记,用于通过模型准确性检测性别偏见。
  • Wiki-GenderBias ,通过比较与配偶、职业、出生率或出生地(类似于 GAP)配对的男性/女性实体提取之间的模型准确性来测试性别偏见
  • CrowS-PairsStereoSet 是成对句子的众包数据集,其中一个句子比另一个句子在特定属性上更常规。适用于任何屏蔽语言模型,如 BERT,与应用程序无关。偏差由模型偏好通过丢失单词的概率来确定
  • WinoMT 英语数据集,评估性别共指关联的刻板印象和非刻板印象职业的翻译。对机器翻译有用

方法 2:子群间的准确性

也称为“校准”,测量偏差的一种常见方法是探索您的模型水平跨亚组的误差度量,例如分析您的模型跨种族亚组的 AUC 分数。

这通常是各种应用程序的首选方法,从毒性检测到问答,再到自动完成生成。

对于如何做到这一点的虚拟示例,让我们看一个任意数据集,其中有 age_range、模型的预测和组真实标签:

作者制作的数据

如果我们 只是检查整个模型 的准确性,我们会得到大约 85%的相当不错的准确性:

def calculate_accuracy(data):
    return 100*len(data[data.model_pred==data.label])/len(data)print(f"Model Accuracy: {calculate_accuracy(x)}%")## Model Accuracy: 84.8%

这甚至可能足够高,这取决于将该模型交付生产的应用程序。乍看之下,肯定足够高,可以为将来的迭代构建。

但是,当我们检查不同年龄组时,我们可以看到一些突出的问题

def calculate_accuracy(data):
    return 100*len(data[data.model_pred==data.label])/len(data)def calculate_subgroup_accuracy(data):
    for group in data.age_range.unique():
        g = data[data.age_range==group]
        print(f"{group}: {calculate_accuracy(g):.2f}%")

print(f"Model Accuracy: {calculate_accuracy(x)}%")
print()
calculate_subgroup_accuracy(x)## Model Accuracy: 84.8%
## <18: 97.41%
## 18-35: 98.71%
## 35-55: 97.06%
## 55+: 48.67%

我们可以看到,我们的模型在预测 55 岁以下的用户方面非常出色,但在预测 55 岁以上的用户方面却非常糟糕。事实上,比偶然更糟。

这是将我们的模型预测按亚组分解的值。由于这是一个后处理分析,您也不需要在模型本身中包含这些敏感特性,这是一个巨大的优势。

虽然最好的选择是拥有明确的子组特征,如种族和性别,但您也可以通过对数据集运行分类算法来产生子组,并在这些组内比较模型指标。它不会显示基于显式要素/子组的偏差,但肯定会确保您的模型在数据集中的隐式段之间是公平的

方法 3:扰动和反事实

扰动输入并观察模型的输出是探索模型中潜在偏差的好方法。

这是用于评估与情感分析和文本生成相关的模型的最常见的方法,但对于任何 NLP 模型来说都非常有用。

虽然前两个偏差探索全局(模型级)偏差伪影在你的模型中,但是这个方法对于发现局部(预测级)偏差伪影是有效的。

最直接的方法是有计划地删除句子中的每个单词,并将其输入到你的模型中。

假设我们想分析为什么我们的模型给出这样的句子:

我真的爱我的好医生

积极情绪得分。更准确地说,我们希望确保我们的模型不会键入非肯定的词语,如“我的”或“医生”

假设我们有一个经过训练的情感分析模型,我们可以这样做:

example = "I really love my good doctor"
prediction = model.prediction(example)words = example.split(" ")
word_impacts = []
for i in range(len(words)):
    s = ""
    for j in range(len(words)):
        if i == j:
            continue
        s += words[j] +" "

    val = model.predict(s)
    word_impacts.append(prediction-val)

其中word_impacts列出了句子中每个单词对最终预测的单独影响。

表现良好的模型会产生word_impact分数,例如:

而表现不佳的模型可能会产生word_impact分数,如:

我们可以从第一个例子中看到,它不仅得到了正确的答案,而且将大部分权重放在了重要的词上——“爱”和“好”。值得注意的是,它没有在限定词“真的”上放置太多的权重,对于这个例子来说,这不是一个大问题,但是是一个需要注意的重要工件… 即使是高性能的模型也有工件和问题!

第二个例子表现很差,显然不知道该看句子中的什么,在所有单词中最强调“my”。虽然我们之前知道这个模型不好,但我们可以看到它仍然在形容词等基本语言概念上苦苦挣扎——回到制图板!

结论

这是三种探索 NLP 模型偏差的方法,我的团队在部署之前经常使用这三种方法进行探索和迭代。这些方法是:

  1. 使用手工制作的数据集,旨在挑战您的模型和表面潜在偏差。
  2. 分析子群之间的模型精度并验证每个子群的精度具有可比性。
  3. 干扰您的输入查看您的模型使用哪些单词/短语进行预测。

适合您的方法将完全取决于您的模型类型和应用程序。好消息是,大多数常见的应用程序和模型都可以利用其中的一些方法。

希望这是一篇有用的信息丰富的文章!🚀

相关消息来源

基于 Plotly 和 K-Means 的 NBA 球员三维聚类

原文:https://towardsdatascience.com/3-d-clustering-of-nba-players-with-plotly-and-k-means-6ee7644f2a6c

如何建立一个关注可解释性的聚类模型

肯尼·埃利亚松在 Unsplash 上的照片

聚类是一种无监督学习的机器学习技术,用于识别给定数据集中的相似数据点组。理论上,这些组将具有相同的属性,有助于数据的可解释性和模式识别。现实生活中的集群应用包括客户和产品细分、设施位置优化、推荐系统、医学成像、体育侦察等等。

无监督学习中最常用的算法之一是 K-Means,我们将在本文中使用它。K-Means 是一种简单的算法,它从随机选择的质心开始对相似的数据点进行分组,并对它们进行迭代以优化质心的位置。当质心稳定或达到最大迭代次数时,算法停止迭代。

迭代过程中优化位置的质心示例。来源:https://commons . wikimedia . org/wiki/File:K-means _ convergence . gif

虽然它可以应用于高维数据,但聚类的一种常见形式是选取数据的两个变量,应用聚类算法(在我们的情况下是 K-means ),然后用区分聚类的颜色绘制散点图。下图显示了一个具有三个集群的应用程序:

k-表示散点图中显示的 2 个特征的聚类。来源:作者

有了标记的组,就可以从那里做出业务决策。想象一下,一家在线零售商的客户最近在婴儿服装和尿布上花了钱。我们可以将该客户标记为对婴儿用品感兴趣,并使用推荐系统来提供婴儿用品组的其他人购买的产品,如玩具或摇篮。

或者想象一下,你是一个篮球队的球探,负责根据球员的数据来确定一个青年联盟的最佳人才。你可以定义最重要的统计数据和球员集群。之后,应该有可能识别出你应该仔细观察的一组优秀球员和那些不会被进一步评估的球员。

图形库 Plotly 有一个散点三维方法,允许我们在数据可视化中超越 2D 障碍,并提高 K-Means 聚类的可解释性。由于数据是以三维散点图绘制的,因此可以直观地将聚类与要素相关联,并识别数据点的共同属性,这些属性导致算法形成这些组。以下是一个包含六个集群的示例:

使用 Plotly 的三维 K 均值聚类示例。来源:作者

在本文中,我们将演示如何构建如上所示的交互式 3D 聚类可视化。为此,我选择了 Kaggle (CC BY-SA 4.0 许可证)的篮球数据集,因为它应该可以使用 4000 多名前任和现任国家篮球协会(NBA)球员的统计数据来说明篮球运动员的例子。此外,我们还将探讨一种定义理想集群数量的方法。最后,随着交互式可视化的建立,我们将讨论每个组的属性,增加模型的可解释性。

所以让我们开始加载数据。我们的数据集存储在数据库中,因此我们必须使用 SQLite 创建到数据库的连接,并定义其路径。然后,在 SQL 中,我们必须编写查询来提取所需的数据,或者在我们的例子中,提取存储在 Player_Attributes 表中的球员统计数据。因为我们还不知道哪些特性将用于聚类,所以用*提取整个表是个好主意。使用 pandas read_sql 方法,可以将 sql 查询的输出存储在 pandas 数据框中,我们可以研究该数据框并为聚类选择最佳特征。

将 Player_Attributes 表存储在 Pandas 数据帧中。

下面是我们构建三维聚类的可用功能:

数据集的列。来源:作者

看看这些特征,大部分都是分类的,但我们在“PTS”、“AST”和“REB”中有我们想要的统计数据,它们是场均得分(PPG)、助攻** (APG)和篮板 (RPG)的缩写,这是一个篮球运动员最常见的三个统计数据。因此,在本文中,我们将用 PPG、RPG 和 APG 这三个维度来构建 4000 多名过去和现在的 NBA 球员的三维聚类。**

当一名球员击球时,他就得了一分。如果一名球员在三分线后投篮,他可以一杆得三分,如果他在三分线内投篮,他可以得两分,如果他在罚球线得分,只有在犯规后才能得分。当一名球员在投篮不中后抢到球时,就是抢篮板球。投篮可以是自己的,也可以是队友的。当一名球员将球传给另一名队友,后者立即得分时,就会出现助攻。

现在我们必须回答这样一个问题:对于超过 4000 个玩家,我们应该有多少个集群来进行优化分组?逻辑告诉我们,聚类越多,模型解释的变异就越多。这是真的,除了在某个点之后,模型会过度拟合。一般来说,必须选择分类的数量,以便添加另一个分类不会给数据建模增加太多。我们的目标是找到最佳点,有一种称为剪影方法的启发式方法可以帮助我们,并且 Yellowbrick lib 有一个功能可以实现它。下面是使用 K-Means 和三个特性的代码:

轮廓分数是所使用的度量,它是计算点被分组到聚类中的程度的度量,从-1 到 1。1 是最佳分组,而-1 是可能的最差分组。轮廓得分的公式是 S = (b — a)/max(a,b) 其中b”是聚类的质心之间的平均距离,而“ a ”是每个聚类内的数据点之间的平均距离。剧情是这样的:

来源:作者。

得分最高的是两个聚类,但是不仅仅是使用得分最高的聚类的数量,还需要考虑数据的上下文。在本文中,我们将根据 4000 多名 NBA 球员的数据对他们进行聚类。如果我们只将数据集分成两个集群,这个模型就没有太多的可解释性,因为它只是高于平均水平的玩家集群和低于平均水平的玩家集群。因此,我们需要一个更高的聚类数,以便稍后清楚地观察导致 K-Means 算法形成每个聚类的属性。

如果我们观察从五个到六个聚类的步骤,模型增加了它的轮廓分数,这意味着六个聚类是比五个更好的分组。考虑到我们的目标是在保持良好轮廓分数的同时拥有最高数量的聚类,我们将为我们的模型选择六个聚类。稍后,当我们解释每个集群的属性时,将有可能更好地理解为什么这是最佳选择。

定义了聚类数后,是时候使用 Plotly 并构建我们的三维聚类了,因此我们必须构建一个函数:

详述该功能的步骤:

  1. 删除所选要素列上有 nan 的行。
  2. 使用函数输入将数据框的维度缩减为三个要素。
  3. 实例化标准缩放器。我们需要标准化我们的聚类数据,因为我们的要素尺度不同,我们不希望其中一个要素仅仅因为尺度更大而对聚类产生更多影响。
  4. 使用标准缩放器拟合和转换数据框,并将其转换为 NumPy 数组。
  5. 定义将在三维散点图上使用的悬停。在我们的例子中,我们使用了包含玩家全名的“DISPLAY _ FIRST _ LAST”列。**
  6. 使用聚类数的函数输入创建 K 均值模型,并将最大迭代次数设置为 100。
  7. 使阵列适合模型。
  8. 在缩减的数据框中创建一个列,其中包含模型为每个数据点提供的标签。
  9. 使用之前定义的悬停和标签列作为颜色参数,使用 Plotly 的" scatter_3d" 创建可视化。
  10. 展示可视化。

现在构建了这个函数,我们只需要用前面讨论过的特性和集群数来调用它,然后看看结果。

*clusterization_nba_players = clusterized_scatter(stats,6,'PTS','REB','AST')*

我们得到了这样的视觉化图像:

除了聚类 1(紫色)和 5(黄色)之外,这六个聚类在三维空间中分布良好。两者都接近原点,所以我们可以假设这些数据点是没有 PPG,RPG 和 APG 高统计的玩家。

在解释聚类之前,我们必须讨论篮球,以便为我们的聚类解释创建一个上下文。篮球有三个位置:后卫、前锋和中锋。后卫通常是更小更快的球员,负责组织球队,带球和投篮。虽然后卫因为远离篮筐而没有很高的篮板统计,但这个位置上最好的球员通常都有很高的得分和助攻统计,因为他们大多数时间都有球。前锋比后卫高,但比中锋矮。他们是灵活的球员,可以传球,投篮,必要时也可以靠近篮筐,得分或者抢篮板。另一方面,中锋是球队中最高的球员,主要任务是抢篮板和在篮下得分。所以,从他们身上,我们必须期待更高的篮板和得分数据,但更低的助攻。

现在,我们将研究六个集群中的每一个,并尝试解释将它们与篮球比赛中的位置相关联的属性:

黄色(5)——第四梯队球员——根据统计数据,这个集群中的球员是那些在他们的 NBA 职业生涯中没有太大影响的球员有趣的是,我们观察到黄色星团是一个非常密集的星团,有 1693 个数据点。这意味着数据集中超过三分之一的玩家符合这个等级。即使他们设法在联盟中比赛,他们的影响并不显著 均值 PPG: 2.5,均值 RPG: 1.3,均值 APG: 0.6**

深紫色(1)——第三梯队球员——这个集群的球员也没有令人难忘的职业生涯,但比第四梯队的球员对自己效力的球队贡献更大深紫色是也是一个密集的集群,有 968 名玩家 。场均 PPG: 5.7,场均 RPG: 3.4,场均 APG: 0.9**

蓝色(0)——第二梯队前锋/中锋——拥有坚实的 NBA 数据的球员专注于篮板而不是助攻,由此我们可以假设这是主要由前锋和中锋组成的群体 均值 PPG: 10.5,均值 RPG: 5.9,均值 APG: 1.6**

橙色(3) — 第二梯队后卫——同样是球员 s 有稳定的数据,但特别是在助攻方面,APG 的数据比蓝色集群好,但在篮板方面最差因此我们可以假设集群上的球员主要是后卫 s. 均值 PPG: 8.4,均值 RPG: 2.3,均值 APG: 2.9**

芥茉(4)——一线前锋/中锋——这组球员场均得分高,篮板突出,尽管在助攻上并不出彩,因为这组球员的平均 APG 甚至低于二线后卫。因此,可以肯定地说,这个集群中的球员都是联盟历史上的精英前锋和中锋。这是一个只有 152 名玩家的低密度集群。 场均 PPG: 17.2,场均 RPG: 9.9,场均 APG: 2.6**

浅紫色(2)————第一梯队后卫——这一组由精英后卫组成,表现为低篮板、高助攻和场均高得分。这组球员的平均 APG 是第一梯队前锋/中锋的两倍以上,但 RPG 不到一半,而 PPG 接近。也不是只有 236 名玩家的密集集群如果我们将精英玩家所在的芥末色和浅紫色聚类相加,我们在这些聚类中只有大约 9%的数据集 均值 PPG: 16.8,均值 RPG: 4.0,均值 APG: 5.4**

现在总结一下,只是对一些异常值的随机观察:

  • 威尔特·张伯伦 ( 一线前锋/中锋) —这位在 60 年代和 70 年代初打球的历史中锋在三维散点图中表现突出,他的数据点与其他任何人都相距甚远。正如剧情所证明的那样,在他那个时代,威尔特在得分和篮板方面都很有统治力。在 1961-62 赛季,他场均得分超过 50 分,抢下超过 25 个篮板,被广泛认为是体育史上最伟大的人物之一。

来源:作者。

  • 丹尼斯·罗德曼(第一梯队前锋/中锋)——尽管“只有”2 米,这对于他的位置来说是个矮个子,但他被认为是联盟历史上最好的篮板手之一,并且是五次冠军。尽管他在进攻端得分和助攻方面合作不多,但他在篮板方面的完全统治力保证了他在精英群体中的一席之地。如果数据没有在聚类过程中进行缩放,Dennis 可能不会与 PPG 要素在同一个精英聚类中,在该聚类中,他只有 7.3 个 PPG,范围更广,并且会对 K-Means 算法产生更大的影响。**

来源:作者。

  • 德雷蒙德·格林(第一梯队后卫)——格林是一名特殊的球员。他身高 1.98 米,和丹尼斯·罗德曼一样矮,除了他不擅长抢篮板,而是擅长助攻。他被认为是帮助改变比赛的球员之一,他的传球和空间能力,快速移动球。德雷蒙德是如此擅长传球,以至于我们的模型把他归为第一梯队后卫,尽管他是一名前锋,有时也打中锋。绿色是另一种情况,如果数据没有标准化,他将不会在第一层集群中排名,因为他的 PPG 低。**

来源:作者。

深入研究细节,理解每个聚类的属性,并创建一个可解释的上下文,将聚类分析扩展到可视化之外。可解释性是数据科学社区中经常讨论的话题,因为数据科学家可能会关注模型而不是问题,可解释性可能会丢失。

我希望你喜欢这篇文章,我可以回答更多的问题和讨论!

3 个简单的数据科学经验教训我得到了惨痛的教训

原文:https://towardsdatascience.com/3-data-science-lessons-i-learned-the-hard-way-e6c62a386eed

我的数据科学之旅中的一些惨痛教训

介绍

照片由 2y .康Unsplash

在我作为数据科学家工作的短暂时间里,我学到了一些经验教训,我认为值得分享。

这些都是我当数据科学学生时没有学到的教训;有些听起来显而易见,但他们从来没有直接教过我。希望在分享这些的时候,你不会有学习这些的困难!

如果你想看些别的东西,可以看看我下面相同主题的视频。

你可以看我在 YouTube 上关于这个话题的视频,而不是看这篇文章。

再三检查你的数字

照片由米卡·鲍梅斯特Unsplash 上拍摄

在数据科学领域做任何事情时,反复检查你的数据是很重要的。

数据科学家通常需要处理很多技术细节。因此,很容易忘记什么是重要的:从数据中提取有用的和有效的可操作的洞察力。

如果在从事数据科学项目时,这些数字没有意义,这很可能会使一切无效。如果这种情况在工作环境中持续发生,那么没有人会再认真对待你的工作。

我在工作中犯过这样的错误,即使是非常基本的任务,老实说,这很尴尬。我防止这种情况发生的主要方法是在每一步都更加多疑。

我宁愿过于偏执,也不愿在最后意识到我必须从头再检查一遍所有的东西。

如果你的计算或公式很复杂,我建议对它们是如何计算的做些笔记或评论。如果出了什么问题,这给了你一些可以依靠的东西,当有人问我如何得到一个特定的数字时,我未来的自己总是对此心存感激。

组织您的项目和代码

Kelly SikkemaUnsplash 上拍摄的照片

我过去有一头扎进数据的习惯,我想很多其他数据科学家也能理解。这可能会给你留下过于复杂的代码和结构不尽如人意的项目。

在项目的早期阶段,这可能没问题。但一切肯定要后期细化。我做过很多项目,每次重访时都不知道自己做了什么。这浪费了你和其他人的时间,如果他们在同一个项目上工作的话。

代码最终应该被简化,用大量的注释和注解来清楚地显示发生了什么。如果有人浏览了你的作品,他们应该很清楚你想要完成什么,不会有太大的困难。

你的项目结构也需要以一种有意义的方式来组织,尤其是当多人在同一个项目中工作的时候。不应该有一个文件夹,笔记本和 CSV 文件与随机脚本混合在一起。尽可能将项目的每个部分放在各自的文件夹中。

对于更严肃的项目,代码需要模块化。如果有经常重复使用的功能,不要把它们放在笔记本里:创建一个单独的文件夹,把这些功能存储在一个位置。这让您和其他人可以根据需要导入函数,如果函数需要调整,保持一致性会变得更容易。

如果你感兴趣,我实际上有一个关于如何组织你的数据科学项目的视频。我认为,如果你目前的项目有点乱,那就值得检查一下。

质疑这个问题

蒂姆·莫斯霍尔德Unsplash 上拍摄的照片

当有数据可用时,通常是你提出的问题决定了你将如何处理这些数据。

很多时候,如果人们知道你是数据科学家,他们会出于好奇问很多数据问题。然而,并不是每个问题都值得花时间来回答。

我学到的是提出问题总是好的。他们为什么问这个?从商业角度来看,这值得研究吗?这与我自己的目标一致吗?

让人们解释为什么调查某事是有益的,这是一个好习惯。如果与你的其他优先事项相比没有明确的价值,那么最好礼貌地拒绝。

事实是,数据科学家的大部分时间都花在了数据清理上。光是以正确的格式获取数据就要花很长时间才能得出一个答案。如果你不问问题就答应了太多的事情,你很可能会因为太多的要求而让自己不堪重负。

这是我从一开始就一直在努力的事情,通过更加关注我自己的优先事项和目标,它变得更好了。

结论

当我们踏上自己的数据科学之旅时,不可避免地会犯错误。希望通过利用我作为数据科学家的短暂时间所学到的东西,你会比我进步得更快。

和往常一样,如果你觉得这篇文章有帮助,你可以看看我在 YouTube 上的其他视频。如果你想通过电子邮件了解我在做什么,你可以考虑注册我的简讯

原载于 2022 年 2 月 6 日 https://leonlok.co.ukhttps://leonlok.co.uk/blog/3-data-scientist-lessons-i-learnt-the-hard-way/

使用 Python APIs 可以完成的 3 个数据科学项目

原文:https://towardsdatascience.com/3-data-science-projects-you-can-do-using-python-apis-d51714a76e55

使用 Python APIs 立即启动数据科学项目

斯特凡·斯特凡·契克Unsplash 拍摄的照片

作为一名数据科学家,您需要知道如何使用 API。通过使用 API,您不仅能够收集真实世界的数据,还可以使事情变得更简单,并加快您的数据科学项目的开发。

比方说你想用 Python 实现情感分析,不想从头构建自己的模型,只想快速解决。在这里,一个 API 可以帮助你完成繁重的工作,只留给你分析的部分。

在本文中,我将向您展示一些 Python APIs,它们将帮助我们实现情感分析、文本摘要和数据收集。您可以将它们视为开始或开发您的数据科学项目的捷径。

1.情感分析

情感分析帮助我们分类文本数据是正面的、负面的还是中性的。通常你会用 Python 构建一个机器学习模型来实现这种 NLP 技术(正如我在本指南中所做的那样),但是用 Python 实现情感分析有一种更简单的方法。

如何用 API 轻松解决这个项目

为了在 Python 中轻松实现情感分析,你可以使用 AssemblyAI API 。这个 API 自动将音频和视频文件转换成文本。一旦我们有了文本数据,实现情感分析就像发送一个post请求并将sentiment_analysis特性设置为True一样简单。

在这篇文章中,我展示了如何使用这个 API 进行情感分析,但是在此之前,你需要通过创建一个免费的 AssemblyAI 帐户来获得你的 API 密钥。每个 API 都需要一个密钥来与它们交互。一旦有了密钥,就可以发送请求了。

在下面的例子中,你可以看到我是如何使用这个 API 对著名的史蒂夫·乔布斯在斯坦福的演讲进行情感分析的。我得到的输出是一个 JSON 文件,我把它变成了熊猫的数据帧。

作者图片

正如您在上面看到的,API 返回了文本、情绪(中性、积极和消极)以及预测的置信度。

你不需要建立自己的模型就可以获得所有这些,而是依赖于一个随时可以使用的尖端人工智能模型。

2.文本摘要

文本摘要包括对大量文本进行摘要,以便从中获取最重要的信息。

我们可以使用 NLTK、Gensim 和 Sklearn 等库在 Python 中实现文本摘要。但是,您也可以使用 API 将文本分成几章,并获得每一章的摘要。

如何用 API 轻松解决这个项目

我们可以使用 AssemblyAI API 在 Python 中轻松实现文本摘要。除此之外,我们还可以将音频和视频文件分成章节,这要归功于这个 API 的语音转文本功能。

在本指南中,我将展示如何通过 3 个步骤轻松总结音频和视频文件。像往常一样,首先你需要获得你的 API 密钥,然后你必须使用 Python 代码上传你的音频文件,提交脚本请求并保存脚本和摘要。所有这些都是通过postget请求完成的,您可以在我之前提到的指南中看到详细信息。

在下面的例子中,我使用 API 为史蒂夫·乔布斯在斯坦福的演讲创建章节,并为每一章生成摘要。这是我在 JSON 文件中得到的一个章节:

{
"**summary**": "The only way to do great work is to love what you do. Keep looking and don't settle. Like any great relationship, it just gets better and better as the years roll on.",
"**headline**": "The only way to do great work is to love what you do.",
"**start**": 514536,
"**end**": 534430,
"**gist**": "don't settle"
},

3.数据收集

开始一个数据科学项目必须要有数据。如果你在一家大公司工作,你的老板很可能会提供你需要的数据。也就是说,你并不总是有数据可用于你将要从事的所有项目——这时你需要从互联网上收集真实世界的数据。

收集数据最安全、最实用的方法是使用目标网站的 API。这将帮助您轻松地为您的数据科学项目构建自己的数据集。

如何用 API 收集数据

现在大多数流行的网站都有自己的 API。尽管您必须了解它们中每一个的来龙去脉才能正确提取数据,但是用于与 API 交互的库和技术是相似的。

假设您想从 YouTube 视频中收集指标,如观看次数、链接、不喜欢和评论数。在这种情况下,您可以使用 YouTube API 提取数据并构建数据集。

这里有一个关于如何使用 YouTube API 的指南,它也将帮助你使用 API。请记住,在从 YouTube 频道收集数据之前,您需要申请一个 API 密钥(这个指南可能会有所帮助)。

现在,假设您想将 YouTube 上的一个视频转换成文本,并收集这些文本数据。在这里,您可以使用 AssemblyAI 的语音到文本 API 将音频/视频文件转换为文本数据。在本指南中,我用这个 API 转录了我自己的 YouTube 视频的介绍。您也可以观看下面的视频,一步步了解如何使用这个 API。

如果你检查指南/视频,你会看到 API 用转录把它钉死了!

加入我的电子邮件列表,与 10k 以上的人一起获取我在所有教程中使用的 Python for Data Science 备忘单(免费 PDF)

如果你喜欢阅读这样的故事,并想支持我成为一名作家,可以考虑报名成为一名媒体成员。每月 5 美元,让您可以无限制地访问数以千计的 Python 指南和数据科学文章。如果你使用我的链接注册,我会赚一小笔佣金,不需要你额外付费。

https://frank-andrade.medium.com/membership

更快的 Python 列表的 3 种数据结构

原文:https://towardsdatascience.com/3-data-structures-for-faster-python-lists-f29a7e9c2f92

明智地选择你的清单

格伦·卡斯滕斯-彼得斯在 Unsplash 拍摄的照片

我们都知道列表是条目的集合,但是也存在其他类似列表的数据结构,可以根据您打算如何使用列表来优化您的 Python 代码。

默认的 Python 列表确实有它的魅力——它简单、易于理解和使用。然而,在 LeetCode 上花了一些时间后,我意识到在某些情况下它可能不是最好的数据结构。例如在这个 LeetCode challenge 中,保持相同的逻辑但是简单地使用另一个数据结构将我的提交运行时间从99 毫秒减少到了33 毫秒!这可能看起来不算多,但是想象一下如果它被扩展,可以节省多少时间。我还必须补充一点,运行时间可能是随机的,匆忙得出它总能提供 3 倍加速的结论是不正确的。

图 1:使用列表的提交运行时(下图)与 heapq(上图)——作者图片

本文将介绍另一种类似列表的数据结构,何时使用它们,以及如何通过 Python 示例应用它们。

目录

维护优先级列表

使用**heapq**更快地检索列表中最小和最大的项目(以及更多)

图 2: 队列结构——作者图片

**heapq**使用堆队列算法,二叉树的设计使得任何子节点的值都大于父节点的值。这导致最小的元素位于树的根节点,任何新项目的插入都将通过“洗牌”找到它在树中的位置。在理解了二叉树是如何设计的之后,重要的是要注意这并不能保证一个精确的排序列表,而仅仅是一个排序的二叉树,类似于图 2。堆队列也称为优先级队列,因为优先级被给予树顶部的项目,并且移除该项目很容易“洗牌”或重新排列剩余节点的优先级。

为了进行高层次的比较,在通常的 Python 列表中,条目是按顺序添加的,比如appends在列表的后面添加一个新条目,而pop移除并返回列表中的最后一个条目。在堆队列结构中,heappop移除并返回列表中最小的项,heappush向列表中添加新项,同时保持已排序的二叉树结构。

何时使用**heapq**

  • 用于检索和删除列表中最小的项目
  • 用于检索列表中最小和最大项目的编号
  • 用于在添加新项目或合并两个堆后保留排序的二叉树

为了使用**heapq**,我们可以将一个空的或填充的列表转换成一个堆,

import heapq

heap = [5, 2, 4, 7, 6]

heapq.heapify(heap)
# heap = [2, 5, 4, 7, 6] -> sorted binary tree
#      2
#   5     4
#  7  6

为了转换堆,可以这样进行对堆的项目的检索和添加,

# Pop (retrieve and remove) smallest item
smallest_item = heapq.heappop(heap)   # smallest_item = 2

# Retrieve n-number of smallest and largest item
smallest2 = heapq.nsmallest(2, heap)  # smallest2 = [4, 5]
largest2 = heapq.nlargest(2, heap)    # largest2 = [6, 7]

# Push (add) new item
heapq.heappush(heap, 3)

# Push then Pop
smallest_item_after_add = heapq.heappushpop(heap, 1)
# smallest_item_after_add = 1, heap = [3, 4, 6, 7, 5]

# Pop then Push
smallest_item_before_add = heapq.heapreplace(heap, 1)
# smallest_item_before_add = 3, heap = [1, 4, 6, 7, 5]

最后,可以使用一个merge方法来合并多个堆,并保留排序后的二叉树结构。请注意,merge的输入应该是一个堆(遵循排序二叉树结构的列表),而不是任何列表!

# Merge two lists
heap1 = [1, 3, 5, 7]
heap2 = [2, 4, 6, 8]
merged_heap = heapq.merge(*[heap1, heap2])
# list(merged_heap) = [1, 2, 3, 4, 5, 6, 7, 8]

维护排序列表

使用***bisect***检索列表中最接近的值(以及更多)

**bisect**与其说是一个数据结构,不如说是一个二分法,帮助你定位和/或插入条目到一个保持顺序的排序列表中。

简单介绍一下,Python 使用了平均时间复杂度为O(nlogn)Timsort 排序算法。这种排序算法很快,但是,在你的列表上连续调用sort()可能并不可取,最好还是维护一个排序后的列表。

请注意,二分法只适用于已经排序的列表,而不适用于未排序的列表!将项目插入到(排序的)列表中可以如下完成,

import bisect

a = [1, 2, 2, 2, 6, 7]

# Insert item to preserve sorted list (in-place)
bisect.insort(a, 5)
# a = [1, 2, 2, 2, 5, 6, 7]

图 3:检索应该插入条目的索引—按作者排序的图片

我在bisect中发现的另一个有用的特性是,它可以返回应该插入条目的列表索引。在图 3 中,**bisect.bisect**(list, 4)方法将返回索引 4,其中数字4应该被插入到排序列表中。如果值已经存在,我们可以使用**bisect.bisect_left**(list, 7)**bisect.bisect_right**(list, 7)来指示数字7是应该插入到现有值的左边还是右边,并相应地返回索引。默认情况下,**bisect**()实现**bisect_right**()

使用**bisect**()检索索引也是在列表中找到与您要‘插入’的值最接近的条目的一种快捷方式。例如,如果我想找到大于或等于 4 的最小数字,我可以使用**bisect_left**()来获取索引并相应地检索值。

何时使用**bisect**

  • 用于向保持列表顺序的排序列表添加项目
  • 为了检索索引,插入一个保持列表顺序的值
  • 用于检索排序列表中大于x的最小值
  • 用于检索排序列表中小于x的最大值

维护列表中的顺序和容量

使用***deque***实现类似队列的列表

**deque**代表双端队列,允许快速添加和删除列表前面和后面的项目,这使得表示队列结构变得容易。当列表达到最大容量时,也可以实现列表的容量,以在后面添加项目时移除前面的项目,反之亦然。

为了便于比较,**deque**提供了与普通 Python 列表中的O(n)时间复杂度相比的O(1)条目添加和移除的时间复杂度。

正常的列表操作,如indexcountextendreverseremove,等。还在**deque**上班。

何时使用**deque**

  • 用于将项目添加到列表的前面和/或后面
  • 用于从列表的前面和/或后面移除项目
  • 用于将项目从队列的后面移到前面,反之亦然(循环队列)
  • 用于实施列表容量

下面是一些如何使用**deque**的例子,

from collections import deque

d = deque([1, 2, 3, 4], maxlen=10)

# Adding item(s)
d.append(5)
d.extend([6, 7])
d.appendleft(0)
d.extendleft([-1, -2])
# d = [-2, -1, 0, 1, 2, 3, 4, 5, 6, 7]

# Removing items
first_item = d.popleft()
last_item = d.pop()
# d = [-1, 0, 1, 2, 3, 4, 5, 6]

# Shift items from back to the front
d.rotate(3)
# d = [4, 5, 6, -1, 0, 1, 2, 3]

希望你已经理解了更多类似列表的数据结构和算法,下次可以使用它们来加速你的代码!你也可以挑战自己,尝试手工实现这些数据结构,比如这个 LeetCode challenge 设计一个**deque**数据结构。

相关链接

平均值的 3 个简单假设检验

原文:https://towardsdatascience.com/3-easy-hypothesis-tests-for-the-mean-value-2d8a06177042

将样本的平均值与其他预期值进行比较的 3 种简单方法

Unsplash 上的 Edge2Edge 媒体拍摄

数据科学家和分析师经常需要处理平均值,需要将一个样本的平均值与已知的期望值或另一个样本的平均值进行比较。统计学帮助我们进行一系列强有力的假设检验来完成这些任务。

问题是

比方说,我们测量类似珠穆朗玛峰的高度。我们知道它是 8848 米。我们测量后,得到 8840 米,标准误差为 20 米。我们的平均值和已知身高有统计学差异吗?

假设另一个研究小组使用不同的工具进行了相同的测量,并获得了 8850 米,标准误差等于 10 米。他们的结果在统计学上和我们的不同吗?

这是处理平均值时的两个常见问题。我们经常需要将我们的平均值与一个已知的期望值或别人得到的平均值进行比较。

将事物相互比较是统计学中的一个常见问题,我们可以从假设检验的理论中获益,以评估这种比较的统计学意义。在这篇文章中,我将讨论学生对平均值的 t 检验。它们是最常见的假设检验类型,非常有用。

它们都依赖于一个基本假设:样本是从正态分布中产生的。

下面是一些使用 Python 编程语言的例子。所有这些例子都是基于 NumPy 的,所以我们首先要导入它并设置随机数生成器的种子。让我们也为直方图计算导入 matplotlib。

import numpy as np 
import matplotlib.pyplot as plt 
np.random.seed(0)

将平均值与已知的期望值进行比较

最简单的 t 检验形式是将样本的平均值与已知的期望值进行比较。

让我们使用 NumPy 在 Python 中创建一个 30 个正态分布随机数的样本,其均值等于 100,标准差等于 10。

x = np.random.normal(size=30,loc=100,scale=10)

作者的 x. Image 直方图

这个样本的平均值是 104.43。我们想知道它在统计上是否不同于 100。

这种均值 t 检验的零假设是:均值等于 100。所以,我们正在进行一个双尾检验。

为了使用它,我们必须从 Scipy 导入适当的函数。

from scipy.stats import ttest_1samp

然后,我们可以使用“ttest_1samp”函数,它给出了这种双尾检验的 p 值:

ttest_1samp(x,100) 
# Ttest_1sampResult(statistic=2.2044551627605693, pvalue=0.035580270712695275)

如果我们想使用 1 尾检验,无效假设将是以下之一:

  • 平均值大于 100
  • 平均值小于 100

通过陈述替代假设,我们可以计算这两个检验的 p 值。

# Null hypothesis: x.mean() is greater than 100 
# (alternative hypothesis, it's less than 100) **ttest_1samp(x,100,alternative='less')** # Ttest_1sampResult(statistic=2.2044551627605693, pvalue=0.9822098646436523) 
######################## 
# Null hypothesis: x.mean() is less than 100 
# (alternative hypothesis, it's greater than 100) **ttest_1samp(x,100,alternative='greater')** # Ttest_1sampResult(statistic=2.2044551627605693, pvalue=0.017790135356347637)

这是一个学生对单一样本进行 t 检验的例子。请记住,样本必须是根据正态分布创建的。

比较具有相同方差的两个样本的平均值

现在让我们从上一个样本的正态分布开始创建一个新样本。我们可以把尺码从 30 号改成 50 号。

y = np.random.normal(size=50,loc=100,scale=10)

其平均值为 96.85。

假设我们已经知道两个样本来自两个方差相同的正态分布。我们可以使用双样本 t 检验来比较它们的平均值。我们必须使用“ttest_ind”函数。

from scipy.stats import ttest_ind

我们现在可以计算我们需要的所有测试的 p 值(两个尾部或一个尾部)。

# Null hypothesis: x.mean() is equal to y.mean() **ttest_ind(x,y)** # Ttest_indResult(statistic=3.4565852447894163, pvalue=0.0008885072426696321) 
###################### 
# Null hypothesis: x.mean() is greater than y.mean() 
# (alternative hypothesis: it's less than y.mean()) **ttest_ind(x,y,alternative='less')** 
# Ttest_indResult(statistic=3.4565852447894163, pvalue=0.9995557463786652) 
###################### 
# Null hypothesis: x.mean() is less than y.mean() 
# (alternative hypothesis: it's greater than y.mean()) **ttest_ind(x,y,alternative='greater')** # Ttest_indResult(statistic=3.4565852447894163, pvalue=0.00044425362133481604)

比较方差不同的两个样本的平均值

最后,最常见的情况:两个样本来自具有不同方差的正态分布。

让我们创建一个来自标准偏差等于 5 的正态分布的新变量:

z = np.random.normal(size=50,loc=100,scale=5)

执行所谓的韦尔奇检验(即学生 t 检验的这种特殊情况)的函数又是“ttest_ind”,但我们必须将 equal_var 参数设置为等于 False。

# Null hypothesis: x.mean() is equal to z.mean()**ttest_ind(x,z,equal_var=False)** 
# Ttest_indResult(statistic=1.094819002420836, pvalue=0.2807390405295771) 
###################### 
# Null hypothesis: x.mean() is greater than z.mean() 
# (alternative hypothesis: it's less than z.mean()) **ttest_ind(x,z,alternative='less',equal_var=False)** 
# Ttest_indResult(statistic=1.094819002420836, pvalue=0.8596304797352115) 
###################### 
# Null hypothesis: x.mean() is less than z.mean() 
# (alternative hypothesis: it's greater than z.mean()) **ttest_ind(x,z,alternative='greater',equal_var=False)** 
# Ttest_indResult(statistic=1.094819002420836, pvalue=0.14036952026478855)

结论

在本文中,我解释了 3 种基于平均值的假设检验:单样本 t 检验,将样本的平均值与已知的期望值进行比较;等方差双样本 t 检验;异方差双样本 t 检验(也称为 Welch 检验)。最后两个测试比较两个样本的平均值。尽管这种测试非常强大,但必须记住,它们强烈要求样本是从高斯分布中生成的。如果满足这一要求,就可以安全地进行这些测试。

原载于 2022 年 10 月 25 日【https://www.yourdatateacher.com】

在线部署您的 Streamlit Web 应用程序的 3 种简单方法

原文:https://towardsdatascience.com/3-easy-ways-to-deploy-your-streamlit-web-app-online-7c88bb1024b1

免费,也不需要码头集装箱

Web 应用程序正日益成为与其他用户共享数据科学项目的流行方式。这是因为 Streamlit 等易于使用的 Python 库的出现,以及免费将 web 应用程序部署到云的便利性增加。

卢卡斯·布拉塞克Unsplash 上拍摄

什么是 Streamlit?

Streamlit 是一个免费的开源 Python 框架,您可以使用它轻松构建和共享您的交互式仪表盘和机器学习 web 应用程序。如果您熟悉 Python,您应该能够在几小时内(如果不是几分钟的话)学会并构建 Streamlit 应用程序。一定要去画廊看看一些应用程序的灵感!https://streamlit.io/gallery

云部署流程

不久前,将一个简单的 web 应用程序部署到云中需要大量的应用程序容器化知识和工具,当然还需要资金。如今,这个过程已经变得简单到只需上传几个文件到网上,运行几个命令行。在本文中,我将介绍如何将您的 Streamlit 应用程序部署到 3 个易于使用且免费的公共云平台上。

这是每个平台中最终产品的外观:

拥抱脸空间

https://huggingface.co/spaces/bohmian/simple_streamlit_app

细流云

https://share . streamlit . io/Damian boh/simple _ streamlit _ app/main/app . py

Heroku 应用平台

https://simple-streamlit-app-bohmian.herokuapp.com/

部署到 3 个云平台的相同 Streamlit 应用程序。图片来自作者。

一个 app,3 个云平台。我们开始吧!

1.构建一个简单的 Streamlit Web 应用程序

让我们先用 Streamlit 创建一个简单的 web 应用程序,然后学习如何将它部署到三个云平台。

1.1.安装和设置

首先使用 pip 工具安装 Python Streamlit 包:pip install streamlit

然后我们创建一个文件夹simple_streamlit_app 来存放 app 需要的文件。

1.2.Web 应用程序脚本

在该文件夹中,我们创建了一个简单的脚本,并将其命名为app.py。在这里,我们编写了一个简单的应用程序,演示了文本输入和滑块小部件的用法,以及如何显示数据帧。

import streamlit as st
import pandas as pdst.title(“A Simple Streamlit Web App”)name = st.text_input(“Enter your name”, ‘’)st.write(f”Hello {name}!”)x = st.slider(“Select an integer x”, 0, 10, 1)
y = st.slider(“Select an integer y”, 0, 10, 1)df = pd.DataFrame({“x”: [x], “y”: [y] , “x + y”: [x + y]}, index = [“addition row”])
st.write(df)

上面的代码基本上是不言自明的。该应用程序接受用户的文本输入,并将其存储为一个name变量,然后打印出问候文本。

它还接受两个范围从 0 到 10 的整数滑块输入,将它们存储为xy变量。然后它打印出数据帧df中的变量及其总和。

1.3.在本地运行应用程序

这就是应用程序所需的全部内容。要在本地启动应用程序,只需在终端中运行以下命令,与您的app.py文件放在同一个文件夹中。

streamlit run app.py

如果成功,应该会出现以下内容:

图片来自作者

您的浏览器也应该弹出上面键入的本地 URL,您将看到类似这样的内容。在这里,我输入了一些输入来显示应用程序如何响应。

简单 Streamlit App 截图。图片作者。

2.在部署到云之前…

我们现在准备在云上公开部署您的应用。在部署到任何云平台之前,您还需要做两件事情。

2.1.安装 git

此链接安装 git 命令行工具。这允许您在终端上运行 git 命令,将您的应用程序文件上传到 web。

2.2.添加一个“requirements.text”文件

下面所有的云平台都需要知道要安装什么 Python 包,才能启动你的 app。我们在一个requirements.txt文件中指定了这一点。

streamlit
pandas

3.第一个平台:将你的应用程序部署到拥抱脸空间

3.1.建立一个拥抱脸帐户

在这里创建一个拥抱脸账户:https://huggingface.co/

3.2.创造一个新空间

点击顶部导航栏的空格。然后点击‘创建新空间’按钮。

拥抱脸空间截图。图片来自作者

填写出现的表格:

  • 输入您想要的“空间名称”(例如“simple_streamlit_app”)
  • 通过单击“Streamlit”选择 Space SDK
  • 点击“创建空间”按钮。

3.3.将应用程序文件上传到您的新拥抱面部空间

现在,您将进入显示此命令行的页面。(您的将与我的不同,因为您使用的是不同的空间。)

  • 复制上面的命令,并在您的终端上运行。(记住你的命令是不同的。)
  • 一个名为name of your new space的文件夹将在您的计算机上本地创建。
  • 将您的app.pyrequirements.txt文件复制到这个新文件夹中。
  • 在终端上,运行以下命令,替换文件夹名称。这些命令告诉 git 考虑您在上一步中添加的 2 个新文件,提交它们并将其推送到您的新拥抱面部空间。
cd *name_of_your_new_folder* git add .
git commit -m "first commit"
git push 

如果成功,您应该会看到以下输出。

终端输出截图。图片来自作者

3.4.您的公共应用程序现在是实时拥抱面部空间!

返回到显示拥抱面部空间页面的浏览器。等待几分钟后,刷新页面,您应该看到您的应用程序正在运行!任何人都可以使用此页面的链接访问此应用程序。这里是我的:【https://huggingface.co/spaces/bohmian/simple_streamlit_app】T4

恭喜您,您已经发布了您的 Streamlit 应用程序!现在让我们来探索第二个云平台。

4.第二个平台:部署您的应用程序以简化云

Streamlit 也提供了自己的云平台。

4.1.设置 GitHub 帐户

在这里创建一个 GitHub 账号:https://github.com/

4.2.创建新的 GitHub 资源库

  • 在任一页面的右上角,使用下拉+菜单,并选择“新建存储库”。

GitHub 截图。图片来自作者

  • 填写您想要的“存储库名称”,然后向下滚动并单击“创建存储库”。不要更改任何其他参数。

4.3.上传文件到你的 GitHub 库

  • 现在点击“上传现有文件”。

来自作者的 GitHub 截图

  • 将您的app.pyrequirements.txt文件拖放到下面的页面中。

4.1.设置 Streamlit 云帐户

在此创建一个 Streamlit 云帐户:https://streamlit.io/cloud

4.2.创建一个新的应用程序并链接您的 GitHub 帐户

  • 一旦你登录,应该有一个非常明显的(你会看到为什么)“新应用程序”按钮供你点击。
  • 然后你会看到一个提示“连接到 GitHub”。登录到您之前创建的 GitHub 帐户。

4.3.部署您的应用

  • 在下一个屏幕中,通过在“repository”下键入名称来搜索您之前创建的 GitHub 存储库。
  • 将“主文件路径”更改为“app.py”。
  • 点击部署!

Streamlit 云截图。图片来自作者

4.4.您的公共应用程序现已在 Streamlit Cloud 上上线!

等待一段时间后,您的应用程序将会出现。恭喜你。下面是我的:https://share . streamlit . io/Damian boh/simple _ streamlit _ app/main/app . py

最后但同样重要的是。再来看我们的第三个云平台。

5.第三平台:将您的应用部署到 Heroku 应用云

这里还需要几个文件,因为 Heroku App 是一个通用的 web app 云平台,没有默认的 Streamlit 配置。

5.1.添加一个“setup.sh”文件

这是一个 shell 文件,您需要在文件中添加以下 shell 命令。它基本上告诉 Heroku 在运行 Streamlit 应用程序时要配置和设置什么。

mkdir -p ~/.streamlit/
echo “\
[server]\n\
headless = true\n\
port = $PORT\n\
enableCORS = false\n\
\n\
“ > ~/.streamlit/config.toml

5.2.添加一个“Procfile”文件

该文件没有文件扩展名。这个文件指定了 Heroku 在部署应用程序时运行的命令。我们指定这是一个以 shell 文件为配置的 web app,并调用 Streamlit 来运行 app.py。

web: sh setup.sh && streamlit run app.py

5.3.为所有文件创建一个新文件夹

在我们之前包含文件的文件夹中,回想一下已经建立了一个本地 git 存储库,它链接到拥抱脸空间。我们不想对此文件夹进行任何更改。因此,我们创建一个新的文件,并将我们的app.pyrequirements.txtsetup.shProcfile文件复制到其中。

5.4.设置 Heroku 应用程序云帐户

在这里创建一个 Herokuapp 账户:https://herokuapp.com/

5.5.创建本地 Git 存储库

在终端的文件夹中运行以下命令。这将初始化一个本地 git 存储库,添加所有文件并提交所有更改。

git init
git add .
git commit -m “first commit”

5.6.创建一个新的 Heroku 应用程序并推送到它的存储库

接下来,运行以下命令(更改‘应用程序名称’),这些命令将依次执行以下操作:

  • 登录到您的 Heroku 帐户(您的浏览器将为您打开以执行登录)
  • 用你想要的名字创建你的 Heroku 应用程序
  • 把仓库推到 Heroku
heroku login
heroku create *name_of_your_app (change this)*
git push heroku master

5.7.您的公共 App 现已在 Heroku App Cloud 上线!

整个部署过程将显示在终端上。一旦完成,你的应用程序应该在*<name_of_your_app>*.herokuapp.com上运行。恭喜你。

下面是我的:https://simple-streamlit-app-bohmian.herokuapp.com/

结束语(赞成和反对)

现在,您已经学会了将您的 Streamlit 应用部署到三个不同的云平台。您可以根据自己的喜好选择部署到任何云中。这里有几点需要考虑。

拥抱面部空间

拥抱面部空间不会将你的应用程序部署到一个完整的浏览器页面上,而是嵌入到一个框架中,所有的导航栏和工具都在顶部。如果你想要一个整页的应用程序,你可以选择其他两个平台(不过我真的很喜欢顶部可爱的拥抱脸标志)。

流线云

Streamlit Cloud 是您访问时加载应用程序最快的。然而,拥抱脸空间和 Streamlit Cloud 都允许用户查看公共应用程序的源代码。我把它作为一个练习留给读者去发现如何做。如果想对源代码保密,可以考虑 Heroku App 代替。

Heroku 应用程序

有些人可能不喜欢为 Heroku app 创建额外文件的麻烦,它也在 App 长时间未使用后启动 App 相当慢。然而,你可能之前已经在 Heroku 上部署了其他框架(比如 Flask 和 Django)的应用。在这种情况下,你可能更喜欢在 Heroku 上管理你的所有应用,包括 Streamlit 应用。请注意,一个免费的 Heroku 帐户最多只允许 5 个应用程序。

我希望这篇文章对你有用。享受 Streamlit 带来的乐趣。构建和部署愉快!

如果你喜欢这篇文章,请随意关注我或者看看我下面的其他文章!😃

https://medium.datadriveninvestor.com/build-a-stock-sentiment-web-app-with-flask-and-deploy-it-online-3930e58a236c https://medium.datadriveninvestor.com/train-and-deploy-an-nlp-news-classifier-web-app-to-the-cloud-for-free-82655b6b32f4

如果你喜欢这样的文章,并希望支持像我这样的作家,请考虑注册成为媒体会员。每月 5 美元,你就可以无限制地阅读 Medium 上的任何文章。如果你注册使用我的链接,我会赚一小笔佣金,不需要你额外付费。

https://medium.com/@bohmian/membership

让你的 Dash 应用看起来更好的 3 个简单方法

原文:https://towardsdatascience.com/3-easy-ways-to-make-your-dash-application-look-better-3e4cfefaf772

Luke Chesser 在 UnSplash 上的照片

Dash 是一个低代码框架,它允许你构建通过网络浏览器呈现的数据可视化。没有许可费用,它提供了一种灵活和免费的方式来构建应用程序。如果你想了解更多关于如何构建 dash 应用程序的知识,我建议你从文档中的教程和 Charming Data 的 Youtube 视频开始。

Dash 中的默认设置可以产生一些“功能性”的东西——它完成了工作——但并不总是看起来很棒。在这篇文章中,我将介绍三种简单的方法来改善你的观想的观感。

为了看看它们在实践中是如何工作的,我构建了一个非常快速的虚拟应用程序,没有使用任何样式——它并不是很棒。

作者图片

1.使用主题

改善整体外观和感觉的最快方法是使用主题。Dash bootstrap 主题通过标准化标题、按钮、标签、表格、警告等内容的格式,提供了一种快速改进格式的方法。有一系列的风格,Dash 提供了一个“主题浏览器”。

主题列表是科斯莫电子人暗黑平淡期刊LITERA流明力士本草明蒂变身https://bootswatch.com/pulse/ SPACELAB超级英雄联队蒸汽雪人西风

要使用主题,您需要导入 dash 引导组件:

import dash_bootstrap_components as dbc

然后,要指定主题,您需要在启动应用程序时向“external_stylesheets”添加一个参数。

app = dash.Dash(external_stylesheets=[dbc.themes.LUX])

下图是 CYBORG——它使字体更加现代。

作者图片

然而,当你使用深色背景的主题时,一个问题就变得很明显了。样式对情节没有任何影响——一个奇怪的白盒出现在黑暗的背景下。我们可以用图形模板来解决这个问题。

作者图片

2.使用图形模板

图形模板设计图形的样式。它通过改变颜色和字体来匹配情节的风格和主题的风格。

要使用体形模板,您需要从 dash 引导模板中导入它:

**from** dash_bootstrap_templates **import** load_figure_template

一旦加载了体形模板,就可以按以下方式使用它:

load_figure_template(‘LUX’)

您可以立即看到原始图形的背景图已经消失,颜色更新为主题。

作者图片

3.使用布局并添加填充

但是我们还可以做更多的事情,因为文本和图例就在页面的边缘。为了解决这个问题,我们可以使用 bootstrap layout 告诉应用程序在哪里放置项目,然后给每个元素添加一些边距。

布局由网格系统控制。有 12 列,列宽由该列应该跨越 12 列中的多少列来控制。

列包含在行中,也就是说,应用程序应该由一系列行组成,这些行可以有不同数量(和宽度)的列。如果不指定行内的列宽,默认情况下,它们将被平均分割。代码的概要如下:

在我们的应用程序中,我们应该有 2 行——一行用于标题,一行用于图表。

因为每行只有一列,所以没有必要放置 dbc。Col()到[]中,但如果有多列,则必须这样做。

现在我们有了布局中的每个元素,我们可以添加样式。样式调用需要一个字典,在那里你可以指定上边距、下边距、左边距和右边距

style = {‘margin-left’:’7px’, ‘margin-top’:’7px’}

在我们的应用程序中,我们已经为标题做了这些,并将图的边距增加到“15px ”,这样它就比标题缩进得更多。

作者图片

使用布局结构的真正好处是,您可以快速、轻松地添加其他元素并更改布局(重要的是对齐)。例如,许多仪表板使用侧栏,您可以在其中选择不同过滤器。要创建侧栏,需要在行内创建列。你想在侧边栏中显示的内容包含在“侧边栏”中。

作者图片

在这里,我将包含图表的列的宽度设置为 9,这意味着侧边栏占据了 3/12。如果侧边栏变宽了,你可以很快地改变它。

作者图片

没那么好,我改回 3/12。

结论

通过查看之前和之后的图像,我们可以看到,通过 15 分钟的工作,我们可以非常快速地改善 Dash 应用程序的外观。你可以在我的 github 上找到生成这个应用的代码。

以前

作者图片

在...之后

作者图片

感谢您的阅读——请务必让我知道您的任何反馈。

参考资料:

Dash 文档:【https://dash.plotly.com/introduction

Dash bootstrap 文档:https://dash-bootstrap-components . open source . faculty . ai


我喜欢为商业用户写关于数据科学的文章,我热衷于使用数据来提供切实的商业利益。

您可以通过 LinkedIn 与我联系,并通过 Medium 关注我,了解我的最新文章。

回归的 3 个评估指标

原文:https://towardsdatascience.com/3-evaluation-metrics-for-regression-80cb34cee0e8

…用简单的英语解释

Unsplash 上的 CHUTTERSNAP 拍摄

基于回归的机器学习模型用于预测连续属性的值。与所有监督机器学习问题一样,该模型使用一组特征(X)来训练,以学习到目标变量(y)的映射。在回归的情况下,目标是一个连续变量,如房价。

大概最简单的回归算法就是线性回归了。简单的线性回归只有一个要素和一个目标,用下面的等式表示。

线性回归。图片作者。

举一个简单的例子,假设我们想只根据一辆汽车的马力来预测它的每加仑英里数。在这种情况下,以下内容适用:

【易】代表目标变量,或 MPG。

代表特性,在这里是马力。

β1 是马力要乘以的系数或数值。

β0是直线与 y 轴相交的点,如下图所示。

εi 是模型中的误差,度量估计关系中的方差。

我们可以使用 Seaborn Python 库为这类问题绘制一个简单的线性回归。

简单线性回归。图片作者。

上图中的线代表预测值。我们可以看到,并不是所有的数据点都完全符合这条线,这代表了模型中的误差。线性回归的目标是通过确定 β0β1 的最佳值来最小化该误差的大小。

与任何机器学习问题一样,有几个指标可用于确定模型的整体性能。换句话说,这个模型在最小化整体误差方面有多好?在本文的剩余部分,我将分享三个可用于评估基于回归的模型性能的指标。

1.r 平方(R2)

r 平方,也称为决定系数,是观察值与拟合回归线接近程度的度量。因变量将包含一定量的变化,r 平方衡量模型解释了这种变化的程度。

如果我们再次看上面的图表,我们可以看到,我们有一条直线代表学习模型。这就是所谓的回归线。然而,许多真实的数据点并没有落在线上。直线和每个观察数据点之间的距离称为残差。

残留。图片作者。

r 平方度量是通过推导每个数据点的残差并将结果平方来计算的。得到的数字相加在一起,这就成了模型中无法解释的方差的度量。它的公式通常表示如下。

r 平方。作者图片

r 平方值的范围从 0 到 1,其中 1 分表示模型能够解释因变量的所有方差。下图比较了两个不同自变量的回归线。我们可以看到,观察到的重量值更紧密地聚集在回归线周围。

如果我们比较 r 平方值,我们也可以看到一个实质性的差异。对于重量与 MPG,r 平方值为 0.69。换句话说,该模型能够解释因变量中 69%的方差。加速度的 r 平方值低得多,为 0.18,这个模型只能解释 18%的方差。

比较不同的独立变量。图片作者。

r 平方很少单独用于估计模型的性能,因为它不能给出任何偏差的度量。因此,对于具有高偏差的模型,可能具有高的 r 平方值。这就是为什么我们还需要考虑其他的绩效衡量标准。

2.均方根误差(RMSE)

上述残差也可以被认为是一种测量回归模型中误差的方法。RMSE 本质上是对这些残差分布程度的一种度量,是量化回归模型总体误差的一种标准方法。

通过首先计算均方误差(MAE)来计算 RMSE。要做到这一点,你需要获得代表因变量的每个数据点的残差,并对该值求平方。然后将所得值相加,并除以总点数减 2。那么 RMSE 就是这个数的平方根。

RMSE。图片作者。

RMSE 越小,模型越接近数据。这通常被认为是解释模型的最佳方式之一,因为它与因变量具有相同的单位。

RMSE 的一个潜在缺点是,由于计算指标的方法,优化 RMSE 将比其他指标更多地惩罚较大的错误。因此,当模型特别不希望出现较大误差时,这是最有用的。

RMSE 没有标准的“好”分数,因此,与基准分数(如使用简单模型生成基线)相比,它是最有用的。

3.平均绝对误差

MAE 是预测值与观察值之间距离的另一种度量。它与 RMSE 相似,其单位与因变量的单位相匹配。然而,在 MAE 分数中观察到的变化是线性的,因为 MAE 的值将随着误差的增加而增加。因此,MAE 不会因为较小的错误而惩罚较大的错误。

MAE 度量总是正数,数字越小,模型越适合。与 RMSE 一样,没有标准的“好”分数,因此与基线模型进行比较非常重要。

MAE 的计算方法是,首先对残差的绝对值求和,然后将结果除以观察总数。

平均绝对误差。图片作者。

与其他机器学习问题一样,对于评估回归模型的性能,没有单一的最佳度量。您选择的度量标准将取决于用于定型模型的数据以及模型的使用方式。考虑偏差风险、误差大小以及在实际使用模型时可能产生的影响。在大多数情况下,通常使用几个指标来评估整体性能,通常与基准进行比较是最有用的。

在本文中,我简单介绍了评估回归最常用的三个度量标准。然而,还有更多的,sckit-learn 文档包含了一个很好的列表,其中列出了可以使用的其他指标这里是

感谢阅读!

你应该知道的 3 个惊人的 Python 库

原文:https://towardsdatascience.com/3-extremely-useful-python-libraries-for-data-science-7f809eb98334

Python 库

你应该知道的 3 个惊人的 Python 库

非常有用的 Python 库——维基百科,Pandasql,Missingno!

若昂·赞诺在 Unsplash 上的照片

Python 以其独特的特性集和提供这些特性的大量库而闻名。

三个如此神奇和强大的库是,

**·** [**Wikipedia**](#216e) **·** [**Pandasql**](#f9f8) **·** [**Missingno**](#5f03)

在本文中,我们将讨论如何在不离开 Python IDE 的情况下搜索尽可能多的信息,使用 SQL 查询轻松提取数据子集,并有效地可视化缺失值。⚡️

维基百科(一个基于 wiki 技术的多语言的百科全书协作计划ˌ也是一部用不同语言写成的网络百科全书ˌ 其目标及宗旨是为全人类提供自由的百科全书)ˌ开放性的百科全书

这是一个 Python 库,使得访问和解析来自维基百科的数据变得容易。使用这个库,我们可以在不离开 Python IDE 或 Jupyter-Notebook 的情况下搜索**wikipedia**上的任何东西。

有什么用💡

记得有一种情况,我们正在进行项目,需要对一些术语进行更多的澄清。通常我们 google 一下,看一下wikipedia进行初步的基本了解。这个库让你不用离开 python 编辑器就可以自由搜索维基百科。

如何在 Python 🛠️中使用维基百科

仅供第一次使用,使用以下代码行安装库,

pip install wikipedia

然后使用import wikipedia导入库,你就可以自由地在网上寻找你想要的内容了。下面是一些开始使用的标准命令。

  • 设置网页结果的语言:set_lang()
  • 维基百科的搜索页面:search()
  • 获取文章摘要:summary()

例子:事物如何运作🚀

让我们看看这个图书馆有多神奇。下面是上面所有命令运行的图片!

例如,让我们在wikipedia上搜索术语“Python”。

维基百科搜索|作者图片

如您所见,search()命令将返回作为“Python”搜索的项目列表。

更进一步,让我们对其中一个结果进行总结。

按作者获取文章|图片的摘要

然而,方法summary()带有一个可选参数sentences,这让我们可以自由地只获取文章的前几个句子,如下所示。

文章摘要两句话|作者图片

默认情况下,生成的网页的语言是英语。使用方法**set_lang()**,我们可以在搜索之前将其更改为任何想要的语言。

例如,我们将语言更改为德语,德语的代码为**de**

根据作者更改维基百科结果|图片的语言

这个库的更多细节可以在 这里 找到。

Pandasql

**pandasql**允许您使用 Python 中的 SQL 语法查询 pandas 数据帧。它为不熟悉 Python 或 pandas 的人提供了更简单的操作和清理数据的方法。

有什么用💡

尽管 Python 中的 Pandas 库被广泛用于数据操作和分析,但在许多情况下,SQL 查询非常高效且易于编写。因此,这个包利用 SQL 的能力从 Pandas 数据帧中快速提取数据子集。

如何在 Python 🛠️中使用 Pandasql

仅供第一次使用,请使用以下方式安装软件包:

pip install pandasql

安装完成后,通过导入sqldf开始使用这个库,如下所示

from pandasql import sqldf

这个sqldf接受两个参数—

  1. SQL 查询字符串— 必需的
  2. 一组会话/环境变量— locals()或 globals() — 可选

例子:事物如何运作🚀

为了演示,我将使用我为所有文章生成的 Dummy_Sales_Data

由 Suraj 创建的 Dummy _ Sales _ Data|作者图片

例如,选择产品类别为“办公”的数据。对它的 SQL 查询将是,

SELECT * FROM df WHERE Product_Category = 'Office'

正如我提到的,函数sqldf接受 SQL 查询字符串作为输入参数,我们可以如下编写 SQL 查询字符串

"SELECT * FROM df WHERE Product_Category = 'Office'"

作为最后和下一步,让我们得到所需的数据如下

在 Pandasql | Image by Author 中使用 SQL 查询获取熊猫数据帧的子集

此外,更复杂的 SQL 查询,包括连接也可以使用pandasql来执行。

您所需要做的就是在“ ”中包含您想要运行的查询

pandasql的官方文档可以在这里找到。

缺少编号

Missingno是一个 Python 库,它提供了通过信息可视化来理解缺失值分布的能力。

有什么用💡

原始数据经常遇到的问题之一是缺失值。如果数据集在单元格中没有任何值,则它有一个缺失值。当这样的数据集被读入 pandas 数据帧时,缺失的值用NaN表示

除了使用pandas.DataFrame.isnull()pandas.DataFrame.isna()来识别NaN之外,还可以可视化数据帧中缺失值的分布。

如何在 Python 🛠️中使用 Missingno

仅供第一次使用,从使用安装库开始

pip install missingno

安装完成后,只需将其导入到您当前的笔记本中,您就可以开始探索了

import missingno as msno
%matplotlib inline

例子:事物如何运作🚀

例如,在我们的数据集中,我们有丢失的值,

熊猫数据框|作者图片中缺少的值

使用missingno包,不同列中缺失值的分布可以在下面的一行中可视化。

msno.matrix(df)

使用 Python 中的 Missingno 可视化缺失值|作者提供的图像

在上图中,每一条水平线(红色矩形)代表一堆缺失值。并且它们的位置指示它们在数据集中的位置。

另一个有用的可视化技术是热图。要了解它的细节,我推荐阅读这篇有趣的文章。🏆

总结一下,

这些库,尤其是pandasql在几乎每一个 Python 数据科学项目中都节省了我的时间,并且非常容易掌握。Wikipedia图书馆也同样有用,可以在维基上从笔记本本身搜索东西。

现在可以通过 在这里报名 成为中会员,阅读我和其他作家发表的所有故事。如果你这样做,我会得到你的费用的一小部分。欢迎加入我的邮件列表来了解我写作的最新进展。

感谢您的阅读!

Julia 1.8 新增了 3 个你不想错过的功能

原文:https://towardsdatascience.com/3-features-just-added-in-julia-1-8-you-wont-want-to-miss-543d523dfb5d

苹果硅支持,键入全局,等等

作者图片

Julia 1.8 是 GitHub 发布的热门版本,包含了大量有用的新特性。如果你想全面了解所有的新变化,可以看看核心开发团队的发布博客。

在这篇文章中,我将重点介绍上面链接中提到的 3 个让我对这个版本最感兴趣的特性!

改进了对苹果芯片的支持🍎💻

随着越来越多的开发人员开始过渡到使用 Apple Silicon,开源工具在这个架构上开箱即用的需求变得越来越重要。Julia 1.8 解决了许多与以下相关的问题:

Julia 如何在内部使用 LLVM 来生成和链接该平台的代码,并最终在 Julia 1.8 中通过转移到一个更现代的链接器得到解决,该链接器对 macOS 上的 ARM CPUs 有更好的支持。

虽然 Julia 1.8 修复了这些问题和常见的分段错误,但这些问题无法移植到 Julia 1.7,因此该版本将始终存在 Apple Silicon 的问题。如果您正在使用 Julia 1.7,并且遇到了上述任何问题,建议更新到 1.8,因为该版本将 Apple Silicon 更改为第 2 层支持【Julia 1.9 可能会为 Apple Silicon 带来第 1 层支持)。

看到如此多的努力被投入到为苹果硅 Mac 用户获得稳定性是令人敬畏的。作为这些用户中的一员,我在产品化期间遇到了一些棘手的问题,但在大多数情况下,这些问题出现的频率似乎在迅速降低。此外,如果你错过了,Metal.jl 的技术预览,这是在 Julia 中编程苹果 M1 GPU 的包,于 2022 年 6 月底公布,请在 Julia GPU 博客上了解更多信息。

M1 Mac Julia 用户的未来是光明的!

编辑:我和我的合著者很高兴地告诉大家,我们的新书《朱莉娅速成教程》已经开始预售了:

https://logankilpatrick.gumroad.com/l/juliacrashcourse

键入全局⌨️🌎

在以前版本的 Julia 中,不可能指定非常数全局变量的类型。在 Julia 1.7 和之前的版本中,如果您尝试这样做,该语言会给出如下错误:

作者捕获的图像

在这个例子中,我们试图将a的类型设置为Int,但是当我们这样做时,Julia 给出了一个错误。

在 Julia 1.8 中,您可以看到行为已被更新以支持此功能:

作者捕获的图像

1.8 的博文还指出:

类型注释全局变量消除了使用非常数全局变量的大部分(但不是全部)开销。

这听起来很好,因为以前热衷于全局变量的一个核心原因是它引入了大量的计算开销。这个改变应该为新的和有经验的 Julia 用户移除一个小的锋利的边缘!

具有可升级包装指示器的包装状态更新📦

任何读过我之前的文章(比如这篇)的人都知道 Julia 中的包管理器是我最喜欢的特性之一。这确实使在 Julia 中做事成为一种真正的乐趣,因为我可以确信在我的本地计算机上运行时不会有任何奇怪的问题。

在 Julia 1.8 中,与包版本相关的另一个令人敬畏的生活质量改进是可用的。在以前的 Julia 版本中,当你在包管理器中运行status命令时,你会得到你的活动环境中所有包的打印结果。虽然这很有帮助,但如果您想知道应该使用哪个版本的软件包或最新的可用版本,它并不总能提供您所需要的全部信息。

现在在 Julia 1.8 中,包管理器给出了一个可视化的指示,如果有一个新版本的已安装包可用,如果有其他包的版本约束,包版本是否可以成功更新。让我们来看看公告帖子中的这个例子:

图片来自公告帖子

在这里,我们可以看到当我们运行st命令(status的简写)时,我们得到不同类型的向上箭头,表示两种不同的行为。这个新特性将会使你更容易判断一个包是否有新的可用版本,以及你是否有理由不能更新这个包。

如果你想了解更多的背景知识,我建议你阅读完整的博客文章。

Julia 1.8 中其他很酷的东西👀

朱莉娅 1.8 是挤满了吨伟大的功能。我想在这篇文章中强调三个让我特别兴奋的地方。话虽如此,我还是有责任提及一些重要的 JuliaCon 2022 会议,这些会议强调了 1.8 版本中的一些工作。首先,Tim Holy 和 Valentin Churavy 做了一个关于“包预编译方面的改进”的演讲,这是 Julia 1.8 的一部分(实际上我已经在我的另一篇文章“Julia con 2022”中强调了这个视频:

另一个值得一看的视频来自 Nathan Daly 和 Pete Vilter,主题是使用 Julia 1.8 的分配分析器寻找分配,这是 Julia 1.8 中引入的一个新功能:

1.8 中发生了这么多令人惊奇的事情,我只能开始想象 Julia 1.9 中会有什么有用的新特性(希望有更多的包管理器的东西)!请继续关注,请告诉我这个版本中你最感兴趣的特性。

你现在应该学习的 3 门免费机器学习课程

原文:https://towardsdatascience.com/3-free-machine-learning-courses-you-should-take-right-now-7bf4e6b459fe

免费开始您的机器学习之旅

Avel Chuklanov 在 Unsplash 上拍摄的照片

开始学习机器学习有很多方法。我之前写过很多关于如何设计你自己的课程路线图作为上课的替代方案。这种方法允许你从互联网上挑选适合你的学习方式和预算的免费或低价资源。

然而,当你刚刚开始机器学习之旅时,至少跟随一个简短的课程通常是有用的,该课程将首先引导你了解基本概念。这会让你对这个领域有一个很好的基础概述,这将使你更容易设计自己的学习路径,然后继续更深入的自我导向学习。

网上有很多机器学习课程。这些课程从短期课程到更长的 MOOCs(大规模开放在线课程)不等,价格也有很大差异。

我是共享免费学习资源的倡导者,幸运的是,有几个免费的机器学习课程。在这篇文章中,我将分享我最喜欢的三门免费课程。它们对机器和深度学习都有自己的观点,并包含各种内容类型,从视频到实用的编码练习,因此,这三者都值得初学者遵循。

如果你刚刚开始学习机器学习,我建议你开始学习这篇文章中的课程。它们是按照我推荐的学习顺序排列的,我还提供了一些附加资源的链接,这些资源将为您提供最后两门课程所需的必备知识。

1.与机器学习交朋友

来自凯西·科济尔科夫

时长: 6.5 小时

最适合:每个人

核心学科:应用机器学习

最初是作为谷歌的内部课程,于 2021 年通过 YouTube 向公众发布。这既是一个非常有趣的应用机器学习的大画面介绍,也是一个非常实用和初学者友好的指南——任何人都可以理解。

它的目的不是专注于机器学习的理论或实现细节,而是给出核心概念的高层次概述。这使得任何人都可以理解机器学习的概述,而不仅仅是技术人员。

通过学习本课程,您将了解端到端的机器学习过程,获得对可用算法的直观了解,包括如何使用它们,并浏览一些真实世界的机器学习用例。

这无疑是我见过的最好的机器学习课程之一。它涵盖了所有概念的介绍,还涵盖了在现实世界中应用机器学习时常见的陷阱和陷阱。在我看来,这门课程应该是任何在应用机器学习领域工作或打算在该领域工作的人的必修课!

如果你对机器学习完全陌生,我建议你从这门课程开始第一次入门。没有任何先决条件,如知道如何编码,所以这是一个理想的起点。一旦您学习了这门课程,我建议您在继续学习本文后续部分推荐的课程之前,至少要掌握基本的 Python 编程技能。Codecademy 是一个开始学习如何编程的好地方。

2.机器学习速成班

来自谷歌

https://developers.google.com/machine-learning/crash-course

时长: 15 小时

最适合:能够用 Python 编程,并且已经对线性代数和统计有很好理解的学习者。

核心科目:实用机器学习

这个相对较短的课程涵盖了广泛的机器学习主题。它非常实用,大部分机器学习代码都集中在tensor flowAPI 上。

该课程由 25 节课组成,每节课涵盖机器学习的一个特定领域。内容包括视频讲座、书面指南和实践练习。这些练习是一些简短测试的组合,用于检查您对概念的理解以及在 Collaboratory 平台上的实际编程。

该课程涵盖了机器学习背后的许多理论及其实际应用。涵盖的主题包括张量流介绍、模型训练和评估、算法、模型优化、泛化和深入研究神经网络。它还包括一系列机器学习的案例研究和一些围绕问题框架的有用内容,这些内容在这些类型的课程中很少见到。

在您掌握了机器学习背后的高级概念并获得了一些 Python 编程经验之后,这是一门完美的课程。对线性代数和统计有一些了解也是有帮助的,所以如果你需要温习这些科目,先看看 khanacademy.org 的一些课程。

3.面向编码人员的实用深度学习

来自 FastAI

https://course.fast.ai

时长: 7 周

最适合:至少有一年编码经验的学习者

核心主题:深度学习

深度学习是机器学习的一个子集,学习一门更深入该领域的课程是谷歌上述课程的完美后续。FastAI 的“程序员实用深度学习”是对深度学习特别是神经网络的一个很好的介绍。

这门课程的创造者表示,他们的目标是“让尽可能多的人能够接触到深度学习”。它主要是为已经知道如何编写 Python 代码的学习者设计的,重点是通过可用的 Jupyter 指导笔记本提供实用的介绍,以及每个部分的视频。因此,一旦你有了至少一年的编程经验,你应该在以后的学习过程中学习这门课程。

这门课程有一个很好的结构,从包括历史在内的深度学习的高级介绍开始,然后逐渐过渡到更复杂的主题。您将了解如何训练深度学习模型,如何优化它们,以及如何将它们投入生产。

深度学习更专业的领域也在这里有一节关于协同过滤的课和一节关于自然语言处理(NLP)的课。

在这篇文章中,我分享了三个学习机器学习的免费在线课程。这三门课程中的每一门都在相对较高的水平上涵盖了该领域的不同方面,起到了完美介绍的作用。

如果你刚刚开始,遵循本文提供的材料会给你坚实的基础知识,然后你可以建立一个定制的学习路径。这些课程应概括如下:

  1. 与机器学习交朋友(不需要编程)
  2. 机器学习速成班——一个详细的端到端机器学习课程,将教你如何用 Python 编写机器学习模型
  3. 面向程序员的实用深度学习——深度学习的精彩实用介绍

一旦你参加了这些课程,我建议你看一看我的帖子,这些帖子在本文前面有链接,将指导你设计一个完整的学习路径。网上有许多免费或非常便宜的资源,它们将建立在你的数据科学和机器学习知识的基础上。

如果你有兴趣了解更多可用的资源,我之前也发布了一份完整的免费资料列表,这些资料在网上随处可见。

感谢阅读!

3 个你可能不会用到的熊猫群组功能

原文:https://towardsdatascience.com/3-functions-to-use-with-pandas-groupby-that-you-probably-dont-use-724db94327ee

探索更多关于熊猫的知识

杰西·卡森在 Unsplash 上的照片

当使用 Pandas 进行数据分析时,groupby 是最常用的函数之一。它允许根据给定的一列或多列中的值对数据点(即行)进行分组。

假设您有一个汽车数据集,并希望根据平均价格比较汽车品牌。这是一个两步任务。第一个是根据颜色对汽车进行分组,这就是 groupby 函数的用途。第二步是根据要聚合的值应用聚合函数。在本例中,这是通过对 price 列应用 mean 函数来实现的。

(图片由作者提供)

有许多聚合函数可以与 groupby 函数一起使用,如 mean、min、max 和 median。我刚刚列出的是常见的。还有一些功能不是那么常用。你不会经常需要它们,但是在某些情况下这些函数会派上用场。所以,最好了解一下他们。

在本文中,我们将讨论其中的 3 个函数。让我们创建一个样本数据帧用于示例。

import pandas as pd
import numpy as npdf = pd.DataFrame({ "Year": [2021, 2021, 2021, 2022, 2022, 2022, 2022, 2022],
  "Month": ["Jan", "Jan", "May", "Jan", "Feb", "Feb", "May", "Sep"],
  "Qty": np.random.randint(10, 100, size=8)

})df

df(作者图片)

我们有一个 3 列 8 行的数据帧。

1.努尼克岛

顾名思义,nunique 函数返回唯一值的数量。如果与 groupby 函数一起使用,我们可以获得每个组的唯一值的数量。

例如,我们可以在我们的数据框架中找到每年独特月份的数量,如下所示:

df.groupby("Year")["Month"].nunique()**# Output**
Year
2021    2
2022    4
Name: Month, dtype: int64

当然,在处理大型数据集时使用它更有意义。

1.n 最大

nlargest 函数返回一列中的 n 个最大值。n 的值可以用函数的 n 参数来指定。

在我们的数据框架中,我们可以将它与 groupby 函数一起使用来查找每年的最大数量。

df.groupby("Year")["Qty"].nlargest(1)**# Output**
Year   
2021  2    85
2022  5    61
Name: Qty, dtype: int64

2021 年一个月中的最高数量是 85,这是索引为 2 的行。让我们看看现在是几月:

df.iloc[2]**# Output**
Year     2021
Month     May
Qty        85
Name: 2, dtype: object

2021 年的最高数量是在 5 月观察到的。

熊猫还有最小的功能,与最大的功能相反。语法是一样的,所以没有必要为最小的做一个单独的例子。

3.累计

cumsum 函数计算给定列中值的累积和。在处理时间序列或序列数据时,这是一个非常实用的方法。一个典型的例子是计算一年的累计收益或收入。

在某些情况下,您可能希望分别计算不同类别或组的累计总和。我们的数据框架中有一个日期和月份列。我们可以使用 cumsum 和 groupby 函数创建一个列,其中包含每年数量的累积和。

df["cumulative_sum"] = df.groupby("Year").cumsum()df

df(作者图片)

正如我们在上面的截图中所看到的,累积总值从 2022 年重新开始。

我们所做的例子并不是 groupby 函数的典型用例。然而,他们绝对有解决问题的潜力。因此,最好把它们放在你的武器库中。

你可以成为 媒介会员 解锁我的全部写作权限,外加其余媒介。如果你已经是了,别忘了订阅https://sonery.medium.com/subscribe如果你想在我发表新文章时收到电子邮件。

*https://sonery.medium.com/membership

感谢您的阅读。如果您有任何反馈,请告诉我。*

特征工程的 3 个基本过程

原文:https://towardsdatascience.com/3-fundamental-processes-in-feature-engineering-d6b84983754

以正确的方式向模型呈现数据模式

阿克顿·克劳福德在 Unsplash 上的照片

介绍

这篇文章解释了特征工程(FE)中的三个关键过程,你需要知道这三个过程才能正确地将数据模式呈现给机器学习(ML)模型。

特征工程是修改现有特征以增强模型从数据中学习的能力的过程。

有限元在不显著增加计算时间和成本的情况下,显著提高了模型精度。

FE 是数据转换的子集,是数据预处理的关键元素。

数据预处理的层次(图片由作者提供)

在最近的一篇文章中,我详细讨论了数据转换。然而,FE 作为一个子领域很突出。文章的链接如下所示:

本文的主要目的是讨论数据转换的组件。这有助于更好地理解数据科学项目生命周期中的数据预处理步骤。

特征工程的 3 个基本过程

特征工程的基本过程(图片由作者提供)

现在,让我们深入研究 FE 中的主要过程:

1.特征提取

这是从现有要素生成新要素的过程。它是高度特定于领域的,并且很大程度上依赖于你对主题领域的知识。主要思想是创建新的特征,使 ML 模型能够更好地从数据中学习。例如,当预测风力涡轮机的功率输出时,根据原始 X 和 Y 方向风速创建风速大小特征可提供更高的模型精度。

此外,许多 ML 模型处理数字数据,即由整数或小数组成的数据。因此,我们需要对原始的分类数据(由字符串组成的数据)进行编码,以使它们可用于模型。例如,状态变量可以有“开”和“关”类别。

基于特征学习技术,有更高级的特征提取方法。这种方法更加数据驱动、通用和可伸缩。一些例子包括自动编码器集群

2.功能选择

这是为训练过程选择最相关特征的过程。特征选择方法分为三个主要类别,即包装器、过滤器和嵌入式方法。关于特性选择的深入讨论可以在这里找到。

功能相关性的一些衡量标准包括:

相关分析:相关系数衡量两个变量之间的关系,取值在-1 和+1 之间。正相关意味着两个变量同向变动(即一个变量增加,另一个变量增加,反之亦然)。此外,系数越大,变量之间的相关性越强。在特征选择中,选择与目标变量具有更高相关性的特征,因为它们具有更高的预测能力。

样本相关图。原始照片裁剪 w:用户:ImagecreatorCC0 ,via Wikimedia

特征重要性:一些树方法,例如随机森林和梯度提升算法,提供特征重要性分数,其显示每个特征对目标预测的影响。这些分数可以用来选择最相关的特征。更多详情可在这里找到。

特征重要性排序示例。照片由 0xkaywongCC BY-SA 4.0 通过维基媒体提供

互信息:基于对一个变量的了解,测量另一个变量的不确定性的减少。不确定性的减少是因为掌握了更多的变量信息。具有高互信息分数的特征被认为更相关,并被选择用于 ML 建模。更多细节可以在找到

3.特征投影

这是将高维数据映射到低维空间的过程。它通常包括减少馈送给 ML 算法的特征的数量。这是有益的,原因有很多。一个是降低最终模型的复杂性,从而减少过度拟合的机会。另一个目的是减少计算时间和工作量,同时不显著影响模型的准确性。

有两类主要的特征投影技术:

线性投影:这些方法采用特征的线性组合,并且不捕捉两个或更多特征之间的相互作用。一些例子包括线性判别分析(LDA)和主成分分析(PCA)。更多细节可以在这里找到。

非线性投影:这些方法比较复杂,用非线性方程描述。一些例子包括核主成分分析(KPCA)和主曲线。更多细节可以在这里找到

结论

在本文中,我们讨论了特征工程中的三个基本过程,特征工程是数据转换的一个子领域。这些过程是特征提取、选择和投影。提供了在这些过程中使用的不同方法的例子,包括一些资源链接。

我希望你觉得这篇文章很有见地,下次再见。干杯!

你可以通过下面我的推荐链接订阅 Medium 来获得更多我和其他作者的启发性文章,这也支持我的写作。谢谢大家!

https://aolaoye.medium.com/membership

量化对 tinyML 重要的 3 个基本原因

原文:https://towardsdatascience.com/3-fundamental-reasons-why-quantization-is-important-for-tinyml-92df82234b91

实现 tinyML 的尺寸、延迟和可移植性

Vishnu Mohanan 在 Unsplash 上的照片

机器学习(ML)已经成为几十年来的热门话题,在我们生活的方方面面都有成功的现实应用,从健康信息学到商业再到网络安全。将 ML 直接嵌入边缘设备彻底改变了 ML 在物联网(IoT)上的研究和应用,在物联网中,成千上万的 thasounds 微型设备被用来提高现实世界问题解决的生产率和效率;这引发了微型机器学习(tiny ML)的使用,这被认为是人工智能的下一件大事。Tiny ML 是机器学习的高级部分之一,它缩小了深度学习神经网络,以适应微型硬件或嵌入式 AI 处理器,如微控制器或嵌入式 npu,它们包含极小的尺寸(例如,内存 256 KB 和存储 1 MB)。小型廉价机器(微控制器)、超低功耗、小内存、低延迟(即时分析)和嵌入式 ML 算法——是微型 ML 的主要特征。

在收缩过程中,TinyML 利用了一些模型压缩技术,如量化、修剪和知识提炼。今天,我将讨论量子化以及它如何有助于开发 TinyML。

量化是一种优化技术,它将模型参数的精度从 32 位浮点值降低到 8 位(int8) 值,而不影响精度,从而减小模型尺寸,提高可移植性,加快计算速度。通过采用可实现更显著加速的超低(1 位或 2 位)精度缩减,可以执行更积极的压缩以进一步减少内存消耗和计算。然而,超低缩减过程可能会产生量化噪声,导致模型精度的显著损失。量化为开发微小的 ML 提供了三个重要的好处:大小、延迟和可移植性。

尺寸— 量化显著减小模型尺寸,使得在嵌入式设备(如微控制器)上运行 ML 模型。

假设我们训练了一个神经网络并获得了一个最优的权重矩阵,我们必须将这个包含权重的模型保存到某个地方以便进行推理。在常规的微控制器中,我们可能有 256 KB (RAM)的存储器大小和 1 MB 的闪存驱动器存储,而神经网络模型的大小明显大于此。例如,专为在边缘设备上应用而设计的 MoblieNet 模型的模型大小为 16 MB ,有 430 万个参数。因此,考虑到存储容量,将这个庞大的模型直接安装在微控制器上是完全不可行的。在这种情况下,量化可能是一个潜在的解决方案—通过应用量化(32 位浮点到 8 位 int 值),我们可以立即将模型大小减少到 4 倍。

照片由 Jorge RamirezUnsplash 上拍摄

现在,你可以想一想,如果我们能以某种方式将模型尺寸缩小到微控制器的给定 RAM 尺寸,那么我们就可以轻松地适应模型,并充分利用 RAM 的空间。然而,我们应该考虑到,整个内存不应该专用于 ML 任务,因为应用程序由 ML 和非 ML 部分组成。因此,我们应该始终致力于将模型缩小到最小,以便内存为非 ML 作业获得空闲空间。

延迟— 在任何微处理器上执行的浮点运算通常比整数运算慢,因为整数运算可能只需要一到两个周期,而浮点运算可能需要十多个周期。因此,将 32 位浮点转换为 8 位 ineger 系统可以显著提高性能。

与浮点计算相比,整数点计算更便宜(因为它需要更长的计算时间和功耗),因此切换到 int8 系统可以降低微控制器的功耗。一些实验表明,与相关浮点模型相比,MobileNet V1、ResNet V2 和 Inception V3 的量化模型(int8 算法)在 CPU 上的速度快 2-4 倍,体积小 4 倍,推理速度更高。

可移植性——量化提供了另一个重要的好处——可移植性——开发微小的 ML,因为可移植性对于嵌入式系统极其重要。并非所有的嵌入式设备都是同等创建的,因为一些微控制器与浮点运算兼容,而一些则与整数值系统兼容。因此,如果不考虑算法兼容性,任何给定的神经网络都不能直接部署在嵌入式设备上进行推理。人们可以认为量化是 ML 算法的归一化技术。与归一化一样,我们将所有特征的值转换为相似的尺度;量化通过将模型参数转换成整数系统来做同样的事情,这是所有不同嵌入式系统的公共基线。因此,量化可以提供更好的可移植性并实现更好的效率。

杰里米·贝赞格Unsplash 上拍摄的照片

总之,对于在嵌入式设备上开发 tinyML 来说,量化是确保达到所需大小、延迟和可移植性的重要步骤。

阅读默罕默德·马苏姆博士(以及媒体上成千上万的其他作家)的每一个故事。

你的会员费将直接支持和激励穆罕默德·马苏姆和你所阅读的成千上万的其他作家。你还可以在媒体上看到所有的故事—https://masum-math8065.medium.com/membership

快乐阅读!

参考

受 HaevardX 在线课程《TinyML 的应用》的启发

今年将加入 3 个大型 Slack 数据科学社区

原文:https://towardsdatascience.com/3-great-slack-data-science-communities-to-join-this-year-9d1bb1f51682

我在哪里可以与其他数据科学家、ML 从业者和其他数据爱好者建立电子联系

图片由来自皮克斯拜迈克和比约恩·布鲁斯坎普拍摄

简介

自从柯维德·疫情风靡全球已经有两年了。尽管两年后的今天,我们的生活似乎正在回归“常态”,但我想我们都知道世界已经变了。

此外,数据科学家和 ML 从业者的世界已经永远改变了。我们有更多的远程工作机会,但这并不是流行病带来的唯一积极结果。

在此之前,COVID ML 专家会组织现场聚会、黑客马拉松、讲座和会议来会见同行。这实际上在 2020 年 3 月停止,并导致人们用在线活动取代那些活动。在线数据科学社区开始比以往任何时候都要多。

现在事情开始开放,我们开始回到现场聚会阶段,但在线社区的重要性将继续存在。你可以足不出户地与来自世界各地的人交谈、学习和交流思想,这个想法太好了,不容错过。

因此,我想向您介绍三个不同的 slack 在线社区,我是其中的活跃成员。

  1. 数据会谈俱乐部

https://datatalks.club/

松弛环节:https://datatalks.club/slack.html

简短描述:这是最大的数据科学社区之一。创建这个社区的 Alexey Griogorev 是一位了不起的数据科学家、演说家和作家!那里有很多好的教育内容,包括文章、网络研讨会和播客。事实上,我很高兴在那里发表了一个关于利用众包监控模型性能的网络研讨会。

最适合:这个社区适合所有数据科学家和机器学习工程师。如果您只是数据科学领域的初学者,这也是一个不错的起点。

2。 MLOps 社区

https://mlops.community/

松弛环节:https://mlops-community.slack.com

简短描述:顾名思义,这是一个非常适合在 MLOps 工作的人的社区。但是什么是 MLOps 呢?把 MLOps 想成 DevOps,但是专门为机器学习问题设计的。显然没那么简单,但我需要一句话来描述。此外,在这个社区如何开始的背后有一个非常有趣的故事。你可以看看这个社区的创始人 Demetrios Brinkmann 在这次采访中谈论这个话题。

最适合:正在构建或想要构建现实生活中的机器学习解决方案的人。这项工作不仅仅是在笔记本上建立模型。在现实生活中,您需要收集数据,部署和观察生产中的模型。这是一个伟大的社区,分享构建 ML 产品时遇到的挑战的实用技巧。

3。 托洛卡全球社区

https://toloka.ai/community/

松弛环节:https://toloka.ai/community

简短描述:就规模而言,这个社区与前两个社区不可同日而语,但绝对是我个人参与最多的社区。实际上,我主持一些每月一次的聚会,问答环节,以及许多其他常规活动。这个社区围绕着以数据为中心的人工智能方法和名为 Toloka 的注释工具。你将学习如何使用众包为现实生活中的 ML 项目获取数据,并且你将了解以数据为中心的人工智能的一些最佳实践。

最适合:如果你仍然认为你的 ML 模型的数据来自 Kaggle,你迫切需要加入这个社区。这是为每个想学习如何为现实生活中的 ML 产品收集和管理数据集的人准备的。许多内容围绕电子商务、搜索相关性、NLP 以及计算机视觉发展。

总结

我刚刚给了你一些伟大的在线数据科学社区的链接。去那里,与其他数据科学家、ML 工程师和数据爱好者交谈,互相学习,最重要的是玩得开心!不要害羞,给我发一个懈怠的信息。

正如我之前提到的,所有这些社区现在都开始组织一些线下聚会和活动。所以,如果你所在的地方有什么事情发生,请继续关注…

PS:我正在 Medium 和aboutdatablog.com上写文章,深入浅出地解释基本的数据科学概念。你可以订阅我的 邮件列表 在我每次写新文章的时候得到通知。如果你还不是中等会员,你可以在这里加入https://medium.com/@konkiewicz.m/membership

下面还有一些你可能喜欢的帖子

* *

进入数据科学的 3 个重要提示—如果你有计算机科学背景

原文:https://towardsdatascience.com/3-important-tips-for-getting-into-data-science-if-youre-coming-from-a-computer-science-9fe55fa134ad

这种转变可能不像你想象的那么简单。

马库斯·斯皮斯克在 Unsplash 上的照片

更新:查看本文的第 2 部分, 进入数据科学的 3 个重要提示——如果你来自非技术背景

数据科学最近似乎风靡一时,来自学术界和工业界各个角落的人都希望进入这一领域。一个人可以从许多不同的方向进入这个领域,并从由此产生的众多视角中受益匪浅。

也就是说,根据你的背景,为了适应这个主题并成为一名熟练的数据科学家,你必须采取的步骤会有所不同。在本文中,我将讨论一些重要的观点,如果您目前从事计算机科学工作,并希望过渡到数据科学,您应该记住这些观点。

许多人持有一种误解,认为计算机科学和数据科学实际上是同一学科的两个名称;然而,尽管它们可能是相互关联的(即计算机科学是数据科学的一个组成部分 [1]),但它们远非完全相同。

作为一个我自己也经历过这种转变,并且目前在这两个领域的交叉领域工作的人,我可以保证,在这个过程中,你需要学习一些新的技能。下面,我试图把我从自己和他人的经历中总结出的最好的建议包括进来。

让我们开始吧。

1。学习 Python

你可能是这个星球上最有才华的系统程序员,能够在一个周末的时间里用 C 语言构建 Mac 层操作系统,或者向最无知的人解释 RISC-V 的来龙去脉——但是如果你想成为一名数据科学家,你应该花一些时间学习 Python。

现在,我并不是说那些系统或软件工程技能对你没有任何好处。他们当然会——数据科学项目经常涉及构建一个工具或系统来帮助解决手头的问题。然而,很大一部分工作将涉及统计分析、随机模拟和机器学习模型的应用等主题——用 C [2]这样的语言编程是相当具有挑战性的事情。

不管你个人对这种语言的感觉如何,不可否认的是 Python 已经主宰了现代数据科学。虽然学习它并不是绝对必要的(例如,R 是另一种具有数据科学功能的流行语言),但是强烈推荐学习。

对于初学者来说,Python 有大量专门用于帮助数据科学的可用包和模块,包括但不限于 Pandas、NumPy、SciPy、Scikit-Learn、PyTorch 和 Tensorflow。所有这些包都具有广泛的、记录良好的功能,通常作为数据科学课程和训练营的一部分来教授。

此外,你可能会和一个数据科学家团队一起工作。不是每个人都会来自一个密集的计算机科学背景;因此,即使你可以用 C++或 Java 执行你的数据处理和分析,你也可能没有这样做的自由,因为团队的首要任务是确保代码对在场的每个人都是可读和可维护的。

所以就帮自己一个忙,学学 Python 吧。

2.学点统计学

我有一个活动给你:去 LinkedIn,找出一些在顶级数据科学职位上的人——比如机器学习工程的主管首席数据工程师等职位。然后看他们的学位。我敢保证,这些人当中有很大一部分都学过统计学,甚至可能获得了统计学博士学位。

统计学是数据科学的基础要素之一[1],构成了数据科学的大部分理论基础。事实上,在现代数据科学发展之前,许多类似的工作都是由才华横溢的统计学家完成的。为了成为一名成功的数据科学家,你至少需要对统计学有所了解。

如果你有计算机科学背景,你可能处于两种情况之一:

  1. 你正式学习计算机科学作为学位课程的一部分。
  2. 你是一个自学成才的程序员,或者在加入这个行业之前,作为一个短期但密集的新兵训练营的一部分学习了编程。

您的统计方法将因您的类别而异。

如果你属于第一类,那么你很可能在你的学位中学习了某种形式的离散数学。如果是这样的话,那么你已经有了一个好的开始,因为同样的解决问题的技术被用在统计难题中。你不需要发展一种新的思维形式;相反,你应该专注于学习具体的统计概念,这将使你在你选择的领域茁壮成长。根据你想做什么样的工作,有无数的在线课程可供选择(例如,看看这个由华盛顿大学教授开发的人机交互实用统计课程【3】)。

或者,如果你是第二组的成员,除了大学代数,你可能从未上过正式的数学课。你需要学习统计学,但是你可能想从磨练你的数学思维技能开始。理论统计学是一门具有挑战性的学科,如果你首先建立了自己的数学成熟度,你会更好地准备去接近它。

学习统计学可能看起来是一项艰巨的任务,但不要让它阻碍你尝试数据科学。这是我自己仍然在做的事情,并且开始从事数据科学工作绝不需要顶级的专业知识。虽然作为一名数据科学家,这绝对是一项你应该不断努力提高的技能,但是太多的人认为他们必须是数学天才才能成为数据科学家。

在现实中,并不是每个数据科学家都需要高级数学(比如编写尖端机器学习算法所必需的那种)来进行日常工作。然而,至少对统计学有基本的了解会增加你对整个领域的欣赏,并帮助你对你所解决的问题有更敏锐的洞察力。

3.学会欣赏人文

作为大学里的一名 STEM 学生,我花了大量时间在一个对人文学科有着微妙但明显蔑视的社团里。对于计算机科学或工程专业的毕业生来说,因为他们的工资更高,工作前景更有希望,所以他们比社会科学专业的毕业生有一点优越感,这并不罕见。

这种态度渗透到工业和学术界的很大一部分。我的一位同事在大学期间学习了计算机科学和创意写作,他现在使用计算机科学工具来研究在线内容社区中的社会和情感联系。在这两个领域的交汇处工作令他着迷。然而,他经常讲述他参加各种研究生院面试的故事,在面试期间,许多教授坚持认为是时候把他的创造性写作兴趣放在一边,专注于“真正的”计算机科学。

也许你也有这种态度,在一个计算繁重的环境中被动地工作多年。如果是这样,你最好在进入数据科学之前改变它。

作为一名数据科学家,欣赏人文学科至关重要,这有两个主要原因。首先,重要的是要认识到数据科学的一个重要组成部分是领域专业知识[1]。您处理的数据只有在上下文中才有意义,并且在许多情况下,向您解释该上下文的领域专家将是人文学科的成员。如果你想有效地理解数据,你必须尊重领域专家和提供的背景信息。

其次,数据科学的早期工作经常遭遇伦理问题 [5],这是由于对其量化元素缺乏根据的固定。最近,越来越多的人转向一种更加的混合方法【6】,这种方法经常利用社会科学的研究技术,以防止算法偏差并产生更加公平的结果。

长话短说,好的数据科学需要人文学科的帮助,作为一名数据科学家,你也一样。

最后的想法和总结

在我过渡到数据科学时,努力学习上述技能对我非常有帮助,我希望学习它们也能对你有所帮助。作为快速复习,以下是它们的汇总:

  1. 学 Python 。这是现代数据科学语言,不要落后。
  2. 学统计学。这是数据科学的理论基础,不要错过了解基础知识。
  3. 学会欣赏人文。它们是好的数据科学的重要元素——不要让你的自我蒙蔽了你的进步。

祝你好运,下次再见!

想擅长 Python? 获取独家、免费获取我简单易懂的指南点击 。想在介质上无限阅读故事?用我下面的推荐链接注册!

https://murtaza5152-ali.medium.com/?source=entity_driven_subscription-607fa603b7ce---------------------------------------

我叫穆尔塔扎·阿里,是华盛顿大学研究人机交互的博士生。我喜欢写关于教育、编程、生活以及偶尔的随想。

参考

[1]https://towards data science . com/the-three-building-blocks-of-data-science-2923 DC 8 C2 d 78
【2】https://towards data science . com/c-for-data-science-8321d 6509484
【3】http://depts.washington.edu/acelab/proj/ps4hci/index.html
【4】https://towards data science . com/an-an

进入数据科学的 3 个重要提示—如果你来自非技术背景

原文:https://towardsdatascience.com/3-important-tips-for-getting-into-data-science-if-youre-coming-from-a-non-technical-background-74cd201d90d0

尽管还有很多东西要学,但你可能已经在不知不觉中领先了一步。

照片由法比奥Unsplash 上拍摄

这是我之前的文章 的后续,如果你有计算机科学背景,这是进入数据科学的 3 个重要提示。

在现代大数据时代,数据科学正成为一门越来越受欢迎的学科,不断吸引着所有学科的人们。就其本质而言,数据科学是一个跨学科领域 [1],因此它从众多视角中受益匪浅。

仍然有一些基础主题是每个学习数据科学的人都应该学习的,但是您的知识库中缺少的部分会因您的背景不同而有所不同。

虽然许多人持有误解,认为你必须有技术背景才能成为优秀的数据科学家,但这远非事实。数据科学越来越需要具备定性技能的专家来帮助有技术头脑的人。也就是说,如果这是你,为了对数据科学团队做出贡献,你还是应该学会一些技巧。

让我们开始吧。

学习编程

我知道,我知道——我刚才说你不一定要来自技术背景,现在又告诉你要学编程。但是听我说完。

就其核心而言,数据科学不是基于计算机科学,而是基于统计学(你可能也应该对统计学更熟悉一点)。这是数据分析、机器学习等理论的主要来源。来自。

另一方面,编程是一种工具,它使得收集、存储和统计分析现代社会中我们可用的不断增长的数据变得可行。严格地说,要成为一名有效的数据科学家,你不需要了解像编译器和图灵机这样的超级高级编程主题。它对一些数据科学家(即更多地从事数据系统的设计和实现的人)有用吗?当然可以。但那不一定是你。

相反,能够编写和解释至少简单的程序将在两个方面帮助你:

  1. 当您在初级阶段探索数据时,您将能够执行简单的处理和操作任务来更好地理解数据。这让你在与整个团队讨论研究问题或公司目标时处于一个更好的位置。
  2. 如果你以常驻领域专家的身份协助一个统计学家和程序员团队,对编程的基本理解将影响你如何将数据放在上下文中,并提出分析数据的可能方法(如果你对程序如何工作一无所知,你可能会给出计算上不可行的建议)。

因此,虽然你不需要成为一名专家,但至少对编程有一个基本的了解肯定会让你受益匪浅。

我的建议是:从基础 Python 课程开始。它读起来非常类似于英语,并且没有许多其他编程语言的语法怪癖和特性。因此,对于没有编程经验的人来说,它是完美的,而且它还有一个额外的优势,那就是它是数据科学领域中使用的主要语言之一。

从长远来看,学习它会对你有好处。

依靠你的定性技能

如果您来自非技术背景,有两个主要原因可以让您对数据科学做出巨大贡献。

首先,虽然技术人员可能很擅长构建系统和开发模型,但他们通常缺乏将这些工件实际推向世界所需的人际技能。数据科学的很大一部分是以一种清晰的方式向公众传达见解,理想情况下是在认真教育的同时努力打击错误信息。

这就是你——非技术超级明星——的用武之地。如果你是一个有才华的作家或沟通者(这并不一定意味着你每天都做 ted 演讲,这可能只是意味着你是一个有魅力的销售人员,喜欢与人互动),那么在数据科学领域有一个完美的位置适合你。拥有自己的技能,把自己推销成程序员和客户之间的桥梁。

其次,非技术研究技能对于有效的数据科学变得越来越重要。我以前说过,现在我再说一遍: 数据科学讲的不仅仅是数字【1】。对量化数据的盲目迷恋是不道德模型的完美配方,并且具有危险的社会影响。

如果你受过社会科学研究的训练,现代数据科学不会简单地想要你——它极度需要你。你有潜力以更好地适应人类在社会中实际运作的方式来完善数据收集技术和改进现有的分析算法。用我的博士导师的话说,

“你不应该编写一个机器学习算法,然后回顾性地考虑如何使它符合伦理。从数据收集过程的一开始,就要考虑数据的人的方面,并将其构建到核心模型本身中。”

要做到这一点,数据科学需要对定性研究有深刻的理解,而这正是你所能提供的。

学会欣赏 STEM

在我的上一篇文章中,我讨论了有多少技术人员带着微妙的鄙视看待社会科学,因为他们的领域受到普遍关注而觉得自己高人一等。这种观点很早就在大学计算机科学系的走廊里形成,由越来越多沉溺于计算机和代码的学生团体传播。

然而,反之亦然。人文学科的学生(以及最终的毕业生)对 STEM 人群采取以下一种或多种评判态度并不罕见:

  • "他们不能写一篇文章来拯救他们的生命。"
  • “看看他们,痴迷于代码,整日整夜地工作,没有任何放松的时间——这是什么样的生活?”
  • “对他们自己和他们的高端技术公司充满信心。”

在某种程度上,这样的评论是无害的,是一群志同道合的学生之间友谊的沉淀剂。然而,正如我在上一篇文章中提出的技术方面的判断一样,它们隐藏了一点真理。

我并不反对偶尔的玩笑——但我确实建议你把你对 STEM 专业的刻板印象留在那些大学礼堂里。这对你的行业没有任何好处。

数据科学是建立在科学和人文领域的结合上【4】;因此,它需要双方的帮助才能茁壮成长。

学会合作。

额外提示:不要低估自己

我已经在上面简要地暗示了这一点,但是我想明确地强调它,因为它非常重要。

许多非技术人员远离数据科学,因为他们觉得自己不适合某个技术领域。摆脱这种误解:正如我上面所说的,数据科学不是纯粹的技术。

你可能会遇到持有过时观点的人,他们认为数据科学不需要除了数学家和程序员之外的任何人的帮助。不要让他们影响你,相反,向他们展示你能带来多大的改变。

在他们对你的强迫性和虚假的优越感中,他们忽视了这样一个事实:他们自己才是被抛在后面的人。

最后的想法和总结

以下是对上述建议的快速总结:

  1. 学习编程 —一些代码知识将完善你的技能组合,并帮助你更有效地为数据科学团队做出贡献。
  2. 利用你的定性技能组合 —数据科学需要那些能够打击不道德行为并清晰传达见解的人。**
  3. 学会欣赏 STEM——优越感对你没有好处;我们需要一起努力。
  4. ****加成:不要低估自己。

当您开始涉足数据科学时,我希望上面的提示对您有所帮助。祝你好运,下次再见!

想擅长 Python? 获取独家、免费获取我简单易懂的指南点击 。想在介质上无限阅读故事?用我下面的推荐链接注册!

**https://murtaza5152-ali.medium.com/?source=entity_driven_subscription-607fa603b7ce---------------------------------------

我叫穆尔塔扎·阿里,是华盛顿大学研究人机交互的博士生。我喜欢写关于教育、编程、生活以及偶尔的随想。

参考

[1]https://medium . com/mlearning-ai/human-centered-data-science-what-is-it-and-why-it-the-way-forward-e44e 749 Fe 4c 9
【2】https://towards data science . com/how-can-we-make-artificial-intelligence-ethical-6d 26657 c6c 32
【3】https://sitn**

编写良好的数据模型的 3 个关键组成部分

原文:https://towardsdatascience.com/3-key-components-of-a-well-written-data-model-c426b1c1a293

如何编写通过时间考验的高性能模型

杰克·亨特在 Unsplash 上的照片

当我刚开始作为分析工程师的职业生涯时,我的任务是重写我们的商业智能工具中的数据模型。当我开始通读它们时,我震惊地发现它们是不可能理解的,非常有条理,并且使用了糟糕的代码。难怪他们中的一些人要花一天时间来跑步!第一次就构建好数据模型是很重要的,这样你就不必经历重写数据模型的过程。

当构建高质量的数据模型时,您需要记住模块化可读性速度。在优先考虑这三个品质的同时编写模型将有助于您尽可能编写最好的数据模型。我们的目标是让它们永远存在,或者只要业务逻辑保持不变,那么您就可以继续关注公司的其他领域,以提高数据的利用率。

模块性

当您的模型是模块化的时,它可以作为单独的代码段存在,可以在其他地方重用和引用。这意味着您必须编写更少的可重复代码,从而节省您的计算能力。

编写模块化模型时,你要遵循干代码的概念。这意味着您编写尽可能少的代码,同时仍然编写执行您需要的功能的代码。不要重复代码!你的函数简洁、清晰、易读。干代码和模块化数据模型齐头并进。当编写模块化模型时,您需要问自己三个不同的问题:

什么代码在多个型号中重复?

在重写数据模型之前,做一个完整的清单是很有帮助的——或者,如果从头开始,考虑一下重复出现的元素。这将帮助您确定将哪些代码转换成它们自己的数据模型。例如,如果您将用户映射到某个匿名浏览器 cookie,并在您的所有模型中使用这种映射,那么这应该作为一个模型存在,可以在其他模型中重复。

一旦你明白了这一点,你需要问自己, 如何将这些重复的代码拆分成它自己的模型,以便在多个模型中重用?

您需要弄清楚一段代码如何能通用于多个用例。这可能意味着您需要删除特定于一个模型的任何筛选器,或者您需要包含更多在某些(但不是全部)模型中使用的列。

例如,如果订阅的数据模型只过滤用户映射代码中的活动用户,则需要从正在模块化的用户映射模型中删除它。然后,当您在订阅模型中直接引用用户映射模型时,您可以为活动用户添加过滤器。这样,一个同样使用“用户映射模型”,但所有类型的用户都需要它的营销模型,仍然可以引用模块化数据模型。

最后,您需要问问自己,这种模块化模型是否真的可以达到与已经直接构建到模型中的代码相同的目的。从一个更大的模型模块中生成一段代码会改变模型的结果吗?

目标是创建不影响代码输出的模块化数据模型。无论代码是如何分离的,结果数据集应该总是相同的。如果这改变了逻辑,也许它不应该成为自己的数据模型。您不需要强迫每一段代码都成为它自己的模型,只需要在您的所有业务逻辑中真正可重复的代码。

让我们看两个不同的数据模型。第一个映射用户第一次访问网站时的所有个人信息。

WITH users_mapped_to_cookies AS (
   SELECT
    sessions.User_id,
    browser_cookies.Cookie_id,
    Browser_cookies.first_url 
   FROM browser_cookies
   LEFT JOIN sessions 
   WHERE sessions.session_started_at <= browser_cookies.event_timestamp <=sessions.session_ended_at
),

mapped_users_joined_user_details AS (
 SELECT 
  Users_mapped_to_cookies.user_id, 
  Users_mapped_to_cookies.first_url, 
  Users.name,
  Users.email,
  Users.phone 
 FROM users_mapped_to_cookies 
 LEFT JOIN users 
 ON users_mapped_to_cookies.user_id = users.user_id 
)

SELECT * FROM mapped_users_joined_user_details

第二个数据模型将用户的首页访问映射到他们的订单。

WITH users_mapped_to_cookies AS (
 SELECT
  sessions.User_id,
  browser_cookies.Cookie_id,
  Browser_cookies.first_url 
 FROM browser_cookies
 LEFT JOIN sessions 
 WHERE sessions.session_started_at <= browser_cookies.event_timestamp <=sessions.session_ended_at
),

mapped_users_joined_orders AS (
 SELECT 
  Users_mapped_to_cookies.user_id, 
  Users_mapped_to_cookies.first_url, 
  Users.name,
  Users.email,
  Users.phone 
 FROM users_mapped_to_cookies 
 LEFT JOIN orders
 ON users_mapped_to_cookies.user_id = orders.user_id 
)

SELECT * FROM mapped_users_joined_orders

我们将把代码抽出来创建一个单独的模型,而不是在两个数据模型中都有这些映射子查询。然后,我们将在另一个模型的代码中引用这个数据模型,就像这样:

SELECT
  Users_mapped_to_cookies.user_id,
  Users_mapped_to_cookies.first_url,
  Users.name,
  Users.email,
  Users.phone
FROM users_mapped_to_cookies
LEFT JOIN users
  ON users_mapped_to_cookies.user_id = users.user_id

而且,别忘了,the users_mapped_to_cookies代码是作为自己的数据模型存在的!

可读性

如果代码是真正可读的,那么除了代码本身之外,其他人应该能够在没有任何资源的情况下阅读它并准确理解它做了什么。如果你的同事不得不不断地问你关于你写的代码的问题,你可以写得更简洁。如果你发现你的代码不可读,你很可能有一个很好的机会来优化它的性能和成本。

通过利用数据目录、描述、注释和沿袭等工具,代码也可以变得对非技术用户更具可读性。这些都有助于用户理解数据模型的完整上下文。

在为技术用户编写可读代码时,有三件事要记住:

总是评论那些不能直观理解的代码。

如果读者需要更多的知识来理解你的代码在做什么,请在你的代码中注明!经常有大量的研究进入理解业务逻辑和如何正确地编码模型。确保您在代码的注释中捕捉到了这些部落知识。这样,你会记得为什么你做了某事,这将有助于向其他人解释你为什么这样写代码。

我个人喜欢评论我过滤掉的值的含义,为什么我使用了某个连接,甚至从模型的更大意义上来说查询在做什么。当有人审查代码时,这些都是很难理解的事情。通过添加这些注释,您还可以确保您的模型不依赖于构建它们的人的知识。当编写原始代码的人离开公司,你不能再问他们问题时,这特别有帮助。

使用 cte 代替子查询。

子查询因使代码难以阅读而臭名昭著。在更大的模型中很难理解它们的上下文,因为它们使代码变得混乱,难以理解。通过使用 cte,您可以将代码分解成更小的步骤,这些步骤产生自己的输出。

较小的代码块使得在需要时更容易调试。调试子查询的唯一方法是将其转换为 CTE,或者将其完全从模型中取出。如果一段代码不能在不做修改的情况下自行调试,那么一开始就不应该使用它。

人们通常选择 cte 上的子查询,因为他们认为它们更复杂。事实并非如此。cte 和子查询有相似的运行时,但是子查询会无缘无故地使您的代码更加复杂。可读的代码总是优于不必要的复杂性。

使用描述性的名称。

最后,为了让您的模型可读,您需要在 cte 中为表、列和别名使用描述性的名称。那些审查你的代码的人应该确切地理解他们的意思,而不必搜索你的代码的其余部分或询问你。这将使您的模型更容易调试和理解。命名越具体,将来使用数据模型就越容易。

例如,如果您要在一个 CTE 中连接表usersaddresses,您可能希望将其命名为users_joined_addresses而不是user_addresses。这告诉阅读您的代码的人,您正在连接两个表。User_addresses 告诉您用户和地址表正在被使用,但不告诉您它们是如何被使用的。

现在让我们看一个写得很好的数据模型的例子,由于别名、列名和代码注释,它非常易读。

WITH
Active_users AS (
  SELECT
    Name AS user_name,
    Email AS user_email,
    Phone AS user_phone,
    Subscription_id
  FROM users
  --- status of 1 means a subscription is active
  WHERE subscription_status = 1
),
Active_users_joined_subscriptions AS (
  SELECT
    Active_users.user_name,
    active_users.user_email,
    Subscriptions.subscription_id,
    subscriptions.start_date ,
    subscriptions.subscription_length
  FROM active_users
  LEFT JOIN subscriptions
    ON active_users.subscription_id = subscriptions.subscription_id
)
SELECT * FROM Active_users_joined_subscriptions

你可以阅读这个模型,因为它有明确的命名,所以你可以准确地理解它的作用。当命名不太清楚时,注释会准确地告诉审阅者 1 的状态是指什么。

速度

编写数据模型的主要目的之一是加速数据集向数据仓库的交付。通过自动化数据模型来生成可供业务使用的数据集,可以使您的数据在需要时更加可靠和可用。

如果数据模型很慢,需要几个小时才能运行,那么它们就没什么用了。这经常会在业务团队中造成瓶颈。如果业务团队试图根据由您的某个数据模型驱动的仪表板做出决策,他们的速度将会变慢,但这需要一整天的时间来运行。或者更糟的是,他们根本无法利用数据来做决定。

加快数据模型的速度可以简单到在模型开始时删除重复项或过滤掉空值。也可以更复杂,比如用窗口函数代替复杂代码。正如我在开始时提到的,将您的模型分解成更小的、模块化的模型也有助于这一点。

当我重写长时间运行的数据模型时,我看到两个函数被大量使用。首先,我看到了TOP函数与GROUP BY一起使用。这意味着代码必须对所有值进行分组、排序,然后选择每个有序组中的第一个值。这浪费了大量的计算能力。

相反,你可以使用FIRST_VALUE()窗口功能。这允许你PARTITION你的值,而不是使用GROUP BY,然后在每个组内排序。窗口功能选择第一个值要比顶部功能快得多。

以下函数可用于查找学生的最高考试分数:

FIRST_VALUE(test_score) OVER(PARTITION BY student_name ORDER BY test_score DESC)

我也看到有人使用子查询来帮助他们计算一个值的总和或平均值。正如我前面提到的,您总是希望使用 cte 而不是子查询,因为子查询会降低代码的速度。在这种情况下,您可以使用聚合窗口函数来替换子查询中使用的SUMAVERAGE。只需在PARTITION BY后指定您希望分组的列,函数将计算每个组的聚合。

以下函数可用于计算每个学生的平均考试分数:

AVG(test_score) OVER(PARTITION BY student_name)

在这里,您不必包括ORDER BY,因为在查找总和或平均值时,顺序并不重要。

编写持久有效的数据模型

编写良好的数据模型有能力改变您的业务运营方式。它们将允许您的数据团队的工作随着业务的增长而增长,而不是随着业务的增长而被取代。直接在【Y42】等平台中编写的 SQL 模型通过目录和沿袭特性得到了广泛的记录,使它们易于随业务一起扩展。当你用模块化、可读性和速度来构建你的模型时,它们将变得永恒和无价。它们不必每隔几个月就被替换,因为它们使得创建仪表板、报告和调试问题变得非常困难。

虽然牢记这些要点来编写未来的数据模型是很重要的,但是您也希望重新评估您当前已有的模型。他们缺少这些方面吗?你能抽出一些代码来创建一个可以在多个地方使用的模块化数据模型吗?需要给代码添加注释吗?这些都是你在回顾过去写过的东西时可以问自己的问题。现在关注这一点将有助于防止未来的技术债务,并优先考虑健康的数据生态系统。

欲了解更多关于分析工程、现代数据堆栈和 dbt 的信息,订阅我的免费每周简讯

查看我的第一本电子书《分析工程基础知识,一本全方位的分析工程入门指南。

改变我数据科学职业生涯的 3 次讲座

原文:https://towardsdatascience.com/3-lectures-that-changed-my-data-science-career-5b78e02acb30

这是我经常与我的同事分享的三个讲座,并且一直记在我的脑海里

介绍

围绕人工智能有很多令人兴奋的事情。最近,ChatGPT 和 Dall-E-2 等模型的演示引起了不可思议的轰动。尽管这些系统令人印象深刻,但我认为保持头脑冷静,不被兴奋的海洋冲昏头脑变得越来越重要。

以下视频/讲座更侧重于如何思考数据科学项目,以及如何解决一个问题。我发现这些讲座对我的职业生涯非常有影响,使我能够建立有效和实用的解决方案,满足我所工作的公司的确切需求。

#1)大数据中缺失的人类洞察力| Tricia Wang

这个视频有点老,是 2017 年的,但它仍然非常相关。Tricia Wang 是一名人种学家,也是咨询公司 【突发罗盘】 的联合创始人,该公司与财富 500 强公司和科技初创公司合作,从大数据中获取见解。最近[她]联合创立了 CRADL——基于世界经济论坛的密码研究和设计实验室。【1】。

她的演讲主要集中在她与诺基亚及其大数据分析工作的经验,以了解中国的手机市场。她认为,诺基亚错过了一个潜在手机买家的大市场,因为他们的数据收集没有捕捉到重要信息。她的论点不是大数据不好,而是大数据可能被错误地使用,并因此变得具有误导性,尤其是当你忽视它的局限性时。最明显的限制是它无法捕捉(她称之为)“厚数据”。“厚数据”是定性信息,如故事和极其复杂的细节。

为什么这个讲座会改变游戏规则?强调定性数据不可替代,定量数据不篡夺定性数据

好吧,有什么大不了的?一位同事曾经问我“在我们的日常工作中,我们如何根据这些信息采取行动?”我回答说,你可以从定性的方法开始,然后朝着定量的方法努力。在许多 NLP 项目中,我通常从无休止的阅读开始,像一个研究者一样对待问题。只有在我对数据和公司的需求有了深入的了解之后,我才开始解决和提取见解。

我试着指导初级数据科学家去获取哪怕是一个数据点,并把这些数据追溯到源头,然后继续下去!一直追溯到定性数据——这个数据点背后的故事。这不仅是对数据的深入了解,也是对整个系统和企业文化的深入了解。然后,开始问更深层次的商业问题。首先像一个研究者一样思考,在你进入定量部分之前问一些定性的问题。

我如何选择一个数据点进行分析?您可以构建一个非常简单的模型(例如,sci-kit learn random forest,使用 0 超参数调整),然后找到置信度最低的数据点。或者你甚至可以随机选择一个数据点。或者随机抽取 10 或 100 个样本。只要你开始对数据和业务有一个定性的了解,那么你就在正确的轨道上。

#2)构建软件 2 0 堆栈(Andrej Karpathy)

安德烈·卡帕西很可能不需要介绍,但如果你不熟悉,安德烈"卡帕西是人工智能研究小组 OpenAI 的创始成员,他从 2015 年到 2017 年作为研究科学家在那里工作。2017 年 6 月,他成为特斯拉的人工智能总监。卡帕西被麻省理工科技评论评为 2020 年 35 岁以下创新者之一。【②】。

在这次演讲中,他解释了两件事。

  1. AI/ML 只是一种新的编写软件的方式。
  2. 在商业中,你的大部分时间最好花在理解和清理数据上。

我最后的视频/讲座推荐将触及第二项,所以我在这里将重点放在第一项。那么,这说明什么呢' AI/ML 只是一种新的编写软件的方式?‘Andrej 将软件开发分为他所谓的软件 1.0 和软件 2.0。软件 1.0 本质上是任何可以显式编写的程序。例如,如果我想让一个程序说“你好,马特”,给定用户的名字是“马特”,这是一个非常容易编写的程序,因此使用软件 1.0。现在让我们假设我想要一个程序获取一个图像,并确定图像中是否包含一只猫。这是一个非常复杂的问题,明确地写出每一条指令是不可能的。因此,我们没有手动编写所有指令,而是设置了一个程序(利用优化)来为我们编写程序,我们称之为机器学习(ML),或软件 2.0。

随着程序复杂度的增加,我们从软件 1.0 切换到需要软件 2.0。

https://karpathy.medium.com/software-2-0-a64152b37c35【3】

为什么这会改变游戏规则?它本质上是一张如何确定什么是 ML 项目,什么不是的蓝图! ChatGPT 出来了,世界兴奋得爆炸,但我要再次引用我自己的话’尽管这些系统令人印象深刻,但我认为保持冷静,不要在兴奋的海洋中失去理智变得越来越重要。将 BERT 或 ChatGPT 塞进每一个 NLP 项目中是非常诱人的;但是我警告你停下来,沉思,从一张空白的画布开始。企业需要什么?数据是什么样的?伯特还有存在的必要吗?例如,假设企业想知道有多少系统注释提到了 COVID。在查看您的笔记主体时,您可能会发现,当笔记与 COVID 相关时,通常会提到' COVID ,而当笔记与 COVID 无关时,则会排除' COVID '。太好了!当一个非常简单的文本搜索就可以做到这一点时,不需要花费大量的金钱来培训、调整和部署一个庞大的模型。你为公司节省了大量的时间和精力!现在你可以前进了,相信我,在你面前有很多有趣的障碍(所以不要担心你的团队会感到无聊,还有很多需要发现和改进的)。

#3)与 Andrew 就 MLOps 的对话:从以模型为中心到以数据为中心的人工智能

2021 年和 2022 年的新热门术语之一是“以数据为中心的人工智能”,而在这场运动的中心,你会发现吴恩达。安德鲁很可能也不需要介绍,但如果你不熟悉的话,安德鲁" Ng 是斯坦福大学 兼职教授**(之前是斯坦福人工智能实验室* 副教授兼主任 或 SAIL)。Ng 还在 在线教育 领域做出了实质性贡献,作为双方Courseradeep learning . ai的联合创始人。他带头通过他的在线课程向超过 250 万名学生教授“民主化深度学习”。他是世界上最著名和最有影响力的计算机科学家之一,被《时代》杂志评为 2012 年 100 位最具影响力的人 ,以及 2014 年 【快公司】 最具创造力的人。【④】。*

这个视频/讲座详细阐述了 Andrej 的观点,即在商业中,你的大部分时间都花在理解和清理数据上;然后 Andrew 进一步指出**理解和清理数据通常比**对模型性能的影响更大。当你只关注模型而在数据上花费更少的时间时——他将此定义为“以模型为中心”的 ML 方法(,这是过去 20 年来的主要方法)。“以数据为中心”的方法是不去管模型算法,而是试图通过关注清理和提高数据质量来提高性能。这并不是说建模算法不重要,这只是强调了数据清理的力量及其对最终 ML 系统的影响。

这很有趣,因为这绝不是一个新想法。这是一个非常古老的想法。统计学家过去常说“垃圾进,垃圾出”,意思是说,如果你给你的模型输入了糟糕的数据,那么从建模的角度来看,无论你做什么,你的模型都将是垃圾。

事实上,如果你有非常高质量的数据,你不需要那么多数据来建立一个模型。如果您有糟糕的数据,那么您可以 1)收集大量数据,希望冲淡糟糕数据带来的噪音,或者 2)修复/清理您的数据。

在我的职业生涯中,我只在几百行数据上建立了高效的模型。怎么会?我们擦洗、检查和审查我们的数据,直到我们知道我们有可以信任的训练和维持数据集。这并不是说你应该扔掉你所有的数据,大数据是愚蠢的,它只是突出了高质量数据和数据清洗的力量。

我认为这引发了更大的讨论,比如你的基本事实是什么?你拿你的模型和什么做比较?0.76 AUC 对你的坚守组合意味着什么?你的坚持集是你试图建模的清晰而准确的表现吗?如果不是,那么 0.76 AUC 实际上代表什么?我的观点是,你应该对你的顽固分子非常挑剔。如果你不能信任你的坚持者,那你还在做什么?

摘要

如果你把这三个讲座放在一起,你会发现它真的为处理数据科学工作创建了一个完整的框架。从定性回顾开始。了解业务和业务需求。密切了解数据。你需要一个软件解决方案吗?如果是,请确定您是需要软件 1.0 解决方案还是更复杂的软件 2.0 解决方案。即使看起来像是软件 2.0 项目,软件 1.0 解决方案的表现如何?如果您绝对需要一个软件 2.0 解决方案(ML),那么在增加建模复杂性之前,从以数据为中心的方法开始。增加建模的复杂性应该是最后一件事。我将再次声明,随着更新的大型语言模型(LLM)的出现和更新的神经网络架构的出现,我认为保持冷静的头脑,不要在兴奋的海洋中迷失方向变得越来越重要。“你想解决正确的事情,如果你没有解决正确的事情,你想快速学习,这样你就可以更快地朝着正确的方向前进。

结束了

感谢阅读,希望你发现这篇文章很有见地,或者至少引发了一些有趣的想法。快乐学习!

参考

3 个鲜为人知的熊猫函数将与 Groupby 一起使用

原文:https://towardsdatascience.com/3-lesser-known-pandas-functions-to-be-used-with-groupby-2f971d99d95d

这将帮助你充分利用它

凯文·穆勒在 Unsplash 上的照片

groupby 是数据分析中最常用的 Pandas 函数之一。它根据列中的不同值对行进行分组,以便我们可以按组计算聚合值。

groupby 函数只对行进行分组,不进行任何计算。我们需要对 groupby 的输出应用一个聚合函数。在某种意义上,它为我们计算聚合值准备了数据框架。

假设我们有一个包含产品代码、产品类别和价格列的数据框架。为了计算每个类别的平均产品价格,我们按产品类别列对行进行分组,然后应用 mean 函数。

平均值、总和、最小值、最大值和计数是常用的聚合函数。在本文中,我们将介绍 3 个不常用的函数,它们可以和 groupby 一起使用。

如果你想在我发表新文章时收到电子邮件,别忘了订阅。

让我们从创建示例中使用的样本数据帧开始。

(图片由作者提供)

它看起来是这样的:

df(作者图片)

1.军阶

第一个是等级函数,用于根据值的降序或升序来分配等级。

我们可以将它与 groupby 函数一起使用,为每个类别分配一个单独的等级。我们按类别列对行进行分组,然后选择值列。最后,使用升序或降序选项应用排名函数。

(图片由作者提供)

下面是数据帧现在的样子:

df(作者图片)

因为选择了升序选项,所以具有最高值的行在每个类别中排名第一。

2.累计

cumsum 函数计算累积和,因此第一行中的值是第一行和第二行中的值的和。第三行中的值是第一、第二和第三行中的值之和,依此类推。

cumsum 函数可以与 groupby 一起使用,以计算每个类别的累积和。

(图片由作者提供)

下面是数据帧现在的样子:

df(作者图片)

3.扩大

扩展函数提供扩展变换。我们仍然需要一个函数来进行聚合,例如均值和求和。如果它与 sum 函数一起使用,结果将与 cumsum 函数相同。

(图片由作者提供)

让我们看看 cumsum 和 expanding sum 列是否有相同的值。

df(作者图片)

我们还可以使用 mean 和 expanding 函数来计算累积平均值。

(图片由作者提供)

df(作者图片)

“累积平均值”列中的第二个值是“值”列中第一个和第二个值的平均值,依此类推。

如果你正在使用熊猫进行数据分析,groupby 很可能是你最喜欢的函数。我们在本文中介绍的函数肯定会对充分利用 groupby 有所帮助。

别忘了 订阅 如果你想在我发表新文章时收到电子邮件。

你可以成为 媒介会员 解锁我的全部写作权限,外加其余媒介。如果您使用以下链接,我将收取您的一部分会员费,无需您支付额外费用。

https://sonery.medium.com/membership

感谢您的阅读。如果您有任何反馈,请告诉我。

你需要知道的 3 个 Matplotlib 技巧

原文:https://towardsdatascience.com/3-matplotlib-tips-you-need-to-know-1b24e41552d5

定制坐标轴、添加标签并润色您的视觉效果

照片由艾萨克·史密斯Unsplash 上拍摄

Matplotlib 是典型的数据可视化库。然而,图书馆是如此之大,以至于经常很难找到你能用它完成的所有酷的事情。

在本教程中,您将学习三种不同的技巧,帮助您创建漂亮的可视化效果。首先,您将学习如何更精确地设置坐标轴的格式,尤其是在处理日期时。然后,您将学习如何注释您的图表。最后,您将学习如何以《经济学人》的风格添加标题!

让我们开始吧!

创造你的第一个视觉效果

让我们从创建基础视觉开始,看看我们从哪里开始。我们将使用 Pandas 和 NumPy 来生成一个看起来像样本股票信息的数据帧。

创建样本数据并在 Matplotlib 中可视化

让我们来分解一下我们在上面的代码中做了什么:

  1. 我们导入了我们的库,并在 Matplotlib 中启用了 retina 模式
  2. 然后,我们设置一个随机种子,使我们的结果可重复
  3. 我们创建了涵盖日期范围和随机数量的数据框架
  4. 最后,我们使用默认参数绘制数据

让我们看看这个可视化是什么样子的:

我们最初的可视化(来源:作者)

好吧…所以这种视觉效果并不令人振奋!下面我们来分解一下如何通过添加更干净的 x 轴标签来改善。

自定义日期 x 轴标签

Matplotlib 试图找到显示每个轴中的值的最佳方式。然而,这不一定是您想要的数据显示方式。

Matplotlib 提供了大量不同的方法来定制你的坐标轴——你将学习到如何使用定制显示日期以及它们是如何显示的!

为了使这个工作,让我们再得到两个导入:

  1. DateFormatter修改日期的显示方式
  2. mdates能够找到具体的日期

看看下面的代码。我们一会儿将探究发生了什么。

在 Matplotlib 中自定义日期时间刻度。

让我们来分解一下代码在做什么:

  1. 我们创建一个日期格式,使用DateFormatter类显示年份,并使用格式化的'%Y-%n'显示一个月的第一个字母。
  2. 然后我们使用.set_major_formatter()方法,用我们指定的格式来格式化 x 轴上的主要标签
  3. 然后每月用.set_minor_formatter()方法定位并显示

让我们看看现在我们的可视化是什么样子的:

使用日期刻度标签(来源:作者)

我们可以看到,我们的 x 轴现在以我们希望的格式显示了一些更清晰的日期。

在 Matplotlib 中标注数据点

有时你会想把注意力吸引到一个点(或多个点)上。Matplotlib 通过使用.annotate()方法使这变得简单!我们可以选择标签和箭头类型。

让我们来看看如何做到这一点:

注释 Matplotlib 可视化。

在第 27–33 行,我们添加了我们的注释。让我们看看如何实现这一点:

  1. 我们添加了text=参数来修改我们想要使用的文本
  2. 然后,我们选择希望标签指向的位置和希望文本出现的位置。我们在第 24 行和第 25 行定义了这些参数。
  3. 然后,我们使用接受样式字典的arrowprops=参数定义我们希望箭头采用的样式。

让我们看看现在是什么样子:

向我们的 Matplotlib 可视化添加标签(来源:作者)

很棒,对吧?

让我们的土地更漂亮

在这最后一部分,我们将看看如何使我们的视觉效果看起来更加完美。Matplotlib 提供了一个的定制能力。这通常会让人不知所措,所以让我们来看看一些关键功能。

在下面的代码中,我们添加了第 30–41 行来定制我们的视觉效果。

给我们的视觉增添一些光彩。

让我们来分析一下这几行代码在做什么:

  1. 我们从顶部和右侧移除脊柱
  2. 然后我们使用.text()方法来添加标题和副标题

添加文本的过程可能有点启发性。最好的办法就是稍微试验一下,直到你得到满意的结果!

看起来很精致,对吧?与我们开始的地方相比,这是一个巨大的进步!

结论

在本指南中,您学习了如何将 Matplotlib 可视化提升到一个新的水平。因为 Matplotlib 提供了如此多的功能,所以常常不知道从哪里开始。希望这个指南为你提供了一些好的资源,让你开始让你的可视化效果更丰富、更漂亮!

使用 Python Pandas 聚合数据的 3 种方法

原文:https://towardsdatascience.com/3-methods-for-aggregating-data-with-python-pandas-14ceb75b6f6e

熊猫提供最适合你的需求

UnsplashAlp Duran 拍摄的照片

Pandas 是 Python 的一个数据分析和操作库,也是最受欢迎的库之一。我认为它最大的优点是易用性和简洁的语法。

Pandas 在如何执行常见操作方面非常灵活,因此它几乎总能提供完全符合您需求的解决方案。

在这篇文章中,我们将回顾用 Pandas 聚合数据的不同方法。你将看到熊猫如何提供各种方法来完成一项特定的任务。

注:本文原载于 datasciencehowto.com

让我们从创建一个填充了模拟数据的样本数据帧开始。

import pandas as pd
import numpy as np
from random import shufflepg = ["A","B","C","D"] * 25
supplier = ["S1","S2"] * 50
shuffle(pg)
shuffle(supplier)df = pd.DataFrame({
    "product_code": np.arange(1000,1100),
    "product_group": pg,
    "supplier": supplier,
    "price": np.round(np.random.rand(100) * 5, 2),
    "sales_qty": np.random.randint(10, 200, size=100)     
})df.head()

df 的前 5 行(图片由作者提供)

我们使用 NumPy 来生成带有随机数的数组。产品组和供应商列是用 Python 列表创建的。为了增加随机性,内置随机库中的洗牌模块用于洗牌。

1.直接使用聚合函数

显而易见的方法是使用集合函数,如均值、中值、最小值等。

df.mean()**# Output**
product_code    1049.5000
price              2.6519
sales_qty        103.5300
dtype: float64

在这种方法中,Pandas 只计算数字列的聚合值。但是,在未来的版本中将不推荐使用此功能,并且此操作将生成类型错误。因此,建议首先选择感兴趣的列,然后进行聚合。

df[["price","sales_qty"]].mean()**# Output**
price          2.6519
sales_qty    103.5300
dtype: float64

虽然产品代码列是数字,但我们不能真正谈论平均产品代码,所以我们不选择它。

2.具有应用功能的多个聚合

我们有时需要在一次操作中计算多个聚合。这可以通过向 apply 函数传递一个函数列表来实现。

df["price"].apply(["mean","median"])**# Output**
mean      2.6519
median    2.8550
Name: price, dtype: float64

如果多个列上有多个聚合,apply 函数将返回一个数据帧,其中包含索引中的函数名。

df[["price","sales_qty"]].apply(["mean","median"])**# Output**

(图片由作者提供)

如果要对不同的列应用不同的聚合函数,可以使用 Python 字典,如下所示:

df[["price","sales_qty"]].apply(
   {"price":"mean","sales_qty":"median"}
)**# Output** price          2.6519
sales_qty    102.5000
dtype: float64

我们在输出中看到的值是价格列的平均值和销售量列的中值。

3.agg 功能

一次计算多个聚合的另一种方法是 agg 函数。

df[["price","sales_qty"]].agg(["mean","median"])

这一行代码与上面的 apply 函数产生相同的输出。

agg 函数还允许为聚合列分配定制的名称。这里有一个例子。

df[["price","sales_qty"]].agg(
    avg_price = ("price","mean"),
    max_price = ("price","max"),
    median_sales_qty = ("sales_qty","median")
)**# Output**

(图片由作者提供)

要聚合的列和聚合函数写在一个元组中。输出是只填入相关值的数据帧。

当与 groupby 函数一起使用时,命名聚合会很方便。我们来做一个例子。

df.groupby("product_group").agg(
    avg_price = ("price","mean"),
    max_price = ("price","max"),
    product_count = ("product_code","count"),
    avg_sales = ("sales_qty","mean")
)**# Output**

(图片由作者提供)

奖励:描述

describe 函数计算以下聚合和统计数据:

  • 数数
  • 意思是
  • 标准偏差
  • 25%(第一个四分位数)
  • 50%(第二个四分位数或中位数)
  • 75%(第三个四分位数)
  • 最大

从最低到最高排序时,25%的值低于第一个四分位数,50%的值低于第二个四分位数,依此类推。

describe 函数可以应用于一列或一组列。我们也可以直接在数据帧上使用它。

df[["price","sales_qty"]].describe()**# Output**

(图片由作者提供)

describe 函数提供了数字列的概述。对于探索性的数据分析是相当有用的。

你可以成为 媒介会员 解锁我的全部写作权限,外加其余媒介。如果你已经是了,别忘了订阅https://sonery.medium.com/subscribe如果你想在我发表新文章时收到电子邮件。

*https://sonery.medium.com/membership

感谢您的阅读。如果您有任何反馈,请告诉我。*

3 项最有价值的数据科学技能让我的薪水增加了 60%

原文:https://towardsdatascience.com/3-most-valuable-data-science-skills-that-increased-my-salary-by-60-89b4bbe0b34f

提示:机器学习不是其中之一

杰森·霍根在 Unsplash 上的照片

请务必点击 订阅此处 千万不要错过另一篇关于数据科学指南、技巧和提示、生活经验等的文章!

当我第一次开始学习数据科学时,有太多的主题和技术需要学习,以至于决定学习什么以及以什么样的顺序学习常常让人感到不知所措。

回顾过去,我可以肯定地说,我学到的某些技能比其他技能更实用、更有用。在这篇文章中,我想和你分享三个技巧,它们最终加速了我的职业生涯,并在过去的一年里让我的薪水增加了 60%。

我将大部分功劳归功于这三项技能的原因是,这三项技能让我能够完全自主地工作,帮助我发现具有难以置信的商业价值的见解和想法,并让我能够更快地交付结果。

说了这么多,让我们开始吧!

1.构建高效的数据管道

什么

数据管道开发指的是管道(或系统)的开发,这些管道将数据输入清理并转换为所需的输出。我特别指的是 ELT 或 ETL 过程的转换步骤,在该步骤中,数据在原始数据被获取之后被转换。

这种方式因公司而异,取决于他们的技术组合。在我的公司,我们使用 Airflow 来调度查询和构建 BigQuery 表。

为什么

  1. 构建数据管道的能力可以帮助您更快地构建模型。在我工作过的每家公司,我的模型所需的数据从来都不完美。要么现有的表有错误(例如,重复的行),要么现有的表不是我想要的格式(例如,基于事件的表需要在用户级别)。通过能够在没有他人帮助的情况下构建我所需要的表格,我能够比需要等待他人的情况下更快地构建模型。更快地构建模型意味着粉碎更多的项目,并进一步提高底线。
  2. 构建数据管道的能力可以帮助企业用户实现数据的民主化。建设管道不仅对自己有用,对别人也有用。在我的职业生涯中,我找到了构建表格的机会,这些表格对我的模型有用,对特定团队和部门的分析和报告也有用。这帮助我与业务中的其他团队建立了更牢固的关系,并最终改善了我的融洽关系。
  3. 建立数据管道的能力允许你设计新的功能。通过构建数据管道,您可以更好地理解正在处理的底层数据。这帮助我想到了有创意和有影响力的功能,如果我不与数据密切合作,我就不会想到这些功能。由于我能够提出如此新颖的功能,我的模型的性能得到了显著提高。这让我想到了我的下一个技能…

请务必 订阅此处 千万不要错过另一篇关于数据科学指南、诀窍和技巧、生活经验等的文章!

2.特征工程

什么

简而言之,功能工程指的是创建新的功能,这些功能并不是显式可用的。例如,如果我有用户的出生日期,我可以使用用户的出生日期创建一个名为“年龄”的新特性。

为什么

  1. 特征工程允许您显著提高模型的性能。根据我的经验,决定我的模型强度的首要因素是设计具有高预测能力的特征的能力。这最终导致更好的预测和更好的针对性。
  2. 工程强大的功能可以帮助你更好地理解你的数据和业务整体。通过设计具有高预测能力的相关功能,您可以更好地了解不同变量之间的关联,从而更好地了解推动业务发展的因素。

3.深潜

什么

深入分析是对感兴趣的问题或主题的广泛调查或分析。

它本质上可以是调查性的或探索性的。调查性的深入分析回答了诸如“为什么上个月销售额下降了 25%?”这样的问题而探索性的深入研究可能会回答诸如“更高水平的应用参与度是否与更有利可图的用户相关联?”

为什么

  1. 深度分析让你发现黄金机会。我所说的“黄金机会”是指那些不会立即显现,但会对业务产生重大影响的东西。这些事情会引起高管们的注意,并因此受到表扬;)
  2. 深入分析让您更好地了解您正在处理的产品和数据。由于您直接处理数据,因此您通常会在各自领域获得最高水平的专业知识。这让你更有见识,更有价值。
  3. 深度分析帮助你减少错误,让你的工作更彻底。深潜并不容易。当你不知道自己不知道的东西的时候,尤其困难。然而,进行彻底深潜的能力会让你成为一个更好的工作者。它会提高你的好奇心,让你更细致,帮助你更全面地学习。

感谢阅读!

请务必 订阅此处 千万不要错过另一篇关于数据科学指南、诀窍和技巧、生活经验等的文章!

不确定接下来要读什么?我为你挑选了另一篇文章:

还有一个:

-特伦斯·申

3 必须了解数据可视化原理

原文:https://towardsdatascience.com/3-must-know-data-visualization-principles-a203745867eb

你的数据有故事可讲

艾萨克·史密斯在 Unsplash 上拍摄的照片

简介

你的数据里有故事。作为分析师,你可能已经知道这个故事是什么了。但是你怎么把这个消息传出去呢?最重要的是,你如何确保你的听众会根据你的叙述采取具体行动?数据可视化是您分析之旅的最后一步,它将帮助您讲述故事并将其转化为决定性的措施。

但是讲述一个引人入胜的故事并非易事。像任何其他类型的交流一样,数据可视化的关键挑战是识别您的消息中哪些元素是信号——您想要交流的信息,哪些是噪音——污染您消息的不必要信息。

考虑到这一点,你的主要目标是以突出重点的方式向观众展示内容,排除任何干扰。

您可能已经花了很多时间来理解、清理和建模您的数据,以得出一个值得分享的结论。所以,不要让这最后一步妨碍你正确传达你的关键见解。

数据可视化中的内存

你上一次参加演示会,看着一系列图表,然后想:“我不知道我应该看什么”是什么时候?这都与你的记忆方式有关。

🧠记忆的三种类型

标志性记忆真的很快。通过你标志性记忆的信息只能持续几分之一秒。图标记忆基本上是视觉刺激的闪存,它将决定你的大脑是丢弃它还是将其转移到你的短期记忆中。

虽然你短期记忆中的信息可以持续几分钟,但它的容量是有限的。你的短期记忆只能同时处理有限的数据,很快就会饱和。同时向你的观众扔太多的信息,这就是你会失去他们的注意力的地方。

当信息离开你的短期记忆时,你的大脑要么永远失去它,要么把它转移到你的长期记忆中,在那里它会把信息储存更长的时间。

在讲述你的故事时,你要尽可能地利用你的听众的标志性记忆,让他们不用处理他们有限的短期记忆中的数据。

所以,下次当你在即将到来的同事的演示中感到失落时,不要责怪自己。要怪就怪你的短期记忆吧。

1.前注意属性

前注意属性是触发你的大脑快速处理信息的视觉特征,不需要你的意识动作。这一切都发生在你标志性的记忆中。

虽然一开始看起来像是一个模糊的概念,但是这些预先注意属性的力量是相对容易证明的。为此,请看下面的序列,并计算数字 9 出现的次数。

串行处理

正确答案是五。但是在这个例子中,没有可以帮助你得出这个结论的视觉指示。你必须一个一个地扫描每个数字,看它是不是 9。

让我们以完全相同的顺序重复同样的练习,但是现在,让我们看看当我们做出一个视觉变化时会发生什么。

前注意加工

因为我们改变了这些数字的颜色强度,它们现在明显地突出来了。突然,你面前出现了五个 9。这是前注意加工和图像记忆在起作用。

现在让我们看看如何在数据可视化中集成这个概念,使用下面的例子,分析订单数和销售额之间的相关性。

请注意,在没有任何视觉指示的情况下,您是如何独自处理所有信息的。你也许能从这张图表中找到自己的见解,但你必须好好利用你的短期记忆,这需要时间。

现在看看当我们将前注意属性包含到同一个图中时会发生什么。

通过修改这四个数据点的色调,你可以让它们变得突出,现在你可以清楚地看到你在前面的例子中可能错过的图案。

前注意加工是一个非常强大的概念。在数据可视化中正确使用它可以让你的观众在意识到他们正在看之前就看到你想让他们看到的东西。

2.洞察时间到了

洞察时间对应于从图表或可视化中获得洞察力所需的时间。越低越好。你想让你的观众尽快从可视化中获得洞察力。

饼图是一个很好的例子来说明这个概念,虽然它们仍然被广泛使用,但你真的想远离它们。

是洞察的时候了📈

使用上面的饼图示例,您可以注意到,从这种类型的图表中获得洞察力所需的时间非常长。你需要在切片和图例之间来来回回才能理解它。在这里,你让你的观众努力工作来获得你的信息。

现在,让我们看看如何改进它,并缩短洞察时间。

洞察时间缩短📉

将你的可视化转换成一个简单的水平条形图,瞧!你的眼睛自然地扫视每个国家。他们不需要像上一个例子那样在图表中移动。

想要将观众的注意力集中在表现最佳的欧洲市场上吗?你可以使用上面提到的前注意属性概念来进一步减少洞察的时间。

你的观众现在开始看到你的故事了。他们只花了几秒钟。

3.数据-油墨比

图形中用于数据的墨水份额越大,效果就越好 —爱德华·塔夫特

你的图表是用墨水做的。有些墨水代表重要的东西,有些则不重要。爱德华·塔夫特的书,定量信息的可视化展示,介绍了数据-墨水比率的概念,即你应该尽可能多地将墨水用于数据。换句话说,你应该消除所有不必要的信息,这些信息会分散你的观众对你想要传达的信息的注意力。

为了在你的图表中最大化你的数据-墨水比率,你应该问自己,'如果这个被消除了,数据会遭受任何损失吗?'如果答案是‘T6’否,‘摆脱它。

花点时间看看下面的组合折线图,测量两个关键的移动应用性能指标。

让我们看看如何通过几个步骤最大化数据-墨迹比。

通过应用一组简单的动作,你已经消除了图表中的所有噪音,降低了你的观众的认知负荷。你的信息现在能更快地影响他们。

结论

作为一名分析师,你可能会认为你的职责仅限于发现隐藏在数据中的故事。但是,确保你的故事与你的观众保持一致往往会使一个好的分析师和一个伟大的分析师之间的差异。为此,请尽量利用好这三个概念:

  1. 通过使用预先注意属性,利用他们的标志性记忆,帮助你的观众关注你的故事的要点。
  2. 总是问自己,“为这张图表绘制洞察力需要多长时间?”“还能改进吗,”大多数时候,答案是肯定的。所以保持简单。
  3. 只保留对你的信息至关重要的数据,去掉其余的。并不是所有的可视化信息都同样重要。有时候,少即是多。

这些简单的概念将帮助你创造简洁明了的视觉效果,让你的观众更容易获得你想要传达的洞察力,并将你的故事转化为具体的行动。

如果你必须记住上面的一件事,这里是最重要的一点:

最重要的是展示数据——爱德华·塔夫特

除特别注明外,所有图片均为作者所有。

参考

南少数,给我看数字:设计图表启发(第 2 版。)(2012)分析出版社

名词(noun 的缩写)C. Knaflic,《用数据讲故事:商业专家数据可视化指南》(第 1 版。)(2015),威利

E.R. Tufte,定量信息的视觉显示(第 2 版。)(2001),图形出版社

你应该知道的 3 个不常见的熊猫把戏

原文:https://towardsdatascience.com/3-not-so-common-pandas-tricks-you-should-know-b26cc7536291

充分利用熊猫

约书亚·钟Unsplash 上的照片

如果你正在读这篇文章,你一定听说过或用过熊猫。因此,我跳过了谈论大熊猫有多棒的部分。😊

在本文中,我们将通过例子展示一些不常用的熊猫功能。在我三年的熊猫之旅中,我并没有经常遇到它们。

学习熊猫或者其他软件工具的最好方法是练习。这就是我们要做的。第一步是创建一个样本数据框架。

import numpy as np
import pandas as pddf = pd.DataFrame({

   "date": pd.date_range(start="2021-11-20", periods=100, freq="D"),
   "class": ["A","B","C","D"] * 25,
   "amount": np.random.randint(10, 100, size=100)})df.head()

df 的前 5 行(图片由作者提供)

我们有一个 3 列 100 行的数据帧。date 列包含 100 个连续的日期,class 列包含 4 个与 object 数据类型一起存储的不同值,amount 列包含 10 到 100 之间的随机整数。

1.至 _ 期间

我们使用具有许多不同间隔或周期的日期,例如日、周、月、季度等等。使用哪一种取决于手头的任务。例如,在收入仪表板中,我们可能希望显示月收入或季度收入。

在 Pandas 中,操作日期的函数在 dt 访问器下可用。to_period 函数允许将日期转换为特定的时间间隔。我经常使用的周期是月和季度。

month 方法仅返回月份,这在许多情况下没有用,例如报告历史收入。我们需要能够区分 2020 年 12 月和 2021 年 12 月。这可以通过在 to_period 函数中使用“M”句点来实现。同样,我们可以用“Q”提取季度信息。

让我们为年-月和季度创建新的列。

df["month"] = df["date"].dt.to_period("M")
df["quarter"] = df["date"].dt.to_period("Q")df.head()

df 的前 5 行(图片由作者提供)

让我们也检查一下数据框架中不同的年-月和季度值。

df["month"].value_counts()**# output**
2021-12    31
2022-01    31
2022-02    27
2021-11    11
Freq: M, Name: month, dtype: int64--------------------------
df["quarter"].value_counts()**# output**
2022Q1    58
2021Q4    42
Freq: Q-DEC, Name: quarter, dtype: int64

2.累计和分组

累积是熊猫非常有用的功能。它计算列中值的累积和。我们通常是这样使用它的:

df["cumulative_sum"] = df["amount"].cumsum()df.head()

df 的前 5 行(图片由作者提供)

现在,我们得到了“金额”列中值的累积和。但是,它不考虑类。在某些情况下,我们可能需要分别计算不同类别的累计和。

谢天谢地,熊猫让这个任务变得非常简单。我们只需要按类列对行进行分组,然后应用 cumsum 函数。

df["class_cum_sum"] = df.groupby("class")["amount"].cumsum()

让我们确认一下 a 班的成绩。

df[df["class"]=="A"].head()

(图片由作者提供)

“类累积和”列包含为每个类单独计算的累积和值。

3.类别数据类型

我们经常需要处理分类数据,这些数据具有有限的、通常是固定数量的可能值。在我们的数据框架中,class 列是一个具有 4 个不同值的分类变量:A、B、C、d。

默认情况下,该列的数据类型变为“object”。

df.dtypes**# output**
date              datetime64[ns]
class                     object
amount                     int64
month                  period[M]
quarter            period[Q-DEC]
cumulative_sum             int64
class_cum_sum              int64

Pandas 还有一个“category”数据类型,它消耗的内存比 object 数据类型少得多。因此,最好尽可能使用 category 数据类型。

让我们复制 class 列,但是使用“category”数据类型。

df["class_category"] = df["class"].astype("category")df.dtypes**# output**
date              datetime64[ns]
class                     object
amount                     int64
month                  period[M]
quarter            period[Q-DEC]
cumulative_sum             int64
class_cum_sum              int64
class_category          category
dtype: object

我们现在可以比较 class 和 class_category 列的内存消耗。

df.memory_usage()**# output**
Index             128
date              800
class             800
amount            800
month             800
quarter           800
cumulative_sum    800
class_cum_sum     800
class_category    304
dtype: int64

class_category 列消耗的内存不到 class 列的一半。相差 496 字节,不算多。然而,当我们处理大型数据集时,这种差异肯定会很重要。

你可以成为 媒介会员 解锁我的全部写作权限,外加其余媒介。如果你已经是了,别忘了订阅https://sonery.medium.com/subscribe如果你想在我发表新文章时收到电子邮件。

感谢您的阅读。如果您有任何反馈,请告诉我。

在编写 Python 代码之前,您应该计划好它的 3 个有力理由

原文:https://towardsdatascience.com/3-powerful-reasons-you-should-plan-your-python-code-before-you-write-it-dcedd4b3bf28

规划代码比你想象的要重要得多。

照片由 UX 印尼Unsplash 拍摄

如果你是一个狂热的 Python 用户,你可能很熟悉那首著名的诗,“Python 的禅”它是由 Tim Peters(该语言的原始开发者之一)编写的,可以通过在 Python 解释器中键入命令import this来完整阅读。

我不会用整首诗来淹没你,但是如果你好奇的话,你可以看看我之前关于这个话题的文章

就本文而言,我想让你注意这首诗中的以下两行:

如果实现很难解释,这是一个坏主意。
如果实现容易解释,可能是个好主意。

对大多数人来说,最突出的词是“实现”、“困难”、“容易”、“坏”和“好”。但我认为,这幅对联中最重要、最有影响力的词完全是另外一个词:解释

在编写代码 之前解释代码 的能力是一项被低估的技能,尤其是在学习编程的早期阶段。回想我读大学的时候,有很多学生编程很好,但却写不出一个合适的句子来拯救他们的生命——最糟糕的是,他们觉得这是完全可以接受的。

不管你是想继续做程序员还是想进入管理型的角色,养成规划代码的习惯从长远来看只会有利于你的职业生涯。

记住这一点,让我们来看看你应该学会解释你的代码的三个强有力的理由,并且解释好它。

1.作为一名数据科学家,你将在工作中获得优势

如果你通过传统的学术项目学习计算机科学,在第三或第四节课之前,你通常需要提交设计文档和项目。

这是一个详细的文档,通常没有任何代码,而是由您最终将编写的代码的高级描述组成。更具体地说,一个好的设计文档具有以下一个或多个特征:

  • 最终系统总体目标的概述
  • 多个地图和图表详细说明了该计划的不同部分将如何组合在一起
  • 相当详细的伪代码,描述了你将使用的数据结构和算法,但没有展示实际的代码。

学生们被要求这样做是有充分理由的:在开始编码之前,野外的软件工程师几乎总是要写一份设计文档。

不幸的是,作为一名数据科学家,您可能没有意识到这是编程的一个方面。由于数据科学家倾向于将编程作为一种工具(而不是他们工作的最终目的),大多数人要么非正式地学习,要么在不太专注于传统软件工程的课堂上学习。

如果你,一个数据科学家,能学会很好地规划你的代码,你就能在你的职业生涯中获得有意义的帮助。出于多种原因(正如我们将在下面看到的),有效的规划提高了最终的代码质量。

成为一名有竞争力的求职者可以归结为一个简单的问题:你能提供一套很难获得的受欢迎的技能吗?

软件工程师可以很好地设计系统,但大多数人不具备成为数据科学家的专业知识。数据科学家知道他们的统计数据,但通常编程能力有限。

两个都精通。变得令人向往。

2.你将避免极其恼人的错误

今年早些时候,我是大学里一个数据科学入门班的助教。它是为有一点编程经验,但还没有处理过复杂数据结构或更大程序的学生设计的。

在课程结束时,学生必须完成他们自己选择的期末项目,主要包括对他们感兴趣的数据集进行程序化分析。作为他们最初提案的一部分,他们需要提交一份他们预计在项目的每个部分(收集数据、编码、撰写最终报告等)花费的时间的粗略分类。).

不可否认,看到这些结果有点好笑。许多学生以前没有编写过大型程序,天真地表示他们预计只花 6-8 个小时来编写所有的代码。我警告他们这是一个严重的低估。

我是怎么知道的?嗯,我(和许多同事)曾参与过许多项目,仅仅是修复一个单曲的 bug 就花了 8 个多小时。

尽管像这样的语法错误通常是不可避免的(例如,在某个地方缺少一个字符,导致计算错误,但没有错误),但在许多情况下,只要稍微做好一点计划就可以避免这些错误。这些都是逻辑错误导致的 bug。

简而言之,算法通常很复杂,如果你试图直接把它们写成代码,很可能你会在不知不觉中出错。然后,当您的最终程序不工作时,您将经历地狱般的痛苦,试图找出哪里出了问题。

或者,如果你首先用人类语言绘制出你的算法,你可以在写任何实际代码之前确保每个部分都是正确的。然后,让你的程序工作就变成了一个简单的翻译问题。

这个过程可能看起来像是额外的工作,但从长远来看,它只是让你的生活更轻松。相信我。

3.您将开发更易维护和扩展的代码

这是一个大的。许多编程新手经常没有意识到一个非常重要的事实:你的代码需要对其他人有意义。

不仅仅是你的同事。如果你必须满足的只是他们,你就有可能摆脱不必要的复杂代码,因为你可以亲自向他们解释。我不是说这是好的或值得推荐的,但这是可能的。

然而,你不可能永远呆在一份工作上——但是当你可以离开的时候,这个项目必须留下来。总有一天,有人会拿出你多年前写的代码,这些代码你已经记不起来了,甚至你自己都认不出来了。

当那一天到来时,两件事之一将会发生:

  1. 他们将花费数小时解析一堆难以理解的变量、关键字和函数。
  2. 他们将阅读附带的设计文档,并很快理解代码作为一个整体意味着什么,以及它的各个部分如何协同工作。

通过在项目的早期阶段努力编写有效的设计文档,您立即为其他人轻松维护和扩展您的代码打下了基础。这一举不仅让你自己受益,也让其他程序员和整个公司受益。

还需要我多说吗?

最终想法+总结

如果你有没有任何计划的直接编码的习惯,是时候做出改变了。这里有一个这样做的原因的快速提示:

  1. 职业积分。如果你是一名数据科学家,掌握正确规划代码的技能将会让你在同事中占得先机。
  2. 安心。通过在早期阶段设计和检查准确性——当你的数据结构和算法仍然是人类语言的时候——你将减少以后遇到令人讨厌的错误的机会。
  3. 好处多多。好的规划=好的代码。这反过来又转化为快乐的同事、快乐的未来员工和快乐的公司。写设计文档。传播快乐。

祝你的编程事业好运!

想擅长 Python? 在这里 获得独家、免费获取我简单易懂的指南。想在介质上无限阅读故事?用我下面的推荐链接注册!

https://murtaza5152-ali.medium.com/?source=entity_driven_subscription-607fa603b7ce---------------------------------------

数据科学教育全国研讨会的 3 个重要收获

原文:https://towardsdatascience.com/3-powerful-takeaways-from-the-national-workshop-on-data-science-education-8552c9c52cd5

随着这个领域的繁荣,我们可以做很多事情来造福无数的学生。

美国宇航局在 Unsplash 拍摄的照片

“哦,我不知道你可以获得数据科学博士学位。我认为那些部门还不存在。”

“嗯,确实如此。从技术上来说,我的部门是以人为中心的设计和工程,但我主要关注数据科学和计算机科学问题,由我的顾问指导。”

上周,我参加了由加州大学伯克利分校主办的国家数据科学教育研讨会,加州大学伯克利分校是该领域的学术领袖。在那里,我与各种各样以这样或那样的方式致力于数据科学传播的人进行了一系列有趣的对话。

上面是这样一段对话的一小段。发表这一评论的教授说得有道理——这使得会议的总体目标更加重要。

截至目前,还没有大量的数据科学部门。大多数人,甚至是那些在大学学习数据科学的人,都住在计算机科学、信息科学、统计等部门。在某种程度上,这是明智的,因为数据科学本身位于许多不同领域的交叉点

也就是说,随着整体技能变得更加令人垂涎,学术机构也更倾向于“正式”教授这一技能。在接下来的几年里,我们可以预计高中和大学级别的数据科学教育将会有很大的发展。

随着这种扩张的发生,我们必须注意这些项目是如何构建的,从过去的错误中吸取教训,以确保未来的成功。在本文中,我讨论了我从参加国家数据科学教育研讨会中得出的三个主要想法,我个人认为这对于设计数据科学课程非常重要。

让我们开始吧。

导论课的重点:理论与实践

加州大学伯克利分校的数据科学入门课程名为 Data 8:数据科学基础。这是校园里最大的课程之一,吸引了各种背景的学生——特别是因为它假定没有编程经验。多个系的全体教员花了许多年时间设计这门课程,使其尽可能影响深远和有效;因此,这是研讨会第一天的主要讨论点。

Data 8 的一个关键特征是,它的核心理念对一些人来说是有希望的,对另一些人来说是毁灭性的:有效的数据科学最初可以在没有底层统计的深入理论知识的情况下教授。Data 8 教授学生使用计算作为工具来处理和分析大型数据集,同时根据需要介绍统计概念。

这带来了一系列好处:

也就是说,这种范式并非没有反对意见。许多铁杆统计学家认为,这种教学方式是危险的,因为它试图在不存在的基础上建立一整套技能——类似于在基础之前建造金字塔的顶部。没有成功的机会。

虽然我可以理解这些情绪(作为一个喜欢数学的人),但我认为它们有点过激。这并不是说学生永远也学不到数据科学背后的统计学和数学。金字塔的两半分别在地面上建造,稍后会被组装在一起;先建上半部分也没关系。此外,光是上半部分就足以开始有效地解决现实世界的问题了。一个简单的事实是,普通的数据科学家不需要知道梯度下降的微妙之处,只要他们可以从 SK-Learn 导入一个模型,并将其应用于他们的数据集。

当然,这是一个开放的话题,我的意思是不要把我的观点强加给你。相反,我提出这一点是作为一个正在进行的辩论——如果你打算冒险进入(或者已经在数据科学教育领域中游泳),我会鼓励你深入思考这个问题。

真实世界数据的重要性

通常,教学有助于设计愚蠢的、虚构的问题,试图教会学生某些技能。我们在小学时都遇到过以下情况:

汤米去商店为他的三个孩子买食物。每个人都想在晚餐吃 3 个西瓜,还有一个西瓜 agua fresca,每个西瓜都需要 2 个西瓜来制作。汤米需要购买多少西瓜来满足每个人,包括他自己?

随着这些年来我们在教育方面的进步,问题变得更加复杂,也许不再那么荒谬,但是有一个事实倾向于持续存在:它们非常不真实。

然而,在数据科学中,情况不一定如此。在现代社会,有许多公开的数据集,你没有理由不把它们融入到你的课程中。研讨会上的发言者非常强调这一点。

通过使用真实世界的数据,您可以在课程中自动构建更深层次的问题:

  • 如果数据的格式不适合分析,我们该怎么办?
  • 如何通过数据科学的实践在世界上做好事?
  • 这项研究的伦理含义是什么?

然后,这些引导出重要的洞察力,否则你的学生可能会失去这些洞察力。通过从一开始就使用真实世界的数据,你自动开始解决一个极其重要但在任何教育环境中经常被忽视的问题:我们为什么要这样做?

不要自欺欺人地认为这很容易。为你希望你的学生每周都达到的特定学习目标找到正确的数据集是相当具有挑战性的。研讨会上的教授承认在这个看似简单的任务上花费了大量的时间。你也应该做好准备。

但是,我知道这是值得的。

道德不应该是一个“旁门左道”

最后,正如现代推动数据科学教育所预期的那样,研讨会的一部分专门用于伦理讨论。然而,主持人接近它的方式引起了我的注意。

作为背景,当来自伯克利的一些教育工作者讨论他们的数据科学计划在未来几年的扩展时,这个话题出现了。他们提到,最初,他们认为只需要一两门道德课程作为必修课程。

但是后来,他们意识到他们又一次犯了致命的错误,从本质上把工作的伦理放在“一边”,而实际上它应该是基础。在许多方面,我们今天在技术世界中面临的一些伦理问题源于相似的、有缺陷的范例

因此,他们又回到了起点,转而决定采用一种不同的方法。当他们设计(并且继续设计,因为在我写这篇文章的时候,这个项目仍在建设中)他们的课程时,他们将伦理讨论纳入了每个教学大纲的一部分,以适应课程的特定主题。

这是一种更好的方法,所有数据科学家——尤其是那些正式或非正式地教授他人的数据科学家——都可以借鉴。持续不断地讨论道德规范(T1)(每门课程),特别是讨论 T2(T3)(与课程材料直接相关),从一开始就使其成为该领域学生的一个重要话题。

通过采用这种范式,我们可以确保数据科学有一个理想的未来:对社会大有裨益,但不会造成不可挽回的附带损害。

最后的想法:什么是负责任的数据实践

最后,我将分享研讨会本身的一些最终想法。在演讲接近尾声时,讨论了以下首要原则。它们被故意弄得模糊不清,我不想说出我自己的想法,因为我认为结束本文的一个合适方式是鼓励您考虑以下每一项对您的意义,特别是在以数据为中心的世界中:

  • 了解世界
  • 想象什么是可能的
  • 对自己的反思
  • 对道德背景的敏感性
  • 走向正义
  • 对不公正制度的批判

当然,不要停留在反思上。将这些理念融入数据科学工作的各个方面,尤其是指导他人。如果我们都这样做,未来是光明的。

想擅长 Python? 在这里 获得独家、免费获取我简单易懂的指南。想在介质上无限阅读故事?用我下面的推荐链接注册!

https://murtaza5152-ali.medium.com/?source=entity_driven_subscription-607fa603b7ce---------------------------------------

我叫 Murtaza Ali,是华盛顿大学研究人机交互的博士生。我喜欢写关于教育、编程、生活以及偶尔的随想。

参考

我对上面提供的原始想法和建议没有任何个人主张,它们都是我对 2022 年全国数据科学教育研讨会上各个演讲者详细讨论的主题的思考。完整的日程安排,以及各种演讲的链接,请参见 https://data.berkeley.edu/2022workshop

3 个 Python 库,用于您可能错过的有效 EDA

原文:https://towardsdatascience.com/3-python-libraries-for-effective-eda-that-you-might-have-missed-3320f48ff070

通过几行代码,EDA 变得更加简单

迈克·多尔纳在 Unsplash 上的照片

介绍

EDA,或探索性数据分析,是每个数据科学努力的第一阶段。这也是数据挖掘的第一阶段,帮助获得数据洞察力,同时不做任何假设。分析师可以使用 EDA 浏览数据描述,理解变量之间的关系,并通过验证数据源、发现缺失值和识别异常值来评估数据质量。简而言之,EDA 在生成精确的数据报告和精确的数据模型方面起着至关重要的作用。

对于初学者来说,由于不熟悉数据挖掘中的语法和过程,可能需要时间来完成这个初步筛选过程。我刚开始了解 Python 的时候也是这种情况。当时,我只希望有一种工具能一次自动为我做所有的工作。甚至在今天,随着我对数据挖掘和清理过程越来越熟悉,我希望在一些特定的过程中节省时间,并快速前进。

这就是为什么今天,我想让您接触一些强大的 EDA 工具,它们可能会帮助您更好地全面了解我们正在浏览的数据。

资料组

在 Python 包seaborn里,有很多免费数据集可以尝试。然而,我会选择名为“钻石”的数据集下面是我获取数据集的方法:

import seaborn as sns
df = sns.load_dataset('diamonds')

数据来源参考: Waskom,m .等人,2017。mwaskom/seaborn:v 0 . 8 . 1(2017 年 9 月),芝诺多。可在:https://doi.org/10.5281/zenodo.883859.

SweetViz

就个人而言,这是我最喜欢的自动化 EDA 之一。为什么?因为它超级酷的界面。为了证明我的说法,在图 1 中,您可以看到由 SweetViz 生成的报告的概述。很酷,对吧?

图 1:作者 df — Gif 数据汇总

那么,SweetViz 是什么?

好吧,简单来说,SweetViz Package 是一个开源的 Python 库,它可以自动启动 EDA,只需几行代码就可以创建令人惊叹的视觉效果。输出是一个完全独立的 HTML 应用程序,如图 1 所示。SweetViz 有助于快速查看不同的数据集特征,并主要提供有关变量之间关联的完整信息。SweetViz 的另一个突出特点是其目标分析,它解释了目标值与其他变量的关系。

我们如何运行它?

基本上,创建报告有三个功能,分别是analyze()compare()compare_intra()

首先,让我们试着得到 所有数据集的汇总。 analyze()就是你在这种情况下应该使用的函数。

#Installing the library 
pip install sweetviz#Importing the library 
import sweetviz as svreport = sv.analyze(df)
report.show_html()

而结果就是你在上面的图 1 中看到的。

当你想 比较两个独立的数据帧时呢? 比如我的情况,我想比较训练和测试集?非常简单,使用compare(),这是我得到的结果:

#Spliting data set into training and testing set
training_data = df.sample(frac=0.8, random_state=25)
testing_data = df.drop(training_data.index)#Applying compare function
report2 = sv.compare([training_data,"TRAINING SET"], [testing_data, "TESTING SET"])
report2.show_html()

图 2:比较两个独立的数据帧——作者 Gif

如果你想在你的数据子集之间进行比较,你可以选择compare_intra()。例如,图 3 显示了 D 颜色的子集和其余部分之间的比较。

report3 = sv.compare_intra(df, df["color"] == "D", ["D", "The rest"])report3.show_html()

图 3:比较 2 个子集——作者 Gif

数据准备

如果要用一句话来形容这个方案,我会说,“它已经做了所有的工作。”换句话说,我们可以在创建的报告中找到几乎所有的信息。这个软件包的一个优点是输出是交互式的,这使得报告更便于跟踪。

DataPrep 绝对是我最喜欢的自动化 EDA。与 SweetViz 类似,该库也有助于在一行代码中探索数据。这就是你要做的:

#Installing the library
!pip install dataprep#Importing 
from dataprep.eda import create_report#Creating report
create_report(df)

图 4:作者的 EDA-Gif 数据准备图

Skimpy 是一个小的 Python 包,它提供了数据汇总的扩展版本。如图 5 所示,数据报告非常简单,但是包含了几乎所有必要的信息。该库不像以前的报告那样完整;不过,我觉得这个总结有时候用起来还是够用的。它的运行速度也比其他两个库快。

from skimpy import skim
skim(df)

图 5:简略摘要—作者图片

下一步是什么?

有许多令人兴奋的自动化 EDA 库,我肯定会进一步学习,如 Bamboolib、Autoviz 或 Dora。我目前只有这些了。

如果你们有任何建议,请与我分享,😄,我很乐意知道更多。

用于自动数据集标注过程的 3 个 Python 包

原文:https://towardsdatascience.com/3-python-packages-for-automatic-dataset-labeling-process-3fb1d898db5b

数据标注对于机器学习项目的成功至关重要

照片由穆拉特·翁德尔Unsplash 上拍摄

数据科学项目涉及大量的数据收集、清理和处理。我们做了所有的步骤来确保数据集质量对于机器学习训练来说是好的。尽管如此,数据科学项目中有一个特别重要的部分可能决定项目的成败:标签。

每个数据科学项目都是为了解决特定的业务问题而开发的,例如,客户流失、购买倾向、欺诈等。考虑主题很容易,但一旦我们需要考虑业务方面,标记过程就变得复杂了。

由于不同的业务需求,同一个客户流失项目可能有不同的标签——一个项目可能只考虑一年内客户流失的人数,而另一个项目则希望预测整体客户流失情况。看到标签已经变得如此不同了吗?这就是为什么贴标过程是必不可少的。

为了帮助从事标注处理的数据人员,我想介绍几个我认为对日常工作有用的 Python 包。包裹是什么?让我们开始吧。

1.构成

Compose 是一个为自动化预测工程工作而开发的 Python 包。Compose 是专门为监督预测问题生成标签而创建的。用户定义标签标准,并合成运行历史数据以创建标签预测。

Compose 主要被设计为与名为 featuretoolsEvalML 的自动化特征工程包一起工作,用于自动化机器学习,但在本文中,我们将重点关注 Compose。

让我们从安装 Compose 包开始。

pip install composeml

此外,对于这个示例,我将使用 Heerla Dedhia 的 Kaggle 中的杂货数据集,该数据集在市场上可以买到。

import pandas as pddf = pd.read_csv('Groceries_dataset.csv')
df['Date'] = pd.to_datetime(df['Date'])df.head()

作者图片

数据集包含 3 列:ID(“Member _ number”)、购买时间(“Date”)和购买的项目(“itemDescription”)。

现在,假设我们有一个业务问题:

"顾客会在下一个购物周期购买一些东西吗?"

根据上面的问题,我们可以尝试使用可用的数据集来回答它们,但是我们需要考虑两个参数:

  1. 客户会购买什么产品?
  2. 下一次购物期是多久?

假设我们想知道顾客是否会在未来 3 天内购买全脂牛奶;然后,我们可以尝试根据这个定义创建标签。

要开始为标签工作使用 Compose 包,我们需要首先定义符合我们标准的标签函数。

def bought_product(ds, itemDescription): return ds.itemDescription.str.contains(itemDescription).any()

上面的代码将检查客户是否购买了特定的产品。创建标签函数后,我们将使用以下代码设置标签生成器。

lm = cp.LabelMaker(#We want to process each customer so we use the Customer ID
target_dataframe_name='Member_number',#Because we want to know if the customer bought item on the next period, we would need the time column
time_index='Date',#Set the label function
labeling_function=bought_product,#How long the shopping Period (or any period between time)
window_size='3d'
)

当我们已经设置了 LabelMaker 类时,我们就可以运行 label maker 进程了。

lt = lm.search(#The dataset
df.sort_values('Date'),#Number of label per customers, -1 means find all the existing
num_examples_per_instance=-1,#What product we want to find
itemDescription='whole milk',minimum_data='3d',
verbose=False,)lt.head()

作者图片

输出的三列解释如下:

  • Member_number 与购买相关。由于每个顾客可以购买不止一次,因此可能有不止一个例子。
  • 时间是购物期的开始。这也是建筑物特征的截止时间。
  • 如果产品是在期间窗口内购买的,则它们是通过标签函数计算的。

我们可以使用下面的代码来获得结果的标签摘要。

lt.describe()

作者图片

从标记过程中,我们可以看到在我们的搜索中有一个不平衡的例子。在购物期的 3 天内购买全脂牛奶的顾客似乎不多。

这就是作曲的例子。如果你想尝试其他数据或看另一个例子,我们可以访问教程

2.通气管

通气管是专门为构建数据集标注而开发的 Python 包,无需任何手动标注过程。speak 旨在用几行代码减少标签工作所用的时间。通气管有 3 个主要特点:

  • 标注数据,
  • 转换数据,
  • 切片数据

但是,本文将只关注标记数据的过程。让我们试试通气管套件,让我们的贴标过程自动化。

首先,我们需要安装软件包。

pip install snorkel

出于指导的目的,我们将使用来自 Nipun Arora 的 Kaggle 的 YouTube 评论数据集,该数据集在市场上可以买到。

import pandas as pddf = pd.read_csv('youtube_dataset.csv')
df.head()

作者图片

数据集包含许多字段,包括 YouTube 评论数据。假设我们想从数据集中训练一个 YouTube 评论垃圾预测器。在这种情况下,我们需要用特定的要求来标记数据—我们认为什么是垃圾邮件?

使用 scupk,我们可以创建一个称为标记功能的弱监督功能——监督规则和启发式规则,将标签分配给未标记的训练数据。

为了清楚起见,让我们将火腿视为 0,垃圾邮件视为 1,弃权为-1。

ABSTAIN = -1
HAM = 0
SPAM = 1

此外,我认为垃圾邮件的文本中包含“check”和“checking _ out”。让我们用上面的规则来构建标签函数。

from snorkel.labeling import labeling_function@labeling_function()def check(x):
   return SPAM if "check" in x.text.lower() else ABSTAIN @labeling_function()def checking_out(x):
   return SPAM if "checking out" in x.text.lower() else ABSTAIN

准备好函数后,我们可以标记注释数据。但是,我们需要更改希望作为“文本”处理的列名。

df = df.rename(columns = {'Comment' : 'text'})

因为我们也使用熊猫数据帧,我们将使用PandasLFApplier来应用标签功能。

from snorkel.labeling import PandasLFApplierlfs = [checking_out, check]applier = PandasLFApplier(lfs=lfs)L_train = applier.apply(df=df)

applier 函数的结果是一个标签矩阵,其中列表示标签函数,行表示数据点。

L_train

作者图片

从标签应用程序函数中,让我们检查每个单词的垃圾邮件覆盖率是多少。

coverage_checking_out, coverage_check = (L_train != ABSTAIN).mean(axis=0)print(f"checking out coverage: {coverage_checking_out * 100:.1f}%")
print(f"check coverage: {coverage_check * 100:.1f}%")

作者图片

根据我们的标签功能,似乎没有那么多的评论是垃圾邮件。让我们使用通气管中的功能来获得更详细的总结。

from snorkel.labeling import LFAnalysisLFAnalysis(L=L_train, lfs=lfs).lf_summary()

作者图片

使用LFAnalysis我们可以获得更多关于贴标过程的详细信息。每一列代表以下信息:

  • 极性:标签功能的唯一标签(不含弃权),
  • 覆盖率:数据集中的 LF 标签分数,
  • 重叠:该 LF 和至少一个其他 LF 标签重叠的数据集部分
  • 冲突:该 LF 和至少一个其他 LF 标签不一致的数据集部分。

这是通气管在贴标过程中的基本用法。对于这些包,您仍然可以做很多事情并从中学习。重要的是,通气管会减少你的标记活动。

3.清洁实验室

Cleanlab 是一个 python 包,用于发现标签问题并自动修复它们。本质上,这个包不同于我前面提到的两个包,因为 Cleanlab 要求我们的数据集已经包含标签。

Cleanlab 旨在减少修复数据错误的手动工作,并帮助使用干净的数据集训练可靠的 ML 模型。大多数时候,坏标签是因为贴错标签而产生的,Cleanlab 旨在解决这个问题。

让我们用一个数据集例子来使用 Cleanlab。首先,我们需要安装软件包。

pip install cleanlab

我们将使用来自 Sklearn 函数的信用数据,并设置随机种子以获得稳定的结果。数据来自于 OpenML 信用数据,其来源是 UCI 并可商业使用。

from sklearn.datasets import fetch_openml
import random
import numpy as npSEED = 123456
np.random.seed(SEED)
random.seed(SEED)data = fetch_openml("credit-g")
X_raw = data.data
y_raw = data.target

之后,我们将使用几个 Sklearn 函数进行一些数据清理。

import pandas as pd
from sklearn.preprocessing import StandardScaler
cat_features = X_raw.select_dtypes("category").columnsX_encoded = pd.get_dummies(X_raw, columns=cat_features, drop_first=True)
num_features = X_raw.select_dtypes("float64").columnsscaler = StandardScaler()
X_scaled = X_encoded.copy()
X_scaled[num_features] = scaler.fit_transform(X_encoded[num_features])y = y_raw.map({"bad": 0, "good": 1})  # encode labels as integers

现在,我们将尝试从数据集样本中找到一个错误标签。根据 cleanlab 文档,cleanlab 需要从模型中对每个数据点进行概率预测。

Cleanlab 也仅用于样本外预测概率,即训练期间模型中的样本。这就是为什么我们会使用 K 倍交叉验证来获得样本外概率。

让我们先建立模型来计算概率。我们将使用样本逻辑回归。

from sklearn.linear_model import LogisticRegressionclf = LogisticRegression()

然后我们会建立 K 倍交叉验证。

from sklearn.model_selection import cross_val_predictnum_crossval_folds = 5 pred_probs = cross_val_predict(
    clf,
    X_scaled,
    y,
    cv=num_crossval_folds,
    method="predict_proba",
)

最后,我们将使用 Cleanlab find_label_issues根据样本外概率和给定标签在数据集中找到坏标签。

from cleanlab.filter import find_label_issuesranked_label_issues = find_label_issues(labels=y, pred_probs=pred_probs, return_indices_ranked_by="self_confidence")print(f"Cleanlab found {len(ranked_label_issues)} potential label errors.")

作者图片

如果我们检查结果,我们将得到坏标签的位置。

ranked_label_issues

作者图片

有了这些信息,我们需要再次检查数据,并确保质量优良。

使用 Cleanlab,您仍然可以探索许多事情。如果你想知道更多,请访问文档

结论

标签和数据科学项目一样重要,因为许多机器学习模型都依赖于正确的标签。为了帮助数据科学家在标注过程中工作,我为自动标注过程引入了 3 个 Python 包。这些软件包是:

  1. 构成
  2. 通气管
  3. 清洁实验室

希望有帮助!

访问我的 社交媒体进行更深入的交谈或有任何问题。

如果您没有订阅为中等会员,请考虑通过我的推荐订阅。

用于交互式数据分析的 3 个 Python 包

原文:https://towardsdatascience.com/3-python-packages-for-interactive-data-analysis-3063a201a589

以更具互动性的方式探索数据

Towfiqu barb huyaUnsplash 拍摄的照片

数据分析是任何数据人员的主要活动,也是理解我们工作内容所必需的。为了帮助数据分析过程,我们使用了 Python 语言来简化工作流程。然而,有时我们想要一种更具交互性的方式来探索数据。一些人开发了 Python 包来交互式地探索数据以满足需求。

本文将探索 3 个 Python 包,我们可以用它们来交互式地探索数据集。让我们开始吧。

1.潘达斯吉

PandasGUI 是一个简单的 Python 包,为数据集探索提供 GUI。该软件包提供了一个独立的 GUI,具有类似 excel 的体验,我们可以使用它来探索数据集、获取统计数据、可视化数据等等。让我们尝试一下这个包,体验一下实际操作。

首先,我们需要安装 PandasGUI 包。

pip install pandasgui

安装完这个包之后,我们可以立即使用这个包来研究我们的数据集。作为一个数据集示例,我将使用 seaborn 的 mpg 数据集。

#Load Dataset
import seaborn as sns
mpg = sns.load_dataset('mpg')#Initiate the GUI
from pandasgui import show
show(mpg)

使用上面的代码,您将在新的屏幕上获得下面的 GUI。

作者图片

PandasGUI 为我们提供了利用各种功能探索数据的选项,包括:

  • 数据过滤,
  • 统计信息,
  • 绘图,
  • 数据重塑。

首先,让我们看看 PandasGUI 选项卡。在下面的 GIF 中,你可以看到我们可以根据需要安排标签要求。

作者创建的 Gif

接下来,我们来看看过滤数据选项卡。此选项卡允许您使用特定查询过滤数据框。要填充的查询是基于 Pandas 查询的,所以如果您已经了解过它,应该会很熟悉。

作者创建的 GIF

看一下上面的 GIF。在我的示例中,我编写了“model_year > 72”查询,其中的结果是带有勾选框的查询。过滤条件将永久存在于查询过滤器列表中,当您不需要它时,可以取消选中它。

如果在查询编写过程中出错,只需双击查询并重写即可。就这么简单。

现在,让我们看看“统计”选项卡。

作者创建的 GIF

统计选项卡为您提供数据的简单变量统计,如计数、平均值和标准差。类似于熊猫的describe属性。

如果您在前面的选项卡中进行过滤,统计数据将根据您的过滤器进行更改。

接下来,我们将进入 Grapher 选项卡或绘图 GUI。此选项卡允许您创建单个变量图或多个变量图。让我给你看下面的例子。

作者创建的 GIF

创建一个情节只是一个拖放的问题,就这么简单。 plotly 包用于可视化,因此我们可以通过将光标悬停在图形上来浏览图形。

最后是整形标签。在这个选项卡中,我们可以通过创建新的数据透视表或融合数据集来重塑数据集。

作者创建的图像

如果要将数据集导入新的 CSV 文件或将新的 CSV 文件导出到 PandasGUI,也可以单击下图所示的选择。

作者图片

2.数字童话

D-Tale 是一个用于交互式数据探索的 Python 包,它使用 Flask 后端和 React 前端来轻松分析数据。数据分析可以直接在你的 Jupyter 笔记本上进行,也可以在笔记本之外进行。让我们试着使用这个包。

首先,我们需要安装软件包。

pip install dtale

然后,我们可以使用以下代码启动 D-tale 流程。我将使用与前一个示例中相同的 MPG 数据集。

import dtale
d = dtale.show(mpg)
d

作者图片

你可以用 D-Tale 做很多活动,我无法一一解释。我只会解释我认为对你来说很重要的特性。

首先,让我们看看“操作”选项卡。我们可以操作该选项卡中的数据集,例如过滤、合并或删除。让我们看看 action 选项卡为我们提供了什么。

作者图片

操作选项卡具有操作数据集的所有功能,例如数据转换、创建数据框函数和过滤。此外,您可以使用 Summarize Data 函数获得数据摘要。

如果您不确定每个功能是做什么的,您可以突出显示该选项,解释就会出现。

作者图片

就我个人而言,我觉得 D-tale 最大的特点是它的可视化功能。

作者图片

正如我们在上图中看到的,我们可以尝试各种可视化方式,例如:

  • 形容

描述让我们获得基本的统计可视化。

作者图片

  • 预测能力得分

数据集的 PPS 评分可视化。

作者图片

  • 各种图表

作者图片

可视化之后,我们可以使用 Highlight 选项卡来帮助我们突出显示数据集中的各种数据,例如缺失的数据或异常值。

作者图片

最后,你可以改变 D-tale 的设置,比如主题、语言和屏幕大小。

作者图片

3.米托

让我们尝试安装米托软件包。米托是一个 Python 包,可将您的数据框转换为类似 excel 的分析数据框。想象一下,如果您有一个 excel 文件,但它在您的 Jupyter 笔记本中。我们可以使用下面的代码来做到这一点。

python -m pip install mitoinstaller
python -m mitoinstaller install

安装后,我们激活米托包,用下面的代码创建一个类似 excel 的工作表。

import mitosheet
mitosheet.sheet(mpg)

作者图片

如上图所示,我们之前的数据框被转换成了类似 excel 的数据表。

该软件包易于开发,如果您已经熟悉 excel,您会有宾至如归的感觉。让我们尝试使用一些我认为对数据探索有用的特性。

首先,我们可以使用 View column summary statistics 来查看列摘要统计信息。

作者图片

然后,我们可以使用 Graph 按钮轻松创建各种图表。

作者图片

如果需要,我们也可以直接在列中过滤数据。

作者图片

你还可以尝试米托的许多功能。如果你喜欢用 excel 进行分析,米托将是一个不错的选择。

结论

任何数据人都做数据分析,因为这是必须的步骤。有时,我们想要一种更具互动性的方法来分析数据。为此,这里有 3 个 Python 包来进行交互式数据分析:

  1. 潘达斯吉
  2. 数字童话
  3. 米托

希望有帮助!

访问我的 社交媒体进行更深入的交谈或有任何问题。

如果您没有订阅为中等会员,请考虑通过 我的推荐 订阅。

使用集合而不是列表的 3 个理由

原文:https://towardsdatascience.com/3-reasons-to-use-sets-over-lists-82b36980c9fd

了解每个容器适用的时间和位置

Heather McKean 在 Unsplash 上拍摄的照片

初学者常常选择熟悉的而不是最佳的。

大多数 Python 课程从列表开始向学生介绍容器数据类型。自然,初学者会对它们感到很舒服。开始时,你专注于快速移动和处理下一个主题,以便在动力持续的时候尽可能多地学习。结果,你养成了有效的习惯,但并不总是最佳实践。由于列表的多功能性,这一点尤其正确。

大多数人在一套足够用的时候会使用列表。当需要列表时,很少看到使用集合。在这些情况下,缺少的信息通常会产生错误。然而,由于列表比集合包含更多的信息,使用列表代替集合通常不会产生错误,这使得很难确定何时应该使用集合

这里有 3 条线索可以帮助你发现什么时候集合比列表更有意义。

1.顺序不重要

与列表不同,集合不存储有序数据。列表有索引和可访问的数据,这意味着每个元素都是可检索的。无法访问集合中的单个项目,因为它们没有索引。

然而,并不是所有的数据都需要索引。比如会员测试。测试一个项目是否属于一个组并不需要对该组进行索引,因为它只返回一个TrueFalse语句。

2.重复是不相关的

根据定义,集合不能包含重复项。这使得集合成为储存独特物品的理想容器。

事实上,这个属性使得 set 数据类型成为从容器中删除重复项的流行方法。例如,下面的代码创建了一个集合,countries,查找所有获得男子 100 米短跑奖牌的国家。即使有些国家多次出现在数据集中,countries也会删除那些重复的值,只返回唯一的项目。

作者图片

要进一步细化集合,请使用集合理解。与列表理解类似,集合理解通过将 for 循环减少到一行代码来创建集合。集合理解允许附加标准。例如,下面的集合理解,startswith,找到所有获奖的国家,并以‘B’开始。

3.处理速度很重要

因为集合不存储索引数据或副本,所以它们比列表使用更少的内存,计算开销也更小。因此,搜索集合花费的时间更少。

为了测试这一点,下面的代码执行两个成员测试。在一种情况下,容器是一个列表,在另一种情况下,它是一个集合。两个容器长度相同,并且两种情况下都将输出存储在一个集合中。

将列表案例的输出存储在一个列表中会花费更多的时间,并且会在实验中引入另一个变量,即输出类型。 用于创建集合理解的容器类型是这两种情况的唯一区别。

下面的图表说明了随着容器大小的增加,成员测试中集合和列表之间的时间差。

作者图片

结论

如您所见,在许多情况下,集合比列表更有优势。希望这篇文章能帮助您确定何时使用集合,以避免过度依赖列表。

感谢您阅读我的文章。如果你喜欢我的内容,请考虑关注我。此外,欢迎所有反馈。我总是渴望学习新的或更好的做事方法。请随时留下您的评论或联系我 katyhagerty19@gmail.com。

https://medium.com/@katyhagerty19/membership

音乐是学习和教授数据科学的理想选择的 3 个原因

原文:https://towardsdatascience.com/3-reasons-why-music-is-ideal-for-learning-and-teaching-data-science-59d892913608

图片由作者提供。

音乐一直是我的一大爱好。以至于我拿到了我的第一个大学音乐学学位。当我开始学习数据科学时,人工智能音乐似乎是一条显而易见的前进道路。然而,在人工智能音乐学习和工作两年多后,我意识到,如果我能回到过去,我会一遍又一遍地从人工智能音乐开始。因为我很快就要担任教学角色,所以我也一直在深入思考将音乐作为教授数据科学的工具。

在本文中,我认为音乐是学习和教授数据科学的理想选择,因为:

  1. 音乐有趣又迷人。
  2. 人工智能音乐包含了大部分人工智能学科。
  3. 有许多未解决的问题。

1.音乐对每个人来说都是有趣和迷人的

“各种各样的物种围绕着乐器跳舞的油画,冥想,精神,天堂般的灯光”——由作者使用稳定扩散生成。

现在,这第一个论点似乎是显而易见的,但它并不像听起来那样微不足道。我们不能忽视数据科学可能是一门非常枯燥和抽象的学科。线性代数、贝叶斯随机、梯度下降、反向传播——这些东西不是小菜一碟,尤其是对于非 STEM 学生/毕业生甚至没有学位的人来说。

音乐激励着每个人

当事情变得具有挑战性时,你需要拿出更多的意志来保持专注并完成困难的课题。根据自我决定理论(SDT),在这些情况下,你真正需要的是一种尽可能内在的动力。如果你完全是外部激励(“我需要学习随机,因为我的雇主希望我这么做”),你已经输掉了这场战斗。尽管真正的内在动机是理想的,但是很少有人喜欢仅仅为了计算梯度而计算梯度。

在现实世界中,你只能在更多和更少的内在动力来源之间做出选择。你更喜欢以下两种心态中的哪一种?

  1. “我需要学习统计学,因为我想成为一名数据科学家”
  2. “我需要研究随机统计,因为这将帮助我理解 Spotify 是如何向我推荐新音乐的”

在我看来,两者都不错。不过,我想你们大多数人会选择心态 2。为什么?因为它不是在抽象和面向未来的意义上重要,而是几乎会立即影响你的日常生活。这是那种能让你坐下来学习的动力。音乐深深嵌入了几乎每个人的日常生活。当你可以教他们建立一个流派识别模型时,为什么要教一个班级建立预测模型来对不同种类的龟背竹进行分类?

听音乐很有趣

除了为音乐应用程序构建人工智能很酷之外,实际上听音乐更有趣。专业做音乐分类模型快两年了。我要做的最有趣的事情——很大程度上——是通过听音乐和判断模型的预测来对我的模型进行定性评估。通过听音乐来了解你的人工智能的优缺点是非常生动的事情。

此外,作为一名数据科学家,有时您必须将您的模型与人类的判断进行比较。让我直截了当地问一句:你是愿意听 200 首音乐来分类它们的流派,还是愿意浏览 200 幅龟背竹的图片来找出每一种是哪一种?

2.音乐包含了大多数人工智能学科

“多只手伸向一把小提琴,天堂般的背景,温柔”——由作者使用稳定扩散生成。

每个数据科学家都知道,处理文本数据与处理图像完全不同。音乐数据的迷人之处在于,它几乎被用于所有主要的数据科学学科,因为这种数据用途广泛。

音乐分类包括图像分类

现在,这个事实可能会像我一样让你大吃一惊:最先进的音乐分类模型,如流派、情绪或乐器分类器,本质上是根据图像数据训练的图像分类模型。如果你将你的音频文件转换成所谓的频谱图(图 1 ) 并在上面微调一个标准的 CNN 图像处理,你很可能会获得令人印象深刻的效果。

图 Metallica《寻找与毁灭》前十秒的数字化音频信号波形和 Mel 声谱图。图片作者。

当然,有许多特定领域的修改可以改进您的模型(Oramas 等人,2017;Choi et al .,2017),但这可能与您的个人学习/教学目的无关。请记住,当你在构建一个分类器来区分布鲁诺·马斯和迈克尔·杰克逊的音乐时,你也在学习构建分类器来区分空的人行横道和上面有奶奶的人行横道(这对自动驾驶来说是好事)。

音乐总是带有元数据

无论是艺术家的名字、专辑的发行年份还是相关的流派,音乐几乎总是带有元数据。在一些免费提供的音乐数据集中,如免费音乐档案馆(FMA)百万首歌曲数据集,你还会发现成百上千的众包标签,涵盖从风格或情绪到情景或关联的所有类别。有时候,你甚至会找到歌词!如果你正试图学习处理基本的文本数据,这里是的绝佳场所

事实上,您可以在不接触音频信号的情况下构建有趣且有用的工具。也许你可以通过对不同艺术家的歌词进行情感检测来分析他们的歌词内容。你也可以建立一个关键词推荐系统,正如我在的这篇文章中所展示的。如果你把元数据和音频结合起来,你可以建立流派或情绪分类器,或者提出你自己的想法。如果你有可用的歌词,你甚至可以尝试使用一个转换器来构建一个歌词转录工具——这就引出了我的下一个观点。

音乐数据非常适合变形金刚

transformer 架构及其关注机制无疑是过去几年最受关注的机器学习技术。在这一点上,如果有足够的数据,transformer 似乎可以解决所有涉及顺序数据的问题,如文本数据、股票数据或音乐数据。

有很多用变形金刚做音乐的很酷的事情。在这个视频中,著名的人工智能大师特里斯坦·伯伦斯展示了他的生成变压器如何为金属乐队的“恩特尔·桑德曼”编写替代鼓:

2021 年,德国人工智能初创公司 Cyanite 推出了一款音乐字幕转换器,它可以自动为给定的音频输入编写全文描述。随着达尔-E-2 和稳定扩散等扩散模型的流行趋势,首次尝试使用扩散模型进行 MIDI-to-audio 合成。在接下来的几个月里还会有更多!

人工智能中音乐的其他酷用例

自从音乐流媒体服务兴起以来,音乐人工智能中最重要的用例之一就是智能音乐推荐系统的开发。概括地说,这些系统由一个相似性度量组成(什么是好的推荐?)和一个搜索算法(如何高效的找到好的推荐?).当谈到音乐推荐系统时,最有趣的部分是开发相似性度量,因为是什么使两个音乐作品彼此相似或不相似并不明显。

学习音乐人工智能的一个相当明显的优势是,你所学的大部分可以转移到其他音频处理任务,如鸟鸣分类、声音识别或语音转录。虽然肯定存在特定领域的特性,但大多数信号处理和机器学习都非常相似,有时甚至完全相同。随着基于音频的控制开始越来越多地取代键盘,这种可移植性在未来可能会被证明是有用的。

最后,音乐是一种很棒的数据类型,可以用来执行数据扩充。正如我之前指出的,音乐经常以图像的形式呈现给神经网络。因此,一些基本的图像增强技术,如拉伸和掩蔽是适用的。此外,音频信号本身可以以多种方式增强。您不仅可以拉伸信号来增加或减少轨道的速度,或者执行音高移动来使乐曲听起来更低或更高。您也可以将混响、合唱或压缩器等音频效果应用到音频信号。让我告诉你,对于数据科学家和音乐家来说,这是一个有趣的游戏场所。

3.有许多未解决的问题

“一位老教授沉思一个特别复杂的问题的照片,蜡烛照明,特写”——由作者使用稳定扩散生成。

当你刚刚开始学习机器学习技术时,开发世界上第 100,000 个泰坦尼克号幸存者分类器肯定很有趣。然而,在某些时候,你可能会想开发一些在现实世界中有实际价值的东西。这就是为什么我想指出音乐人工智能中的各种问题,这些问题仍然没有得到令人满意的解决。愿这成为你人工智能之旅的灵感和动力。

音乐词干

音乐词干背后的想法是将音乐作品的信号分离成其乐器成分。例如,通常将信号分为人声和乐器(2 个干)或人声、节奏和和声(3 个干)。对于初学者来说,这听起来似乎是一个微不足道的任务。毕竟,我们能不能不只是“定位人声”和“删除”它们呢?虽然我不能在这里列出技术细节,但我可以说,在 Deezer 2019 年开创性地发布sp leater之前,音乐词干算法的质量远远不可用。

虽然市场上出现了许多创新的词干工具,但我仍然认为“孤立的”乐器轨道的质量不令人满意。我推荐你看看这篇的好文章,其中来自 musictech.com 的艾利克斯·霍姆斯比较了不同的最先进的堵塞工具。如果这些人工智能生成的茎真的变得与“真正的”孤立乐器轨道不可分,那将是一场小小的革命

音乐一代

音乐生成领域与音乐词干领域非常相似:创新的速度非常快,我们越来越接近目标,但我们还没有完全达到目标。首先,我们需要区分生成符号音乐(对音乐应该如何播放的高级描述)和发声音乐(构成实际的(数字模拟的)声学事件)。

在 AI 音乐中,常用 MIDI 作为一种象征性的音乐形式。粗略来说,MIDI 描述的是什么时候用什么速度弹奏哪个音符(~响度)。优秀的 transformer 模型已经被训练输出 MIDI 符号,这些符号可以被管弦乐队转换成声音音乐。结果令人印象深刻,你可以在特里斯坦·伯伦斯用 GPT-2 创作重金属音乐的视频中看到:

嵌入的 Youtube 视频显示特里斯坦伯伦斯如何使用 GPT-2 生成重金属音乐。

产生声音音乐比产生 MIDI 音乐要困难得多。这并不奇怪,因为 MIDI 是实际音频信号的简化抽象。然而,据我估计,自卡尔&祖科夫斯基(2018)训练递归神经网络生成重金属、摇滚和朋克的有影响力的 SampleRNN 模型以来,人工智能生成的声音音乐的质量并没有实质性的提高。事实上,他们在“Archspire”音乐风格上训练的模型仍然在 YouTube 直播流中全天候创作音乐:

Youtube 直播流全天候自动生成重金属音乐。

歌词转录

语音转录工具变得越来越强大,现在可以用于多种语言。对于一个局外人来说,在这一点上,抄写音乐歌词似乎是一件微不足道的任务。然而,这与现实相去甚远。事实上,令人震惊的是,人工智能转录工具在转录流行歌曲等看似简单的任务上仍然表现不佳。在一个案例研究中,音频情报服务 AssemblyAI 显示他们的 AI 可以正确识别大约 20%到 30%的歌词。****

我可以说,当一个人说瑞典语时,我目前能理解大约 70%的单词,比 AssemblyAI 理解歌词好得多。然而,出于显而易见的原因,我不会出售我作为一名瑞典语翻译的服务。此外,当公开评估他们自己的 AI 时,我确信作者选择了有利的例子。此外,所有的歌曲都来自流行、摇滚和 R & B 等流派。我敢打赌,为死亡金属歌曲改编的音乐更具喜剧性,而非有益性。然而,作者指出,如果将人声从乐器中分离出来,转录会变得更好。这意味着在某种程度上,词干和歌词转录的进展是齐头并进的。

其他未解决的问题

热门歌曲检测领域,构建分类器来找出哪些歌曲将成为热门歌曲,哪些将成为失败歌曲。该领域大多被放弃,因为即使有最先进的技术,也尚未找到广受欢迎的“热门歌曲公式”(见杨等人,2017)。也许当一个突破性的想法或新技术出现时,这个领域会经历一次复兴。

****音乐抄袭检测这个领域从商业角度来看也是极具前景的。虽然已经开发了性能良好的相似性度量(He 等人,2021),但是从相似性度量转移到抄袭检测是相当大的一步。这一领域的一个主要问题是地面真实数据相对较少。毕竟还没有几十万成功的音乐抄袭诉讼。

最后,我想指出的是音乐封面艺术生成领域。该领域相当活跃,最近发表了许多有趣的文章(例如 Efimova 等人,2022;Marien 等人,2022 年)。然而,据我所知,还没有人尝试使用从达尔-E-2 和稳定扩散已知的当前趋势扩散模型来生成音乐封面艺术。这可能是有前途的!

结论

在这篇文章中,我展示了音乐是学习和教授数据科学的理想选择,因为(1) 它有趣而迷人,(2) 可以应用于大多数人工智能学科,以及(3) 为你自己的创造性努力和数据科学项目留下了很多空间。

如果你想阅读更多关于音乐和人工智能的内容,可以考虑看看我在 Medium 上的一些相关作品:

  1. 用 Python 构建你的第一个基于情绪的音乐推荐系统
  2. 音乐流派分类采用一种划分方式&征服 CRNN

非常感谢你阅读这篇文章,请让我知道你对这个话题的想法!

科学参考

[1]卡尔和祖科夫斯基(2018)。“使用 SampleRNN 生成专辑以模仿金属、摇滚和朋克乐队”,载于: arXiv ,DOI:https://doi.org/10.48550/arXiv.1811.06633

[2] Choi 等人(2017)。《用于音乐分类的卷积递归神经网络》,载于:声学、语音和信号处理国际会议 2017

[3] Efimova 等人(2022 年)。“音乐封面图像的条件矢量图形生成”,载于: arXiv ,DOI:https://doi.org/10.48550/arXiv.2205.07301

[4]何等(2021)。“通过二部图匹配的音乐剽窃检测”,载于: arXiv ,DOI:https://doi.org/10.48550/arXiv.2107.09889

[5] Marien 等人(2022 年)。《用遗传算法进行音频引导的专辑封面艺术生成》,载于: arXiv ,土井:https://doi.org/10.48550/arXiv.2207.07162

[6]奥拉马斯等人(2017 年)。“使用深度特征从音频、文本和图像进行多标签音乐流派分类”,载于: arXiv ,DOI:https://doi.org/10.48550/arxiv

[7]杨等(2017)。“使用卷积神经网络重新审视基于音频的热门歌曲预测问题”,载于:arXiv,DOI:https://doi.org/10.48550/arXiv.1704.01280

Spark 懒评有用的 3 个理由

原文:https://towardsdatascience.com/3-reasons-why-sparks-lazy-evaluation-is-useful-ed06e27360c4

Spark 的懒评以及你为什么要在意

作者:阿玛尔·哈斯尼 & 迪亚·赫米拉

照片由卡斯滕·怀恩吉尔特Unsplash 上拍摄

有多少次你在笔记本上运行 PySpark 代码,期望看到一个漂亮的格式化表格,却得到一些“随机”字符串?很快你意识到你忘了展示/显示你的数据框,于是你就把它修好了。但是实际发生了什么呢?

你可能已经知道答案:懒评。但是到底什么是懒惰评估,更重要的是为什么 Spark 会有这种行为?

**Table of Contents:**
· [What is Lazy Evaluation?](#ad8a)
· [What is the difference between TRANSFORMATIONS and ACTIONS?](#cc3a)
  ∘ [Transformations](#c810)
  ∘ [Actions](#bda5)
· [Spark’s Catalyst Optimizer](#1adb)
· [What are the advantages of using Lazy Evaluation?](#bfa6)

什么是懒评?

首先,懒惰评估不是 Spark 发明的概念,已经存在一段时间了,只是众多评估策略中的一种。在我们的上下文中,了解以下两点是有用的:

  • 惰性求值是一种求值策略,将表达式的求值延迟到需要它的值的时候。
  • 急切求值是你最熟悉的求值策略,在大多数编程语言中都有使用。与惰性求值相反,表达式的求值一遇到就执行。

让我们回到火花。在 Spark 中,惰性评估意味着您可以应用任意多的转换,但是 Spark 不会启动进程的执行,直到一个动作被调用。

💡因此,转变是懒惰的,而行动是热切的。

转换和动作之间的区别是什么?

转换

转换是你用来以你想要的方式修改数据帧的指令,并且是延迟执行的。有两种类型的转换:

  • 转换:单个分区需要计算的数据存在于同一个分区中。
    例子: selectfilter

作者图片

  • 转换:需要为单个分区计算的数据可能存在于多个分区中。
    举例: groupByrepartition

作者图片

行动

动作是要求立即计算一个值的语句,是急切的语句。
例子: show count collect save

💡通常,一个转换将获取一个 RDD 并返回另一个 RDD。操作将采用 RDD,但将返回不同性质的内容:

.---------------- ---------.
| Transformation | Actions |
| -------------- | ------- |
| select         | show    |
| distinct       | count   |
| groupBy        | collect |
| sum            | save    |
| orderBy        |         |
| where          |         |
| limit          |         |
.---------------- ---------.

火花的催化剂优化器

在说实际优势之前,我们先快速说一下 Spark 的触媒优化器

当执行不同的转换时,Spark 会将它们存储在一个有向无环图(或 DAG)中。你实际上可以在 SparkUI 中查看 DAG。下面是一个简单的例子,大概是这样的:

作者图片

一旦 DAG 被构建,Spark 的 catalyst 优化器将执行一组基于规则和基于成本的优化,以确定执行的逻辑和物理计划

作者图片

显然,这是一个非常简化的版本,但对于我们的目的来说已经足够了。如果你想了解更多细节,你可以看看 Databricks 博客上的这篇帖子

用懒人评价有什么好处?

在使用惰性评估的优势中,我们发现了以下三点:

1.提高效率

Spark 的 Catalyst optimizer 将操作组合在一起,减少数据传递次数,提高性能。

catalyst 优化器的另一个优点是,通常不会用于最终结果的值将不会被计算。

举个例子吧。让我们首先定义一些数据帧:

现在,如果我们添加一个“性别”列,然后立即覆盖它:

Spark 会自动将这些操作组合在一起,因此会忽略第一个定义,因为它在最终结果中实际上并不使用。快速浏览一下逻辑与物理计划会使其更加清晰:

作者截图

所有这些也将优化驱动程序和集群通信,并加快程序。

📔查看这篇博客文章获得更多详细的例子。

2.更好的可读性

因为您知道 Spark 将操作组合在一起并在幕后优化代码,所以您可以使用更小的操作来组织您的程序,这将提高代码的可读性和可维护性。

3.内存管理

如果 Spark 的转换迫在眉睫,您必须将所有中间数据帧/rdd 存储在某个地方,或者至少管理内存将成为您的另一个关注点。

使用惰性评估,Spark 将只在实际需要的时候存储中间结果。

显然,如果需要,您可以通过缓存或导出结果来手动规避这种行为。但是很多时候,中介结果是“中介”的,不需要存储。

最后的想法

不可否认的是,懒评估在优化和效率方面增加了很多价值。然而,它也伴随着一些挫折。

其中一个原因是,惰性求值很难与来自命令式编程的特性一起使用,命令式编程假定执行顺序是固定的。一个例子是异常处理:如果在运行时发生错误,Spark 只会在使用一个动作时显示它。由于操作的顺序是不确定的(由于潜在的优化),这使得很难知道是哪个确切的转换导致了它。

如果您是 PySpark 的新手,正在从 Pandas 过渡过来,或者只是想要一个不错的备忘单,您可能想看看这篇文章:

谢谢你坚持到现在。注意安全,下一个故事再见😊!

更多文章阅读

</8-tips-to-write-cleaner-code-376f7232652c>

数据科学解决方案需要低代码平台的 3 个原因

原文:https://towardsdatascience.com/3-reasons-why-you-need-low-code-platforms-for-data-science-solutions-4c63cc7496d6

Genessa panainite 在 Unsplash 上拍摄的照片

意见

低代码 ML 应用程序有助于解决模型维护、上市时间和人才短缺的挑战

各行各业的组织都在转向数据和分析来解决业务挑战。由新华帝合作伙伴进行的一项调查发现,91%的企业已经投资了人工智能。然而,同一项研究发现,这些公司中只有 26%在大规模生产中使用了人工智能。

组织正在努力用人工智能解决业务挑战。他们发现构建机器学习(ML)应用程序需要时间,需要昂贵的维护和紧缺的人才。领导们表示,超过 70%的数据科学项目报告业务影响极小或为零。

以下是低代码 ML 平台如何帮助应对这些挑战。

什么是低代码,为什么现在这么热?

低代码是一种软件开发方法,它利用可视化用户界面来创建应用程序,而不是传统的手工编码。几十年来,开发人员通过从头开始编写数千行代码来构建应用程序,通常是昼夜不停地工作。

使用低代码构建软件解决方案介于从零开始编程和购买现成代码之间。它通过平衡灵活性和上市时间带来了两全其美。

低代码开发平台(LCDP)被认为是构建更快、维护更经济、对开发人员友好的,因为它的可视化方法。

低代码工具通过使软件开发民主化来增强企业的能力。今天,任何有商业兴趣和基本技术技能的人都可以使用低代码技术构建应用程序。根据 Gartner 的调查,到 2024 年,超过 65%的应用程序开发将会使用低代码。在全球范围内,低代码市场预计到 2030 年将达到 1870 亿美元。

低代码能加速 AI 解决方案吗?

史蒂文·勒勒姆在 Unsplash 上拍摄的照片

T4 预计,到 2029 年,全球移动通信市场将达到 2090 亿美元,复合增长率为 38.8%。机器学习操作(MLOps)是近年来引人注目的一套实践。通过简化软件操作和简化数据科学和开发团队之间的协作,MLOps 有助于构建生产级人工智能解决方案。

实质上,MLOps 通过三种实践交付产品:持续集成(CI)、持续交付(CD)和持续培训(CT)。

CI 处理将来自多个贡献者的代码自动构建和集成到单个应用程序中。CD 是持续地、可预测地将高质量产品交付生产的实践。当模型性能开始下降时,CT 确保使用新数据监控和重新训练 ML 模型。

为什么组织努力用 ML 建立、扩展和交付价值?有三个主要挑战:

  • 周期时间长:在企业规模上构建健壮的人工智能模型需要时间。80%的公司说他们花了六个月的时间生产一个人工智能模型。
  • 模型漂移:随着外部市场、业务动态和基础数据的不断变化,模型往往会很快失效。模型漂移会导致准确性下降和糟糕的业务决策。
  • 人才短缺:能够应用 AI 解决业务挑战的数据科学从业者供不应求。VentureBeat 认为技能短缺是人工智能采用缓慢的主要原因之一。

低代码方法通过为 MLOps 带来可视化的自动化方法来应对这些挑战。它有助于加快上市速度,实现高效的模型维护,并通过降低技能壁垒来实现数据科学开发的民主化。

低代码数据科学平台如何应对 MLOps 挑战

照片由岩田良治Unsplash 上拍摄

低代码平台有三种方式来解决大多数数据科学团队面临的障碍:

1.更快上市

低代码平台可以通过提供整个 ML 生命周期所需的可重用组件(数据连接器、数据处理器、后端/前端开发模块、ML 算法、可视化小部件以及管理和安全模块)来加速开发。

通过以拖放方式提供一个现成的库,它允许开发人员快速构建和修复错误。这使得数据科学团队可以轻松协作、迭代和优化,直到业务挑战得到解决。

2.更容易的模型维护和改进的治理

当经过训练的 ML 算法甚至在上线之前就有失效的风险时,低代码工具提供了保持算法更新的有效方法。它们使得持续监控模型、检测模型退化以及通过集中治理自动采取行动变得容易。

低代码 ML 平台通过标记基于触发器的警报来帮助检测模型漂移。它们提供了在定义的阈值重新训练模型的机制,并基于性能动态地替换模型。通过操作 CI-CD-CT 的 MLOps 实践,低代码 ML 平台有助于解决模型维护问题。

3.弥合技能差距

每个组织,无论规模大小,都在努力寻找、吸引和留住数据科学人才。通过提供直观的拖放界面,低代码平台打破了数据科学发展的障碍。

有了低代码平台,很容易重新培训内部软件开发团队来满足 ML 需求。可重复工作流中的可重用组件使得保留关于人工智能应用程序的知识或用新员工维护它们变得不那么麻烦。这意味着更低的培训和 ML 开发成本。

冷链物流提供商美国冷藏(USCS)公司旨在减少仓库周转时间,以改善客户体验并避免高额罚款。他们采用低代码的 ML 平台来开发一个自动预约调度器。USCS 召集了数据科学专家来确定这种延迟的根本原因——人工预约调度系统。他们使用低代码工具在一个季度内构建了一个预测调度程序。

该解决方案在一个仓库进行试点后,在美国的 26 个仓库进行了生产。这导致仓库周转时间减少了 16 %,在一个季度内节省了 30 万美元。低代码平台允许 USCS 团队在对其技术人员需求最小的情况下快速构建和部署解决方案。

采用低代码数据科学平台,降低总拥有成本

马修·斯特恩在 Unsplash 上的照片

组织通常通过评估技术平台来进行低代码数据科学开发。这可能是灾难性的。开始低代码之旅的最好地方是从组织的优先级和理解短期和长期的业务需求开始。

通过检查与组织的技术策略、架构和路线图的一致性来评估低代码平台。通过将构建和维护阶段的工具、人员和流程变更的支出考虑在内,根据总拥有成本做出选择。

本文首发于 企业家项目 。增加了插图。

使用 Python 列表要避免的 3 个新手错误

原文:https://towardsdatascience.com/3-rookie-mistakes-to-avoid-with-python-lists-625c0e8e57df

如何解决可能导致严重问题的小错误

格伦·卡斯滕斯-彼得斯在 Unsplash 上拍摄的照片

在所有的编码语言中,Python 可能是对初学者最友好的。它直观、有据可查,并且易于学习。然而,所有的语言都有怪癖,特别是作为初学者,这一点很难发现。它们不会产生错误或终止运行。相反,它们与其他代码融合在一起。

许多数据科学项目使用列表作为存储有序数据的方式。然而,未能正确使用它们可能会导致效率低下、结论不正确,甚至丢失数据。

以下是使用列表时要注意的 3 个错误:

1.用等于运算符创建列表的副本

错误:

复制列表时,不要使用=。这是非常违反直觉的,因为=是用来给变量赋值的。然而,=操作符并不创建副本,而是创建一个别名originalnew_copy都指向相同的数据位置,如下所示。

new_copy没有复制数据,而是创建了另一种访问original的方式。

修复:

为了避免这个错误,使用copy,一个列表的内置方法。此方法将数据存储在内存中的两个不同位置。因此,对一个列表的更改不会影响另一个列表。

2.迭代时更改列表大小

错误:

上面的例子试图从nums中删除所有以‘t’开头的条目。然而,‘three’依旧。这是因为nums的长度在循环中发生了变化。For 循环依赖于内部的零索引计数器,它会记住自己在循环中的索引。该计数器为每次迭代确定num的值。

例如,在循环的第一次迭代中,计数器为 0,而num为‘0’,因为nums[0] = ‘zero’。对于第二次迭代,计数器等于 1,产生num = ‘one’。对于第三次迭代,num = ‘two’又被从nums中移除。对于第四次迭代,内部计数器等于 3 和nums[3] = ‘four’。结果,循环跳过了‘three’值。

第二次迭代开始时,nums[3] = ‘three’。到最后,列表的大小改变了,并且‘three’值滑回到nums[2]位置。简而言之,循环改变列表,但不更新内部计数器。

修复:

为了避免这种错误,创建列表的副本,并使用该副本来定义 for 循环。然后,在循环体中使用原始列表(在本例中为nums)。

因为copy_nums的长度从不改变,所以循环遍历列表中的每个值。

3.不使用列表理解来创建列表

错误:

For 循环为构造列表提供了一个简单明了、文档完备的解决方案。然而,Python 有一个更简洁的方法——列表理解。List comprehension 采用了 for 循环的功能,并将其压缩到一行代码中,使其更简洁、更易于理解。

与其他两个错误不同,这个错误不会产生不正确的解决方案,只是效率较低。例如:

修复:

使用列表理解代替 for 循环。两者产生相同的输出,但是列表理解在大多数情况下更加清晰和快速。随着列表长度的增加,下图比较了两种方法的时间。

作者图片

结论

这篇文章的代码可以在这里找到

感谢您阅读我的文章。如果你喜欢我的内容,请考虑关注我。此外,欢迎所有反馈。我总是渴望学习新的或更好的做事方法。请随时留下您的评论或联系我 katyhagerty19@gmail.com。

https://medium.com/@katyhagerty19/membership

用 Python 快速生成基于文本的表格的 3 种简单方法

原文:https://towardsdatascience.com/3-simple-ways-to-quick-generate-text-based-tables-in-python-6db88ac0eed5

创建基于文本的表格的简单而有用的库

安尼尔·泽维尔在 Unsplash 上的照片

介绍

最近,我经常在早上花些时间阅读新的 Python 包。令人惊讶的是,有这么多简单而有用的库,我希望我能早点知道它们。

我试图将它们总结成不同的主题,在今天的这篇文章中,我想与您讨论其中的一个主题:“如何在 Python 中快速创建表?”。

现在,让我们看看这里有什么。

漂亮的桌子

PrettyTable 是一个 Python 包,允许您创建基本的 ASCII 表。不同的表格模式,如文本对齐或数据顺序,可以通过简单的代码轻松定制。更多细节,我们来看下面几个例子。

但是首先,通过以下方式安装该软件包:

!pip install prettytable 
from prettytable import PrettyTable as pt

创建表格

我们可以应用add_rowadd_column方法来生成想要的表格。表格输出如下:

图 1:用 PrettyTable 创建一个表格——作者的图片

  • Add_row(): 行被逐渐添加到表中。
tb = pt()#Add headers
tb.field_names = ["ID","Name", "Major","Grade"]#Add rows
tb.add_row([1,"Chi", "Statistics",3.5])
tb.add_row([2,"John","Business Administration"],3.6)
tb.add_row([3,"Lily","Satistics"],3.7)print(tb)
  • Add_column(): 列逐渐添加到表中。
tb1 = pt()#Add headers
column_names = ["ID","Name", "Major"]#Add columns
tb1.add_column(column_names[0],[1,2,3])
tb1.add_column(column_names[1],["Chi","John","Lily"])
tb1.add_column(column_names[2],["Statistics","Business Administration","Statistics"])
tb1.add_column(column_names[3],[3.5,3.6,3.7])print(tb1)

命名表格

我们可以用get_string(title = “table name")来给表格命名

图 2:向表格添加标题——作者图片

调整表格数据

使用align属性,我们可以控制数据向右、居中或向左对齐。例如,我想将列的数据值更改到左边,将align设置为l类似地,如果您想要右边的数据,将其设置为rc进行居中。

tb.align["Major"] = "l"

删除行

从表中删除不需要的行很容易。你所要做的就是应用del_row因为我不再需要最后一行,下面是我如何从我的表中删除它:

tb.del_row(2)

分类数据

sortbyreversesort有助于按特定顺序排列数据值。当sortby识别哪个列被排序时,reversesort指定排序的顺序。

从最高年级到最低年级对学生进行排序。

图 3:按作者排序数据—图片

tb.sortby = "Grade"
tb.reversesort = True

生成 HTML 输出

get_html_string的支持下,我们可以很容易地在控制台中生成 HTML 输出。

print(tb.get_html_string())

有平面的

制表是我想推荐的另一个库。基本上,它与 PrettyTable 非常相似,但我认为它比 PrettyTable 在定制网格方面更加灵活。我们将通过一些例子来看看如何使用制表属性定制这些元素。

我们可以通过以下方式安装此软件包:

!pip install tabulate

生成没有网格线的表格

图 4:无网格线—作者图片

df =   [["Chi", "Vietnam","Graduate"], 
        ["John","USA","Graduate"], 
        ["Lily","Belgium","Graduate"]]

#define header names
col_names = ["Name", "Country", "Program"]

#display table
print(tabulate(df, headers=col_names))

网格线生成表格

print(tabulate(df, headers=col_names, tablefmt="fancy_grid"))

图 5:带网格线的表格——作者图片

除了fancy_grid,还有一些其他的表格格式可以尝试,比如jiratextilehtml

向表中添加索引

添加索引:应用属性showindex = "always”显示索引

图 6:带索引的表格——按作者分类的图片

文本表格

个人认为这是三个库中可调性最强的一个库。它可以控制列宽,调整数据水平和垂直对齐,并灵活地改变表格的网格线。

生成表格

例如,下面的代码展示了我如何使用 Texttable 库创建一个表格。PrettyTable 类似,to 可以通过生成一个包含行内容的列表,并应用 TextTable 对象的add_row()函数将行添加到表中,从而将行插入到表中。

#Installing
pip instal texttable
import texttable as tt
tb = tt.TextTable()#Adding header and rows to the table
tb.header(["ID","Name", "Major","Grade"])
tb.add_row([1,"Chi", "Statistics","3.5"])
tb.add_row([2,"John","Business Administration","3.6"])
tb.add_row([3,"Lily","Satistics","3.7"])
print(tb.draw())

图 7:带文本的表格—作者图片

更改列的宽度

使用set_cols_width可以调整表格中的列宽。列表中的总数对应于表格中的列数。

tb.set_cols_width([11,12,15,14])

设置数据对齐

方法set_cols_alignset_cols_valign可用于在表格单元格内水平和垂直对齐数据。

使用set_cols_align(),输入可以设置为set_cols_align(['c','l','r']),对应居中、左对齐或右对齐。

使用set_cols_valign(),我们可以指定t用于顶部对齐,m用于中间对齐,b用于底部对齐。

注意,放入对齐函数的列表应该与一行中的值的数量一样长。

控制线

使用set_deco功能改变行和列之间以及标题和第一行之间的线条的绘制。在set_deco中,有四个控制元素:

  • texttable.BORDER表格的边框
  • texttable.HEADER标题下的行
  • texttable.HLINES行间的线条
  • texttable.VLINES各列之间的线条

通过在set_deco()中组合这四个元素,您可以决定表可以使用哪个特性。例如,在下面的代码中,我选择保留标题下的行和行之间的行。同时,我没有提到texttable.BORDERtexttable.VLINES意味着我关闭了列之间和表格周围的线条。

tb.set_deco(tb.HEADER | tb.HLINES)

图 8:控制线条——作者的图像

结论

以上是我对生成基于文本的表格的一些建议。我希望他们能在某些方面帮助你。

天气真好。

参考

https://www.statology.org/create-table-in-python/ https://www.geeksforgeeks.org/creating-tables-with-prettytable-library-python/

3 种软件工程技能可以让数据科学家受益

原文:https://towardsdatascience.com/3-software-engineering-skills-that-can-benefit-data-scientists-d9bcfcf192d3

意见

3 种软件工程技能可以让数据科学家受益

软件工程和其他有助于简化数据科学工作的非数据科学技术

彼得·冈博斯在Unsplash【1】上的照片。

目录

  1. 介绍
  2. DevOps 部署脚本
  3. Python 中的 SQL 查询
  4. 模型间的预处理自动化
  5. 摘要
  6. 参考

介绍

数据科学需要广泛的技能,大多数人在学术界遵循传统路线,如研究生学位,因此可能不会太重视软件工程。本文面向从非技术背景进入工作岗位的数据科学家,或者只是对软件工程有所帮助的其他方式感兴趣的人。对我来说,我在本科学位时没有学习工程/技术,所以我很惊讶在我的第一个数据科学角色中,我必须执行多少软件工程,以及它能有多大的帮助。数据科学完全是关于算法的,但是为了使用它们,你需要对软件工程有所精通。因此,下面,让我们讨论一下软件工程中可以帮助您改进数据科学流程的 3 个领域。

DevOps 部署脚本

Philippe OurselUnsplash【2】上拍摄的照片。

数据科学教育中最容易被忽视的话题可能是 DevOps 和机器学习操作,这两者都使用了某种形式的软件工程。其中一个原因是因为类不会有可以将算法部署到 AWS ( Amazon Web Services)之类的系统,可能是因为它很贵,对于较短的类风格来说太复杂了,而且还有很多不同的工具可以使用,所以重点往往是放在你的 Jupyter 笔记本上,或者只是本地预测。

以下是一些软件工程技能和场景的示例,它们对一些数据科学过程至关重要:

  • 当使用一个模型时,您会希望对代码进行修改,并在生产中更新模型。例如,其中一种方法是使用Docker,在这里您将构建并推动代码变更。虽然这听起来很简单,而且您不一定需要在本地完成,但是熟悉 Docker 文件语言,使用像FROMENVCOPYRUN这样的命令是非常有益的。
  • 除了脚本本身之外,您还想知道如何构建和推动代码变更。这个过程可以通过终端或 GitHub 库中的命令来完成,例如 docker image build [OPTIONS] PATH | URL | -

虽然 DevOps 不完全是软件工程,但它是与软件工程齐头并进的领域之一。例如,DevOps 中不一定有本科学位,但通常是 SE 中的某个人执行这些过程,这些技能对于希望更新其模型的数据科学家来说非常有价值(在这个用例中是)。当然,在其他情况下,数据科学家可能会在没有 docker 或 DevOps 的情况下执行不同的流程。

Python 中的 SQL 查询

David ClodeUnsplash【3】上的照片。

虽然 SQL 不仅仅是一种软件工程技能,但它也被许多人使用,比如数据工程师、数据科学家、数据分析师、业务分析师和产品经理。这里的区别在于,有时您会将 SQL 和 Python 结合起来创建一个脚本来自动运行您的 SQL 查询。

这一过程在以下情况下发生:

  • 从 SQL 创建一般查询
  • 创建从 SQL 启动任务的 Python 脚本
  • 添加 Python 来确保任务以特定的频率运行,比如说,每周一次,或者每小时一次
  • 添加 Python 来创建非静态值,例如,如果您想要查询一个月前的开始日期,您可以插入一个从另一个 Python 文件填充的参数,该参数指示多少个月前,比如说 1 或 12,以获取去年的数据。这样,您就不必编辑查询本身。

最终,您在这里所做的是使用软件工程技术来自动化和扩展您对数据科学模型数据的查询。

模型间的预处理自动化

Joshua SortinoUnsplash【4】上拍摄的照片。

最后一项技能是在面向对象编程方面纯粹使用软件工程。虽然您可以在您的本地笔记本中有更多的静态代码用于测试,这仍然是有益的,但是将运行您的模型的整个过程的不同的、有序的任务组合起来可能更简单。您甚至可以使用这种类型的编程来自动测试您的模型,以及测试准确性、错误等。)。

使用这种类型的编程的另一种方式是,您可以使用您的生产代码,但是在开发环境中运行它,因此您知道您的模型将如何以 1:1 的方式运行到生产中,但是不需要在生产中执行更改。

以下是如何自动化数据科学建模的预处理:

  • 如果你有不止一个模型,你可以有一个其他模型继承的基类,这个预处理文件可以用来过滤掉某些数据并在Pandas中创建新的特性,而不是从你的 SQL 代码中,这有时是数据科学家特别喜欢的。
  • 当您拥有预处理文件时,您的训练任务(建模过程中的下一个任务)可以读入预处理 Python 文件中生成的训练和测试数据。
  • 您可以创建一个流程来简化您的模型构建过程,从查询到预处理,再到训练,然后部署和预测。

当您的文件和模型数量开始增长时,这是非常有用的;它本质上允许您在不增加代码量的情况下提高生产率。

摘要

如果在您的数据科学之旅中,您还没有专注于软件工程,那么现在是开始学习的时候了。如上所述,本文主要面向初学数据的科学家,并告诉您不仅需要学习数据科学本身,如算法和统计,还需要学习软件工程技术,以便使您的数据科学工作更加容易和高效。是的,一些数据科学教育、训练营和认证计划确实包含了一些这方面的内容,但是拥有一个 3 天的课程,例如 SQL 介绍和 Python 介绍,不足以成为一个更全面的数据科学家。

总而言之,这里有一些非数据科学和软件工程技能和场景可以帮助您的数据科学过程:

** DevOps Deployment Scripts* SQL Querying Within Python* Preprocessing Automation Between Models*

我希望你觉得我的文章既有趣又有用。如果您同意或不同意这些提到的技能和用例,请随时在下面发表评论。为什么或为什么不?关于软件工程和数据科学,你认为还有哪些技能是重要的?这些当然可以进一步澄清,但我希望我能够阐明掌握软件工程如何在数据科学的许多方面帮助你。

我不属于这些公司中的任何一家。

请随时查看我的个人资料、 Matt Przybyla和其他文章,并通过以下链接订阅接收我的博客的电子邮件通知,或通过点击屏幕顶部的订阅图标 点击订阅图标,如果您有任何问题或意见,请在 LinkedIn 上联系我。

订阅链接:https://datascience2.medium.com/subscribe

https://datascience2.medium.com/membership】引荐链接:

(如果你在 Medium* 上注册会员,我会收到一笔佣金)*

参考

[1]由彼得·冈博斯Unsplash 上拍摄的照片,(2019)

[2]照片由菲利普·欧塞尔Unsplash(2021)拍摄

[3]照片由 David ClodeUnsplash 上拍摄,(2018)

[4]Joshua Sortino 在 Unsplash 上拍摄的照片,(2017)

3 个关于计算累计总数的 SQL 面试问题

原文:https://towardsdatascience.com/3-sql-coding-questions-on-computing-running-totals-bf657cca8d89

采访倒计时 P2:在这篇文章中,我提出了关于用窗口函数计算运行总数的三个常见编码问题的解决方案。

比安卡·加斯帕罗托摄于佩克斯

推荐给我的读者

你是在 学习 SQL 还是在为下一次 技术面试 而你喜欢这篇文章的提问风格?

那么,你应该看看由StrataScratch提供的SQL 编码挑战【T4**

在他们的平台上,你可以找到 FAANG 和其他主要科技公司提出的最新和最现实的面试问题,并决定你是否希望使用 SQL 或 Python 来解决这些问题。

介绍

窗口函数是可应用于数据集的分析函数,无需改变其粒度。

它们对记录窗口进行操作,为每一行返回一个值,而不是像GROUP BY那样折叠结果。

现在,让我直截了当地问你一个问题: 你真的想得到那份有趣又高薪的数据工作吗

好吧,如果你是,在你的下一次 SQL 技术面试中,准备好回答关于窗口函数的问题。他们经常会被问到。

“在你的下一次 SQL 技术面试中,准备好回答关于窗口功能的问题。更多的时候,他们会被问到。”

作为一名候选人,我不记得有哪一次 SQL 编码没有要求我编写某种涉及窗口函数的查询。

另一方面,作为一名技术面试者,我仍然会遇到申请数据领域中级职位的候选人,他们以前甚至从未听说过窗口函数!

对我来说,这是一个危险信号:如果您每天都要处理报表或 KPI,那么在某些时候,您一定需要按日期对维度进行排序,或者计算特定时间间隔内的累计总和。不要声称你总是用连接来做,我不会买它…

在之前的帖子中,我已经提到了一些关于排名的面试编码问题:

**</6-sql-window-functions-coding-problems-on-ranking-interview-countdown-p1-9be0ccf66453>

在本文中,我将与您分享一些关于用窗口函数计算运行总数的常见编码挑战。

SQL 运行总计语法

要计算累计,应使用以下语法:

**SUM(col) OVER ( partition_clause
                order_clause
                frame_clause )**

长话短说,当一个OVER()子句出现时,你在一个窗口函数前面。事实上,该子句用于定义将要执行SUM()操作的行组(又称分区)。

OVER()中的子句是可选的,因此当缺少这些子句时,将对整个结果集应用累加和,而不考虑特定的行组或顺序。

相反,指定一个partition_clause允许定义将应用累计的分区:

**SUM(col) OVER ( PARTITION BY col1, col2...)**

order_clause也允许定义累计应用于分区的顺序:

**SUM(col) OVER ( PARTITION BY col1, col2... ORDER BY col1 ASC|DESC)**

最后,frame_clause可以用来选择每个分区中的行子集,以应用运行总和。它本身由一个frame_start和一个frame_end组成,在一个分区内为用户提供了极大的灵活性:

**SUM(col) OVER ( PARTITION BY col1, col2... ORDER BY col1 ASC|DESC RANGE|ROWS BETWEEN frame_start AND frame_end)**

其中frame_start取下列值之一:

**N PRECEDING** -> (for instance 2 PRECEDING)
**UNBOUNDED PRECEDING** 
**CURRENT ROW**

并且frame_end取以下值之一:

**CURRENT ROW** 
**UNBOUNDED FOLLOWING** 
**N FOLLOWING** -> (for instance 7 FOLLOWING)

你能看到无穷无尽的组合,以及如果有效使用的话frame_clause将会给你带来的力量吗?

我认为,许多分析师仍然在计算窗口函数,而没有完全意识到框架如何支持他们的事业。

数据集+编码挑战

对于下面介绍的三个编码挑战,您将使用来自模式的公共仓库orders表,您可以通过他们的 SQL 编辑器直接查询该表,以及许多其他数据集。

orders表的前 10 行显示如下:

在您开始编码之前,请看一下这些规范:

  • 该表的主键是id字段。
  • 有多个accounts_ids,每个都可以关联一个或多个订单 id(id)。
  • 表格的粒度由timestamp决定,记录在occurred_at字段中。

问题 1 |难度:简单

面试官: “我想让你先写一个查询,生成一个按月分组的新数据集,而不是时间戳。该数据集应包括三个字段: account_idoccurred_monthtotal_amount_usd ,并且应仅针对以下账户进行计算:10411051106110141

然后,使用新的数据集,请计算一个按 *occurred_month* 排序的 运行总数 ,不折叠结果集中的行。只显示两列 occurred_month cum_amnt_usd_by_month

预期输出:

在输出中只显示 15 行中的 10 行。

面试官提示: “查询分两步。我建议首先创建一个新的数据集作为 CTE 的一部分,然后在其上计算累计”。

解决方案:在这个案例中,面试官正在测试一些技能。他们希望了解您是否可以使用CTEs,是否可以使用GROUP BY改变数据集的粒度,以及最终是否能够得到一个简单的运行总数:

因为没有指定分区,所以运行总计应用于整个数据集,并按(升序)occurred_month排序。

例如,对于 2016 年 9 月,运行总计等于6932.43,因为它是在CTE中计算的 8 月和 9 月部分合计的累积和:

问题 2 |难度:简单

面试官: “现在,使用与前面查询相同的 cte,请计算一个 运行总计 *account_id* ,按 *occurred_month* 排序。结果集应改为按 *account_id*排序,并包括三列,即:account_idoccurred_monthcum_mon_amnt_usd_by_account

预期产出:

解决方案:面试官只是要求你在OVER()子句中引入一个由account_id划分的部分,并保持与上一个练习中相同的顺序。然而,这一次,将为每个account_id运行单独的运行总计。

在这种情况下,还将测试您区分窗口中的排序结果和主查询中的排序结果的能力:

问题# 3 |难度:中等

面试官: “最后让我们来关注一下 *quantity* 领域。像你以前做的那样,先创建一个 *CTE* 来返回 *quantity* 并按 *occurred_month* 排序。

然后,使用 *CTE* 的输出,计算一个 3 个月的滚动运行总数 使用一个包含当前月份的窗口。将字段命名为 *cum_sum_3_months_right_rolling*

也计算一个 7 个月的累计运行总数 使用一个当前月份始终是中间月份的窗口。将字段命名为 *cum_sum_7_months_center_rolling* 。”

预期产出:

在输出中显示 38 行中的 10 行。

面试官的提示: “要解决这个问题,你需要使用一个 *frame_clause* 。在计算滚动累积和时,考虑 *current_row* 相对于您试图创建的帧的位置。

解决方案:要创建一个滚动的运行总数你需要使用ROWS BETWEEN语法。

在第一种情况下,您将包括2 PRECEDING行,而CURRENT_ROW将位于框架的右边缘。在第二种情况下,您将包括3 PRECEDING行和3 FOLLOWING行,并且CURRENT_ROW将位于框架的中间:

当没有足够的行来匹配帧所要求的数量时(在CURRENT ROW之前或之后),将只使用可用的行来计算滚动和。

为了理解这个概念,让我们看看CTE输出的幕后发生了什么:

例如,当试图计算cum_sum_7_months_center_rolling字段时,CURRENT ROW需要位于间隔的中心,这意味着当指针位于行1 ( 蓝色框)时,在中心 之后将只有行 ,而在中心 之前没有行 ,因此滚动求和将只在 4 行上执行( 213,863 【T63

但是,当指针在第4 ( 红框)行时,在 之前将有 3 条记录 ,在CURRENT ROW之后将有 3 条记录 ,这样在计算滚动和( 367,695 )时 7 天框将完全匹配。

结论

如果您的 SQL 技术面试倒计时已经开始,请确保准备好回答有关分析功能的问题。

为了支持您的旅程,在本文中,我讨论了如何使用窗口函数在 SQL 中计算累计值。

此外,您的知识已经过测试,解决了 SQL 编码中常见的 3 个编码难题。

祝你面试顺利,学习顺利!**

来源

*https://mode.com/sql-tutorial/sql-window-functions/ https://www.sqltutorial.org/sql-window-functions/

这篇文章包括附属链接,如果你购买的话,我可以在不增加你额外费用的情况下赚取一小笔佣金。*

数据科学家和数据工程师的 3 个 SQL 面试技巧

原文:https://towardsdatascience.com/3-sql-interview-tips-for-data-scientists-and-data-engineers-bbf7d859407c

不仅仅是回答 SQL 问题

照片由 Elisa VenturUnsplash 上拍摄

在过去的十年里,SQL 已经成为各行各业和各种工作岗位的通用技能要求。

像亚马逊和谷歌这样的公司通常会要求他们的数据分析师、数据科学家和产品经理至少熟悉 SQL。这是因为 SQL 仍然是数据的语言。

这导致 SQL 成为许多数据专业人员面试循环的主要部分。这意味着您最好计划将 SQL 包含在您的学习会话中。也就是说,仅仅解决 SQL 问题并不总是有效的。

在这篇文章中,我将介绍三个技巧来帮助你提高面试和一般情况下的 SQL。

尝试用多种方法解决 SQL 问题

解决大多数 SQL 问题的方法不止一种。

但是我们经常求助于我们最近用过的方法。

例如,如果你刚刚学习了分析函数,它可以为你未来的解决方案分类。这就是为什么尝试用多种方式解决 SQL 问题很重要。

为了解决我们所有的问题,我将使用 InterviewQuery 中的问题集,这是一个数据科学家可以用来练习比 SQL 更多内容的网站。

但是现在让我们看看他们提出的一个简单的问题。

我们有两个表,一个是包含人口统计信息和他们居住的街区的users表,另一个是neighborhoods表。

编写一个查询,返回所有有 0 个用户的邻居。

我们拥有的表格如下所列。

来源:访谈查询

这里我们有两个输入表和一个预期输出。在进一步阅读之前,你对如何获得 0 用户的社区名称有什么想法吗?

你的第一个回答是什么?

不管怎样,让我们看看第一个可能的解决方案。

这个解决方案依赖于左连接来返回任何没有用户的 u.id 为空的邻域。

但是这个例子可能有点令人困惑,因为它不明确,所以对某些人来说不可读。左连接有点让人读起来有点困难。这样做的原因是你必须在精神上管理你头脑中的逻辑。

让我们快速地看一下左连接将创建的“没有过滤器”的表。

资料来源:访谈查询

上面你会看到 user_id 有空值。这是因为我们左边的表是邻居。这意味着没有用户的地方,仍然会有邻居。

但是,这只是解决这个问题的一种方法。让我们以不同的方式编写这个查询。

有什么想法吗?

您可以查看下面的查询,它实际上是相同的东西,但是以更明确的方式。

此查询使用更显式的 HAVING 子句只对 u.id 进行计数。count 只在 u . id 不为 null 时进行计数。因此,这样一来,查询真正以同样的方式运行。

因此,如果用户表中没有与邻域 id 匹配的 ID,那么它将使用 null 替换 user-id。因此,如果我在 user id 为 NULL 的地方写,我将得到与 COUNT(u.id)相同的响应。

分解问题和逻辑

你得到的许多问题将要求你把逻辑分解成多个步骤。一个简单的例子是,当问题要求您获取事件的第一个实例时。

InterviewQuery 有这样一个问题,他们会问:

给定一个表song_plays和一个表users,编写一个查询来提取每个用户播放他们的第三首独特歌曲的最早日期。

下表列出了:

资料来源:采访查询

在这里,他们写出了他们想要第三首“独特”歌曲的事实。如果您只是要实现一个快速的 ROW_NUMBER ()函数,这应该是一个致命的提示,有多个歌曲播放的实例会打乱您的解决方案。

帮助简化的一个好方法是开始旋转一些形状。

首先,让我们创建一个数据集,该数据集只获得每个游戏的唯一实例。

这里有趣的是,我不同意 InterviewQuery 提供的解决方案,或者至少我不是 100%支持它。要获得一首独特的歌曲和第一次播放的日期,你应该能够只使用 MIN()获得第一次播放的日期。

您可以通过下面的查询做到这一点。

如您所见,我们需要做的就是获取歌曲 id 和用户的最小播放日期。这将清理连续播放的任何混乱的重复播放。使数据更容易处理。

InterviewQuery 建议使用 row_number()获取一首歌曲的首次播放。我发现这有点不太清楚,因为您现在将被迫进行第二次查询来获得第一个值。而使用 MIN()方法,您只有一个查询,并且已经缩减了数据集。

但是正如我前面提到的,获得大量 SQL 答案的方法不止一种。

我绝不讨厌 row_number()函数。事实上,在下一步中,我们将使用它。您可以在下面的查询中看到它。

从这里开始,其余的应该是不言自明的。我们需要查询第三行号码。如下所示。

还有一个问题。这实际上并不能解决 InterviewQuery 的问题。

这引出了我对 InterviewQuery 当前解决方案的另一个问题。InterviewQuery 希望我们返回所有用户,即使他们没有第三首歌曲播放。问题中没有提到这一点,我也看不到它的价值。但这些都是尼特。

他们有一个不同的解决方案,使用左连接,然后返回有和没有第三首歌曲播放的用户。所以一定要注意这个挑剔的细节。

了解如何进行非标准连接

许多人习惯于简单的连接。带一个基本的“=”。

这很好,但事实是连接可以像 WHERE 子句一样使用。

曾经有一段时间,联接并不存在,子句被用作联接。我偶尔还会看到一些人使用一长串 WHERE 子句进行连接,因为他们要么当前使用的是旧系统,要么曾经学习过 SQL,连接并不常见(SQL-92 中添加了显式连接)。

这意味着你可以用很多有趣的方式使用连接。例如,如果您曾经不得不在没有窗口函数的情况下计算滚动和,您将知道您可以使用">和

In our final question we are asked:

Given a table of students and their SAT test scores, write a query to return the two students with the closest test scores with the score difference.

If there are multiple students with the same minimum score difference, select the student name combination that is higher in the alphabet.

This is what the table looks like:

来源:InterviewQuery

花点时间想想你该如何解决这个问题。

别急着过来。有很多方法可以让这个问题变得特别复杂。

答案很简单。

但这一切都始于你需要创建一个每个学生和每个学生的分数的组合。

让我们来看一个可能的解决方案,并分析它为什么有效。

那么,为什么会这样呢?我们告诉查询在 ID 小于我们要连接的 ID 的所有情况下进行自连接。

这意味着我们正在创建一个类似于下表的表格:

作者图片

现在我们有了所有可能的学生 id 的组合,我们可以找到 ABS()分数的不同,并正确地设置顺序。

就是这样。

我要补充的最后一点是,我最终决定使用“!=" vs "

How Will You Take Your SQL To The Next Level

SQL looks like it is here to stay. It seems if anything it is picking up speed. The challenge is how do you take your SQL to the next level. It’s not just about learning new syntax.

It’s about learning how the data you’re working on can be manipulated using even simple clauses. In doing so you will be creating SQL at a much higher level and better prepare you for your SQL 面试

无论你是的数据科学家的数据工程师还是的分析师,我都祝你好运!

3 次 SQL 交换以编写更好的代码

原文:https://towardsdatascience.com/3-sql-swaps-to-write-better-code-f8d304699cde

如何确保您的代码是准确的、可读的和高效的

照片由丹尼斯·莱昂Unsplash 上拍摄

无论你是数据分析师、数据工程师、数据科学家还是分析工程师,你都必须编写干净的代码。你不应该是唯一一个能理解你写的东西的人。它需要让团队中的其他人能够阅读,以便在未来几年中使用和改进。

我最大的烦恼之一是当我发现草率的代码,然后写它的人已经不在公司了!没有办法知道他们在想什么,为什么他们以某种方式写逻辑。在我目前的角色中,这是一个持续的斗争,我正在重写我们所有的核心数据模型。

信不信由你,写 SQL 代码有好有坏。仅仅因为它运行并得到您想要的结果,并不意味着它是编写良好的代码。要被认为是好的代码,它必须是准确的、可读的和高效的。

这里有一些你可以在代码中进行的 SQL 交换,以确保它更具可读性和效率,这是编写良好代码的两个核心要素。

TOP →行号()

在重写旧的数据模型时,我经常遇到使用函数TOP的子查询。虽然这可能会让你得到你正在寻找的解决方案,但它很难阅读,并且可能需要很长时间来运行。

以下是我发现的一个例子:

SELECT
   customer_id,
   (SELECT
       TOP order_id 
    FROM orders
    WHERE orders.customer_id = customers.customer_id
    ORDER BY date DESC)
FROM customers 

作为工程师和分析师,我们希望确保我们正在编写尽可能干净和高效的代码。所以,如果你使用的是TOP,这里有一个函数可以代替。

ROW_NUMBER()是一个窗口功能,允许您为满足特定条件的每一行分配一个序号。使用ORDER BYPARTITION BY指定这些条件。

ORDER BY指定您希望如何对表格中的值进行排序。日期通常用于此。

PARTITION BY指定作为值分组依据的列。这取决于您查询的目的。

在这个例子中,我们需要ORDER BY date 和PARTITION BY customer_id。因为我们试图为每个客户找到最近的订单,所以按客户 id 进行分区将为每个唯一的 id 计算一个新的序列。

SELECT 
   customer_id, 
   order_id,
   ROW_NUMBER() OVER(PARTITION BY customer_id ORDER BY date) AS order_sequence_number 
FROM orders

现在,这将产生一个与原始表具有相同行数的表,但是,这一次有一个新的列order_sequence_number来指示每个客户的订单顺序。为了获得客户的第一个订单,我们需要编写另一个查询,只选择等于 1 的序列号。

WITHorder_row_number_calculated AS (
   SELECT 
      customer_id, 
      order_id,
      ROW_NUMBER() OVER(PARTITION BY customer_id ORDER BY date) AS order_sequence_number 
   FROM orders
)SELECT 
   customer_id,
   order_id 
FROM order_row_number_calculated
WHERE order_sequence_number = 1

现在我们有了一个 CTE,它在第一个查询中查找每一行的行号,然后通过只查找分组中第一个行号来过滤查询。这对任何人来说都更容易阅读,并且通常运行速度更快。

子查询→cte

上面显示的最后一个例子也可以用于这种交换!如果你看上面,我们从查询中的子查询开始,然后使用 cte 结束。

CTE 到底是什么?CTE 代表普通餐桌用语。它创建了一组临时结果,您可以在后续查询中使用。它要求您以WITH开始,并在每个 CTE 前使用 table_name AS。序列中的最后一个 CTE 应该是一个简单的 SELECT 语句,既没有 table_name 也没有AS

它应该是这样的:

WITH 
money_summed AS (
   SELECT 
      customer_id,
      date,
      SUM(balance) AS balance,
      SUM(debt) AS debt
   FROM bank_balance 
   GROUP BY customer_id, date
),money_available_calculated AS (
   SELECT 
      customer_id,
      date,
      (balance - debt) AS money_available 
   FROM money_summed 
   GROUP BY customer_id, date
)SELECT
   customer_id,
   money_available 
FROM money_available_calculated 
WHERE date = '2022-01-01' 

注意,在最后一个SELECT语句之前,我们没有使用表名或括号。前一组括号后面也没有逗号。一系列 cte 中的最后一个查询总是作为普通查询写入。请务必记住这一点,因为在使用 cte 时,由于格式化导致的错误是常见的!

≤和≥ →之间

使用日期列将两个表连接在一起是很常见的。大多数时候,当我看到这个的时候,他们是通过使用来连接的。虽然这种方法有效,但看起来很混乱。幸运的是,有一个更好的方法来做到这一点!

BETWEEN是一个 SQL 函数,允许您选择两个给定值之间的范围。它返回在你给它的值之间的值。它可以与数字、日期甚至字符串一起使用。

但是,最需要注意的是,这个功能是包含的。这意味着指定的值也将包含在您的结果中。所以,它只能真正取代而不是<>

首先,让我们看一个查询,它使用符号连接两个使用日期的表。

SELECT
   customers.customer_id,
   customers.activated_at, 
   campaigns.campaign_id
FROM customers
LEFT JOIN campaigns 
ON customers.campaign_id = campaigns.campaign_id 
WHERE customers.activated_at >= campaigns.started_at AND customers.activated_at <= campaigns.ended_at

WHERE子句中,我们需要使用activated_at指定两个不同的语句。一个是该列在≥ started_at处,另一个是≤ ended_at处。

现在,让我们使用BETWEEN

SELECT
   customers.customer_id,
   customers.activated_at, 
   campaigns.campaign_id
FROM customers
LEFT JOIN campaigns 
ON customers.campaign_id = campaigns.campaign_id 
WHERE customers.activated_at BETWEEN campaigns.started_at AND campaigns.ended_at

这里,我们只需要指定activated_at一次,而不是两次。

哪个查询更容易阅读和理解?虽然第一个可能不太复杂,但是代码中的小差异会产生巨大的差异。这就是好的和伟大的的区别。

结论

刚开始学习 SQL 的时候,你希望专注于能够解决给你的问题,并得到正确的答案。随着你发展自己的技能,变得更加自信,你需要努力改进如何找到解决方案。

每个工程师和分析师都希望他们的队友能够阅读他们的代码,并且容易理解。你不仅会讨厌回答无数的问题,而且他们也会讨厌问你这些问题。努力使您的 SQL 代码高效易读。如果有一个功能可以作为快捷方式,那就使用它!

另外,不要忘记文档的重要性。给你的代码加注释可以让其他人的工作变得容易很多,也省去了提问的必要。如果你认为你写的东西可能很难理解,解释它的意思!我坚信代码永远不会有太多的注释。

有关提高 SQL 技能的更多提示,请查看您需要了解的 8 个 SQL 日期函数如何使用 SQL 交叉连接,以及如何使用 SQL 窗口函数

Sklearn 中的 3 步功能选择指南,让您的模型焕然一新

原文:https://towardsdatascience.com/3-step-feature-selection-guide-in-sklearn-to-superchage-your-models-e994aa50c6d2

为任何受监督的问题开发一个健壮的特征选择工作流

了解如何使用最好的 Sklearn 功能选择器来面对机器学习的最大挑战之一。

照片由斯蒂夫·约翰森拍摄

介绍

如今,数据集拥有数百甚至数千个要素是很常见的。从表面上看,这似乎是一件好事——更多的特性提供了关于每个样本的更多信息。但通常情况下,这些额外的功能并不能提供太多的价值,反而会带来复杂性。

机器学习的最大挑战是通过使用尽可能少的特征来创建具有强大预测能力的模型。但是考虑到当今数据集的庞大规模,很容易忽略哪些特征重要,哪些不重要。

这就是为什么在 ML 领域需要学习一整套技能——特征选择。特征选择是选择最重要特征的子集,同时试图保留尽可能多的信息的过程(摘自本系列的第一篇文章)。

由于功能选择是一个如此紧迫的问题,有无数的解决方案可供你选择🤦‍♂️🤦‍♂️.为了减轻你的痛苦,我将教你 3 个特征选择技巧,当一起使用时,可以增强任何模型的性能。

本文将向您概述这些技术以及如何使用它们,而不需要过多了解其内部原理。为了更深入的理解,我为每一个都写了单独的帖子,并解释了细节。我们开始吧!

https://ibexorigin.medium.com/membership

获得由强大的 AI-Alpha 信号选择和总结的最佳和最新的 ML 和 AI 论文:

https://alphasignal.ai/?referrer=Bex

数据集介绍和问题陈述

我们将使用安苏尔男性数据集,该数据集包含 100 多种不同的美国陆军人员身体测量数据。在这个特征选择系列中,我一直在过度使用这个数据集,因为它包含 98 个数字特征,这是一个教授特征选择的完美数据集。

我们将尝试预测以磅为单位的重量,因此这是一个回归问题。让我们用简单的线性回归建立一个基本性能。LR 是这个问题的一个很好的候选,因为我们可以预期身体测量是线性相关的:

对于基本性能,我们得到了令人印象深刻的 0.956 的 R 平方。然而,这可能是因为在特性中也有以千克为单位的重量列,为算法提供了它所需要的一切(我们试图预测以磅为单位的重量)。所以,让我们试着不用它:

现在,我们有 0.945,但我们设法降低了模型的复杂性。

第一步:方差阈值

第一种技术将针对每个特征的单独属性。方差阈值化背后的思想是,具有低方差的特征对整体预测没有太大贡献。这些类型的要素的分布具有太少的唯一值或足够低的方差,因此无关紧要。VT 使用 Sklearn 帮助我们移除它们。

应用 VT 之前的一个关注点是特征的规模。随着要素中的值变大,方差呈指数增长。这意味着不同分布的特征具有不同的尺度,因此我们不能安全地比较它们的方差。因此,我们必须应用某种形式的标准化,将所有特征置于相同的比例,然后应用 VT。代码如下:

归一化后(这里,我们将每个样本除以特征的平均值),您应该选择一个介于 0 和 1 之间的阈值。我们没有使用 VT 估算器的.transform()方法,而是使用了get_support(),它给出了一个布尔掩码(应该保留的特征的真值)。然后,可以用它来对数据进行子集划分,同时保留列名。

这可能是一个简单的技术,但它可以帮助消除无用的功能。要获得更深入的见解和对代码的更多解释,您可以阅读本文:

第二步:两两相关

我们将通过关注特征之间的关系来进一步修整我们的数据集。显示线性关系的最佳指标之一是皮尔逊相关系数(表示为 r )。使用 r 进行特征选择的逻辑很简单。如果特征 A 和 B 之间的相关性为 0.9,这意味着您可以在 90%的情况下使用 A 的值来预测 B 的值。换句话说,在存在 A 的数据集中,您可以丢弃 B,反之亦然。

作者照片

没有一个 Sklearn 估算器实现基于相关性的特征选择。所以,我们要靠自己:

这个函数是一个简写,它返回根据自定义相关阈值应该删除的列的名称。通常,阈值将超过 0.8 才是安全的。

在函数中,我们首先使用.corr()创建一个相关矩阵。接下来,我们创建一个布尔掩码,只包含相关矩阵对角线以下的相关性。我们用这个掩模来划分矩阵的子集。最后,在列表理解中,我们找到应该删除的特征的名称并返回它们。

关于代码,我还有很多没有解释。即使这个函数工作得很好,我还是建议阅读我的另一篇关于基于相关系数的特征选择的文章。我充分解释了相关性的概念以及它与因果关系的不同之处。还有一个单独的部分是关于将完美的相关矩阵绘制成热图,当然还有对上述函数的解释。

对于我们的数据集,我们将选择阈值 0.9:

该函数告诉我们删除 13 个功能:

现在,只剩下 35 个特征了。

步骤三:交叉验证的递归特征消除(RFECV)

最后,我们将根据特性对模型性能的影响来选择最终的特性集。大多数 Sklearn 模型都有.coef_(线性模型)或.feature_importances_(基于树和集合模型)属性,显示每个特征的重要性。例如,让我们将线性回归模型拟合到当前的要素集,并查看计算出的系数:

上面的数据框显示了系数最小的特征。特征的权重或系数越小,它对模型预测能力的贡献就越小。考虑到这一点,递归特征消除使用交叉验证逐个移除特征,直到剩下最佳的最小特征集。

Sklearn 在 RFECV 类下实现了这种技术,它采用一个任意的估计量和几个其他参数:

在将估计量拟合到数据之后,我们可以得到一个布尔掩码,其中的真值对应该保留的特征进行编码。我们最终可以用它来最后一次对原始数据进行子集划分:

在应用 RFECV 之后,我们成功地放弃了另外 5 个特性。让我们在此要素所选数据集上评估最终的 GradientBoostingRegressor 模型,并查看其性能:

尽管我们的性能略有下降,但我们设法删除了近 70 个特性,从而显著降低了模型的复杂性。

在另一篇文章中,我进一步讨论了.coef_.feature_importances_属性,以及 RFE 每一轮淘汰赛中发生的额外细节:

摘要

功能选择不应该掉以轻心。在降低模型复杂性的同时,由于数据集中缺少分散注意力的特征,一些算法甚至可以看到性能的提高。依赖单一方法也是不明智的。相反,从不同的角度和使用不同的技巧来解决问题。

今天,我们了解了如何分三个阶段将要素选择应用于数据集:

  1. 基于使用方差阈值的每个特征的属性。
  2. 基于使用成对相关的特征之间的关系。
  3. 基于特征如何影响模型的性能。

在处理过程中使用这些技术应该可以为你所面临的任何监督问题提供可靠的结果。

关于特征选择的进一步阅读

https://ibexorigin.medium.com/membership https://ibexorigin.medium.com/subscribe

构建高效利用资源的气流管道的 3 个步骤

原文:https://towardsdatascience.com/3-steps-to-build-airflow-pipelines-with-efficient-resource-utilisation-b9f399d29fb3

照片由凯勒·尼克森Unsplash 拍摄

这篇博客着眼于一些对管理工作流中的资源有价值的气流特性。我们将探讨一些相互关联的概念,这些概念会影响任何数据管道的底层基础设施的资源利用。特别是,我们将探讨以下概念:

  • 气流池用于根据预定义的指标将资源分配给一组任务。
  • 并行&并发高效扩展管道,充分利用可用的基础设施。
  • 优先级权重用于确定的优先级,并在其他任务之前为关键任务分配资源。

本博客不着重介绍气流;要了解更多关于使用 Apache Airflow 构建管道的信息,请点击这里查看我的其他博客。事不宜迟,让我们开始探讨上面提到的话题。

1。气流池

作为数据工程师,我们构建多个管道来负责运行特定的工作流。解决方案需要一个 DAG 或一组 DAG 来实现预期的结果。例如,一组 Dag 将数据加载到数据仓库,另一组部署和监控机器学习模型,一些 Dag 启动或停止项目的基础设施。

有这么多 Dag,有时需要同时运行其中的几个,管理底层资源的分配变得至关重要。这样做很重要,这样气流就不会淹没基础架构或由于资源限制(如可同时运行的任务/Dag 数量)而阻碍业务关键型任务。我们可以使用池的概念将任务分配给资源。

照片由 Jonathan Chng 在 Unsplash 上拍摄

与游泳池类似,气流罐中的池是流程运行的区域。它包含 插槽 ,气流中的操作员一旦分配到池中就可以使用。根据任务的配置,任务可以使用一个或多个插槽。默认情况下,每个任务使用一个槽,并被分配给包含 128 个槽的 default_pool。

在单个池中运行所有任务是有问题的。例如,如果 airflow 实例正在利用池中的所有插槽,并且需要运行更多的任务,在这种情况下,任务将排队等待正在进行的进程完成。

在气流中使用水池

如下所示,我们可以使用管理面板访问 Airflow 中的池。我们还可以使用它来查看/修改所有现有池或创建新池。

作者图片

创建之后,我们可以使用操作符中的 属性将任务分配给池。我们可以让同一个 DAG 中的操作员,或者根据逻辑差异将多个 DAG 分配给不同的池。此外,如果池中的一些任务比其他任务需要更多的资源,我们可以使用操作符中的 pool_slots 属性为这些任务分配更多的资源。

例如,我们可以从下面的 DAG 中观察到,我们有一些关键任务和一些非关键任务。我们根据任务的重要性将它们分配到不同的池中。此外,我们为基本任务分配更多的 pool_slots,让 Airflow 知道这些任务需要更多的资源。

现在我们知道了如何配置池,要有效地使用它们,还需要一些额外的步骤。

  • 将任务分配给不同的池。在单个池中运行所有任务可能会有问题。例如,如果一个 Airflow 实例正在使用所有的槽,并且需要运行更多的任务,那么不管这些任务的重要性如何,它们都会被排队,直到一个正在进行的进程释放出一个位置。因此,我们可以为业务关键型作业创建一个池,为非关键型任务创建另一个池,并相应地为池类型分配操作。
  • 除了分离池,我们还需要管理池内的槽。我们必须确保业务关键型池有足够的槽,以便任务在开始处理之前不会等待太久。
  • 池的数量取决于用例。例如,我们可以为高、中、低关键任务设置三个池,或者为不同的工作流设置单独的池,例如一个池用于管理基础架构,另一个池用于管理数据管道等等。
  • 池中的插槽数量。可以帮助确定槽数的几个因素如下
    *】需要并行运行的任务数
    *】每个任务需要的槽数
    *】一个任务的时延容忍度。
    例如,如果一个池需要为一个管道并行运行 10 个任务,每个任务需要两个插槽,并且如果所有的任务都是不停机运行的关键,那么我们应该为池分配至少 20 个插槽来有效地运行管道。

2.并行和并发

在本节中,我们将了解池正常工作所需的一些气流配置。

  • 并行度:定义为一个气流实例可以同时执行**的任务数,即包括所有 Dag。如果 airflow 实例处于最大允许并行度容量,即将到来的任务将排队,而不管它们的池配置如何。
    例如,让我们假设具有以下配置的情况:
    *]要运行的任务:100
    ]池容量(槽数)= 200
    ]每个任务的槽数= 1
    假设 并行度 被设置为其默认值 32。在这种情况下,尽管池可以同时运行所有任务,但由于最大并行度的限制,它将在任何给定时间运行 32 个任务。
  • Dag_concurrency :定义为一个 DAG 中可以同时执行**的最大任务数。与并行性类似,dag 并发会影响工作流的资源利用率。并行性影响气流级别(即跨所有 dag)的任务排队,而 dag_concurrency 影响 DAG 级别的进程排队。
    例如,让我们假设具有以下配置的情况:
    ]要运行的任务:100
    ]并行度= 128
    ]池容量(槽数)= 200
    ]每个任务的槽数= 1
    假设
    Dag _ concurrency
    设置为其默认值 16。尽管配置的其余部分支持并行处理,但它受到 dag 并发性的限制。因此,所有超过 16 的操作都要排队。

3.优先级权重

在构建大数据管道时,有时我们希望将一组任务的优先级高于其他任务。例如,如果我们有多个数据源,并且在 ETL 过程中处理一些数据源比其他数据源更重要,我们可以配置我们的工作流来区分这些任务的优先级。

作者图片

从上面的 DAG 我们可以观察到,Airflow 运行一组任务,即在data _ source _ 2之前data _ source _ 1的 ETL。我们可以通过设置以下配置来实现:

  • priority _ weight:优先级权重是一个操作员的属性,为每个任务分配优先级。

  • weight_rule :权重规则决定了任务权重的计算方法。

在气流中,我们有如下三个重量规则:

  1. *Absolute :允许气流实例根据分配给每个任务的 priority_weight 对任务进行优先级排序。
    例如,让我们假设以下配置。
    *]priority _ weight = 2 for all critical_data 分支
    ]priority _ weight = 1 for all non _ critical _ data 分支
    现在,对于下面的 DAG,所有具有较高 priority_weights 的任务,即 critical _ data 任务,首先被调度和执行。

作者图片

2。上游:使用上游权重规则允许 Airflow 实例通过将操作的权重分配为等于其下游任务的权重之和来区分 DAG 中上游任务的优先级。
例如,让我们假设以下配置。
]所有任务的 priority _ weight = 1
现在,对于下面的 DAG,任务
load _ data _ source _ 1 _ pod _ 0*priority_weight 为 5 ,即下游任务为 4,自身为 1。

作者图片

3。下游:使用下游权重规则允许 Airflow 实例通过分配一个操作的权重等于其上游任务的权重之和来区分 DAG 中下游任务的优先级。例如,让我们假设以下配置。
] priority_weight = 1 对于所有任务
现在,对于下面的 DAG,任务
extract _ data _ source _ 1 _ pod _ 0*priority_weight 为 4,即上游任务为 3,自身为 1。

作者图片

如果任务属于同一个库,那么知道它们之间的优先级是可比较的是至关重要的。如果 DAG 中的操作员被分配到不同的池,则每个池中具有较高优先级的任务将首先执行。较高的 priority_weights 意味着 Airflow 将在服务任何其他排队作业之前运行这些任务。

结论

建立有效利用基础设施的数据管道是多种因素的结合。这篇博客探讨了其中一些相互关联的概念,以便管道可以基于底层资源和逻辑流进行伸缩。

参考

*https://airflow.apache.org/

阅读其他数据博客

在 Linkedin 上连接:

https://www.linkedin.com/in/vachan-anand-26bb76b7/ *

零经验找数据工作的 3 个步骤

原文:https://towardsdatascience.com/3-steps-to-getting-a-job-in-data-with-zero-experience-ccaad96d6477

帮助你开始分析生涯的实用建议

我最受欢迎的媒体文章之一是关于如何在没有 STEM 学位的情况下进入数据和分析领域。自从我写了那篇文章,已经有几个人通过 Linkedin 联系我,告诉我他们是如何按照我的一些建议找到第一份分析工作的。

距离我写那篇文章已经过去几年了,所以我正在写这个为 2022 年更新的更简单的版本。

我希望它能帮助更多的人开始你的分析之旅。

第一步——建立一个书面文件夹。

建立一系列代表你的数据技能的博客/文档/发表的论文。每一篇文章都应该清楚地解释你着手解决的一个问题,以及你用来解决这个问题的数据技巧——可视化/算法/分析。把它们都放在一个地方(LinkedIn 或者 Medium 或者网站)。在你的 LinkedIn 页面上展示这些,并与你的社交网络分享。因为你没有“商业”经验——这些片段将是你向世界解释你能做什么和你的技能有多熟练的主要方式。

对于这些文档,选择与业务相关的问题。一些示例包括:分析营销活动绩效、预测收入、预测执行某项操作(购买、转换、打开、查看)的可能性、创建显示业务 KPI 的执行仪表板、将 API 中的数据收集到数据库中、使用算法或 SQL 创建市场细分、零售销售分析等等。你可以在 Kaggle 上找到与这些问题中的一个或多个相关的数据集——或者通过快速的谷歌搜索。

这些文档将充当你的“简历”,因为在这一点上,你并没有一份专门针对数据分析的简历。你会经常指向这些文档,并在你的 Linkedin/Twitter 或其他地方分享,向潜在雇主展示你的领域知识。

当你开始写这些文章时,你会觉得这是在浪费时间——我是说,谁会在乎一篇博文呢?我向你保证,即使没有人阅读它们,在你想工作的领域创造内容的练习至少会提高你的技能,没有什么比这更好的了。

第二步——在 Coursera/Data Camp/Udemy 上获得认证。

像 Coursera 和 Udemy 这样的网站上有很多课程,你可以把证书和简历放在你的 LinkedIn 页面上。你可能已经掌握了他们教授的许多技能——但这里有一个秘密:许多这些课程允许你通过测验来测试整个部分。这样做可以让你从可靠的来源快速收集一系列证书,并展示给潜在的雇主。

自从我写了我的原创文章以来,在线认证在行业中获得了更大的力量。像谷歌和特斯拉这样的公司已经完全放弃了大学学位的要求,这将为许多其他效仿的公司提供机会。事实上,谷歌最近凭借自己的一套课程进入了在线学习领域,该公司将这些课程视为等同于该学科的四年制大学学位。谷歌甚至提供数据和分析证书。

这意味着,如果你完成了谷歌数据和分析证书,你可以向雇主发出信号,表明你拥有世界上最大和最负盛名的科技公司之一正在寻找的数据技能。

归根结底,证书之类的东西都是广告——它们向雇主发出信号,表明你拥有有效完成工作的技能。谷歌进入这一领域使得广告对普通雇主来说更有价值。正如他们所说,水涨船高。

照片由马体·米罗什尼琴科佩克斯拍摄

第三步— 瞄准你想要的入门级工作,在那里你拥有他们要求的大约 80%的技能,并正确地制作你的简历。

一旦你完成了第一步和第二步,就该去找工作了。

对许多人来说,这实际上是最具挑战性的一步。因此,这里有一些提示,让这个过程的最后一部分变得简单一点。

  • 上 Linkedin 找工作,列出一大堆你想要的“入门级”工作。入门级意味着他们想要有 1-3 年经验的人。如果他们要求 3 年以上的工作经验,招聘人员不会看你的简历——即使你能胜任这份工作。众所周知,有时招聘人员会在这里犯错误,将入门级的工作列为需要博士学位和 15 年的工作经验。不幸的是,找工作全凭感觉。即使这些要求很荒谬,但你觉得自己很合格,仍然不值得你花时间去申请,因为招聘人员会忽略你的简历。关键是你拥有工作清单所要求的 80%的技能——如果你达到了这个门槛,你仍然可以进入这个大门。
  • 用关键词和结果陈述充实你的简历(问题→你做了什么→结果),与你想要的工作保持一致。一个策略是把工作清单的文本放入文字分析器(Google this)——然后确保你的简历被他们列出的关键词填满。我意识到这就像它听起来一样——关键词填充。你不想做得太过分,但为了通过简历筛选,你绝对必须这样做。数以千计的合格候选人因为他们的简历中没有足够的筛选系统正在寻找的关键词而被淘汰。只要在你的结果陈述中明智地做到这些,你就会增加接到电话的机会。
  • 如果你没有足够的或者任何重要的工作可以在简历上列出来,不要害怕从你的书面文件夹中拿出来。我怎么强调都不为过。在简历上列出你的个人项目是完全可以的。只需在简历上加上“相关经历”这个副标题,就万事大吉了。如果你遵循了我在第一步中的建议——你将会有几个个人项目以及问题/你做了什么/结果陈述。
  • 在你有关系的地方,尽可能地利用你的关系。不要害怕直接联系招聘人员来获得你在 LinkedIn 上想要的工作。你通常可以通过在 Linkedin 上搜索“[公司名称],招聘人员”来找到你想要的招聘人员,然后你可以直接给他们发信息。有些人可能不喜欢这样,但这就是招聘人员的目的——嘿,你在努力找工作。通过运用这一技巧,我个人已经在不同的公司获得了 3 次单独的面试机会,而如果不直接联系招聘人员,我就不会有这样的机会。

找一份没有经验的数据工作是一场艰苦的战斗。但是在实际工作之外,做一点工作来充实你的经验,这是可以做到的。最后一个建议是,如果你能在实际业务中获得咨询/自由职业/免费工作,那将会有很大的不同。然而,不要依赖这一点,因为让你访问他们的数据可能是一个很大的要求。

希望这篇文章中的步骤和技巧能够帮助更多的人在分析领域找到工作。

如果你有具体的问题,请随时直接在 Linkedin 上给我发信息,或者在 camw81@gmail.com 给我发邮件。

在 Medium 上关注我,获取更多关于数据、分析、职业和商业的文章。

任何 DAX 查询故障排除的 3 个步骤

原文:https://towardsdatascience.com/3-steps-to-troubleshoot-any-dax-query-d02a4829cc25

排除 DAX 性能故障是最具挑战性的任务之一,但也是最有意义的任务!了解如何利用 DAX Studio 外部工具来快速了解 DAX 查询缓慢的原因。

作者图片

免责声明:这是而不是一篇关于 DAX 的深度文章!本文的主要目的是帮助您熟悉各种 工具 来解决 DAX 查询的性能问题。如果你想学习和理解 DAX 语言,这里是我的资源列表,可以帮助你步入正轨:

之前的一篇文章中,我们介绍了 Power BI 中的一个内置特性——性能分析器,它可以帮助您了解报告页面性能背后的不同指标,并快速识别潜在的瓶颈。然而,Performance Analyzer 不仅仅如此,它还为您提供了获取生成的 DAX 查询以填充某个视图,然后利用其他工具对该查询进行故障排除的可能性。

对性能不佳的电源 BI 报告进行故障排除时,最常见的工作流程如下:

作者插图

前两步非常简单明了。然而,第三步不仅需要知道 DAX 语法,还需要对 Power BI 内部和引擎工作方式有一个扎实的理解。您可以在本文的中找到关于底层架构的两个关键组件——公式引擎和存储引擎——的更多详细信息,我强烈建议您在继续之前阅读它,因为它将帮助您更好地理解这里描述的步骤和过程。

了解要排除哪些故障…

现在,当您处理糟糕的报告性能时,第一个问题是—我应该排除什么故障?!这是一个公平的问题。此外,Performance Analyzer 可以帮助您确定主要问题,然后应该对其进行更深入的调查。

为了举例说明,我将向您展示一个简单的报告页面,上面有 3 个可视元素——两个简单的卡片视图和一个表格视图。基本指标是订单总数,同时我也想知道我的客户下了多少大订单。什么是大订单?销售额超过 500 美元的所有订单。

下面是我用来计算销售额大于 500 的订单总数的度量定义:

Total BIG Orders Bad =
CALCULATE (
    DISTINCTCOUNT ( 'Online Sales Filtered'[SalesOrderNumber] ),
    FILTER ( 'Online Sales Filtered', 'Online Sales Filtered'[SalesAmount] > 500 )
)

你很快就会意识到为什么我把“坏”加到度量名中…

作者图片

这是我的报告页面的外观。那么,让我们打开性能分析器,看看这个报告是如何执行的:

作者图片

如你所见,卡片视觉效果非常快。但是,表格可视化需要 11 秒以上的时间来渲染。而且,与上一篇文章不同,当大量的页面视觉效果是报告性能缓慢的主要原因时(记住性能分析器中的 Other 值),这一次 Other 根本不是问题。几乎所有 11.3 秒的总时间都花在 DAX 查询上——这意味着您的“敌人”是 可能是DAX 查询。

我有意使用 word possible,因为可能发生的情况是,您的数据集太大了,所以即使您的 DAX 代码是最佳的,引擎也只是需要更多的时间来扫描数据和检索结果。然而,在本例中,我的表“只有”1260 万行,这对于 VertiPaq 数据库来说并没有什么特别的。

因此,我们在故障排除工作流程中迈出了非常重要的第一步— 我们确定了最有问题的查询。 因此,此时我们将忘记卡片的视觉效果,将注意力转移到理解为什么这张桌子的视觉效果如此之慢…

步骤 2 捕获查询计划并使用 DAX Studio 进行分析

一旦您确定了有问题的元素,您就可以轻松地获取生成的查询来填充该特定的可视化内容:

作者图片

我现在将转移到 DAX Studio,一个由 Darren Gosbell 开发的奇妙的免费工具。这个工具是 Power BI 开发工具箱中的必备工具,在本文中,我不会浪费太多时间来描述 DAX Studio 的所有惊人特性和功能。

这里的目标是向您展示如何利用 DAX Studio 对 DAX 性能进行故障排除:

作者图片

为了能够对查询进行故障排除,您需要更多关于它的详细信息。因此,我将打开查询计划和服务器计时特性,开始跟踪我的查询。下一步是将从性能分析器捕获的查询粘贴到 DAX Studio 的主窗口中:

作者图片

让我们先来看看“服务器计时”选项卡:

作者图片

让我停下来解释一下“服务器计时”选项卡的主要属性:

  • 总计 —以毫秒为单位显示总的查询持续时间。换句话说,您会看到我的查询用了 11.3 秒来执行
  • SE CPU —存储引擎查询所花费的 CPU 时间。由于存储引擎以多线程方式工作,因此在运行查询时能够实现一定程度的并行性。在我们的例子中,查询总共花费了 75 秒的 CPU 时间
  • SE 和 FE —存储引擎和公式引擎之间的时间分割。显示为数值和百分比
  • SE 查询 —存储引擎查询数

让我们在这里快速回顾一下我们的具体计算。正如您可能注意到的,在 Server Timings 选项卡的中心区域有一大堆查询。它们的速度都很快——不到 10 毫秒。但是,问题是它们有很多…准确地说,有 1099 个查询。当您用 ca 乘以 1099 个查询时。每个 10 毫秒,你总共得到我们的 11 秒。

在这种情况下,主要问题是我在用于计算大订单总数的 DAX 公式中不恰当地使用了 FILTER()函数。FILTER 函数接受两种类型的对象作为第一个参数—表或列。如果您将整个表作为一个参数传递(尤其是当表很大时),这意味着存储引擎将不得不扫描和具体化大量数据,就像我的情况一样,我为每个日期运行一个单独的查询。

现在,因为我的计算中唯一的条件是基于单个列值,即销售额值,而不是将整个表作为参数传递,所以我可以重写我的计算,只基于某一列应用筛选:

Total BIG Orders Good =
CALCULATE (
    DISTINCTCOUNT ( 'Online Sales Filtered'[SalesOrderNumber] ),
    FILTER (
        ALL ( 'Online Sales Filtered'[SalesAmount] ),
        'Online Sales Filtered'[SalesAmount] > 500
    )
)

这两个公式之间的差别是微妙而重要的:在这两种情况下,计算逻辑是相同的,但是过滤函数的不同用法可能会对查询性能产生巨大的影响。与第一个定义不同,这次我将使用一个与 ALL 函数结合使用的筛选函数——ALL 函数将首先从 sales amount 列中删除所有活动的筛选,完成后,我将应用我需要的筛选——只保留 Sales Amount 大于 500 的那些行。但是,这一次,我没有将范围放在整个表中,而是在单个列级别上操作。

我在 Power BI 报告中创建了两个单独的表,分别测量两种计算的性能:

作者图片

正如你可能注意到的,“坏的”表仍然需要超过 11 秒的时间来渲染,而“好的”表只需要 1/3 秒多一点。这是一个巨大的差异!此外,我们可以确认两个表中的结果完全相同。

我现在将复制更快的查询,并检查它在 DAX Studio 中的外观:

作者图片

这一次,不是 1099 个 SE 查询,而是只有 3 个(其中 2 个在计算总数)。此外,SE CPU 时间不再是 75 秒,现在只有 1.5 秒。最后,总的查询执行时间从 11.3 秒减少到 263 毫秒…

除了“服务器计时”选项卡之外,您可能还想检查“查询计划”选项卡。在这里,您可以检查实际的物理和逻辑查询计划。理解查询计划超出了本文的范围,因为即使对于经验丰富的 Power BI 专业人员来说,这也是一个复杂且具有挑战性的过程。但是,当试图理解公式引擎在将 DAX 代码转换为应由存储引擎执行的一系列物理操作时所执行的各种步骤时,它会非常有帮助。请记住,物理查询计划不一定要遵循逻辑计划中定义的步骤顺序。

作者图片

现在,引入这个例子并不一定是为了演示如何优化 DAX 公式(尽管如此,如果您在这方面也有所了解,这当然不会有什么坏处)——我想向您展示如何利用 DAX Studio 及其令人惊叹的内置功能,如服务器计时和查询计划,来了解您的视觉效果的数据检索过程的细节。

结论

在使用 Power BI 时,对 DAX 查询进行故障排除是最具挑战性的任务之一。然而,与此同时,这也是您可以实现最显著的性能改进的地方。

这是 DAX 优化工作流程的高级概述:

作者图片

DAX Studio 在此工作流中起着关键作用,因为它使您能够对可能有问题的 DAX 查询进行故障排除,并更深入地了解呈现报表视觉效果时幕后发生的情况。

感谢阅读!

成为会员,阅读 Medium 上的每一个故事!

用人工智能重新定义你的高管职业道路的 3 个策略

原文:https://towardsdatascience.com/3-strategies-to-redefine-your-executive-career-path-with-ai-442ae035a41c

迈克·莱温斯基在 Unsplash 上的照片

领导者可以使用人工智能教育的三种方式

人工智能(AI)正在破坏每个行业的业务和工作角色,引起人们对低技能体力工作和管理角色等长期工作保障的担忧。

为了为这个人工智能驱动的经济做准备,许多经验丰富的经理和资深高管正在转向 MOOCs(大规模开放在线课程),以提升基础数据分析和人工智能方面的技能。这一趋势不太可能很快放缓:全球 MOOC 市场预计将从 2018 年的 39 亿美元增长到 2023 年的 208 亿美元,CAGR 为 40.1%。

商业和技术相关课程占这些在线课程的 40%。许多大学也加入了通过提供高接触高管教育项目来填补人工智能领导力缺口的努力。

虽然技能提升项目很容易获得,但许多高管不确定如何利用他们新获得的技能来推进自己的职业生涯。鉴于这些角色的高技术门槛,成为人工智能“从业者”可能不是一些人的正确选择。其他人可能会排除“初级化”,这可能会让他们在职业生涯中倒退几步。

围绕人工智能建立职业生涯的 3 个挑战

完成此类计划的组织领导通常有三个问题:

  • 我能过渡到领导人工智能组织计划的技术领导角色吗?
  • 我如何将我的职能领导经验与我新获得的人工智能技能结合起来?
  • 在今天的人工智能经济中,我可以在职业生涯中期转向哪些新角色?

这些问题并不容易回答,职业生涯中期的转变也不容易。根据我指导个人和帮助公司采用人工智能相关技术的经验,这里有三个领导者可以采用的战略来重塑他们的职业生涯。

1.转变为在整个组织中领导人工智能的技术角色

安迪·赫尔曼万在 Unsplash 上的照片

企业正在建立人工智能卓越中心,并增加新的高级职位,如首席数据官(CDO)或首席分析官(曹)来领导数据和分析。Gartner 发现72%的受访组织的数字化转型是由 CDO 等数据高管领导或严重影响的。获得人工智能技能的高级管理人员可以重塑他们的职业生涯,通过领导组织内的人工智能计划转变为以技术为中心的角色。

这些组织转型需要领导者能够预见和制定如何将分析融入企业核心的战略。他们还需要优秀的执行能力来建立数据和分析团队,确保公平和道德地使用人工智能,并帮助促进数据驱动的决策。总的来说,这个角色需要良好的思维领导力、情商和解决冲突的技巧。

NewVantage Partners 发现49%的公司倾向于从内部为这种新兴的以数据为中心的领导角色配备人员,利用可以充当内部变革代理人的人。

2.通过利用人工智能的能力提高你的功能专长

照片由 Yusuf EvliUnsplash 拍摄

企业正在面向客户的产品和内部运营中广泛实施人工智能。随着公司越来越受分析驱动,他们需要能够在其职能范围内支持人工智能驱动的战略计划、促进团队之间的协作以及通过管理变化来推动采用的领导者。这些“人工智能指挥者”的一个关键区别属性是深厚的功能经验和对如何应用人工智能产生商业价值的深刻理解。

谈到人工智能,大多数企业主要关注高级技术角色,如首席数据科学家、人工智能经理或首席分析官。然而,没有强有力的职能领导,人工智能的成功是不可能的。这种不平衡的关注可以帮助解释今天人工智能面临的最大挑战之一:尽管超过 95%的组织已经投资人工智能,但只有 26%的组织报告称正在创建一个数据驱动的组织。商业领袖必须带头推销他们对人工智能的愿景,确保团队之间的协作,并在自己的业务中采用人工智能解决方案。

3.打破常规,创造新的组织角色

达维素子Unsplash 上的照片

埃森哲对 1000 多家大公司的全球研究指出,出现了三种新的人工智能相关工作:

  • 训练员和机器一起工作,教人工智能系统高效准确地工作。
  • 讲解者提供清晰度,并在人工智能专家和商业领袖之间架起一座桥梁。
  • 维持者通过避免人工智能支持的自动化的意外后果,帮助维持运营。拥有丰富行业经验的管理者和领导者将会很好地适应解释者和支持者的角色。

让我们以传统的贷款经理为例,他的主要工作是检查、评估和处理信贷额度。像 Rocket Mortgage 这样的在线贷款发放平台的兴起可能会让贷款经理过时。然而,美国的信贷和贷款监管框架目前尚未构建来实施公平的人工智能。

这些贷款经理可以补充他们现有的知识,成为“贷款解释者”或“贷款道德经理”——例如,可以解释为什么客户的贷款被“黑盒”机器学习算法拒绝的人。同样,这一角色可以帮助贷款人避免潜在的歧视问题,并确保遵守围绕人工智能使用的快速发展的监管准则。

将战略付诸实施

从上述三种策略中选择合适的策略取决于许多因素——你的职业抱负、手头的机会和你的风险偏好。高级经理和高管必须通过融合他们当前的优势和新获得的人工智能技能来发挥创造力,以便在人工智能时代领先。

值得注意的是,领导者不必被组织内部存在的机会所束缚;他们可以在自己的行业中寻找创业机会。就在疫情中部,2021 年风险投资基金在全球投资了创纪录的 2680 亿美元。对于有经验的经理来说,初创公司可能是一个有吸引力的提议,这些经理将对行业服务不足的需求和客户痛点的深刻理解与人工智能释放的新可能性相结合。

通过提高你的可信度来推动你的人工智能职业转型

KOBU 社Unsplash 上拍摄的照片

如今,职业转型因容易获得技能提升计划、丰富的社交平台和建立强大个人身份的便捷途径而变得容易。

人们经常建议领导者通过 LinkedIn 的存在、文章中的新闻字节和活动参与来建立个人品牌。虽然一个吸引人的个人品牌可能会让你的个人资料更有吸引力,让你在社交媒体帖子上获得更多的喜欢,但强大的个人可信度将有助于与相信你工作的人建立深厚的联系。

为了提高你的可信度,以增加价值为目的建立关系网,就人工智能在商业中的应用提出强有力的观点,并能够以令人信服的方式阐述你的想法。例如,人工智能领域刚刚起步,还没有严格的监管(尽管它非常需要)。如果你对组织和社区如何负责任地采用人工智能有什么看法,请分享。从事参与性法规关于 AI 在你所在行业的使用。

建立个人信誉需要时间和努力。确保你不断学习,持续参与,并建立一个连贯的足迹。这可以带来更好的职业选择和更充实的职业生涯。

本文首发于 企业家项目 。增加了插图。

我们对顶级 ML 团队调查的 3 点收获

原文:https://towardsdatascience.com/3-takeaways-from-our-survey-of-top-ml-teams-c53067fba50e

图片由作者提供

与 DevOps 或数据工程相比,MLOps 作为一个学科仍然相对年轻,尽管有了巨大的增长。虽然人们很容易与 DevOps 相提并论,特别是因为它的一些最佳实践很容易被移植到 MLOps 中,但大多数业内人士都认为,在将 ML 投入生产时,存在一系列独特的挑战和需求。不幸的是,很少有强有力的行业调查来记录团队如何应对这些挑战。

为了弥补这一点,并让 MLOps 从业者从同行那里了解如何在专业上取得成功,并运送和维护更好的模型,我们最近对 945 名数据科学家、ML 工程师、技术高管和其他人进行了调查。结果表明,当模型失败时,明显需要更顺畅的跨团队协作和改进的工具来帮助更快地进行根本原因分析。

以下是三个关于 ML 监控和可观察性的调查结果——以及关于团队可以做些什么的建议。

解决模型问题仍然非常痛苦和缓慢

尽管取得了进展,但在生产环境中进行故障诊断、分类和解决模型问题时,ML 团队经常面临延迟和挫折。总的来说,84.3%的数据科学家和 ML 工程师表示,检测和诊断模型问题所需的时间至少有时是他们团队的一个问题,超过四分之一(26.2%)的人承认,他们需要一周或更长时间来检测和修复模型问题(即在检测到概念漂移后在生产中重新训练模型)。一周或更长时间的延迟在金融服务中最为常见,紧随其后的是医疗保健和技术。

资料来源:阿里泽·艾对大联盟球队的调查

根据近一半(48.6%)的团队,这些问题可能会因大流行后的环境而加剧,其中漂移和性能问题会增加。

资料来源:艾瑞泽艾对大联盟球队的调查

建议: 评估并实现一个有助于暴露和消除 AI 盲点的 ML 可观察性平台。

几乎所有的 ML 团队都监控已知的模型指标,如准确性、 AUC 、F1 等。—大多数人也试图通过可解释性来解决黑盒人工智能(已知的未知)。然而,经常缺少的是暴露团队没有积极寻找的问题的解决方案:盲点,或者未知的未知。真正的 ML 可观察性可以帮助消除盲点,在潜在问题影响业务结果之前自动将其暴露出来。使用现代 ML observability platform 的团队可以快速可视化所有潜在问题,并且只需点击几下鼠标就可以执行根本原因分析,而不是编写看似没完没了的查询来找出性能下降的原因。

ML 团队需要与业务主管更好地沟通

尽管事实上,在新冠肺炎会议之后,ML 模型对业务结果更为关键,但超过一半(54.0%)的数据科学家和 ML 工程师报告说,他们经常遇到业务主管无法量化 ML 计划的 ROI 的问题,几乎同样多的人(52.3%)还报告说,业务主管并不一贯理解机器学习。可能导致这种脱节的事实是,“与团队中的其他人共享数据”和“当新模型更好时说服利益相关者”仍然是问题,至少有时对于超过 80%的 ML 实践者来说是这样。

资料来源:艾瑞泽 AI 对 ML 团队的调查

建议: 提高内部知名度,增加 ML 素养,将模型指标与业务结果联系起来

业务高管需要更好地访问工具和可消化的相关 KPI——最重要的是,包括量化人工智能 ROI 的方法。通过将 ML 模型性能指标与关键业务指标联系起来,并允许高管访问跟踪进度的仪表板,ML 团队可以确保更广泛的参与。为了帮助实现这一点,评估 ML 可观察性平台的 ML 团队可能希望考虑产品功能,如支持设置用户定义的函数以将模型性能与业务结果联系起来,将预生产模型与当前生产模型(冠军和挑战者)进行比较的能力,以及动态分析基于概率的决策模型阈值的能力。此外,支持保存了过滤器的图表共享链接的平台也有助于跨团队协作。

可解释性很重要,但不是一切

尽管技术高管高度重视的可解释性,ML 工程师——他们通常是将模型投入生产并在生产后对其进行维护的人——将监控和排除漂移列为更高的优先级,将可解释性与监控性能和数据质量问题放在同等重要的位置。

资料来源:艾瑞泽 AI 对 ML 团队的调查

推荐: 不要单靠可交代性;采取积极主动的方法来模拟绩效管理

在模型生命周期的预生产阶段关注可解释性——在部署之前训练模型并验证它——可能是有用的。然而,一旦模型投入生产,继续在可解释性上花费大量资源的效用是有限的,因为它创建了一个被动的反馈循环。虽然可解释性在对生产中的模型性能进行故障排除时有助于排序,但它不能像数据质量监控那样帮助您发现盲点,例如,在推理分布发生重大变化之前帮助您主动捕捉潜在问题。通过在给定的模型上设置自动化的性能监视器,ML 团队可以拥有第一道防线——特别是如果能够 A/B 比较数据集并执行数据质量检查的话。跨环境或生产前期的漂移监控也可能是模型输出发生变化的早期信号。

结论

虽然这些并不是 MLOps 团队面临的唯一问题,但根据被调查者的说法,它们是一些最突出的问题。请参阅报告中按行业和角色列出的完整调查结果列表:“调查:行业已经为大规模的 ML 可观察性做好了准备

3 从多元非线性数据集构建机器学习回归模型的技术

原文:https://towardsdatascience.com/3-techniques-for-building-a-machine-learning-regression-model-from-a-multivariate-nonlinear-dataset-88b25fc24ad5

关于数据转换、多项式回归和非线性回归的一切

刘烨·埃斯塔班在 Unsplash 上拍摄的照片

当目标变量和预测变量之间的关系为线性时,简单线性回归(SLR)模型易于构建。当因变量和自变量之间存在非线性关系时,事情就变得更复杂了。在本文中,我将向您展示在同一个非线性数据集上构建回归模型的三种不同方法:

1.多项式回归
2。数据转换
3。非线性回归

数据集:

我考虑的数据集取自 ka ggle:https://www . ka ggle . com/datasets/Yasser h/student-marks-dataset

数据由学生的分数组成,包括他们的学习时间和课程数量。

数据帧细节(作者图像)

如果你检查目标变量“标记”与学习时间和课程数量之间的关系,你会发现这种关系是非线性的。

因变量和自变量之间的非线性关系(作者图片)

挑战此数据集上的简单线性模型

我尝试用 sklearn LinearRegression()模型建立一个线性回归模型。我定义了一个函数来计算模型的各种度量。

当我为我的模型调用这个函数时,我得到了下面的输出。

R2 平方值:0.94
RSS:1211.696
MSE:12.117
EMSE:3.481

94%的 r2 分数还不错,但我们很快就会看到,使用非线性回归模型可以得到更好的结果。问题更多在于线性回归模型背后的假设。

单反假设 1:同质性

同方差意味着残差在回归线上具有相等或几乎相等的方差。通过绘制误差项和预测项,我们应该确认误差项中没有模式。然而,在这种情况下,我们可以清楚地看到,误差项具有一定的形状。

同质性(作者图像)

单反假设 2:误差项正态分布

具有正态或接近正态分布的钟形分布对于误差项应该是理想可见的。然而,从下图可以清楚地看出,我们有一个双模型分布。结果,在这种情况下,线性回归的假设被打破了。

错误术语的分布(作者图片)

单反假设 3:误差项相互独立

因此,误差项之间的自相关应该不存在。然而,下图显示误差项似乎表现出一定程度的自相关性。

错误术语之间的自相关(作者图片)

到目前为止,我们已经验证了数据是非线性的,但我们仍然建立了一个 SLR 方程。虽然我们取得了令人尊敬的 94%的 r2 分数,但没有一个单反假设得到满足。因此,对于这种类型的数据,SLR 不是一个明智的解决方案。我们现在将研究在同一数据集上改进模型的其他技术。

1.使用多项式回归模型建模非线性关系

非线性回归是自变量 x 和因变量 y 之间的关系,其产生非线性函数模型化的数据。本质上,任何非线性的关系都可以被称为非线性,并且通常由 k 次的多项式来表示(最大功率为 x )。

y**= ax+bx+cx+d

非线性函数可以包含指数、对数、分数等元素。比如:y= log(x*)

甚至,更复杂的比如:
y= log(ax+bx+cx+d)*

但是如果我们有不止一个自变量会怎么样呢?

对于 2 个预测值,多项式回归方程变为:

2-预测多项式方程

*其中,

  • Y 为目标,
  • x 1, x 2 为预测值或自变量
  • 𝜃0 为偏差,
    -𝜃1、𝜃2、𝜃3、𝜃4 和𝜃5 为回归方程中的权重*

对于 n 个预测值,该方程涵盖了各阶多项式的所有可行组合。这就是所谓的多维多项式回归,众所周知它很难实现。我们将构建不同程度的多项式模型,并评估它们的性能。但是首先,让我们为训练准备数据集。

我们可以建立一个管道,并传递我们希望用来生成各种次数的多项式的模型的次数和类别。这是下面的代码为我们做的:

如果您希望查看所有系数和截距,请使用以下代码块:请记住,系数的数量将根据多项式的次数而变化:

这是输出结果:

不同次数多项式回归的系数/截距(作者图片)

这并没有给出关于每个模型的性能的太多信息,所以将检查 r2 分数。

不同程度多项式回归的 r2 分数(作者图片)

因此,我们使用 sklearn 管道方法构建了高达 7 次的多项式方程,并发现 2 次及以上产生了 99.9%的准确度(相比之下,SLR 的准确度约为 94%)。在同一个数据集上,我们现在将看到另一种构建回归模型的技术。

2.使用数据转换对非线性关系建模

线性回归框架假设反应变量和预测变量之间的关系是线性的。为了继续利用线性回归框架,我们必须修改数据,以便变量之间的关系变成线性的。

数据转换的一些准则:

  • 响应变量和预测变量都可以转换
  • 如果残差图显示数据中存在非线性关系,一个直接的策略是利用预测值的非线性变换。在 SLR 中,这些转换可以是 log(x)、sqrt(x)、exp(x)、倒数等等。
  • 至关重要的是,每个回归变量与目标变量具有线性关系。因变量的变换是解决非线性问题的一种方法。

简而言之,通常是:

在我们的数据集中,当我们绘制因变量【分数】学习时间课程数量时,我们观察到分数与学习时间呈非线性关系。因此,我们将对特征 学习时间 进行转换。

研究时间显示非线性行为与标记(作者图像)

在应用上述转换后,我们可以绘制相对于新功能 time_study_sqaured标记,以查看关系是否已变为线性。

新特征表现出线性关系(作者图像)

我们的数据集现在已经准备好构建单反模型了。在这个转换后的数据集上,我们现在将使用 sklearn LinearRegression()方法创建一个简单的线性回归模型。当我们在构建模型后打印指标时,我们会得到以下结果:

R2 平方值:0.9996
RSS:7.083
MSE:0.071
EMSE:0.266

与之前在原始数据集上构建的 SLR 模型相比,这是一个显著的改进(没有任何数据转换)。我们得到的 R2 平方值是 99.9%,而不是 94%。现在,我们将验证单反模型的各种假设,看看它是否适合。

验证单反模型的所有假设(作者图片)

因此,在这一部分,我们转换了数据本身。知道特征 time_study标记不线性相关,我们创建了一个新的特征time _ study _ squared,它与标记线性相关。然后我们又建立了一个单反模型,验证了一个单反模型的所有假设。我们观察到这个新模型满足了所有的假设。现在,是时候探索我们的下一个和最后一个技术了,在同一个数据集上构建不同的模型。

3.使用非线性回归模型对非线性关系建模

对于非线性回归问题,可以尝试 sklearn 库中的 SVR()、KNeighborsRegressor()或 DecisionTreeRegression() ,比较模型性能。这里,出于演示目的,我们将使用 sklearn SVR() 技术开发我们的非线性模型。SVR 支持多种 内核 。核使得线性 SVM 模型能够分离非线性可分离的数据点。我们将使用 SVR 算法测试三个备选内核,并观察它们如何影响模型准确性:

  • rbf(支持向量回归的默认内核)
  • 线性的
  • 聚酯纤维(polyester 的简称)

i. SVR()使用 rbf 内核

这里是模型指标:仍然是一个更好的 R2 平方比我们的第一个单反模型。

R2 平方值:0.9982
RSS:4053558.081
MSE:0.363
EMSE:0.602

快速检查一下误差项分布似乎也没问题。

具有 rbf 核的 SVR 模型的误差项分布(作者图片)

二。SVR()使用线性内核**

这里是我们使用线性内核时的模型指标:R2 平方值再次下降到大约 93%

R2 平方值:0.9350
RSS:4063556.3
MSE:13.201
EMSE:3.633

同样在这种情况下,误差项似乎是一条近似正态分布曲线:

具有线性核的 SVR 模型的误差项分布(作者图片)

三世。SVR()使用 poly 内核

以下是支持向量回归多内核的模型指标:R2 平方值为 97%,高于线性内核,但低于 rbf 内核。

R2 平方值:0.9798
RSS:4000635.359
MSE:4.087
EMSE:2.022

这是误差项分布:

多重核支持向量回归模型的误差项分布(作者图片)

因此,在本节中,我们使用具有 3 个不同内核的 sklearn SVR 模型 创建了一个非线性模型。我们用 rbf 核得到了最好的 R2 平方值。

  • 径向基函数核的 r2 得分= 99.82%
  • R2-线性核得分= 93.50 %
  • 具有多内核的 r2 分数= 97.98 %

结论:

在这篇文章中,我们从一个不依赖于目标变量的线性数据集开始。在我们能够研究在非线性数据集上建立回归模型的替代策略之前,我们构建了一个 r2 分数为 94%的简单线性回归模型。然后,我们研究了三种不同的非线性数据集建模方法:多项式回归、数据转换和非线性回归模型(SVR)。我们发现,多项式次数为 2 或更高会产生 99.9%的 r2 得分,而具有 rbf 核的 SVR 会产生 99.82%的 r2 得分。一般来说,每当我们有一个非线性数据集时,我们应该尝试几种策略,看看哪种效果最好。

https://github.com/kg-shambhu/Non-Linear-Regression-Model】在这里找到数据集和代码:

**你可以在 LinkedIn 上联系我:https://www.linkedin.com/in/shambhukgupta/

3 种经过测试的技术来恢复失败的模型

原文:https://towardsdatascience.com/3-tested-techniques-to-recover-your-failing-models-67c070fb591

曾经表现良好的模型可能会开始恶化。这就是你能坚持下去的方法。

照片由来自 PexelsThilo Lehnert 拍摄。

宇宙中只有一个常数——变化!

你所看到和感觉到的一切都是一个版本——你用来拟合模型的数据也不例外。

随着时间的推移,一个完美的模型无法像过去那样预测。这不是一个错误;这就是 ML 模型的工作方式。期待它是 ML 工程师的工作。

生产中的 ML 模型与白水漂流非常相似。更糟糕的是,这是一条没有人走过的河流。你必须对当前的形势有所了解,才能预见未来。忽视危险可能会把你的木筏引向悬崖。

将其转化为 MLOps,您必须在您的模型开始跌落悬崖之前主动跟踪底层数据的变化——在它们做出不准确的预测之前。

这种现象被俗称为“概念漂移

由于并非所有的变化都是独特的,处理它们需要不同的策略。例如,社会行为,如离婚率,显示出缓慢的变化。另一方面,股票市场经常受到冲击,一夜之间创造和毁灭百万富翁。

而且还有周期性变化。你现在经历的变化可能会在未来几年逆转。

您的域可能会显示这些类型的变化之一。你应该在它们发生之前做好准备。

https://levelup.gitconnected.com/concept-drift-in-machine-learning-1fc7a4396b10

这里有三种 ML 工程师经常用来对抗概念漂移的技术。

为你的模特制定一个再培训计划。

再培训是一个简单易懂的概念。在每个周期中,你都会得到一组新的数据。您可以使用它们从头开始再次训练模型。

鉴于其简单性,您可能会经常使用它。但是,再培训是一项昂贵的工作。只有当你的模型训练起来既便宜又快速时,你才能从再训练中获益。

你可以采取三种方法中的一种来优化成本和培训时间。您可以用…重新训练模型

  • 仅限您的新数据;
  • 你过去的所有数据,或者;
  • 最新数据点权重更大的完整数据集。

仅用最近的数据重新训练模型。

虽然放弃旧数据并完全根据新数据进行重新训练听起来可能违反直觉,但它们在许多情况下是有帮助的,尤其是如果您确定旧数据已经过时,并且只会在模型中产生噪声。

短期金融市场预测就是一个很好的例子。因为有大量的机器人交易账户,如果有一种模式,很快所有的机器人都会学习它们。结果,这种模式很快就过时了。您的模型可能必须忘记过时的模式,并在新的数据集中找到新的模式。

这种再培训方式成本较低,因为它涉及的数据很少。但是这个模型失去了先前学习的背景。

只有当你的旧数据毫无疑问是不相关的时候,才使用它。

使用较小的数据集时,您应该注意模型过度拟合。虽然只有最近的数据集可能看起来是一种廉价而快速的重新训练方法,但如果您的模型有很多参数,它可能会过度学习数据点。

重新训练你所有过去的数据集

当你需要在知识中坚持的时候,你不能丢弃你已经拥有的。因此,您可能需要使用所有过去的数据来重新训练模型。

例如,天气预报肯定会发生变化。出于这个原因,我们更严肃地谈论气候变化。但是这种转变是渐进的。您的模型可以从过去的数据中受益,同时从新数据中学习不断变化的模式。

这种培训方式的缺点是成本高。数据点越多,存储和培训成本就越高,这不足为奇。

但是如果你的模型有很多参数,这可能是不可避免的。为了避免过度拟合,数据集必须足够大。

在最近的数据点上重新训练更多的权重

当数据集必须足够大,但又想考虑老化数据集时,可以使用这种方法。

当您需要在整个数据集上重新训练模型,但又希望赋予最新的模型更多的重要性时,您可以使用权重。您可以为较新的数据点分配较大的权重,而为较旧的数据点分配较小的权重。

但是要做到这一点,您的算法应该支持数据点选择。如果没有,你可以对数据集进行采样,使其更接近最新的。

定期用新数据更新旧模型。

这听起来可能与前面的策略相似。但是有一个微妙的区别。这里我们不像以前那样从头开始重新训练模型。我们用新的数据集更新已经训练好的模型。

你的算法应该支持初始权重和批量训练。如果你使用的是深度神经网络,这是一个很好的选择。

更新模型可能比从头再培训更划算。但这也取决于模型的大小和输入数据的大小。如果每次更新都有大量的数据点,并且您的模型有数百万个参数,那么这可能不是一个很好的选择。

另一方面,如果你必须坚持过去的知识并适应新的变化,这种方法是合适的。

使用新组件扩展您的模型。

基于前面的两个策略,只重新训练模型的可变组件可能是有益的。

更先进的技术,如迁移学习和模型集成,使这成为可能。

迁移学习中,你拿一个预先训练好的神经网络进行再训练。不是重新训练整个模型,而是只解开网络的最后一层。这通常被称为解冻。现在,您使用新数据训练前一层。这个模型不会忘记它以前学过的所有东西。然而,最新数据在最终决策中发挥着关键作用。

你也可以使用一个新的模型来改进你的预测。我们称这样的团体为“T2 模特组合”。虽然您的初始模型保持不变,但中间会有一个新的模型。新模型从新数据中学习,并改变原始模型的行为。

有时候,什么都不做也没关系!

你没看错。

什么都不做意味着你训练一个模型,并长时间使用它。它也被称为静态模型

静态模型之所以吸引人,有几个原因。

你需要一些标准来衡量任何事情。静态模型允许我们在它们发生时识别和漂移。对于数据漂移,这个静态模型就是你的标尺

此外,当您对现有模型进行更改时,您需要一个基准来评估。静态模型也是一个完美的目标。

然而,您必须小心静态模型。如果您在生产中使用,您应该确保数据和模型漂移不会对模型产生太大影响。

最后的想法

如果你认为数据科学家或 ML 工程师的工作在模型部署后就结束了,那你就是在冒险。

这只是开始。

生产中的模型性能下降。这被称为概念漂移,是机器学习中一个被广泛研究的挑战。

根据具体情况,您可以使用各种技术来确保您的模型持续保持最佳性能。

在这篇文章中,我们讨论了 ML 工程师经常使用的五种策略来对抗概念漂移。

您可以重新培训、更新或扩展模型!每一种都有其优点和缺点。

当你的模型无法准确预测时,你会怎么做?

感谢阅读,朋友!在LinkedInTwitterMedium上跟我打招呼。

还不是中等会员?请使用此链接 成为会员 因为,在没有额外费用给你的情况下,我赚了一点佣金。

关于 Python 元组你可能不知道的 3 件事

原文:https://towardsdatascience.com/3-things-you-may-not-know-about-python-tuples-4ff414f351d6

更好地使用元组

奥斯卡·尼尔森在 Unsplash 拍摄的照片

元组是 Python 中一种重要的内置数据类型。像列表一样,我们经常使用元组将多个对象保存为一个数据容器。然而,使它们不同于列表的是它们的不变性——不可变的数据序列。下面的代码片段向您展示了元组的一些常见用法。

response = (404, "Can't access website")response_code = response[0]
response_data = response[1]**assert** response_code == 404
**assert** response_data == "Can't access website"

上面的用法对你来说应该很直观。我们使用一对括号创建一个 tuple 对象,将元素括起来。当我们需要使用单个项目时,我们可以使用索引。

除了这些基本用法,还有其他一些不太为人所知的用法。让我们在本文中回顾一下它们。

1.创建仅包含一个项目的元组

我们提到,我们使用一对括号来创建一个元组对象。通常,一个 tuple 对象包含两个或更多项,我们使用逗号来分隔这些项。如果我们想创建一个单项式元组,应该怎么做?难道是(item)?让我们试试:

>>> math_score = (95)
>>> math_score[0]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'int' object is not subscriptable
>>> type(math_score)
<class 'int'>

正如你所看到的,(95)并没有像你们中的一些人想的那样创建一个tuple对象。相反,它创建了一个整数。解决方法是您需要在该项后面附加一个逗号:

>>> math_score = (95,)
>>> math_score[0]
95
>>> type(math_score)
<class 'tuple'>

您可能想知道何时需要使用单项式元组。这里有一个关于熊猫的例子。当我们使用 pandas 时,我们经常使用apply从现有列创建新数据。下面给你展示一个使用apply的简单案例。

>>> import pandas as pd
>>> df = pd.DataFrame({"a": range(1, 4), "b": range(4, 7)})
>>> df
   a  b
0  1  4
1  2  5
2  3  6
>>> def creating_exponents(x):
...     return pow(x["b"], 2)
... 
>>> df.apply(creating_exponents, axis=1)
0    16
1    25
2    36
dtype: int64

在大多数情况下,我们在apply中使用的映射函数只接受一个参数,即 DataFrame 的行(当axis参数为 1 时,如果axis=0为列)。我们可能有一个接受附加参数的映射函数,这样映射函数就更加灵活,并且可以通过不同地设置第二个参数来用于不同的 DataFrame 对象。在这种情况下,我们可以使用一个一项元组来传递第二个参数,如下所示。

>>> def creating_exponents(x, exp):
...     return pow(x["b"], exp)
... 
>>> df.apply(creating_exponents, axis=1, args=(3,))
0     64
1    125
2    216
dtype: int64
>>> df.apply(creating_exponents, axis=1, args=(4,))
0     256
1     625
2    1296
dtype: int64

如您所见,我们对args参数使用了一个单项式元组,它与行数据一起传递给映射函数。

2.使用下划线和*解包元组

虽然我们可以通过使用索引来访问一个元组的各个项,但更常见的是使用解包技术,如下所示:

response = (404, "Can't access website")
response_code, response_data = response

对于解包,您定义了一些变量,这些变量的数量与元组的计数相匹配。元组的每个项被分配给各自的变量。

如果您不需要使用所有创建的变量,建议您使用下划线来表示它们没有被使用。例如,我们可能只对使用响应数据感兴趣,而对代码不感兴趣,我们可以这样做:

_, response_data = response

这样,您就告诉了代码的读者,我们只对访问 tuple 对象的第二项感兴趣。

当一个元组对象中有多个项目时,您可能希望访问多个连续的项目。您可以使用带星号的表达式:

scores = (98, 95, 95, 92, 91)algebra, *others, zoology = scores**assert** others == [95, 95, 92]

如上所示,我们有一个 tuple 对象来保存按字母顺序排序的课程分数,我们知道第一门课程是代数,最后一门是动物学。在上面的例子中,我们得到了中间的三个分数。

这个特性(tuple 解包中的星号表达式)在您不知道到底有多少到表达式时特别有用。所有的学生都学代数和动物学,但他们在其他课程上可能会有所不同。我们可以使用带星号的表达式来获得其他课程的分数,而不需要知道课程的数量。

def extract_scores(scores):
    algebra, *others, zoology = scores
    return {"algebra": algebra, "zoology": zoology, "others": others}scores1 = (98, 95, 92, 93, 91)
scores2 = (97, 95, 95, 90)
scores3 = (90, 90)>>> extract_scores(scores1)
{'algebra': 98, 'zoology': 91, 'others': [95, 92, 93]}
>>> extract_scores(scores2)
{'algebra': 97, 'zoology': 90, 'others': [95, 95]}
>>> extract_scores(scores3)
{'algebra': 90, 'zoology': 90, 'others': []}

正如您所看到的,这个带星号的表达式可以处理中间任意数量的元素,包括零个元素(在scores3的情况下)。

3.命名元组

您可以通过使用索引或解包元组来访问元组的各个项,以将这些项分配给单独的变量。有时候,这样做可能会很乏味。请参见以下示例:

location1 = (27.2, 7.5)
location2 = (30.1, 8.4)
location3 = (29.9, 7.7)latitude1 = location1[0]
longitude2 = location2[1]
latitude3, longitude3 = location3

我们有三个位置,显示了它们各自的坐标。当我们访问这些坐标的单个项目时,代码看起来不太清晰。虽然我们可以使用定制类来实现坐标的数据模型,但是定制类对于这个简单的数据模型来说可能是“沉重”的。相反,我们可以使用命名元组作为轻量级数据模型:

from collections import namedtupleLocation = namedtuple("Location", ["latitude", "longitude"])location1 = Location(27.2, 7.5)
location2 = Location(30.1, 8.4)
location3 = Location(29.9, 7.7)latitude1 = location1.latitude
longitude2 = location2.longitude
location3.latitude, location3.longitude

如上所示,我们调用namedtuple通过指定类名及其属性来创建一个命名元组类。现在,我们可以调用该类的构造函数来创建命名元组类的实例。对于这些实例,我们可以使用点符号来访问它们的属性,这是常规元组对象所不具备的特性。

如前所述,命名元组是一个简单而方便的类,它们也在熊猫中使用。当我们迭代 DataFrame 对象的行时,我们可以使用itertuples方法,如下所示:

>>> df
   a  b
0  1  4
1  2  5
2  3  6>>> for row in df.itertuples():
...     print(row)
... 
Pandas(Index=0, a=1, b=4)
Pandas(Index=1, a=2, b=5)
Pandas(Index=2, a=3, b=6)

每一行都是一个有三个属性的命名元组:索引和两列的值。有了命名元组,您可以方便地访问列的数据,比如row.arow.b

结论

在本文中,我们回顾了 Python 中元组的三个特性。我们还使用了一些与使用 pandas 进行数据处理相关的例子。希望这篇文章对你有用。

感谢阅读这篇文章。通过注册我的简讯保持联系。还不是中等会员?通过使用我的会员链接支持我的写作(对你没有额外的费用,但是你的一部分会费作为奖励由 Medium 重新分配给我)。

使用 PyScript 构建之前要知道的 3 件事

原文:https://towardsdatascience.com/3-things-you-must-know-before-building-with-pyscript-245a0a82f2c3

在最近遇到一些障碍、错误和怪癖之后,我想用 PyScript、Python 和 HTML 做一个构建指南

戴维·克洛德在 Unsplash 上的照片

对于那些还没有听说过的人来说,在 PyCon 2022 上首次亮相的 PyScript 是一个嵌入浏览器的 python 环境,构建在一个名为 Pyodide 的现有项目之上。这个项目让长期的 Python 爱好者和 web 开发人员感到震惊,它在一个双向环境中无缝地融合了(好得几乎是 ) JavaScript 和 Python,允许开发人员在浏览器中使用 Python staples,如NumPy或** 熊猫 **

玩了几天这个项目后,我想分享一些我在掌握 PyScript 的过程中遇到的学习和 gotchya 的经验。

****前奏:py script
1中的速成班。包装压痕至关重要!
2。本地文件访问
3DOM 操作

PyScript 速成班

要开始使用 PyScript,我们首先必须将我们的 HTML 文件与 PyScript 脚本链接起来,就像我们处理任何普通 javascript 文件一样。此外,我们可以链接 PyScript 样式表来提高可用性。

**<head>**
    <link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
    <script defer src="https://pyscript.net/alpha/pyscript.js"></script>
**</head>**

在 HTML 文件头中导入 PyScript 后,我们现在可以利用 HTML 主体中的 < py-script > 标签来编写 python 代码。

**<body>**
    <py-script>
        for i in ["Python", "in", "html?"]:
            print(i)
    </py-script>
**</body>**

没错。开始真的就这么简单。现在,事情在哪里变得棘手?

包装压痕很重要

使用 PyScript 的一个很大的优势是能够导入 Python 库,比如 NumPy 或 Pandas,这首先在中使用 < py-env > 标签完成,然后在 < py-script > 标签内部完成,就像在普通 Python 中一样。

**<head>**
    <link rel="stylesheet" href="https://pyscript.net/alpha/pyscript.css" />
    <script defer src="https://pyscript.net/alpha/pyscript.js"></script> <py-env>
- numpy
- pandas
    </py-env>
**</head>****<body>**
    <py-script>
        **import pandas as pd**
    </py-script>
**</body>**

从表面上看,这似乎很简单,但是请注意 < py-env > 中的包的缩进。

 <py-env>
**- numpy
- pandas**
    </py-env>

原来,如果有任何缩进,您将收到一个ModuleNotFoundError:没有名为‘pandas’ModuleNotFoundError:没有名为‘numpy’)的模块用于 PyScript。这个错误一开始让我措手不及,因为 Python 中的缩进非常重要。**

本地文件访问

与 Python 相比,JavaScript 处理文件访问的方式非常不同……鉴于 web 开发与隐私和安全之间的关系,这是理所应当的。因此普通 JavaScript 不能直接访问本地文件。因为 PyScript 项目是建立在 JavaScript 之上的,所以您的 Python 代码将不能像您可能习惯的那样访问本地文件

PyScript 确实在标签中提供了文件访问的解决方案。除了导入包之外,还可以导入 CSV 或 XLSXs 等文件。

 *<py-env>
- numpy
- pandas
**- paths:
    - /views.csv**
    </py-env>*

再次注意缩进,因为在这种情况下,CSV 必须相对于路径缩进。**

有了包含在路径中的文件,您可以在您的代码中读取它。

*<py-script>
    import pandas as pd
    df = pd.read_csv("**views.csv**")
</py-script>*

DOM 操作

对于任何从事过 web 开发的人来说,您应该熟悉 DOM 或文档对象模型。DOM 操作在大多数 web 应用程序中很常见,因为开发人员通常希望他们的网站与用户交互,读取输入并响应按钮点击。在 PyScript 的例子中,这提出了一个有趣的问题:按钮和输入字段如何与 Python 代码交互?

PyScript 对此也有一个解决方案,但是,它可能不是您所期望的。下面是 PyScript 具有功能的几个例子:

  1. 对于按钮,可以包含pys-onClick = " your _ function "参数,在点击时触发 python 函数。**
  2. 用于从 < py-script > 标签document . getelementbyid(' input _ obj _ id ')中检索用户输入。值可以检索输入值。**
  3. 最后py script . write(" output _ obj _ id ",data) 可以从 < py-script > 标签内将输出写入标签。**

我们可以看到这三种 DOM 操作技术被放在一个 web 应用程序中,该应用程序允许用户检查 CSV 是否已被添加到 PyScript 路径中:

*<body>
   <form onsubmit = 'return false'>
   <label for="fpath">filepath</label>
   <input type="text" id="fpath" name="filepath" placeholder="Your name..">
   <input **pys-onClick="onSub"** type="submit" id="btn-form" value="submit">
    </form><div **id="outp"**></div> <py-script>
        import pandas as pd def onSub(*args, **kwargs):
            file_path = **document.getElementById('fpath').value**
            df = pd.read_csv(file_path)
            **pyscript.write("outp",df.head())**
    </py-script>
</body>*

这些例子并不全面,因为该项目还支持可视组件标签

结论

PyScript 将一些优秀的 Python 包引入 web 开发领域,是朝着正确方向迈出的精彩一步。尽管如此,它仍然有一点成长要做,在该项目被广泛采用之前,还有许多需要改进的地方。

对在这个【https://github.com/pyscript】棒极了的项目中工作的团队表示一些支持

留下您在使用 PyScript 时可能遇到的任何其他见解或 gotchya 的评论,我将制作第 2 部分。

Jan Kahánek 在 Unsplash 上拍摄的照片

在机器学习中处理图像之前你需要知道的 3 件事

原文:https://towardsdatascience.com/3-things-you-need-to-know-before-working-with-images-in-machine-learning-6a2ab6f6b822

在接受计算机视觉项目之前掌握基本知识

照片由 PexelsLisa Fotios 拍摄

从处理结构化数据过渡到处理非结构化数据是我学习过程中的一个重要里程碑。我喜欢在机器学习项目中处理图像,因为它让我接触到许多新的数据科学工具和技术。

然而,事后看来,我可以说我在承担计算机视觉项目之前没有打下良好的基础。由于我匆忙地通过使用图像来挑战自己,我忽略了许多重要的概念,从长远来看,这耗费了我大量的时间和精力。

为了给其他人省点麻烦,我将讨论我认为人们在机器学习项目中使用图像之前应该熟悉的 3 件事。

习惯导航目录

自然,在你开始处理你的图像之前,你必须阅读它们。

与电子表格不同,图像可以跨多个文件夹存储在数千个不同的文件中。因此,如果您选择处理图像,您将需要浏览各种文件夹以读取其中存储的图像。

目录是一个简单的概念,但是如果您刚刚开始,您可能会发现很难用代码遍历它们。

在 Python 中,用于此类任务的主要模块是 OS 和 Glob。

作为一个例子,我们可以使用一个猫对狗的数据集(版权免费),可以在这里访问。以下代码显示了一种使用 OS 和 OpenCV 模块读取文件夹中图像的方法。

让我们创建一个函数“show_images ”,我们可以用它来显示收集到的第一批猫和狗的图像。

代码输出(由作者创建)

了解图像变换的基本类型

与在用于训练模型之前转换的结构化数据集中的特征类似,图像也必须在任何模型训练之前经历一组转换。

有很多原因会让你想要修改你的图片。以下是一些主要的例子:

1.运行机器学习模型

图像需要在任何模型训练之前进行归一化。

卷积神经网络只有在用于训练它们的图像共享相同维度时才起作用。因此,调整图像大小是计算机视觉中的一种常见做法。

下面是你如何使用 Skimage 模块将先前加载的猫图像的大小调整为 100x100 像素。

代码输出(由作者创建)

2.降低计算需求

出于降低成本的考虑,最好只保留正在讨论的任务所需的信息。

执行此步骤的常见方法包括缩小图像尺寸和去除颜色。在许多情况下,这种详细程度并不是模型良好运行所必需的。

例如,在比较猫和狗时,颜色并不是决定性因素。你可以很容易地建立一个没有彩色图像的模型来区分这两个物种。

这里,Skimage 包用于从猫图像中去除颜色。

去除颜色并不会真的让猫看起来不像猫,对吧?

3.增加训练数据量

通过变换改变原始图像来增加训练数据的行为被称为图像增强

这种类型的转换提供了许多好处。

首先,神经网络需要大量数据才能有效运行。数据扩充可以提供训练神经网络的方法,以便用有限的训练数据做出准确的预测。

其次,它是对数据不平衡的一种威慑。数据扩充可以通过人为增加表示少数类的数据量来抵消数据不平衡。这反过来减轻了过度拟合。

一个简单的变换例子是旋转,这是用 Skimage 模块演示的。

代码输出(由作者创建)

熟悉流行的图像处理模块

如果你有使用 Python 处理结构化数据的经验,你就会知道 Pandas 实际上已经垄断了数据框操作的手段。如果您有与数据框相关的查询,您会发现向他人寻求帮助很容易,因为他们的工作可能使用您非常熟悉的相同模块。

不幸的是,你没有同样的图像奢侈品。

有很多库可以用于图像处理,比如 OpenCV、Skimage、Pillow 等。

花时间探索这些库,不要太依赖它们。坚持一个意味着你受限于那个库提供的服务。

此外,如果你从其他人的工作中寻求指导或灵感,如果他们主要使用你不熟悉的库,你可能会陷入困境。

开始时,我个人非常喜欢 OpenCV 模块,我将它与 Keras 结合使用。不幸的是,这意味着每当我试图诊断一个问题或找到一种解决问题的方法时,我都会碰到涉及 Pillow、Torchvision 和其他对我来说非常陌生的库的代码。我对少数图像处理工具的过度依赖成了我学习中的一个主要瓶颈。

拥有用于图像处理的定位模块是可以的,但不要成为只会一招的小马。

结论

照片由普拉蒂克·卡蒂亚尔Unsplash 拍摄

如果你没有在机器学习中处理图像的经验,你无疑会有相当多的挣扎。

然而,如果您花时间巩固您对图像处理中使用的基本工具和技术的理解,这些挫折将更容易管理。

我祝你在机器学习的努力中好运!

参考

  1. 切塔尼姆拉万。(2018).猫狗图片,第一版。从https://www.kaggle.com/chetankv/dogs-cats-images检索到 2022 年 1 月 9 日。

3 个省时的 BigQuery 特性

原文:https://towardsdatascience.com/3-time-saving-bigquery-features-6433ba794e27

编写更高效的查询并加快分析速度

照片由泰勒维克Unsplash 拍摄

介绍

BigQuery 是最流行的基于云的数据仓库平台之一。虽然它的主要功能是存储、管理和分析数据,但它的真正威力在于一组奇妙的内置功能,这些功能可用于从数据工程到数据科学的整个数据领域。

在过去几年的数据分析师工作中,我发现了一组有价值的特性和函数,它们帮助我编写了更高效的查询并增强了我的即席分析。

这里有三个必须知道的 BigQuery 特性和函数,它们将为您的数据之旅节省一些宝贵的时间。

时间旅行

"我希望我能回到过去。"谁没想过至少一次?BigQuery 在某种程度上让这成为可能。

为了演示到目前为止似乎不可能的事情,让我们以 BigQuery 中的sales表为例,该表每天更新前一天的数据,并直接输入到您的销售仪表板中。

今天是 2022 年 9 月 1 日,你正在查看你的销售仪表板,你注意到与昨天相比,两天前的 8 月 30 日销售量下降了。您的第一反应是使用以下查询在 BigQuery 中查看当天的原始数据:

查询结果(作者图片)

您的查询结果仅确认您在销售仪表板上看到的内容。但是当你昨天看着同一个仪表板时,你确信你的销售量更高。

使用 BigQuery 中的FOR SYSTEM_TIME AS OF子句,可以在特定时间点查询您的sales表,并确认您最初的假设。该功能的工作原理如下:

BigQuery 时间旅行图解(图片由作者提供)

例如,以下查询将返回 24 小时前sales表的历史版本:

查询结果(作者图片)

通过时光倒流,你已经确认了你的销售数字从一天到另一天发生了变化。你的商品 A_0044 的销售额从 387 降到了 0。看起来问题来自数据接收。你现在可以开始在那个方向缩小范围了。

当您需要检查旧版本的表或监控可能的数据摄取问题时,使用 BigQuery 进行时间旅行会很方便,如上例所示。

临时表

BigQuery 中另一个强大的概念是临时表。BigQuery 中的所有查询结果都自动存储在临时表中,供以后的分析使用。这对于在运行即席分析时使您的代码更加整洁非常有帮助。

图解的 BigQuery 临时表(图片由作者提供)

为了说明这个概念,让我们使用下面的查询示例,从您的salesusers表中返回每天的 total_salestotal_unique_users

查询结果(作者图片)

这个查询工作得很好,但是为了更容易阅读,您可以将salesuserscte(公共表表达式)的结果保存在 BigQuery 的临时表中。

为此,在两个大查询选项卡中分别运行salesusers查询(cte),并遵循以下步骤:

在 BigQuery 查询结果窗口中,选择:

  1. 工作信息
  2. 目的地表
  3. 临时表

这将打开一个新的 BigQuery 窗口,查询结果存储在一个名为 randomly 的临时表中。对于这个例子,让我们假设这两个临时表被命名为temporary_salestemporary_users

然后,您可以在查询中使用这些新创建的临时表:

查询结果(作者图片)

这个最终查询将返回与原始查询相同的结果,除了它已经从 30 行减少到只有 8 行,使得它更容易阅读和操作。

当在即席分析中运行多个查询(有时是大量查询)时,这个 BigQuery 特性特别有用。

过滤窗口函数

窗口函数(也称为分析函数)用于计算一组特定行的值,为每一行返回一个结果。

当您需要计算移动平均值、累积和,甚至对数据进行排序时,这些函数特别有用。

为了展示它们的威力,让我们使用ROW_NUMBER BigQuery 函数对sales表中的每一行进行排序,按国家进行分区,并按销售额降序排列:

查询结果(作者图片)

然而,大多数时候,您需要过滤查询结果。在这种情况下,我们希望只保留每个国家销售额最高的行— WHERE rank = 1

您的第一个猜测可能是在WHERE子句中添加上述条件——您可能是对的。然而,您将在查询结果中得到以下错误消息。

BigQuery 错误消息(图片由作者提供)

这是不言自明的;在WHERE子句中不允许使用窗口函数。

要解决这个问题,第一个解决方案是在 CTE 中添加原始查询,并在下面的最终查询中过滤出结果,如下所示:

查询结果(作者图片)

那很完美,对吧?然而,BigQuery 提供了一个更加优雅的解决方案来过滤窗口函数的结果,它不会让您的代码负担过重。通过使用QUALIFY子句,您可以去掉 CTE,最终得到完全相同的结果。

查询结果(作者图片)

很棒,对吧?您的查询已经从十八行代码减少到只有七行代码。

SQL 窗口函数非常强大,知道如何操作它们的结果将允许您编写更干净、更高效的代码。

结论

这些只是我经常使用的三个最有用的 BigQuery 特性。利用它们,您不仅可以编写更高效的查询,还可以在进行下一次分析时节省宝贵的时间。

现在轮到你了。您最常用的 BigQuery 特性是什么?不要犹豫,分享你的。

参考

[1] BigQuery,使用时间旅行访问历史数据 (2022),谷歌云

[2] BigQuery,编写查询结果 (2022),谷歌云

[3] BigQuery,查询语法— QUALIFY 子句 (2022),谷歌云

使用 Python 获取目录中所有文件的 3 种省时方法

原文:https://towardsdatascience.com/3-time-saving-ways-to-get-all-files-in-a-directory-using-python-32113a801701

数据科学

总有一种方法是你在寻找的

图片由 Freepik 上的PCH . vector

获取目录和子目录中的所有文件!

你谷歌过“ 如何列出一个目录的所有文件?使用 Python 查找一个目录下的所有 CSV 文件。 “怎么样?

那么这篇文章将是你所有问题的一站式解决方案。

作为一名分析专家,我在日常工作中使用 Python。我经常需要从一个文件夹和子文件夹中取出所有文件。我相信你也遇到过类似的情况。

因此,我总结了 3 种快速获取目录或子目录中所有文件的方法。总有一种方法可以满足您的确切需求。

为了举例,我使用下面的文件夹模式。

字典结构|作者图片

将读取文件夹**01_Main_Directory**内容的笔记本在文件夹**Challenges**中。

我们开始吧..

根据您的任务,您可以使用以下一种或多种方法的组合。

我会从最简单的方法开始。

假设,你想列出文件夹**01_Main_Directory**中的所有文件。因此,您可以使用名称中明确说明其用途的功能,即**listdir()**

os.listdir()

Python 模块**os**提供了这个功能,顾名思义,你可以获得路径中所有文件、文件夹和子文件夹的列表。

使用该功能前,不要忘记导入模块os。在这个例子中,要列出**01_Main_Directory** 中的所有文件,你需要做的就是——在os.listdir()函数中提供这个文件夹的路径。如果此文件夹不在您当前的路径中,那么您需要将它添加到路径中。

但是我怎么得到当前的路径呢??

您可以使用另一个函数os.getcwd()来获取当前路径。

import os
os.getcwd()

#Output
'C:\\Users\\Suraj\\Challenges'

如您所见,当前路径指向存储该笔记本的挑战文件夹。

您需要手动将文件夹01_Main_Directory添加到该路径,以获得其中所有文件的列表,如下所示。

import os
os.listdir(os.getcwd()+'\\01_Main_Directory')

#Output
['ABCD_1.docx',
 'ABCD_1.txt',
 'ABCD_2.txt',
 'ABCD_3.txt',
 'ABCD_4.txt',
 'ABCD_5.txt',
 'ABCD_5.xlsx',
 'Sub_Dictionary_1',
 'Sub_Dictionary_2']

简单!你拿到了文件夹里所有文件的清单。

该列表包含所提供路径中的所有文件和子文件夹。

或者,要获得所有文件夹、子文件夹和子文件夹中的文件的列表,您可以使用 os 模块中更复杂的功能。

os.walk()

顾名思义,这个函数将带您浏览目录树。

Python 中的这个方法类似于os.listdir(),但是os.walk()返回一个由 3 个元素组成的元组,其中包含——

  1. **folder_path**:当前文件夹以及当前文件夹中所有文件夹的路径
  2. **folders**:所提供路径中的文件夹或目录列表
  3. **files**:提供的目录路径及其子目录下的文件列表

为了便于理解,让我们来看看这个函数的运行情况!

path = os.getcwd()+'\\01_Main_Directory'
for folder_path, folders, files in os.walk(path):
    print(folder_path)

Python |作者图片中的 os.walk()

输出的第一行将总是当前目录的路径或作为输入提供给os.walk()的路径。后面是按字母顺序排列的子目录路径。

要获得所提供路径中所有文件夹的列表,可以使用os.walk()生成器对象中的第二个变量,如下所示。

path = os.getcwd()+'\\01_Main_Directory'
for folder_path, folders, files in os.walk(path):
    print(folders)

Python 中的 os.walk()目录名|作者图片

folder_path类似,该输出的第一行将是在提供的路径中出现的所有子文件夹的列表。第二行和第三行列出了这些子文件夹中的文件夹。

在本例中,Sub_Dictionary_1Sub_Dictionary_2中没有文件夹。所以输出的剩余行显示空列表。

类似地,使用元组的最后一个元素,可以检索路径中存在的所有文件。

path = os.getcwd()+'\\01_Main_Directory'
for folder_path, folders, files in os.walk(path):
    print(files)

按作者列出路径|图像中存在的文件列表

由于所有文件只存在于01_Main_Directory中,输出的第一行列出了所有文件。

当您只想查看文件夹中有哪些文件时,这尤其有用。要使用这些文件,您需要文件路径。

这就是另一个模块glob将帮助您实现的地方。

glob — Unix 样式路径名模式扩展

该模块对匹配特定模式的文件路径很有帮助——在 Python glob 模块的**glob()**函数中指定。您应该在glob()函数中提到的模式应该遵循 Unix 路径扩展规则。

要获得后续文件夹中文件的路径,您只需提供存储文件的文件夹的路径。您可以灵活地提供绝对和相对文件路径。

例如,假设您想要检索01_Main_Directory中的所有文件,您需要做的就是提供该文件夹的路径。

import glob
path = os.getcwd()+'\\01_Main_Directory'
for filepath in glob.glob(path):
    print(filepath)

#Output
C:\Users\Suraj\Challenges\01_Main_Directory

这只是将路径返回给了01_Main_Directory,因为glob.glob()中提供的路径终止于该文件夹。

要检索所有文件,您实际上应该指定超出该文件夹的路径,如下所示。

path = os.getcwd()+'\\01_Main_Directory\\*'
for filepath in glob.glob(path):
    print(filepath)

#Output
C:\Users\Suraj\Challenges\01_Main_Directory\ABCD_1.docx
C:\Users\Suraj\Challenges\01_Main_Directory\ABCD_1.txt
C:\Users\Suraj\Challenges\01_Main_Directory\ABCD_2.txt
C:\Users\Suraj\Challenges\01_Main_Directory\ABCD_3.txt
C:\Users\Suraj\Challenges\01_Main_Directory\ABCD_4.txt
C:\Users\Suraj\Challenges\01_Main_Directory\ABCD_5.txt
C:\Users\Suraj\Challenges\01_Main_Directory\ABCD_5.xlsx
C:\Users\Suraj\Challenges\01_Main_Directory\Sub_Dictionary_1
C:\Users\Suraj\Challenges\01_Main_Directory\Sub_Dictionary_2

如您所见,这里的路径使用**\\*** 扩展到文件夹01_Main_Directory内部。这里,星号(*****)是通配符,代表选择文件夹内的所有文件。

但是,您通常知道文件名的结尾部分,或者只知道文件名中的几个字符。

举个例子,假设您想从这个文件夹中获取所有文件名中包含字符串**1**的文件路径。您可以通过如下所示的非常简单的方式使用glob()功能。

path = os.getcwd()+'\\01_Main_Directory\\*1.*'
for filepath in glob.glob(path):
    print(filepath)

#Output
C:\Users\Suraj\Challenges\01_Main_Directory\ABCD_1.docx
C:\Users\Suraj\Challenges\01_Main_Directory\ABCD_1.txt

这会获取名称中包含 1 的所有文件名,但输出包含所有类型的文件。

如果你只想拉。txt 文件吗??

就像你在上面看到的用例一样,你需要写一个模式。当然可以。txt 文件末尾会有**.txt**。你想要获取所有的文件,这样你就可以使用通配符星号(*****)。所以您在glob()中提供的模式是***.txt** ,您可以如下图所示使用它。

path = os.getcwd()+'\\01_Main_Directory\\*.txt'
for filepath in glob.glob(path):
    print(filepath)

#Output
C:\Users\Suraj\Challenges\01_Main_Directory\ABCD_1.txt
C:\Users\Suraj\Challenges\01_Main_Directory\ABCD_2.txt
C:\Users\Suraj\Challenges\01_Main_Directory\ABCD_3.txt
C:\Users\Suraj\Challenges\01_Main_Directory\ABCD_4.txt
C:\Users\Suraj\Challenges\01_Main_Directory\ABCD_5.txt

答对了。!你得到了文件夹中所有文本文件的路径。同样,要获得所有的。docx 文件,需要在glob()内提供模式***.docx**

再往前一步,假设您想获得子文件夹— Sub_Disctionary_1Sub_Dictionary_2中的所有文件,那么 glob()是最有用的函数。

您需要做的就是在路径中使用通配符模式******。这里需要设置参数recursive=True,如下图。

path = os.getcwd()+'\\01_Main_Directory\\**\\*.txt'
for filepath in glob.glob(path, recursive=True):
    print(filepath)

#Output
C:\Users\Suraj\Challenges\01_Main_Directory\ABCD_1.txt
C:\Users\Suraj\Challenges\01_Main_Directory\ABCD_2.txt
C:\Users\Suraj\Challenges\01_Main_Directory\ABCD_3.txt
C:\Users\Suraj\Challenges\01_Main_Directory\ABCD_4.txt
C:\Users\Suraj\Challenges\01_Main_Directory\ABCD_5.txt
C:\Users\Suraj\Challenges\01_Main_Directory\Sub_Dictionary_1\File_1_in_SubDict_1.txt
C:\Users\Suraj\Challenges\01_Main_Directory\Sub_Dictionary_1\File_2_in_SubDict_1.txt
C:\Users\Suraj\Challenges\01_Main_Directory\Sub_Dictionary_2\File_1_in_SubDict_2.txt
C:\Users\Suraj\Challenges\01_Main_Directory\Sub_Dictionary_2\File_2_in_SubDict_2.txt

路径中的模式******将与文件夹01_Main_Dictionary中的所有目录和文件相匹配。

仅此而已!

我希望这篇文章对快速参考有用。

当然还可以有更多来自不同 Python 包的工具,比如pathlibos.scandir(),但是上面提到的三个函数非常简单,也很常用。

如果你想在 Medium 上阅读如此精彩的文章,可以考虑成为 Medium 会员,无限制地阅读所有文章。

您可以使用下面的我的推荐链接加入 Medium。这将有助于我和其他作者,因为 Medium 与我们分享你的 5 美元中的一小部分。

https://medium.com/@17.rsuraj/membership

另外,请 订阅 我的邮件列表&将我的文章直接放入你的收件箱。

感谢您的阅读!

除了编码最佳实践之外,编写干净代码的 3 个技巧

原文:https://towardsdatascience.com/3-tips-for-writing-clean-codes-beyond-coding-best-practices-c53b04120c3

编写优雅的、模块化的、可理解的和可维护的代码

Pierre chtel-Innocenti 在 Unsplash 上拍摄的照片

你可能听说过“混乱的代码”这个术语,并想知道混乱到底是什么意思(当你的代码工作时),或者遇到过一些编码最佳实践术语,如固体设计原则、干燥(不要重复自己),或者亲吻(保持简单愚蠢)原则。编码最佳实践中有如此多的术语和规则,以至于我发现它令人困惑和重复(讽刺来自 KISS 和 DRY 原则),并质疑它们在实践中是否可行,因为它们毕竟是在理论上。

本文旨在提供良好编码标准、编码最佳实践、不同代码味道和设计模式的速成课程和总结,并以编写干净代码的 3 个实用技巧结束。在我以前的一篇文章中,我写了一些学习新编程语言的方法,这篇文章是对那篇文章的扩展,因为这篇文章假设了一些代码理解。请随意查看我以前的文章,

目录

  1. 编码标准
  2. 编码最佳实践
  3. 代码气味
  4. 设计模式
  5. 提示 1:规划你的组件
  6. 技巧 2:不断抽象你的代码
  7. 提示 3:利用开源工具

编码标准

编码标准定义了代码约定或风格指南,就像英语如何遵循语法规则一样,编写遵循编码约定的代码可以提高代码的可读性和可理解性。

不同编程语言的编码标准通常遵循相同的规则,但由于不同的语言有不同的语法,所以可能会略有不同。Python 有 PEP 8 标准,Java 有Oracle创建的代码约定。

为了使本文与语言无关,编码标准通常为以下内容定义规则

  • 文件夹和文件结构(针对 Java)
  • 缩进和间距
  • 包、模块、类、变量名等的命名约定。
  • 执行导入、编写注释和语句的正确方式

在上面的每一个类别中,都有很多规则要遵循——在 PEP 8 文档中甚至有一个关于“讨厌的东西”的章节!有这么多规则要遵守,很难记住所有的规则,或者很容易漏掉某些违规,就像英语中有拼写错误一样。

有一些工具可以帮助标记出不符合正确编码标准的代码,如 IDE(集成开发环境)可以突出显示不符合正确编码标准的代码,还有一些工具可以帮助重新格式化和重写代码,称为代码林挺。帮助林挺的一些流行的 Python 包有 pylintblackflake8isort 等等。

编码最佳实践

编码最佳实践定义了构建代码的理论和指导方针,增强了代码的模块化和可维护性

正如本文开头所提到的,在编码最佳实践的大伞下使用了许多行话。我在下图中总结并画出了常用术语之间的联系。这应该是一个总结,而不是详尽的例子。

图 1:原则和指南摘要—作者图片

遵循可靠的设计原则,

  • 单一责任原则:一个班只能有一项工作
  • 打开关闭原则:一个类应该对扩展开放,但对修改关闭
  • 利斯科夫替换原则:程序中的对象应该可以用它们的子类型的实例替换,而不改变程序的正确性
  • 接口分离原则:永远不要强迫客户实现一个它不使用的接口
  • 依赖倒置原则:高级模块应该依赖于高级概括,而不是低级细节

其他设计原则和指南包括:

  • 组合对象原则:类应该通过聚合而不是继承来实现代码重用
  • 得墨忒耳定律/最小知识原理:类应该尽可能少地了解其他类并与之交互
  • 抽象:通过只显示相关信息来简化
  • 封装:将属性和行为捆绑到一个对象中,并在必要时公开特性
  • 分解:将一个实体分解成可以单独实现的部分
  • 泛化:分解出可以在其他地方重用的类的公共特性
  • 耦合和内聚:松散耦合的模块依赖性更小,更容易重用,而高内聚描述的是一个有明确目的的模块,不会比它需要的更复杂
  • 继承:子类从超类继承或者通过接口实现的属性或行为
  • 信息隐藏:模块应该只能访问它需要的信息
  • 关注点分离:不同的关注点应该在不同的模块中
  • 不要重复自己:减少代码重复
  • 保持简单愚蠢:简单应该是一个设计目标
  • 概念完整性:创建一致的软件,并决定如何设计和实现系统

主要外卖就是这些是一大堆原则,有些原则是对比的!例如,封装和分解在某种程度上有相反的含义,这就引出了什么时候应该使用每一个原则的问题。

在实践中,我们根据自己的判断,在任何适用的情况下运用这些原则,我们甚至可能为了“更大的利益”而违背某些原则。了解这些原则就足够了,它不应该作为实现一切的清单来执行。

代码气味

代码气味是坏代码的一个症状,这可能表明更深层次的问题

类似于编码最佳实践,知道代码气味的存在就足够了,而不是强制或可能避免所有代码气味。也很难避免代码味道,因为它们可能是基于开发人员、编程语言和问题类型的主观味道。

常见的代码气味是,

  1. 注释:有注释是好的,但是如果注释被过度使用(主观)来弥补代码的不清晰,那就有问题了
  2. 大类:如果一个类非常大(主观,考虑使用分解
  3. 数据类:如果类太小(主观);与大类相反
  4. 数据块:如果一组代码经常一起出现,考虑使用封装
  5. 重复代码:如果在代码库的多个部分发现了几乎没有变化的相同代码,考虑使用泛化
  6. 长方法:如果一个方法很大(主观,这表明关注点的分离很差,考虑使用分解
  7. 长参数列表:如果一个方法有一个长参数列表(主观),考虑传递封装了公共参数的参数对象
  8. 霰丨弹丨枪手术:如果一个地方的变化导致了其他多个部分的变化,这表明了紧耦合

以上项目是常见代码气味的非详尽列表,完整的代码气味列表可以在这里找到。正如您从上面的列表中所观察到的,代码气味可能是相当主观的,并且与编码最佳实践密切相关——如果您努力实践和实现编码最佳实践,代码气味也可以被最小化。

设计模式

设计模式为常见的软件工程问题提供解决方案,并且与语言和代码无关。

有三种类型的设计模式——创造、结构和行为设计模式。

  • 创造性设计模式定义了设计对象实例化方法的方式,例如使用继承或封装来实例化对象的不同方式等。
  • 结构设计模式定义了创建类和关系的设计方法,重点是保持它们的灵活性和高效性
  • 行为设计模式定义了设计相关类行为的方法,重点是类和对象如何相互通信

虽然设计模式更适用于面向对象编程,但它的设计概念是与代码无关的。了解不同的设计模式使您能够选择适用于该问题的设计模式。每个设计模式的详细说明可以在这里找到。

№1.规划您的组件

“如果你没有计划,你就计划失败。”——本杰明·富兰克林

总是仔细检查项目需求并计划组件以防止将来主要的代码重组是有好处的。

在大多数情况下,在编写代码的时候,你确实对代码库的结构有一些想法。例如,数据科学工作流分为数据接收、数据处理、特征工程、建模和评估组件,并且作为关注点分离最佳实践的一部分,为每个组件创建单独的文件夹或文件。

这些组件可以源自项目的性质(在这种情况下是数据科学工作流),也可以是特定于项目的组件。如果项目需要添加额外的组件,比如数据分析,那么就要为它做好计划,并尽早将它们包含进来。

最后,除了与代码相关的组件,规划与数据相关的组件也很重要。确定将要加载和保存的数据量和内容,并设计数据的存储方式!

№2.不断抽象你的代码

“设计是一个迭代的过程。一个想法往往建立在另一个之上”——马克·帕克

按照上一节,当您完成所有组件时,代码正常工作,没有任何中断——但是将来会中断吗?可能会有变化或新的需求、数据、特性或实现方法。

让我们假设数据路径发生了变化,您最终更改了代码的多个部分来从新路径中读取数据——这发出了一种猎枪手术代码味道的信号。您执行抽象,将数据路径抽象到配置文件中,问题就解决了。

第二天,数据格式发生了变化,您最终更改了代码的多个部分来改变数据的读取方式——这发出了一种猎枪手术代码味道的信号。您执行抽象,将代码抽象成一个加载数据的新函数,问题就解决了。

这就引出了一个问题——您应该事先执行抽象吗?您第一次没有正确规划组件吗?然而,如果您过度抽象您的代码,这可能会导致不必要的复杂性,因为您过度设计了代码(这也是另一种代码味道)。这是编码最佳实践在理论和实践上的冲突。

一般的经验法则是执行关注点分离,而不是硬编码变量。如果您不得不在项目过程的后期抽象出组件,那也没关系——变化确实会发生,编码是一个迭代循环。

№3.利用开源工具

不要多此一举

因为现在每个组件都是分离的,所以很容易感到渴望从头开始实现每个组件。手工实现组件也让开发人员对流程有了更多的控制,因为每个部分都可以根据需要进行调整。

然而,你写的代码越多,代码库越复杂,其他开发者就越难理解你的代码库。如果其他开发人员不理解你的代码库,将来很难维护。利用其他开发人员广泛使用和了解的开源工具会更容易。

例如,如果您正在安排作业,请使用 Apache Airflow。如果你在做实验,用 MLFlow 跟踪你的实验。利用开源工具并将其集成到项目中,因为它们通常由自己的开发人员更好地开发和维护,这样您就少了一份担心。

结论

在重构和重组了来自我的队友的多个代码库以及我自己的代码库之后,我发现这些技巧是有益的,可以节省我很多时间和精力。编码实际上是一个迭代周期,即使遵循了编码最佳实践,我仍然发现自己在做调整和改变。我希望这篇文章对编码标准、最佳实践、代码味道和设计模式有所启发,并且这些提示将成为您在未来项目中考虑的东西!

概括来说,这是本文分享的 3 个技巧

  1. 规划您的组件
  2. 不断抽象你的代码
  3. 利用开源工具

感谢您的阅读!如果你喜欢这篇文章,请随意分享。

相关链接

编码标准

设计模式

与熊猫建立更稳固管道的 3 个技巧

原文:https://towardsdatascience.com/3-tips-to-create-more-robust-pipelines-with-pandas-c404c52ad216

高效有序的工作流程之路。

Unsplash偷拍的照片

Pandas 是一个数据分析和操作库,所以它可以让你从杂乱的原始数据到丰富的见解。不过在这个过程中,你可能会做一系列的数据清理、处理、分析操作。

当您有一组连续的步骤来预处理原始数据时,pipe 函数有助于设计一个有组织的、健壮的工作流。

在本文中,我将分享在设计更好的管道时很重要的 3 个技巧。

在开始学习这些技巧之前,让我们先简单介绍一下什么是管道并创建一个管道。管道是指使用管道功能连接的一系列操作。管道中使用的函数需要将一个数据帧作为输入,并返回一个数据帧。

我有一个包含一些模拟数据的数据帧:

import numpy as np
import pandas as pddf = pd.read_csv("sample_dataset.csv")df.head()

df(作者图片)

以下是需要在该数据帧上完成的操作列表:

  • 日期列的数据类型是 string,需要将其转换为适当的数据类型。
  • 价格列中有缺失值,需要用以前的价格填充。
  • 销售数量列中有一些异常值,需要删除。

我们的管道包含 3 个步骤。我们首先为上面的任务定义函数。

def handle_dtypes(df):
    df["date"] = df["date"].astype("datetime64[ns]")
    return dfdef fill_missing_prices(df):
    df["price"].fillna(method="ffill", inplace=True)
    return dfdef remove_outliers(df):
    return df[df["sales_qty"] <= 2000].reset_index(drop=True)

这里是管道:

df_processed = (df.
                 pipe(handle_dtypes).
                 pipe(fill_missing_prices).
                 pipe(remove_outliers))

通过分别应用这些功能,可以完成相同的操作。但是,管道功能提供了一种结构化和有组织的方式,可以将多个功能合并到一个操作中。

根据原始数据和任务,预处理可能包括更多步骤。我们可以使用管道功能根据需要添加任意多的步骤。随着步骤数量的增加,与单独执行函数相比,管道函数的语法变得更加清晰。

我们现在有了一个功能管道,所以我们可以从吸头开始。

1.独占启动管道

在下面的管道中,我们将修改后的 DataFrame 赋给另一个名为“df_processed”的变量。

df_processed = (df.
                 pipe(handle_dtypes).
                 pipe(fill_missing_prices).
                 pipe(remove_outliers))

我们可以假设原始数据帧 df 保持不变。然而,事实并非如此。即使我们将流水线的输出赋给另一个变量,原始的数据帧也会被更新。

这不是一个好的做法,因为我们通常希望保持原始数据对我们可用。解决方案是用一个独占的启动步骤来启动流水线,它只是复制原始的数据帧。

这个步骤可以使用下面的函数来完成。

def start_pipeline(df):
    return df.copy()

让我们也相应地更新管道。

df_processed = (df.
                 pipe(start_pipeline).
                 pipe(handle_dtypes).
                 pipe(fill_missing_prices).
                 pipe(remove_outliers))

现在,无论我们在管道中做什么,原始数据帧都保持不变。

2.添加参数

参数为函数增加了更多的功能和灵活性。我们可能在管道中有带参数的函数。

酷的是这些参数可以在管道内部访问。我们可以用它们作为管道函数的参数。

为了演示这种情况,让我们通过将检测异常值的阈值作为一个参数,使删除异常值函数更灵活一些。

def remove_outliers(df, threshold=2000):
    return df[df["sales_qty"] <= threshold].reset_index(drop=True)

默认值是 2000,因此如果我们在管道中不使用该参数,异常值阈值将是 2000。

我们可以如下控制流水线中的阈值:

df_processed = (df.
                 pipe(start_pipeline).
                 pipe(handle_dtypes).
                 pipe(fill_missing_prices).
                 pipe(remove_outliers, threshold=1500))

3.记录

我们有一个由 4 个步骤组成的管道。根据原始数据和手头的任务,我们可能需要创建包含多个步骤的管道。

在这样的工作流中,跟踪每一步发生的事情是很重要的,这样在出现问题时就更容易调试。

我们可以通过在每一步之后记录一些信息来实现这一点。在我们的管道中,数据帧的大小告诉我们是否发生了意想不到的事情。

让我们在管道中应用每一步后打印数据帧的大小。由于这些步骤是函数,我们可以使用 Python 装饰器来完成这项任务。

一个装饰器是一个接受另一个函数并扩展其行为的函数。不修改基本函数。装饰者包装它并添加额外的功能。

这是我们将在管道中的函数上使用的装饰器。

from functools import wrapsdef logging(func):
    [@](http://twitter.com/wraps)wraps(func)
    def wrapper(*args, **kwargs):
        result = func(*args, **kwargs)
        print(f"The size after {func.__name__} is {result.shape}.")
        return result
    return wrapper

我们将如下“装饰”管道中使用的函数:

[@logging](http://twitter.com/logging)
def start_pipeline(df):
    return df.copy()[@logging](http://twitter.com/logging)
def handle_dtypes(df):
    df["date"] = df["date"].astype("datetime64[ns]")
    return df[@logging](http://twitter.com/logging)
def fill_missing_prices(df):
    df["price"].fillna(method="ffill", inplace=True)
    return df[@logging](http://twitter.com/logging)
def remove_outliers(df, threshold=2000):
    return df[df["sales_qty"] <= threshold].reset_index(drop=True)

让我们重新运行管道。

df_processed = (df.
                 pipe(start_pipeline).
                 pipe(handle_dtypes).
                 pipe(fill_missing_prices).
                 pipe(remove_outliers, threshold=1500))**# output**
The size after start_pipeline is (1000, 3).
The size after handle_dtypes is (1000, 3).
The size after fill_missing_prices is (1000, 3).
The size after remove_outliers is (997, 3).

我们现在有了一个输出,它告诉我们管道中的流程。您可以定制日志记录功能,并添加一些其他功能,如测量函数执行所需的时间。

你可以成为 媒介会员 解锁我的全部写作权限,外加其余媒介。如果你已经是了,别忘了订阅如果你想在我发表新文章时收到电子邮件。

结论

管道非常适合组织数据清理和处理工作流。我们在本文中所做的例子似乎很容易通过分别应用函数来处理。然而,考虑到我们有超过 10 个步骤应用于原始数据。与使用管道相比,用单独的函数处理它们调试起来有点麻烦和乏味。

感谢您的阅读。如果您有任何反馈,请告诉我。

掌握连续调色板的 3 个技巧

原文:https://towardsdatascience.com/3-tips-to-master-your-sequential-palette-a56a46bd7853

有意义地使用颜色

作者配图

数据可视化中使用了三种调色板:分类调色板、顺序调色板和发散调色板。每一种都有其适当的用途,并带有不同的数据类型。所以如果你不确定区别在哪里,我建议退一步,先看看这篇文章

连续调色板遵循与感知色彩明度(也称为亮度或发光度)相关的顺序。因此,这个调色板适用于从低值到高值的数据。它有一个序数(如李克特量表),间隔(如温度),或比例(如利润值)。通常,调色板从代表较低值的浅色到代表较高值的深色。

亮度是颜色的所有三个感知维度的结果:色调、饱和度(或色度)和明度(或亮度)[1]。由于这种复杂的相关性,颜色亮度的线性变化可以通过三种不同的方式实现。根据我们改变的感知维度,我们区分三种类型的连续调色板:

  • 灰度 —如果只是亮度发生了变化
  • 单一色调 —明度和色彩丰富度都变了
  • 多色调 —色调、色彩丰富度和亮度已经改变

1)保持亮度的线性变化

连续调色板中的颜色遵循直观表示值变化的顺序。因此,颜色的变化,更准确地说是亮度的变化,必须适应数值的变化。当我们创建一个音阶时,我们应该保持相等的间隔。唯一的例外是对数标度。不是以相等的增量(线性)增加,而是以对数为底的因子(指数)增加每个间隔。

对数标度值得单独撰写一篇文章,所以我们现在只关注线性标度。对于这些标度,亮度的变化必须是线性的,并且每一步的亮度差应该相等。这极大地影响了评估两点之间差异的准确性。

我们可以在许多程序或软件包中找到默认调色板,它们可能被错误地归类为顺序调色板。为了避免误用调色板,请检查亮度是如何变化的。如果亮度改变方向,保持不变,或变化不一致,寻找另一个调色板。

亮度变化方向不一致

彩虹调色板是亮度矢量变化不一致的调色板的完美例子。拥有许多不同的色调会导致亮度值和方向的突然跳跃。就像下面的例子,最轻的点在中间的某个地方。

在彩虹调色板中,光度(下面的灰色版本)在两个方向上都发生了变化——这是作者的一个图表。

亮度没有变化

当渐变具有恒定的亮度时,它只是对连续调色板的模仿。亮度没有变化给了每一步相同的感知权重,使得评估变化的价值或方向变得更加困难。因为颜色的亮度取决于色调、饱和度和亮度,所以我们必须仔细选择开始和结束颜色。一个好的开始是避免将感知亮度相同或非常相似的颜色配对。显示 12 种原色亮度的图表可能会很方便。

调色板基于两种亮度相同的颜色——作者的图表。

亮度变化不一致

乍一看,亮度变化不一致的连续调色板,尤其是连续调色板,可能看起来很好。但如果你转向阶梯式版本,它的古怪就变得更加明显了。亮度的跳跃在视觉上增强了一些步骤之间的差异,并减小了其他步骤之间的差异。如果我们不检查图例,我们可能会无意识地认为在第二种和第三种颜色之间有一些额外的步骤。

亮度跳跃的调色板——作者的图表。

光度的线性变化

具有线性亮度变化的连续调色板在连续和离散变体中都得到很好的平衡。因此,任何两种颜色之间的关系都不会混淆。如果你想确保你的调色板遵循线性模式,你可以使用 Chroma.js 调色板助手。这个免费的在线工具将帮助你纠正亮度。我建议从解释如何利用其全部潜力的文章开始。

亮度线性变化的均衡有序调色板—作者的图表

2)添加色调变化

如果发光变化一定是线性的,是不是意味着我们要避免使用两种以上的颜色?

答案可能会让你吃惊,但是在一个连续的调色板中使用两种以上的颜色并没有错。此外,添加色调变化可以为我们的调色板带来额外的改善。它提供了更好的颜色对比,从而使颜色更容易区分。它降低了极端值的重要性,增加了序列中所有值的重要性[4]。

在基于两种颜色的多色调连续调色板中,我们应该为较亮的一端选择较高的亮度,为较暗的一端选择较低的亮度。以黄色(亮度最高的颜色)开始调色板,以蓝色、绿色或红色结束调色板是一个很好的选择,因为亮度会有明显的差异。但是正如你在下面的例子中看到的,调色板以深绿色开始,以浅蓝色结束是行不通的。

基于两种色调的多色调调色板——对比度好的从较亮的颜色开始,对比度差的从较暗的颜色开始。作者配图

如果我们想要包含两种以上的色调,这个过程会变得更加复杂,因为颜色的所有三个维度(色调、饱和度/色度、明度/亮度)都在同时变化[1]。使用一系列色调的规则是根据它们的亮度进行排序,并在整个调色板中保持高饱和度/色度。

在下面的例子中是两对互补的调色板。顶行由三种色调的版本组成。中间的色阶更加饱和,使其更加突出。底部的调色板仅由两种色调组成,不强调中间值,而强调极端值。

两对相似的多色调——上面的是基于三种色调,下面的是基于两种色调——作者的图表。

3)使用单一色调的色度轨迹

我们已经讨论了连续调色板中的亮度应该线性变化,但是色调呢?这可能是违反直觉的,但是在中间有最丰富多彩的步骤对于单一色调调色板来说是一个很好的解决方案。要做到这一点,我们必须从使用色度而不是饱和度开始。这意味着从 HSL (色相-饱和度-明度)或 HSB (色相-饱和度-明度)色彩模型切换到 HCL (色相-色度-明度)。

HCL 模型最显著的优点是它最接近人类感知颜色的方式。这就是为什么在数据可视化软件中广受欢迎,并被整合到 R、Python 或 JavaScript 包中。

根据心理物理学理论,人类用三维来描述颜色[5]:

  • 色调(通常与颜色本身联系在一起)
  • 色度(颜色相对于灰色的强度)
  • 亮度(亮度,灰度)

将最丰富的颜色放在调色板的中间可以使色阶更容易区分[4]。下面是用 HCL 模型创建的调色板的两个例子。左边的遵循色度的线性变化,这使它看起来很平,而右边的融入了三角形色度轨迹。类似于前面的例子,当调色板的中间部分被去饱和时,它强调了极端。增加中间颜色的丰富性使它们变得同等重要。

受色彩空间工具箱启发的示例[4]。左边是色度线性变化的顺序调色板,右边是色度三角形变化的调色板(最丰富的颜色在中间)——作者的图表。

不想错过我的任何帖子? 直接把它们发到你的收件箱里!

如果你还不是中等家庭的一员,考虑注册成为会员。它每月只需 5 美元,支持数千名作家。 注册我的会员链接 ,除了可以访问所有发表的内容,你将得到我永远的感激。

链接

[1] M .哈罗威,c .布鲁尔, ColorBrewer.org:选择地图配色方案的在线工具 (2003 年),制图杂志

[2] C. Shanley,混合亮度相等的颜色—第 1 部分 (2020),中等

[3] G. Aisch,利用 Chroma 掌握多色调色阶. js (2013),作者博客

[4] A. Zeileis,J.C. Fisher,K. Hornik,R. Ihaka,C.D. McWhite,p .穆雷尔,R. Stauffer,C.O. Wilke,色彩空间:操纵和评估颜色和调色板的工具箱 (2019),arXiv.org 电子印刷档案馆

[5] A. Zeileis,K. Hornik,p .穆雷尔,逃离 RGBland:为统计图形选择颜色 (2007),研究报告系列/统计和数学系

通过智能提示降低 OpenAI GPT-3 成本的 3 个技巧

原文:https://towardsdatascience.com/3-tips-to-reduce-openai-gpt-3s-costs-by-smart-prompting-53c457229cfc

减少 GPT-3 提示令牌并节省资金

作者图片

GPT-3 的最高和最准确的模型达芬奇成本为每 1000 代币 6 美分。因此,在生产应用中进行大规模运营并不便宜。

所以除了设计提示之外,掌握智能提示的技巧也很重要,那就是减少输入提示中的标记数量。

在本教程中,我们将看到一些技术来减少给定提示中的令牌数量,这些技术来自我构建superme . ai的经验,这是一个基于 GPT 3 的应用程序,目前正在生产中。请记住,每减少 1000 个代币可以节省 6 美分(0.06 美元),因此从规模上来看,这是巨大的。

1.迅速解释

所以让我们从 OpenAI 的游乐场本身提供的一个例子开始,叫做“来自产品描述的广告”。

在下图中,输入是黑色文本,输出是 GPT-3 生成的绿色高亮文本。

为了在生产应用程序中运行,第一行“在脸书上为以下产品写一个创意广告给 rn,目标是父母:“,总是保持不变,只有产品描述是从用户输入中动态获取的。

GPT 3 号游乐场广告描述示例

在下图中,您可以看到第一行输入来自 GPT-3 令牌估计器的 16 个令牌。

具有 16 个令牌的原始提示

但是我们可以使用类似于 Quillbot 的解释工具来缩短提示,然后在 GPT-3 令牌估计器中测试修改后的提示的令牌总数。请注意,字数的减少并不一定意味着标记的减少,因为 GPT-3 标记器是根据自己的数据训练的,并不直接与单词相关。

用 Quillbot 解释提示

新的转述提示“为以下针对父母的产品创建一个聪明的脸书广告”,只需要 13 个令牌,而原来的提示需要 16 个令牌。这是一个 3 令牌减少!

只有 13 个标记的解释提示

通过在操场上再次测试,你可以看到转述提示在为脸书生成一个好的广告文案方面也很有效。

如果您对转述提示符生成的文本感到满意,那么您可以继续使用转述提示符,它的令牌数更少,生产成本也更低。

生成的带有解释提示的广告

2.NER 替换提示

让我们考虑另一个例子,你试图对一个给定的句子进行情感分析。在下图中,你可以看到输入的句子是“rams ri 喜欢在 Supermeme 的办公室工作”。在这里,Ramsri 是一家公司的名字,Supermeme 是一家公司的名字

原始提示情绪

如果您查找该提示消耗的令牌数,您可以看到“Ramsri 喜欢在 Supermeme 的办公室工作”总共有 11 个令牌。这是因为 Ramsri 对于 GPT-3 记号赋予器来说不是一个已知单词,所以它将 Ramsri 拆分为“R”+“AMS”+“ri”(3 个记号),如下图中的彩色编码文本所示。

但是有趣的部分来了!能不能把 Ramsri (3 个令牌字)换成一个像‘约翰’这样的令牌字,省两个令牌?答案是肯定的!

原始句子标记计数

因此,您可以用“John”替换“Ramsri ”,用“Google”替换类似的“Supermeme ”,并将句子的令牌从 11 个减少到 7 个!

因此,本质上,您可以进行 NER(命名实体识别)来识别命名实体,如名称、组织、地点等,并用相应的一个替代令牌来替换它们。

NER 修改令牌计数

就句子的情感而言,不管你有“约翰快乐”还是“拉姆斯里快乐”!对于这种情况,它总是产生积极的正确情绪。

NER 取代了即时情绪

3.多任务提示

与多次调用 GPT-3 引擎并为每个单独的任务消耗令牌相比,您可以在一个提示中组合多个任务。

在这里,你可以看到,在一个提示中,我们能够将句子“埃隆·马斯克再次表明,他可以通过他的推文影响数字货币市场”修改为 1。较短的版本 2。更长的版本和 a 3。正式版。

如果单独完成,您将需要 3 次调用 GPT-3 API,并且您将因句子中的令牌数量而被计费 3 次,“埃隆·马斯克再次表明,他仅通过他的推文就可以影响数字货币市场”

但是通过一些仔细的提示,我们能够将多个任务批处理到一个提示中!

多任务提示

祝 NLP 探索愉快,如果你喜欢它的内容,请随时在 Twitter 上找到我。

如果你想以实用的方式学习 NLP,请查看我的课程自然语言处理实用介绍

成功实现数据可视化需要的 3 个技巧

原文:https://towardsdatascience.com/3-tips-you-need-to-be-successful-in-data-visualization-9b5225ab7afc

你的数据很好,但你可以做得更好

工作室共和国Unsplash 拍摄的照片

我喜欢把数据可视化看作类似绘画的东西。这位艺术家有一个故事要讲——他有向世界展示他的杰作所需的一切图片——布局、概念和灵感。这幅画仍然在他的脑海中,但剩下的就是拿起他的装备,开始画画。

为了让你的观众理解故事的全部含义,你的可视化数据的能力必须是一流的。你需要尽可能用最简单、最容易理解的方式展示你的分析。

目的是用你的分析讲一个故事。

从普通的计算机科学家转行到数据分析师后,我意识到在数据科学行业发展有利可图的技能是转行过程的一部分。不要误解我的意思,对于每个数据科学家来说,扎实的计算机科学背景是必不可少的

如今,每个人都在利用大数据的优势,金融机构、小型企业和蓬勃发展的公司都依靠大数据的概念来构建和简化他们的数据库。

数据分析师收集和分析数据,但这并没有全部结束。收集的信息仍然需要呈现给最终用户,他们需要这些数据来学习或做出有价值的决策。这就是数据可视化派上用场的地方。

为了提高数据可视化的专业性,您需要熟悉一些基本技巧。这些技巧不仅仅是通往成功的一次性秘籍,为了最大化你的效率,你需要练习,并让这些技巧成为你可视化过程的一部分。

不多说了,这里有三个技巧可以帮助你将数据可视化事业提升到一个新的水平。

1。比工作更关注你的听众。

把你的观众放在首位。

总是有一种将努力投入到你的分析内容中的驱动力,想要使项目尽可能的整洁和有效是绝对正常的。但是大多数数据专业人员犯的一个主要错误是忽视了受众。

正如詹姆斯·斯图尔特所言,

"永远不要把你的观众当成顾客,而要把他们当成合作伙伴."

要让每一个可视化项目都满足你受众的信息需求。假设我们的分析将被我们这些数据科学家利用,我们基本上可以使用科学方法来可视化数据的组成部分。

我甚至可以决定把数据集留在我的笔记本里——我仍然会从我需要的信息中获得最好的信息。

但是我们有受众,很可能是技术人员和非技术人员的混合体。设身处地为观众着想。

  • 谁是你的观众?他们是以技术为导向的,还是来自不同行业的随机人群?
  • 你希望你的观众对你的第一印象是什么,畏缩还是着迷?
  • 他们想什么时候停止学习?就我个人而言,我有一个学习极限,一旦超过了这个极限,一切都变得索然无味。大多数人也有类似的特质,做一些研究,问问自己你希望你的演示有多长——特别是如果是视频或幻灯片演示的话。
  • 他们为什么要关注你?根据研究,人类不喜欢用无聊的视觉呈现信息。因此,当他们遇到凹凸不平或锯齿状的信息时,他们往往会失去注意力。关键是保持平衡,保持简单。

2。在你的图形中确定正确的概念。

获得完美的图形和你展示的数据一样重要。

在数据可视化中,大多数图形都不是万能的,不是所有的图形都适用于所有情况,有时您需要思考、观察并走出舒适区,选择能够简化数据本质的正确图形。

有一些特定的概念与图形表示的想法结合在一起,所有这些概念同时发挥作用,以获得数据可视化的最佳效果。让我们指出几个:

答:图表:

图表有日期吗?

从个人角度来说,图表是数据可视化最有效的基本方法。大多数时候,有点“传统”可能正是你最大限度地发挥数据科学潜力所需要的。

我和一群全国最好的数据专家一起做一个数据会计项目——我说的是一些有才华的男人和女人,他们有趋势研讨会和大量出版物来支持他们的工作。

经过数据整理和分析,项目结束。但我们要向几乎没有技术背景的人展示的是一群商业巨头,他们基本上花了大半辈子研究经济学和金融学的根源。

因为我们已经了解我们的受众,所以关键是缩小我们的数据视觉效果,使之更加微妙。再说一遍,理解你的听众有更多的好处。

B.布局模式:

尽管每个概念都很重要,但模式选择仍然是数据可视化中的一个固定类别。

简而言之,一个好的模式会设定正确的基调,而一个不合适的模式可能会误导你的受众如何接受数据的叙述。

人类的大脑不断寻找我们最近或过去遇到的物体、人、颜色,甚至习惯性的动作。我们是天生的视觉敏锐者。我们的眼睛和大脑能够快速处理某些指示,这些指示说明或显示了我们需要的信息。

作为数据科学家,我们如何利用这一点?

尽管您喜欢在选择模式时多样化,但最好是将选择范围缩小到可预测的和常见的模式。

简单有效胜于复杂混乱。

C.颜色:

我讨厌颜色。

开玩笑的。

颜色很棒。除了非常棒之外,它们还是您成功进行数据可视化项目的门票。在数据可视化中,颜色是文字或数字的最佳替代品。

在您的数据可视化设计中应用完美的颜色混合,甚至在您开始演示之前,就可以让查看者快速浏览数据及其目标。

选择时请记住以下几点:

  • 将你的颜色限制在 2-3 种,太多的颜色只会让项目显得业余。
  • 如果您正在处理与温度相关的数据集,请使用红色表示高温,天蓝色表示低温。
  • 用绿色的表示积极,用红色表示不确定。
  • 开始的时候,让设计尽可能吸引人。
  • 而不是使用多种颜色。选择一个并修改对比度以匹配您的数据集。

3。停止成为数据可视化软件程序的小气鬼。

有很多专门为数据可视化开发的软件。这些工具中有很大一部分是免费使用的,其他的需要付费才能使用,还有一些两者兼而有之——功能有限的免费版和让你完全使用高级功能的付费版。

“一定会有另一种软件,以更低的价格提供类似的功能”

在购买应用程序时,我们喜欢扮演华尔街的经济学家。

每个人都这样做。在做出财务决策之前,我们往往会考虑其他选择。

相反,带着这种心态进入数据可视化并不是一个好主意。使用廉价的工具可能会毁掉你在数据分析上的所有努力。

结果不会是专业的,随着数据科学行业的高度竞争,不专业的工作是数据可视化中最不希望出现的事情。

"没有专业精神,我会是一个业余爱好者,我想要的客户不会雇佣业余爱好者."

大卫·艾雷。

选择合适的工具,完美满足您的解决方案需求。如果它要求你在获得最大化的特性上花费一些钱,那就去做吧。

TableauSPSS 是你可以用来进行数据可视化的有效工具。

适用外卖

数据可视化的艺术仍然非常微妙,需要很高的技术水平。

有数以百计的博客、在线社区和论坛致力于数据可视化,可以帮助您提高以前获得的技能,并开发新的技能。

数据可视化不仅仅是一种技能,更是一种生活方式。不断学习,寻找新的方法变得更好。

3 个用于快速数据分析的工具

原文:https://towardsdatascience.com/3-tools-for-fast-data-profiling-5bd4e962e482

使用这些 Python 工具快速分析和总结您的数据

罗宾·皮耶尔在 Unsplash 拍摄的照片

数据概要分析是任何数据科学项目的首要步骤之一。它是探索性数据分析的一种形式,旨在分析、描述和总结数据集,以了解其质量和基本特征。

数据分析任务用于通知数据科学项目中的进一步步骤,例如所需的数据清理的类型和范围,以及可能需要应用的任何其他预处理技术。在没有首先应用至少一些基本处理的情况下,真实世界中的数据很少准备好用于诸如机器学习之类的任务。

数据分析中涉及的许多步骤在不同的数据集和项目中是通用的。数据分析通常包括对每一列应用描述性统计、确定缺失值的数量以及了解变量之间存在的交互和相关性等任务。

由于这些任务可能非常常规,因此有许多开源 Python 库寻求自动化数据分析任务。在本文中,我将通过代码示例简要介绍三个 Python 包,它们极大地简化并加速了这个初步的探索性分析。

1.勒克斯

Lux 是一个 python 库,作为流行的数据分析包 Pandas 的补充。Lux 库提供了一种简单的方法来快速创建数据集的可视化,并以最少的代码应用基本的统计分析。此外,Lux 还提供了一些工具,可帮助指导和通知数据分析的后续步骤。

Lux 可以通过运行以下命令来安装。如果您在交互式 Jupyter 笔记本中使用 Lux,您还需要安装 Lux 小工具。

$ pip install-api# Install Lux widget for Jupyter Notebooks$ jupyter nbextension install --py luxwidget
$ jupyter nbextension enable --py luxwidget# Or for JupyterLab$ jupyter labextension install @jupyter-widgets/jupyterlab-manager
$ jupyter labextension install luxwidget

为了说明其中的一些功能,我将使用一个来自 Kaggle.com 的数据集。数据可以通过这个链接下载。该数据集包含来自 1990 年加利福尼亚人口普查的与加利福尼亚地区住房相关的各种属性。

一旦莱克丝安装好,我们就把它和熊猫一起进口。现在,当我们运行某些常用的熊猫函数时,Lux 提供了一些增强的功能。

如果我们将 Lux 和 Pandas 都导入到一个笔记本中,然后运行df,在读取上述数据集后,我们将在显示的 dataframe 上方看到一个新按钮,如下所示。

熊猫/力士切换。作者图片

单击“切换熊猫/勒克司”按钮会显示一系列交互式可视化,为数据集中的要素提供基本的统计分析。此外,单击黄色警告三角形可以深入了解与所提供的分析相关的任何警告。

正如您在下图中看到的,Lux 报告有几个选项卡。套件中的第一个选项卡显示所有定量变量组合的相关图。此数据集的后续选项卡显示相关要素的分布和出现情况。

Lux 提供的自动分析报告。作者图片

除了提供一种快速可视化数据集的方法,Lux 还为进一步分析提供指导和建议。该功能由intent功能引导。为了表达您的分析意图,您可以将感兴趣的列传递给此函数,Lux 会提供合适的可视化效果,并显示分析中建议的后续步骤的图表。

在下面的例子中,我将两个列名传递给intent,“中位数 _ 房价 _ 价值”和“中位数 _ 收入”。Lux 返回一个散点图,比较这些列中的值与选择的其他图和增强之间的关系。

基于分析目的的 Lux 增强。作者图片

2.熊猫-侧写

pandas-profiling 工具也提供了一种快速了解数据集的方法。

Pandas-profiling 可以按如下方式安装。我已经给出了安装 Jupyter 扩展的可选命令,这是在笔记本中生成内联可视化所必需的。

$ pip install -U pandas-profiling
$ jupyter nbextension enable --py widgetsnbextension

熊猫概况的基本功能是概况报告。这提供了数据集中变量的详细概述。这样可以深入了解各个特征的统计数据,如分布、平均值、最小值和最大值。此外,该报告提供了变量之间的相关性和相互作用的见解。

熊猫-简介报告。作者创建的 Gif

一个很好的特性是 pandas-profiling 工具还集成了 Lux。如果我们导航到 profile 报告的 sample 选项卡,我们会再次看到 Toggle Pandas/Lux 按钮!

Lux 与熊猫的融合。作者图片

3.甜蜜的

Sweet-Viz 是另一个用于快速数据可视化和分析的开源 Python 库。Sweet-Viz 的卖点在于,它提供了一个丰富的 HTML 仪表板,其中包含有用的可视化和数据汇总,并且只有一行代码。

Sweet-Viz 可以用下面的命令安装。

$ pip install sweetviz

让我们看看生成 Sweet-Viz 仪表板所需的代码。

HTML 报告将在您的浏览器中打开。

甜蜜的仪表板。作者图片

与本文中的其他两个库相比,Sweet-Viz 的一个很好的附加功能是能够比较不同的样本或数据版本。例如,如果您想要比较从不同时间段收集的机器学习的训练数据集,这可能非常有用。

为了演示这一点,在下面的代码中,我将数据集分成了两部分。然后,我使用 Sweet-Viz compare函数生成了一个报告,该报告提供了一些分析来比较这两个样本的 chrematistics 和 statistics。

Sweet-Viz 仪表板比较两个数据集。作者图片

本文中涉及的三个库都试图在应用其他数据科学技术之前,自动执行常规的数据分析任务。

虽然每个工具执行相似的任务,但它们都有独特的功能。我在下面提供了我对每个库的主要想法的简要总结。

  1. Lux 通过现有的 pandas 功能提供可视化数据分析,如果你已经是 pandas 的用户,这将非常容易使用。它还提供了一些建议来指导您使用intent功能进行分析。然而,Lux 没有给出关于数据集质量的更多指示,例如提供缺失值的计数。
  2. Pandas-profiling 用一行代码生成丰富的数据分析报告,并在 Juypter 笔记本中显示出来。该报告提供了数据分析的大部分元素,包括描述性统计数据和数据质量指标。熊猫轮廓也与力士集成。
  3. Sweet-Viz 提供了一个全面的、视觉上吸引人的仪表板,涵盖了所需的绝大多数数据概要分析。这个库还提供了比较同一个数据集的两个版本的能力,这是其他工具所不能提供的。

感谢阅读!

致谢

加州住房数据集: 该数据集最初从 StatLib 存储库[https://www . DCC . fc . up . pt/~ ltorgo/Regression/cal _ housing . html]获得,在 CCO 1.0 Universal (CCO 1)许可下使用。

成为更好的数据科学家所需的 3 项可转移技能

原文:https://towardsdatascience.com/3-transferrable-skills-you-need-to-become-a-better-data-scientist-435586b094a2

培养以产品为中心的思维模式有助于交付有影响力的数据科学解决方案

在开始我的数据科学职业生涯后不久,我看到了一篇关于产品管理的文章。我立刻产生了兴趣,并在接下来的几个月里尽可能多地学习这个领域的知识。当我开始将我学到的知识应用到我的数据科学工作中时,我意识到我获得的知识有助于弥合学术数据科学项目和公司真实数据科学工作之间的差距。这篇文章概述了我通过学习产品管理获得的三项技能。将它们应用到我的日常工作中使我成为了一名更好的数据科学家,我希望它能帮助你更上一层楼。

来源: Unsplash 上的 Jexo

结构化思维和清晰的问题框架

数据科学家需要关注的一项基本任务是定义问题并获得业务理解。没有在数据科学生命周期的这个阶段投入足够的时间,可能会导致无法满足利益相关方的需求,或者完全解决错误的问题。像数据科学家一样,产品经理通常需要解决任何问题,将其分解为可操作的步骤,并制定解决问题的策略。掌握这项技能将有助于你成为一名更好的数据科学家,确保你创建一个有效的解决方案来解决正确的问题。

如何发展这项技能:

问题几乎总是以一种非结构化和模糊的形式出现。在深入研究更多的技术方面之前,数据科学家应该对它们进行清晰的划分和定义。结构化思维是一个处理模糊问题并添加结构/创建框架来解决问题的过程。下面是一种给不清楚的问题增加结构的方法。

第一步:将问题分解成最简单的元素

这一步的主要目标是识别问题。识别和定义问题的一种方法是使用第一性原理思维。这种方法帮助你将问题分解成核心要素,然后将信息拼凑起来,构建一个创新的解决方案。你可以在这里和这里了解更多基本原则思维。通过将一个模糊的问题分解成可管理的部分,你将能够找出问题的根源以及如何解决它。

步骤 2:验证问题

一旦确定了问题,就该验证它了。这是您的最终用户面临的真正问题,还是有更大的问题需要优先解决?验证这个问题需要定量和定性的证据。评估机会的大小至关重要。例如,如果你建立一个模型来帮助客户流失,试着产生一个每年损失多少钱的美元值。与最终用户和关键涉众交谈以获得领域知识对于验证问题也是至关重要的。

步骤 3:创建问题陈述

一旦您更好地理解了问题,并用数据、研究和领域知识验证了它,创建一个您和您的团队可以在整个项目中参考的问题陈述是至关重要的。拥有一份清晰简洁的问题陈述是在项目的开始阶段协调利益相关者的关键工具。

步骤 4:定义结果和成功标准

创建问题陈述后,下一步是定义结果和成功标准。换句话说,你怎么知道你已经解决了这个问题?理想情况下,衡量标准应该是一个具体的数字,表明解决方案是成功的。需要考虑的一些事情有:

  • 解决问题的理想业务成果
  • 对最终用户的影响
  • 基准绩效与理想的未来绩效

通过影响力进行沟通和领导

数据科学领域中讨论较少的一项技能是通过影响力而非权威进行沟通和领导。产品经理必须掌握这项技能,因为他们经常在跨职能团队中工作,并负责利用他们团队的资源来交付有影响力的解决方案。同样,数据科学家必须向非技术利益相关者传达复杂的技术概念。向非技术利益相关者解释分析的范围和能力是数据科学家工作的一个重要方面。有时利益相关者有相互竞争的优先级,数据科学家需要在问题上协调利益相关者。这样做需要很强的沟通和领导技能,因为大多数时候,利益相关者都是高管。获得通过影响力进行领导的技能可以让你成为一名更全面的数据科学家。

如何发展这项技能:

  • 关注大局,必要时深入技术细节
  • 关注业务成果并讲述一个故事
  • 找出每个利益相关者的动机,并尝试找到共同点
  • 公开分享信息,并经常与利益相关者沟通
  • 倾听并理解

强烈关注最终用户

产品经理是客户的拥护者。能够感同身受并理解客户的痛点是一项重要的技能。我认为关注最终用户在数据科学中也很重要。尤其是在选择项目的度量标准时,将最终用户放在心上是至关重要的。例如,假设您正在构建一个预测欺诈的模型,而最终用户是一个调查团队,他们必须决定是否应该关闭一个帐户。设身处地为调查人员着想,想想什么样的解决方案最适合他们。通过关注最终用户,您将能够更好地了解项目的用例,并创建一个使最终用户的工作更容易的解决方案。要在数据科学项目中做到这一点,请尝试关注模型的可解释性,并构建针对问题的定制指标。

最后,产品经理非常关注对业务和客户的影响。在数据科学工作中采用这种心态,尤其是在数据科学过程的问题框架/业务理解阶段,将有助于您成为更好的数据科学家。

美化 Matplotlib 情节的 3 个技巧

原文:https://towardsdatascience.com/3-tricks-to-prettify-matplotlib-plots-d0a73b861c09

你如何显示信息是至关重要的

图为 Unsplash 上的杜尔西·利马

Matplotlib 是 Python 的数据可视化库之母。它是其他一些用于可视化数据的工具的基础,如 Seaborn 和 Pandas。

Matplotlib 提供了很大的灵活性,因此您可以定制或调整图上的几乎任何内容。如果您想完全控制可视化效果,这是一个优势,但是这需要您编写更多的代码。

在本文中,我们将介绍 3 个可用于定制 Matplotlib 图的技巧,它们是:

  • 减少 x 轴或 y 轴上的刻度数
  • 添加辅助 y 轴
  • 共享 x 轴和紧凑布局的人物与支线剧情

我们将创建线形图,但是这些技巧也可以应用于其他类型的图。当然,我们需要一些数据来处理。我创建了一个包含模拟价格和销售数据的数据集。你可以从我的 GitHub 页面上的数据集库中下载数据集。让我们从从这个数据集创建一个熊猫数据帧开始。

import pandas as pd
import numpy as npdf = pd.read_csv("mock_sales_data.csv", nrows=100)df.head()

(图片由作者提供)

数据集包含日期、价格和销售量列。出于演示目的,我只读了数据集的前 100 行。

减少刻度数

如果绘制在轴上的数据点数很多,刻度可能看起来太紧,甚至在某些情况下重叠。处理时间序列数据时,x 轴通常包含占用大量空间的日期,因此最好减少轴上的刻度数。

我们先做一个例子,不限制 x 轴上的刻度数。

import matplotlib.pyplot as plt
plt.style.use("seaborn-darkgrid")# create a Figure object
plt.figure(figsize=(12, 6))# create the line plot
plt.plot(df["Date"], df["Price"])
plt.show()

(图片由作者提供)

刻度重叠,我们无法读取它们。让我们创建一个相同的图,但是使用更少的刻度。

# create a Figure object
plt.figure(figsize=(12, 6))# create the line plot
plt.plot(df["Date"], df["Price"])# show one tick for every 15 value and change the fontsize of ticks
plt.xticks(np.arange(0, len(df), 15), fontsize=12)
plt.yticks(fontsize=12)plt.show()

(图片由作者提供)

现在看起来好多了。我们使用 NumPy 的 arrange 函数指定了记号的位置。

第二 y 轴

我们有时想在同一个图上显示两个变量。例如,可以将一种产品的价格和它的销售数量绘制在一起,以查看价格对销售数量的影响。

如果价格和销售量具有非常不同的值范围,则需要一个辅助 y 轴。否则,情节将不会好看,甚至可能无法阅读。

下面是演示这种情况的一个示例。我们的数据框架中的销售数量和价格列显示在同一个线图上,只有一个 y 轴。

(图片由作者提供)

因为与销售量相比,价格值非常低,所以我们把它们看作一条直线,它不能告诉我们价格和销售量之间的任何关系。

让我们用第二个 y 轴生成同样的图。

# create a Figure and an Axes object
fig, ax1 = plt.subplots(figsize=(12,6))# create the second Axes object with same x-axis
ax2 = ax1.twinx()# create the line plots
ax1.plot(df["Date"], df["Price"])
ax2.plot(df["Date"], df["SalesQty"], color="orange")# create axis labels and title
ax1.set_ylabel("Price", fontsize=15)
ax2.set_ylabel("SalesQty", fontsize=15)# customize x-ticks and y-ticks
ax1.tick_params(axis='both', which='major', labelsize=12)
ax2.tick_params(axis='both', which='major', labelsize=12)# reduce the number of x-ticks
plt.xticks(np.arange(0, len(df), 15))# remove the grid lines
ax1.grid(False)
ax2.grid(False)plt.show()

(图片由作者提供)

看起来好多了。我们可以观察到价格和销售量之间的反比关系。

共享 x 轴和紧凑布局的人物与支线剧情

我们可以在一个人物对象上创建多个支线剧情。Matplotlib 允许使用 subplots 函数创建一个 subplots 网格。例如,下面的代码行创建了一个 2x2 网格的图形,其中有 4 个支线剧情。

fig, (ax1, ax2, ax3, ax4) = plt.subplots(nrows=2, ncols=2)

我们使用 nrows 和 ncols 参数定制网格的结构。

当创建一个有支线剧情的网格时,有一些事情要记住。第一个是 sharex 参数。如果我们把支线剧情一个接一个的放在一起,那么最好在底部的剧情上只有 x 轴。这可以通过使用 sharex 参数来实现。

另一个提高可读性的技巧是 tight_layout 函数。它可以用来调整支线剧情之间的填充。在某些情况下,支线剧情过于紧凑,甚至重叠。我们可以使用 tight_layout 函数来防止这种情况。

让我们用这些技巧做一个例子。

# create a grid of subplots with 2 rows
fig, (ax1, ax2) = plt.subplots(
    nrows=2, ncols=1, 
    sharex=True,
    figsize=(12, 8)
)# adjust the space between the subplots
fig.tight_layout(pad=2)# create the first subplot
ax1.plot(df["Date"], df["Price"])
ax1.set_title("Price", fontsize=15)# create the second subplot
ax2.plot(df["Date"], df["SalesQty"])
ax2.set_title("SalesQty", fontsize=15)# customize x-ticks and y-ticks
ax1.tick_params(axis='both', which='major', labelsize=12)
ax2.tick_params(axis='both', which='major', labelsize=12)# reduce the number of x-ticks
plt.xticks(np.arange(0, len(df), 15), fontsize=12)plt.show()

(图片由作者提供)

随意更改凸台参数的值,并查看其对图形的影响。

我们已经学习了 3 个自定义 Matplotlib 可视化的技巧。可视化显示的内容是关键部分,但如何显示也很重要。因此,这些技巧肯定会帮助您创建更多信息和功能的数据可视化。

你可以成为 媒介会员 解锁我的全部写作权限,外加其余媒介。如果你已经是了,别忘了订阅https://sonery.medium.com/subscribe如果你想在我发表新文章时收到电子邮件。

感谢您的阅读。如果您有任何反馈,请告诉我。

3 个棘手的数据分析问题以及如何用熊猫解决它们

原文:https://towardsdatascience.com/3-tricky-data-analysis-questions-and-how-to-solve-them-with-pandas-ceb53bbb9c9e

Pandas 简化并加速了复杂的任务

micha Parzuchowski 在 Unsplash 上的照片

Pandas 是数据科学生态系统中使用最频繁的库之一。它非常灵活和高效,几乎可以为您可能遇到的任何数据分析和操作问题提供解决方案。

在这篇文章中,我们将讨论 3 个相当棘手的数据分析和操作问题,并看看如何用熊猫来解决它们。

这些问题将与我用模拟数据创建的数据集相关。请随意从我的 GitHub 页面下载并跟随。我们将使用杂货数据集。

import pandas as pdgrocery = pd.read_csv("groceries.csv")grocery.head()

(图片由作者提供)

该数据集包含一些带有每日销售量和价格信息的杂货产品。

问题 1

价格列包含一些丢失的值。我们如何用产品的平均价格来替代这些缺失的值呢?请注意,我们不应该用价格列的平均值来填充缺少的值。苹果的缺失值需要用苹果的平均价格来填充,等等。

解决方案 1

有多种方法可以完成这个操作。最实用的选择之一是在fillna函数中使用groupby函数。

我们先来看看每个产品的均价。

grocery.groupby('product_description')['price'].mean()# output
product_description
apple           2.077778
butter-0.25    11.400000
cucumber        4.532857
grape           4.400000
milk-1.5        6.078571
onion           2.150714
orange          2.714286
plum            4.389655
tomato          3.121034
yogurt-1        6.693103
Name: price, dtype: float64

但是我们不能在fillna函数中使用这行代码。相反,我们将通过添加transform方法来稍微改变它。

grocery["price_new"] = grocery['price'].fillna(
   grocery.groupby('product_description')['price'].transform("mean")
)

让我们通过比较 price 列中缺少的值和新列中的值来检查结果。

grocery[grocery["price"].isna()].head()

(图片由作者提供)

番茄的缺失值用 3.12 填充,这是我们之前计算的平均值。类似地,黄瓜和洋葱的缺失值用正确的平均值填充。

问题 2

如何才能找到每个产品的最高价和最低价的区别?

解决方案 2

当然,完成这项任务有多种方式。groupby函数也为这个任务提供了一个快速的解决方案。我们不需要使用内置的聚合函数,只需要编写自己的函数。

在根据产品描述列对行进行分组之后,我们将应用一个 lambda 函数来计算最大值和最小值之间的差值。

grocery.groupby("product_description")["price"].apply(
    lambda x: x.max() - x.min()
)# output
product_description
apple          0.3
butter-0.25    1.0
cucumber       0.4
grape          0.0
milk-1.5       0.5
onion          0.3
orange         0.3
plum           0.8
tomato         0.6
yogurt-1       1.0
Name: price, dtype: float64

让我们检查最高和最低苹果价格之间的差异,以确认我们的结果。

max_apple = grocery[grocery.product_description=="apple"]["price"].max()min_apple = grocery[grocery.product_description=="apple"]["price"].min()max_apple - min_apple# output
0.30

它等于苹果在groupby函数输出中的差值。

问题 3

我们如何创建一个销售金额列来显示每次销售中销售了多少产品(以千克为单位)。

有些产品的单位是千克,所以我们可以只取它们的销售数量列中的值。然而,有些产品是按件出售的。这些产品的重量信息可从描述中提取。

butter-0.25  # 0.25 kg
milk-1.5     # 1.5 kg
yogurt-1     # 1 kg

解决方案 3

对于以千克为单位的产品,销售金额值将与销售数量值相同。

对于按件销售的产品,我们需要从描述中提取 kg 信息,并乘以销售额。

我们可以使用where函数有条件地更新这些值。可以通过使用st访问器下的split函数提取重量信息。

(图片由作者提供)

我不想将代码显示为文本,因为在纯文本中它看起来有点复杂。

where功能接受一个条件或一组条件。然后,我们可以为符合和不符合条件的行分配单独的值。

这个条件是在第一个where函数里面指定的。符合条件的行保持不变。因此,没有片段单元的行将保持不变。

第二行和第三行指定如何更新不符合条件的行。第二行从产品描述中提取重量信息。在第三行,这个值乘以销售数量。

让我们检查一些结果。

grocery.tail()

(图片由作者提供)

“黄油-0.25”重 0.25 公斤。在最后一行,销售数量是 36,所以销售额需要是 0.25 * 36,等于 9。

Pandas 是一个非常棒的数据分析和处理库。它提供了许多功能,简化和加快甚至复杂的任务。

如果你想在我发表新文章时收到电子邮件,别忘了订阅。

你可以成为 媒介会员 解锁我的全部写作权限,外加其余媒介。如果您使用以下链接,我将收取您的一部分会员费,无需您支付额外费用。

https://sonery.medium.com/membership

感谢您的阅读。如果您有任何反馈,请告诉我。

您应该了解的 3 种数据架构组件:应用程序、仓库和湖泊

原文:https://towardsdatascience.com/3-types-of-data-architecture-components-you-should-know-about-applications-warehouses-and-lakes-9e399c744ebb

有什么区别,为什么重要?

彼得·德·格兰迪在 Unsplash 上拍摄的照片

当我开始涉足分析领域时,数据架构非常令人生畏。这些术语对我来说是陌生的,人们会抛出一些术语,比如“ETL”和“数据湖”,我会点头附和,对他们谈论的内容只有模糊的感觉,然后把它放在“太难”的框中。

今天,我想用简单的术语描述数据架构的 3 个部分;应用程序、数据仓库和数据湖。我将重点讲述作为一个业务人员你需要知道的东西(而不是分析),为了保持实用性,我将使用一个我们大多数人可能至少每周都会做的例子,用信用卡买东西。

应用数据库

应用程序是生成数据的地方。

假设我每周都去乐购购物。当我交出我的卡进行支付时,卡应用程序将记录我在 4 月 19 日下午 5.05 支付了乐购 45.50 英镑(有几个中间步骤,但对于本文来说,这并不重要)。但是卡应用程序只生成和保存关于卡的数据,没有关于你是否持有抵押贷款、你的地址、你的营销偏好等信息。现在,假设您想了解客户每月的交易总数,除以客户是否还有抵押贷款。仅仅使用卡应用数据是不可能的,这就是为什么我们需要一个数据仓库。

数据仓库

数据仓库是事实的单一版本。不同的应用程序数据被放在一起并重新格式化,以便来自不同应用程序的数据以相同的方式定义和构造。

继续我的 Tesco 示例,来自卡应用程序的交易数据被传输到数据仓库。来自抵押贷款应用程序的数据也被传输到数据仓库,以查看哪些客户持有抵押贷款以及他们的未偿余额。我们也从第三方获得数据;每个月我们都会收到一份来自信用机构的报告,上面有每个客户的信用评分。数据移动的频率取决于数据的类型。客户的信用评分每月才可获得,而信用卡交易数据每分钟都在发生。这就是数据架构师的用武之地——定义移动数据的最佳频率。

作者图片

现在,将不同的来源汇集在一起,我们可以对客户每月进行的交易数量进行分析,按客户是否持有抵押贷款进行划分。

数据仓库保存一定时间的历史数据(我们通常保存 2-3 年),这就是数据湖的由来。

数据湖

数据湖基本上是一个巨大的停车场。数据湖主要用于需要访问数据的机会减少的旧数据。

回到我的例子,你可以想象英国每天发生的卡交易数量(数百万!).将这些数据长时间保存在数据仓库中是不现实的,因为这样会降低速度,而且保存这些数据的成本会很高。在固定时间后,卡交易数据将从数据仓库转移到数据湖。它仍然可以访问,但是不在分析师日常使用的表中。

作者图片

作为一名业务人员或产品负责人,我需要了解多少?

实际情况是,不多,但有几个“注意”区域会影响完成工作的可行性或完成请求的时间长度。

如果我们需要的数据不在数据仓库或数据湖中,数据和分析团队将需要与应用程序所有者合作,建立将数据传输到数据仓库的流程。这可能需要时间,并且可能涉及数据共享协议。

如果数据很旧并且在数据湖中,那么数据是可用的,但是可能需要分析师多花一点时间来提取,所以您可能希望在项目计划中留出多一点时间。

在本文中,我们没有考虑数据是存储在物理服务器上还是存储在云中的区别——但那是以后的事情了!

感谢您的阅读——请务必让我知道您的任何反馈。

参考资料:

Inmon,W.H. (2019) 数据架构:数据科学家入门。第二版。加利福尼亚州圣地亚哥:爱思唯尔。


我喜欢为商业用户写关于数据科学的文章,我热衷于使用数据来提供切实的商业利益。

你可以在 LinkedIn 上与我联系,并在 Medium 上关注我,了解我的最新文章。

Python 中你必须知道的 3 种数据清理类型

原文:https://towardsdatascience.com/3-types-of-data-cleaning-you-must-know-in-python-1ab6986a8b1d

计算机编程语言

数据清洗是数据分析中枯燥却又至关重要的一步

pix abay 拍摄的照片

数据清理是最耗时的任务之一!

我必须承认,真实世界的数据总是混乱的,很少是干净的。它包含不正确或缩写的列名、缺失的数据、不正确的数据类型、单个列中的信息过多等等。

在处理数据之前解决这些问题非常重要。最终,干净的数据总是能提高生产力,让你创造最好的,准确的洞察力。

因此,我列出了在使用 Python 处理数据时必须知道的 3 种类型的数据清理。

为了举例,我使用的是由 Pavlo Fesenko 创建的 Titanic 数据集的扩展版本,该数据集可以根据 CC 许可免费获得。

泰坦尼克号数据集 |作者图片

它是一个简单的数据集,有 1309 行和 21 列。我在下面展示了大量关于如何从这些数据中获得最佳收益的例子。

我们开始吧..🚀

首先,导入 pandas 并在 pandas DataFrame 中读取这个 csv 文件。使用.info()方法获得关于数据集大小、列及其各自数据类型的完整概述是一个很好的实践。

df = pd.read_csv("Complete_Titanic_Extended_Dataset.csv")
df.info()

df.info()获得数据集|按作者分类的图像的概述

让我们从最简单的清洁步骤开始,这可能会节省一些内存和时间,以及你继续进行处理。

移除未使用和不相关的列

您可以注意到,该数据集包含 21 列,您很少会将它们全部用于数据分析任务。因此,请仅选择所需的列。

举个例子,假设你不需要列PassengerIdSibSpParchWikiIdName_wikiAge_wiki

您需要做的就是创建这些列名的列表,并在如下所示的**df.drop()**函数中使用它。

**columns_to_drop = ['PassengerId', 'SibSp', 
                   'Parch', 'WikiId', 
                   'Name_wiki', 'Age_wiki']****df.drop(columns_to_drop, inplace=True, axis=1)**
df.head()

仅保留相关列|作者图片

当您使用.info()方法中的参数**memory_usage = "deep"**检查内存消耗时,您会注意到这个新创建的数据集只消耗了 834 KB,而原始数据帧消耗了 1000 KB。

这些数字在这里可能看起来很小,但在处理大数据集时会非常大。

所以删除不相关的列节省了 17%的内存!!

使用方法.drop()删除列的一个小缺点是,当您使用inplace = True时,它会改变原始数据帧。如果您仍然对原始数据帧感兴趣,您可以将df.drop()输出(不替换)赋给另一个变量,如下所示。

df1 = df.drop(columns_to_drop, axis=1)

或者,当您希望删除大量的列而只保留 4–5 列时,可能会出现这种情况。在这种情况下,不要使用df.drop(),而应该使用具有选定列数的df.copy()

例如,如果您想只使用数据集中的姓名、性别、年龄和幸存列,您可以使用如下所示的df.copy()对原始数据集进行子集化。

**df1 = df[["Name","Age","Sex","Survived"]].copy()**

使用列列表的子集数据集|按作者分类的图像

根据您的任务的实际需求,您可以使用上述任何一种方法来只选择相关的列。

在上图中,您可能会注意到,Age 和 Survived 列中的一些值丢失了。在继续之前需要解决这个问题。

处理缺失值或 nan

在几乎所有的数据集中,你需要处理丢失的值,这是数据清理的棘手部分之一。如果你想利用这些数据进行机器学习,你应该知道,大多数模型不接受缺失数据。

但是如何找到缺失的数据呢??

有多种方法可以找出数据集中的哪一节、哪一列缺少值。下面是四种常用于查找缺失数据的技术。

的方法。信息()

这是了解任何列中是否有缺失值的简单方法之一。当您使用df.info()时,您可以看到如下数据框df 的快速概览。

df.info()获取作者的 DataFrame | Image 概览

上面红框中显示的列名是多个值缺失的地方。理想情况下,该数据集中的每一列都应该包含 1309 个值,但是该输出显示大多数列包含小于 1309 的值。

您还可以可视化这些缺失的值。

缺失数据的热图

这是可视化缺失数据的常用方法之一。您可以通过将数据编码为布尔值(即10)来创建数据的热图,并且您可以使用熊猫函数.isna()来创建热图。

熊猫里的.isna()是什么??

方法isna()返回一个 DataFrame 对象,对于NaN,所有的值都被替换为布尔值 True,否则为 False。

你所需要做的就是输入一行代码,如下所示。

import seaborn as sns
**sns.heatmap(df.isna())**

缺失值热图|作者图片

上图中的 X 轴显示所有的列名,而 Y 轴代表索引号或行号。右侧的图例告诉您用于表示缺失数据的布尔值。

这有助于您了解数据在特定列的哪个部分或哪个索引号之间丢失。

好吧,如果列名不容易阅读,你可以创建它的转置版本,如下所示。

**sns.heatmap(df.isna().transpose())**

缺失值热图|作者图片

当要素或列的数量较少时,此类热图非常有用。如果有大量的功能,您可以始终对其进行子集化。

但是,请记住,如果数据集很大,可视化需要时间来创建。

尽管热图可以让您了解丢失数据的位置,但它不会告诉您丢失数据的数量。你可以用下一种方法得到它。

缺失数据占总数据的百分比

没有直接的方法可以得到它,但是你能使用的就是.isna()方法和下面的一段代码。

import numpy as np
print("Amount of missing values in - ")
for column in df.columns:
    percentage_missing = **np.mean(df[column].isna())**
    print(f'{column} : {round(percentage_missing*100)}%')

熊猫数据框|作者图片中缺失值的百分比

通过这种方式,您可以看到各个列中缺少多少百分比值。这在处理这些缺失值时会很有用。

我找到了丢失的数据,但是接下来呢??

没有处理缺失数据的标准方法。唯一的方法是查看单个列、其中缺失值的数量以及该列在未来的重要性。

根据以上观察,您可以使用以下 3 种方法中的任何一种来处理缺失数据。

  1. 删除记录 —当特定列缺少值或**NaN**时,删除索引处的整个记录。请注意,如果提到的列有大量缺失值,这种技术可以大大减少数据集中的记录数量。
  2. 删除专栏或功能 —这需要对特定的专栏进行深入研究,以了解其在未来的重要性。只有当您确信该特征不提供任何有用的信息时,才能这样做,例如,该数据集中的PassengerId特征。
  3. 估算缺失数据—在这种技术中,您可以用同一列的平均值、中值或众数替换缺失值或NaN

所有这些处理缺失数据的方法都是一个很好的讨论主题,我将在下一篇文章中介绍。

除了缺失数据之外,数据的另一个常见问题是数据类型不正确,需要解决这个问题才能获得高质量的数据。

更正数据类型

在使用不同的 Python 库时,您会注意到需要特定的数据类型来完成特定的转换。因此,每一列的数据类型都应该是正确的,适合于将来的使用。

当您在 pandas 中使用read_csv或任何其他read_函数将数据放入 DataFrame 时,pandas 将通过观察存储在其中的值来猜测每一列的数据类型。

除了少数几列,这个猜测几乎对所有的列都是正确的。并且您需要手动更正这些列的数据类型。

例如,在 Titanic dataset 中,您可以使用下面的**.info()**来查看列数据类型。

熊猫数据框|作者图片中的数据类型不正确

在上面的输出中,列 Age 和 Survived 的数据类型为float64,但是 Age 应该始终是一个整数,而 Survived 应该只有两种类型的值——Yes 或 No。

为了更好地理解它,让我们看看这些列中随机的 5 个值。

df[["Name","Sex","Survived","Age"]].sample(5)

示例 5 行|作者图片

除了缺少的值之外,幸存的列有两个值— 0.0 & 1.0 —理想情况下,这两个值应该分别是01的布尔值No & Yes。另外,“年龄”列包含十进制格式的值。

在继续之前,您可以使用正确的列类型来解决此问题。根据您的 pandas 版本,您可能需要在更正数据类型之前处理丢失的值。

除了上面的数据清理步骤,根据您的使用情况,您可能还需要下面的一些数据清理方法。

  1. 替换列中的值 —有时数据集中的列包含 True-False、Yes-No 等值,这些值可以很容易地替换为1 & 0以使数据集可用于机器学习应用程序。
  2. 去除异常值 —异常值是与其他观察值显著不同的数据点。然而,丢弃离群值并不总是一个好主意。需要仔细评估这些显著不同的数据点。
  3. 删除重复项 —当记录中所有列的所有值都相同时,可以认为数据是重复的。熊猫数据框方法**.drop_duplicates()**对于删除重复非常方便。

仅此而已!

我希望这篇文章对你有用,让你耳目一新。数据清理是最耗时的任务之一,通常需要创造性的方法来处理不同类型的数据问题。

如果你喜欢阅读这样令人惊叹的文章,请订阅 我的邮件列表

作为一个免费用户,你只能阅读 3 个故事,但作为一个媒体成员,你可以访问媒体上的所有内容。所以, 加入 Medium 使用我下面的推荐链接,它也将支持我作为一个作家,因为 Medium 与我分享你的一小部分费用。✅

https://medium.com/@17.rsuraj/membership

感谢您的阅读!

Python 中处理缺失值的 3 种终极方法

原文:https://towardsdatascience.com/3-ultimate-ways-to-deal-with-missing-values-in-python-ac5a17c53787

数据科学

在插补和删除数据之间做出明智的选择

Unsplash 上由阿尼鲁德拍摄的照片

缺失数据是最常见的数据问题之一!

现实世界中的数据集通常包含丢失的数据,这可能是由于数据损坏或数据不可用造成的。然而,为了进一步处理数据以获得准确和可行的见解,您应该处理缺失值。

如果你想将这些数据用于机器学习目的,那么你必须知道,大多数机器学习模型不接受缺失数据。因此,学习处理缺失数据的不同方法是很重要的。

在这里,我列出了 3 种处理缺失值的经典方法,当你遇到缺失数据时可以随时使用。

在我的上一篇文章—Python 中你必须知道的 3 种数据清理类型 —我讨论了识别丢失数据的方法。现在,让我们看看下面三种处理缺失数据的方法。

与上一篇文章类似,我使用的是由 Pavlo Fesenko 创建的 Titanic 数据集的扩展版本,该数据集可以在 CC 许可下免费获得。

让我们将数据集读入 pandas DataFrame,并快速浏览一下,以了解其中的列和缺失数据。

import pandas as pd
**df = pd.read_csv("Complete_Titanic_Extended_Dataset.csv")
df.info()**

作者提供的数据帧图像的简明摘要

这是一个跨 21 列有 1309 条记录的数据集,这意味着理想情况下每列应该有 1309 个值。

但是,您可以在上图中看到,红框内标记的列包含的记录少于 1309 条,即它们有一个或多个缺失值。

在随后的章节中,我解释了大量的例子来处理这些缺失的值。

在开始处理缺失值之前,我必须承认,没有最好的方法来处理这些值。您所能做的就是仔细查看每个缺少值的列,并理解该列对于将来使用这些数据的重要性。

在处理缺失数据时,可以使用两种主要的方法——数据的 插补剔除 。哪种方法用于哪一列完全取决于您对数据的研究和理解。

让我们从最简单的方法开始——数据的 去除 。当数据在随机位置丢失时,可以从数据帧中删除相关数据。然而,删除数据可能不是好的解决方案,如果它留给您的'数据不足以获得可靠的分析结果。

您可以使用以下两种方法从数据集中移除数据。

放下唱片

您可以使用 pandas DataFrame 方法[**.dropna()**](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.dropna.html)删除包含至少一个缺失值的行或记录。

让我们删除所有包含缺失值的行,如下所示。

df_records_dropped = **df.dropna(axis=0, how='any')** df_records_dropped.info()

在上面的代码中,axis=0显示 DataFrame 中的记录或行,而how = ‘any’ 显示删除其中任何一列有缺失值的所有行。

熊猫 dropna()删除记录|作者图片

当您检查这个新数据帧df_records_dropped的大小时,您会注意到——它包含零行。意思是,你丢失了所有数据。关于丢弃记录,这是需要记住的重要一点。

删除记录会大大减少您的数据!!🚩

为了解决这个问题,让我们使用how = ‘all’只删除那些包含所有列中缺失值的记录。

df_records_dropped = **df.dropna(axis=0, how='all')** df_records_dropped.info()

熊猫 dropna()删除行|作者图片

现在,这看起来像是原始数据帧的副本,即没有删除任何记录。

因此,使用方法dropna()中的另一个选项子集,只删除那些在特定列中缺少值的记录。

执行此操作时,请注意要删除的行数。在我所有的研究中,我将这个数字限制在数据集中所有行的 1%。因此,在这个数据集中,只有当被删除的行数少于 13 时,我才会删除该记录。

因此,让我们删除列 Fare、Embarked、WikiId、Name_wiki、Age_wiki、homeland、Boarded、Destination、Class 缺少值的行,如下所示。

columns_with_na = ['Fare', 'Embarked', 'WikiId',
                   'Name_wiki', 'Age_wiki', 'Hometown',
                   'Boarded', 'Destination', 'Class']
df_records_dropped = **df.dropna(axis=0, subset = columns_with_na)**
df_records_dropped.info()

从所选列中删除缺少的值|按作者排序的图像

通过这种方式,您可以删除上述列中缺少值的所有行。您可以注意到,除了用红色圈出的列之外,所有列现在都有相同数量的记录。

类似地,您可以考虑从包含大量缺失值的数据集中删除一列。然而,为此你需要理解这个特性对未来可用性的重要性。

删除列或特征

上面的图片显示,大部分的价值仍然是失踪的列体,救生艇,船舱。

为了理解这个特性的重要性,让我们看看这些列中的数据是什么样子的。

condition = (df_records_dropped.Cabin.isna()
             & df_records_dropped.Lifeboat.isna()
             & df_records_dropped.Body.isna())
df1 = **df_records_dropped[~condition]**
df1[["PassengerId","Name","Ticket","Cabin","Lifeboat","Body"]]

查看列|作者图片中的非缺失值

上面的代码显示了所有 696 行,其中这三列中至少有一列有一个**NaN**。由于行数巨大,删除这些记录将会使数据集减半。

此外,当您检查这些值时,例如,机舱中的**C85**、救生艇中的**14?**和身体中的**32MB**,您会看到这些列没有提供任何有用的信息。因此,您可以从数据集中删除这三列。

**columns = ['Cabin','Lifeboat','Body']**
df_columns_dropped = **df_records_dropped.drop(columns, axis=1)**
df_columns_dropped.info()

熊猫。DataFrame.drop 到 drop 列|按作者分类的图像

现在,您得到了一个只有 17 列的数据集,所有记录都具有相同数量的非缺失值,除了列幸存年龄

当理解一个列在有数值时的重要性时,您可以使用其他探索性的方法,例如不同列之间的关系。这将让您知道缺少值的列是否会影响其他功能。

最后,仅当您确信—
1 时,才使用上述数据删除方法。一个专栏或专题不会提供任何有价值的信息
2。删除记录不会导致质量结果的记录非常少

否则,使用另一种方法处理数据— 插补——您可以用其他值替换数据集中缺失的值。

估算缺失数据

您可以随时填充缺失的值,而不是删除记录或列,Python 提供了灵活的工具来完成这项工作。

最简单的方法是熊猫。DataFrame.fillna() 使您能够用特定值或使用下面列出的两种策略之一填充NaNs

  1. **ffill**:用同一列的前一个或最后一个非空值替换 NaN
  2. **bfill**:用同一列中下一个非空值替换 NaN。

此外,方法fillna()不追加原始数据帧,除非您提到**inplace = True**

让我们来看看这些不同的fillna策略在起作用。为了更好地理解fillna策略,我只提取了数据集的一小部分。

columns = ['Name', 'Survived', 'Age', 'Sex']
df1 = **df_columns_dropped[columns].sample(10, random_state=7)**
df1

作者随机选择数据帧|图像中的记录

您可以看到这个子集对于数字列年龄幸存几乎没有丢失值。

让我们首先使用ffill策略用前面或最后的非空值填充所有的NaNs

df2 = **df1.fillna(method='ffill')**
df2

将 NaNs 替换为熊猫数据帧|作者图片中的前置值

在上图中,蓝色圆圈中的值与之前的值相同,因为您用ffill策略替换了它们。

您可以注意到,在开始的几个**NaNs**幸存的列没有被填充,因为它们没有任何前面的非空值。你可以对这些NaNs使用回填策略,如下所示。

df3 = **df2.fillna(method='bfill')**
df3

将 NaN 替换为熊猫数据帧|作者图片中的下一个值

这样,你需要使用ffillbfill的组合来填充所有缺失的值。

或者,您可以用固定值代替NaN,如下所示。

df4 = **df1.fillna(100)**
df4

用固定值替换所有缺失值|按作者排序的图像

这里你把所有的NaNs都换成了 100。简单!

但是等等,这是 sense❓吗

幸存的列只需要两个值中的一个,即 0.0 和 1.0,因此 100.0 在此列中被错误地替换。

Pandas 为您提供了用不同的值替换不同列中的NaNs的灵活性。你可以这样做—

**values = {"Survived": 1.0, "Age": 100}**
df5 = **df1.fillna(value=values)**
df5

将每列中的 NaNs 替换为不同的值|图片由作者提供

现在,结果看起来更一致了。✅

在数字列中用固定值替换NaNs时,可以考虑该列中所有非空值的平均值或中值。

这些是估算缺失值的基本方法,但是您也可以使用高级方法,如多元估算、最近邻估算。

由于删除记录或特征通常不是一个好的选择,因此了解不同的插补方法非常重要。因此,我将单独讲述高级插补方法的工作原理。

仅此而已!

我希望这篇文章对你有用并且实用。处理丢失的值总是一个讨论的话题,根据您正在处理的数据,您需要有创造性地填充 nan。

现在你可以直接在你的收件箱里得到我的所有文章— 在这里得到

有兴趣无限制地使用媒体吗???

加入 Medium 使用我下面的推荐链接,它也将支持我作为一名作家,因为 Medium 与我分享你的一小部分费用。✅

https://medium.com/@17.rsuraj/membership

感谢您的阅读!

在 SQL 中查找唯一记录的 3 种终极方法

原文:https://towardsdatascience.com/3-ultimate-ways-to-find-unique-records-in-sql-6ddf8ae567b0

数据科学

停止使用 DISTINCT!开始使用这些快速的替代方法来避免混淆!

路易斯·科尔特斯Unsplash 上拍摄

不使用 **DISTINCT** 关键字获取唯一记录!🏆

在您的数据分析项目中,每当您需要从数据库中提取唯一的记录时,一个简单的答案就是使用**DISTINCT**!!

毫无疑问,DISTINCT 是为返回唯一行而设计的,它做得很好。但是,它不会告诉您所使用的连接和过滤器是正确的还是不正确的,这实际上是重复的原因。

因此,我总结了 3 个最好的、安全的和省时的替代方法,它们在不同的 doe 下返回相同的输出,并且仍然保持代码整洁和易于维护。💯

你可以使用下面的索引跳到你最喜欢的部分。

**·** [**UNION()**](#d286) **·** [**INTERSECT()**](#5b09) **·** [**ROW_NUMBER()**](#3f9b) **·** [**GROUP BY**](#421a)

📍注意:我使用的是 SQLite DB 浏览器和自己创建的 Dummy_Employees ,你可以在我的 Github repo 上免费获得!

好了,我们开始吧…🚀

首先,让我向您展示数据是怎样的。

虚拟员工数据集|作者图片

这是一个简单的 10x4 数据集,是我在文章 Faker 中创建的:一个惊人且非常有用的 Python 库 📚

上图中以蓝色和红色突出显示的行在数据集中是重复的。

📚您可以使用这个 SQLite 数据库 来跟踪本文中的查询。

在我上一篇文章2022你应该知道的 5 个实用 SQL 查询中提到,在寻找唯一记录之前,你必须定义哪一列或者哪几列的组合构成了唯一行。

对于在单个列中查找唯一值,DISTINCT 总是更方便。但是,对于从数据集中检索唯一的行,这些替代方法可以保持代码的整洁和高效。

例如,让我们使用 DISTINCT 从数据集中获得雇员 id、雇员姓名部门的唯一组合。

SELECT **DISTINCT** employee_id,
                employee_name,
                department
FROM Dummy_employees

使用 DISTINCT | Image by Author 选择唯一值

正如预期的那样,它只返回属于employee _ id212的重复行的一个实例,最终得到 8 行。

现在,让我们看看如何在不专门使用 DISTINCT 的情况下获得完全相同的结果。

联合()

在 SQL 中,UNION是一个运算符,用于组合两个SELECT语句的结果。类似于对器械包的UNION操作。

此外,它还会删除结果数据集中多次出现的行,只保留每行的一次出现。✅

你所需要做的就是写两条完全相同的SELECT语句,并用操作符UNION将它们连接起来,如下所示。

SELECT employee_id,
       employee_name,
       department
FROM Dummy_employees**UNION**SELECT employee_id,
       employee_name,
       department
FROM Dummy_employees

不使用 DISTINCT | Image by Author 选择唯一的行

这显示了与 DISTINCT 相同的输出,只是记录的顺序不同。

现在,让我向您展示一下后端刚刚发生了什么。🛠️

UNION 如何在 SQL 中删除重复|按作者分类的图片

通过这种方式,UNION简单地连接两个单独的SELECT语句的输出,并且只保留重复行的一个实例。

选择唯一记录的另一个有趣的方法是使用另一个操作符— INTERSECT

相交()

与前面的操作符类似,INTERSECT也用于连接两个SELECT查询的结果,并且只返回那些在两个SELECT查询的输出中相同的记录。它与两个集合的交集相同。

INTERSECT还删除结果数据集中多次出现的行,只保留每行的一次出现。✅

你需要做的就是写两个完全相同的SELECT语句并用INTERSECT将它们连接起来,如下所示。

SELECT employee_id,
       employee_name,
       department
FROM Dummy_employees**INTERSECT**SELECT employee_id,
       employee_name,
       department
FROM Dummy_employees

不使用 DISTINCT | Image by Author 选择唯一的行

由于两个SELECT查询产生相同的输出,连接将产生 10 行数据。然后根据INTERSECT返回唯一行的固有属性,将只返回一次重复行,最终输出 8 行。

🚩注意:使用UNIONINTERSECT时,两个 SELECT 语句中的列数和顺序必须相同。

继续下一步,获取唯一的记录..

ROW_NUMBER()

在 SQL 中,ROW_NUMBER()是一个窗口函数,它将一个连续的整数分配给结果集分区内的每一行。

窗口函数:一个 SQL 函数,输入值取自SELECT语句结果集中的一行或多行的“窗口”。它使用OVER子句后跟PARTITION BYORDER BY子句来创建一个包含一行或多行的窗口。

因此,在每个分区中,第一行的行号为 1。✅

这是它的工作原理..

SELECT employee_id,
       employee_name,
       department,
       **ROW_NUMBER() OVER(PARTITION BY employee_name,
                                      department,
                                      employee_id) as row_count**
FROM Dummy_employees

ROW_NUMBER()在 SQL | Image 中的工作方式(按作者)

正如你所看到的,当 employee_nameAbdulStella 时,每个分区中有两行。因此行号 2 被分配给这些重复行中的每一行。

因此,要获得唯一记录,您需要选择行号为 1 的所有行,即上表中 row_count 的值为 1。

❓然而,这里有一个捕捉!!

不能在WHERE子句中使用窗口函数,因为在 SQL 查询执行中,WHERE子句是在计算窗口函数之前处理的。你可以在 Agnieszka 的这篇文章中阅读更多关于 SQL 查询执行顺序的内容。

最终,您需要创建一个临时表来存储上述查询的输出,并需要另一个SELECT语句来获得不同的记录。您可以使用WITH子句或CTE s(通用表表达式)来创建临时表。💯

让我们看看如何从数据集中获得雇员 id、雇员姓名部门的唯一组合。

**WITH temporary_employees** as
(
SELECT 
  employee_id,
  employee_name,
  department,
  **ROW_NUMBER() OVER(PARTITION BY employee_name,
                                 department,
                                 employee_id) as row_count**
FROM Dummy_employees
)SELECT *
FROM temporary_employees
**WHERE row_count = 1**

使用 SQL | Image by Author 中的 ROW_NUMBER()获取不同的记录

这样,您可以看到只有那些记录出现在具有**row_count = 1**的输出中

这里,生成最后一列— row_count 只是为了提供信息。即使不包括该列,查询仍然有效。

除了操作符和窗口函数,还有一种简单方便的方法来获得唯一的行— GROUP BY

分组依据

在 SQL 中,GROUP BY子句用于按一列或多列对行进行分组。经常与COUNT()MAX()MIN()SUM()AVG()等聚合函数一起使用,得到分组行的聚合计算。

但是,可以在没有任何聚合函数的情况下使用它来获得不同的或唯一的记录,如下所示,

SELECT employee_id,
       employee_name,
       department
FROM Dummy_employees
**GROUP BY employee_id,
         employee_name,
         department**

使用 GROUP BY | Image by Author 获取 SQL 中的唯一记录

简单地说,您需要在GROUP BY子句中提到所有的列名来获得唯一的记录。

几乎 90%的时候,我发现GROUP BY更方便,因为我总是想用集合函数做一些其他的计算。

仅此而已!

希望你很快看完这篇文章,觉得耳目一新,很有用。

我在过去的 3 年里一直使用 SQL,我发现这些替代方法非常省时,而且功能强大,尤其是在处理大型数据集的时候。此外,我发现其中一些问题是很好的面试问题。

对阅读介质上的无限故事感兴趣??

💡考虑 成为媒体会员访问媒体上无限的故事和每日有趣的媒体文摘。我会得到你的费用的一小部分,没有额外的费用给你。

💡不要忘记 注册我的电子邮件列表 来接收我文章的第一份拷贝。

感谢您的阅读!

让你成为下一级数据科学家的 3 项不被重视的技能

原文:https://towardsdatascience.com/3-underappreciated-skills-to-make-you-a-next-level-data-scientist-6b5236770651

超越标准课程,充分利用您的数据。

附身摄影Unsplash 上拍照

“不要去读历史博士,”我曾经被一个历史博士生告知。我没打算这么做,但我必须承认我觉得这个提示有点讽刺和有趣,尤其是因为它来自哪里。

我的一位老助教给了我这个建议,他是我大学第一年必须上的一门历史导论课的研究生导师。以他自嘲的方式,他只是想表达一个高级历史学位所授予的技能并不是当今就业市场所需要的。

尽管如此,至少对于历史专业的本科生来说,还是有一线希望的。同一个助教还告诉了我一个关于历史的独立的、积极的故事。他详细讲述了他在大学时有一个主修历史的朋友,结果获得了出色的口头和书面交流技能。大学毕业后,一位在科技行业工作的老同事偶然遇到了他,在看到他的技能组合后,给他提供了一个面向客户的顶级职位,这位历史系毕业生在这方面表现出色(我要补充的是,还赚了一大笔钱)。

这两个故事都说明了一个重要的观点:在就业市场上,如果你拥有一项雇主急需的技能,你就增加了被聘用的机会。通常,必要的技能可能有点非正统——比如历史专业的学生进入上述技术领域——但这正是它的需求所在。该领域的标准成员还没有掌握它,因此它是令人垂涎的。

数据科学是一个广阔且不断发展的领域,白天吸引新的信徒,晚上进一步催眠现有成员。然而,尽管它很受欢迎,但大多数进入数据科学角色的人往往表现出相同的标准技能:数据管理、统计和概率熟练程度、用户测试、基本数据分析和机器学习基础等。

虽然这些技能不可否认地重要,但如果你将它们与其他不太常见但对数据科学工作流程有益的技能结合起来,你对雇主的吸引力会越来越大。在这篇文章中,我将讨论三个不被重视的技能,你可以学会这些技能来为你的简历增加一点魅力,因为它会与所有其他技能竞争。

形象化

一般来说,数据科学的主要目标之一是从数据中收集有意义的见解,并随后将这些见解呈现给一些目标受众。虽然这通常是通过数据清理、分析和建模的标准管道来完成的,但是还有另一个相关的任务,许多人在这方面缺乏实际经验:数据可视化。

用加州大学伯克利分校著名信息可视化研究者 Marti Hearst 教授的话说,“视觉表示比文本更能快速有效地传达信息”[1]。想想普通人坐在沙发上看新闻。他们会想听一个关于充满数字、方程和复杂性的模型结果的长篇大论吗?

不,他们不会的。人们喜欢简单和漂亮的东西。幸运的是,可视化——如果做得好——有可能将数据简化成漂亮的摘要。如果你能掌握设计和实现的技巧,毫无疑问,你会在数据科学环境中吸引注意力。

这有两个部分:1) 理解什么是好的可视化和 2) 实际实现这些可视化

让我们从第一部分开始。要深入了解这些主题,您可以查看我的文章《提炼数据可视化的基本原则》第 1 部分【2】和第 2 部分【3】。在这里,我将只列出一些高水平的提示,让你开始:

  • 不要试图展示一切:对于一个数据集来说,没有完美的、无所不包的可视化。选择数据的 1-2 个方面来突出显示,并在此基础上设计可视化。
  • 保持简单:不要过度——你的工作是简化数据,而不是让它变得更复杂。
  • 选择明智的表示法:例如,不要使用一组离散的随机颜色来表示一个连续的量化值,如考试分数。选择易于观众理解的视觉表现。
  • 不要在数据上撒谎:如果我需要在这个问题上说服你,你最好远离数据科学。

好吧,但是你实际上是如何实现可视化的呢?假设你完全没有任何经验,根据我自己的经验,我建议你遵循以下的一般流程:

  1. Excel/Google Sheets :这些工具有一套固定的图表,你可以用自己获取的各种数据自动生成。这是一个探索可视化和学习基础知识的好方法,不需要太多的努力。
  2. Tableau【4】:Tableau 是一个非常有用的工具,被各地的从业者用来可视化他们的数据。虽然它有一个学习曲线,但它不需要任何编程知识,并允许您在一个方便的设置中探索相当广泛的可视化。
  3. Matplotlib/Seaborn: 如果你已经熟悉了 Python 编程,你可以直接跳到这一步。这些是相当容易使用的 Python 库,允许你用代码编写基本的可视化程序。
  4. Altair/Plotly/Vega-Lite [5,6,7] :事情变得有趣了。如果你真的想成为可视化研究专家,你需要自己想出引人注目的图形,而不是直接基于预先生成的图形。这些声明式编程库(Python 中的前两个,JavaScript 中的最后一个)提供了一组简洁的工具,这些工具比上面简单的库更难操作,但也提供了更多的自由度。
  5. D3【8】:最后,这将我们带到 D3:数据驱动文档——在可视化领域广为人知,是设计和实现数据可视化的黄金标准。D3 是一个 JavaScript 库,它受益于一个非常强大的特性:它可以直接操作网页的 DOM(文档对象模型),允许程序员几乎可以制作他们想要的任何东西,并轻松地将其部署到 web 上。这是这个列表中最难学的技能(也是我目前正在开发的阶段)。然而,作为回报,你将能够用你设计的可视化效果让人们大吃一惊。如需入门,请查阅其发明者十年前撰写的原始研究论文【9】。它最近在 VIS 上赢得了时间的考验奖,VIS 是世界上最重要的可视化学术会议。

如果你选择学习这项技能,前面还有很长的路要走。但作为回报,在追求数据科学卓越的过程中,你将获得巨大的回报。

不要害怕回到数据上

在过去的一年里,我花了一些时间在一个机器学习研究项目上,这个项目是由我的一个同事牵头的。与许多这样的项目一样,我们需要模型在训练数据上达到一定的性能阈值。

然而,无论我们如何努力,再多的参数调整或 SK-Learn 模型搜索都无法给出我们需要的数字。我们被迫面对一个令人沮丧的现实:我们的地面实况数据根本不够好,我们需要从头开始。

换句话说,我们的研究团队必须手动梳理许多许多行的训练数据,并重新评估我们分配的初始标签(在技术术语中,这被称为审计数据)。这是一个真正的痛苦,因为它给项目增加了近六个月的额外工作。然而,我们根本没有选择,因为该模型不会以任何其他方式改进。

虽然我选择了机器学习的特定子领域作为个人轶事,但这是一个贯穿整个数据科学的问题。无论你在做什么——构建模型、设计可视化或建立数据库— 数据的质量至关重要

这似乎是一个足够简单的陈述,尤其是当你想到“数据科学”这个名字的时候但是,当你被一个已经工作了数月(甚至数年)的复杂而重要的项目所束缚时,这是一个非常容易被忽视的事实。很难承认你必须重新开始。仅仅这样做本身就是一种技能——一种被低估的有价值的技能。

这就是生活。不管这意味着什么,解决方案并不总是“改进模型”。有时,再多花哨的 Python 模块或不连贯的统计操作也无法得到您需要的结果,您需要接受您的数据可能不充分或不准确。

是啊,糟透了。但至少这是对的。

非正统形式的数据

作为一名数据科学家,你能获得的最令人垂涎的技能之一是熟悉和舒适地处理非正统形式的数据。普通的数据科学学生学习操作和处理最常见的数据形式:数字表格。这通常会很好,因为无数的工作需要他们的工人的这种技能。

然而,很少有人知道如何使用大量的数据格式——如果你擅长其中一种,你可能会成为就业市场上的抢手货。以下是一个(非常不完整的)示例列表:

  • 文本数据:很大一部分有趣的人类数据是以文字的形式存在的。我所说的“人类数据”指的是人类产生的任何数据——想想推特、脸书、短信等等。随着数据科学作为解决人类现代问题的主要途径不断取得进展,理解人类如何思考、感受和交流(从技术角度)将变得至关重要。因此,学习处理文本数据将是一项非常有价值的技能。
  • 图像数据:大多数人——包括数据科学家——可能不太了解图像是如何被抽象障碍下的计算机编码的。关于像素和 RGB 值的东西吧?这是一种有点难处理的数据形式,因此如果你选择学习它,它会对你更有好处。
  • 地理空间数据:这个很有意思。与普通公众进行数据交流的最常见方法之一是通过地图(如果你不相信我,可以考虑最近的选举季)。然而,很少有人知道如何执行将数字数据转换成地图的转换。你可能是其中之一——首先,看看 Python 中的 GeoPandas 模块,这是一个与传统熊猫很好集成的工具。

世界上几乎所有的东西都可以被视为数据,因此体现了数据科学领域探索的潜在途径。因此,不幸的是,我们常常忽略了潜在的令人兴奋的研究领域,而偏爱一排排数字带来的舒适。

这是一个简单的供求关系。没有足够多的人知道如何处理大量的非正统数据——成为他们中的一员,你会有很高的需求。

总结和最终想法

随着数据科学越来越受欢迎,个体数据科学家学习目前未被重视的技能将变得越来越重要。通过掌握它们,你将从你的数据中获得最大的收益(更不用说你的简历了)。

以下是一份备忘单,供将来参考:

  1. 人们喜欢有意义的美好事物。擅长可视化
  2. 没有人喜欢蹩脚的解决方案。必要时回去修复数据。
  3. 数字不是一切。学会处理其他数据格式。

我祝你在数据科学的努力中好运。

我叫 Murtaza Ali,是华盛顿大学研究人机交互的博士生。我喜欢写关于教育、编程、生活以及偶尔的随想。

请考虑使用我下面的推荐链接注册成为正式的媒体会员。你一个月就能看无限的故事,你的会员费直接支持我和其他作家。

https://murtaza5152-ali.medium.com/?source=entity_driven_subscription-607fa603b7ce---------------------------------------

参考

[1]https://searchuserinterfaces.com/book/
【2】https://medium . com/digital-diplomacy/distillation-the-essential-principles-of-Data-visualization-part-1-5df 4302 e401a
【3】https://medium . com/mlearning-ai/distillation-the-essential-principles-of-of-Data-visualization-part-2-644 BD 1 b 01 a 05
【4】https://www.tableau.com/【T10

让你成为下一级熊猫用户的 3 个不被重视的技能

原文:https://towardsdatascience.com/3-underappreciated-skills-to-make-you-a-next-level-pandas-user-b173f1b15ada

一键编码、合并和连接:向有用的数据转换和时髦的数据组合问好。

法比奥Unsplash 上的照片

这是我的下一级系列的第三篇文章。一定要看看前两个: 3 个不被重视的技能让你成为下一级数据科学家 3 个不被重视的技能让你成为下一级 Python 程序员

众所周知,熊猫是一个很难学习的模块。这可能会令人困惑和不知所措——尤其是对新程序员来说。然而,如果你想成为一名数据科学家 ,这也是 非常重要的一点。

出于这个原因,甚至数据科学教育项目也开始转向比以前更强调学习熊猫的模式。当我第一次学习数据科学时(大约 4 年前),我在加州大学伯克利分校的课程使用了一个名为datascience [1]的内部模块,该模块建立在 Pandas 之上,但功能完全不同。

但是课程开始改变了。最近,加州大学圣地亚哥分校推出了一个模块,旨在为学生向成熟的熊猫过渡做准备——因此,他们称之为babypandas [2]。

个人和机构都开始意识到,理解熊猫是现代数据科学的必要条件,他们正在围绕这一前提形成自己的教育愿望。

如果你正在读这篇文章,很可能你就是其中之一。请允许我在路上帮助你。

让我们来看看 3 个被低估的技能,它们将帮助你成为下一级熊猫用户。

分类变量的一键编码

为了正确理解这项技能,我们需要快速回顾一下统计环境中不同类型的变量。变量的两个主要类型是定量定性(分类),它们可以进一步细分为以下几组:

  • 离散(定量):这是一个数值,但可以精确计数。例如,如果您的变量是一个城市的人口,它将是一个离散变量。为什么?很明显,这是一个可以进行各种算术计算的数字,但同时,说一个城市的人口是 786.5 人是没有意义的。它必须是一个精确的数字。
  • 连续(定量):这也是一个数值,但它是由测量的,因此永远无法精确确定。身高就是一个例子。虽然由于可用的工具,我们可能会测量到最接近的厘米或毫米,但理论上,我们可以通过极其精细的测量(微米、纳米、皮米等)达到我们想要的深度。
  • 序数(分类):这是一个定性变量——也就是说,它不是一个对其执行算术运算有意义的数字。这种变量可以取有限数量的有序类别内的任何值。例如,您可能有一个可变的“香料级别”,其潜在值为“温和”、“中等”或“热”
  • 名义上的(分类的):这类似于一个顺序变量,除了类别没有明确的层次结构。标称变量的一个常见例子是颜色。

关于上述定义的一个注意事项:序数和名义变量通常仍然可以是数字;区别在于对这些数字进行算术运算是没有意义的。例如,地理邮政编码是一个名义变量,而不是一个数量变量,因为计算总和或差值(或乘积、商等)是没有意义的。)的两个邮政编码。

既然我们已经回顾了上述内容,我们可以解决主要问题了:计算机喜欢定量数据,但我们可用的数据通常是定性的。特别是在构建预测模型的上下文中,我们需要一种方法来以对模型有意义的方式表示分类数据。这一点最好通过例子来看。

假设我们有一个包含三列的数据集:"Age""State""Income"。我们想建立一个模型,用一个人的居住状态和年龄来预测他们的收入。我们数据集的一个子集可能如下所示:

作者图片

在我们可以根据这些数据训练一个模型之前,我们需要对"State"列做一些事情。虽然它目前的格式对人类可读性很好,但机器学习模型将很难理解它,因为模型喜欢数字。

第一次尝试可能包括简单地将数字 1-6 分配给我们上面的六种不同的状态。虽然对于顺序变量来说这是一个好主意,但对于我们的名义变量来说,这并不奏效,因为它意味着数据中的排序并不存在。

名义变量最常见的转换技术被称为一键编码。一键编码是将具有不同类别值的一列转换为多列(每个不同类别值一列)的过程,并且每一行都有一个二进制整数来指示它是否适合该列[3]。

因此,我们将重新组织数据,使数据中出现的每个唯一状态都有列"is_state_California""is_state_Oregon"等等,而不是只有一个名为"State"的列。然后,"State"列最初具有值"California"的行将在"is_state_California"列中具有值1,在所有其他列中具有值0

现在重要的是:我们如何在熊猫身上实现这一点?完成了所有的概念性工作后,您会很高兴地了解到代码本身实际上相当简单:Pandas 有一个名为get_dummies的函数,它为我们完成了所有的一次性编码工作[4]。假设我们上面的数据帧被称为my_df,我们将执行以下操作:

pd.get_dummies(my_df, columns=["State"], prefix='is_state')

作者图片

现在你知道了!你的数据现在的格式更有利于训练机器学习模型。

将数据帧合并在一起

如果你已经在数据科学领域工作了一段时间,你会很清楚数据的初始形式总是丑陋的。一直都是。无一例外。如果你刚刚进入这个领域,这是一个你很快就会熟悉的现实。

因此,数据科学家的大部分工作涉及将来自不同位置的数据组合在一起,并清除缺失的值。组合数据的最重要的方法之一——不幸的是也是最复杂的方法之一——是通过合并

原则上,合并背后的想法实际上并不坏:它只是提供了一种方式来组合来自两个不同数据框架的数据,这两个数据框架具有不同的信息,但至少有一列具有匹配的值。然而,实现可能会变得混乱,因为有许多不同类型的合并(也称为联接)。

一如既往,让我们看一个例子。让我们从上面类似的数据帧开始,除了这次它也有名字,叫做left_df(你马上就会明白为什么):

作者图片

我们还有一个名为right_df的第二个数据框架,它包含不同人的大学学位的附加信息,其中一些人与left_df中的人相同:

作者图片

我们对添加一个人的学位作为我们模型的特征感兴趣,所以我们决定将这两个数据框架合并在一起。当我们合并时,我们需要指定一些不同的东西:

  • 左侧数据帧
  • 正确的数据帧
  • 我们要合并的列
  • 我们需要什么类型的联接:内联接、左联接、右联接还是外联接

上面的最后一个规范是令人困惑的地方,所以让我们详细地看一下它们。

一个内部连接将两个数据帧合并在一起,这样只有在两个数据帧中都匹配的行才会出现在输出数据帧中。例如,对于上面的两个数据帧,如下所示:

left_df.merge(right_df, on='Name', how='inner')

作者图片

只有艾丽夏、阿迪提和塔蒂亚娜出现在两个数据帧中,因此,当通过内部连接合并时,只有他们的行是输出的一部分。我们还可以看到现在出现了"Degree"列,这说明了我们最初合并的原因。

下图直观地描绘了内部联接。左边的圆圈可以看作是left_df,右边的圆圈可以看作是right_df

内部联接。图片作者。

一个左连接包括左侧数据帧中的所有行,即使它们在右侧数据帧中没有匹配。对于那些没有出现在正确数据帧中的数据(因此在新列中没有值,在本例中是"Degree"),Pandas 填充一个空值。在本文的后面,我们将看到如何处理这样的值。

重要的是,这种类型的合并不包括右边数据帧中在左边没有匹配的值。让我们看一下我们的例子:

left_df.merge(right_df, on='Name', how='left')

作者图片

我们可以看到所有来自left_df的人都在场,即使他们在right_df没有匹配。另一方面,只在right_df中的 Ariel 和 Juan 不在输出数据帧中。

以下是左连接的图形描述:

左接合。图片作者。

右连接与左连接几乎完全相同,除了这次它包括右数据帧的所有值,而不是左数据帧的所有值,同样用空值填充不匹配:

left_df.merge(right_df, on='Name', how='right')

作者图片

这次是 Ted、Aaron、Lee、Abdul 和 Khadija 从输出中消失了,因为他们没有出现在right_df中。这是一个以图形方式显示的右连接:

右接合。图片作者。

最后一种合并是通过外部连接完成的。正如您可能已经猜到的,这种类型的连接包括两个数据帧中的所有行,用空值填充所有缺少的值。根据我们的数据,这看起来如下:

left_df.merge(right_df, on='Name', how='outer')

作者图片

我们可以看到 Pandas 是如何为 Ted、Aaron、Lee、Abdul 和 Khadija 的"Degree"值填充NaN的,因为它们没有出现在right_df中,因此没有该列的相应数据。类似地,Ariel 和 Juan 具有"State""Income"NaN值,因为它们在left_df中不存在。

以下是外部联接的图形描述:

外部联接。图片作者。

有了这些,你应该准备好融入野外了。

让我们继续我们最后一项不被重视的技能。

将数据帧连接在一起

在 merge 中迷宫般的可能性之后,您会很高兴地了解到连接相当简单。它还涉及组合两个数据帧,除了不是基于一个公共标签连接列,它更像是将两个数据帧堆叠在一起。此外,该操作还可以同时在两个以上的数据帧上执行。

最基本的连接示例涉及两个列相同的数据帧[5]。例如,假设我们有以下两个数据帧,分别称为top_dfbottom_df:

top_df。图片作者。

底 _df。图片作者。

我们可以将它们连接起来,如下所示:

pd.concat([top_df, bottom_df])

作者图片

关于上述内容,有几个重要注意事项:

  • 与我们经常在 DataFrame 对象上直接调用的merge不同(例如top_df.merge(bottom_df),我们使用pd.concat调用concat
  • 我们要连接的数据帧是作为列表中的一个参数传入的,而不是两个(或更多)单独的参数。

我们还可以连接不完全匹配的数据帧。例如,假设我们向我们的bottom_df添加另一列:

作者图片

然后,相同的连接为我们提供了以下输出数据帧:

作者图片

它可以工作,但并不理想,因为我们最终需要对那些讨厌的空值做些什么,以及将浮点数转换回整数(见下一节)。

最后,串联也可以水平工作。为了看到这一点,我们将向我们的武器库中添加一个数据帧,称为more_df:

more_df。图片作者。

然后,我们得到以下结果:

pd.concat([top_df, more_df], axis=1)

图片作者。

附加参数axis=1告诉熊猫我们要横向组合(按列);如果我们省略这个参数,它默认为axis=0,垂直组合(按行)。

注意,水平连接不同于合并两个数据帧,因为它不选择公共列来将两个数据帧连接在一起;它基本上只是将两个不同的数据帧粘在一起,而不用担心公共标签的存在。

唯一需要解决的是那些讨厌的NaN值。

加成技能:填充替换

您可能已经注意到,当我们从不同的地方收集数据到一个位置时,我们经常会遇到令人讨厌的空值或输入错误的数据条目。让我们来看看如何解决这些问题。作为一个例子,我们将使用上面的一个数据帧,这次称它为faulty_df:

faulty_df。图片作者。

空值代表我们没有的数据;在许多情况下,我们希望填入这些值,这样我们就可以在不出错的情况下进行分析。填补缺失数据的方法有很多,但我们在本例中只选择一种简单的方法:使用平均值——在本例中是 17。

在熊猫身上实现这一点最简单的方法是通过fill_na功能:

faulty_df = faulty_df.fillna(17)
faulty_df

作者图片

然后,我们可以通过astype函数将这些浮点数转换回期望的类型——整数:

faulty_df['Age'] = faulty_df['Age'].astype('int')
faulty_df

作者图片

现在,您已经有了一个简单的方法来处理在合并和连接后可能会得到的一些不完整的数据帧条目。

总结和最终想法

作为一名数据科学家,舒适地收集、组织、清理和重组数据以满足您的分析需求是非常重要的。通过掌握以上技能,你将离理想更近一步。

以下是一份备忘单,供将来参考:

  1. 分类数据不符合 ML 模型。学习一键编码
  2. 你需要的数据通常是分散的。善于信息融合在一起。
  3. 相似的数据集应该放在一起。通过串联帮助他们团结起来。

祝你的数据处理工作好运。

想擅长 Python? 获取独家,免费获取我简单易懂的指南 。想在介质上无限阅读故事?用我下面的推荐链接注册!

https://murtaza5152-ali.medium.com/?source=entity_driven_subscription-607fa603b7ce---------------------------------------

我叫穆尔塔扎·阿里,是华盛顿大学研究人机交互的博士生。我喜欢写关于教育、编程、生活以及偶尔的随想。

参考

[1]【http://data8.org/datascience/】
【2】https://babypandas.readthedocs.io/en/latest/
【3】https://www.educative.io/blog/one-hot-encoding
【4】https://stack abuse . com/one-hot-encoding-in-python-with-pandas-and-scikit-learn/
【5】https://www.w3resource.com/pandas/concat.php

让你成为下一级 Python 程序员的 3 个不被重视的技能

原文:https://towardsdatascience.com/3-underappreciated-skills-to-make-you-a-next-level-python-programmer-a20de69b29f2

向图形、可视化和时髦的数据结构问好。

威胁者杨Unsplash 上拍照

您称自己为 Python 程序员,但是您可能没有意识到编程语言有趣的、公开的秘密。

帮你自己一个忙,从那里开始。打开你最喜欢的终端,启动 Python 解释器,进入如下:import this

按下回车键后,你会看到下面这首动人的诗。

“Python 的禅”,作者蒂姆·彼得斯

漂亮总比难看好。
显性比隐性好。简单比复杂好。
复杂总比复杂好。
扁平比嵌套好。
稀不如密。
可读性很重要。特例不足以特殊到违反规则。
虽然实用性胜过纯粹性。错误永远不会悄无声息地过去。
除非明确消音。
面对暧昧,拒绝猜测的诱惑。应该有一种——最好只有一种——显而易见的方法来做这件事。虽然这种方式一开始可能并不明显,除非你是荷兰人。
现在总比没有好。
虽然永远也不会比现在*好。如果实现很难解释,这是个坏主意。
如果实现起来容易解释,这也许是个好主意。名称空间是一个非常棒的想法——让我们多做一些吧!"

我将把对这一文学瑰宝的深入分析留到另一篇文章中,只强调一个要点: Python 被设计成一种简单、简洁、优雅的语言

尽管 Python 越来越受欢迎,但该语言的大多数新信徒倾向于展示相同的标准技能集:循环、定义函数、构建对象——您知道,通常的编程基础数组(双关语)。有些人甚至可能到处使用列表理解。

虽然这些技能不可否认地重要,但是把自己限制在这些技能上是一个明显的错误。为什么?它没有利用一个至关重要的事实:Python 的简单性允许程序员用相当简单的代码完成不可思议的任务,构建最终的工具和程序,这在其他语言中需要更多的麻烦。

为了实现这个目标,这里有三种 Python 技能可以考虑学习。

Python 的图形海龟库

Python 的 Turtle 库可能是整个语言中最被低估、使用最少的图形模块之一。人们痴迷于更高级的工具,如 PyGame 和 Tkinter,它们的学习曲线要陡峭得多。相比之下,Turtle 非常简单,以至于许多入门编程类都用它来向从未编写过代码的人介绍 Python。

本质上,Turtle 非常简单。你只需要有你的鼠标(“乌龟”),你给它提供基本的命令,告诉它向你想要的方向移动,画出一个特定的形状。随着绘图的深入,您可以强调边框并用颜色填充形状,就像在 Adobe Illustrator 等高级软件系统中一样。

这就是 Turtle 的全部,归根结底:使用代码来绘制和绘画。

为了说明它的简单性,下面是一段画了一个正方形的代码:

import turtle as t
t.forward(100)
t.right(90)
t.forward(100)
t.right(90)
t.forward(100)
t.right(90)
t.forward(100)
t.right(90)
t.done()

或者,更简洁地说:

import turtle as t
for _ in range(4):
    t.forward(100)
    t.right(90)
t.done()

作者图片

下面是代码的快速分解:

  • forward命令告诉乌龟对象向前移动 100 个像素。
  • right命令告诉乌龟对象向右旋转 90 度
  • done命令让 Python 知道我们已经完成了绘图,这使得包含绘图的弹出窗口不会自动关闭。

即使有了这个简单的例子,我们也已经可以开始看到 Turtle 的基本构件是如何扩展的,以制作更深入的程序。例如,一个正方形离各种各样的“棋盘”并不远,对于编写像 Connect-4 或 2048 这样的著名游戏很有用。只要稍微算一下,画几条线,就上路了。

因此,Turtle 的一个很大的优势是,它允许你仅用入门知识就能编写出有趣、漂亮的游戏和图形。换句话说,你不需要成为一个 JavaScript 专家,就能让人们对你的发明刮目相看。在我上过的第一堂编程课上,学生们在第一次看到 Python 几周后,就开始用 Turtle 制作复杂的、可玩的游戏。

如果你愿意付出一点努力,你也可以。

Altair 中的可视化

随着世界变得越来越以数据为中心,处理和分析数据的技术正走向所需技能的前沿。任何人(尤其是计算机程序员)都可以有效地利用数据科学的核心目标:展示来自数据的有意义的洞察力

最不复杂但最有效的方法之一是通过可视化。在 Python 编程语言中,两个最常见的可视化模块是 MatplotlibSeaborn

这样做有很好的理由:这两个模块在语法上很简单,因此很容易学习。这使得它们成为用于基本探索性数据分析的快速可视化任务的理想工具。例如,在 Seaborn 中生成折线图很简单:

import matplotlib.pyplot as plt
import seaborn as snssns.lineplot([1, 2, 3, 4], [1, 2, 3, 4])
plt.xlabel('X-Axis')
plt.ylabel('Y-Axis')
plt.title('An Exciting Line Chart')

作者图片

然而,它们的简单是有代价的。数据可视化的主要原则之一是表现力,粗略地衡量为数据中有多少相关信息被编码到可视化中。因为你可以用 Matplotlib 和 Seaborn 制作的大部分情节都是预先确定的,所以你的表现力相当有限。

进入牛郎星。Altair 构建在著名的 JavaScript 可视化库 Vega-Lite 之上,提供了用 Python 代码 [1]生成各种漂亮的可视化效果的能力。诚然,学习曲线比 Matplotlib 高了一步,但它仍然比学习 JavaScript 容易得多。

Altair 提供了一种声明性语法——虽然代码可能会因为更复杂的可视化而变得越来越混乱,但它的优势是它总是可以被分解成相同的构建块。例如,下面是如何从上面生成折线图:

import pandas as pd
import altair as altsource = pd.DataFrame({'X': [0, 1, 2, 3, 4], 'Y': [0, 1, 2, 3, 4]})
alt.Chart(source).mark_line().encode(
    x=alt.X('X', scale=alt.Scale(domain=[0, 4]), title='X-Axis'),
    y=alt.Y('Y', scale=alt.Scale(domain=[0, 4]), title='Y-Axis')
).properties(
    title='An Exciting Line Chart'
)

作者图片

Altair 的强大之处(即表现力)在于用户可以随意修改的大量自定义选项;我上面展示的只是很小的一部分。

这些年来,我个人多次使用 Altair 来设计和编程我脑海中想象的新颖的可视化效果。虽然当然仍有局限性,但这是 Matplotlib 和 Seaborn 的巨大进步。此外,如果你曾经感到困惑,牛郎星社区是令人难以置信的反应和帮助。

所以,下次你需要编写一个线图时,也许可以试试 Altair。

古怪的控制和数据结构

当然,虽然 Python 提供了与所有其他编程语言相同的标准循环和结构,但它也拥有许多独特的结构,既有趣又有用。我们来看两个有趣的。

For-Else 循环

与大多数语言不同,Python 允许将条件关键字elsefor循环结合使用。使用这种特殊的语法,您可以编写一个普通的循环,后跟一个else语句。Python 使用以下执行规则:当且仅当循环没有被 **break** 语句终止时,执行 **else** 语句。

通过示例,这一点更容易理解:

# No break, so we enter else statement
>>> for element in ['a', 'b', 'c']:
...     if element == 'x':
...             break
... else:
...     print("THERE WAS NO BREAK")
...
THERE WAS NO BREAK# Break, so we do not enter else statement
>>> for element in ['a', 'x', 'b', 'c']:
...     if element == 'x':
...             break
... else:
...     print("THERE WAS NO BREAK")
...
>>>

由于第一个代码片段从未脱离for循环,Python 知道进入else条件;同样,它知道在第二种情况下不要这样做。

for-else循环是一个相当特殊的用例,但是下一次当您想要执行某个由 iterable 的所有元素是否满足某个条件决定的动作时,它可能会很有帮助。

字典理解

大多数 Python 程序员都听说过列表理解【2】;在这里,我想讨论一下它们鲜为人知的表亲——词典理解。

字典 [3]无疑是 Python 最有用的特性之一,但是有时候定义它们会有点痛苦。输入字典理解。

例如,假设您有一个姓名列表,您想要创建一个字典,其中键是姓名本身,值是姓名的长度。以下是您传统的做法:

>>> names = ['Alice', 'Bo', 'Malika']
>>> traditional_dict = dict()
>>> for name in names:
...     traditional_dict[name] = len(name)
...
>>> traditional_dict
{'Alice': 5, 'Bo': 2, 'Malika': 6}

字典理解简化了代码:

>>> names = ['Alice', 'Bo', 'Malika']
>>> comprehension_dict = {name: len(name) for name in names}
>>> comprehension_dict
{'Alice': 5, 'Bo': 2, 'Malika': 6}

干净多了。

字典理解的工作方式类似于列表理解,有效地消除了简单用例中的for循环。

Python 被设计得简洁明了,因此它包含了大量旨在促进这一目标的数据和控制结构。循环和字典理解是我个人最喜欢的两个。

我建议你做一点挖掘来找到你自己的。

总结和最终想法

随着 Python 越来越受欢迎,对于个人程序员来说,学习目前未被重视的技能将变得越来越重要。通过掌握它们,你将从你的代码中获得最大的收益(更不用说你的简历了)。

以下是一份备忘单,供将来参考:

  1. 游戏和绘画不仅仅是有趣,它们还是一种受欢迎的产品。投入一些时间学习海龟
  2. 数据可视化是一项有价值的技能。用牛郎星变得伟大。
  3. 不要把自己局限在基础上。掌握新的数据和控制结构

祝你的 Pythonic 冒险之旅好运。

想擅长 Python? 获取独家,免费获取我简单易懂的指南在这里 。想在介质上无限阅读故事?用我下面的推荐链接注册!

https://murtaza5152-ali.medium.com/?source=entity_driven_subscription-607fa603b7ce---------------------------------------

我叫 Murtaza Ali,是华盛顿大学研究人机交互的博士生。我喜欢写关于教育、编程、生活以及偶尔的随想。

参考

[1]https://altair-viz.github.io/gallery/index.html
【2】https://towards data science . com/whats-in-a-list-comprehension-C5 d 36 b 62 f 5
【3】https://towards data science . com/whats-in-a-dictionary-87 F9 b 139 cc 03

用于时间序列预测的 3 个独特的 Python 包

原文:https://towardsdatascience.com/3-unique-python-packages-for-time-series-forecasting-2926a09aaf5b

您可以添加到您的武器库中的一些时间系列包

拉尔夫·哈特在 Unsplash 上拍摄的照片

时间序列预测是统计领域中的一种方法,用于分析具有时间成分的历史数据,并基于该数据创建预测。

时间序列预测方法的一些经典例子是移动平均、ARIMA 和指数平滑。这些方法已经使用了很长时间,现在仍然有用,因为用户很容易解释结果——尽管预测不太准确。

反过来,许多机器学习驱动的预测是通过牺牲一些可解释性和提高准确性来开发的,如预言家Kats

无论您需要经典方法还是机器学习驱动的模型,许多人都开发了 Python 包来访问所有这些方法。一些著名的包有 Statsmodelpmdarimasktime 。然而,预测模型不仅限于我上面列出的那些,因为许多伟大的软件包都值得考虑。

这就是为什么本文将介绍我的 3 个独特的用于时间序列预测的 Python 包。让我们开始吧。

1.统计预测

StatsForecast 是一个 Python 包,它提供了一组单变量时间序列预测模型。StatsForecast 的独特之处在于,该模型提供了快速训练,并针对高精度模型进行了优化。此外,该软件包提供了几个基准,我们可以在训练各种模型时使用。

让我们试用一下这个包,感受一下它。首先,我们需要安装 StatsForecast 包。

pip install statsforecast

出于演示目的,我将使用从 StatsForecast 生成的合成数据。使用下面的代码,我将获得每月记录的合成数据。

from statsforecast.utils import generate_seriessynthetic_panel = generate_series(n_series=1, freq = 'M')synthetic_panel.head()

作者图片

数据集包含一个日期特征(“ds”)和我们要预测的数字特征(“y”)。此外,根据 StatsForecast,该指数具有“唯一 id”指数,这将提高训练速度。

接下来,我会将数据集分成训练数据和测试数据。我将最后 6 次观察作为测试数据,其余的作为训练数据。

Y_train_df = synthetic_panel[:-6]
Y_test_df = synthetic_panel[-6:]

准备好数据集后,我们可以尝试开发我们的预测模型。第一步是导入我们想要使用的模型。在我们的例子中,我们将使用 AutoARIMA(带自动参数训练的 ARIMA 模型)和指数平滑(ETS)。

from statsforecast import StatsForecast
from statsforecast.models import AutoARIMA, ETS

接下来,我们将建立模型并向模型传递一些参数。我们要传递的参数是季节长度(使用 12,因为一年有 12 个月),以及 ets 的“ZMZ”模型,以便对模型进行优化调整。此外,我设置了 horizon 变量作为我们预测的长度。

season_length = 12horizon = len(Y_test_df)models = [
AutoARIMA(season_length=season_length),
ETS(season_length=season_length, model='ZMZ')
]model = StatsForecast(
df=Y_train_df,
models=models,
freq='M',
n_jobs=-1)

StatsForecast 的优点是可以在一行中直接测试各种模型。我们只需要决定我们想要使用什么样的预测模型,我们可以通过下面的代码轻松获得所有的预测。

%timeY_hat_df = model.forecast(horizon).reset_index()
Y_hat_df.head()

作者图片

StatsForecast 自诩训练时间快,从上图可以看出预测时间。我们的预测花了很短的时间。那么,我们的预测有多准确呢?让我们用时间图来看看。

fig, ax = plt.subplots(1, 1, figsize = (20, 7))Y_hat_df = Y_test_df.merge(Y_hat_df, how='left', on=['unique_id', 'ds'])plot_df = pd.concat([Y_train_df, Y_hat_df]).set_index('ds')
plot_df[['y', 'AutoARIMA', 'ETS']].plot(ax=ax, linewidth=2)ax.set_title('Forecast Synthetic Data', fontsize=22)
ax.set_ylabel('Number', fontsize=20)
ax.set_xlabel('Timestamp [t]', fontsize=20)
ax.legend(prop={'size': 15})
ax.grid()

作者图片

从上图可以看出,预测数据模式足够接近实际数据。这两种预测都会导致与实际情况重叠的预测。

你可以用 StatsForecast 尝试很多模型;建议你来访问这个页面

2.PyAF

PyAF 或 Python Automatic Forecasting 是一个开源的 Python 包,用于自动开发时间序列预测模型(单变量或外生数据)。该模型是在 Scikit-Learn 和 Pandas 的基础上构建的,因此可以期待熟悉的 API。该软件包还提供了各种模型,尽可能在几行中使用。

让我们用之前的数据集来试试 PyAF 包。首先,我们需要安装软件包。

pip install pyaf

接下来,我们可以使用以前的数据来开发我们的 PyAF 预测模型。让我们用下面的代码试试自动预测引擎。

horizon = len(Y_test_df)import pyaf.ForecastEngine as autof#set up the model engine
lEngine = autof.cForecastEngine()# get the best time series model for test prediction
lEngine.train(iInputDS = Y_train_df, iTime = 'ds', iSignal = 'y', iHorizon = horizon)

我们试着看一下预测数据。我们可以使用下面的代码来获取预测。

forecast_df= lEngine.forecast(Y_train_df, horizon)

预测结果将是我们当前和预测数据的数据框架。此外,每个预测结果都有如此多的信息,我们可以用来评估我们的模型。

作者图片

让我们只获取关键信息,并进行视觉比较。

forecast_df.plot.line('ds', ['y' , 'y_Forecast','y_Forecast_Lower_Bound', 'y_Forecast_Upper_Bound'], grid = True, figsize=(12, 8))

预测相当不错,如上图所示,预测数据和实际数据重叠。此外,上限和下限足够小,可以表示模型的可信度。我们可以通过使用外源数据来改进模型,你可以尝试使用下面的笔记本教程

3.神经营养细胞

NeuralProphet 是一个 Python 包,用于开发基于脸书预言家的时间序列模型,但具有神经网络架构。这个包基于 PyTorch,可以很容易地使用尽可能少的代码行。

让我们从安装包开始。

pip install neuralprophet

如果你想在 Jupyter 笔记本中实现交互式可视化,我们可以使用下面的代码来安装它。

pip install neuralprophet[live]

让我们从初始化模型开始。对于这个例子,我们使用与上一个相同的数据集。此外,为了使事情更容易,我将删除数据索引。

train = Y_train_df.reset_index(drop = True)
test = Y_test_df.reset_index(drop = True)

接下来,我们将启动神经先知模型。

from neuralprophet import NeuralProphet
m = NeuralProphet()

然后,我们将使用下面的代码来训练模型。

metrics = m.fit(train, freq='M', validation_df=Y_test_df, progress='plot')

作者图片

该模型将自动递归训练数据,并在默认纪元后停止(您可以设置您的纪元)。要查看最终的指标,我们可以使用下面的代码。

metrics.tail(1)

作者图片

我们还可以尝试使用该模型来直观地预测和比较当前的训练数据。

forecast = m.predict(train)
fig = m.plot(forecast)

从上面的图我们可以看出,预测和实际数据点比较接近。我们试着和测试数据对比一下。

forecast = m.predict(test)
m = m.highlight_nth_step_ahead_of_each_forecast(1)
fig = m.plot(forecast)

作者图片

我们可以在上面的图像中看到,预测与实际数据相当接近。仍然有一些误差可以通过进一步的预测模型开发来修正。

与 Prophet 类似,我们可以使用下面的代码获取 NeuralProphet 预测组件。

fig_param = m.plot_parameters()

作者图片

分解将显示我们的训练数据的趋势和季节性,这对我们的洞察力也是至关重要的。

撰写本文时,NeuralProphet 包仍处于测试阶段,因此可以期待该包的许多新开发,尤其是增加预测能力。要了解他们的发展时间表,您可以点击查看

结论

时间序列预测是一种基于历史时间数据(例如,天气或人数)预测未来值的方法。

许多 Python 包是为时间序列预测开发的,但我想在本文中展示一些更独特的包。它们是:

  1. 统计预测
  2. PyAF
  3. 神经营养细胞

希望有帮助!

访问我的 社交媒体进行更深入的交谈或有任何问题。

如果您不是作为中等会员订阅,请考虑通过 我的推荐 订阅。

数据科学家应该知道的 3 种独特工具

原文:https://towardsdatascience.com/3-unique-tools-data-scientists-should-know-7713d2da8a81

意见

如何将 DevOp 工具用于您的数据科学和机器学习操作

托尼·汉德在un splash【1】上拍摄的照片。

目录

  1. 介绍
  2. 为什么?
  3. 邮递员
  4. 大牧场主
  5. 詹金斯
  6. 摘要
  7. 参考

介绍

数据科学家的职位可以有很大的不同,无论是从 only 专注于 Jupyter 笔记本中的算法,还是成为利用数据科学模型的全栈软件工程师。在学校或在你的早期职业生涯中,可以预计你会更多地关注不同类型的算法及其适用的用例。随着你的职位越来越高,你会越来越熟悉机器学习操作和 DevOps 工具,我们将在本文中讨论。

谁为什么?

有一些更大的公司,如果你只在算法领域工作,实际上会更受欢迎,而且你永远不会接触某些工具。虽然还有其他规模较小的公司希望你成为全栈数据科学家,但不是从全栈软件工程师的角度,而是从能够剖析问题、找到数据、聚合数据、自动化数据收集、特征工程师、模型构建、部署以及监控和警报的角度。总而言之,不管是什么情况,了解和掌握数据科学的全部管道都是令人满足的。也就是说,这些工具不仅对所有级别的数据科学家和在面试中保持领先非常重要,而且对希望在工作中合作和完全自主的数据科学家也非常重要。

邮递员

Joanna Kosinska 在Unsplash【2】上的照片。

我们将讨论的第一个工具叫做Postman【3】,我称这个工具更独特,因为与其他更广为人知的工具相比,我看到的关于它和接下来两个工具的讨论和期望要少得多。

这个工具被描述为一个 API 平台。它可以用于各种用例,但由于我们希望专注于数据科学,我们可以强调您希望使用它的原因。

以下是您应该使用 Postman 作为数据科学家的原因:

  • 发送 API 请求
  • 测试您的 Python 任务
  • 确保您的新模型代码将在生产中工作,而不会扰乱生产
  • 检查 Python 任务是否返回预期结果
  • GitHub pull 请求的最后检查( PR )

数据科学家的邮差请求测试的一个例子是从 PR 测试您的生产管道代码变更。例如,如果您更新了某种类型的preprocess.py文件,并且您希望确保它在生产环境中能够正确工作,那么您可以发送 API 请求,并利用文件中包含的所有其他代码(比如特定的 Python 库导入)来检查您用新代码预处理的数据是否能够工作。

大牧场主

雅各布棉Unsplash【4】上拍照。

在 Postman 的基础上,你可以从这个工具中获益。它被描述为一个软件栈,用于与采用容器和交付 Kubernetes 作为服务进行协作。

以下是您应该使用 Rancher 作为数据科学家的原因:

  • 现在您已经使用了 Postman,您可以在 Rancher 中看到您的请求日志
  • 希望您的新代码更改不会返回错误,但是如果返回错误,您也可以在 Pod 日志中看到它们
  • 如果您有任何错误,您将能够通过错误消息来解决它们,而不会影响当前的生产过程

对于正在寻找更加自动化和简化的工作检查方式的数据科学家来说,这是一个非常好的工具。

詹金斯

帕特里克·托马索在Unsplash【6】上拍摄的照片。

第三个工具也将在这个更加面向 DevOps 和机器学习操作的过程中最后使用。这个工具,Jenkins【7】,被描述为一个自动化的开源服务器,在这个用例中,它允许数据科学家构建、测试和部署他们的模型更改或只是一般的模型。

一旦你用 Postman 和 Rancher 测试了你的改变,你的下一步可以是使用 Jenkins。

以下是您应该使用 Jenkins 作为数据科学家的原因:

  • 确保您可以部署 docker PROD 映像
  • 构建和测试变更
  • 这也可以在您将代码变更合并到 GitHub 之后自动发生

摘要

总之,这三个独特的工具对于数据科学家来说非常有帮助,可以确保和验证您的代码按照预期的方式工作。了解这一点也是有益的,这样你就可以更加自律。最后,它可以让你成为一个更有竞争力的申请人。

总而言之,这里有三个你应该知道的对数据科学家来说独特而有益的工具:

* Postman* Rancher* Jenkins

我希望你觉得我的文章既有趣又有用。如果您同意或不同意这些特定的工具,请随时在下面发表评论。为什么或为什么不?关于数据科学开发操作和机器学习操作(或 MLOps ),您认为还有哪些工具值得一提?这些当然可以进一步澄清,但我希望我能够为数据科学家提供一些更独特的工具、技能和平台。

我不属于这些公司中的任何一家。

请随时查看我的个人资料、 Matt Przybyla和其他文章,并通过以下链接订阅接收我的博客的电子邮件通知,或通过点击屏幕顶部的订阅图标 点击关注图标 的订阅图标,如果您有任何问题或意见,请在 LinkedIn 上联系我。

订阅链接:https://datascience2.medium.com/subscribe

引荐链接:https://datascience2.medium.com/membership

(如果你在 Medium 上注册会员,我会收到一笔佣金)

参考

[1]照片由托尼·汉德Unsplash 上拍摄,(2019)

[2]Joanna Kosinska 在 Unsplash 上拍摄的照片,(2018)

[3] 2022 邮差公司,邮差主页,(2022)

[4]照片由雅各布棉花Unsplash(2019)上拍摄

[5]牧场主,牧场主主页,(2022)

[6]帕特里克·托马索在 Unsplash 上拍摄的照片,(2018)

[7]詹金斯,詹金斯主页,(2022)

PySpark 中聚合数据的 3 种方法

原文:https://towardsdatascience.com/3-ways-to-aggregate-data-in-pyspark-72209197c90

编程 | 大数据 | PySpark

PySpark 用编码示例解释基本聚合。

照片由像素上的像素拍摄

建议的点播课程

我的一些读者联系我,要求提供点播课程,以了解关于使用 Python 的Apache Spark的更多信息。这是我推荐的 3 个很好的资源:

还不是中等会员?考虑与我的 推荐链接 签约,以获得 Medium 提供的一切服务,价格低至【5 美元一个月

介绍

Apache Spark 是一个数据处理引擎,在大型数据集上执行聚合的速度非常快。根据所执行的聚合类型,输出数据集通常会显示:

  • 较低的 基数 与原始数据集 →当对一组维度应用聚合时会出现这种情况。
  • 相同的 基数 与原始数据集 →当对记录窗口应用聚合时会发生这种情况。

在本教程中,我将分享使用 Python 在 PySpark 数据帧上执行聚合的三种方法,并解释何时根据目的使用每种方法是有意义的。

对于编码示例,我将使用虚构的数据集,包括按世界区域划分的500 万笔销售交易。如果你想继续下去,你可以从这个网站下载 CSV 文件。

原始数据集已被简化,如下表所示:

💔-ways-to-create-tables-with-apache-spark-32aed0f355ab>

在 PySpark 中聚合数据

在本节中,我将介绍在 PySpark 数据帧上工作时聚合数据的三种方法。

在下面的代码片段中,我将只使用SUM()函数,但是同样的推理和语法也适用于MEAN()AVG()MAX()MIN()COUNT()PIVOT()函数。

方法 1:使用 GroupBy( ) +函数

在 PySpark 数据帧上运行聚合的最简单方法是将groupBy()与聚合函数结合使用。

这种方法非常类似于使用 SQL GROUP BY子句,因为它通过一组维度有效地折叠输入数据集,从而产生粒度更低的输出数据集 ( 意味着记录更少)。

例如,如果选择的函数是sum(),语法应该是:

dataframe.groupBy(‘dimension_1’, 'dimension_2', ...).sum(‘metric_1’)

回到销售数据集,假设任务是计算:

  • Total Revenue (£M)Region组成
  • RegionItem Type组成的Total Revenue (£M)

在这种情况下,你可以写:

与 SQL 一样,groupBy()可用于在多个列上运行聚合。下面,找到由Region聚合的输出数据集:

输出 1

以下是由RegionItem Type聚合的输出数据集:

输出 2

何时使用/避免→ 当不需要格式化并且您只想在浏览数据集时运行快速聚合时,应该使用该方法。

相反,当您希望执行多重聚合或对聚合输出应用多个转换时,应该避免使用它。

例如,对聚合输出进行舍入并将列重命名为更整洁的名称非常麻烦,因为它需要两次单独的转换。

方法 2:使用 GroupBy( ) + AGG()

使用groupBy()执行聚合的另一种方式是将所需的函数包装在AGG()方法中。

至于METHOD 1,这个方法的行为也类似于 SQL GROUP BY子句,因为它生成一个数据集,其基数比它的源低。然而,正如您将验证的那样,它比METHOD 1要方便得多,因为它需要对聚合输出执行多次转换。

同样,假设选择的函数是SUM(),语法应该是:

*dataframe.groupBy('dimension_1', 'dimension_2', ...).agg(sum(“column_name”))*

例如,如果您希望在销售数据集上复制使用METHOD 1 所取得的成果,您可以编写以下代码:

这再次导致两个输出,一个按世界Region分组,另一个按RegionItem Type分组:

输出 1

输出 2

何时使用/避免→ 在生产中对 PySpark 数据帧执行聚合时,这种方法应该是您的首选解决方案。事实上,使用AGG()允许您在第 行中应用 多重连接转换,使您的代码更加易读和简洁。

另一方面,当您的目标是运行聚合时,您应该避免使用这种方法,保持源数据集的粒度不变(这意味着不按维度组折叠记录)。

的确,这个要求,导致了METHOD 3

方法 3:使用窗口函数

在 PySpark DataFrame 中聚合数据的最后一种方法是对行窗口应用函数。

这实际上相当于一个 SQL 窗口函数,因此以SUM()为例,语法将是:

*# WINDOW DEFINITION
Window.partitionBy(‘dimension_1’, 'dimension_2', ...)

# DF AGGREGATION USING WINDOW FUNCTION
dataframe.withColumn(‘new_column_name’, functions.sum(‘metric_1’)\
         .over(Window.partitionBy(‘dimension_1’)))*

和在 SQL 中一样,partitionBy子句用来代替groupBy()来对特定的行窗口应用SUM()函数。对于销售数据集,您可以编写:

正如您在下面的输出中看到的,这一次列Total Revenue (£M)保持不变,取而代之的是计算一个新列Total Revenue (£M) wndw,显示窗口中的总收入。

输出 1

输出 2

何时使用/避免→ 当您希望保留数据集的粒度时,应该首选此方法。实际上,窗口函数的一个主要优点是聚合应用于记录窗口,然后显示每一行,而不会折叠源数据集中的记录。

另一方面,当您处理非常大的数据集并希望执行聚合以获得更小、更易于管理的输出时,您应该避免使用这种方法。

*💔-nanodegrees-you-should-consider-to-advance-your-data-engineering-career-in-2021-baf597debc72>

结论

在本教程中,我讨论了在 Spark 数据帧上工作时,如何使用 Python 执行聚合,至少有三种基本方法。

从概念上讲,在 PySpark 中聚合数据与在 SQL 中使用GROUP BY子句或利用窗口函数聚合数据非常相似。

具有强大 SQL 背景的数据专业人员通常会发现向 PySpark 的过渡非常简单,尤其是在使用 pyspark.sql 模块时。

但是你呢?您是否尝试过使用 rollupcube 运行更高级的聚合?*

给我的读者一个提示

这篇文章包括附属链接,如果你购买的话,我可以免费(但实际上是打折)给你一点佣金。

消息来源

构建面板可视化仪表板的 3 种方式

原文:https://towardsdatascience.com/3-ways-to-build-a-panel-visualization-dashboard-6e14148f529d

hvPlot。互动,面板。bind 和 Param。依赖

索菲亚·杨马克·斯科夫·麦德森

您对用 Python 构建交互式仪表板感兴趣吗?不仅有不同的工具可以使用,甚至像 Panel 这样的单一工具也有多种方式来构建仪表板。您是否想知道为什么会有不同的选项,以及哪种方法最适合您自己的用例?本文将向您介绍三种创建面板仪表板的方法:

  • hvPlot。交互式将您的任何数据帧处理管道转变为仪表板(如果您想探索数据集,这是个好主意!);
  • 面板。绑定将你的小部件和你的交互情节绑定在一起(如果你想构建一个任意的应用程序,这很棒!);
  • Param 将您的仪表板封装为自包含类(如果您想要构建一个支持 GUI 和非 GUI 使用的复杂代码库,这是个好主意)。

我们将向您展示如何选择适合您的方法,以及如何使用以下三种方法创建这个交互式仪表盘:

什么是面板?

Panel 是开源 HoloViz 生态系统中的仪表板库,包括八个库(见图 1),由我们的 Anaconda 朋友 Philipp Rudiger ,Jean-Luc Stevens 和 Jim Bednar 开发。HoloViz 每月有数十万次下载,是最受欢迎的 Python 可视化生态系统。

Panel 旨在构建定制的交互式应用和仪表盘。有许多 Python 可视化和仪表板工具,每种工具都有自己的优点和特殊功能。要了解更多关于 Python dashboarding 的情况,并找出哪种工具最适合您的用例,请查看我们之前的博客文章比较最流行的仪表板工具。在这里,我将重点介绍 Panel,并展示三种非常不同的使用方法,以便您可以看到哪种方法最符合您的目标和情况。

图一。HoloViz 生态系统中的八个包。

以数据为中心的方法:hvPlot。互动

hvPlot 是 HoloViz 生态系统中绘图的推荐入口点。如果你了解熊猫或者哈维。plot API,你已经知道如何使用 hvPlot:只需将df.plot替换为df.hvplot即可。

hvPlot 的。如果您主要关注于探索 Panel、Dask DataFrame 或 Xarray DataArray 中的数据集,交互式支持是使用 Panel 的最佳方式。有了.interactive,你可以非常容易地将你的处理流水线变成一个面板仪表盘,只需要几行代码。学习如何绘制?互动作品详情,请查看我们之前关于这个话题的博文和视频

下面是 hvPlot。用于创建上面仪表板的交互式代码。我们将在此强调一些要点:

  • hvPlot。互动是以数据为中心的。一旦有了数据框,就可以通过调用idf=df.interactive()把这个数据框变成交互数据框。
  • 在这段代码中,我们定义了三个小部件cylindersmfryaxis,这样我们的用户就可以交互地控制这三个值。然后,我们可以将小部件传递到数据处理管道中,产生交互式数据处理管道ipipeline,并构建反映从小部件中选择的值的交互式绘图iplot
  • 然后,我们使用一个模板在侧边栏中显示小部件,并在应用程序的主体中绘图。

请注意,即使您没有数据框作为起点,hvplot.bind(function, widget).interactive()也可以将函数绑定到微件,并使绑定的函数具有交互性。此功能允许您从数据库或 web API 查询数据,因此您仍然可以使用。互动,即使你还没有拿着你的数据框。

方法 1: hvplot。交互式(要运行此脚本,首先通过运行“conda install hvplot panel”来设置您的环境,然后在命令行中运行“panel serve HV plot _ interactive . py”

以应用为中心的方法:pn。绑定

如果您不是从正在探索的数据集开始,而是编写了一些函数来返回您想要显示的内容,无论是否涉及数据集,该怎么办?

不是从数据帧或创建数据帧的函数开始。绑定从一个函数开始。正如您在下面的代码中看到的,导入包和定义小部件的前 19 行与前面的方法完全相同。区别从第 20 行开始,这里我们定义了一个 plot 函数,它返回一个 plot(或者面板可以显示的任何东西)。

当我们使用 pn 时,奇迹就发生了。绑定将标绘函数plot与控件cylindersmfryaxis绑定。结果是一个互动的情节interactive_plot:

interactive_plot = pn.bind(plot, cylinders, mfr, yaxis)

方法二:pn。bind(要运行此脚本,首先通过运行“conda install hvplot panel”设置您的环境,然后在命令行中运行“panel serve pn_bind.py ”)

您可以使用pn.bind将窗口小部件“绑定”到任意数量的不同功能,然后用 Panel 布局每个“绑定”的功能,这样当绑定到它的任何窗口小部件被修改时,该功能会被自动调用。这种反应式编程模型允许您将任何小部件和输出的集合构建到仪表板中,如果您的目标是构建应用程序而不是探索数据集,pn.bind 是一种极好的方法。

以应用为中心的方法:param。取决于

如果您主要是为研究、分析、科学或工程领域编写代码,但是您也想支持可选的 GUI 应用程序接口,该怎么办?也就是说,如果您需要维护一个既可以用作 GUI 又可以用作命令行、批处理或其他自动化过程的单一代码库,该怎么办?

如果您的代码主要是作为 Python 函数组织的,pn.bind 可以很好地处理这种情况;只需将这些函数放入一个可导入的文件中,然后将它们“绑定”到一个单独的 app.py 文件中的小部件上,以生成 GUI 版本。如果你的代码被组织成 Python 类会怎样?在这种情况下,Panel 被设计为与param包一起工作,该包允许您在 Python 类中声明所有代码的参数,然后单独地打开一个 GUI 来编辑这些值,同时保持您的 GUI 和非 GUI 代码完全独立。

正如您在下面的代码中看到的,对于这种方法,我们创建了一个名为InteractiveDashboard的类。在这个类中,我们创建三个参数cylindersmfryaxis。注意,这些是抽象参数,而不是面板小部件,所以代码不依赖于任何特定的 GUI 框架。重要的是,我们不需要依赖 Panel 来调用和使用这个类。我们可以在不使用 Panel 或任何其他 GUI 库的情况下使用这个 dashboard 类。

类似于 pn。上面的绑定方法,我们使用一个plot函数来创建我们的情节。@param.depends装饰器让我们显式地表达绘图函数和参数之间的依赖关系,这样我们就知道这个绘图依赖于三个小部件。

我们通过调用dashboard=InteractiveDashboard()来实例化这个类。然后在最后一步,我们使用一个模板在侧边栏显示参数dashboard.param并在应用程序的主体中绘制dashboard.plot

方法 3:参数。depends(要运行此脚本,首先通过运行“conda install hvplot panel param”来设置您的环境,然后在命令行中运行“panel serve param_depends.py”

你应该选择哪种方法?

你在做数据探索吗?

如果你是一名数据科学家或数据分析师,使用 Pandas 或 Dask DataFrame 或 Xarray 对象,从 hvPlot .interactive 开始。interactive 满足了我的大部分仪表板需求。

代码复杂度:

hvPlot。互动< Panel .bind < Param .depends

  • hvPlot .interactive is no doubt the easiest to learn and implement, and produces very short, readable code. It lives within the hvPlot framework. Even though it uses Panel to create a Panel dashboard, you don’t actually need to know much about Panel.
  • Panel .bind requires you to write functions, which is pretty easy as well, and is a better choice if you want to write an app that does a lot of computation that is not centered around dataframes.
  • Param .depends requires you to write classes, which is suited to the subset of people who are maintaining large, class-based Python codebases.

App 灵活性:

hvPlot。互动< Panel .bind < Param .depends

  • hvPlot .interactive is restricted to Pandas, Dask, Xarray DataFrame, or functions that produce such a data object.
  • Panel .bind can handle any arbitrary collection of objects and computations, but is specific to building an app.
  • The Param .depends approach lets you write code that supports a GUI but can also be used fully on its own, with no GUI dependencies.

你有问题吗?

我可以用 Jupyter 笔记本制作我的 app 吗?

是的,绝对的!需要指出的一点是,我们上面展示的三个示例文件都是。py 文件,但也可以是。ipynb 文件。因此,如果你是 Jupyter Notebook 用户,你可以在 Jupyter Notebook 中创建你的仪表盘,然后运行panel serve filename.ipynb来服务你的应用。

如果我需要更多的控制怎么办?我是否应该使用其他受支持的方法,如 pn。看情况 pn。互动,参数。手表,还是 HoloViews 动态地图?

本文提到的三种方法中的一种最适合大多数用户。pn.interact 主要是为从 ipywidets.interact 迁移而提供的,它的功能有限。pn.bind 取代了 pn.depends,支持相同的用途,同时也有助于保持 GUI 代码与应用程序的隔离,而不是影响特定领域的计算。参数。watch 是所有这些方法的底层实现,因此如果您需要对事件和相关计算进行最精细的控制,您可以使用它,但即使对于复杂的应用程序,也很少需要这样的控制。HoloViews DynamicMap 有助于优化您的应用程序,以避免闪烁并为部分绘图提供细粒度更新,但它比这里的方法更难描述,并且在您准备好优化交互性能之前不需要。

从哪里可以了解更多信息?

希望这篇文章对你有帮助!如果你有问题或者想联系其他 HoloViz 用户,请查看 https://discourse.holoviz.org/.的

致谢:

谢谢你的反馈和支持!

参考文献:

. . .

索菲亚杨马克斯科夫麦德森于 2022 年 9 月 20 日。

Sophia Yang 是 Anaconda 的高级数据科学家。在 LinkedInTwitterYouTube 上与我联系,并加入 ds/ml❤️读书俱乐部

计算 Python 列表中项目频率的 3 种方法

原文:https://towardsdatascience.com/3-ways-to-count-the-item-frequencies-in-a-python-list-89975f118899

实用指南

Ibrahim Rifath 在 Unsplash 上的照片

数据结构在编程语言中至关重要。如何存储、管理和操作数据是创建健壮高效的程序的关键因素。

Python 中内置的数据结构之一是列表,它被表示为方括号中的数据点集合。列表可用于存储任何数据类型或不同数据类型的混合。

以下是 Python 列表的一个示例:

mylist = ["a", "a", "b", "c", "c", "c", "c", "d", "d"]

在这篇文章中,我们将学习 3 种计算列表中项目的方法,这对于很多任务来说可能是非常有用的输入。更具体地说,我们将计算项目出现的次数,以获得它们的分布。否则,使用 len 函数可以很容易地计算出项目的总数。

len(mylist)
**# output**
9

计数方法

第一个是 count 方法,它返回给定项目的出现次数。

mylist = ["a", "a", "b", "c", "c", "c", "c", "d", "d"]mylist.count("c")
**# output**
4

如果您要查找特定的项目,此方法非常有用。要一次获得所有项目的频率,我们可以使用以下两种方法之一。

计数器功能

集合模块中的计数器函数可用于查找列表中项目的频率。它是 dictionary 的子类,用于计算可散列对象的数量。

Counter 返回一个 counter 对象,其中项目存储为键,频率存储为值。它非常类似于 Python 字典,这是另一种内置的数据结构。

from collections import Countermylist = ["a", "a", "b", "c", "c", "c", "c", "d", "d"]Counter(mylist)
**# output**
Counter({'a': 2, 'b': 1, 'c': 4, 'd': 2})

我们可以按如下方式访问项目的出现次数:

mycounter = Counter(mylist)mycounter["a"]
**# output**
2

counter 函数也可以用来计算字符串中的字符数。这里有一个例子:

mystring = "Data science ????"Counter(mystring)
**# output**
Counter({'D': 1,
         'a': 2,
         't': 1,
         ' ': 2,
         's': 1,
         'c': 2,
         'i': 1,
         'e': 2,
         'n': 1,
         '?': 4})

熊猫重视计数

Pandas 的 value counts 函数返回所有项目及其出现次数。结果,我们得到了列表分布的概况。

因为这是一个熊猫函数,我们首先需要将列表转换成一个系列。

import pandas as pdmylist = ["a", "a", "b", "c", "c", "c", "c", "d", "d"]pd.Series(mylist).value_counts()
**# output**
c    4
a    2
d    2
b    1
dtype: int64

value counts 函数的输出是一个序列,其索引包含列表中的项目。我们可以按如下方式访问项目的出现次数:

myseries = pd.Series(mylist).value_counts()myseries["d"]
**# output**
2

我们还可以使用 normalize 参数获得项目的百分比份额。

pd.Series(mylist).value_counts(normalize=True)**# output**
c    0.444444
a    0.222222
d    0.222222
b    0.111111
dtype: float64

在这个简短的指南中,我们学习了在 Python 中执行一个简单而重要的操作的 3 种不同方法。

感谢您的阅读。如果您有任何反馈,请告诉我。

创建多页简化应用程序的 4 种方法

原文:https://towardsdatascience.com/3-ways-to-create-a-multi-page-streamlit-app-1825b5b07c0f

Streamlit 可能不是为成熟的网站设计的,但在一个应用程序中创建多个页面是相当简单的

作者图片

创建多页面应用程序有两个方面:如何从用户界面中选择你想要的,以及如何选择要运行的代码。

UI 可以是选项菜单、下拉菜单、按钮或其他 UI 元素。在这里,我们将使用侧边栏中的 Streamlit selectbox来选择运行应用程序的哪一部分。

为了确定要运行哪些代码,我们将考察您可以自己实现的 3 种不同技术,以及 Streamlit 的多页面新的本机实现:

  • 使用 select 语句如if... else...或 3.10 模式匹配来选择要显示的页面。这是最简单的方法,适用于少量页面。
  • 将应用程序构建为库包。一种更复杂的交付多页的方式,也很容易使用——只要遵循这个模式。
  • 一个应用程序库的通用启动器应用程序。这个启动器会自动获取存储在库中的应用程序,但仍然易于创建和使用。
  • Streamlit 本机方法

书页

在每种情况下,我们将使用相同的两个代码块来显示来自 Plotly 中包含的 Gapminder 数据的关于一个国家或洲的数据。所以让我们先来看一下代码。

首先让我们得到数据:

df = pd.DataFrame(px.data.gapminder())

下面的代码显示了两个图表,一个是一个国家的人均 GDP,另一个是人口增长。数据在熊猫数据框df中,我们首先从数据框中构建一个唯一的国家名称列表。然后从细流中选择国家selectbox。然后,我们将图形分成两列,使它们并排出现。

下一个代码块非常相似,但是显示了一个大陆上所有国家的数据。

因此,这两个代码块将成为我们的两个“页面”。对于这三种解决方案,我将向您展示框架并指出这些代码块的位置。

简单选择

第一种技术非常简单,我们简单地使用一个if... else...或 Python 3.10 match语句来选择要运行的代码。这非常简单,但可能更适合于少量的页面,比如我们在这里使用的两个页面。

在这个解决方案中,我们将页面定义为函数countryData()continentData(),并将st.selectbox放在st.sidebar中,作为选择我们将运行哪个代码的机制。然后,我们简单地根据从st.selectbox返回的值调用适当的函数。

如果您使用的是 Python 3.10 或更高版本,您可以用类似下面的match语句替换if... else...:

match page:
    case 'Country data': countryData()
    case 'Continent data': continentData()

这个结构更简洁一些,尤其是当你有超过两个页面的时候。

实现为库

如果您有几个页面需要选择,那么将所有代码放在一个文件中会有点麻烦。更好的方法是使用 Python 包机制来保存可以导入到主程序中的函数。

您需要做的第一件事是创建一个存放页面的文件夹,并将其配置为库。所以首先创建一个名为stlib的子文件夹,然后在里面创建一个文件__init__.py。这个文件可以是空的,它只需要将文件夹标记为库。

现在在子文件夹中再创建两个文件,一个用于国家数据页面,另一个用于洲数据页面。我们将这些文件称为countryData.pycontinentData.py

主代码编码为一个名为run()的函数。它可以被命名为任何名称,但是它有助于使用一个标准名称来调用函数,我们将在后面看到。

最后一个if语句是可选的,但是如果你包含它,你可以将模块作为独立程序运行。

现在我们已经将“页面”实现为 Python 模块,我们可以导入它们并为每个调用run()函数。

通用解决方案

库的方法非常吸引人,因为这意味着我们可以将“页面”的功能转移到函数库。然而,我们可以更进一步,将模块信息存储在一个外部文件(在库中)中,并构建一个通用的“主”程序,该程序将读取该文件,构建选择菜单并调用任何可用的模块。

首先要做的是在 library 文件夹中创建一个包含可用模块列表的文件。我称之为libContents.py,它看起来像这样:

*# Return a list of the modules in this package*
    def packages():
        return ['countryData','continentData']

这是一个以列表形式返回模块名称的函数。

这个解决方案中的代码要多一点,但是更加灵活,您只需要编写一次。

代码如下所示,首先要注意的是我们显式地导入了libContents,然后我们声明了保存模块列表(名称、描述和模块引用)的全局数组。moduleNames是直接从libContents分配的,其他的我们会在后面的循环中处理。第一件事是使用importlib.import_module从名字中获取模块引用。然后我们在一个全局字符串description中寻找模块的描述。如果存在,我们将其存储在descriptions列表中,否则,我们存储模块名称。

这意味着模块现在可以包含如下描述:

description = "Continent Data"def run():
    import streamlit as st *# etc.*

这不是强制性的,但如果有,它将在下拉菜单中使用。

我们将使用st.selectbox中的描述。这与我们之前看到的类似,但是它使用一个函数来定义显示的文本,而不是传递给它的实际值(这非常简洁)。

因此函数format_func(name)获取模块的名称,在moduleNames列表中找到它的索引,然后使用这个索引来选择要为descriptions列表显示的正确文本。

最后一行

modules[moduleNames.index(page)].run()

通过检索模块引用,再次通过使用模块名称的索引来运行选定的模块。

Streamlit 本机方法

在我写这篇文章的几个小时内,Streamlit 宣布了一个简单易用的原生多页面特性。

你需要把你的应用组织成一个文件层次结构。在你的主目录中必须有一个主文件,它是应用程序的入口点。必须有一个名为“页面”的子文件夹。你把附加的页面文件放在这个子文件夹中,主程序会自动把它们捡起来并显示在侧边栏中。选择其中一个条目将加载该页面。简单!

下面是这个实现的完整代码。

我们做到了!三…不,四,在 Streamlit 中实现多页面应用的方法。第一个简单,第二个更适合更多页面,第三个是可以在任何应用程序中重用的通用解决方案,第四个是由 Streamlit 新提供的非常简单的解决方案。

虽然 Streamlit 版本很简单(尽管,在撰写本文时,它似乎在 Python 3.10 中不起作用),但我最喜欢的解决方案是第三个,因为一旦编写了主函数,这个解决方案就像原生解决方案一样容易使用,但更灵活,因为可以添加描述,并且顺序由作者决定(Streamlit 按字母顺序排序)。它还可以进一步定制。

感谢阅读,我希望这是有用的。如果你发现任何错误,有任何建议,或者只是想说声“你好”,请留下你的评论。

你可以在我的 Github 页面上找到这篇文章和我其他作品的代码

https://alanjones2.github.io

你可以在 Substack 上订阅我偶尔发的时事通讯。

https://technofile.substack.com

处理时间序列中异方差的 3 种方法

原文:https://towardsdatascience.com/3-ways-to-deal-with-heteroskedasticity-in-time-series-831f6499e688

如何稳定时间序列的方差,提高预测性能

塞缪尔·费拉拉在 Unsplash 上的照片

本文是对我的上一篇文章的后续。在那里,我描述了如何检测时间序列中的异方差。

我们在这里继续研究非常方差的问题。您将了解处理这种情况的三种方法。

非恒定方差的影响

异方差影响预测模型的拟合

方差不恒定的时间序列通常具有长尾分布。数据是左偏或右偏的。这可能会损害某些算法的学习过程。与基于树的方法不同,诸如深度神经网络的方法受到这个问题的影响。

线性模型的估计系数仍然是无偏的。这意味着,平均而言,他们将是正确的。但是,它们不会是最精确的。

异方差也使任何假设观测值间方差不变的统计检验无效。

总而言之,如果不处理异方差,你的表现就会被搁置。

如何应对异方差

假设你运行了一个统计测试,证实时间序列是异方差的。

对此你能做些什么?

让我们看看三种可能的方法。

1.对数或幂变换

转换数据是消除异方差的最佳方法。目标是稳定方差,使分布更接近正态分布。

日志是做到这一点的有效转换。平方根或立方根是两种可能的选择。这些是 Box-Cox 变换的特殊例子。

以下是如何使用 Python 将 Box-Cox 应用于时间序列:

import numpy as np
from pmdarima.datasets import load_airpassengers
from scipy.stats import boxcox
from scipy.special import inv_boxcox

# loading the data
series = load_airpassengers(True)

# transforming the series
# lambda_ is the transformation parameter
series_transformed, lambda_ = boxcox(series)

# reverting to the original scale
original_series = inv_boxcox(series_transformed, lambda_)

# check if it is the same as the original data
np.allclose(original_series, series)
# True

Box-Cox 依赖于转换参数 lambda。但是,它是在引擎盖下由 scipy 自动优化的。没必要担心那个。当λ的值等于 0 时,应用 Box-Cox 变换与对数标度相同。

您可以使用函数 inv_boxcox 将转换后的数据恢复到其原始比例。

Box-Cox 的一个局限性是,它只为正数据定义。Yeo-Johnson 转换类似于 Box-Cox 方法,解决了这个问题。

下面是脚本中使用的示例时间序列中 Box-Cox 的影响。

图 1:原始时间序列(上图)和各自的 Box-cox 变换(下图)。方差在变换后变得稳定。图片作者。

2.波动标准化

波动率标准化是处理非恒定方差的另一种方法。

时间序列的波动性是数据最近的变化水平。这种可变性通常用标准差来量化。波动率标准化的思想是根据其波动率对序列进行标准化。它导致了具有相同变化水平的观察结果。

波动性标准化在具有许多时间序列的数据集中特别有用。例如,在训练全球预测模型时

例子

让我们看一个使用多元时间序列的例子。

目标是预测序列中不同变量的未来值。我们将使用一个全球预测模型来做这件事。在这篇介绍性文章中,你可以了解更多关于全球预测模型的信息。基本思想是使用几个时间序列作为输入建立一个单一的预测模型。

此示例中的数据集是葡萄酒销售时间序列。它看起来是这样的:

图 2:葡萄酒销售多元时间序列。目标是预测超过测试开始标记的所有观察值。这些数据是公开的。查看参考文献[3]中的原始资料。图片作者。

在每个变量(葡萄酒类型)中,方差在系列中看起来是稳定的。但是,很明显,不同的变量有不同程度的可变性。波动率标准化可用于稳定每个变量的方差。

以下是在构建预测模型时如何应用波动率标准化。查看评论了解更多上下文。

import re
import numpy as np
import pandas as pd

# using xgboost as the regression algorithm
from xgboost import XGBRegressor
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_absolute_error as mae

# https://github.com/vcerqueira/blog/
from src.tde import time_delay_embedding

# https://github.com/vcerqueira/blog/tree/main/data
wine = pd.read_csv('data/wine_sales.csv', parse_dates=['date'])
wine.set_index('date', inplace=True)

# train test split
# using the last 20% of data as testing
train, test = train_test_split(wine, test_size=0.2, shuffle=False)

# transforming the time series for supervised learning
train_df, test_df = [], []
for col in wine:
    # using 12 lags to forecast the next value (horizon=1)
    col_train_df = time_delay_embedding(train[col], n_lags=12, horizon=1)
    col_train_df = col_train_df.rename(columns=lambda x: re.sub(col, 'Series', x))
    train_df.append(col_train_df)

    col_test_df = time_delay_embedding(test[col], n_lags=12, horizon=1)
    col_test_df = col_test_df.rename(columns=lambda x: re.sub(col, 'Series', x))
    test_df.append(col_test_df)

# different series are concatenated on rows
# to train a global forecasting model
train_df = pd.concat(train_df, axis=0)
test_df = pd.concat(test_df, axis=0)

# splitting the explanatory variables from target variables
predictor_variables = train_df.columns.str.contains('\(t\-')
target_variables = train_df.columns.str.contains('Series\(t\+')
X_train = train_df.iloc[:, predictor_variables]
Y_train = train_df.iloc[:, target_variables]
X_test = test_df.iloc[:, predictor_variables]
Y_test = test_df.iloc[:, target_variables]

# volatility standardization
# dividing by the standard deviation of past 12 lags
X_train_vs = X_train.apply(lambda x: x / x.std(), axis=0)
X_test_vs = X_test.apply(lambda x: x / x.std(), axis=0)

# testing three methods
## no normalization/preprocessing
mod_raw = XGBRegressor()
## volatility standardization
mod_vs = XGBRegressor()
## log transformation
mod_log = XGBRegressor()

# fitting on raw data
mod_raw.fit(X_train, Y_train)
# fitting with log-scaled data
mod_log.fit(np.log(X_train), np.log(Y_train))
# fitting with vol. std. data
mod_vs.fit(X_train_vs, Y_train)

# making predictions
preds_raw = mod_raw.predict(X_test)
preds_log = np.exp(mod_log.predict(np.log(X_test)))
preds_vs = mod_vs.predict(X_test_vs)

print(mae(Y_test, preds_raw))
# 301.73
print(mae(Y_test, preds_vs))
# 294.74
print(mae(Y_test, preds_log))
# 308.41

用波动率标准化对数据进行预处理可以提高预测性能。相对于这个问题中的对数变换,波动率标准化也更好。

3.加权回归

另一种处理异方差的方法是选择合适的方法。例如,不假设观测值之间的方差相等。

您还可以根据观察值的可变性为其分配权重。默认情况下,学习算法对数据集中的所有观察值给予相同的权重。然而,可变性更高的病例具有更少的信息。你可以通过减轻它们的重量来降低它们对方法的重要性。

这些权重是根据拟合值的方差计算的。方差越大,权重越小。这里有一个来自 statsmodels Python 库的例子。

scikit-learn 中的几个算法都有一个 sample_weight 参数,可以用来设置权重。

方差建模

Nikola Knezevic 在 Unsplash 上拍摄的照片

您可以模拟方差的变化,而不是稳定它。

这可以通过 ARCH(自回归条件异方差)等模型来实现。这种类型的模型用于根据时间序列的过去值预测方差。

GARCH(广义自回归条件异方差)扩展了 ARCH。除了使用序列的过去值,它还使用过去的方差。

arch 库为这些方法提供了 Python 实现。

外卖

在本文中,您学习了如何处理时间序列中的异方差。我们讨论了三种方法:

  1. 对数或幂变换;
  2. 波动率标准化;
  3. 加权回归。

我个人的偏好是转换数据。当我处理一个单一的时间序列时,我会选择选项 1。对于几个时间序列,我倾向于使用选项 2。但是,你可以使用交叉验证来优化

您可以使用 ARCH/GARCH 方法直接对方差建模。

谢谢你的阅读,下一个故事再见!

进一步阅读

[1] 关于电力变换,预测原理与实践

[2] 关于加权回归,工程统计手册

[3]罗布·海德曼和杨卓然(2018)。时间序列数据库。v 0 . 1 . 0 .https://pkg.yangzhuoranyang.com/tsdl/(GPL-3)

3 种你可能不知道的时间序列可视化方法

原文:https://towardsdatascience.com/3-ways-to-visualize-time-series-you-may-not-know-c8572952ea9c

数据可视化,时间序列

关于如何在 Python 和 Altair 中可视化时间序列的现成教程

Anton Maksimov 5642.su 在 Unsplash 上的照片

时间序列是一系列数据点,通常以离散的时间间隔测量。我们可以使用各种方法来表示时间序列数据,包括折线图、条形图和散点图。在 Python 中,我们可以使用 matplotlib、seaborn 和 Altair 等库来创建时间序列图。

有几种方法可以显示时间序列数据,如折线图和条形图。折线图是最常见的时间序列图,用于显示一段时间内的趋势。条形图用于显示不同时间段之间的比较。在本文中,我们将描述三种可视化时间序列的替代方法:

  • 日历热图
  • 箱形图
  • 循环图

为了演示这三种类型的图,我们将使用 Python 和 Altair 实现一个实际的例子,但是我们可以将这种方法推广到其他库。

数据集加载

作为一个例子,我们使用在开放数据共享许可下发布的全球温度时间序列

首先,我们加载数据集作为熊猫数据帧

import pandas as pd

df = pd.read_csv( '../Datasets/monthly_temperature.csv' , parse_dates=[ 'Date' ]) 
df.head()

作者图片

接下来,我们关注 GCAG 源,因此我们应用一些过滤器:

df = df[df[ 'Source' ] == 'GCAG' ] 
df.drop(labels=[ 'Source' ], axis= 1 , inplace= True )

我们画一条简单的线来显示经典趋势线。

import altair come alt 

alt.Chart(df).mark_line().encode( 
    x= 'Data' , 
    y= 'Media'
 )

作者图片

日历热图

日历热图是一种可视化时间序列的好方法。它显示了值随时间的分布,并使查看模式和异常值变得更加容易。让我们构建一个日历热图,在 x 轴上显示年份,在 y 轴上显示月份。

首先,我们从日期中提取月份和年份。

df[ 'Mese' ] = pd.to_datetime(df[ 'Data' ]).dt.month 
df[ 'Anno' ] = pd.to_datetime(df[ 'Data' ]).dt.year

然后,我们建立图表。

alt.Chart(df).mark_rect().encode( 
    x= 'Anno:O' , 
    y= 'Mese:O' , 
    color=alt.Color( 'Mean:Q' , scale=alt.Scale( range =['blue','green', 'yellow','orange','red'])) 
).properties(width= 800 )

作者图片

日历热图对于显示几个月和几年的重复模式非常有用。在我们的方案中,我们只看到温度逐年上升。

箱线图

箱线图是一种显示数据集分布的图形。这是可视化时间序列的好方法,因为它显示了值随时间的分布。创建箱线图时,确保轴的比例正确。否则剧情会有误导。例如,如果 y 轴没有正确缩放,看起来会有比实际更多的异常值。

一旦我们创建了箱线图,我们就可以用它来识别数据中的模式。例如,我们注意到数据中有很多变化,或者在一天中的某些时候,这些值往往会高于或低于其他值。

在 Altair 中编写以下代码来构建一个 boxplot:

alt.Chart(df).mark_boxplot().encode(
    x='Month',
    y='Mean'
)

作者图片

循环图

周期图是一种图形工具,用于可视化时间序列数据的周期性质。这种类型的图对于识别数据的季节性特别有用。循环图的 x 轴被分成相等的间隔,每个间隔代表一个完整的数据循环。y 轴显示周期中每个点的数据量。

周期图可用于识别数据中的周期性趋势,如每月或每年的周期。它们还可用于识别一次性事件,如不定期出现的数据峰值。

要在 Altair 中构建循环图,我们必须连接 12 个不同的图,每个月一个。

months = ['Jan', 'Feb', 'Mar', 'Apr', 'May','Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec',]

charts =alt.hconcat(spacing=0)
for i in range(1,13):
    if i == 1:
        axis = alt.Axis(grid=False)
    else:
        axis = None
    chart = alt.Chart(df).mark_line().encode(
        x=alt.X('Year:O', title=months[i-1]),
        y=alt.Y('Mean', axis=axis)
    ).transform_filter(
        alt.FieldEqualPredicate(field='Month', equal=i)
    ).properties(
        width=70,
        height=300
    )
    charts |= chart

作者图片

摘要

恭喜你!您刚刚学习了三种可视化时间序列的新方法!有许多方法可以可视化时间序列数据,在本文中,我们探讨了三种您可能不熟悉的方法。日历热图、箱线图和周期图都可以为您的数据提供有价值的见解。

所以下次你查看时间序列时,不要忘记尝试这些不同的可视化技术——你可能会发现一些关于你的数据的新东西。

在这里下载这篇文章中描述的例子的代码来玩你的数据集。

你可能也会对…感兴趣。

你想了解更多关于时间序列的知识吗?

阅读 Packt 有限公司出版的《用于数据科学的彗星》一书的第 11 章。

作者图片

30 个非常有用的熊猫函数,用于日常数据分析任务

原文:https://towardsdatascience.com/30-very-useful-pandas-functions-for-everyday-data-analysis-tasks-f1eae16409af

卢卡斯·森奇尼在 Unsplash 上的照片

30 个非常有用的熊猫函数,用于日常数据分析任务

熊猫小型张

Python 的 Pandas 库是 Python 中使用最广泛的库。因为这是数据分析或机器学习的每个方面都需要的数据操作库。即使你正在进行数据可视化或机器学习,一些数据操作仍然会存在。在本文中,我将列出日常使用所必需的 Pandas 函数,这些函数可能足以执行常规的数据操作任务。

在本文中,我将使用来自 Kaggle 的公共数据集 FIFA dataset。

这里提到的用户许可是https://www.kaggle.com/stefanoleone992/fifa-21-complete-player-dataset/metadata

请随意从这里下载数据集:

*https://github.com/rashida048/Datasets/blob/master/fifa.csv

好戏开始了!

我正在导入必要的包和数据集:

import numpy as np
import pandas as pd
pd.set_option('display.max_columns', 100)

让我们开始讨论功能:

1.pd.read_csv,pd.read_excel

首先要提到的函数是 read_csv 或者 read_excel。到目前为止,我在每个项目中至少使用了其中一个函数。这些函数已经不言自明了。它们用于将 CSV 或 excel 文件读取为 pandas DataFrame 格式。这里我使用 read_csv 函数来读取 FIFA 数据集:

df = pd.read_csv("fifa.csv")

我有一个关于 read_csv 函数的详细视频。它有几个很好的参数,可以帮助您在读取数据集时稍微清理一下数据集。我这里有一篇详细的文章:

答。txt 文件也可以使用。read_csv()函数使用以下语法:

data = pd.read_csv(file.txt, sep=" ")

如果您有一个 excel 文件而不是 csv 文件,您将使用 pd.read_excel。

也是常用的。head()函数在 read_csv 或 read_excel 后查看数据帧。默认情况下,它显示数据帧的前 5 行。在这里,我展示了上面数据帧 df 的前五行:

df.head()

作者图片

如果您想要特定的行数而不是 5 行,您可以指定。如果我想要 7 行,我会在。head()函数作为参数。

df.head(7)

2.df.columns

当你有这么大的数据集时,很难看到所有的列。使用。columns 函数,可以打印出数据集的所有列:

df.columns

输出:

Index(['Unnamed: 0', 'sofifa_id', 'player_url', 'short_name', 'long_name', 'age', 'dob', 'height_cm', 'weight_kg', 'nationality', 'club_name', 'league_name', 'league_rank', 'overall', 'potential', 'value_eur', 'wage_eur', 'player_positions', 'preferred_foot', 'international_reputation', 'weak_foot', 'skill_moves', 'work_rate', 'body_type', 'real_face', 'release_clause_eur', 'player_tags', 'team_position', 'team_jersey_number', 'loaned_from', 'joined', 'contract_valid_until', 'nation_position', 'nation_jersey_number', 'pace', 'shooting', 'passing', 'dribbling', 'defending', 'physic', 'gk_diving', 'gk_handling', 'gk_kicking', 'gk_reflexes', 'gk_speed', 'gk_positioning', 'player_traits', 'attacking_crossing', 'attacking_finishing', 'attacking_heading_accuracy', 'attacking_short_passing', 'attacking_volleys', 'skill_dribbling', 'skill_curve', 'skill_fk_accuracy', 'skill_long_passing', 'skill_ball_control', 'movement_acceleration', 'movement_sprint_speed', 'movement_agility', 'movement_reactions', 'movement_balance', 'power_shot_power', 'power_jumping', 'power_stamina', 'power_strength', 'power_long_shots', 'mentality_aggression', 'mentality_interceptions', 'mentality_positioning', 'mentality_vision', 'mentality_penalties',
'mentality_composure', 'defending_marking', 'defending_standing_tackle', 'defending_sliding_tackle', 'goalkeeping_diving', 'goalkeeping_handling', 'goalkeeping_kicking', 'goalkeeping_positioning', 'goalkeeping_reflexes'], dtype='object')

3.df.drop()

您可以使用 df.drop()删除一些不必要的列。在这个数据集中,我们有如此多的列,我们不打算在本教程中使用它们。所以,我们可以很容易地放弃一些:

df = df.drop(columns=['Unnamed: 0', 'weak_foot', 'real_face'])

我只是掉了这三列:‘未命名:0’,‘弱 _ 足’,‘真 _ 脸’。

4.。len()

为提供数据帧的长度。让我们看一个例子:

len(df)

输出:

16155

这个数据帧有 16155 行数据。

5。df.query()

您可以使用布尔表达式进行过滤或查询。在这个例子中,我将使用“射门”和“传球”列。在这里,我检查哪些行“射门”大于“传球”。

df.query("shooting > passing")

这将只返回投篮大于传球的行。

6.df.iloc()

该函数将行和列索引作为参数,并相应地给出数据帧的子集。这里我取前 10 行数据,索引第 5 到第 10 列:

df.iloc[:10, 5:10]

作者图片

7.df.loc()

这个函数的操作与。iloc()函数。但是在这里,我们可以准确地指定我们想要的行索引,以及我们希望在子集中包含的列的名称。这里有一个例子:

df.loc[[3, 10, 14, 23], ['nationality', 'weight_kg', "height_cm"]]

作者图片

查看行索引。我们只有第 3、10、14 和 23 排。另一方面,对于列,我们只有指定的列。

8.df['']。数据类型

另一个非常基本和广泛使用的功能。因为在我们深入分析、可视化或预测建模之前,有必要知道变量的数据类型。我正在使用获取“height_cm”列的数据类型。此处的 dtypes 函数:

df.height_cm.dtypes

输出:

dtype('int64')

您可以选择使用以下语法获取每一列的数据类型:

df.dtypes

输出:

height_cm                     int64
weight_kg                     int64
nationality                  object
random_col                    int32
club_name                    object
league_name                  object
league_rank                 float64
overall                       int64
potential                     int64
value_eur                     int64
wage_eur                      int64
player_positions             object
preferred_foot               object
international_reputation      int64
skill_moves                   int64
work_rate                    object
body_type                    object
team_position                object
team_jersey_number          float64
nation_position              object
nation_jersey_number        float64
pace                        float64
shooting                    float64
passing                     float64
dribbling                   float64
defending                   float64
physic                      float64
cumsum_2                      int64
rank_calc                   float64
dtype: object

9.df.select_dtypes()

您可以使用此函数选择特定数据类型的变量或列。例如,我只想选择数据类型为“int64”的列。下面是如何做到这一点:

df.select_dtypes(include='int64')

作者图片

我们得到了所有数据类型为“int64”的列。如果我们在' select_dtypes '函数中使用' exclude '而不是' include ',我们将得到不具有数据类型' int64 '的列:

df.select_dtypes(exclude='int64')

作者图片

这是输出的一部分。看,变量不是整数。你可能认为‘random _ col’列是整数。但是如果你检查它的数据类型,你会发现它看起来是整数,但是它的数据类型是不同的。请随意检查。

10。df.insert()

顾名思义,该函数在指定位置插入一列。为了说明这一点,我将首先创建一个长度与数据帧相同的随机数数组:

random_col = np.random.randint(100, size=len(df))

我将把这个数组作为一列插入数据帧 df 的第 3 列。记住,列索引从零开始。

df.insert(3, 'random_col', random_col)

这是数据帧的一部分:

df.head()

作者图片

看,列“random_col”被插入到第三个位置。

11。df['']。累计值()

它为你提供了累计的总和。我举个例子解释一下。在本例中,我将使用“value_eur”和“wage_eur”列。代码如下:

df[['value_eur', 'wage_eur']].cumsum()

输出:

作者图片

正如您在每一行中看到的,它为您提供了前面各行中所有值的累积和。

12.df.sample()

当数据集太大时,您可以从中选取一个有代表性的样本来执行分析和预测建模。那可能会节省你一些时间。此外,过多的数据有时可能会破坏可视化。我们可以用这个函数得到一定数量的数据点或者某个分数或者数据点。在这里,我从国际足联的数据集中抽取了 200 个数据点。它随机抽取样本。

df.sample(n = 200)

我在这里取了国际足联数据集的 25%:

df.sample(frac = 0.25)

13.df['']。哪里()

此函数帮助您基于布尔条件查询数据集。举个例子,我们之前做的 random_col 的取值范围是从 0 到 100。下面是我们如何制作一个系列,看看它们中哪些大于 50。

df['random_col'].where(df['random_col'] > 50)

输出:

0         NaN
1         NaN
2        56.0
3         NaN
4         NaN
         ... 
16150    65.0
16151     NaN
16152     NaN
16153    57.0
16154     NaN
Name: random_col, Length: 16155, dtype: float64

如果值不满足条件,即值不大于 50,则返回 NaN。我们可以使用以下语法将 NaN 替换为 0 或任何其他值:

df['random_col'].where(df['random_col'] > 50, 0)

输出:

0         0
1         0
2        56
3         0
4         0
         ..
16150    65
16151     0
16152     0
16153    57
16154     0
Name: random_col, Length: 16155, dtype: int32

14.df['']。唯一()

这在我们有分类变量的地方非常有用。它用于找出分类列的唯一值。让我们看看 FIFA 数据集中“skill_moves”列的唯一值是什么:

df.skill_moves.unique()

输出:

array([4, 5, 1, 3, 2], dtype=int64)

因此,在 skill_moves 列中有五个唯一值。如果我们打印出数据集的头部来检查列的值,您可能看不到其中所有的唯一值。所以,要知道所有的唯一值。unique()函数非常方便。

15.df['']。努尼克

另一个受欢迎的功能。这个函数让你知道一列中有多少个唯一值。例如,如果您想查看这个数据集中有多少不同的国籍,您可以使用下面这行简单的代码

df.nationality.nunique()

输出:

149

最棒的是,这个函数还可以用于总数据集,以了解每列中唯一值的数量:

df.nunique()

输出:

height_cm                      48
weight_kg                      54
nationality                   149
random_col                    100
club_name                     577
league_name                    37
league_rank                     4
overall                        53
potential                      49
value_eur                     161
wage_eur                       41
player_positions              907
preferred_foot                  2
international_reputation        5
skill_moves                     5
work_rate                       9
body_type                       3
team_position                  29
team_jersey_number             99
nation_position                28
nation_jersey_number           26
pace                           74
shooting                       70
passing                        67
dribbling                      67
defending                      69
physic                         63
cumsum_2                    14859
rank_calc                     161
dtype: int64

这里我们有每列中唯一值的数量。

16.df['']。排名()

该函数为您提供基于某一列的排名。在 FIFA 数据集中,如果我们想根据“value_eur”列对球员进行排名,下面是其语法:

df['rank_calc'] = df["value_eur"].rank()

使用上面的代码行,我创建了一个名为“rank_calc”的新列。这个新的栏目会根据“价值欧元”给你每个玩家的排名。默认情况下,该列将被添加到末尾。请自行运行该行代码进行检查。

17.。isin()

我将制作一个数据集的子集,其中只包含一些使用。isin()函数。

nationality = ["Argentina", "Portugal", "Sweden", "England"]
df[df.nationality.isin(nationality)]

如果您运行这段代码,您会看到我们得到的数据集只包含上面列表中提到的几个国家。你可以在这里看到数据集的一部分:

作者图片

18.df.replace()

它确实像它听起来那样。它替换列的值。当我们只需要替换一个列的唯一值时,我们只需要传递旧值和新值。想象一下,我们刚刚发现‘league _ rank’1.0 现在需要换成 1.1。下面是如何做到这一点:

df.replace(1.0, 1.1)

作者图片

再看现在数据集中的 league_rank 列,1.0 换成了 1.1。如果我们需要更改多个值,我们可以向 replace 函数传递一个字典,其中键应该是原始值,值应该是替换值。

df.replace({1.0: 1.1,  4.0: 4.1, 3.0: 3.1})

作者图片

19.df.rename()

它用于重命名列。在这里,我将“体重 _ 千克”和“身高 _ 厘米”列更改为“体重(千克)”和“身高(厘米)”:

df.rename(columns = {"weight_kg": "Weight (kg)", "height_cm": "Height (cm)"})

作者图片

非常简单有用!

20.。菲尔娜

现实生活中无论什么时候你会收到一个大的数据集,大多数情况下都会有一些空值。很难得到一个完美的数据集。因此,如果您是数据分析师或数据科学家,填充空值是您日常任务的一部分。这个功能。fillna()用您选择的其他值替换空值。以下是国际足联数据集末尾的一些栏目:

作者图片

你看,投篮,传球,防守,还有其他一些栏目都有空值。在开始进行任何预测建模和其他数据科学任务之前,我们确实需要用一些兼容数据类型的值来替换这些空值。否则,我们可能会出错。例如,在“步速”列中,值应该是数字,但在这里和那里您会看到 NaN 值。最普通但不太有效的方法是用零替换那些 NaN 值。以下是用零更改“pace”列的所有 NaN 值的方法:

df['pace'].fillna(0, inplace=True)

作者图片

如果你注意到,在速度栏中的 NaN 现在是零。在总起搏栏中,如果有更多的 NaN 值,也应将其替换为零。

正如我之前提到的,用零替换可能不是最有效的方法。您可以用自己选择的其他值来替换它。用平均值或中值替换值也很常见。如果我们想用空间平均值列替换 pace 列的 NaN 值,我们应该使用下面这行代码:

df['pace'].fillna(df['pace'].mean(), inplace = True)

21.df.groupby()

这是最流行的数据汇总功能。您可以按照某个变量对数据进行分组,并找出关于这些组的有用信息。例如,我在这里按国籍对数据进行分组,并计算每个国籍的总“价值欧元”:

df.groupby("nationality")['value_eur'].sum()

输出:

nationality
Albania                25860000
Algeria                70560000
Angola                  6070000
Antigua & Barbuda       1450000
Argentina            1281372000
                        ...    
Uzbekistan              7495000
Venezuela              41495000
Wales                 113340000
Zambia                  4375000
Zimbabwe                6000000
Name: value_eur, Length: 149, dtype: int64

阿尔巴尼亚所有球员的总价值为 25860000 欧元。

也可以通过几个变量进行分组,并使用几个集合函数。我们将看到每个国籍和每个联赛级别的平均值欧元、中值欧元、平均工资欧元和中值工资欧元。

df.groupby(['nationality', 'league_rank'])['value_eur', 'wage_eur'].agg([np.mean, np.median])

输出:

作者图片

使用“分组依据”功能,您可以做更多的事情。我这里有一篇详细的文章:

22.。pct_change()

你可以从变量的前一个值得到百分比变化。在本演示中,我将使用 value_eur 列,并获取每行数据相对于之前的百分比变化。第一行将是 NaN,因为之前没有要比较的值。

df.value_eur.pct_change()

输出

0             NaN
1       -0.213930
2       -0.310127
3       -0.036697
4        0.209524
           ...   
16150    0.000000
16151    0.500000
16152   -0.500000
16153    0.000000
16154   -1.000000
Name: value_eur, Length: 16155, dtype: float64

在这个数据集中,你可能觉得这并不重要。

但是想想一些财务数据。特别是当你每天都有股票市值的时候。看到每天价值的百分比变化该有多好。

23.df.count()

它提供数据帧中指定方向的数据数量。当方向为 0 时,它提供列中的数据数:

df.count(0)

输出:

Unnamed: 0                 16155
sofifa_id                  16155
player_url                 16155
short_name                 16155
long_name                  16155
                           ...  
goalkeeping_diving         16155
goalkeeping_handling       16155
goalkeeping_kicking        16155
goalkeeping_positioning    16155
goalkeeping_reflexes       16155
Length: 81, dtype: int64

您可以看到每列中的数据数量。

当方向为 1 时,它提供行中的数据数量:

df.count(1)

输出:

0        72
1        72
2        72
3        72
4        71
         ..
16150    68
16151    68
16152    68
16153    68
16154    69
Length: 16155, dtype: int64

正如您所看到的,每一行都有不同数量的数据。如果仔细观察数据集,您会发现它在几列中有许多空值。

24.df['']。值计数()

我们可以使用这个函数获得每个类别的值计数。在这里,我得到了每个等级中有多少个值。

df['league_rank'].value_counts()

输出:

1.0    11738
2.0     2936
3.0      639
4.0      603
Name: league_rank, dtype: int64

它返回默认排序的结果。如果希望结果以升序排列,只需设置 ascending=True:

df['league_rank'].value_counts(ascending=True)

输出:

4.0      603
3.0      639
2.0     2936
1.0    11738
Name: league_rank, dtype: int64

25.pd.crosstab()

它给出了一个频率表,是两个变量的交叉列表。我在这里做一个联赛排名和国际声誉的交叉列表:

pd.crosstab(df['league_rank'], df['international_reputation'])

作者图片

所以,我们得到了联赛排名和国际声誉的所有组合的数量。我们可以看到,大多数球员的国际声誉和联赛排名都是 1。

它可以进一步改进。我们可以在两个方向上添加边距,这将是总和,如果需要,我们还可以获得归一化值:

pd.crosstab(df['league_rank'], df['international_reputation'], 
            margins = True,
            margins_name="Total",
            normalize = True)

作者图片

下面是关于 count、value_counts 和 crosstab 方法的详细教程:

[## 熊猫总结数据的三个非常有用的功能

towardsdatascience.com](/three-very-useful-functions-of-pandas-to-summarize-the-data-491b64db9370)

26.pd.qcut()

该函数根据数据的分布对数据进行分类或分段。所以,我们得到了每个玩家的范围。在这里,我将把 value_eur 分成 5 个部分,并得出哪个玩家属于哪个部分:

pd.qcut(df['value_eur'], q = 5)

输出:

0        (1100000.0, 100500000.0]
1        (1100000.0, 100500000.0]
2        (1100000.0, 100500000.0]
3        (1100000.0, 100500000.0]
4        (1100000.0, 100500000.0]
                   ...           
16150          (-0.001, 100000.0]
16151          (-0.001, 100000.0]
16152          (-0.001, 100000.0]
16153          (-0.001, 100000.0]
16154          (-0.001, 100000.0]
Name: value_eur, Length: 16155, dtype: category
Categories (5, interval[float64]): [(-0.001, 100000.0] < (100000.0, 230000.0] < (230000.0, 500000.0] < (500000.0, 1100000.0] < (1100000.0, 100500000.0]]

您可以使用上面代码行中的 value_counts 来查看玩家属于哪个范围:

pd.qcut(df['value_eur'], q = 5).value_counts()

输出:

(-0.001, 100000.0]          3462
(230000.0, 500000.0]        3305
(100000.0, 230000.0]        3184
(500000.0, 1100000.0]       3154
(1100000.0, 100500000.0]    3050
Name: value_eur, dtype: int64

如你所见,数字非常接近。默认情况下,qcut 试图平均分配它们。但在现实生活中,它并不想总是平等的。因为大部分时间分布并不均匀。

27.pd.cut()

宁滨的另一种方法。如果我们想使用 cut 创建 5 个箱,它会将整个 value_eur 范围分成相等的五个部分,每个箱中的人口也会相应地增加。

pd.cut(df['value_eur'], bins = 5).value_counts()

输出:

(-100500.0, 20100000.0]      16102 
(20100000.0, 40200000.0]        40 
(40200000.0, 60300000.0]        10 
(60300000.0, 80400000.0]         2 
(80400000.0, 100500000.0]        1 
Name: value_eur, dtype: int64

每个范围内的间隔是相等的。但是每个群体中的人口是非常不同的。

我有一篇关于使用 cut 和 qcut 方法的数据宁滨的详细文章。请随意看一看:

28.df['']。描述()

这是一个伟大的功能,提供了一些基本的统计措施。在这里,我对 wage_eur 列使用了 describe 函数:

df['wage_eur'].describe()

输出:

count     16155.000000
mean      13056.453110
std       23488.182571
min           0.000000
25%        2000.000000
50%        5000.000000
75%       10000.000000
max      550000.000000
Name: wage_eur, dtype: float64

如输出所示,我们有八个不同的度量。每一个都非常重要。

29.最大和最小

这将为您提供具有指定变量的 n 个最大值或最小值的数据集。例如,我想获得工资最高的 5 行:

df.nlargest(5, "wage_eur")

作者图片

同样,我可以用 5 个最小的 wage_eur 数据创建数据集的子集:

df.nsmallest(5, "wage_eur")

作者图片

30.df.explode()

当您在某些行中有一个数据列表时,分解会很有用。当一些列中有整数,一些列中有列表时,很难分析、可视化或执行一些预测建模。Explode 有助于分解这些列表。例如,看这个数据帧:

df1 = pd.DataFrame({"city": ['A', 'B', 'C'],
                   "day1": [22, 25, 21],
                   'day2':[31, 12, 67],
                   'day3': [27, 20, 15],
                   'day4': [34, 37, [41, 45, 67, 90, 21]],
                   'day5': [23, 54, 36]})
df1

作者图片

让我们展开 d4 列:

df1.explode(jupyter notebook
'day4').reset_index(drop=True)

作者图片

结论

Python 的熊猫库好大。功能那么多。我选择一些日常生活中的重要功能。如果您非常了解这些,您将能够成功地执行大多数分析任务。熊猫还有一个非常有用的功能,我在这里没有提到。plot()函数。你只能用熊猫来绘图。熊猫在后端使用 Matplotlib,为你返回剧情。我这里有一个详细的教程:

希望这篇文章是有帮助的。

请随时在 Twitter脸书页面上关注我,并查看我的新 YouTube。频道

更多阅读

https://pub.towardsai.net/a-complete-guide-to-confidence-interval-t-test-and-z-test-in-r-for-data-scientists-cd16dd2d0eec *

使用 NumPy 将有限差分法的分辨率提高 300 倍

原文:https://towardsdatascience.com/300-times-faster-resolution-of-finite-difference-method-using-numpy-de28cdade4e1

有限差分法是解决复杂问题的强大技术,NumPy 使其

左边界为 500°C,上边界为 250°C 的温度图(图片由作者提供)

你可以在最后找到所有的代码。所有方程图像都是作者制作的。

记得使用右边的“关注”按钮来关注我→:你会收到新文章的通知,并帮助我达到 100 个关注者的目标:)

我最近看到了这篇关于用有限差分法求解 2D 偏微分方程的文章。我发现这个帖子是对有限差分法(FDM)的一个很好的介绍:如果你使用数值方法,一定要去看看。这是很好的解释,并使用了一个简单的例子,所以很容易理解。

*https://levelup.gitconnected.com/solving-2d-heat-equation-numerically-using-python-3334004aa01a

但当我阅读代码时,我意识到可以进行一些改进来加快解决速度,特别是因为 FDM 被认为是“慢”或“计算量大”的方法。

我将向您展示几行 num-python 代码如何将解析时间提高了 300 倍!

方程式快速入门

热量方程基本上是一个混合了时间和空间的偏微分方程——倒方形三角形只是“对每个方向上的二重导数求和”的一个有趣符号:

αa(扩散率)为常数。所以在 2D 我们可以写得更明确:

现在这种方程没有解析解,所以我们用数值方法求解。为了做到这一点,我们可以使用有限差分法:这种方法只是用一个“斜率”表达式来近似导数。例如,时间导数:

所以用有限差分符号,我们可以重写 2D 热方程:我们用 k 来描述时间步长,I 和 j 来描述 x 和 y 步长:

请注意,二阶导数(针对上述 x 或 y)在目标位置(I,j)之前(i-1 或 j-1)和之后(i+1 或 j+1)使用样本。

为简单起见,假设我们在每个方向上使用相同的采样:δx =δy。该等式得到简化,我们可以仅使用时间 t 的温度值,在几个空间位置上表示时间 k+1 的温度:

现在我们已经有了从时间“k”的样本给出时间“k+1”的温度的等式,我们可以递归地计算每个“帧”。

第一种方法:想到图像卷积!

请注意,计算 k+1 时刻温度的等式是 k 时刻其他温度点的线性组合。因此,该关系可视为线性运算,因此可写成卷积。

如果这没有意义,这里有另一个公式:将时间 k 的热图想象为 2D 图像,将时间 k+1 的热图想象为另一个图像,这是使用特定内核对第一个图像进行卷积的结果。

这个概念在使用模板表示的原始帖子中也有很好的描述。

用以下等式重写等式:

我们得到位置(I,j)在时间(k+1)的温度表达式:

该表达式可以写成内核(不依赖于 u)与时间 k 的温度图之间的卷积,内核可以写成:

局部(以位置(I,j)为中心)和电流(在时间 k)热图:

请注意,这个 3x3 矩阵只是主要目标样本周围的 9 个局部样本,是时间 k 时温度图像的“裁剪”

因此,下一时间步“k+1”的温度表达式就是这两个矩阵的“和积”,也称为张量积或点积:

密码

基于原帖的代码,我们初始化一个 3D 温度图,其中第一维度是时间,第二维度和第三维度是空间维度。我们将每个方向上的样本数设置为参数,以方便以后改进模拟。

现在,让我们来看看用于沿每个维度传播温度的代码:

众所周知,python 的“for 循环”应该在大多数情况下避免使用。尤其是嵌套的时候。所以我们将使用更快的 pythonic 符号重写上面的函数。

回到等式:

请注意,等式右侧的所有内容仅取决于第 k 次热图。我们有一个 k 循环沿时间方向传播,I 和 j 循环设置每个空间位置的温度。
现在我们想用 numpy 和一种“内核卷积方法”重写这个函数。

本质上,有限差分方法将解从时间 k 传播到时间 k+1,所以我们必须保留最外面的循环:k 循环。但是 2 个内环可以简化很多

请记住上面的点积:通过和积运算,我们可以计算位置 I,j 在时间 k+1 的温度,但是 numpy 允许对所有空间位置同时进行计算!所以不做 NxNy 操作,只做一个!*

为此,我们需要一个滑动窗口,这是处理卷积时的一个常用工具,由函数“NP . lib . stride _ tricks . sliding _ window _ view(arr,shape)”提供:该函数使用输入数组上的 stride 视图来返回给定形状的每个“局部”窗口的视图。

只是为了使滑动窗口视图更加清晰:

得到的数组具有形状(2,4,3,3):
-垂直方向上有 2 个元素,因为我们只能垂直地适应两个 3x3 的窗口
-水平方向上有 4 个元素,因为我们只能水平地适应四个 3x3 的窗口
-并且每个窗口的形状都是 3x3

既然我们有了每个局部窗口,我们还需要内核:因为伽马系数已经被定义,我们可以立即定义内核:

最后,我们用一个函数来替换原来的函数:

对于边界内的所有样本,滑动窗口函数返回一个 3x3 数组,该数组用于乘以内核,然后求和以最终计算 k+1 时刻的温度。

现在我们已经重写了函数,让我们确保它们输出相同的结果:

哪个输出为真!最后,我们可以使用 ipython 神奇的命令“timeit”来估计速度的提高:

所以我们从 10 秒,到只有 0.2 秒!

所以计算时间大大提高了!有限差分慢,但不是慢就是慢。

如果…会怎样

如果我告诉你我们可以用更简单的代码获得 10 倍以上的计算速度呢?嗯,我们可以,使用简单的索引。

同样,记住位于(I,j)的样本的基本方程:

该等式适用于边界内的所有样本(因此,不包括第一行、最后一行、第一行或最后一行的样本,因为它们没有完整的邻域)。

还要注意,有 5 个“u 变量”,即:

我们来写:
—— a = u[k,2:,1:-1]代表 u_{i+1,j}^k
—— b = u[k,:-2,1:-1]代表 u_{i-1,j}^k
—— c = u[k,1:-1,2: ]代表 u_{i,j-1}^k
—— d = u[k,1:-1,:-2]代表 u_{i,j+1}^k
—— e = u[k,1:-1,1:-1]代表 u_{i,j}^k

其中“1:-1”在这里是为了保持边界不变,k 在这里是因为我们只使用时间 k 的样本来计算时间 k+1 的样本。这样我们可以写…

现在,对所有样本及其邻域进行加权平均的操作在一个操作中完成,对于所有样本:

让我们确保它输出与之前相同的结果:

它输出 True。更有趣的是,让我们测试一下这个方法:

因此,我们得到了大约 30 毫秒,而使用嵌套循环得到了大约 10 秒,这是 300 倍的增益!(大约比卷积方法快 7 倍)

包裹

*以下是这篇帖子需要记住的重要内容:

  • 查看原帖。
  • 卷积:如果“新”值的等式是旧值的线性组合,就像模板图案一样,新值可以用卷积来表示:想想图像卷积。与嵌套循环相比,这种技术有了很大的改进,但仍然不如索引有效。
    -尽可能随时使用 numpy 索引 :这样效率更高,也更 pythonic 化。*

由于我们获得了巨大的速度提升,我们可以增加样本数量来优化模拟:

***

50x50 样本(左)和 200x200 样本(右)的仿真比较(图片由作者提供)。*

以下是完整的代码:*

31 个独特的 Python 包来改进您的数据工作流

原文:https://towardsdatascience.com/31-uniques-python-packages-to-improve-your-data-workflow-4f9762fc8f8b

面向数据人员的各种 Python 包

亚历山大·席默克在 Unsplash 上的照片

数据是一个广阔的领域,有大量的社区支持技术发展。此外,Python 拥有热心的支持者,帮助数据世界变得更容易访问,并为数据工作流带来价值。

已经开发了各种 Python 包来帮助数据人员的工作。根据我的经验,许多有用的数据 Python 包缺乏认知度,或者仍在流行。

这就是为什么在本文中,我想向您介绍几个独特的 Python 包,它们将在许多方面帮助您的数据工作流。让我们开始吧!

1.敲门

Knockknock 是一个简单的 Python 包,用于在机器学习模型训练完成或崩溃时通知你。我们可以通过电子邮件、Slack、微软团队等多种渠道获得通知。

为了安装这个包,我们使用下面的代码。

pip install knockknock

例如,我们可以使用以下代码向您的 Gmail 电子邮件地址通知您的机器学习建模培训状态。

from knockknock import email_sender
from sklearn.linear_model import LinearRegression
import numpy as np@email_sender(recipient_emails=["<your_email@address.com>", "<your_second_email@address.com>"], sender_email="<sender_email@gmail.com>")def train_linear_model(your_nicest_parameters): x = np.array([[1, 1], [1, 2], [2, 2], [2, 3]])
    y = np.dot(x, np.array([1, 2])) + 3 
    regression = LinearRegression().fit(x, y) 

    return regression.score(x, y)

无论你返回哪个函数,你都会得到通知。

2.tqdm

当你做一个迭代或者循环过程时,你需要一个进度条吗?那么 tqdm 就是你的答案。这个包会在你的笔记本或命令提示符中提供一个简单的进度条。

让我们从安装包开始。

pip install tqdm

然后我们可以尝试使用下面的代码来显示循环过程中的进度条。

from tqdm import tqdm
q = 0
for i in tqdm(range(10000000)):
    q = i +1

作者 GIF

正如你在上面的 GIF 中看到的,你的笔记本中显示了一个漂亮的进度条。当您有一个复杂的迭代并且想要跟踪进度时,它会有用得多。

3.熊猫-日志

Pandas-log 是一个 Python 包,提供对熊猫基本操作的反馈,比如.query.drop.merge等等。它基于 R Tidyverse,在这里你可以理解所有的数据分析步骤。

让我们尝试安装软件包。

pip install pandas-log

安装软件包后,让我们使用以下代码创建一个示例数据框。

import pandas as pd
import numpy as np
import pandas_logdf = pd.DataFrame({"name": ['Alfred', 'Batman', 'Catwoman'],
                   "toy": [np.nan, 'Batmobile', 'Bullwhip'],
                   "born": [pd.NaT, pd.Timestamp("1940-04-25"),   pd.NaT]})

然后,让我们用下面的代码尝试做一个简单的熊猫执行。

with pandas_log.enable():
    res = (df.drop("born", axis = 1)
             .groupby('name')
          )

作者图片

有了 Pandas-log,我们可以获得所有的执行信息。

4.表情符号

顾名思义,表情符号是一个支持表情符号文本数据分析的 Python 包。通常,我们在阅读 Python 的表情符号时会有困难,但是表情符号包可以帮助我们。

使用以下代码安装表情包。

pip install emoji

让我们尝试一个简单的包装表情符号。

import emoji
print(emoji.emojize('Python is :thumbs_up:'))

作者图片

有了这个包,我们可以输出表情符号,因为表情符号已经被解码成 Python 中可接受的。

5.TheFuzz

TheFuzz 是一个 Python 包,它使用 Levenshtein 距离计算相似度来匹配文本。

要使用这个包,我们需要先安装它。

pip install thefuzz

让我们试试这个包,看看我们如何使用 TheFuzz 包来进行相似性文本匹配。

from thefuzz import fuzz, process#Testing the score between two sentences
fuzz.ratio("Test the word", "test the Word!")

作者图片

Fuzz 还可以同时从许多单词中提取相似性分数。

choices = ["Atlanta Falcons", "New York Jets", "New York Giants", "Dallas Cowboys"]
process.extract("new york jets", choices, limit=2)

作者图片

Fuzz 适用于任何文本数据相似性活动。它应该是你的武器库中的一个包。

6.数字计算器

Numerizer 是一个 Python 包,它将书写的数字文本转换成整数或浮点数。让我们试试这个包来了解更多。

首先,我们使用下面的代码安装这个包。

pip install numerizer

然后我们可以测试这个包。我们来试试几个词来转化。

from numerizer import numerize
numerize('forty two')

作者图片

如您所见,单词被转换成了它们的整数对应物。如果你使用另一种书写风格,比如下面的,它也是有效的。

numerize('forty-two')

作者图片

它也适用于表示浮点数字文本的单词。

numerize('nine and three quarters')

作者图片

如果单词不是一个数字表达式,它们会保持原样。

numerize('maybe around nine and three quarters')

作者图片

这个包很简单,但是在很多场合都很有用。

7.PyAutoGUI

PyAutoGUI 是一个简单的 Python 包,可以自动控制鼠标和键盘。它的工作原理是在你的 IDE 中传递代码并让它们为你工作。让我们从安装包开始。

pip install pyautogui

然后我们可以使用下面的代码来测试这个动作。

import pyautogui
pyautogui.moveTo(10, 15)
pyautogui.click()
pyautogui.doubleClick()
pyautogui.press('enter')

上面的代码会将鼠标移动到某个位置并点击你的鼠标。通过按下功能,你也可以按下某个键盘按钮。

当你需要像下载文件或收集数据这样的重复性动作时,这个包非常有用。

8.加权计算

Weightedcalcs 是一个 Python 包,用于简化基于我们的数据框架的加权统计计算。从简单的统计,如加权平均值、中值和标准偏差,到加权计数和分布,用法各不相同。

为了使用这个包,我们需要使用下面的代码来安装它。

pip install weightedcalcs

让我们试着用现有的数据来计算一个加权分布。

import seaborn as sns
df = sns.load_dataset('mpg')

我会使用 seaborn 包中的 MPG 数据集。为了计算加权统计量,我们需要首先用加权变量声明类。

import weightedcalcs as wc
calc = wc.Calculator("mpg")

然后,我们将使用该类通过传递数据集和计算预期变量来进行加权计算。

calc.distribution(df, "origin")

作者图片

9.scikit-posthocs

scikit-posthocs 是一个用于事后测试分析的 python 包,通常用于统计分析中的成对比较。这个包提供了简单的 scikit-learn API 来进行分析。让我们从安装软件包到试用它开始。

pip install scikit-posthocs

那么让我们从简单的数据集开始,在试用这个包之前做一个 ANOVA 测试。

import statsmodels.api as sa
import statsmodels.formula.api as sfa
import scikit_posthocs as sp
df = sa.datasets.get_rdataset('iris').data
df.columns = df.columns.str.replace('.', '')lm = sfa.ols('SepalWidth ~ C(Species)', data=df).fit()
anova = sa.stats.anova_lm(lm)
print(anova)

作者图片

我们获得了 ANOVA 测试结果,但不确定哪个变量类别对结果的影响最大。这就是为什么我们要使用下面的代码进行事后测试。

sp.posthoc_ttest(df, val_col='SepalWidth', group_col='Species', p_adjust='holm')

作者图片

使用 scikit-posthoc,我们简化了事后检验的成对分析过程,并获得了 P 值。如果你想了解更多的事后测试,你可以在我下面的另一篇文章中读到更多。

10.youtube_dl

youtube_dl 是一个简单的 python 包,通过提供代码链接来下载 youtube 视频。让我们先安装包来试试这个包。

pip install youtube_dl

然后,我们使用以下代码将视频下载到您的环境中。

# Youtube Dl Example
import youtube_dl
ydl_opt = {}with youtube_dl.YoutubeDL(ydl_opt) as ydl:
    ydl.download(['[https://www.youtube.com/watch?v=ukzFI9rgwfU'](https://www.youtube.com/watch?v=ukzFI9rgwfU')])

作者图片

下载过程将开始,mp4 格式的视频将可用。

11.地狱犬座

Cerberus 是一个轻量级 python 包,用于数据验证活动。它旨在验证我们发起的任何模式数据以及基于它的数据。让我们从安装包开始。

pip install cerberus

Cerberus 的基本用法是启动验证器类来拥有数据模式。

from cerberus import Validator
schema = {'name': {'type': 'string'}, 'gender':{'type': 'string'}, 'age':{'type':'integer'}}
v = Validator(schema)

然后,使用我们传递给验证器类的模式,我们可以验证传递给代码的数据。

document = {'name': 'john doe', 'gender':'male', 'age': 15}
v.validate(document)

作者图片

如果传递的数据与模式相似,那么验证器类将得到真实的输出。这样,我们可以确保数据输入对于模式总是可靠的。

12.ppscore

ppscore 是一个 python 包,用来计算关于目标变量的变量预测能力。该软件包计算可以检测两个变量之间的线性或非线性关系的分数。得分范围从 0(无预测能力)到 1(完美预测能力)。

首先,我们将安装软件包进行测试。

pip install ppscore

然后使用可用的数据,我们将使用 ppscore 包来计算基于目标的分数。

import seaborn as sns
import ppscore as ppsdf = sns.load_dataset('mpg')
pps.predictors(df, 'mpg')

作者图片

结果是根据目标及其 ppscore 对变量进行排序。排名越低,变量对目标的预测能力越低。

13.玛雅人

Maya 是一个 python 包,用于尽可能轻松地解析日期时间数据。它使用一种简单的人类可读的交互来获取我们想要的日期时间数据。让我们通过首先安装它来开始使用这个包。

 pip install maya

然后我们可以使用下面的代码轻松访问当前日期。

import maya
now = maya.now()
print(now)

作者图片

我们还可以为明天的日期初始化一个对象类。

tomorrow = maya.when('tomorrow')
tomorrow.datetime()

作者图片

这个包对于任何与时间序列相关的活动都很有用,所以试试吧。

14.钟摆

Pendulum 是另一个关注日期时间数据的 python 包。它用于简化任何日期时间分析过程。让我们从导入包开始。

pip install pendulum 

使用一个简单的例子,我们可以很容易地访问时间,并用下面的代码更改它。

import pendulumnow = pendulum.now("Europe/Berlin")# Changing timezone
now.in_timezone("Asia/Tokyo")# Default support for common datetime formats
now.to_iso8601_string()# Day Shifting
now.add(days=2)

作者图片

15.类别 _ 编码器

category_encoders 是一个 python 包,用于类别数据编码(转换成数值数据)。这个包是各种编码方法的集合,我们可以根据需要将这些方法应用于各种分类数据。

为了试用这个包,我们需要安装这个包。

pip install category_encoders

然后我们可以使用下面的例子来应用转换。

from category_encoders import BinaryEncoder
import pandas as pd# use binary encoding to encode two categorical features
enc = BinaryEncoder(cols=['origin']).fit(df)# transform the dataset
numeric_dataset = enc.transform(df)
numeric_dataset.head()

作者图片

16.sci kit-多重学习

scikit-multilearn 是专门针对多类分类模型的机器学习模型的 python 包。该软件包提供了用于训练机器学习模型的 API,以预测具有两个以上类目标的数据集。

让我们通过首先安装它来开始使用这个包。

pip install scikit-multilearn

使用样本数据集,我们可以使用多标签 KNN 来训练分类器并测量性能指标。

from skmultilearn.dataset import load_dataset
from skmultilearn.adapt import MLkNN
import sklearn.metrics as metricsX_train, y_train, feature_names, label_names = load_dataset('emotions', 'train')
X_test, y_test, _, _ = load_dataset('emotions', 'test')classifier = MLkNN(k=3)
prediction = classifier.fit(X_train, y_train).predict(X_test)metrics.hamming_loss(y_test, prediction)

作者图片

17.多重集

Multiset 是一个简单的 Python 包,类似于内置的 set 函数,但是这个包允许多次出现。

pip install multiset

我们可以使用下面的代码来使用 Multiset 函数。

from multiset import Multiset
set1 = Multiset('aab')
set1

作者图片

您还可以测试用于比较和数据可变性的各种函数。

18.爵士音乐

Jazzit 是一个可爱而有趣的 python 包,可以在代码出错或等待代码运行时播放音乐。让我们从安装包开始。

pip install jazzit

然后,我们可以使用下面的代码在出错的情况下尝试样本音乐。

from jazzit import error_track[@error_track](http://twitter.com/error_track)("curb_your_enthusiasm.mp3", wait=5)
def run():
    for num in reversed(range(10)):
        print(10/num)

出错时会播放音乐,所以不要惊讶。

19.手摇计算器

handcalcs 是一个 python 包,用来简化笔记本渲染的数学 latex 过程。它将任何数学函数转化为方程形式。

要安装这个包,我们可以使用下面的代码。

pip install handcalcs

首先,我们需要导入必要的包。

import handcalcs.render
from math import sqrt

然后我们将尝试使用下面的代码来测试 handcalcs 包。使用%%render magic 命令渲染 Latex 计算。

%%rendera = 4
b = 6
c = sqrt(3*a + b/7)

作者图片

20.整洁文本

NeatText 是一个简单的 python 包,它简化了文本清理和文本数据的预处理。它对任何 NLP 项目和文本机器学习项目数据都很有用。让我们从安装包开始。

pip install neattext

使用下面的代码,我们可以试用这个包。

import neattext as nt 
mytext = "This is the word sample but ,our WEBSITE is [https://exaempleeele.com](https://exaempleeele.com) 😊✨."
docx = nt.TextFrame(text=mytext)

TextFrame用于启动 NeatText 类,我们可以使用各种函数来描述数据和清理数据。

docx.describe()

作者图片

使用 describe 函数,我们可以理解我们需要知道的每个文本统计。

为了进一步清理数据,我们可以使用下面的代码。

docx.normalize()

作者图片

清理数据还是比较简单的,但是有很多功能改进了预处理。

21.小型爵士乐队

Combo 是一个用于机器学习模型和分数组合的 python 包。该软件包提供了一个工具箱,允许将各种机器学习模型训练到一个模型中。它被视为集成学习模型中的一个子任务。

要试用这个包,让我们先安装它。

pip install combo

我们可以尝试使用从 scikit-learn 获得的乳腺癌数据集和从 scikit-learn 获得的各种分类模型来创建机器学习组合。

首先,让我们导入所有重要的包。

from sklearn.tree import DecisionTreeClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.neighbors import KNeighborsClassifierfrom sklearn.model_selection import train_test_split
from sklearn.datasets import load_breast_cancerfrom combo.models.classifier_stacking import Stacking
from combo.utils.data import evaluate_print

接下来,让我们看看用于预测目标的单个分类器。

# Define data file and read X and y
random_state = 42
X, y = load_breast_cancer(return_X_y=True)X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.4,
                                                        random_state=random_state)# initialize a group of clfs
classifiers = [DecisionTreeClassifier(random_state=random_state),
                   LogisticRegression(random_state=random_state),
                   KNeighborsClassifier(),
                   RandomForestClassifier(random_state=random_state),
                   GradientBoostingClassifier(random_state=random_state)]
clf_names = ['DT', 'LR', 'KNN', 'RF', 'GBDT']# evaluate individual classifiers
for i, clf in enumerate(classifiers):
    clf.fit(X_train, y_train)
    y_test_predict = clf.predict(X_test)
    evaluate_print(clf_names[i] + '   |   ', y_test, y_test_predict)
    print()

作者图片

接下来,让我们看看使用组合包的堆叠模型。

# build a Stacking model and evaluate
clf = Stacking(classifiers, n_folds=4, shuffle_data=False,
                   keep_original=True, use_proba=False,
                   random_state=random_state)clf.fit(X_train, y_train)
y_test_predict = clf.predict(X_test)evaluate_print('Stacking | ', y_test, y_test_predict)

作者图片

有所改善,但肯定还有进行另一项实验的空间。您可以使用该软件包尝试任何您认为必要的组合。

22.皮阿兹特罗

你需要星座数据还是只是好奇你今天的运气?然后你可以用 PyAztro 来实现!该软件包涵盖了独特的信息,如幸运数字,幸运标志,心情,等等。让我们试着通过安装来使用这个包。

pip install pyaztro

然后我们可以用下面的代码尝试访问今天的星座。

import pyaztro
pyaztro.Aztro(sign='gemini').description

作者图片

23.骗子

Faker 是一个 Python 包,用来简化生成合成数据。许多开发人员使用这个包来创建另一个合成数据生成器包。要使用这个包,让我们安装它。

pip install Faker

为了使用 Faker 包生成合成数据,我们需要初始化Faker类。

from faker import Faker
fake = Faker()

例如,我们将使用初始化的类创建一个合成数据名。

fake.name()

作者图片

每当我们运行 Faker 类中的属性.name时,Faker 会随机生成合成数据。您仍然可以尝试使用许多属性来生成数据。

24.费尔勒恩

Fairlearn 是一个 python 包,用于评估和减轻机器学习模型中的不公平性。这个包提供了许多必要的 API 来查看偏差,这样我们就可以避免它。要试用这个包,让我们先开始安装它。

pip install fairlearn

然后,我们可以使用 Fairlearn 的数据集来查看模型中有多少偏差。出于教学目的,我们将简化模型预测。

from fairlearn.metrics import MetricFrame, selection_rate
from fairlearn.datasets import fetch_adultdata = fetch_adult(as_frame=True)
X = data.data
y_true = (data.target == '>50K') * 1
sex = X['sex']selection_rates = MetricFrame(metrics=selection_rate,
                              y_true=y_true,
                              y_pred=y_true,
                              sensitive_features=sex)fig = selection_rates.by_group.plot.bar(
    legend=False, rot=0,
    title='Fraction earning over $50,000')

作者图片

Fairlearn API 有一个selection_rate函数,我们可以用它来检测群体模型预测之间的分数差异,这样我们就可以看到结果的偏差。

25.tiobeindexpy

tiobeindexpy 是一个简单的 python 包,用于获取 TIOBE 索引数据。TIOBE index 是一个编程排名数据,遵循它可能很重要,因为我们不想错过编程世界中的下一件事。

要使用 tiobeindexpy,我们需要先安装它。

pip install tiobeindexpy

然后我们可以通过下面的代码获得当月排名前 20 的编程语言。

from tiobeindexpy import tiobeindexpy as tb
df = tb.top_20()

作者图片

26.pytrends

pytrends 是一个 python 包,使用他们的 API 获取 Google 上的趋势关键词。当我们想要跟上当前的网络趋势或与我们的关键词相关的趋势时,这个包是有用的。要使用这个包,我们需要先安装它。

pip install pytrends

假设我想知道与关键字“礼物”相关的当前趋势,那么我将使用下面的代码来了解当前趋势。

from pytrends.request import TrendReq
import pandas as pd
pytrend = TrendReq()keywords = pytrend.suggestions(keyword='Present Gift')
df = pd.DataFrame(keywords)
df

作者图片

该包将返回与关键字相关的前 5 个趋势。

27.视力

visions 是一个用于语义数据分析的 python 包。该包可以检测数据帧类型,并推断该列的数据应该是什么。它旨在自动化数据推断并降低工作复杂性。让我们从安装包开始。

pip install visions

然后,我们可以使用下面的代码通过 visions 来检测 dataframe 中的列数据类型。我会使用来自 seaborn 的泰坦尼克号数据集。

import seaborn as sns
from visions.functional import detect_type, infer_type
from visions.typesets import CompleteSet
df = sns.load_dataset('titanic')
typeset = CompleteSet()# Inference works well even if we monkey with the data, say by converting everything to strings
print(detect_type(df, typeset))

作者图片

28.日程安排

Schedule 是一个 python 包,为任何代码创建作业调度功能。它的设计是为了方便用户在你可以设置的重复时间里安排他们想要的任何事情。让我们从安装包开始。

pip install schedule

例如,我想打印出我每 10 秒钟工作一次。然后我会用下面的代码来做这件事。

import schedule
import timedef job():
    print("I'm working...")schedule.every(10).seconds.do(job)while True:
    schedule.run_pending()
    time.sleep(1)

作者图片

29.自动更正

自动更正是一个 python 包,用于许多语言中的文本拼写更正。这种用法很简单,但对数据清理过程非常有用。让我们从安装包开始。

pip install autocorrect

然后我们可以使用类似于下面代码的自动更正包。

from autocorrect import Speller
spell = Speller()
spell("I'm not sleaspy and tehre is no place I'm giong to.")

作者图片

30.funcy

funcy 是一个 python 包,其中充满了日常数据分析使用的奇特实用函数。软件包中的函数太多了,我无法一一展示,还有一个备忘单可以让它变得更简单。让我们从安装包开始。

pip install funcy

我将只展示一个从 iterable 变量中选择偶数的示例函数,如下面的代码所示。

from funcy import select, even
select(even, {i for i in range (20)})

作者图片

31.冰淇淋

IceCream 是一个 python 包,用于打印目的,但使调试过程更容易。基本上,这个包在打印/记录过程中提供了稍微详细一点的输出。

为了使用这个包,我们需要使用下面的代码来安装它。

pip install icecream

然后我们可以用下面的代码来使用这个包。

from icecream import icdef some_function(i):
    i = 4 + (1 * 2)/ 10 
    return i + 35ic(some_function(121))

作者图片

该函数也可以用作函数检查器。

def foo():
    ic()

    if some_function(12):
        ic()
    else:
        ic()foo()

作者图片

对于我们所做的任何数据分析来说,详细程度都是非常好的。

结论

在本文中,我们研究了 31 个独特的 python 包,它们在数据工作流中很有用。大多数软件包易于使用且简单明了,但有些可能需要进一步阅读。

希望有帮助!

访问我的 社交媒体进行更深入的交谈或有任何问题。

如果您不是作为中等会员订阅,请考虑通过 我的推荐 订阅。

33 个对日常列表问题有用的 Python 片段

原文:https://towardsdatascience.com/33-useful-python-snippets-for-everyday-problems-with-lists-447b9348d2d3

UnsplashAltumCode 拍摄的照片

无论你在哪个项目中工作,都有可能到处使用列表。

在 Python 中可以做很多事情,尤其是在列表方面。

因此,你需要基本上对你能用它们做的许多事情有一个相当好的理解。

这篇文章的目的是告诉你在 Python 中使用列表的技巧。

这个列表并不详尽,我相信还有很多技巧可以包含在这里。

事不宜迟,让我们开始吧…

1.使用命名变量从列表中获取元素

我们可以相对容易地从列表中提取元素:

2.将列表中的值作为方法参数传递

我们可以使用符号“*”提取列表中的所有元素,如下所示:

这在我们希望将列表中的所有元素作为方法参数传递的情况下很有帮助,如下例所示:

3.获取列表中间的所有元素

在 Python 中,不必删除列表中的第一个和最后一个元素,只需使用下划线符号,它们就会被忽略:

4.列出理解

下面这个可能是最常用的方法之一,你可以看到它被用在很多项目中。

我们可以使用理解来遍历列表中的元素:

您也可以使用这种类型的字典、集合和生成器元素循环。

5.将字符串转换成字符串列表

假设您有如下输入:

您希望它是一个列表:

或者,您可能会从 API 调用中得到以下响应:

您不必花费几个小时来计算将帮助您完成工作的确切正则表达式,您可以简单地导入模块 ast ,然后调用它的方法 literal_eval :

这就是你需要做的。

现在你将得到一个列表或列表列表,如下所示:

6.列表是可变的

这意味着您可以修改列表,即使列表已经创建:

这意味着即使添加了一个元素,列表也是一样的:

7.在列表的第一个位置添加一个值

您可以使用 insert(),在列表的第一个位置添加一个元素,如下例所示:

8.快速计算满足条件的元素在列表中出现的次数

9.使用 slice()获取列表的最后 n 个元素

您还可以使用 slice() 执行其他常规切片任务,例如:

10.从列表中删除所有元素

11.合并 2 个列表

12.在一个 if 语句中使用列表中的所有元素作为多个条件

13.在一个 if 语句中至少使用一个列表元素作为多个条件

14.任何非空列表都被评估为真

15.使用“集合”中的计数器计算字符串或列表中元素的数量

16.使用计数器检查两个列表是否有相同的元素

17.根据频率对字符串或列表中的元素进行排序

默认情况下,集合模块中的计数器不会根据元素的频率对其进行排序。

18.在一行中找到列表中最频繁出现的元素

19.以字节为单位查找列表的内存使用情况

20.在一行中删除列表中的重复项

21.在列表中查找最小值

22.查找列表中的最大值

23.使用 Sort()对列表进行就地排序

24.通过使用 sorted()创建新列表来对列表进行排序

25.对列表进行反向排序

26.打乱列表中的顺序

27.查找列表中元素的总和

28.找出列表中元素的总和,并添加一个元素

29.重复一个列表 n 次

30.从列表中删除错误值

31.求元素的乘积

从 Python 3.8 开始,数学库中引入了一个 prod 函数,现在可用于查找列表中元素的乘积:

32.使用负切片反转列表

33.将字符串转换成列表

这篇文章中还可以包含更多的内容,但是我们现在就把它放在这里吧。

我希望你喜欢它,并且至少从这篇文章中学到了一个你可以立即开始使用的技巧。

三维人体扫描改善了代谢综合征的预测模型

原文:https://towardsdatascience.com/3d-body-scans-improve-predictive-models-for-metabolic-syndrome-6a05fc5aaa99

健康和医学的 3D 数据

我们使用 3D 身体扫描数据来改进代谢疾病的模型预测

摘要 TL:DR

  1. 3D 数据是高维的,可以用来构建强大的模型。
  2. 在健康模型中使用 3D 数据(3D 生物标志物)有助于改善代谢综合征状态的预测。
  3. 我们展示了另一个发表的例子,使用综合判别改进(IDI)和净重新分类指数(NRI)来评估和比较两个模型和新的生物标志物。
  4. 阅读文章

3D 扫描和健康

这些年来,三维(3D)扫描技术已经变得更便宜、更精确、更容易获得。Xbox kinect 等游戏平台包含能够捕捉 3D 身体数据的摄像头,非常容易访问。新的 iPhone 12 也有一个 3D 扫描摄像头,因此,展示了获取 3D 数据的障碍正在快速减少。因此,许多人已经开始探索强大的机器学习和深度学习模型,这些模型结合了图形和 3D 卷积等迷人的技术。在这项工作中,我们展示了如何更简单的模型可以受益于三维的适当利用。

30 秒内完成高分辨率 3D 扫描。与这种扫描不同,研究参与者穿着合身的衣服,以捕捉更准确的体型(图片由作者提供)

医疗保健和医学研究已经注意到 3D 身体扫描技术,许多人已经开始使用它来监测一个人的健康状况。这个想法是,你可以看着一个人,从视觉上对一个人的总体健康状况有一个很好的直觉。也有人认为,这种视觉直觉是一种比简单的身高和体重测量以及由这两种测量得出的身体质量指数(身体质量指数)更有力的健康指标。事实上,我目前的研究小组目前获得了美国国立卫生研究院(NIH)的拨款,以研究 2D 和 3D 体型如何与代谢疾病、癌症和整体健康状况相关联。我们发现,3D 扫描是一种强大、全面、信息密集的健康数据,易于获取。在这项工作中,我们观察了 3D 扫描仪捕捉到的体形如何帮助我们更好地预测某人是否患有代谢综合征。

什么是代谢综合征

代谢综合征(MetS)在美国三分之一的成年人中流行,并在下面的文本中定义,但表格可能更容易阅读。基本上,如果三个或更多的测量值符合标准,那么这个人患有代谢综合征。患有代谢综合征的人患心脏病的风险更高,全因死亡率也更高。好消息是,一个人有能力通过修改上表中的任何测量值来改变他们的代谢综合征状态,干预越早,结果越好。

使用 2005 年国家胆固醇教育计划成人治疗小组 III (NCEP ATP III)指南将代谢综合征定义为具有≥3 个以下特征:高腰围(通过人工人体测量测量;男性≥102 cm,女性≥88 cm),甘油三酯升高(≥150 mg/dL),血压升高(≥130 mm Hg 收缩压或≥85 mm Hg 舒张压),空腹血糖升高(≥100 mg/dL),和/或 HDL-C 降低(< 40 mg/dL in men, <50 mg/dL in women). (Image by author)

使用 3D 数据改善代谢综合征模型

除了腰围和血压之外,其他测量数据更难获得,需要抽血。因此,使用可获得的测量方法建立一个模型来预测代谢综合征状态将是有益的。身体质量指数是一种容易获得的常用测量方法;然而,我们认为它是有限的。我们也相信(或假设)3D 扫描能提供更多信息,而且同样容易获得。

作者图片

3D 扫描系统产生一个人的 3D 网格,并且还报告所有的 3D 人体测量值,包括腰围、体积以及腰、臂和腿的表面积等等。周长测量可以用卷尺手动获得,但是收集所有区域需要更多的时间。因此,在临床上,如果有的话,通常只收集腰围。使用逻辑回归和可获得的患者数据,而不是血液标志物,建立了几个模型来预测代谢综合征。最佳模型利用身体质量指数、年龄、性别、种族和 3D 数据预测代谢综合征,AUC 为 0.92。我们的结果表明,可以使用更容易获得的数据建立代谢综合征预测模型,而不需要抽血。我们还表明,身体质量指数是相当有限的,增加容易获得的三维数据大大提高了模型的性能。

进一步证明了身体质量指数的局限性

下面是年龄相仿、身体质量指数相同的亚洲女性的 3D 扫描图。然而,当我们看扫描时,我们可以看到身体质量指数没有解释的体型差异。从 3D 数据中,你可以看到清晰度、脂肪分布、肌肉张力等方面的差异。此外,左边的女性有代谢综合征,而右边的女性没有,当你看 3D 扫描时,这在一定程度上是有意义的。它最终比身体质量指数一个人的信息量更大。

两位年龄相似、体重指数相同(身体质量指数)的参与者,但一位患有代谢综合征(左),一位没有(右)。(图片由作者提供)

综合歧视改善(IDI)和净重新分类(NRI)

综合判别改进(IDI)和净重新分类(NRI)对于比较模型和使用新的生物标志物是有用的。在这种情况下,我们从三维身体扫描数据中寻找三维生物标志物。我有一个以前的帖子/教程,演示了如何使用 python 计算它。

作者图片

我们再次使用这些图来显示包含 3D 数据的模型如何改进仅使用身体质量指数的模型。添加 3D 数据导致综合灵敏度和综合特异性分别为 21.35 和 4.58,表明灵敏度和特异性均有提高。使用 Youden 方法计算的阈值,代谢综合征和非代谢综合征的净再分类指数分别为 9%和 8%。这意味着利用 3D 数据,该模型能够正确地识别出 9%以上患有代谢综合征的个体,而身体质量指数模型仅遗漏了这些个体。这也意味着,使用 3D 数据,该模型能够比仅使用身体质量指数的模型多正确识别出 8%的未患代谢综合征的个体,这些个体被错误地识别为患有代谢综合征。

更多资源:

在这里看报纸

关于 AUC、IDI 和 NRI 的教程和更多信息

https://www.lambertleong.com/thoughts/AUC-IDI-NRI#idi_plot https://github.com/LambertLeong/AUC_NRI_IDI_python_functions

发表 IDI 的例子

https://www.nature.com/articles/s43856-021-00024-0#Fig3

资助和研究数据请求

https://shapeup.shepherdresearchlab.org/

使用 Python 中的 UV 纹理映射实现 3D 地球可视化

原文:https://towardsdatascience.com/3d-earth-visualisation-with-uv-texture-mapping-in-python-201c92aa177a

使用 NumPy 和 PyVista 的纹理映射绘制真实的地球

介绍

许多数据科学工程项目从引人入胜的可视化中获益。生成动态图表能够实现更好的理解和数据通信,以及其他好处。

互动视觉具有巨大优势的一个领域是轨迹绘制,适用于轨道力学 两体问题 等主题。

Juliana Kozoski 在 Unsplash 上拍摄的照片

应用

在成功应用数值积分技术求解运动方程后,可以使用 Matplotlib 为两体问题创建动态 3D 绘图。然而,Matplotlib 的一个缺点是它使用了 2D 渲染器。因此,有其他选项可以产生更好的 3D 输出。

https://levelup.gitconnected.com/the-two-body-problem-in-python-6bbe4a0b2f88

图 1 描绘了两个物体的运动,这仅仅是由于它们相互的重力吸引的影响。

使用 Matplotlib 而不是简单地制作点质量的动画,拥有一个行星体纹理显著增强图形。

图 1——惯性空间中的两体问题运动(图片由作者提供)

纹理映射

纹理映射 逼真的图案或图像转换到计算机模型上。以图 2 为例平地地图。

UV 贴图 这个 2D 图像投射到 3D 模型的表面。该过程将图像像素分配给模型上的表面区域。

图 2——蓝色大理石 Nasa 纹理图(来源: NASA )

可视化工具包【VTK】是为 3D 计算机图形、图像处理和数据可视化而设计的软件。 PyVista 是一个 3D 绘图网格分析 Python 库,作为 VTK 的流线型接口。

使用 Gist 1 在 PyVista 中创建一个球体同样简单。执行下面的代码会得到如图 3 所示的结果。

要点 1 —在 PyVista 中创建球体

在 Matplotlib 中执行这个过程是可能的。然而,使用 PyVista 会给出更加真实的图像。

图 3 — PyVista 球体(图片由作者提供)

球形 UV 贴图的相关方程在维基百科上,使得该过程易于实现。等式 1 和 2 确定了在 3D 图像上正确显示 2D 图案的坐标。

等式 1 和 2 —紫外线坐标(图片由作者提供)

dₓ、dᵧ和 dᶻ是从 3D 球形模型的中心到其表面上的一点的笛卡尔位置

结果

图 4 是用 PyVista 和蓝色大理石 NASA jpeg 制作的 3D 纹理映射地球 T21 动画。

gif 帧率相对较高,文件大小大幅压缩以满足 Medium 的 25 图片上传限制。因此,实际结果在桌面上会更好,它显示为一个标准的交互式 Python 窗口。

图 4-纹理映射地球的模拟结果(图片由作者提供)

结论

PyVista 提供了更新网格值和重绘图形的函数。因此,根据 3D 现实建模的结果,下一步是将其纳入轨道力学模拟的代码中,并尝试重新生成图 1 的 gif。

探索 PyVista 文档中关于地理数据的其他独特例子。

如果你对 Python、工程学和数据科学感兴趣,可以看看我的其他文章。

https://medium.com/@andrewdaviesul/membership

参考

【1】Python 贴图图像到 3D 球体—stack overflow
【2】UV 贴图— 维基
【3】为什么是 PyVista?— PyVista 文档

3D 机器学习 201 指南:点云语义分割

原文:https://towardsdatascience.com/3d-machine-learning-course-point-cloud-semantic-segmentation-9b32618ca5df

完整的 python 教程,为非结构化 3D 激光雷达点云数据的语义分割创建监督学习 AI 系统

3D 机器学习教程:如何开发 3D LiDAR 点云数据的语义分割框架。F. Poux

拥有攻击点云处理的每个方面的技能和知识打开了许多想法和开发的大门。🤖它就像是 3D 研究创造力和开发灵活性的工具箱。核心是这个不可思议的人工智能空间,目标是 3D 场景理解。🏡

由于其对许多应用的重要性,如自动驾驶汽车、自主机器人、3D 地图、虚拟现实和元宇宙,它尤其相关。如果你是一个像我一样的自动化极客,你很难抗拒拥有新的路径来应对这些挑战的诱惑!

本教程的目的是给你我认为必要的立足点:开发三维点云语义分割系统的知识和代码技巧。

但实际上,我们如何应用语义分割呢?而 3D 机器学习的挑战性有多大?

让我介绍一个清晰、深入的 201 动手课程,重点是 3D 机器学习。在本教程中,我将详细介绍什么是 3D 机器学习,以及我们如何利用高效的 python 代码来为非结构化的 3D 点云生成语义预测。

Table of Contents[3D Scene Perception](#bba3)
✔️ 3D Sensors
✔️ 3D Scene Understanding
✔️ Classification[Semantics Addition Methods for 3D data](#92f1)
✔️ 3D Object Detection
✔️ 3D Semantic Segmentation
✔️ 3D Instance Segmentation[3D Predictions with Supervised learning](#ca39)[3D Python Workflow](#866a)
✔️ Step 1: Definition and Data Curation
✔️ Step 2\. Environment Set-up
✔️ Step 3\. 3D Feature Engineering
✔️ Step 4\. 3D Machine Learning
✔️ Step 5\. Performance Analysis[Conclusion](#b1fe)

让我们开始吧!🤿

三维场景感知:人工智能前言

由于 3D 捕获数据的复杂性质,在激光雷达(代表光探测和测距)中识别 3D 对象是一个巨大的挑战。通过 3D 扫描技术获得的原始点云是非结构化的、未精炼的、无序的,并且易于不规则采样,使得 3D 场景理解任务具有挑战性。那么,我们该怎么办呢?到底可行不可行?哈,这就是我们喜欢的!真正的挑战!😉

一个 3D 场景理解表示的示例,它将不同房屋的知识结合在一个相关的本地上下文中。F. Poux

👀3D 传感器

让我们从系统的输入开始。3D 传感器(激光雷达、摄影测量、SAR、雷达和深度感应相机)将通过空间中的许多 3D 点来描述场景。然后,这些可以托管有用的信息,并使使用这些输入的机器学习系统(例如,自动驾驶汽车和机器人)能够在现实世界中运行,并创建改进的元宇宙体验。好了,我们有了来自感官信息的基本输入,接下来是什么?

🏕️三维场景理解

你猜对了:场景理解。它描述了感知、分析和解释通过一个或多个传感器观察到的 3D 场景的过程(场景甚至可以是动态的!).接下来,这个过程主要包括将来自观察场景的传感器的信号信息与我们用来理解场景的“模型”相匹配。取决于神奇的🧙‍♂️有多蓬松,这些模型将允许一个相关的“场景理解”。在低级视图上,技术是从表征场景的输入数据中提取和添加语义。这些技术有名字吗?

🦘/🐈‍⬛分类

嗯,我们在 3D 场景理解框架中经典涉及的是分类的任务。这一步的主要目标是理解输入数据并解释传感器数据的不同部分。例如,我们有一个由自主机器人或汽车收集的户外场景的点云,如高速公路。分类的目标是找出场景的主要组成部分,因此知道点云中的哪些部分是道路,哪些部分是建筑物,或者人在哪里。从这个意义上说,它是一个旨在从我们的传感器数据中提取特定语义的总体类别。从那里,我们想添加不同粒度的语义。👇

三维数据的经典语义添加方法

正如您在下面看到的,可以通过各种策略为 3D 场景添加语义。这些不一定是独立的设计,当需要时,我们经常可以依靠混合装配。

3D 机器学习方法:数据被馈送到模型,该模型将输出 3D 边界框、每个点的标签或者每个点的标签加上每个类的每个对象的实例指针。F. Poux

让我更详细地描述一下这些技术。

📦三维物体检测

第一个将包含 3D 对象检测技术。它是许多应用程序的重要组成部分。基本上,它使系统能够捕捉世界上物体的大小、方向和位置。因此,我们可以在现实世界的场景中使用这些 3D 检测,如增强现实应用程序、自动驾驶汽车或通过有限的空间/视觉线索感知世界的机器人。包含不同物体的漂亮的 3D 立方体。但是如果我们想要微调物体的轮廓呢?

🏘️ 3D 语义分割

这就是我们要用语义分割技术解决问题的地方。将语义标签分配给属于感兴趣对象的每个基本单元(即,点云中的每个点)是最具挑战性的任务之一。本质上,3D 语义分割旨在更好地描绘场景中存在对象。一个 3D 包围盒检测。因此,它意味着每个点都有语义信息。我们可以深入那里。但是仍然存在一个限制:我们不能直接处理我们攻击的每个类别(类)的不同对象。我们也有这方面的技术吗?

🏠 3D 实例分割

是啊!这就是所谓的三维实例分割。它甚至有更广泛的应用,从自主系统中的 3D 感知到绘图和数字结对中的 3D 重建。例如,我们可以想象一个库存机器人,它可以识别椅子,能够数出有多少把椅子,然后通过第四条腿抓住它们来移动它们。实现这个目标需要区分不同的语义标签以及具有相同语义标签的不同实例。我认为实例分割是巨型立体图像上的语义分割步骤😁。

既然您已经对不同输出的当前方法有了基本的理解和分类,那么问题仍然存在:我们应该遵循哪种策略来注入语义预测?🤔

有监督学习的 3D 预测

如果你还在那里,那么你已经通过了 mumble bumble 3D charabia,并准备好抓住它的单角任务。🦄我们希望提取语义信息,并将其以点云的形式注入到我们的 3D 数据中。为此,我们将深化一种策略,帮助我们从传感器中获取此类信息。我们将专注于一个算法家族,监督学习方法——与下面显示的非监督方法相反。

使用监督学习方法,我们本质上向过去的系统显示特定的分类示例。这意味着我们需要给这些例子贴上标签。为此,您有以下教程:

</3d-point-cloud-clustering-tutorial-with-k-means-and-python-c870089f3af8>

然后,我们使用场景中每个被考虑元素的标签来预测未来数据的标签。因此,目标是能够推断出尚未看到的数据,如下图所示。

监督学习工作流程。训练阶段允许获得用于预测未知数据上的标签的机器学习模型。F. Poux

但是我们如何评估经过训练的模型的表现呢?一个直观的分析就够了吗(这是一个实际的问题吗?🙃)

好吧,视觉分析——姑且称之为定性分析——只是答案的一部分。另一个大块是通过使用各种度量标准评估的定量分析,这些度量标准将突出我们方法的特定性能。它将帮助我们描述特定分类系统的工作情况,并为我们提供工具来选择不同的分类器。

而现在,(光)论结束了!让我们通过五个步骤深入了解一个有趣的 python 代码实现🤲!我推荐一个很棒的🫐碗。

1.3D 机器学习工作流定义

航空激光雷达点云数据集来源

你知道规矩吗?我们做的第一步是潜入网络,寻找一些有趣的 3D 数据!这一次,我想深挖一个法国人(抱歉我这么势利😆)找到冷冻激光雷达数据集的地方:法国国家地理研究所(IGN)。随着 LiDAR HD 活动的开展,法国开始了开放式数据采集,您可以获得法国一些地区清晰的 3D 点云!在最上面,一些有标签,使它很容易不从头开始,你会在下面的链接中找到。

https://geoservices.ign.fr/lidarhd#telechargementclassifiees

但是为了使教程简单明了,我上了上面的门户,选择了覆盖洛汉斯城(71)部分的数据,删除了地理参考信息,计算了一些额外的属性(我将在另一个教程中解释)😜),然后在我的打开数据驱动文件夹中提供。你感兴趣的数据是3DML_urban_point_cloud.xyz3DML_validation.xyz。如果你想在网上可视化,你可以跳转到 Flyvast WebGL 摘录

IGN 提供的 Louhans 市的航空激光雷达点云数据视图。左侧我们看到的是 RGB 颜色的点云,右侧是我们将研究的三个感兴趣的类别(地面、植被和建筑物)。F. Poux

整体循环策略

我建议遵循一个简单的程序,您可以快速复制来训练 3D 机器学习模型,并将其用于现实世界的应用程序,如下图所示。

3D 机器学习工作流程:点云语义分割。F. Poux 和 3D 地理数据学院

🤓 :这个策略是我在 3D 地理数据学院 主持的在线课程中的一个文档的一点摘录。本教程将涵盖步骤 4 至 8 + 10 + 11,其他步骤将在课程中深入介绍,或者通过此 支持链接 跟随其中一个教程。

2.设置我们的 3D python 上下文

在这个动手操作的点云教程中,我主要关注高效和最小的库使用。为了掌握 python,我们只用两个库来完成这一切:PandasScikitLearn。我们会创造奇迹😁。启动脚本的五行代码:

import pandas as pdfrom sklearn.model_selection import train_test_split
from sklearn.metrics import classification_reportfrom sklearn.ensemble import RandomForestClassifier
from sklearn.preprocessing import MinMaxScaler

🤓 :如你所见,我以不同的方式从库中导入函数和模块。对于熊猫,我使用 *import module* ,这样就减少了对 *import* 语句的维护。然而,当你想更多地控制一个模块的哪些项可以被访问时,我推荐使用 *from module import foo* ,这允许使用 *foo* 进行更少的输入。

不错!从那里,我建议我们相对地表达我们的路径,将包含我们的数据集的data_folderdataset名称分开,以便在运行中容易地切换:

data_folder=”../DATA/”
dataset="3DML_urban_point_cloud.xyz"

现在,我们可以使用Pandaspcd变量中快速加载数据集。因为原始文件不干净并且包含NaN值,我们将使用非常方便的dropna方法inplace来确保我们从一个只有完整行的过滤数据帧开始。然而,这意味着我们会在前进的道路上丢掉一些分数(记录的<1%),但是这一次我们对此没有意见。

pcd=pd.read_csv(data_folder+dataset,delimiter=' ')
pcd.dropna(inplace=True)

🤓 注意 :将 *inplace* 参数设置为 *True* 允许直接替换 python 对象,而不是制作 dataframe 副本。

3.特征选择和准备(步骤 4)

为了理解我们在使用机器学习框架时做了什么,你必须理解我们依赖于可变代表的特征集或特征向量。在我们的方法中,诀窍是很好地了解我们进化的环境,并创造性地设计我们认为将是我们数据中方差的优秀描述符的特征。或者至少帮助我们区分感兴趣的类别。

航空激光雷达点云训练特征集从左到右依次为:(1) RGB 颜色,(2)法线,(3)平面性,(4)垂直度,(5)全方差,(6)法线变化率。F. Poux

我决定创建另一个专注的教程,只讨论获得这些特性的准备步骤。但是为了简单起见,我已经为你计算了一堆,过滤的主要目的是与随后的语义分割任务相关。

数据帧的摘录。F. Poux

为了在坚实的基础上开始,我们将在标签之间组织我们的特征,即我们将尝试预测什么,以及特征,即我们将使用什么来进行预测。对于熊猫,我们可以通过两行代码轻松做到这一点:

labels=pcd['Classification']features=pcd[['X','Y','Z','R','G','B']]

这种数据帧结构允许在不使用数字索引的情况下快速切换到一组特定的相关特征。因此,您可以在这一步随意返回并更改features矢量集。

选择功能

特征选择是通过仅使用最相关的变量并消除数据中的噪声来减少输入模型的输入变量的方法。它是根据您试图解决的问题类型,为您的机器学习模型选择相关功能的过程。如果自动完成,这属于将机器学习应用于现实世界问题的任务自动化的 AutoML 过程。

这里有两个方向。您要么完全不受监督(例如,减少要素之间的相关性),要么以受监督的方式进行(例如,在更改要素和参数后增加模型的最终得分)。

为了简单起见,我们将通过监督方向手动调整我们当前特征向量的选择:我们将运行实验,如果结果不够好,我们将进行调整。准备好了吗?🙂

准备功能

一旦我们的初始特征向量准备好了,我们就可以开始处理了!💨或者我们可以吗?要警惕!根据我们使用的机器学习模型,我们可能会遇到一些惊喜!事实上,让我们举一个简单的例子。

假设我们选择的特征向量如下:

features=pcd[['X','Y']]

在这里,如果我们用它来训练我们的算法,那么我们会被限制在可见的范围内,例如,X 在 0 到 100 之间变化。如果经过这个范围的训练后,模型被输入了具有相似分布但不同范围的未来数据,例如 X 从 1100 到 1200,那么我们可能会得到灾难性的结果,即使它是同一个数据集,只是中间有一个平移。事实上,对于某些模型,高于 100 的 X 值可能会使模型预测出错误的值,而如果事先保证,我们会将数据转换到训练中看到的相同范围内。这些预测更有可能有意义。

我转向了特征缩放和归一化的概念。这是数据预处理阶段的一个关键部分,但我看到许多初学者忽视了这一点(损害了他们的机器学习模型)。我们不会犯的错误!💪

因为我们处在一个空间密集的环境中,避免泛化问题的一个好方法是将其简化为我们所说的最小-最大归一化。为此,我们将使用MinMaxScaler功能:

from sklearn.preprocessing import MinMaxScaler
features_scaled = MinMaxScaler().fit_transform(features)

💡 提示 :该 *MinMaxScaler()* 通过对每个特征进行缩放和平移,使其位于给定的范围内,例如 0 到 1 之间,从而对特征进行变换。如果您的数据是正态分布的,那么您可以使用 StandardScaler。

3D 机器学习培训设置

好的,我们有一个labels向量和一个合适的features向量。现在,我们需要为培训阶段做好准备。首先,我们将分割两个向量——同时保持标签和特征之间的适当索引匹配——以使用一部分用于训练机器学习模型,另一部分仅用于观察性能。我们用60%的数据进行训练,用40%的数据看表演,都是从同一个分布中随机抽取的。从scikitlearn使用train_test_split功能制作:

X_train, X_test, y_train, y_test = train_test_split(features_scaled, labels, test_size=0.4)

🤓 :我们在处理机器学习任务的数据时使用命名约定。 *X* 表示输入到模型中的特征(或数据) *y* 表示标签。每一个都根据其终结性分解为 *_train* *_test*

然后,我们通过以下方式创建一个“分类器对象”:

rf_classifier = RandomForestClassifier()

🤓 :以上分类器为随机森林分类器。简而言之,它在特征的各个子样本上拟合几个决策树分类器,并使用平均来提高预测精度和控制过拟合。引人注目的东西😁

在分类器初始化之后,我们将分类器与训练数据进行拟合,以调整其核心参数。此阶段是训练阶段,可能需要几分钟,具体取决于我们之前使用的超参数(即,定义机器学习模型架构的参数)(树的数量、深度):

rf_classifier.fit(X_train, y_train)

最后,瞧!我们有训练有素的模特!是的,就是这么简单!所以走捷径也是那么容易。😉

对于预测阶段,无论是否有标签,都需要执行以下操作:

rf_predictions = rf_classifier.predict(X_test)

然后,您可以使用下面的代码块可视化结果和差异,该代码块将创建三个子图:3D 点云数据地面实况、预测以及两者之间的差异:

fig, axs = plt.subplots(1, 3, figsize=(20,5))
axs[0].scatter(X_test['X'], X_test['Y'], c =y_test, s=0.05)
axs[0].set_title('3D Point Cloud Ground Truth')
axs[1].scatter(X_test['X'], X_test['Y'], c = rf_predictions, s=0.05)
axs[1].set_title('3D Point Cloud Predictions')
axs[2].scatter(X_test['X'], X_test['Y'], c = y_test-rf_predictions, cmap = plt.cm.rainbow, s=0.5*(y_test-rf_predictions))
axs[2].set_title('Differences')

如果您想检查一些指标,我们可以使用scikit-learnclassification_report函数打印一个带有一串数字的分类报告:

print(classification_report(y_test, rf_predictions))

但是,我们难道不应该理解每个指标的含义吗?🤔

4.3D 机器学习调整(步骤 5)

绩效和指标

我们可以使用几个量化指标来评估语义分割和分类的结果。我将向您介绍对 3D 点云语义分割评估非常有用的四个指标:精确度、召回率、F1 分数和整体准确度。它们都取决于我们所说的真正的积极和真正的消极:

  • 真阳性(TP):观察为阳性,预测为阳性。
  • 假阴性(FN):观察结果为阳性,但预测结果为阴性。
  • 真阴性(TN):观察为阴性,预测为阴性。
  • 假阳性(FP):观察为阴性,但预测为阳性。

总准确度是对关于分类器正确预测标签的性能的所有观察的一般度量。精度是分类器不将阴性样品标记为阳性的能力;召回直观上是分类器找到所有阳性样本的能力。因此,您可以将精度视为了解您的模型是否精确的一个很好的度量,而将回忆视为了解您以何种穷尽性找到每个类(或全局)的所有对象的一个很好的度量。F1 分数可以被解释为精确度和召回率的加权调和平均值,因此给出了分类器在一个数字上表现如何的良好度量。

🤓此后,在我们的实验中的 F1 分数指示了所提出的分类器的平均性能。

型号选择

是时候选择具体的 3D 机器学习模型了。对于本教程,我将选择限制在三种机器学习模型:随机森林、K 近邻和属于深度学习类别的多层感知器。为了使用它们,我们将首先导入以下必要的函数:

from sklearn.neighbors import RandomForestClassifier
rf_classifier = RandomForestClassifier()from sklearn.neighbors import KNeighborsClassifier
knn_classifier = KNeighborsClassifier()from sklearn.neural_network import MLPClassifier
mlp_classifier = MLPClassifier(solver='lbfgs', alpha=1e-5,hidden_layer_sizes=(15, 2), random_state=1)

然后,您只需用想要的算法堆栈替换下面代码块中的XXXClassifier():

XXX_classifier = XXXClassifier()
XXX_classifier.fit(X_train, y_train)
XXX_predictions = XXXclassifier.predict(X_test)
print(classification_report(y_test, XXX_predictions, target_names=['ground','vegetation','buildings']))

🤓注意 :为了简单起见,我将对应于地面、植被和建筑物的树类列表传递给了 *classification_report*

现在,进入使用上述三个分类器的测试阶段,参数如下:

Train / Test Data: 60%/40% 
Number of Point in the test set: 1 351 791 / 3 379 477 pts
Features selected: ['X','Y','Z','R','G','B'] - With Normalization

随机森林

我们从随机森林开始。某种神奇的树魔法,通过一个集合算法将多个决策树结合起来,给我们一个最终的结果:基于对1.3 million points的支持,总体精度为98%。它进一步分解如下:

╔════════════╦══════════════╦══════════╦════════════╦═════════╗
║  classes   ║    precision ║   recall ║   f1-score ║ support ║
╠════════════╬══════════════╬══════════╬════════════╬═════════╣
║ ground     ║         0.99 ║     1.00 ║       1.00 ║  690670 ║
║ vegetation ║         0.97 ║     0.98 ║       0.98 ║  428324 ║
║ buildings  ║         0.97 ║     0.94 ║       0.96 ║  232797 ║
╚════════════╩══════════════╩══════════╩════════════╩═════════╝

3D 航空激光雷达点云上监督机器学习随机森林方法的结果。F. Poux

🤓 :这里不多说什么,与其说它提供了令人印象深刻的结果。地面点几乎被完美分类: *1.00* 召回意味着所有属于地面的点都被找到, *0.99* 精确意味着仍有微小的改进余地,以确保没有假阳性。Auqlitqtivelym ze 注意到错误分布在各处,如果必须手动纠正,这可能会有问题。

K-NN

K-最近邻分类器使用邻近度来预测单个数据点分组。我们获得了 91%的全局准确度,进一步分解如下:

╔════════════╦══════════════╦══════════╦════════════╦═════════╗
║  classes   ║    precision ║   recall ║   f1-score ║ support ║
╠════════════╬══════════════╬══════════╬════════════╬═════════╣
║ ground     ║         0.92 ║     0.90 ║       0.91 ║  690670 ║
║ vegetation ║         0.88 ║     0.91 ║       0.90 ║  428324 ║
║ buildings  ║         0.92 ║     0.92 ║       0.92 ║  232797 ║
╚════════════╩══════════════╩══════════╩════════════╩═════════╝

有监督的机器学习 K 最近邻方法在 3D 航空激光雷达点云上的结果。F. Poux

🤓 :结果低于随机森林,这是意料之中的,因为我们在当前向量空间中更容易受到局部噪声的影响。我们在所有的类上有一个同质的精度/召回平衡,这是一个好的迹象,表明我们避免了过度拟合问题。至少在目前的分布中是这样😁。

采用多层感知器的 3D 深度学习

多层感知器(MLP)是一种学习线性和非线性数据关系的神经网络算法。MLP 需要调整几个超参数,如隐藏神经元的数量、层数和迭代次数,这使得很难获得开箱即用的高性能。例如,使用超参数集,我们有一个全局精度64%,进一步分解如下:

╔════════════╦══════════════╦══════════╦════════════╦═════════╗
║  classes   ║    precision ║   recall ║   f1-score ║ support ║
╠════════════╬══════════════╬══════════╬════════════╬═════════╣
║ ground     ║         0.63 ║     0.76 ║       0.69 ║  690670 ║
║ vegetation ║         0.69 ║     0.74 ║       0.71 ║  428324 ║
║ buildings  ║         0.50 ║     0.13 ║       0.20 ║  232797 ║
╚════════════╩══════════════╩══════════╩════════════╩═════════╝

监督深度学习 MLP 方法在 3D 航空激光雷达点云上的结果。F. Poux

🤓 :MLP 指标故意提供了一个被认为是糟糕指标的好例子。我们的准确率低于 75%,这通常是衡量目标的第一手指标,然后我们看到内部和内部类别之间的显著差异。值得注意的是,buildings 类还远远不够健壮,我们可能会有一个过度适应的问题。从视觉上来说,也发现了这一点,因为我们可以看到,这是关于深度学习模型的混乱的主要来源。

在这一步,我们不会通过特性选择来改进,但是我们总是有这种可能性。在这一步,我们决定采用性能最好的模型,即随机森林方法。现在,我们必须调查当前训练的模型在挑战看不见的场景下是否表现良好,准备好了吗?😄

5.3D 机器学习性能:走向一般化

现在事情变得棘手了。看着上面我们所拥有的,如果我们想要将当前的模型扩展到扩展当前样本数据集范围的真实世界应用程序,我们可能会遇到巨大的麻烦。因此,让我们进入该模型的全面部署。

验证数据集

这是一个关键的概念,我建议,以确保避免过度拟合问题。我认为,与其只使用来自同一分布的训练数据集和测试数据集,不如使用另一个具有不同特征的未知数据集来衡量现实世界的性能,这一点至关重要。因此,我们有:

  • 训练数据:用于拟合模型的数据样本。
  • 测试数据:用于提供模型无偏评估的数据样本,该模型符合训练数据,但用于调整模型超参数和特征向量。因此,当我们用它来调整输入参数时,评估变得有点偏差。
  • 验证数据:不相关的数据样本用于提供与训练数据相匹配的最终模型的无偏评估。

构成验证数据的 3D 点云的视觉渲染。它是从 Manosque 市上空的航空激光雷达 IGN HD 战役中捕获的(04)。它呈现出不同的语境和对象特征。F. Poux

以下是一些附加的澄清说明:

  • 测试数据集也可以在其他形式的模型准备中发挥作用,例如特征选择。
  • 最终的模型可以符合训练和验证数据集的集合,但我们决定不这样做。

所选的验证数据来自 Manosque 市(04),该市呈现了不同的城市环境,例如,不同的地形和大不相同的城市环境,如下所示。这样,我们增加了应对泛化的挑战😆。

左边是我们在测试端训练和评估的数据集(40%不可见)。在右边,您有一个不同的验证数据集,这将是我们的模型给出的真实世界可能性的一个重要标志。

您可以从我的打开的数据驱动器文件夹中下载3DML_validation.xyz数据集(如果尚未下载的话)。正如下面所解释的,您还可以找到标签来研究我所做的不同迭代的度量和潜在收益。

改善概化结果

我们的目标是检查验证数据集的结果,看看我们是否忽略了一些可能性。

首先,我们用以下三行代码在脚本中导入验证数据:

val_dataset="3DML_validation.xyz"
val_pcd=pd.read_csv(data_folder+dataset,delimiter=' ')
val_pcd.dropna(inplace=True)

然后,我们准备特征向量以具有与用于训练模型的特征相同的特征:不多也不少。我们进一步归一化我们的特征向量,使其处于与我们的训练数据相同的条件下。

val_labels=val_pcd['Classification']
val_features=val_pcd[['X','Y','Z','R','G','B']]
val_features_scaled = MinMaxScaler().fit_transform(val_features)

然后,我们将已经训练好的模型应用于验证数据,并打印结果:

val_predictions = rf_classifier.predict(val_features_scaled)
print(classification_report(val_labels, val_predictions, target_names=['ground','vegetation','buildings']))

这就给我们留下了验证数据集中存在的3.1 million点的最终精度为54%(相对于包含1.3 million点的测试数据的98%)。它分解如下:

╔════════════╦══════════════╦══════════╦════════════╦═════════╗
║  classes   ║    precision ║   recall ║   f1-score ║ support ║
╠════════════╬══════════════╬══════════╬════════════╬═════════╣
║ ground     ║         0.65 ║     0.16 ║       0.25 ║ 1188768 ║
║ vegetation ║         0.59 ║     0.85 ║       0.70 ║ 1315231 ║
║ buildings  ║         0.43 ║     0.67 ║       0.53 ║  613317 ║
╚════════════╩══════════════╩══════════╩════════════╩═════════╝

验证点云数据集上随机森林分类器的定性结果。只有空间坐标和 R、G、B 通道被用作输入特征。F. Poux

你刚刚见证了机器学习的真正黑暗面:使模型过度适应样本分布,并且在推广方面有巨大的困难。因为我们已经确保对数据进行了规范化,所以我们可以调查这种低性能行为可能是由于功能不够独特造成的。我的意思是,我们使用了一些最常见/最基本的功能。因此,让我们通过更好的功能选择来进行改进,例如,下面的功能选择:

features=pcd[['Z','R','G','B','omnivariance_2','normal_cr_2','NumberOfReturns','planarity_2','omnivariance_1','verticality_1']]val_features=val_pcd[['Z','R','G','B','omnivariance_2','normal_cr_2','NumberOfReturns','planarity_2','omnivariance_1','verticality_1']]

很好,我们现在重新开始测试数据的训练阶段,我们检查模型的性能,然后检查它在验证数据集上的表现:

features_scaled = MinMaxScaler().fit_transform(features)
X_train, X_test, y_train, y_test = train_test_split(features_scaled, labels, test_size=0.3)
rf_classifier = RandomForestClassifier(n_estimators = 10)
rf_classifier.fit(X_train, y_train)
rf_predictions = rf_classifier.predict(X_test)
print(classification_report(y_test, rf_predictions, target_names=['ground','vegetation','buildings']))val_features_scaled = MinMaxScaler().fit_transform(val_features)
val_rf_predictions = rf_classifier.predict(val_features_scaled)
print(classification_report(val_labels, val_rf_predictions, target_names=['ground','vegetation','buildings']))

让我们研究一下结果。我们现在对测试数据有 97%的准确率,进一步分解如下:

╔════════════╦══════════════╦══════════╦════════════╦═════════╗
║  classes   ║    precision ║   recall ║   f1-score ║ support ║
╠════════════╬══════════════╬══════════╬════════════╬═════════╣
║ ground     ║         0.97 ║     0.98 ║       0.98 ║  518973 ║
║ vegetation ║         0.97 ║     0.98 ║       0.97 ║  319808 ║
║ buildings  ║         0.95 ║     0.91 ║       0.93 ║  175063 ║
╚════════════╩══════════════╩══════════╩════════════╩═════════╝

与只使用基本的X, Y, Z, R, G, B集合相比,添加特性会导致性能略微下降,这表明我们添加了一些噪声。但是为了一般化,这是值得的!我们现在在验证集上有 85%的全局准确率,所以仅通过特征选择就提高了 31%!它是巨大的。正如你所注意到的,建筑是影响表演的主要因素。这主要是因为它们与测试集中的特征非常不同,并且特征集不能在不相关的上下文中真实地表示它们。

╔════════════╦══════════════╦══════════╦════════════╦═════════╗
║  classes   ║    precision ║   recall ║   f1-score ║ support ║
╠════════════╬══════════════╬══════════╬════════════╬═════════╣
║ ground     ║         0.89 ║     0.81 ║       0.85 ║ 1188768 ║
║ vegetation ║         0.92 ║     0.92 ║       0.92 ║ 1315231 ║
║ buildings  ║         0.68 ║     0.80 ║       0.73 ║  613317 ║
╚════════════╩══════════════╩══════════╩════════════╩═════════╝

验证点云数据集上随机森林分类器的定性结果。选择了一个功能集。F. Poux

这非常非常好!我们现在有一个比你能找到的大多数模型都要好的模型,甚至使用深度学习架构!

假设我们想扩大规模。在这种情况下,从验证分布中注入一些数据来检查这是否是模型中所需要的可能是有趣的,代价是我们的验证失去了它的地位,成为测试集的一部分。我们采用 10%的验证数据集和 60%的初始数据集来训练随机森林模型。然后,我们使用它并检查构成测试数据的其余 40%的结果,以及验证数据的 90%的结果:

val_labels=val_pcd['Classification']
val_features=val_pcd[['Z','R','G','B','omnivariance_2','normal_cr_2','NumberOfReturns','planarity_2','omnivariance_1','verticality_1']]
val_features_sampled, val_features_test, val_labels_sampled, val_labels_test = train_test_split(val_features, val_labels, test_size=0.9)
val_features_scaled_sample = MinMaxScaler().fit_transform(val_features_test)labels=pd.concat([pcd['Classification'],val_labels_sampled])
features=pd.concat([pcd[['Z','R','G','B','omnivariance_2','normal_cr_2','NumberOfReturns','planarity_2','omnivariance_1','verticality_1']],val_features_sampled])
features_scaled = MinMaxScaler().fit_transform(features)
X_train, X_test, y_train, y_test = train_test_split(features_scaled, labels, test_size=0.4)rf_classifier = RandomForestClassifier(n_estimators = 10)
rf_classifier.fit(X_train, y_train)
rf_predictions = rf_classifier.predict(X_test)
print(classification_report(y_test, rf_predictions, target_names=['ground','vegetation','buildings']))val_rf_predictions_90 = rf_classifier.predict(val_features_scaled_sample)
print(classification_report(val_labels_test, val_rf_predictions_90, target_names=['ground','vegetation','buildings']))

令我们非常高兴的是,我们看到,在测试集上,我们的指标至少下降了 5%,而损失只有 1%,因此,代价是最小的特征噪声,如下所示:

40% Test Predicitions - Accuracy = 0.96    1476484

╔════════════╦══════════════╦══════════╦════════════╦═════════╗
║  classes   ║    precision ║   recall ║   f1-score ║ support ║
╠════════════╬══════════════╬══════════╬════════════╬═════════╣
║ ground     ║         0.97 ║     0.98 ║       0.97 ║  737270 ║
║ vegetation ║         0.97 ║     0.97 ║       0.97 ║  481408 ║
║ buildings  ║         0.94 ║     0.90 ║       0.95 ║  257806 ║
╚════════════╩══════════════╩══════════╩════════════╩═════════╝90% Validation Predicitions - Accuracy = 0.90    2805585╔════════════╦══════════════╦══════════╦════════════╦═════════╗
║  classes   ║    precision ║   recall ║   f1-score ║ support ║
╠════════════╬══════════════╬══════════╬════════════╬═════════╣
║ ground     ║         0.88 ║     0.92 ║       0.90 ║  237194 ║
║ vegetation ║         0.93 ║     0.94 ║       0.94 ║  263364 ║
║ buildings  ║         0.87 ║     0.79 ║       0.83 ║  122906 ║
╚════════════╩══════════════╩══════════╩════════════╩═════════╝

验证点云数据集上随机森林分类器的定性结果。来自验证的一些数据被用于训练。F. Poux

通常有趣的是用不同的模型和相同的参数检查最终结果,然后经历超参数调整的最后阶段。但那是以后的事了😉。你不累吗?我认为我们的大脑能量需要充电;让我们把其余的留到另一个时间来完成这个项目。😁

导出带标签的数据集

标题说明了一切:是时候导出结果,以便在另一个应用程序中使用它们了。让我们用下面几行将它导出为 Ascii 文件:

val_pcd['predictions']=val_rf_predictions
result_folder="../DATA/RESULTS/"
val_pcd[['X','Y','Z','R','G','B','predictions']].to_csv(result_folder+dataset.split(".")[0]+"_result_final.xyz", index=None, sep=';')

放大点云语义分割机器学习工作流的最终结果。从左至右:地面真相,红色差异,预测。F. Poux

导出 3D 机器学习模型

当然,如果您对您的模型满意,您可以永久保存它,然后将其放在某个地方,用于生产中不可见/未标记的数据集。我们可以使用 pickle 模块来做到这一点。三行代码:

import pickle
pickle.dump(rf_classifier, open(result_folder+"urban_classifier.poux", 'wb'))

当您需要重用模型时:

model_name="urban_classifier.poux"
loaded_model = pickle.load(open(result_folder+model_name, 'rb'))
predictions = loaded_model.predict(data_to_predict)
print(classification_report(y_test, loaded_predictions, target_names=['ground','vegetation','buildings']))

你可以用这个 Google Colab 笔记本直接在你的浏览器中访问完整的代码。

结论

那是一次疯狂的旅行!完整的 201 课程,带 3D 机器学习动手教程!😁您学到了很多东西,尤其是如何导入具有特征的点云,选择、训练和调整受监督的 3D 机器学习模型,并将其导出以检测户外课程,从而出色地概括到大型航空点云数据集!热烈祝贺!但这只是 3D 机器学习等式的一部分。为了扩展学习之旅的成果,未来的文章将深入探讨语义和实例分割[2–4],动画和深度学习[1]。我们将研究如何管理大点云数据,如下文所述。

我的贡献旨在浓缩可操作的信息,以便您可以从零开始为您的项目构建 3D 自动化系统。你可以从参加地理数据学院的课程开始。

参考

  1. Poux,F. ,& J.-J Ponciano。(2020).三维室内点云实例分割的自学习本体。 ISPRS Int。拱门。Pho 的。&雷姆。B2,309–316;https://doi . org/10.5194/ISPRS-archives-XLIII-B2–2020–309–2020

  2. Poux,F. ,& Billen,R. (2019)。基于体素的三维点云语义分割:无监督的几何和关系特征与深度学习方法。 ISPRS 国际地理信息杂志。8(5), 213;https://doi.org/10.3390/ijgi8050213

  3. Poux,F. ,纽维尔,r .,纽约,g .-a .&比伦,R. (2018)。三维点云语义建模:室内空间和家具的集成框架。遥感10 (9),1412。https://doi.org/10.3390/rs10091412

  4. Poux,F. ,Neuville,r .,Van Wersch,l .,Nys,g .-a .&Billen,R. (2017)。考古学中的 3D 点云:应用于准平面物体的获取、处理和知识整合的进展。地学7 (4),96。https://doi.org/10.3390/GEOSCIENCES7040096

基于 RANSAC 和 Python 的点云三维模型拟合

原文:https://towardsdatascience.com/3d-model-fitting-for-point-clouds-with-ransac-and-python-2ab87d5fd363

3D Python

无监督三维点云二元分割的线性模型创建、检测和拟合的 5 步指南:RANSAC 从头实现。

点云好玩!现在,让我们试着理解这个模糊的集合。弗·普克斯。我获得了研究员办公桌,ADAS 激光雷达来自威力登传感器,操场是由 Emm 用 Everypoint.io 生成的(场景)。

你有没有想过为什么我们会在周围的世界中发现如此多的几何图形?不,你没有?好消息,这意味着你是理智的。我倾向于对生活和事物有奇怪的疑问🙃。我觉得它非常迷人,尤其是❄️薄片的对称奇迹,美味中的基本形状🍈、或遗产设计🕌图案的奇迹。

我们的世界充满了不同的几何风味。但是如果你环顾四周,我打赌你至少能找到五个简单的几何图形。我们注意到,我们发现的大多数形状都可以与几何图元联系起来,如平面、金字塔、圆柱体、立方体和球体。这是一个引人注目的观察结果;为什么?

让我们假设我们可以捕捉并数字化我们真实世界环境的细节。在这些 3D 数字复制品中检测组成场景的形状并将其用作语义提取层会不会很方便?做模特吗?为了场景理解?

哈哈,准确的说!在本教程中,我会给你一个快速的方法来定义三维平面,并使用它们作为基础来划分三维点云。

本教程涵盖了整个工作流程。我们获取一个点云场景,我们将使用随机样本一致性方法对其进行分割。F. Poux

为此,我们将介绍一个健壮的算法,并从头开始实现它:RANSAC!你准备好了吗?让我们开始吧!

步骤 0。战略

在直截了当地用一个有效的解决方案来处理这个项目之前,让我们先设计一个总体方案。本教程遵循由五个简单步骤组成的策略,如下图所示。

基于 RANSAC 平面模型拟合的点云二值分割策略图。F. Poux

首先,(1)我们在我与你分享的三个数据集中选择了一个点云数据集。然后,(2)在数据中选择一个几何模型进行检测。(3)研究了推广参数的定义。(4)我们将这三种成分与 RANSAC 配方混合在一起,(5)我们分割我们的点云:瞧!一个精心制作的点云!该战略已经制定,您可以在下面找到这些步骤的快速链接:

Step 1\. The Point Cloud Data
Step 2\. Geometric Model Selection
Step 3\. Parameter's Definition
Step 4\. RANSAC Model Fitting (from scratch)
Step 5\. Point Cloud Binary SegmentationPerspectives & Conclusion

现在我们已经设置好了,让我们直接开始吧。

第一步。点云数据

好了,我们走吧。我们将设计一个容易扩展到不同用例的方法。出于这个目的,不是一个而是三个数据集,你可以从中选择,下载,并做你的科学实验😁。选择这些来说明三种不同的场景,并提供基本的数据。多酷啊,匈奴?

这一集中可用的不同点云可以直接在提供的链接下载:研究员桌(。xyz),汽车(。xyz)、操场(。xyz)。操场是 Emm 用 Everypoint.io 生成的(场景)。F. Poux

我们想要展示的场景如下:

  • 🤖机器人:我们正在设计一个机器人,它需要清洁地面和桌子,并确保在清洁时避开障碍物。最重要的是,我们希望检测感兴趣的元素的位置,并将其作为未来清理任务的基础,以了解我们最初是否需要重新定位它们。
  • 🚙ADAS(高级驾驶辅助系统):在这里,我们感兴趣的是让车辆能够自己驾驶:一辆自动驾驶的车辆。为此目的,我们使用威力登 VLP-16 扫描的一个时期,在此期间我们通常进行实时分析以检测目标。
  • 🏚️建筑公司:几年前建造的一个操场由于地基不稳定出现了问题。因此,我们希望评估元素的平面度,并确定是否有必要进行调平操作。

为了确保您的选择,您可以使用 Flyvast WebGL 应用程序在线玩它们,然后在这里(研究员工作台)下载它们。,【xyz】,车子(。【xyz】,操场(。xyz) )。

https://medium.com/@florentpoux/membership

第二步。选择几何模型

在之前的一篇文章中,我们定义了 RANSAC 方法,该文章提出了自动分割和聚类:

RANSAC(随机样本一致性)是一种试错法,它将你的数据点分成两个部分:一个内部集和一个外部集。

[## 如何使用 Python 实现 3D 点云分割和聚类的自动化

towardsdatascience.com](/how-to-automate-3d-point-cloud-segmentation-and-clustering-with-python-343c9039e4f5)

为了实现这一目标,我们采取了三个简单的步骤:

  • 我们选择一个几何模型,它符合我们数据集中的一个微小的随机样本(如果我们想定义一个平面,随机选取 3 个点)。
  • 然后,我们通过检查有多少点“接近”感兴趣的表面来估计拟合的好坏,因此我们得到一个内层计数。
  • 我们在一定数量的迭代中重复这个过程,并保留使内层计数最大化的平面。

这种方法不是火箭科学,而是一种针对嘈杂的真实世界数据集的超级实用的方法。

RANSAC 通过多次迭代及其随机计算初始化来工作。来源: 如何用 Python 实现 3D 点云的自动分割和聚类 ,F. Poux

在本教程中,我们选择了:平面几何!这是快速理解大量数据集的最佳方式。但是请容忍我;我现在给你一些重要的数学理解,我们用来描述欧几里得空间中的平面。 中平面的方程的一般形式为 𝑎𝑥+𝑏𝑦+𝑐𝑧+𝑑=0

多美啊🦋。撇开笑不谈,𝑎,𝑏和𝑐常数是垂直于平面或平行于平面的任何向量的法向量-=(𝑎,𝑏,𝑐)的分量。当你掌握了这一点,玩变换(平移,旋转,缩放)并适应它是超级容易的。d 常数将使平面从原点移动。

意味着一个点 p = (𝑥,𝑦,𝑧) 属于由法向量-引导的平面,如果它满足等式。如果你理解了这一点,你就获得了指导几何拟合的第一手原理。太好了!

现在让我们用 RANSAC 到处安装飞机。

操场上的 RANSAC 飞机汤点云。这几乎是艺术,不是吗😀?F. Poux

兰萨克汤,是吗?好的,让我们定义参数使它正常工作。

第三步。参数定义

是时候弄脏我们矮小的编码者的手了!而这一次,让我们从零开始编写一个点云的 RANSAC 平面检测算法,更好地把握遮光罩下的东西。我们将用两个库来做这件事:randomnumpy。很难再简约了。为了形象化,我们亲爱的(或甜蜜的敌人😊)matplotlibplotly用于交互式 Jupyter 笔记本和 Google Colab 脚本。

import random
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits import mplot3dimport plotly.express as px

A.明智地选择数据集

你选择的武器是什么?我将把我的研究桌作为主要案例研究:

dataset="the_researcher_desk.xyz"
pcd = np.loadtxt(data_folder+dataset,skiprows=1)

然后,我通过从辐射属性中分离出几何属性来快速准备:

xyz=pcd[:,:3]
rgb=pcd[:,3:6]

好了,现在是时候设置一些参数了。

B.手动参数设置

我们需要定义一个阈值参数来确定一个点是属于拟合的平面形状(内层)还是一个离群点。我们将根据点到平面的距离来区分;因此,我们需要快速掌握点云中的单元。让我们用matplotlib显示点云:

plt.figure(figsize=(8, 5), dpi=150)
plt.scatter(xyz[:,0], xyz[:,1], c=rgb/255, s=0.05)
plt.title("Top-View")
plt.xlabel('X-axis (m)')
plt.ylabel('Y-axis (m)')
plt.show()

研究桌面点云的俯视图。F. Poux

有时,可能很难解释两点之间的区别,尤其是使用 Google Colab 和非交互式渲染。如果您在这样的场景中,您可以将plotly与 import plotly.express as px一起使用,然后您可以通过

fig = px.scatter(x=xyz[:,0], y=xyz[:,1], color=xyz[:,2])
fig.show()

左边是 plotly 点云,右边是场景的交互缩放。F. Poux

它允许我们看到,平均来说,每个5 mm都有相邻点,因此我们将阈值参数设置得高十倍(绝对是经验性的😊):threshold=0.05。同样,我们将把迭代的次数设置为一个不受限的相当大的数;让我们说1000 iterations:

iterations=1000

C.自动参数设置

我们可能有点受限,需要一些领域知识来设置阈值。因此,尝试绕过这一点向非专家开放这种方法将是令人兴奋的。我将与你分享一个可能有用的简单想法。如果我们计算数据集中各点之间的平均距离,并以此为基础设置阈值,会怎么样?

这是一个值得探索的想法。为了尝试确定这样一个值,我们可以使用一个KD-Tree来加速查询每个点的最近邻居的过程。在流程的这个阶段,我建议使用scikit-learn实现,并在每个节点将 KD 树分成两个超平面:

from sklearn.neighbors import KDTree
tree = KDTree(np.array(xyz), leaf_size=2) 

然后,我们可以使用简单的查询方法查询点云中每个点的 k-最近邻:

tree.query(xyz, k=8)

其分别输出点距离和点索引:

KD 树查询的 numpy 输出。F. Poux

🤓注意 : 最近邻的第一个距离值始终等于 *0* 。你会问奇怪吗?这是因为我们对整个点云本身进行查询;因此,每个点到自身都有一个距离。因此,我们需要过滤每行的第一个元素: nearest_dist, nearest_ind = tree.query(xyz, k=8)

太好了!现在,如果我们对每个邻居候选进行平均,用np.mean(nearest_dist[:,1:],axis=0)从最近到最远排序,我们得到:

>> array([0.0046, 0.0052 , 0.0059, 0.0067, 0.0074, 0.0081, 0.0087])

这意味着,如果我们通过考虑最近的邻居进行推理,我们将得到 4.6 mm 的平均距离。如果我们想要使用np.mean(nearest_dist[:,1:])获得每个点到其第 n 个最近邻居的平均距离的局部表示,则在我们的情况下输出6.7 mm。

为了让您的实验顺利进行,我建议设置一个查询,使用 8 到 15 个点作为邻居,并对其进行平均。因此,它给出了点云中噪声比的良好局部表示。我们将在未来的教程中探索更巧妙的方法来寻找点云的噪波比。😉

🧙‍♂️ 专家 : 有一种自动的方法每次都能得到正确的迭代次数。如果我们希望以概率 p(例如 99%)成功,我们数据中的异常值比率是 e(例如 60%),我们需要 s 点来定义我们的模型(这里是 3)。下面的公式给出了要进行的试验(迭代)次数:

第四步。RANSAC 模型拟合

A.寻找平面(1 次迭代)

让我们在自动化指定数量的迭代之前模拟一次迭代。

首先,我们要从点云中随机选取三个点:

idx_samples = random.sample(range(len(xyz)), 3)
pts = xyz[idx_samples]

然后,我们要确定平面的方程。例如,找到方程𝑎𝑥+𝑏𝑦+𝑐𝑧+𝑑=0.的参数𝑎,𝑏,𝑐和𝑑为此,我们可以玩一个奇妙的线性代数性质,即两个向量的叉积生成一个正交向量。

Z 向量是 X 和 Y 叉积的结果,这符合经验法则😀。F. Poux

因此,我们只需要从平面上的同一点定义两个向量vecAvecB,然后计算它们的法线,这将是平面的法线。多棒啊。

vecA = pts[1] - pts[0]
vecB = pts[2] - pts[0]
normal = np.cross(vecA, vecB)

从那里,我们将归一化我们的normal向量,然后得到定义向量的𝑎,𝑏和𝑐,并使用落在平面上的三个点之一找到𝑑:d =(𝑎𝑥+𝑏𝑦+𝑐𝑧)

a,b,c = normal / np.linalg.norm(normal)
d=-np.sum(normal*pts[1])

现在,我们准备开始计算我们刚刚定义的平面上任何剩余的点💪。

B.点到平面的距离:阈值定义

如果你相信我的话,下面是我们需要实现的:

点到平面的距离用上面的符号表示。点 P(见下)到给定平面的距离就是向量 w 到单位法向量 n 上的投影长度,我们知道,向量 n 的长度等于 1,点 P 到平面的距离就是向量 w 和 n 的点积的绝对值!F. Poux

这个距离是最短的,是点和平面之间的正交距离,如下图所示。

一个法线 n 定义了平面,我们可以看到我们想要计算的点到平面的 D 距离是什么样子的。F. Poux

这意味着我们可以简单地计算这个距离,只需取点云中的每个点,这些点不是我们在一次 Ransac 迭代中用来建立平面的三个点的一部分,就像这样:

distance = (a * xyz[:,0] + b * xyz[:,1] + c * xyz[:,2] + d
            ) / np.sqrt(a ** 2 + b ** 2 + c ** 2)

对于我们的随机选择和平面拟合输出:

array([-1.39510085, -1.41347083, -1.410467 , …, -0.80881761, -0.85785174, -0.81925854])

🤓注意 : 看到负值了?我们必须解决这个问题来得到无符号的距离,因为我们的法线在平面上可以翻转 180°。

非常好!从那里,我们可以对照阈值进行检查,并过滤所有符合标准的点,只保留点到平面距离在threshold以下的点作为内嵌点。

idx_candidates = np.where(np.abs(distance) <= threshold)[0]

🤓注意:[0]允许我们在这一步只处理索引,不要用不必要的点坐标溢出我们的系统。**

一次迭代的结果。在青色中,平面适合三个采样点。蓝色表示被选为内线的点,得分为 17 772。F. Poux

你已经知道下一步会是什么了吗?🤔

C.迭代和函数定义

的确,我们现在需要迭代一定的次数来找到最优平面!为此,我们将定义一个函数,该函数将输入点coordinatesthresholditerations的编号作为输入点,并返回平面equation和点inliers索引:

*def function(coordinates, threshold, iterations):
  ...
  i=1
  while i < iterations:
    do <<all below>>
    if len(idx_candidates) > len(inliers):
      equation = [a,b,c,d]
      inliers = idx_candidates
    i+=1
  return equation, inliers*

🤓注意 : 我们在迭代参数上创建 RANSAC 循环。对于每个循环,我们将计算最佳拟合 RANSAC 平面,并保留方程和内嵌索引。使用 if 语句,我们然后检查当前迭代的得分是否最大,在这种情况下,我们切换点索引。

现在,让我们填充 RANSAC 函数,得到如下结果:

*def ransac_plane(xyz, threshold=0.05, iterations=1000):
  inliers=[]
  n_points=len(xyz)
  i=1 while i<iterations:
    idx_samples = random.sample(range(n_points), 3)
    pts = xyz[idx_samples] vecA = pts[1] - pts[0]
    vecB = pts[2] - pts[0]
    normal = np.cross(vecA, vecB)
    a,b,c = normal / np.linalg.norm(normal)
    d=-np.sum(normal*pts[1]) distance = (a * xyz[:,0] + b * xyz[:,1] + c * xyz[:,2] + d
                ) / np.sqrt(a ** 2 + b ** 2 + c ** 2) idx_candidates = np.where(np.abs(distance) <= threshold)[0] if len(idx_candidates) > len(inliers):
      equation = [a,b,c,d]
      inliers = idx_candidates

    i+=1
  return equation, inliers*

在这里,我们为平面检测创建了一个 RANSAC 函数,它可以吃掉 3D 点云!!!!它以这种方式进行了充分的优化,让你可以攻击大的点云,而不会有烧毁电脑的风险🔥!现在,让我们扩展到我们想要分割点云的实际情况。

第五步。点云二值分割

这是最后一步!至少在现阶段😀。我们将在两个变量中保留函数的结果:

*eq,idx_inliers=ransac_plane(xyz,0.01)
inliers=xyz[idx_inliers]*

非常好!但现在,我们还想对原始点云进行拆分,高效地抓住离群点。这是一个极好的转机。我们创建一个遮罩,作为快速过滤器来获取不属于内联体的其余点:

*mask = np.ones(len(xyz), dtype=bool)
mask[idx_inliers] = False
outliers=xyz[mask]*

太棒了!我们现在有了一个内部集合和一个外部集合!让我们用matplotlib来检验一下结果:

*ax = plt.axes(projection='3d')
ax.scatter(inliers[:,0], inliers[:,1], inliers[:,2], c = 'cornflowerblue', s=0.02)
ax.scatter(outliers[:,0], outliers[:,1], outliers[:,2], c = 'salmon', s=0.02)
plt.show()*

研究桌的 3D 点云用我们的 RANSAC 函数分割。F. Poux

哇,它非常好用!我们在这个场景中找到了地面!多牛逼啊!最后一件事:分别导出两个数据集:

*result_folder=”../DATA/RESULTS/”
np.savetxt(result_folder+dataset.split(“.”)[0]+”_inliers.xyz”, inliers, fmt=’%1.4f’, delimiter=’;’)
np.savetxt(result_folder+dataset.split(“.”)[0]+”_outliers.xyz”, outliers, fmt=’%1.4f’, delimiter=’;’)*

其他数据集呢?这是我们使用自动阈值方法得到的结果,基于到第 15 个最近邻居的距离估计!多好啊!

操场点云被分割,研究桌被分割,威力登 adas 激光雷达数据集被分割。正如我们所看到的,自动阈值方法允许以 100%的自动化有效地处理手头的任务。F. Poux

令人着迷的是,我们对噪声和数据环境具有超强的鲁棒性!你值得在这台 Google Colab 笔记本上访问和运行完整的代码。尽情享受吧!

结论

🥳万岁!您从头开始实现了一个完整的 RANSAC 模型拟合算法,用于平面检测和 3D 点云分割。最重要的是,您现在可以自动设置 RANSAC 参数,这样您就不会有 99%的自动解决方案,而是 100%的自动化。这是重要的一步!如果您想更深入地了解如何在您的项目中包含这项新技能,下面是下一步教程,它将允许您迭代 RANSAC 方法并使用聚类方法来检测点云中的实例:

* 的课程开始。

https://learngeodata.eu/

更进一步

存在用于点云的其他高级分割方法。这是一个我深入参与的研究领域,你已经可以在文章[1-6]中找到一些设计良好的方法。对于更高级的 3D 深度学习架构,一些综合教程即将推出!

  1. Poux,F. ,& Billen,R. (2019)。基于体素的三维点云语义分割:无监督的几何和关系特征与深度学习方法。ISPRS 国际地理信息杂志。8(5), 213;https://doi.org/10.3390/ijgi8050213—杰克·丹格蒙德奖(链接到新闻报道)
  2. Poux,F. ,纽维尔,r .,纽约,g .-a .&比伦,R. (2018)。三维点云语义建模:室内空间和家具的集成框架。遥感10 (9),1412。https://doi.org/10.3390/rs10091412
  3. Poux,F. ,Neuville,r .,Van Wersch,l .,Nys,g .-a .&Billen,R. (2017)。考古学中的 3D 点云:应用于准平面物体的获取、处理和知识集成的进展。地学7 (4),96。https://doi.org/10.3390/GEOSCIENCES7040096
  4. Poux,F. ,Mattes,c .,Kobbelt,l .,2020 年。室内三维点云的无监督分割:应用于基于对象的分类,摄影测量、遥感和空间信息科学国际档案。第 111-118 页。https://doi:10.5194/ISPRS-archives-XLIV-4-W1-2020-111-2020
  5. Poux,F. ,Ponciano,J.J .,2020。用于 3d 室内点云实例分割的自学习本体,ISPRS 摄影测量、遥感和空间信息科学国际档案。第 309-316 页。https://doi:10.5194/ISPRS-archives-XLIII-B2-2020-309-2020
  6. Bassier,m .、Vergauwen,m .、 Poux、F. 、(2020)。用于建筑物内部分类的点云和网格特征。遥感。12, 2224.https://doi:10.3390/RS 12142224*

基于 K-means 和 Python 的三维点云聚类教程

原文:https://towardsdatascience.com/3d-point-cloud-clustering-tutorial-with-k-means-and-python-c870089f3af8

实践教程,3D Python

创建 3D 语义分割数据集的完整 python 实践指南。了解如何使用 K-Means 聚类通过无监督分割来转换未标记的点云数据。

来自航空激光雷达数据的机场的 3D 点云无监督分割。聚类方案组合的示例,如 K-Means 聚类。F. Poux

如果你正在寻找一个语义分割的(监督的)深度学习算法——关键词警报😁—你肯定发现自己在寻找一些高质量的标签+大量的数据点。

在我们的 3D 数据世界中,3D 点云的未标记特性使得回答这两个标准特别具有挑战性:没有任何好的训练集,很难“训练”任何预测模型。

我们是否应该探索 python 技巧,并将其添加到我们的“箭筒”中,以快速生成出色的 3D 标注点云数据集?

让我们开始吧!🤿

无监督工作流聚类前言

为什么无监督的分割和聚类是“人工智能的主体”?

通过监督系统的深度学习(DL)非常有用。在过去的几年里,DL 架构深刻地改变了技术领域。然而,如果我们想要创造出出色的机器,深度学习将需要一次质的更新——拒绝“越大越好”的概念。今天有几种方法可以达到这个里程碑,最重要的是,无人监督或自我监督的方向是游戏规则的改变者。

点云不同细节层次的聚类策略。F. Poux

聚类算法通常用于探索性数据分析。它们也构成了人工智能分类管道中的大部分过程,以无监督/自学的方式创建良好标记的数据集。

这句话摘自上一篇文章“高维数据聚类的基础知识”,总结了我们快速探索创建半自动标签管道的实用方法的驱动因素。激动人心!但是当然,如果你觉得你需要一些快速的理论更新,你可以在下面的文章中找到完整的解释。

如何定义聚类?

一句话,聚类意味着将相似的项目或数据点组合在一起。K-means 是计算这种聚类的特定算法。

那么我们可能想要聚类的那些数据点是什么呢?这些点可以是任意点,例如使用激光雷达扫描仪记录的 3D 点。

3D 点云中的点分组示例,尝试使用 K-Means 查找主要欧几里德区域。F. Poux

但是它们也可以表示空间坐标、数据集中的颜色值(图像、点云等)或其他特征,例如从图像中提取的关键点描述符,以构建单词字典包。

从两幅立体图像中提取 SIFT 特征点,并在聚类步骤后使用摄影测量重建相应的三维点云。更多信息,了解如何在 3D 地理数据学院用开源软件做到这一点。F. Poux

https://learngeodata.eu/3d-reconstructor-formation/

您可以将它们视为空间中的任意向量,每个向量包含一组属性。然后,我们在一个定义的“特征空间”中收集许多这样的向量,我们希望用少量的代表来表示它们。但这里的大问题是,那些代表应该是什么样子?

k 均值聚类

K-Means 是计算这种聚类的一种非常简单和流行的算法。这是一个典型的无人监管的过程,所以我们不需要任何标签,如在分类问题。

我们唯一需要知道的是一个距离函数。告诉我们两个数据点相距多远的函数。以最简单的形式,这就是欧几里德距离。但是根据您的应用,您可能还想选择不同的距离函数。然后,我们可以确定两个数据点是否彼此相似,从而确定它们是否属于同一个聚类。

K-Means 是如何工作的?

它用 K 个代表来表示所有的数据点,这就是该算法的名字。所以 K 是我们放入系统的用户定义的数字。例如,取所有的数据点,用空间中的三个点来表示。

K 的意思是工作。首先,我们在特征空间中有一些数据点(欧几里得空间中的 X、Y 和 Z)。然后,我们计算 K 个代表,并运行 K-Means 将数据点分配给该代表所代表的聚类。F. Poux

所以在上面的例子中,蓝色的点是输入数据点,我们设置 K=3。这意味着我们希望用三种不同的代表来表示这些数据点。那么由红色点表示的那些代表将数据点的相应分配定向到“最佳”代表。然后我们得到三组点,绿色、紫色和黄色。

K-means 以最小化数据点与其最接近的代表点之间的平方距离的方式来实现。实现这一点的算法部分由两个简单的迭代步骤构成:初始化和赋值:

  1. 我们随机初始化 K 个质心点作为代表,并计算每个数据点到最近质心的数据关联。所以我们在这里做的是最近邻查询。
  2. 每个数据点都被分配到它最近的质心,然后我们在我们的空间中重新配置每个质心的位置。这是通过计算分配给质心的所有数据点的主向量来实现的,这改变了质心的位置。

所以在算法的下一次迭代中,我们会得到一个新的赋值,然后是一个新的质心位置,我们重复这个过程直到收敛。

K-Means 是如何工作的?直观解释。F. Poux

💡提示:我们要注意,K-Means 并不是一个最优算法。这意味着 K-Means 试图最小化距离函数,但我们不能保证找到全局最小值。因此,根据您的起始位置,您可能会得到不同的 K 均值聚类结果。假设我们想以一种快速的方式实现 K-Means。在这种情况下,我们通常需要在我们的空间中有一个近似的最近邻函数,因为这是用该算法完成的最耗时的操作。好消息,稍后我会在中提示 *k-means++* 😉。

因此,K-Means 是一种相对简单的两步迭代方法,用于寻找高维空间中潜在的大量数据点的代表。既然理论已经结束,让我们通过五个步骤深入到有趣的 python 代码实现中🤲!

1.点云工作流定义

航空激光雷达点云数据集

我们实践教程的第一步是收集一个好的数据集!这一次,我想分享另一个寻找酷炫激光雷达数据集的绝佳地点:法国国家地理研究所的地理服务。法国 ign 的 LiDAR HD 活动启动了一个开放式数据收集,在这里你可以获得法国一些地区清晰的 3D 点云!

https://geoservices.ign.fr/lidarhd#telechargement

我进入上面的门户,选择一个切片,从中提取一个子切片,删除地理参考信息,准备一些激光雷达文件的额外属性部分,然后在我的 Open Data Drive 文件夹中提供它。你感兴趣的数据是KME_planes.xyzKME_cars.xyz。如果你想在网上看到它们,你可以跳转到 Flyvast WebGL 摘录。

整体循环策略

我建议遵循一个简单的程序,您可以复制该程序来标记您的点云数据集,如下图所示。

标注 3D 点云数据集的半监督工作流。F. Poux

🤓 :这个策略是从我在 3D 地理数据学院主持的在线课程的一个文档中摘录的。本教程将涵盖第 7 步到第 10 步,其他步骤将在课程中深入讨论,或者按照下面的编码指南进行。

[## 如何使用 Python 实现 3D 点云分割和聚类的自动化

towardsdatascience.com](/how-to-automate-3d-point-cloud-segmentation-and-clustering-with-python-343c9039e4f5)

2.设置我们的 3D python 上下文

在这个动手操作的点云教程中,我主要关注高效和最小的库使用。我们可以用其他库做所有的事情,比如open3dpptkpytorch3D …但是为了掌握 python,我们将用NumPyMatplotlibScikitLearn做所有的事情。启动脚本的六行代码:

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits import mplot3d
from sklearn.cluster import KMeans
from sklearn.cluster import DBSCAN

很好,从这里开始,我建议我们相对地表达我们的路径,将包含我们的数据集的data_folderdataset名称分开,以便在运行中容易地切换:

data_folder=”../DATA/”
dataset=”KME_planes.xyz”

从那里,我想说明一个用Numpy加载你的点云的好技巧。直观的方法是将所有内容加载到一个pcd点云变量中,比如pcd=np.loadtxt(data_folder+dataset)。但是因为我们将对这些特性稍加研究,所以让我们通过动态地解包变量中的每一列来节省一些时间。Numpy到底有多酷?😆

x,y,z,illuminance,reflectance,intensity,nb_of_returns = np.loadtxt(data_folder+dataset,skiprows=1, delimiter=’;’, unpack=True)

不错!我们现在有一切可以玩的东西了!由于 K-Means 的本质,我们必须小心地面元素的无所不在,这将提供一些奇怪的东西,如下所示:

一些 K-Means 在 3D 点云上的结果,基于各种属性,没有智能注入。请注意,当仅使用空间属性时,第一幅图像上有规则的三角形分隔。不理想,嗯?弗·普克斯。

为了避免奇怪的结果,我们应该处理我们认为的异常值,即地面。下面是一个直接的窍门,不需要注入太多约束性的知识。

3.点云快速选择

让我通过Matplotlib用一个微小的监督步骤来说明如何处理这个问题。它还允许我给你一些代码,这些代码在创建支线剧情和线条分层时总是很方便的。我们将检查两个视图上的 2D 图,我们点的平均值落在哪里,看看这是否有助于在后面的步骤中过滤掉背景。

首先,让我们制作一个 subplot 元素,它将保存我们在X, Z视图上的点,并绘制 pour 空间坐标的平均值:

plt.subplot(1, 2, 1) # row 1, col 2 index 1
plt.scatter(x, z, c=intensity, s=0.05)
plt.axhline(y=np.mean(z), color=’r’, linestyle=’-’)
plt.title(“First view”)
plt.xlabel(‘X-axis ‘)
plt.ylabel(‘Z-axis ‘)

💡提示:如果你观察线条内部,我使用强度场作为我们的图的着色元素。我可以这样做,因为它已经在一个[0,1]间隔被标准化了。s代表尺寸,允许我们给我们的点一个尺寸。😉

然后,让我们做同样的把戏,但这次是在Y, Z轴上:

plt.subplot(1, 2, 2) # index 2
plt.scatter(y, z, c=intensity, s=0.05)
plt.axhline(y=np.mean(z), color=’r’, linestyle=’-’)
plt.title(“Second view”)
plt.xlabel(‘Y-axis ‘)
plt.ylabel(‘Z-axis ‘)

在那里,我们可以使用以下命令绘制该图:

plt.show()

哈哈,好听,hun?代表平均值的红线看起来可以让我们很好地过滤掉接地元素!所以,让我们利用它吧!

4.点云过滤

好的,我们想要找到一个掩码,允许我们去掉不满足查询的点。我们感兴趣的查询只考虑具有高于平均值的Z值的点,具有z>np.mean(z)。我们将把结果存储在变量spatial_query中:

pcd=np.column_stack((x,y,z))
mask=z>np.mean(z)
spatial_query=pcd[z>np.mean(z)]

💡提示:*Numpy*的* *column_stack* 函数非常方便,但要小心使用,因为如果应用于太大的矢量,它会产生开销。尽管如此,它使得使用一组特征向量变得非常方便。*

然后,您可以通过查看过滤后的点数来快速验证它是否有效:

*pcd.shape==spatial_query.shape 
[Out] False*

现在,让我们用以下命令绘制结果,这次是 3D 的:

*#plotting the results 3D
ax = plt.axes(projection=’3d’)
ax.scatter(x[mask], y[mask], z[mask], c = intensity[mask], s=0.1)
plt.show()*

同样,如果您想要一个与我们的激光雷达高清数据相适应的俯视图:

*#plotting the results 2D
plt.scatter(x[mask], y[mask], c=intensity[mask], s=0.1)
plt.show()*

**

很好,我们去掉了恼人的离群点,现在我们可以专注于这两个平面,并尝试为每个平面附加语义。

5.k-均值聚类实现

高水平Scikit-learn图书馆的建设会让你开心。只需一行代码,我们就可以拟合聚类 K 均值机器学习模型。我将强调标准符号,其中我们的数据集通常表示为X来训练或适应。在第一种情况下,让我们创建一个特征空间,仅保存屏蔽后的 X,Y 特征:

*X=np.column_stack((x[mask], y[mask]))*

从那里,我们将运行我们的 k-means 实现,K=2,看看我们是否可以自动检索两个平面:

*kmeans = KMeans(n_clusters=2).fit(X)
plt.scatter(x[mask], y[mask], c=kmeans.labels_, s=0.1)
plt.show()*

💡提示: 我们通过调用 sklearn.cluster._kmeans 上的 *.labels_* 方法,从 k-means 实现中检索标签的有序列表。k 表示 kmeans 对象。这意味着我们可以直接将列表传递给散点图的颜色参数。

如下所示,我们在两个集群中正确地检索了两个平面!增加簇的数量(K)将提供不同的结果,您可以在这些结果上进行实验。

**

三维点云实例分割与零件分割可能的工作流程,由 K-Means 参数化给出。F. Poux

选择正确的集群数量最初可能并不那么明显。如果我们想有一些启发法来帮助以无人监督的方式决定这个过程,我们可以使用肘方法。我们正在使用肘方法中的参数 K,因此是我们想要提取的聚类数。

为了实现该方法,我们将循环K,例如,在[1:20]的范围内,使用K参数执行 K-Means 聚类,并计算 WCSS(类内平方和)值,我们将把该值存储在一个列表中。

💡提示:init参数是初始化质心的方法,这里我们设置为 k-means++ 进行聚类,重点是加速收敛。然后, wcss 值到 kmeans.inertia_ 表示每一个点与一个簇中的质心之间的平方距离之和。**

**X=np.column_stack((x[mask], y[mask], z[mask]))
wcss = [] 
for i in range(1, 20):
 kmeans = KMeans(n_clusters = i, init = ‘k-means++’, random_state = 42)
 kmeans.fit(X)
 wcss.append(kmeans.inertia_)**

🦩 有趣的事实:如果你注意了 k 线的细节,你可能会想为什么是 42?嗯,没有什么聪明的理由😆。数字 42 是科学界一直在开的一个玩笑,来源于传说中的银河系漫游指南,其中一台名为深度思考的巨型计算机计算出“生命终极问题的答案……”

然后,一旦我们的wcss列表完成,我们可以根据K值绘制图形wcss,这看起来像一个肘(也许这与方法的名称有关?🤪).

**plt.plot(range(1, 20), wcss)
plt.xlabel(‘Number of clusters’)
plt.ylabel(‘WCSS’) 
plt.show()**

这看起来很神奇,因为我们看到我们创造肘部形状的值位于 2 个集群中,这非常有意义😁。

与 DBSCAN 的聚类比较

在上一篇文章中,我们深入研究了 DBSCAN 的集群技术。

** [## 如何使用 Python 实现 3D 点云分割和聚类的自动化

towardsdatascience.com](/how-to-automate-3d-point-cloud-segmentation-and-clustering-with-python-343c9039e4f5)

如果你跟随它,你可能想知道在 3D 点云的情况下 K-Means 比 DBSCAN 真正的好处是什么?好吧,让我举例说明你可能想转换的情况。我提供了航空激光雷达数据集的另一部分,其中包含三辆相互靠近的汽车。如果我们用K=3运行 K-Means,我们会得到:

data_folder="../DATA/"
dataset="KME_cars.xyz"
x,y,z,r,g,b = np.loadtxt(data_folder+dataset,skiprows=1, delimiter=';', unpack=True)
X=np.column_stack((x,y,z))
kmeans = KMeans(n_clusters=3).fit(X)

如你所见,即使我们不能在空间上描绘出物体,我们也能得到很好的聚类。用 DBSCAN 是什么样子的?好吧,让我们看看下面的代码行:

#analysis on dbscan
clustering = DBSCAN(eps=0.5, min_samples=2).fit(X)
plt.scatter(x, y, c=clustering.labels_, s=20)
plt.show()

D3 点云的 DBSCAN 聚类。ε值分别被设置为 0.1、0.2 和 0.5。F. Poux

正如你所看到的,除了设置 epsilon 参数有困难之外,我们不能描绘,至少用这些特征,右边的两辆车。在这种情况下,K-均值为 1–0🙂。

玩弄特征空间。

现在,我们只使用空间特征来说明 K-Means。但是我们可以使用任何功能的组合,这使得它在不同的应用程序上使用起来非常灵活!

出于本教程的目的,您还可以使用照度、强度、返回次数和反射率进行实验。

从航空激光雷达高清数据集中提取三维点云特征。F. Poux

下面是使用这些功能的两个示例:

X=np.column_stack((x[mask], y[mask], z[mask], illuminance[mask], nb_of_returns[mask], intensity[mask]))
kmeans = KMeans(n_clusters=3, random_state=0).fit(X)
plt.scatter(x[mask], y[mask], c=kmeans.labels_, s=0.1)
plt.show()

或者再次

X=np.column_stack((z[mask] ,z[mask], intensity[mask]))
kmeans = KMeans(n_clusters=4, random_state=0).fit(X)
plt.scatter(x[mask], y[mask], c=kmeans.labels_, s=0.1)
plt.show()

K-Means 使用不同的特征空间和 K 值在 3D 点云上产生结果。F. Poux

为了更深入,我们可以更好地描述每个点周围的局部邻域,例如,通过主成分分析。事实上,这可以允许提取一大组或多或少相关的几何特征。这将超出当前文章的范围,但是您可以肯定,我将在以后的某个特定问题上深入研究它。你也可以通过点云处理器在线课程直接钻研 PCA 专业知识。

https://learngeodata.eu/point-cloud-processor-formation/

最后,我们只剩下将数据导出到一致的结构中,例如. xyz ASCII 文件,该文件仅保存空间坐标和可在外部软件中读取的标签信息:

result_folder=”../DATA/RESULTS/”
np.savetxt(result_folder+dataset.split(“.”)[0]+”_result.xyz”, np.column_stack((x[mask], y[mask], z[mask],kmeans.labels_)), fmt=’%1.4f’, delimiter=’;’)

如果你想让它直接工作,我还创建了一个 Google Colab 脚本,你可以在这里访问:到 Python Google Colab 脚本

结论

热烈祝贺🎉!您刚刚学习了如何通过 K-Means 聚类开发一个自动半监督分割,当语义标记与 3D 数据一起不可用时,它非常方便。我们了解到,我们仍然可以通过研究数据中固有的几何模式来推断语义信息。

真心的,干得好!但是,这条道路肯定不会就此结束,因为您刚刚释放了在细分级别进行推理的智能过程的巨大潜力!

未来的帖子将深入探讨点云空间分析、文件格式、数据结构、对象检测、分割、分类、可视化、动画和网格划分。

更进一步

存在用于点云的其他高级分割方法。这是一个我深入参与的研究领域,你已经可以在文章[1-6]中找到一些设计良好的方法。一些更高级的 3D 深度学习架构的综合教程即将推出!

  1. Poux,F. ,& Billen,R. (2019)。基于体素的三维点云语义分割:无监督的几何和关系特征与深度学习方法。 ISPRS 国际地理信息杂志。8(5), 213;https://doi.org/10.3390/ijgi8050213——杰克·丹格蒙德奖(链接到新闻报道)
  2. Poux,F. ,纽维尔,r .,纽约,g .-a .&比伦,R. (2018)。三维点云语义建模:室内空间和家具的集成框架。遥感10 (9)、1412。https://doi.org/10.3390/rs10091412
  3. Poux,F. ,Neuville,r .,Van Wersch,l .,Nys,g .-a .&Billen,R. (2017)。考古学中的 3D 点云:应用于准平面物体的获取、处理和知识集成的进展。地学7 (4),96。https://doi.org/10.3390/GEOSCIENCES7040096
  4. Poux,F. ,Mattes,c .,Kobbelt,l .,2020 年。室内三维点云的无监督分割:应用于基于对象的分类,摄影测量、遥感和空间信息科学国际档案。第 111-118 页。https://doi:10.5194/ISPRS-archives-XLIV-4-W1-2020-111-2020
  5. Poux,F. ,Ponciano,J.J .,2020。用于 3d 室内点云实例分割的自学习本体,ISPRS 摄影测量、遥感和空间信息科学国际档案。第 309-316 页。https://doi:10.5194/ISPRS-archives-XLIII-B2-2020-309-2020
  6. 巴斯尔,男,维高温,男,普克斯,女,【2020】。用于建筑物内部分类的点云和网格特征。遥感。12, 2224.https://doi:10.3390/RS 12142224**

NumPy 简介

原文:https://towardsdatascience.com/3short-introduction-to-numpy-3a65ec23eaba

数字图书馆和 ufuncs 的一些基本知识

埃里克·麦克林在 Unsplash 上的照片

NumPy 代表数值 Python,是一个用于处理数组的 Python 库。在这些数组的帮助下,来自线性代数的元素,比如向量和矩阵,可以用 Python 来表示。由于该库的大部分是用 C 语言编写的,所以即使使用大型矩阵,它也能执行特别高效和快速的计算。

什么是 NumPy?

Python 提供了多种数据结构,可用于存储数据,无需额外的库。然而,这些结构,比如 Python 列表,非常不适合数学运算。在处理大量数据时,逐个元素添加两个数字列表会很快对性能产生不利影响。

由于这个原因,NumPy 被开发出来,因为它提供了快速有效地执行数值运算的可能性。尤其重要的是来自线性代数领域的计算,例如矩阵乘法。

如何安装 NumPy?

像许多其他库一样,NumPy 可以使用 pip 从笔记本上直接安装。为此,使用命令“pip install”和模块名称。这一行前面必须有一个感叹号,以便笔记本识别出这是一个终端命令:

如果安装成功,模块可以简单地导入并在笔记本中使用。这里经常使用缩写“np ”,以便在编程过程中节省一点时间,并且不必每次都输入 NumPy:

什么是 NumPy 数组?

NumPy 数组是传统 Python 列表的有效替代。它们提供了存储多维数据集的可能性。在大多数情况下,数字被存储,数组被用作向量或矩阵。例如,一维向量可能是这样的:

除了 NumPy 数组的不同功能(我们将在另一篇文章中介绍)之外,可能的维度对于区分仍然很重要:

区分了以下维度:

  • 0D —数组:这只是一个标量,即单个数字或值。
  • 1D —数组:这是一个向量,作为一维的一串数字或值。
  • 2D 阵列:这种阵列是一个矩阵,也就是几个 1D 阵列的集合。
  • 3D — Array :几个矩阵组成一个所谓的张量。我们已经在关于张量流的文章中对此进行了更详细的解释。

NumPy 数组和 Python 列表有什么区别?

根据来源的不同,NumPy 数组和 Python 列表之间有几个基本的区别。最常提到的有:

  1. 内存消耗:数组的编程方式是它们占据内存的某一部分。然后,数组的所有元素都位于那里。另一方面,列表的元素在内存中可能相距很远。因此,一个列表比一个相同的数组消耗更多的内存。
  2. 速度:数组的处理速度也比列表快得多,因为它们的内存消耗更低。这对于有几百万个元素的对象来说有很大的不同。
  3. 功能:数组提供了更多的功能,例如,它们允许逐个元素的操作,而列表则不允许。

什么是 Numpy ufuncs?

所谓的“通用函数”(简称:ufuncs)用于不必逐个元素地执行某些操作,而是直接对整个数组执行。在计算机编程中,当命令直接对整个向量执行时,我们称之为矢量化。

这不仅在编程上快得多,而且导致更快的计算。在 NumPy 中,提供了几个这样的通用函数,可以用于各种操作。其中最著名的有:

  • 使用“add()”可以逐个元素地对多个数组求和。
  • “subtract()”正好相反,它逐个元素地减去数组。
  • “multiply()”将两个数组逐个元素相乘。
  • " matmul()"形成两个数组的矩阵乘积。请注意,在大多数情况下,这不会给出与“multiply()”相同的结果。

这是你应该带走的东西

  • NumPy 代表 Numerical Python,是一个用于处理数组的 Python 库。
  • 在这些数组的帮助下,线性代数中的元素,比如向量和矩阵,可以用 Python 来表示。
  • 因为这个库的大部分是用 C 语言编写的,所以它可以执行特别高效和快速的计算,即使是大型矩阵。
  • NumPy 数组与 Python 列表相当,但在内存需求和处理速度方面明显优于 Python 列表。

如果你喜欢我的作品,请在这里订阅https://medium.com/subscribe/@niklas_lang或者查看我的网站* 数据大本营 !还有,medium 允许你每月免费阅读 3 篇 。如果你希望有无限制的 访问我的文章和数以千计的精彩文章,请不要犹豫,点击我的推荐链接:【https://medium.com/@niklas_lang/membership】每月花$5***获得会员资格**

*</4-basic-commands-when-working-with-python-dictionaries-1152e0331604> </6-fundamental-questions-when-working-with-a-pandas-series-1d142b5fba4e> *

Power BI 中的 4 + 2 安全特性

原文:https://towardsdatascience.com/4-2-security-features-in-power-bi-4c5a21968e53

一年前,我写了一篇关于 Power BI 的四个安全特性的文章。与此同时,我们获得了一些新的安全功能。让我们调查他们。

约翰·萨尔维诺Unsplash 上拍摄

介绍

去年,2021 年 11 月 03 日,我写了下面这篇文章:

此后,微软在 Power BI 中增加了两个新的安全特性。

这是一个很好的理由回到这个话题,并更新你。

在上面提到的文章中,我列出了 Power BI 的以下四个安全特性:

  • 超级查询中的隐私级别
  • Power BI 中的行级安全性(RLS)
  • Office 365 敏感性标签
  • Power BI 工作空间安全性

虽然我在那篇文章中提到了应用程序安全性,但微软已经为应用程序添加了一个新功能:受众。

此外,微软还在 Power BI 中增加了对象级安全性。

那么,让我们来看看这两个特性:

应用受众

在探索 Power BI 服务中的应用体验时,重要的一点是不可能在每个工作空间创建多个应用。

向一个工作区添加另一个应用程序将允许我们定义哪个用户可以从工作区访问哪个报告。

新功能受众允许我们定义一组用户对应用程序中报告和报告页面的访问权限。

首先,你必须点击工作区的“创建应用”或“更新应用”按钮,才能跳转到编辑应用的功能。

然后,您可以直接切换到“受众”标签:

图 1 —转到“受众”选项卡(作者的图)

如果你没有看到观众页面,你必须升级你的应用体验。你可以在下面链接的视频中看到如何做-

现有受众允许所有用户完全访问。

现在,您可以向应用程序添加新的受众:

图 2 —添加新的受众(作者提供的数字)

要配置对应用程序每个元素的访问,您必须单击该元素。然后更改它的访问列表:

图 3 —设置应用程序中元素的访问权限(作者提供的图片)

设置新的访问群体后,您还可以更改第一个(默认)访问群体的访问权限。

请观看下面参考资料部分中 Guy in a Cube 的 YouTube 视频,了解如何使用该功能的详细演示。

正因如此,我就不深究这个特性了。

但是,看看这个出色的新功能,它可以彻底改变您使用 Power BI 应用程序的工作。

对象级安全性

顾名思义,我们可以使用对象级安全性(OLS)来控制对 Power BI 数据模型中对象的访问。

从一开始,我们就有了分析服务中的 OLS 列表。但这对于 Power BI 来说是全新的。

我们可以为表和列设置 OLS,但不能为度量、计算组或其他对象设置。

但是,当我们限制对某个度量使用的表或列的访问时,对该度量的访问也会受到限制。

在下面的参考资料一节中,您将找到一篇由 SQLBI 撰写的关于如何隐藏 OLS 度量值的文章的链接。

OLS 是另一个不能在 Power BI Desktop 中单独使用的功能。您必须使用表格编辑器才能使用该功能。

首先,您需要在数据模型中创建一个新角色。

您必须在 Power BI Desktop 中创建角色:

图 4 —在 Power BI Desktop 中创建一个新角色(图由作者提供)

我在表格编辑器中创建了一个角色,但是我不能在 TE 中重命名这个角色,OLS 也不能像预期的那样工作。

因此,在 Power BI Desktop 中创建角色是正确的方法。

现在,您可以在表格编辑器中为对象配置 OLS。

例如,当您想要限制对客户表的访问时,您将单击该表并为其设置 OLS:

图 5 —为客户表配置 OLS(由作者提供)

现在,您必须保存对模型的更改,并返回到 Power BI Desktop。

要查看它是否有效,您可以测试它:

图 6 —测试 OLS(由作者提供)

我的报告“按地理位置显示客户”将显示以下消息:

图 7 —受限访问的错误(作者提供的图)

如您所见,Customer 表的 Customer Name 字段和所有度量依赖项都失败了。

在设置 OLS、测试它并向 Power BI Service 发布报告之后,您必须向角色分配成员,如上面链接的我的前一篇文章所示。

结论

这两项在过去几个月中增加的功能可以帮助我们为 Power BI 解决方案增加更多灵活性。

我已经有两个客户要求我使用这些新特性来满足他们需求的解决方案。

我不知道这两个哪个更酷。两者我都喜欢,方式相似。

无论如何,我希望在将它们添加到您的工具集之后,您可以从中获得乐趣。

山姆·克拉克Unsplash 上拍摄

参考

如何发布应用并创造受众:在 Power BI 中发布应用—微软学习

YouTube 上的观众视频由在立方体中的家伙:

Power BI 中的对象级安全性:对象级安全性(OLS) —微软学习

SQLBI 制作的关于对象级安全的 YouTube 视频:

Power BI 中使用对象级安全的隐藏措施— SQLBI

https://medium.com/@salvatorecagliari/membership

你可能已经忘记的 4 个高级 Python 操作

原文:https://towardsdatascience.com/4-advance-python-operations-you-may-have-forgotten-58b0565b9f

了解如何在 Python 中使用熔化、透视、堆叠和分解

Pic 鸣谢:Unsplash

默认情况下,数据不是可用的格式;数据科学专业人员必须将 70–80%的时间花在数据清理和处理上,以使其能够用于生成有意义的见解。

在数据操作过程中,数据科学家/分析师可能不得不进行各种类型的数据转换,有时我们会感到困惑,因为我们不知道 python 中是否存在执行所需转换的直接函数。

在这篇博客文章中,我们将看看 4 个高级 python 数据转换函数,它们将使您作为数据科学专业人员的生活变得更加轻松,并且将是您的数据操作函数库的一个巨大补充。

1.在枢轴上转动

pandas 中的透视功能与 excel 中的透视操作功能相同。我们可以将数据集从长格式转换为宽格式。

长到宽格式(图片由作者提供)

我们用一个例子来理解这个。想象一下,我们有一个跨国家的新冠肺炎病例数据集,如下所示。

作者图片

我们希望将数据集转换成一种形式,使每个国家成为一列,新确诊病例成为与这些国家相对应的值。我们可以使用 pivot 函数来执行这种数据操作。

枢纽功能(图片由作者提供)

### Pivot the dataset
pivot_df = pd.pivot(df, index =['Date'], columns ='Country', values =['NewConfirmed'])## renaming the columns  
pivot_df.columns = df['Country'].sort_values().unique()

透视后的数据集(作者提供的图片)

通过重置索引,我们可以使新列与索引列数据处于相同的级别。

## reset the index to modify the column levels
pivot_df = pivot_df.reset_index()

重置索引(图片由作者提供)

https://medium.com/codex/dont-use-iterrows-for-loops-in-python-instead-use-these-6363395dcea2

2。融化

Melt 与 pivot 相反,它用于取消数据集的透视。它将数据从宽格式转换为长格式。

宽到长格式(图片由作者提供)

让我们看看如何取消我们在上面创建的宽格式新冠肺炎数据集的透视。

## The dataset is melted by setting the id column - a column that will not change.
## and value column - columns we want to unpivotmelted_df = pivot_df.melt(id_vars = 'Date', value_vars = ['US', 'India', 'China'])# we can rename the columns too
melted_df.columns = ['Date', 'Country', 'NewConfirmed']

作者图片

将数据从宽格式融合到长格式(图片由作者提供)

3.堆

stack 函数用于将多级列转换(或取消透视)为行。

我们来看几个例子!

如果我们选择透视新冠肺炎数据集而不重置索引,那么它看起来会像这样。

透视后的数据集(作者提供的图片)

我们可以使用 stack 函数将 country 列堆叠回行,如下所示。

## stack the dataset
stack_df = pivot_df.stack()## reset the index and set column names
stack_df = stack_df.reset_index()
stack_df.columns = ['Date','Country','NewConfirmed']
stack_df

堆叠数据集(按作者分类的图像)

现在,你可能会想同样的转换也可以用融化函数来完成,你是对的。但这两者还是有区别的,stack 函数更高级——它适用于多级列,而 melt 不能。例如,堆栈功能可以转换具有 2 个列级别的以下数据:

堆叠数据集(按作者排列的图像)

“-1”级别表示倒数第一列。

4.出栈

解散堆叠与堆叠相反,它用于透视多级列数据集的一级/多级。

让我们看几个例子来更好地理解它!

使用 unstack,我们可以透视数据集的列,如下所示。

拆分数据集(按作者排列的图像)

分解功能也可以处理多级列数据集,而熔化功能则不能。

拆分功能(图片由作者提供)

枢轴/熔化功能是堆叠/分解功能的子集。透视/融合不适用于多层柱。

https://medium.com/codex/9-python-concepts-you-should-not-skip-for-effective-data-science-a8606c58a53b

结论

在这篇博客中,我们研究了 4 种高级数据转换技术,将数据格式从长格式转换为宽格式,反之亦然。

Pivot/Melt 适用于单级列数据集,而 Stack/Unstack 也可应用于任何复杂的多级列数据集。

谢谢你

我希望这个故事对你有用。你可以在收件箱里看到我所有的帖子。 做到这里

如果你自己喜欢体验媒介,可以考虑通过 注册会员 来支持我和其他几千位作家。它每个月只需要 5 美元,它极大地支持了我们,作家,你可以在媒体上看到所有精彩的故事。

你可能喜欢的故事!

https://medium.com/codex/dont-use-loc-iloc-with-loops-in-python-instead-use-this-f9243289dde7

4 先进的机器学习技术

原文:https://towardsdatascience.com/4-advanced-machine-learning-techniques-71d485e9fcab

进一步提高模型分数的替代方法

Unsplash 上由 Silvan Arnet 拍摄的照片

改进机器学习模型的典型方法有哪些?添加更多功能。执行选择以移除冗余特征。优化超参数。将几个模型组装在一起。是的,所有这些都可能奏效,但还有许多其他方法可以提高分数。也许有些方法不太为人所知,有些方法并不适用于所有情况,但是在适当的时候应用它们可以带来显著的改善。让我们来看看其中的一些。

伪标记

对于数据科学任务,我们通常有一个带有已知标签的训练数据集。一般来说,我们拥有的训练数据越多,模型学到有用东西的可能性就越大。但是在大多数情况下,标记的训练数据的数量是有限的。在某些情况下,这是因为贴标签的过程成本太高(例如,每个箱子都需要人工贴标签)。

对此的一个解决方案是使用伪标记技术创建额外的训练数据。

为此,我们需要没有标签的额外数据。如果已经有可用的测试数据(例如,在比赛中),我们可以使用它。否则,需要在某个地方收集数据——但由于它不需要标签,这应该比收集真实的训练数据容易得多。

一旦收集了数据,我们就使用我们的模型对其进行预测。没有标签,就不知道预测有多好。但在大多数情况下,越自信的预测意味着正确的概率越大。因此,我们选择一些百分比的最有信心的模型预测,并使用这些作为额外的训练数据标签。该模型然后在两者上被重新训练——原始训练数据+我们新的伪标记的附加训练数据。新模型可能会比原来的模型产生更好的分数。

为什么会这样?

此外,收集的数据可能与原始训练数据略有不同。在不同的时间间隔从另一个源收集,等等。因此,这些数据可能包含稍微不同的关系和信号。该模型不能从原始数据中学习这些关系,因为它们不存在或者至少在那里略有不同。但是如果分配给它们的标签大部分是正确的,这些可以从新的伪标签数据中学习。

然而,伪标签的工作有一个重要的要求——原始模型的精度必须足够高。否则,许多行将被错误地标记,并且伪标记数据将引入太多噪声。因此,在模型开发的最新阶段使用伪标注是一个很好的实践,此时它已经通过特征工程、参数优化和其他基本技术得到了改进。

通过模型预测去除异常值

从训练数据中移除离群值是大多数机器学习管道中的标准步骤。但是这里我不是在谈论这种简单的标准方法,它通常涉及到查看每个特性,并从两端删除一些百分点,以消除太小和/或太大的值。

威尔·梅尔斯在 Unsplash 上拍照

存在一种更高级的方法来处理异常值。该技术不仅允许去除单个特征的过大/过小值方面的异常值,还允许处理异常特征交互。

该技术的核心思想非常基本:

  • 首先,以标准方式训练和调整模型,包括特征选择、超参数调整等等。
  • 然后对训练数据行以 OOF(出折叠)方式进行预测。
  • 为每一行计算预测的误差(或特定问题的任何其他相关度量)。
  • 误差最大的行被定义为异常值。在每种情况下,要删除的行的百分比会有所不同。
  • 该模型在训练数据上被重新训练,其中已识别的异常行被移除。

为什么会这样?

如果对于某个数据行,与该给定任务的平均误差相比,模型产生了较大的误差,这意味着对于该给定数据行,特征告诉模型一件事,但是标签非常不同。在现实生活中,这可能是由于各种原因造成的:

  • 一个或多个重要特征中存在异常值;
  • 标签不正确(由于标签错误、人为错误或其他原因);
  • 这是模型无法从给定数据中学习的一些特殊的罕见情况。

现在,如果它是某个特征中的异常值或错误值,我们要删除这一行。如果它有错误的标签,我们肯定也要删除它。我们可能更愿意在训练数据中保留这一特定行的唯一情况是它描述了一些罕见的情况。在大多数情况下,对于给定的行,不可能将这些情况分开,所以我们需要全局地决定——我们是否要保留这样的行?

从我的经验来看,在许多任务中,这种方法会带来轻微的改进。改进的大小显然取决于特定数据集有多少异常值、不良特征和不正确的目标值。但是,在某些情况下,可能会发生这样的情况,即大多数被检测为异常值的行实际上是有效的。发生这种情况主要是由于模型太弱——因此,我建议只在模型调整的最后阶段应用这种方法,此时现有模型已经用标准技术尽可能地提高了。

数据扩充

在某种程度上,这种技术类似于伪标记。从某种意义上说,这有助于获得更多的训练数据。并且更多的训练数据通常会产生更好的模型。主要区别在于我们获取更多训练数据的确切方式。

如果在伪标记中,我们使用额外的真实数据和自己分配的标记。但在某些情况下,我们根本没有任何额外的数据。在扩增的情况下,我们使用真实的标签,但数据本身以不同的方式被修改和转换,以创建与原始数据集具有相似特征的新数据。

对于各种类型的数据——数字数据、时间序列、图像和文本数据,有各种各样的数据扩充技术。例如,图像可以以不同的方式旋转、裁剪或倾斜。从逻辑角度来看,图像上的图片(因此,原始标签也是如此)没有改变。但是对于模型来说。这个新图像看起来不同,有助于使模型更加健壮。

对于文本数据,一种方法是翻译。我们可以把原来的句子翻译成其他语言,然后再翻译回来。在翻译过程中,原句会略有不同,但意思应该是一样的,因此保留了原标签。

对于数字和时间序列数据,确切的方法在很大程度上取决于数据究竟代表什么。可能需要一些领域知识来正确创建带有原始标签的新数据行。

我在处理图像的计算机视觉任务中看到了这项技术的最大改进。但是其他类型的数据也有潜力。

解释模型预测

机器学习模型有时被认为是一个黑箱。但实际上,并非如此。我们可以从这个模型中收集到大量的信息,确切地了解它是如何在这种或那种情况下做出决策的。我们可以获得的确切信息量取决于模型的类型。一些模型,如基于树的模型或线性回归,非常容易解释。但是,例如,神经网络模型对内部发生的事情提供的可解释信息较少。

JESHOOTS.COMUnsplash 上拍照

在任何情况下,尽我们最大的努力去理解模型到底是如何使用这些特性的是很有帮助的。查看特征重要性图是一种方法。如果我们在特征重要性图的顶部发现了一些奇怪的特征,那么就有必要尝试找出该特征中是否真的有一些信号,或者这只是噪声。在最简单的情况下,尝试删除该特性,并比较有无该特性时的验证分数。

但是特性重要性图并不是关于特性使用的唯一信息来源。有更多的可能性深入挖掘模型内部。莱姆和 SHAP 就是其中的一些(如果你感兴趣,我会把关于它们的技术细节留给你自己研究)。这些方法的好处不仅在于检查模型使用了哪些特征,还在于检查特征影响的方向。它让我们明白,特定特性的较低值会导致目标的较低或较高值。这些知识允许我们使用领域知识来判断这样的特征解释是否有意义。

深入研究特征及其对模型的影响不是一件容易的事,而且速度也不快,所以在大多数情况下,对每个特征都这样做是没有好处的。但至少,检查最重要的特性并理解模型如何使用它们以及这样做是否有意义是值得的。根据结果,我们可能想要决定移除该特性,或者在某些情况下甚至完全审查我们的验证方法——如果我们看到使用明显错误的特性会导致更好的验证分数。

一些最后的话

在机器学习中,模型永远不会真正完成。总有一种可能性,所以挤出一些额外的微小改进。这里的关键时刻是在适当的时候停止改进——以便模型“足够好”,但也在合理的时间内开发出来。

希望这篇文章能给你一些想法,让你在不投入太多额外时间的情况下,尝试从你的模型中获得一些额外的改进。

感谢阅读!

作为一名数据科学家,4 款应用将提高您的工作效率

原文:https://towardsdatascience.com/4-apps-that-will-make-you-more-productive-as-a-data-scientist-4b0c19c6a0e7

在编写代码、做笔记、组织任务、项目等方面变得更加高效!

照片由 Unsplash 上的Jorge Ramirez拍摄

数据科学工作流充满了需要在昨天完成的任务。如果我们加上日常办公任务,比如去开会和回复邮件,要做的事情清单是无穷无尽的。

幸运的是,有一些应用程序可以帮助你变得更有效率,专注于最重要的事情。

在这篇文章中,我列出了一些应用程序,它们帮助我在编写代码和做笔记时变得更有效率,还用来组织我的任务、日历、电子邮件、项目,甚至 Github 卡。

免责声明:此列表中的大多数应用程序都是免费的。也就是说,其中几个包含附属链接,如果你通过它们购买,我会赚取佣金,而不会额外增加你的成本。

Todoist

想想你一天中的所有任务。

作为一名数据科学家,您可能会觉得有太多事情要做,不知所措。你不仅要收集和清理数据集,还要参加会议,回复电子邮件,以及做一份办公室工作所期望的大量其他事情。

你甚至可能会忘记做其中的一些。

这时你需要一个像 Todoist 这样的任务管理器。这个应用程序可以帮助你组织一天甚至一周的所有任务。不要把所有的任务都记在脑子里,用 Todoist 写下来。

作者图片

你只需要打开应用程序,添加任务、描述、优先级,如果有必要,还可以添加频率。

创建任务后,您可以将它们添加到项目中。免费计划的限制是 5 个项目,这在大多数情况下应该足够了。一个项目提供两种视图:列表和公告板。以上是我的“自动化”项目的董事会视图的一个例子。

最棒的是,所有这些任务在你的所有设备上都是同步的,所以你永远不会忘记做清单上的任何任务,但你可以随时勾选任务。

下次你感到无聊,不知道下一步该做什么的时候,拿起你的手机,打开 Todoist,你会发现一些有意义的任务要做。

孙萨玛

作为一名数据科学家,您可能会被工作中收到的所有电子邮件、日历上的会议甚至项目板上的 Github 卡片淹没。

你可以通过组织你的一天,制定计划,优先处理最重要的任务来避免被这些事情搞得筋疲力尽。

这款应用将日历应用推向了一个新的高度。Sunsama 与您的 Google/Outlook 日历同步,因此您可以在一个地方查看您的日程安排并管理您的任务。

更好的是,Sunsama 集成了 Todoist、Github、Slack 和 Trello 等应用程序。把那些你计划要做的事情做好,不要为剩下的事情感到压力!

这是你用 Sunsama 组织你的任务后得到的视图。

资料来源:Sunsama(保持生产力)

正如你所看到的,这个每日计划器帮助你在一个地方组织任务、电子邮件等等。

有了 Sunsama,您每天都可以优先处理工作。你只需要为你每天想要完成的事情设定目标。那些一天没有完成的任务会自动转到第二天。

概念

如果你喜欢苹果的 Notes 或 Evernote,你可能会喜欢 idea。

理念不仅仅是做笔记,还包括记录你的项目和创建路线图来跟踪你的工作流程。这个应用程序有工作区,您可以使用它来分离您拥有的每个项目。

好消息是,您不必从头开始创建工作区,而是可以使用模板。您会发现一些更有用的模板是在“工程”部分。

下面是概念工程部分的“文档”模板。

作者图片

一旦你有了模板,你就可以随心所欲地定制它。

例如,我有一个 Python 工作空间,在那里我有关于如何设置虚拟环境、如何对我的计算机进行故障诊断的说明,以及其他没有概念我就不会记得的事情。

粘贴(仅限 Apple 设备)

当你写代码的时候,有没有发生过这样的事情,你不记得保持你的工作流运行所必需的 Python 方法/函数?

这经常发生在我身上…直到我发现了浆糊。

粘贴是一个剪贴板管理器,不仅仅是存储你用电脑复制的文本。这个应用程序将图像、文件、代码、链接等保存到剪贴板历史记录中,并在所有苹果设备上共享。

但这还不是全部!您可以根据需要创建任意数量的插接板,将项目分类到不同的类别中。

下面是我的名为“编码”的插接板,其中有我刚刚学会但有时会忘记的代码片段和终端命令。

作者图片

当您向每个类别添加更多项目时,您可能会丢失其中的一些项目,但粘贴提供了一个搜索功能,允许我们找到很久以前复制的任何内容。

最后但同样重要的是,该应用程序支持 macOS 上的快捷方式。每当你想使用其中一个项目时,只要按几个键,然后,粘贴就会弹出来。

这是目前为止我最喜欢的应用程序。不幸的是,它只适用于苹果设备。

用 Python 学习数据科学?通过加入我的 10k 多人电子邮件列表,获取我的免费 Python for Data Science 备忘单。

如果你喜欢阅读这样的故事,并想支持我成为一名作家,可以考虑报名成为一名媒体成员。每月 5 美元,让您可以无限制地访问数以千计的 Python 指南和数据科学文章。如果你使用我的链接注册,我会赚一小笔佣金,不需要你额外付费。

https://frank-andrade.medium.com/membership

使用 Python 字典时的 4 个基本命令

原文:https://towardsdatascience.com/4-basic-commands-when-working-with-python-dictionaries-1152e0331604

让您了解 Python 字典的特征以及如何处理它们

Emmanuel Ikwuegbu 在 Unsplash 上拍摄的照片

Python 字典用于存储变量中的键值对。它是预装在 Python 中的总共四种数据结构之一。除了字典,这些还包括元组集合列表

Python 字典的基本特征是什么?

Python 版本 3.7 开始,字典被订购。这意味着我们存储键值对的顺序也起着作用。相比之下,在之前的版本中,顺序没有任何意义。此外, Python 字典也是可修改的,即在它被创建后,可以从字典中修改、添加或删除元素。

Python 字典最重要的特性是不允许重复的键值对。然而,在 Python 的其他数据格式中,重复元素是允许的。如果我们想将一个键-值对添加到字典中,而字典中的键已经存在,那么旧的键-值对将被覆盖,而不会发出通知。

1.定义和查询字典

我们定义了一个 Python 字典,将键值对写在花括号中,并用冒号分隔。我们可以在一个字典中存储不同数据类型的元素。

我们可以通过指定方括号中的键来查询字典的元素。然后我们得到为这个键存储的相应值。我们可以从字典中查询各种信息和元素。

正如我们已经看到的,我们可以通过在方括号中定义相关的键来查询值。类似地,“get()”方法返回相同的结果:

2.获取字典的键和值

用命令”。按键()"和"。values()" Python 返回给我们一个所有键和值的列表。列表的顺序也对应于它们在字典中的存储方式。这也意味着值列表可能包含重复项。

另一方面,如果我们想要检索完整的键-值对,我们使用“.items()"方法,该方法将对作为元组列表返回:

3.更改字典中的元素

如果我们想改变 Python 字典中的单个值,我们可以直接通过键来实现。因为不能有重复的键,所以旧值会被简单地覆盖。如果我们想一次改变多个线对,我们使用“.”。update()"方法,并在其中定义新的键值对。

4.删除元素或整个字典

如果我们想从 Python 字典中删除单个元素,我们可以指定键并使用“pop()”方法专门删除元素,或者使用“popitem()”删除最后添加的键-值对:

最后,您可以用“clear()”方法清除整个 Python 字典:

这是你应该带走的东西

  • Python 字典是 Python 中预装的四种数据结构之一。
  • 它用于在单个变量中存储键值对。
  • 字典的值可以有不同的值。除了单个标量,列表、元组或新字典也可以存储为值。

如果你喜欢我的作品,请在这里订阅https://medium.com/subscribe/@niklas_lang或者查看我的网站* 数据大本营 !此外,媒体允许你每月免费阅读 3 篇 。如果你想让无限制地访问我的文章和数以千计的精彩文章,不要犹豫,通过点击我的推荐链接:*https://medium.com/@niklas_lang/membership获得会员资格,每个月只需支付 5**

***</6-pandas-dataframe-tasks-anyone-learning-python-should-know-1aadce307d26> </4-basic-commands-when-working-with-python-tuples-8edd3787003f> ***

使用 Python 元组时的 4 个基本命令

原文:https://towardsdatascience.com/4-basic-commands-when-working-with-python-tuples-8edd3787003f

让您了解 Python 元组的特征以及如何处理它们

照片由华盛顿·奥利维拉·🇧🇷Unsplash 拍摄

Python 元组用于在一个变量中存储多个值。它是预装在 Python 中的四种数据结构之一。除了元组之外,这些还包括字典,集合,以及列表

元组是有序的,不能更改。一方面,这意味着元素具有特定且恒定的顺序。由于顺序固定,元组也允许重复。另一方面,元组在被定义后不能被改变。因此,不能删除或添加任何元素。

为什么了解不同的数据类型如此重要?

Python 总共有四种不同的数据类型,它们已经存在于基本安装中,因此不能仅通过安装模块来使用,例如 Panda 的 DataFrames。这些可以用于各种各样的用例,也是模块中使用的许多其他数据类型的基础。

Python 中的四种基本数据类型是:

  • 列表 是元素的有序集合,是可变的,也可以包含重复的元素。
  • 元组实际上是一个列表,不同之处在于它不再是可变的。因此以后不能添加或删除任何元素。
  • 集合不允许重复输入。同时,集合中元素的排列是可变的。集合本身可以更改,但是单个元素以后不能更改。
  • 从 Python 版本开始,一个 字典 就是可以改变的元素的有序集合。在早期版本中,字典是无序的。

1.定义一个元组

我们可以通过在圆括号中定义元素并用逗号分隔它们来创建 Python 元组。具有不同数据类型的元素可以毫无问题地存储在一个元组中。

2.查询元素

由于元组的顺序,我们可以借助索引从元组中检索单个元素。应该注意的是,元素的计数从 0 开始。另一方面,如果我们想从末尾检索一个值,我们从 1 开始计数。

如果还不知道某个元素的索引,可以用“index”的方法去求。因为 Python 元组中的顺序不变,所以该值也保持不变。

3.更改元素

我们已经知道,元组实际上是不可变的。也就是说,一旦我们定义了一个元组,就不能再添加或删除元素了。

为了能够改变元组,我们使用了一个小技巧。我们首先将元组转换成一个 Python 列表。由于这是可变的,我们可以简单地在这里添加或删除元素。然后我们将列表转换回一个元组。这样,我们间接地改变了 Python 元组的元素。

4.合并元组

如果我们想要合并两个或更多的元组,我们可以简单地使用“+”操作符。因此,第一个命名元组的顺序在第二个命名元组之前。

这是你应该带走的东西

  • Python 元组是 Python 中预装的四种数据结构之一。
  • 它用于在单个变量中存储多个值。
  • 元组创建后不能修改。它也是有序的,这意味着值具有预定义的顺序。

如果你喜欢我的作品,请在这里订阅https://medium.com/subscribe/@niklas_lang或者查看我的网站* 数据大本营 !此外,媒体允许你每月免费阅读三篇文章。如果你想让无限制地访问我的文章和数以千计的精彩文章,不要犹豫,通过点击我的推荐链接:【https://medium.com/@niklas_lang/membership】每月花$ 5 获得会员资格*

** **

每个新数据科学家都应该知道的 4 个基本 SQL 命令

原文:https://towardsdatascience.com/4-basic-sql-commands-every-new-data-scientist-should-know-ba02e40bfc1a

结构化查询语言简介

迈克尔·泽兹奇在 Unsplash 上的照片

在这篇文章中,您将发现对于关系型数据库的基本工作来说最重要的 SQL 命令。结构化查询语言(SQL) 是处理关系数据库时最常用的语言。不管它的名字是什么,这种语言不仅仅可以用于简单的查询。它还可以用于执行创建和维护数据库所需的所有操作。

结构化查询语言的优势是什么?

结构化查询语言提供了许多读取、修改或删除数据的功能。此外,许多分析师认为它优于其他语言,原因如下:

  • 它在语义上非常容易阅读和理解。即使是初学者也能在很大程度上理解这些命令。
  • 这种语言可以直接在数据库环境中使用。对于信息的基本工作,数据不必首先从数据库转移到另一个工具。简单的计算和查询可以直接在数据库中进行。
  • 与其他电子表格工具(如 Excel)相比,使用结构化查询语言的数据分析可以很容易地复制和拷贝,因为每个人都可以访问数据库中的相同数据。因此,相同的查询总是导致相同的结果。

SQL 提供了 Excel 电子表格中大多数执行的汇总和计算的替代方法,例如总计、平均或在列中查找最大值。这些计算也可以在多个数据集上同时进行。

我们使用什么样的样本数据?

为了能够实时测试最常见的 SQL 命令,我们使用来自 Kaggle 的信用记录数据集,它列出了各种匿名人的信用数据,如他们的收入、教育或职业。

我们将这个表作为 Pandas DataFrame 加载到我们的笔记本中,然后可以在上面测试常见的 SQL 命令:

如何查询数据?

使用“选择”可以查询完整的表。由于不需要查询任何特定的列,所以我们只需使用星号“*”,以便输出所有可用的列。在“LIMIT 10”的帮助下,我们确保 SQL 命令只返回前 10 行,否则会变得太混乱:

由于有大量的列,我们只限于“姓名 _ 收入 _ 类型”和“子女”列。我们可以通过显式指定来查询它们:

正如我们所看到的,一些收入类型在这些行中出现了两次。如果多个信用嫌疑人的收入类型相同,就会出现这种情况。

为了只获得收入类型的唯一条目,我们使用附加参数“DISTINCT”:

如何筛选数据?

可以使用“WHERE”参数过滤数据。根据数据类型,对此有不同的查询:

  • 可以使用大于号或小于号来比较数值,例如,“AMT_INCOME_TOTAL < 427500”. These can be supplemented with an equal sign, e.g. “AMT_INCOME_TOTAL < 427500”.
  • For texts or strings, the comparisons “=” or “<>”用于检查文本是否匹配(“=”)或不同(“<>”)。

对于所有收入超过$427,500 的信贷申请人,我们得到以下 SQL 命令:

为了能够在一个 SQL 命令中使用多个过滤器,我们可以用“and”或“or”将它们连接起来。通过这种方式,我们可以获得所有高收入的女性申请者:

如何对结果进行排序?

可以使用“ORDER BY”根据列对每个输出进行排序。数字和字符串都可以排序,然后按字母顺序排序:

默认情况下,输出总是按升序排序。要更改这一点,您还必须为降序指定“DESC ”:

记录怎么统计?

使用 SQL 命令“count ”,您可以计算列中或整个数据库中的值:

在这种情况下,我们在数据库中有 438,557 条记录。为了对列中的值进行计数,我们使用列的名称而不是星号“*”。此外,我们可以使用参数“DISTINCT”来只计算列中的唯一值:

因此,数据集中有 866 种不同的收入水平。

这是你应该带走的东西

  • 在处理关系数据库时,结构化查询语言是使用最广泛的语言。
  • 在 SQL 命令的帮助下,大量的数据查询可以被设计和个性化。

参考

  1. 信用卡审批预测CC0:公共域许可下

如果你喜欢我的作品,请在这里订阅https://medium.com/subscribe/@niklas_lang或者查看我的网站* 数据大本营 !还有,medium 允许你每月免费阅读 3 篇 。如果你希望有无限制的 访问我的文章和数以千计的精彩文章,不要犹豫,点击我的推荐链接:【https://medium.com/@niklas_lang/membership】每月花$5***获得会员资格**

* *

4 个可以简化查询的 BigQuery SQL 快捷方式

原文:https://towardsdatascience.com/4-bigquery-sql-shortcuts-that-can-simplify-your-queries-30f94666a046

检查您的数据库是否也有它们

来自 PexelsThisIsEngineering 摄影

开始学习 SQL 时,最常见的建议是练习基本语句,因为它们将跨多个数据库工作。缺点是您可能永远也不会发现可以简化查询的特定于数据库的语法,因为根本不需要阅读文档。对我来说就是这样,直到我开始使用 Google BigQuery,阅读了 SQL 语法文档,发现了一些你应该知道的惊人的快捷方式。

1.除...之外

在 SELECT *中使用 EXCEPT 来选择表中除外的所有字段。在下面的例子中,我创建了一个名为订单CTE ,并选择了中除之外的所有用于项目 _id项目 _ 名称

作者创建的 EXCEPT 查询示例的屏幕截图

在此之前,我将通过为 item_iditem_name 列出除之外的每一列来编写下面的选择。这看起来不像是有 6 列的捷径,但是想象一下,如果你有一个 20 列的表,而你只想排除 2 个字段。不用在 SELECT 语句中键入 18 个列名,只需使用 EXCEPT 来排除不需要的 2 列。

作者创建的不带 EXCEPT 查询示例的屏幕截图

2.在枢轴上转动

我不知道我从一个表中查询了多少次数据,然后输入到 Excel 中,使用数据透视表得到不同时间段的分类汇总。现在我可以用一个 PIVOT 语句绕过 Excel 轻松做到这一点。

屏幕截图示例生成由作者创建的数据

要使用上面的示例数据按季度计算销售额,您只需在数据透视表中指定季度。

作者创建的按季度透视的屏幕截图

或者,要按季度比较年与年的总销售额,您可以删除 product 列,并在 PIVOT 语句中指定年份。

作者创建的按年份划分的透视屏幕截图

3.卷曲

过去,我使用 Excel 数据透视表或运行多个查询来获得总计和小计,但现在我可以使用 ROLLUP 和 GROUP BY 来代替。使用上面显示的产品示例,我们可以在 GROUP BY 之后使用 ROLLUP ( year,quarter ) 获得每年的总销售额和小计。 20202021 的总销售额为 355 ,由季度列中的空值表示。 2020 销售额为 1992021156 ,由季度列中的空值表示。

使用作者创建的汇总按年度和季度显示的销售屏幕截图

4.具有资格;合格;取得资格(或学历)

QUALIFY 允许您像在 SELECT 语句中创建的列上应用 WHERE 条件一样应用它,因为它是在 GROUP BY、HAVING 和 WINDOW 语句 之后计算的

只需使用 QUALIFY = 1,您就可以使用 QUALIFY 来获取用等级窗口函数计算的季度销售额最高的产品。

作者使用 QUALIFY = 1 创建的屏幕截图

不使用 QUALIFY 的传统方法是将 SQL 语句作为子查询,然后应用 WHERE rank = 1,如下所示。用 QUALIFY 看起来简单多了,对吧?

作者使用 WHERE rank =1 创建的屏幕截图

最后的想法

了解 SQL 基础知识是很重要的,但是回顾一下文档,看看是否有特定于数据库的 SQL 语法可以简化您的查询,因为它们可能在其他数据库中可用。例如,雪花还有 PIVOT、ROLLUP 和 QUALIFY。我强调了一些 SQL 快捷方式,但我确信我只是触及了皮毛。你还能找到多少?

注意:以上所有查询都是在 BigQuery 沙箱 上运行的,这对任何拥有谷歌账户的人都是免费的。

你可能也会喜欢…

https://medium.com/swlh/how-i-used-a-machine-learning-model-to-generate-actionable-insights-3aa1dfe2ddfd </6-best-practices-i-learned-as-a-data-engineer-9d3ad512f5aa>

4 机器学习模型部署中再现性的挑战

原文:https://towardsdatascience.com/4-challenges-of-reproducibility-in-the-machine-learning-model-deployment-3b4ca7b975c8

照片由 Unsplash 上放大

在机器学习模型的管道中,有几个我们考虑的环境——研究环境、开发环境和生产环境。在研究环境中,执行模型开发的不同组成部分,例如探索性数据分析(EDA)、模型构建、模型评估和结果分析。在开发环境中,在生产环境中向客户提供/展示模型之前,检查模型性能的质量,尤其是再现性。

机器学习(ML)部署中的再现性表明在给定相同输入数据的情况下,机器学习模型将在研究和生产环境中提供相同的结果。为了确保基于 ML 的模型部署中的再现性,我们不仅要确保模型训练时的再现性,还必须确保 ML 管道的其他组件中的再现性,包括数据收集、特征工程、特征选择和模型部署过程,参见图 1。

机器学习管道中的再现性(图片由作者提供)

再现性对于开发基于 ML 的管道以提供研究的正确性、可信度和基线是至关重要的。我们预期具有相同数据和过程的 ML 模型将提供相同的结果;否则,整个模型的正确性和可信度都会受到质疑。在科学研究中,我们经常报告我们的发现,并将其与基线模型进行比较,以说明我们提出的工作的优越性。如果 ML 模型不可复制,那么进行比较分析是不公平的。

在本文中,我们将讨论任何 ML 管道的主要组件面临的挑战和潜在解决方案,在这些组件中,我们必须确保再现性:

  1. 再现性—数据收集

数据收集是再现性的主要挑战之一。数据是构建 ML 的关键组成部分,也是实现再现性的最大挑战。如果使用相同的数据来训练 ML 模型,则 ML 模型仅再现完全相同的结果。但是,由于数据库不断更新,训练数据无法再现,而且在许多情况下,数据的顺序并不像 SQL 中那样固定。

潜在解决方案— 我们可以将训练数据集保存在另一个存储中,将动态数据转换为静态数据,解决数据加载中的不一致问题。然而,这种方法也有局限性,比如数据伦理。在另一个地方存储数据可能违反欧盟的一般数据保护规则(GDPR) 。另一方面,存储数据对于大规模数据集来说并不是一个可行的解决方案。因此,我们必须寻找其他解决方案,比如设计带有准确时间戳的数据源。此外,我们可以在数据的顺序上使用一些条件来加载数据。

2。再现性—特征工程

在大多数情况下,对数据进行预处理时会发现缺乏再现性。在以下情况下,可能会出现缺乏再现性的情况

  • 替换数据集中要素的缺失值
  • 根据用于替换缺失值的要素计算统计汇总
  • 检测异常值

潜在解决方案— 我们应该应用不同的策略来保持再现性,同时进行特征工程:

  • 对于训练和测试数据的缺失值插补,我们应该始终考虑训练数据的汇总统计
  • 在将数据分成训练集或测试集时,将种子值设置为固定值。此外,还设置了一个固定的种子数量,而工作的随机性
  • 我们应该在编码时始终实践标准,比如使用版本控制和时间戳散列版本

我写了一篇关于如何在特征工程中避免缺乏可重复性的实践文章:避免数据预处理步骤中的数据泄漏

3。再现性—模型训练

模型训练是 ML 管道中的另一个组成部分,在这里我们遇到了再现性的挑战。许多机器学习模型,包括基于神经网络(NN)和深度学习(DL)的方法,在模型训练的不同部分使用随机性。例如,神经网络模型训练中的初始化权重矩阵是随机的。

潜在解决方案—

  • 我们可以通过设置种子值来控制模型的随机化
  • 应该详细给出关于模型训练的信息,例如特征的顺序、不同的特征变换和模型超参数

4。再现性—模型部署

在部署模型时保持可再现性有几个挑战:

  • 硬件环境——在某些情况下,ML 模型的再现性取决于开发阶段使用的硬件。因此,遵循相同的硬件设置是对再现性的挑战
  • 软件环境—在研究环境中使用不同的编程语言,这些语言在生产环境中可能不可用—这对可重复性是一个挑战
  • 真实环境中缺失的要素-在某些情况下,用于模型训练的所有要素可能无法用于生成实时结果

潜在解决方案—

  • 记录所有软件相关信息,包括不同软件包的版本,并在部署时匹配软件版本
  • 使用容器(例如,Docker)
  • 在管道的所有环境(研究和生产环境)中使用相同的编程语言
  • 使用训练数据的汇总统计来估算缺失的特征

总之,我们可以保证 ML 模型结果的再现性,然而,实践上述标准方法将有助于最小化模型部署中再现性的缺乏。

阅读默罕默德·马苏姆博士(以及媒体上成千上万的其他作家)的每一个故事。

你的会员费将直接支持和激励穆罕默德·马苏姆和你所阅读的成千上万的其他作家。你还可以在媒体上看到所有的故事—【https://masum-math8065.medium.com/membership】

快乐阅读!

参考

  • UDEMY-机器学习模型的部署
  • 奥洛里萨德,B. K .,布雷顿,p .,,安朵斯,P. (2017)。基于机器学习的研究中的再现性:文本挖掘的一个例子。

4 种可能已经存在于代码中的代码味道

原文:https://towardsdatascience.com/4-code-smells-that-are-probably-already-in-your-code-ae75dea3fe32

通过重构常见的代码味道产生干净的代码

马库斯·斯皮斯克Unsplash 上拍摄

缺乏经验、仓促的截止日期或错过代码审查只是可能导致您创建构思不佳的代码的几个因素,即所谓的“代码味道”

要修复这些“气味”,你必须打开你的 IDE,检查你的代码,并找出你的代码的哪一部分受到影响。

虽然代码味道不会立即破坏你的应用程序,但它可能会导致将来的错误,因为它可能会使代码不可读和不可维护。此外,实现新功能将会更加复杂,花费更长的时间,并引入更多的错误。

本文将讨论四种流行的代码味道,并解释可能出现的问题。我将详细描述每一个,提供实例,并展示如何修复它们。

为了突出代码的味道,我使用了 JavaScript,但是它们存在于每一种编程语言中!

神奇的数字

幻数是软件开发人员分配给代码中变量的值,用来做“一些事情”。它们总是有一些意义,但是如果编写代码的软件开发人员离开了,没有人会记得它。虽然它们被称为幻数,但这种代码味道包括了每一种原始数据类型,如CharStringBoolean等。

最重要的是要明白你的代码在任何时候都是可读的。使用神奇的数字将会阻止你的同事甚至是你在未来的工作和改变。

为了更好地理解这个问题,请查看下面的代码片段:

let a = "1534";

for(let i = 0; i < 4; i++) {
    send(a[i])
}

这是一个相当愚蠢的例子,但它应该足以说明问题。代码遍历输入字符串a中的每个字符,并为每个字符调用send()。然而,for 循环是从 0 - 3 开始的,因为输入字符串有 4 个字符,并且您想要迭代整个字符串。

实现这个循环的开发人员确实使用了这个神奇的数字,因为输入总是 4 个字符长。这个限制在这个代码片段中是有意义的,但是如果字符串a由于某种原因改变,将来可能会引入一些奇怪的错误。

缺乏规划使得代码无法扩展。

然而,代码片段中的一个简单变化会产生很大的不同:

let a = "1534";

for(let i = 0; i < a.length; i++) {
    send(a[i])
}

通过删除幻数,for 循环遍历输入字符串的长度。现在,代码可以扩展,适用于任何输入字符串,并且是面向未来的。

幻数的另一个问题是代码可读性:

const totalCost = order.getCost() * 1.19;

你可能会问自己 1.19 的值从何而来,为什么一个订单的成本要乘以这个值。也许你可以做一些有根据的猜测,但你能做的只有这些:猜测

这个神奇的数字是个问题,因为:

  • 你不能确定这个号码是做什么用的
  • 如果多次使用,将很难更改此号码

要解决这个问题,您可以记录代码行并解释这个数字,或者通过用一个 mnemotechnic 名称定义一个常数并使用它来替换这个幻数。始终选择第二个选项,因为常量很容易重用和更改:

const OVERALL_PROFIT_MARGIN = 1.19

const totalCost = order.getCost() * OVERALL_PROFIT_MARGIN 

对这个神奇数字的修正很容易,这将有助于理解在总成本计算的末尾增加了一个固定利润率。如果您之前猜测 1.19 会将税率添加到订单中,那么您就错了,因为这已经包含在订单成本中了。

对于任何字符串、数字或其他数据类型,如果在没有适当文档的情况下使用它们的原始表示,都应该进行这种重构。

几个月后,它会帮助每个人阅读你的代码,甚至是你自己。

重复的逻辑/代码

每个软件开发人员都应该知道几种技术来避免在整个软件项目中创建重复的代码。应该敲响警钟的一个明显迹象是复制粘贴任何逻辑。如果发生这种情况,您应该将其抽象成函数,并通过调用新创建的函数来替换用法。

但是,如果你不是在复制代码,而是在复制逻辑,你会怎么做?

在软件团队中,经常会有许多不同的开发人员从事软件的某些部分。通常,他们会遇到相同的问题,并实现一个有良好文档记录、可读性和可维护性的解决方案。

为了演示这个问题,假设您正在处理一个大型软件项目,并且使用了多个console.log实例。现在您想使用一种更好的方法来记录您的错误、警告和信息。现在,您在utils.js文件中创建了一个新的全局日志功能:

const log = (message) => {
    if(LOG_ENABLED) {
        console.log(message)
    }
}

从现在开始,你可以导入你的utils.js文件,使用你的log函数来记录任何事情,也可以通过调整全局常量LOG_ENABLED来完全停止日志输出。

由于您与许多开发人员一起工作,另一个开发人员可能也考虑到了这一点,并实现了另一个日志功能:

const log = (message) => {
 if(NODE_ENV === 'production') {
     console.log(message)
    }
}

不幸的是,另一个开发人员创建了一个新文件log.utils.js来存储他的日志功能,并在需要的地方使用它。

您将最终实现两个日志记录函数,它们使用不同的变量来检查日志是否被启用。如果您现在想要允许日志消息,但是没有更新NODE_ENV,,您将只能看到一些日志,并且会疑惑为什么没有生成其他日志消息。

记住:重复代码是不好的,但是重复逻辑更糟糕。

识别这种问题要困难得多,潜在的解决方案需要大量的工作(或返工)。尝试总是谈论、计划和协调添加影响整个软件项目的新特性。

一个功能是统治他们所有人

如果“一个戒指统治所有人”在指环王中对任何人都不起作用,为什么它应该对你的软件项目起作用?

在一个软件项目中,避免使用元函数来统治…我的意思是,包含所需的业务逻辑的每一部分。理想情况下,每个功能应该只处理一件事情,并且有一个单一的职责。如果设计任何类或函数,你应该总是问自己:

  • “这个阶层为什么存在?”
  • “这个函数解决哪个问题?”

Robert C. Martin 有一句名言,在实现类、模块或函数时,你应该经常考虑:

“一个类(,模块,或者函数)应该只有一个改变的理由。”

这是因为如果你遇到任何问题,你会知道在哪里搜索它。此外,如果您必须更改一些逻辑、修正一些计算或删除一个依赖项,您可以在没有任何影响的情况下这样做。

就像用乐高积木一样。如果你只有一个大的,想改变一个单一的东西,那是不可能的。但是如果你用你能买到的最小的积木,你可以毫无问题地把一些积木换成其他积木。

将软件项目和功能与乐高积木进行比较非常有效,因为你的积木越小,你在构建任何东西时就有越大的灵活性!

听说过单一责任原则 (SRP)吗?这个原则定义了你在软件项目中实现的所有东西都应该只有一个单一的职责(无论是函数、模块、类,还是你代码中的任何结构)。这意味着函数只做一件事,而类(或模块)将多个与同一任务相关的函数组合在一起!

例如,如果您正在与一家网店合作,并希望实现付款工作流,您有几种方法来实现这一点:

  1. 创建一个名为makePayment的新功能,它集成了完整的支付网关并集中了所有逻辑。它将在一个地方包含成功支付的所有内容,并将有几千行代码长。
  2. 将每个部分集成到它的类中,分成不同的模块,每个模块专用于一个网关。这将保持代码整洁,但也增加了可维护性,因为许多工作流可能有许多共同点,或者使用可以抽象和重用的公共概念。
  3. 创建一个单一的支付工作流程,其中每个类或模块为每个网关集中单独的功能或方法。

就 SRP 而言,选项 2 是最合适的,因为责任是处理付款。此外,这将是选项#1 和选项#2 之间的权衡。此外,它将使代码分布在不同的结构中,但在单个逻辑组中是可管理的。您将不必维护大量的逻辑,并且可以在互不影响的情况下重构或分离更多的部分。

永远记住: SRP 是关于责任,而不是把所有事情都放在一个单一的功能中。

长参数列表

在一个函数调用(或类)中有一个很长的参数列表是一件令人讨厌的事情。并且应该尽快删除!

通常一个很长的参数列表表明实现有问题,或者几个算法被合并到一个方法中(这是违反 SRP 的!).

官方并没有具体规定多少才算多,但通常情况下,你应该永远不要使用超过三个或四个。每次将参数列表长度增加到 5 时,都应该重构这个函数(或类)。

让我们看看下面的代码片段,它从几个值创建了一个用户:

const createUser = (username, password, state, city, street, nr) => {
  // ...   
}

创建用户需要六个不同的值:usernamepasswordstatecitystreetnr。现在,代替使用这个参数列表,该方法可以使用另一个数据结构作为输入来创建将减少所使用的参数的用户:

const createAddress = (state, city, stree, nr) => {
    // ...
}

const createUser = (username, password, address) => {
    // ...
}

通过这一更改,您将拥有两个独立的功能,承担一项责任,并且只包含属于一起的参数。一个新的函数将创建 address 对象,然后将其作为参数传递给用户,而不是将地址分配给用户。

但是为什么要这样做呢?

因为它会产生一些收益:

  • 可读性更强,代码更短
  • 重构可能会暴露出以前没有注意到的重复代码!

结束语

在我们作为软件开发人员、工程师或领导的职业生涯中,我们经常需要在没有计划的情况下编写代码。结果往往是我们最终产生了代码味道。

有时代码味道可以很容易地被识别和重构,但是在某些情况下,它们可能需要大的重构。解决它们的最好方法是意识到它们,并在它们成为软件项目中的问题之前发现它们。在开始一个新特性之前,花时间规划实现和研究。

通常,几行额外的代码、1 个小时的额外研究或 15 分钟的给另一个团队成员打电话可以在项目后期节省几个小时的头痛时间。

在实现新功能之前花点时间,因为你以后会感谢你自己!

你呢?你还有其他我应该在这里提到的代码气味吗?此外,您对提到的代码气味有任何疑问吗?我很想听听你的想法。请在评论中分享一切。

请随时在我的博客LinkedInTwitterGitHub 上与我联系。

本文原载于我的博客https://www . paulsblog . dev/4-code-smokes-that-is-possible-in-your-code/

我从数据科学顾问那里学到的 4 条重要经验

原文:https://towardsdatascience.com/4-crucial-lessons-i-learned-from-a-data-science-consultant-bbfd21257c83

数据科学咨询

在与数据科学顾问合作后,我看到了我在之前的数据科学项目中错过的宝贵价值,这导致了一次不太愉快的经历

娜塔莉·佩迪戈在 Unsplash 上的照片

两个月前,我的团队聘请了一家数据科学咨询公司开展新的数据科学项目。顾问将开发机器学习模型和整个管道。在与顾问工作的两个月中,我从他那里学到了技术技能和提供咨询以及与技术和非技术人员合作的技巧。

顾问是傅奇川。除了提供咨询,他还撰写了关于数据科学、Python、R 和 Tableau 的各种文章。

我从 Chee Chuan 学到的第一个教训是,协商的双方都应该从对方那里得到期望和假设🤝。

假设来自双方,而不仅仅是客户。

例如,客户认为顾问具有提供主题见解的专业知识。然后顾问,在这种情况下,数据科学顾问,期望客户提供足够的数据进行分析。还需要相关业务流程、逻辑和知识的共享。没有这些,顾问就不能开发模型,甚至不能启动项目。

为了使咨询成功,客户和顾问应该始终理解对方的要求并提供必要的支持。

我学到的第二课是要自信😎。当被复杂的业务流程轰炸或在开发过程中遇到问题时,顾问永远不会失去信心或方向。他把挑战当成学习的机会。数据科学项目充满了不确定性,他总是保持冷静,通过研究来克服这个问题。他总是保持冷静,不慌不忙地整理信息,集思广益。然后,只要他觉得有必要,就询问更多的信息。

这是我在从事第一个数据科学项目时错过的重要价值之一。当有这么多不同的业务流程和许多我不理解的东西时,我感到害怕。我甚至不敢向商业用户询问更多的信息,因为我担心他们会觉得我没有能力,这让我很难相处,我变得很难共事。

事实是,他们非常乐意提供帮助,而最好的做法是让问题浮出水面,因为每个人都希望项目完成或问题得到解决。

我学到的第三课来了。我们应该相信自己,计划好每项任务的时间,并在问题可能影响项目时间表时提出来。毕竟,数据科学项目需要团队合作,而不是单打独斗。尤其是当你在一个庞大的组织中,你将需要来自各方的帮助和支持。

例如,数据库管理员提供对数据库的访问,它向所需的应用程序提供许可,然后主题专家提供所有相关的业务知识、流程和逻辑。不知道一些事情总是没关系的,这仅仅意味着你正在学习新的知识🔥!

第四课是注重细节。我不仅从车川身上看到了这种价值观,甚至我的父亲也警告我,如果我不注重细节,我有时可能会制造麻烦😅。我父亲警告我,因为我前几天发给他的信息中有一个打印错误。他说今天你在信息中打了一个错字,但没有改正。将来,你可能会在数据输入中出错,1000 万美元和 10 美元有很大的区别。

好吧,让我们回到车川。相比我,他确实是一个非常注重细节的人。他关注每一个细节,研究商业利益相关者提供的每一个公式。他甚至设法在提供的信息中发现了一些错误。这是因为提供的信息不完整,使得逻辑不匹配。我尊重他注重细节的风格,并努力向他看齐😊。

简而言之,这是我从车川中学到的四个教训,

  1. 在咨询中,假设来自顾问和客户。要使咨询成功,这两个假设都需要满足。
  2. 要自信,把每一次挑战都当成机会。
  3. 趁还不算太晚,把问题提出来。
  4. 注重细节,一个小错误会带来大麻烦。

我希望我的经历也能激励你(愿原力与你同在)😊).

Chee Chuan 是真正的专业数据科学顾问。我为有机会和他合作而感到幸运。向他致以最好的祝愿!

祝贺并感谢你阅读到最后。希望你喜欢这篇文章。😊

梁杰森Unsplash 上的照片

4 使用 Scikit-learn 的数据预处理操作

原文:https://towardsdatascience.com/4-data-preprocessing-operations-with-scikit-learn-5d26bf1442dd

通过使数据正确来帮助算法

哈里·格劳特号航天飞机上的照片

数据预处理是机器学习管道中的一个基本步骤。这取决于所使用的算法,但总的来说,我们不能或不应该期望算法在原始数据中表现良好。

如果原始数据处理不当,即使结构良好的模型也可能无法产生可接受的结果。

有些人可能会考虑使用术语数据准备来涵盖数据清理和数据预处理操作。本文的重点是数据预处理部分。

例如,一些算法要求将数字特征缩放到相似的级别。否则,它们往往会更加重视具有较高价值范围的特征。

考虑一个房价预测任务。房屋面积通常在 1000 到 2000 平方英尺之间,而在大多数情况下,年龄小于 50 岁。为了防止机器学习模型更加重视房屋面积,我们会将这些特征缩放到给定的最小值和最大值之间,例如 0 和 1 之间。这个过程被称为最小最大缩放。

我们将介绍 4 种常用的数据预处理操作,包括解释如何使用 Scikit-learn 进行这些操作的代码片段。

我们将使用一个银行流失数据集,该数据集可在 Kaggle 上获得创意共享许可。请随意下载并继续。

读取数据

import pandas as pd

# Read the dataset (only 5 columns) into a Pandas DataFrame
churn = pd.read_csv(
    "BankChurners.csv",
    usecols=["Attrition_Flag", "Marital_Status", "Card_Category", "Customer_Age", "Total_Trans_Amt"]
)

churn.head()

数据框的前 5 行(作者提供的图像)

这里要提到的一件非常重要的事情是训练-测试分裂,这对于评估模型性能是至关重要的。就像我们用数据训练模型一样,我们用数据来衡量它们的准确性。但是,我们不能将相同的数据用于培训和测试。

在训练模型之前,我们应该留出一些数据进行测试。这被称为训练测试分割,必须在任何数据预处理操作之前完成。否则,我们将导致数据泄漏,这基本上意味着模型学习测试数据的属性。

因此,所有以下操作必须在列车测试分离后进行。想想我们拥有的数据框架,它只包含训练数据。

1.处理缺失值

现实生活中的数据集很可能包含一些缺失的值。有两种方法来处理它们,即删除缺失的值并用适当的值替换它们。

一般来说,后者更好,因为数据是基于数据的产品中最有价值的资产,我们不想浪费它。替换缺失值的合适值取决于数据集的特征和结构。

我们使用的数据集没有任何缺失值,所以让我们故意添加一些值来演示如何处理它们。

import numpy as np

churn.iloc[np.random.randint(0, 1000, size=25), 1] = np.nan
churn.iloc[np.random.randint(0, 1000, size=25), 4] = np.nan

churn.isna().sum()

# output
Attrition_Flag      0
Customer_Age       24
Marital_Status      0
Card_Category       0
Total_Trans_Amt    24
dtype: int64

在上面的代码片段中,一个包含 25 个随机整数的 NumPy 数组用于选择第二列和第五列中的值被替换为缺失值(np.nan)的行的索引。

在输出中,我们看到这些列中有 24 个缺失值,因为 NumPy 数组是随机生成的,可能包含重复值。

为了处理这些缺失值,我们可以使用 SimpleImputer 类,它是单变量特征插补的一个示例。简单估算器提供了估算缺失值的基本策略,可以使用提供的常数值进行估算,或者使用缺失值所在的每列的统计数据(平均值、中值或最频繁值)进行估算。

让我们用列的平均值来代替缺失的值。

from sklearn.impute import SimpleImputer

# Create an imputer
imputer = SimpleImputer(missing_values=np.nan, strategy='mean')

# Apply it to the numeric columns
numeric_features = ["Customer_Age", "Total_Trans_Amt"]
churn[numeric_features] = imputer.fit_transform(churn[numeric_features])

churn.isna().sum()

# output
Attrition_Flag     0
Customer_Age       0
Marital_Status     0
Card_Category      0
Total_Trans_Amt    0
dtype: int64

在上面的代码片段中,使用 mean 策略创建了一个简单的估算对象,这意味着它使用列的平均值来估算缺失值。然后,我们用它来替换“客户年龄”和“总交易金额”列中缺失的值。

Scikit-learn 还提供了更复杂的输入缺失值的方法。例如,迭代插补器类是多变量特征插补的一个示例,它将每个具有缺失值的特征建模为其他特征的函数,并使用该估计值进行插补。

2.标准化

我们提到,与其他特性相比具有更高值范围的特性可能被赋予更高的重要性,这可能会产生误导。此外,当要素处于相对相似的比例时,模型往往表现更好,收敛更快。

处理具有非常不同的值范围的要素的一个选项是标准化,这基本上意味着通过移除每个要素的平均值来转换数据以使其居中,然后通过将非恒定要素除以其标准偏差来缩放数据。生成的要素的标准差为 1,平均值非常接近于零。因此,我们最终得到的特征(即数据集中的变量或列)几乎呈正态分布。

让我们将 Scikit-learn 的 StandardScaler 类应用于客户年龄和总交易量列。正如我们在下面的输出中看到的,这两列具有非常不同的值范围。

churn[["Customer_Age", "Total_Trans_Amt"]].head()

(图片由作者提供)

让我们对这些特性应用标准化,然后检查这些值。

from sklearn.preprocessing import StandardScaler

# Create a scaler object
scaler = StandardScaler()

# Fit training data
scaler.fit(churn[["Customer_Age", "Total_Trans_Amt"]])

# Transform the feature values
churn[["Customer_Age", "Total_Trans_Amt"]] = scaler.transform(churn[["Customer_Age", "Total_Trans_Amt"]])

# Display the transformed features
churn[["Customer_Age", "Total_Trans_Amt"]].head()

(图片由作者提供)

我们还可以检查变换后要素的标准差和平均值。

churn["Customer_Age"].apply(["mean", "std"])

# output
mean   -7.942474e-16
std     1.000049e+00
Name: Customer_Age, dtype: float64

标准偏差为 1,平均值非常接近预期的 0。

3.缩放比例

将数值范围提高到类似水平的另一种方法是将它们缩放到特定的范围。例如,我们可以将每一列压缩到 0 和 1 之间,使得缩放前的最小值和最大值在缩放后变成 0 和 1。这种缩放可以通过 Scikit-learn 的 MinMaxScaler 来实现。

from sklearn.preprocessing import MinMaxScaler

# Create a scaler object
mm_scaler = MinMaxScaler()

# Fit training data
mm_scaler.fit(churn[["Customer_Age", "Total_Trans_Amt"]])

# Transform the feature values
churn[["Customer_Age", "Total_Trans_Amt"]] = mm_scaler.transform(churn[["Customer_Age", "Total_Trans_Amt"]])

# check the feature value range after transformation
churn["Customer_Age"].apply(["min", "max"])

# output
min    0.0
max    1.0
Name: Customer_Age, dtype: float64

正如我们在上面的输出中看到的,这些特性的最小值和最大值分别是 0 和 1。MinMaxScaler 的默认范围是[0,1],但是我们可以使用 feature_range 参数来更改它。

StandardScaler 和 MinMaxScaler 对异常值不稳健。假设我们有一个值在 100 到 500 之间的特性,其异常值为 25000。如果我们用MinMaxScaler(feature_range=(0,1))缩放该特性,25000 被缩放为 1,所有其他值变得非常接近下限,即零。

因此,我们最终得到了一个不成比例的比例,这对模型的性能产生了负面影响。一种解决方案是移除异常值,然后应用缩放。然而,删除异常值并不总是一个好的做法。在这种情况下,我们可以使用 Scikit-learn 的 RobustScaler 类。

顾名思义,RobustScaler 对异常值具有鲁棒性。它会移除中位数,并根据分位数范围(默认为 IQR:四分位数范围)缩放数据。IQR 是第一个四分位数(第 25 个四分位数)和第三个四分位数(第 75 个四分位数)之间的范围。RobustScaler 不会以预定的时间间隔限制缩放范围。因此,我们不需要像对 MinMaxScaler 那样指定一个范围。

4.一键编码

我们经常使用具有分类特征的数据集,这些数据集也像数字特征一样需要一些预处理。

一些算法期望分类变量采用数字或一键编码格式。标签编码简单地说就是将类别转换成数字。例如,值为 S、M 和 L 的尺寸要素将被转换为值为 1、2 和 3 的要素。

如果分类变量不是有序的(也就是说,它们没有等级顺序),标签编码是不够的。我们需要使用一键编码对名义分类变量进行编码。

考虑前面的例子,我们对婚姻状况特征进行了标签编码。未知状态编码为 3,而已婚状态编码为 1。机器学习模型可能会将此评估为未知状态优于或高于已婚状态,这是不正确的。这些值之间没有等级关系。

在这种情况下,最好进行一键编码,为每个类别创建一个二进制列。让我们把它应用到婚姻状况一栏。

from sklearn.preprocessing import OneHotEncoder

# Create a one-hot encoder
onehot = OneHotEncoder()

# Create an encoded feature
encoded_features = onehot.fit_transform(churn[["Marital_Status"]]).toarray()

# Create DataFrame with the encoded features
encoded_df = pd.DataFrame(encoded_features, columns=onehot.categories_)

# Display the first 5 rows
encoded_df.head()

(图片由作者提供)

由于婚姻状况列中有 4 个不同的值(离婚、结婚、单身、未知),因此创建了 4 个二元列。婚姻状况列的第一个值是“已婚”,因此第一行中已婚列的值为 1。第一行中的所有其他值都是 0。

需要提及的一件重要事情是 drop 参数。如果一个分类列中有 n 个不同的值,我们可以对 n-1 列进行一次热编码,因为其中一列实际上是冗余的。例如,在上面的输出中,当 3 列的值为 0 时,则该行属于第四列。我们实际上不需要第四纵队来了解这一点。我们可以使用 OneHotEncoder 的 drop 参数删除其中一列。

结论

我们已经学习了机器学习中一些最常见的数据预处理操作,以及如何使用 Scikit-learn 库来执行这些操作。

你可以成为 媒介会员 解锁我的全部写作权限,外加其余媒介。如果你已经是了,别忘了订阅https://sonery.medium.com/subscribe如果你想在我发表新文章时收到电子邮件。

感谢您的阅读。如果您有任何反馈,请告诉我。

防止过度拟合的 4 种有效方法及其工作原理

原文:https://towardsdatascience.com/4-effective-ways-to-prevent-overfitting-and-why-they-work-f6e3b98aefda

构建有用的机器学习模型

过度拟合会导致你的模型错过目标,照片由 Unsplash 上的 engin akyurt 拍摄

介绍

在这篇文章中,我将分享在构建机器学习(ML)模型时可以避免过度拟合的四种实用方法,以及它们为什么有效。

过度拟合是一种不希望出现的情况,当模型拟合得过于接近训练数据,以至于无法很好地推广到新的示例,即无法为以前未见过的数据集提供准确的预测。

面对现实吧,过度拟合让 ML 模型无法使用。

检测过度拟合的最常见方法是通过比较训练和测试数据集上的模型性能。与训练集相比,过度拟合的模型在测试集上将具有明显更差的性能。

4 防止过度拟合的有效方法

作者图片

为了构建有用的 ML 模型,我们需要有效地解决过度拟合问题。以下是一些避免过度拟合模型的实用方法:

  1. 添加更多数据

是的,增加训练样本的数量是减少过度拟合的可靠方法。除非训练集正确地代表了整体数据中的真实模式,否则您的模型可能会过于接近有限的数据,从而使其无法通用化到未经训练的新数据集。

这可以通过收集新样本(这在某些应用中可能很困难)或数据扩充(这将产生现有样本的变体)来实现。例如,在图像分类任务中,已经发现数据扩充可以显著提高模型性能。

工作原理:随着数据量的增加,该模型倾向于更一般化,因为它适合训练样本的较小部分。

2.调整超参数

复杂的 ML 模型通常比简单的模型更精确,但是前者更容易过度拟合。

在这种情况下,当超参数越多或训练时间越长时,ML 模型变得越复杂。超参数的值控制学习过程,不能从数据中估计,并且在模型之外。因此,它们是在训练开始前设置的。

该解决方案取决于算法类型,可以通过设置最佳超参数值来实现。一些常见的例子包括:

  • 树方法(决策树、随机森林、LGBM、XGBoost): 减少每棵树的最大深度(即每棵树的叶子数)。
  • 神经网络:早期停止(较早停止训练过程)和减少隐层数量(去掉部分神经元)。
  • K 最近邻(KNN): 增加 K 的值

工作原理:通过调整超参数可以降低模型的复杂性,从而减少过度拟合的机会。例如,越早停止训练过程,模型越简单。在 KNN 的情况下,增加 K 的值降低了模型对局部模式的敏感性,因为在训练过程中使用了更多的邻居。这使得模型对于新的数据集更具普适性,从而减少过度拟合。

3.减少特征数量

过度拟合可能是由具有大量特征的有限数据量造成的。但是,减少要素的数量可能会导致重要信息的丢失,因此必须谨慎操作。

一种想法是在探索性数据分析期间手动移除预测能力低的特征。与目标变量具有更强相关性的特征具有更强的预测能力。此外,可以使用特征重要性分数和互信息来测量预测能力。

此外,可以使用诸如主成分分析(PCA)的技术来降低数据的维度。使用这种方法,可以选择分量的数量,使得仅选择贡献重要信息(解释的方差)的特征。然而,PCA 导致变换特征的可解释性的损失。

工作原理:使用较少的特征降低了模型的复杂性,有助于防止过度拟合。

4.正规化

该方法用于通过惩罚对学习过程贡献很小或没有贡献的特征来约束 ML 模型的复杂性。

一些正则化类型包括 L1(最小绝对收缩和选择算子——套索)、L2(脊)和专门用于神经网络的下降

LASSO 将不太重要的要素的贡献缩小到零,从而消除了这些要素,而 Ridge 则减少了这些要素的贡献。关于正规化的更多细节可以在这里找到。

工作原理:正则化限制了模型的复杂性,从而减少了过度拟合的机会。

结论

我们已经介绍了解决过度拟合的四种有效方法以及它们为什么有效。这些方法包括添加更多数据、调整超参数、减少特征数量和正则化。还提供了一些资源链接供进一步学习。

我希望这篇文章有深刻的见解,直到下一次。干杯!

你可以通过下面我的推荐链接订阅 Medium,获得更多我和其他作者的启发性文章,这也支持我的写作。谢谢大家!

https://aolaoye.medium.com/membership

帮助您理解嵌套循环的 4 个示例

原文:https://towardsdatascience.com/4-examples-to-help-you-understand-nested-loops-94bb7df797c4

对嵌套 for 循环如何工作以及如何将它们用于各种任务有更好的直觉和理解。

布伦特·德·兰特在 Unsplash 上拍摄的照片

嵌套的 for 循环迭代多个索引,例如行和列。具有两个级别的嵌套循环有一个内循环,该内循环在外循环的每次迭代中执行。理论上,您可以在任意多的层中嵌套一个循环,但是很难跟踪在两层以上的循环中会发生什么。

对于大多数任务,可以使用矢量化运算或更有效的内置函数。但是,如果您正在努力理解嵌套循环的内部工作原理,我希望这些例子可以帮助您更好地理解嵌套 for 循环的工作原理,以及如何将它们用于各种任务。

你可以在这个 Github repo 中找到本文使用的代码。

我们将通过使用嵌套的 for 循环来解决以下四个任务:

  1. 创建乘法表
  2. 矩阵加法
  3. 创建希尔伯特矩阵
  4. 找出伯努利数

在进入示例之前,让我们使用一个嵌套的 for 循环来迭代这个小矩阵。它将打印每个元素的位置(索引)和它的值,这样我们就可以看到嵌套的 for 循环在矩阵上的迭代顺序。

作者图片

作者图片

正如您所看到的,外部循环遍历所有行,对于每一行,内部循环遍历该行的所有元素。在这种情况下,当我们循环一个矩阵时,我们遵循命名索引 ij 的惯例,这就是在数学中索引矩阵的方式。但是你可以给它们起任何你想要的名字,这有助于你记住迭代的顺序。

乘法表

让我们从一个简单的例子开始,它的输入、迭代和输出都非常简单。我们将创建一个乘法表。

  • 我们指定表的大小,并创建一个矩阵来保存这些值
  • 创建一个嵌套的 for 循环,外部循环遍历行,内部循环遍历列
  • 通过将每个行索引乘以列索引来计算矩阵中每一项的值,并将它们存储在矩阵中

作者图片

让我们来分解一下每个循环中发生了什么。

**Outer loop, loop 1**, **for i=1:** The first outer loop stays on index i=1 (row 1) and the inner loop iterates over the entire length of index j, the columns. That is, we iterate over each j element (j=1 to j=n) in this row (i=1):
    **Inner loop: The inner loop will iterate from j=1 to j=n**:
    i=1, j=1, multiplies i=1 with j=1 and assigns value to mult_table[row i=1, col j=1]
    i=1, j=2, multiplies i=1 with j=2 and assigns value to mult_table[row i=1, col j=2]
    i=1, j=3, multiplies i=1 with j=3 and assigns value to mult_table[row i=1, col j=3]
    ...
    i=1, j=1n, multiplies i=1 with j=n and assigns value to mult_table[row i=1, col j=n]**Outer loop, loop 2**, **i=1:** The second outer loop stays on index i=2 (row 2) and the inner loop iterates over the entire length of index j, the columns:    
    **Inner loop: The inner loop will iterate from j=1 to j=n**:
    i=2, j=1, multiplies i=2 with j=1 and assigns alue to mult_table[row i=2, column j=1]
    i=2, j=2, multiplies i=2 with j=2 and assigns value to mult_table[row i=2, column j=2]
    i=2, j=3, multiplies i=2 with j=3 and assigns value to mult_table[row i=2, column j=3]
    ...
    i=2, j=n, multiplies i=2 with j=n and assigns value to mult_table[row i=2, j=n]

循环继续像这样迭代,每行的列中的每个元素,直到我们迭代完最后一行 n。

**Outer loop, loop n**, **i=n:** The last outer loop stays on index i=n (row n) and the inner loop iterates over the entire length of index j, the columns:
    **Inner loop: The inner loop will iterate from j=1 to j=n**:
    i=n, j=1, multiplies i=n with j=1 and assigns value to mult_table[row i=n, col j=1]
    i=n, j=2, multiplies i=n with j=2 and assigns value to mult_table[row i=n, col j=2]
    i=n, j=3, multiplies i=n with j=3 and assigns value to mult_table[row i=n, col j=3]
    ...
    i=n, j=n, multiplies i=10 with j=n and assigns value to mult_table[row i=n, col j=n]

在这个嵌套的 for 循环中,我们一次填充乘法表的一行,从左到右将值添加到列中。行 I 的每次迭代包含或嵌套了列 j 的 10 次迭代。

矩阵加法

在矩阵加法中,被加的矩阵必须具有相同的维数(行数和列数)。矩阵加法是一个简单的运算,我们将两个矩阵的相应元素相加。

将 A (a_11)的第一行(i=1)和第一列(j=1)中的元素添加到 B (b_11)的第一行(i=1)和第一列(j=1)中的相应元素,依此类推。

作者图片

我们将使用小数字,以便于看到矩阵的每一个加法。

作者图片

  • 我们创建两个矩阵,A 和 B,我们将添加。我们还创建了一个矩阵 C,用于存储结果。
  • 创建一个嵌套的 for 循环,外层循环遍历行,内层循环遍历列。
  • 我们将矩阵 A 和 B 中的每个对应元素相加,并将总和存储在矩阵 c 中的对应索引中。

作者图片

在这个例子中,迭代遵循与乘法表中相同的模式。唯一不同的是,它同时迭代三个矩阵 A、B 和 C。

**Outer loop, loop 1**, **i=1:** The first outer loop stays on index i=1 (row 1) and the inner loop iterates over the entire length of index j (j=1 to j=3), for all three matrices A, B and C:
    **Inner loop: The inner loop will iterate from j=1 to j=3**:
    Adding matrix A[row i=1, col j=1] to matrix B[row i=1, j=1] and assigns value to matrix C[row i=1, col j=1]
    Adding matrix A[row i=1, col j=2] to matrix B[row i=1, j=2] and assigns value to matrix C[row i=1, col j=2]
    Adding matrix A[row i=1, col j=3] to matrix B[row i=1, j=3] and assigns value to matrix C[row i=1, col j=3]**Outer loop, loop 2**, **i=2:** Here i=2 (row 2 in all matrices), and the inner loop iterates over the entire length of index j (j=1 to j=3), for all three matrices A, B and C.
    **Inner loop: The inner loop will iterate from j=1 to j=3**:
    Adding matrix A[row i=2, col j=1] to matrix B[row i=2, j=1] and assigns value to matrix C[row i=2, col j=1]
    Adding matrix A[row i=2, col j=2] to matrix B[row i=2, j=2] and assigns value to matrix C[row i=2, col j=2]
    Adding matrix A[row i=2, col j=3] to matrix B[row i=2, j=3] and assigns value to matrix C[row i=2, col j=3]

希尔伯特矩阵

希尔伯特矩阵是一个正方形矩阵,其中每个元素是一个单位分数,定义如下:

作者图片

这是 5×5 希尔伯特矩阵:

作者图片

我们将定义一个创建任意大的希尔伯特矩阵的函数:

  • 创建选定大小的矩阵 H
  • 创建一个嵌套的 for 循环,外部循环遍历行,内部循环遍历列
  • 计算矩阵中每一项的值

作者图片

在这个循环中,它按照以前的模式,一次填充矩阵的一行,从左到右在列中填充值。对于每个元素,它根据公式计算单位分数,并将值赋给希尔伯特矩阵。

**Outer loop, loop 1**, **i=1:** The first outer loop stays on index i=1 (row 1) and the inner loop iterates over the entire length of index j, the columns. That is, we iterate over each j element (j=1 to j=n) in this row (i=1):
    **Inner loop: The inner loop will iterate from j=1 to j=n**:
    i=1, j=1, calculates 1/(row i=1 + col j -1) and assigns value to hilbert[row i=1, col j=1]
    i=1, j=2, calculates 1/(row i=1 + col j -1) and assigns value to hilbert[row i=1, col j=2]
    i=1, j=3, calculates 1/(row i=1 + col j -1) and assigns value to hilbert[row i=1, col j=3]
    …
    i=1, j=n, calculates 1/(row i=1 + col j -1) and assigns value to hilbert[row i=1, col j=n]**Outer loop, loop n**, **i=n:** The last outer loop stays on index i=n (row n) and the inner loop iterates over the entire length of index j, the columns. That is, we iterate over each j element (j=1 to j=n) in this row (i=n):
    **Inner loop: The inner loop will iterate from j=1 to j=n**:
    i=n, j=1, calculates 1/(row i=n + col j -1) and assigns value to hilbert[row i=n, col j=1]
    i=n, j=2, calculates 1/(row i=n + col j -1) and assigns value to hilbert[row i=n, col j=2]
    i=n, j=3, calculates 1/(row i=n + col j -1) and assigns value to hilbert[row i=n, col j=3]
    ...
    i=n, j=n, calculates 1/(row i=n + col j -1) and assigns value to hilbert[row i=n, col j=n]

寻找伯努利数

最后,我将展示一个例子,说明我们如何通过使用嵌套的 for 循环来求解有索引的数学方程。我们将编写一个函数来寻找第二个伯努利数的第一个数字。第二伯努利数可以用下面的等式表示:

作者图片

为了了解如何计算这些数字,让我们来计算第二个数字 B_2。当 k=0 时,只有一项 j=0。

作者图片

当 k=1 时,需要计算 j=0 和 j=1 的两项。

作者图片

当 k=2 时,j=0,j=1,j=2 有三项。

作者图片

如你所见,如果我们想找到更高的伯努利数,这个方程很快就变得复杂了。我们可以让 R 用一个嵌套的 for 循环来替我们完成这项工作。

作者图片

在这个例子中,我们不像前面三个例子那样遍历行和列。相反,我们正在计算 k 和 j 的每一项,如上面求解伯努利数 2 的例子所示。

  • 外循环的迭代次数是等式中 k 的外和,范围从 0 到 n,如等式中所定义。
  • 作为 j 的内求和的内循环的迭代次数由 k 决定,因为它的范围从 0 到 k

结论

出于某种原因,我发现嵌套循环有些令人困惑,即使它们的逻辑非常清楚。我不愿意承认的是,嵌套循环经常会产生我没有预料到的结果,这也不是我想要的。在那些场合,我发现回到这些简单的例子有助于“重置”我的思维。如果您发现嵌套循环令人困惑,我希望这些例子可以帮助您。

你可以在这个 Github repo 中找到本文使用的代码。

2022 年开放数据科学大会上的 4 项激动人心的数据科学发展

原文:https://towardsdatascience.com/4-exciting-data-science-developments-at-the-open-data-science-conference-odsc2022-e427df926f85

塞缪尔·佩雷拉在 Unsplash 上拍摄的照片

上周,我参加了在波斯顿举行的开放数据科学大会(ODSC)。作为一名早期职业数据科学家,这是我与社区联系的机会,我从中获得了明显的兴奋感和动力。

ODSC 持续了 4 天,同时进行了个人和在线跑步。会谈分为几个部分,包括机器学习、MLOps、NLP、生物技术等。

话题之广意味着不可能完全准确地概括 ODSC,所以我将挑选一些最令人兴奋的观点。

这些是:

  1. “生成模型正在经历一个时刻”——希拉里·梅森
  2. 大公司正在投资解决无处不在的工程挑战的开源 MLOps 工具
  3. 数据科学家对组织内部更好的合作感兴趣
  4. 富有成效的人工智能协作将在不久的将来成为可能(现在!)

1.“生成模型正在经历一个时刻”——希拉里·梅森

来自隐形门的希拉里·梅森,一家基于人工智能讲故事的视频游戏初创公司,在她的演讲中提出了一个强有力的案例。虽然很难不意识到这一趋势,但希拉里为我解释了为什么,为什么是现在。

为什么是生成模型?从生成模型中取样使你能够创造出文本、图像、蛋白质序列和其他有用的输出。最著名的是, GPT-3 几年前问世,引发了许多关于机器智能的有趣讨论。 GPT3 已经产生了类似人类的文本,而且模型只会越来越好。

进一步研究这些模型,以创造新的能力,并为不同类型的产品打开大门,包括人工智能生成的艺术,如 DALL-E使用人工智能说书人的视频游戏,甚至更强大的语言模型,如 PaLM

DALL-E 生成的图像来自戴夫·奥尔生成并在此分享的提示“一个形状像营火的人工智能给着迷的森林动物观众讲故事

为什么是现在?长期以来,外行人对这些模型的训练和改进深感难以理解。很容易想到,在可预见的未来,如果你想在 GPT3 等模型上工作,你需要在 DeepMind 或 OpenAI 上工作。

然而,希拉里指出,与这项技术互动比以往任何时候都更容易:

  • HuggingFace 这样的平台让分享数据和模型变得前所未有的容易。
  • Colab 和其他计算平台(如初创公司 SaturnCloud)使得根据需要访问强大的 GPU 和 TPU 变得越来越容易。

如果你想快速体验希拉里所说的,那就去 OpenAI 的网站,使用 API playground。OpenAI 通过按需提供生成模型,证明了它们已经足够成熟,可以作为公用事业进行交易,就像互联网或电力一样!

2.大公司正在投资解决无处不在的工程挑战的开源 MLOps 工具

根据我的经验,MLOps 是数据科学家生活中的一个重要组成部分。同时,它在学术背景下完全没有被教授。

MLOps 和数据工程是 ODSC 的工作重点。我参加的一个演讲特别好,来自谷歌/探照灯的 Robert Crowe 在tensor flow Extended(TFX)上做的。

TFX 是一个部署 ML 管道的端到端平台,被 Spotify、Google(地图/Gmail)和 OpenX 等公司使用。

Robert 认为构建 TFX 的动机就像构建任何软件工具的动机一样。每个人都面临着相同的任务,一次又一次地重写相同的样板代码。这与我自己的经历和我交谈过的许多与会者的经历相吻合。不管我们愿不愿意承认,许多重复的工作在应该自动化或抽象化的时候并没有自动化或抽象化——所以 TFX 的存在是件好事!

Robert 接着描述了与 TFX 合作开发和利用 ML 管道的许多细节,不过您可以在此处找到此类细节。

现在,TFX 是否是正确的 MLOps 解决方案可以进行更详细的调查(如本文中的)。我只想说,当我得知许多人面临着类似的挑战,大公司正在合作开发强大的开源解决方案时,我感到非常兴奋。

最后一点,罗伯特建议使用深度学习。艾·TFX 在 Coursera (他是该网站的讲师)上为那些对这一领域的培训感兴趣的人服务。

https://www.tensorflow.org/tfx

3.数据科学家对沟通感兴趣,以最大化他们在组织中的价值

对于在这样一个技术领域工作的如此多的技术人员来说,讨论大多数技术主题是非常容易的。在 ODSC 会议上,并没有很多关于机器学习的社会和商业背景的演讲。

特别是,Mona Khalil '的演讲“提升贵组织基于数据的决策能力”既鼓舞人心又切合实际。Mona 是温室软件公司的数据科学经理。

Mona 首先鼓励与会者考虑他们组织内更广泛的数据背景。我对他们的论点的理解是,在考虑创造价值的途径时,制定有效的沟通策略可以使价值最大化。

在 Mona 的整个演示过程中,我不禁想到了 DevOps 中的 3 种方法,其中包括系统思维(即:价值途径)和有效的沟通策略(放大反馈周期)作为关键组成部分。

我想强调一下 Mona 提出的具体建议,包括:

  • 审计您的数据资产。了解哪些利益相关者需要访问哪些数据。
  • 创建每月简讯,让您的组织了解与您的团队相关的关键数据点和发展。
  • 使用仪表板工具在您的组织中创建有价值数据的低成本视图。

然而,Mona 的建议引起了我最大的共鸣,那就是在你的组织中加强学习(类似于 DevOps 中的第三种方法)。

人们对能够为他们的决策提供信息的数据了解得越多,数据科学专业人员随时获得数据支持的压力就越小。

Mona 提供了一些有价值的资源来提供进一步的细节,包括这篇关于自助服务分析的文章、Shopify 的“数据科学和工程基础”文章以及这篇关于为组织中的其他团队提供数据即服务的文章

卡洛斯·穆扎在 Unsplash 上的照片

4.富有成效的人工智能协作将在不久的将来成为可能(现在!)

今年早些时候,我开始使用 GitHub Copilot 这是一个 AI pair 程序员,其功能远远超出了复杂的自动完成功能,可以将注释转换为相对复杂的代码,编写我的单元测试,并建议替代解决方案来完成任务。如果你还没试过,我强烈推荐。

Rene Schulte 提供了 GitHub copilot 的快速演示。

所以当我看到 Padhraic Smyth 正在做一个题为“机器学习中的过度自信:我们的模型知道他们不知道的东西吗?”—我很感兴趣,但我没想到会有如此深入而有趣的关于人类与人工智能合作的演讲。

Smyth 首先表明,SOTA(最先进的)图像分类等任务模型可能是错误的,而且肯定是错误的。他举了一些例子,说明真正强大的、训练有素的模型给不正确的类别或预测分配了很高的概率。

有趣的是,他进一步指出,文献表明浅层模型往往校准得更好(与正确预测相比,不正确预测的置信度更低),尽管已经进行了许多尝试来解决这些问题,例如通过集成、贝叶斯方法或标签平滑,但它们仅取得了不同程度的成功。

在这一点上,Smyth 出现了分歧,专注于作为解决方案的人类-人工智能互补性。基本的想法(我可能过于简单化了),是人类和人工智能会犯不同类型的错误。也就是说,我们可能能够利用我们预测的正交性,并使用贝叶斯方法将人类/人工智能预测结合起来,比单独使用任何一种都要好。

史密斯论文的图 3人类-人工智能互补性的贝叶斯建模| PNAS ”很好地展示了这种效果(我本应该在这里包括它,但想避免版权问题。看一看它,并注意到在预测的相关性较低的地方,人类-人工智能杂交的准确性提高了。

在这项图像分类任务中,人类和神经网络误差的相关性最小,可以使用贝叶斯建模来组合预测并改善结果。

Smyth 的见解和我自己的非常一致。是的,Github 副驾驶可能经常自信地出错。但对我来说,这显然是错误的。然而,它仍然非常有用,在我们两个之间,我们比以前更快地编写代码,并进行更全面的测试。

另一个我渴望更多使用的类似工具是人工智能研究助理工具引出,它使用微调的 GPT-3 语言模型来帮助研究人员评估证据。

就我个人而言,我很高兴自己的生产力在这些工具的帮助下有所提高,并期待看到这个领域的进步,或者尽可能为之做出贡献。

最终注释

参加东 East 2022 是一次很棒的经历,我强烈推荐任何从事科技工作的人参加。

底线很简单。

机器学习和人工智能的能力正在达到新的高度,增强了人类的能力,使我们能够在我们的组织中民主化信息,并比以往任何时候都自动化更多的无聊任务。

希望我能在 2023 年 ODSC 奥运会上见到你们!

你可以在 twitter @ jbloomAus 上联系我,或者在这里阅读我的其他文章:

4 关于熊猫日期时间操作的常见问题

原文:https://towardsdatascience.com/4-faq-about-date-time-manipulation-with-pandas-eecedcf111e3

举例说明

(图片由作者提供)

熊猫图书馆是非常有效的时间序列数据。事实上,它是由 Wes McKinney 创建的,用于处理基本上由时间序列数据组成的金融数据。

当处理时间序列数据时,大量的时间花费在日期和时间操作上。在本文中,我们将讨论这方面的 4 个常见问题。

你可能遇到过这些问题。除了最后一个问题,它们都可以通过简单的操作来解决,最后一个问题有点棘手,需要多个步骤来解决。

让我们从创建一个示例数据帧开始。

df = pd.DataFrame({ "booking_id": [1001, 1002, 1003, 1004, 1005],
    "property" : ["A", "A", "B", "B", "C"],
    "created_at": ["2022-03-01", "2022-02-10", "2022-04-12",
                   "2022-04-11", "2022-06-05"],
    "checkin_date": ["2022-06-01", "2022-06-10", "2022-06-02",
                     "2022-06-20", "2022-08-10"],
    "checkout_date": ["2022-06-06", "2022-06-15", 
                      "2022-06-06","2022-06-28", "2022-08-16"],
    "amount": [5400, 5600, 4800, 9000, 6500]})# change the data type 
date_cols = ["created_at","checkin_date","checkout_date"]
df[date_cols] = df[date_cols].astype("datetime64[ns]")# display the DataFrame
df

df(作者图片)

为了能够使用 Pandas 的日期操作功能,我们需要将日期放在适当的数据类型中。这就是我们将数据类型更改为“datetime64[ns]”的原因。

1.如何提取年月?

日期包含不同的信息,如年、星期、月等。使用 dt 访问器提供的方法,可以从日期中提取所有不同的信息。

例如,我们可以使用 month 方法获得月份。其中一个不太明显的是年月组合。我们可以借助 to_period 方法提取这些信息。

# create the year_month column
df["year_month"] = df["created_at"].dt.to_period("M")# display the DataFrame
df

df(作者图片)

2.如何给日期加上时间间隔?

给日期加上或减去时间间隔通常在日期操作中执行。我们可以使用“DateOffset”或“Timedelta”函数来执行这项任务。

让我们将 id 为 1001 的预订的退房日期增加 1 天。

df.loc[df["booking_id"]==1001, "checkout_date"] = \
df.loc[df["booking_id"]==1001, "checkout_date"] + \
pd.DateOffset(days=1)# check the result
print(df.loc[df["booking_id"]==1001, "checkout_date"])**# output**
0   2022-06-07
Name: checkout_date, dtype: datetime64[ns]

3.如何求两个日期的天数差?

我们可以通过从两个日期中减去一个来找出两个日期之间的差异。但是,此操作的结果是一个 Timedelta 对象,如下所示:

df["checkout_date"][0] - df["checkin_date"][0]**# output**
Timedelta('6 days 00:00:00')

我们可以使用 days 方法提取整数形式的天数。让我们创建一个列,显示入住日期和预订创建日期之间的天数。

# difference in days
df["days_to_checkin"] = \
(df["checkin_date"] - df["created_at"]).dt.days# display the DataFrame
df

df(作者图片)

4.如何扩展开始日期和结束日期之间的日期?

假设我们需要一个日历来显示房产的预订天数。例如,数据框第一行中的预订告诉我们,房产 A 的预订时间是 2022 年 6 月 1 日至 2022 年 6 月 7 日。因此,酒店 A 的预订日期为 2022 年 6 月 1 日、2022 年 6 月 2 日、2022 年 6 月 3 日、2022 年 6 月 4 日、2022 年 6 月 5 日、2022 年 6 月 6 日(假设退房时间为 2022 年 6 月 7 日上午 10 点)。

我们可以通过查找入住日期和退房日期之间的日期来创建这样一个日历,然后基于这些日期展开数据框架。

首先,我们创建一个包含 property、checkin_date 和 checkout_date 列的日历数据帧。

# create a calendar DataFrame
calendar = df[["property","checkin_date","checkout_date"]]

date_range 函数给出了开始日期和结束日期之间的日期。这是第一次预订时的样子:

pd.date_range(calendar["checkin_date"][0], calendar["checkout_date"][0])**# output**
DatetimeIndex(['2022-06-01', '2022-06-02', '2022-06-03', 
               '2022-06-04', '2022-06-05', '2022-06-06', 
               '2022-06-07'],
              dtype='datetime64[ns]', freq='D')

这里的问题是,我们不希望退房日期显示为已预订。因此,我们将从退房日期中减去 1 天,然后找出两者之间的日期。

为了对所有的行执行这个操作,我们需要使用 apply 函数。我们还将使用 list 构造函数将 date_range 函数的输出转换为一个列表。

# create the booked_days column
calendar.loc[:, "booked_days"] = calendar.apply(

    lambda x: list(
        pd.date_range(
            x.checkin_date, 
            x.checkout_date + pd.DateOffset(days=1)
        ).date
    ),
    axis = 1

)# display the DataFrame
calendar

日历(图片由作者提供)

下一步是根据 booked_days 列中的日期展开数据框架。explode 函数就是做这个操作的。

# explode 
calendar = calendar.explode(
    column="booked_days", ignore_index=True
)[["property","booked_days"]]# display the first 5 rows
calendar.head()

日历(图片由作者提供)

我们现在有一个已预订天数的日历。

我们已经解决了您在处理时间序列数据时可能会遇到的 4 个问题。最后一个不像前三个那样常见,但我想把它包括进来,因为解决起来有点棘手。

你可以成为 媒介会员 解锁我的全部写作权限,外加其余媒介。如果你已经是了,别忘了订阅https://sonery.medium.com/subscribe如果你想在我发表新文章时收到电子邮件。

*https://sonery.medium.com/membership

感谢您的阅读。如果您有任何反馈,请告诉我。*

使用混淆矩阵时的 4 个基本问题

原文:https://towardsdatascience.com/4-fundamental-questions-when-working-with-a-confusion-matrix-e49fc9536066

这将有望让你对混淆矩阵不那么困惑

丹尼尔·利维斯·佩鲁西在 Unsplash 上的照片

混淆矩阵是在机器学习中评估分类模型质量的工具。它检查有多少预测被正确或错误地分配给一个类。

1.如何判断一个分类?

在最简单的情况下,分类由两种状态组成。假设我们想调查电晕试验如何反映病人的感染状况。在这种情况下,电晕测试用作总共两种状态的分类器:感染或未感染。

根据测试的分类是否真正正确,这两个类别总共可以产生四种状态:

  • 真阳性:快速检测将此人归类为受感染,随后的聚合酶链式反应测试证实了这一结果。因此,快速测试是正确的。
  • 假阳性:快速检测对一个人呈阳性,但随后的聚合酶链式反应测试显示这个人实际上没有被感染,即阴性。
  • 真阴性:快速检测为阴性,人实际上没有被感染。
  • 假阴性:电晕快速检测将受检者分类为健康,即阴性,然而,受检者被感染,因此应进行阳性快速检测。

2.什么是混淆矩阵?

混淆矩阵有助于评价和中立地评估学习分类的质量。此外,在矩阵的帮助下,可以更容易地计算具体指标。为了构建混淆矩阵,需要数据集的测试集。分类器将类别分配给数据点。

矩阵由已经提到的错误类型组成。行是测试集的预测类,列是测试集的实际标签:

混乱矩阵结构|来源:作者

假设我们用于 Corona 快速测试的测试集包括 200 个人,按细胞细分如下:

混淆矩阵示例|来源:作者

具体来说,该矩阵产生以下值:

  • 真阳性= 120 :共有 120 人被快速检测归类为感染者,实际携带病毒。
  • 假阳性= 20 :根据快速检测有 20 人患病,但并未实际感染。
  • 假阴性= 40 : 40 名受试者快速检测呈阴性,但实际上已被感染。
  • 真阴性= 20 : 20 人呈阴性,快速检测证实了这一点。

因此,混淆矩阵通常用于确定分类器中经常出现的错误类型。我们的示例性 Corona 快速测试在 70 %的情况下是正确的((120 + 20) / 200),乍一看这是一个不错的值。然而,假阴性错误发生在所有病例的 20 % (40 / 200)中。这意味着,在 20%的情况下,这个人看起来是健康的,尽管他实际上是生病了,而且具有传染性。因此,在病毒性疾病的情况下,不仅准确性是决定性的,假阴性率也是决定性的。

这些比率可以很容易地从混淆矩阵中读出,然后计算出来。

3.从混淆矩阵中可以计算出哪些比率?

由于每个用例关注不同的度量标准,其中一些度量标准已经随着时间的推移而发展。在这一章中,我们简要介绍最重要的几个。

灵敏度

敏感度或真阳性率描述了阳性分类数据点实际上为阳性的情况:

特征

特异性,或真阴性率,测量阴性分类数据点实际上为阴性的所有情况:

精确

精确度是正确、肯定分类的主题的相对频率:

准确(性)

我们已经知道其他类型模型的准确性。它描述了与所有分类相关的正确分类人员的总数:

出错率

错误率与准确性相反,即错误分类的百分比:

4.如何用 Python 创建混淆矩阵?

一旦你用 Python 训练了一个分类器,就可以使用“Scikit-Learn”模块创建真相矩阵。为此,我们只需要两个数组,其中包含测试集的预测类和测试集的实际标签。在我们的例子中,分类模型可以区分类“猫”、“蚂蚁”和“鸟”。因此,我们期望一个具有三行三列的混淆矩阵。

# Import Scikit-Learn
from sklearn.metrics import confusion_matrix# True Labels of Testset
y_true = ["cat", "ant", "cat", "cat", "ant", "bird"]# Predicted Labels of Testset
y_pred = ["ant", "ant", "cat", "cat", "ant", "cat"] # Create Confusion Matrix
confusion_matrix(y_true, y_pred, labels=["ant", "bird", "cat"])Out: 
array([[2, 0, 0],
       [0, 0, 1],
       [1, 0, 2]], dtype=int64)

这个矩阵现在也可以用来计算真阳性、假阳性等。从中。超过两个类别的分类手动起来会很复杂。

# Get Figures of a two-class Classification
tn, fp, fn, tp = confusion_matrix([0, 1, 0, 1], [1, 1, 1, 0]).ravel()
(tn, fp, fn, tp)Out: 
(0, 2, 1, 1)# Get Figures of a multi-class Classification
confusion_matrix(y_true, y_pred, labels=["ant", "bird", "cat"]).ravel()Out: 
array([2, 0, 0, 0, 0, 1, 1, 0, 2], dtype=int64)

这是你应该带走的东西

  • 混淆矩阵有助于评估分类模型。
  • 在大多数情况下,它包含四个字段:真阳性、真阴性、假阳性和假阴性。
  • 这些字段可用于计算有助于评估分类器的特定指标。

如果你喜欢我的作品,请在这里订阅https://medium.com/subscribe/@niklas_lang或者查看我的网站* 数据大本营 !还有,medium 允许你每月免费阅读 3 篇 。如果你希望有无限制的 访问我的文章和数以千计的精彩文章,不要犹豫,点击我的推荐链接:【https://medium.com/@niklas_lang/membership】每月花$5***获得会员资格**

* *

初学者的 4 个重要 SQL 概念

原文:https://towardsdatascience.com/4-important-sql-concepts-for-beginners-51d69f195843

让我们为初学者学习一些重要的 SQL 概念来增强您的查询能力

照片由 unsplash.com@克里斯利维拉尼拍摄

QL 是目前最灵活的编程语言之一。随着 1974 年第一次实现,SQL 是一种查询语言,使开发人员能够顺利地处理存储在关系表中的数据。

如果你在一个组织中工作,你很有可能会在你公司的报告中发现一些 SQL 代码。为什么?因为应用程序开发人员、数据科学家、数据分析师或云工程师等各种各样的角色都使用 SQL。

SQL 也非常灵活——您可以将其与 Python、R、Java 和大多数编程语言集成。大多数情况下,如果您的应用程序有一个数据库层,您可能会使用某种类型的 SQL 实现(如 PostGres、MySQL 或 SQLite)与之通信。

在本帖中,我们将为 SQL 初学者检查 4 个重要概念,它们将帮助你进一步练习和提高这门语言。

示例数据

对于我们的沙盒示例,我们将使用一个名为companies的表,其中包含不同行业的几个组织的信息。

我将从头开始创建它,以便您也可以在一些 SQL 实现上复制这些示例(我将使用 MySQL,所以请注意,如果您选择其他实现,一些查询子句可能会有不同的语法)。

要运行这段代码,确保创建了一个sandbox数据库——如果没有,只需执行CREATE DATABASE SANDBOX;

下面的代码创建了我们的companies表结构,并将一些数据插入其中:

create table sandbox.companies (
 company_name varchar(30),
    industry varchar(30),
    ticker varchar(5),
    market_cap bigint,
    num_employees int
    );insert into sandbox.companies (
 company_name, industry, ticker, market_cap, num_employees
    ) values ("Apple","Technology","AAPL", 2621000000, 154000),
    ("L'oreal", "Consumer Goods", "LRLCY", 214272000, 85087),
             ("Intel", "Semiconductors", "INTC", 196323000, 110600),
             ("Novo Nordisk", "Pharmaceutical", "NVO",246022000,45000),
             ("Bayer", "Pharmaceutical", "BAYRY",56833000,99637),
             ("Abbvie", "Pharmaceutical", "ABBV",280506000,50000),
             ("Facebook", "Technology", "FB",552707000,71970),
             ("Johnson & Johnson", "Pharmaceutical", "JNJ",464855000,130000);

以下是我们数据的表格形式:

公司表-按作者分类的图片

这是我们将在整个帖子中使用的表格。

分组数据

在构建数据管道时,分组和聚合数据是最酷的技能之一。分组数据使您能够完全转换表结构,并基于几个列在原始数据上构建几个聚合。

一些虚构用例的示例:

  • 对股票行情自动收录器的每日股票价格进行分组,以了解特定一天的平均价格;
  • 对商店数据进行分组,以获得每个商店和每个月的总销售额;

关于用例,对数据进行分组主要有两个目的:

  • 构建数据管道,并为特定需求创建具有聚合数据的定制 ETL—例如,为仪表板或机器学习算法准备数据。
  • 对数据进行快速统计。

大多数情况下,数据分组是使用GROUP BY SQL 子句完成的。将GROUP BY子句与聚合函数结合起来是一个非常强大的 SQL 特性——例如,如果我们想在companies表中检查每个行业的平均雇员人数,我们只需:

select industry, avg(num_employees) as avg_n_employees
from sandbox.companies
group by industry;

注意这段代码有多简单——几乎就像我们在交谈一样!

我想从“公司”表中选择行业和雇员人数的平均值,并按行业对数据进行分组。

这将产生一个结果,其中我们有两列——industryavg_n_employees。SQL 如何计算这个avg_n_employees?让我给你解释一下原因。

我们的原始表中有 4 家制药公司:

过滤查询-按作者分类的图像

该行业的平均雇员人数将为:(45000+99637+50000+130000)/4,大约为 81.159 人。这个数字代表 “制药行业公司的平均员工人数”。

如果一切正确,我们的GROUP BY输出必须包含制药行业行的相同数据:

按公司列出的平均员工人数-按作者列出的图片

而且,没错!对于其他行业,SQL 自动计算相同的公式— 由于半导体和消费品在我们的 **companies** 表中只有公司,所以这些行业的员工人数值与 **n=1** 中的公司相同。

酷!我们还可以用GROUP BY做什么花样?另一个想法是计算每个行业的公司数量——使用count()函数:

select industry, count(company_name) as nb_companies
from sandbox.companies
group by industry;

这会产生:

每个行业的计数-按作者分类的图片

在 SQL 中,GROUP BY子句通常位于FROM之后(如果您没有任何连接过滤器)。如果连接过滤器存在,这些子句将为我们查询的后续部分推送GROUP BY子句。只要记住他们总是需要跟在FROM从句后面!

你可以在我的 SQL 课程的第一部分了解更多关于GROUP BY子句的知识。

连接

SQL 中另一个非常重要的概念是表连接。连接主要是为了将多个表合并成一个表。它们是 SQL 中需要掌握的关键方面之一,连接的效率(当与索引结合时)是开发人员可能更喜欢使用该语言来构建数据管道的主要原因之一。

所以..依赖于连接的最常见的 SQL 用法是什么?

两个主要的例子是:

  • 在关系数据模型中连接数据;
  • 为数据集市构建新的组合表;

连接有多种形式。在这一部分,我将解释一些最常见的。

对于我们的沙盒示例,我们需要一个额外的表与我们的companies 表交叉。让我们创建一个包含每个行业市场规模的新表:

# Create industries data
create table sandbox.industries (
    industry varchar(30),
    market_size bigint
    );

# Insert some industries data
insert into sandbox.industries (
 industry, market_size
    ) values ("Technology",5200000000),
    ("Consumer Goods", 2000000000),
             ("Semiconductors", 6000000000),
             ("Banking",7500000000);

我们的industries表如下所示:

行业表-按作者分类的图片

请注意该表的两点:

  • 这里有一个行业(银行业)不在公司表上;
  • 有一个行业在公司表中,但不在 **industries** (制药)中。

对于现实生活中的数据,数据库中缺少一些信息是很常见的情况。这个小细节对于理解我们将要做的不同连接是很重要的。

让我们执行一个内部连接——假设我想将market_size列添加到companies表中——例如,对于特定行业中的每家公司,我希望有一个包含市场规模信息的列。我可以用一个连接来做到这一点!

让我们学习一下INNER JOIN的语法:

select left.*, right.market_size
from sandbox.companies as left
inner join sandbox.industries as right
on left.industry = right.industry;

对于连接,关键是定义将被用作表之间的连接器T21 的列。在我们的例子中,我们使用industry列,因为这是我们在表上都有的列。关于该查询的一些重要细节:

  • 我们使用别名来引用表格。左边是公司表,右边是行业表。
  • 子句中的声明了将用于连接两个表的列——通常称为连接键
  • 左。* 意味着我们要从公司表中选择所有列。

INNER关键字只返回在连接的两个表中都存在的行。例如,由于制药公司不在行业表中,这些公司将从结果中排除:

内部连接结果-按作者排序的图像

有时,您可能希望覆盖这一点,例如,当行业数据不可用时,将 market_size 设为NULL—这可以通过LEFT JOIN来实现,这意味着您希望将表中的每一行都放在左侧和右侧上,而不管它是否出现在右侧上:

# Left join example
select left.*, right.market_size
from sandbox.companies as left
left join sandbox.industries as right
on left.industry = right.industry;

语法和INNER JOIN超级相似——真的很酷。唯一的区别是我们现在用LEFT JOIN作为连接从句。上述查询的结果如下:

左连接结果-按作者排序的图像

通过这种方式,你不会丢失公司的数据,即使你没有更多关于这个行业的信息。

您也可以使用RIGHT JOIN进行相反的操作:

# Right join example
select left.*, right.market_size
from sandbox.companies as left
right join sandbox.industries as right
on left.industry = right.industry;

右连接结果-按作者排序的图像

请注意,现在我们有了银行业的市场规模,所有其他行都显示为NULL。奇怪的是,我们没有“银行”行的industry为什么?因为在查询中我们从表left(我们的公司表)中选择了行业。

总而言之,连接是非常酷的概念,它使我们能够连接不同的表。我们没有涉及的其他连接是OUTERFULL,但是您可以在掌握INNERRIGHTLEFT之后学习它们。

你可以在我的 SQL 课程的第三部分了解更多关于JOIN子句的知识。

子查询

子查询是另一个 SQL 特性,它将使您的查询非常灵活。

使用子查询,您可以嵌套查询,并直接使用查询结果作为其他查询的输入。这听起来令人困惑,但实际上很简单!

例如,让我们创建一个表,只过滤我们的companies表中的制药公司:

select * 
from sandbox.companies
where industry = 'Pharmaceutical';

该查询将产生以下结果:

子查询结果-按作者排序的图像

如果我们现在想从这个查询结果中获取最大数量的 **num_employees** 怎么办?当然,我们可以在where上的查询中直接使用计算列,但是我们也可以使用子查询,例如:

# Subqueries Example
select max(subtable.num_employees) as max_n_employees 
from (
 select * 
 from sandbox.companies
 where industry = 'Pharmaceutical'
    ) as subtable;

可以把子查询想象成在FROM子句中替换一个物理表——SQL 的灵活性使我们能够直接在同一个from子句中使用任何查询结果。这有几个优点:

  • 当我们想要进行两个连续的 group by 操作时,这一点尤其重要;
  • 当您想要构建数据管道而不实际创建表时,这很有用。

您可以在我的 SQL 课程的第五部分了解更多关于子查询的知识。

其中=/=拥有

初学者在开始用 SQL 编码时面临的一个常见问题是理解WHEREHAVING子句之间的区别。

主要区别在于WHERE在任何GROUP BY应用之前应用,而HAVING在分组之后应用。让我们检查以下两个查询:

# Query with WHERE
select industry, avg(market_cap) as market_cap
from sandbox.companies
where market_cap < 1000000000
group by industry;# Query with HAVING
select industry, avg(market_cap) as market_cap
from sandbox.companies
group by industry
having market_cap < 1000000000;

我们会有两种不同的结果:

使用 Where 的查询结果-按作者排序的图像

作者使用 Having-Image 查询的结果

请注意行业技术的变化。这是为什么呢?第一个查询翻译成下面的句子:

“我想按行业选择平均市值,但排除市值超过 1 万亿的公司”

这是因为WHERE总是在分组前应用。在这种情况下,Apple在计算之前被移除了——因此唯一进入平均值计算的公司是Facebook,因为它是唯一与 where 子句中的筛选器匹配的技术公司。

另一方面,对于第二个查询,我们执行以下操作:

“我想按行业选择平均市值,但排除平均市值超过 1 万亿的行业”

注意到区别了吗?这是因为HAVING子句在分组完成后起作用。在这种情况下,Apple进入计算,使科技行业的平均价值超过 1 万亿市值。由于平均值超过 1 万亿,我们从结果中过滤掉了它,我们不再有关于HAVING条款的技术争论。

你可以在我的 SQL 课程的第一部分了解更多关于WHEREHAVING子句的知识。

我们完事了。感谢你花时间阅读这篇文章。当涉及到操作数据时,SQL 具有很少语言能够比拟的灵活性。它非常容易掌握,可能是不同数据领域角色(分析师、科学家、工程师等)使用最广泛的语言。).

在这篇文章中,我们探索了一些很酷的 SQL 概念,它们将帮助初学者提高查询的灵活性——还知道其他类似的概念吗?写在下面的评论里吧!

我在Udemy上开设了一门关于从零开始学习 SQL 的课程,我在其中深入探讨了这些概念以及更多内容——这门课程适合绝对的初学者,我希望您能在我身边!

Python 数据可视化生态系统中的 4 个主要参与者:Matplotlib、Seaborn、Altair 和 Plotly

原文:https://towardsdatascience.com/4-key-players-in-python-data-visualization-ecosystem-matplotlib-seaborn-altair-and-plotly-23ae37a68227

一张图胜过千言万语

照片由 Unsplash 上的尼克·费因斯拍摄

事实证明,数据可视化在许多方面对数据科学家非常有帮助,例如:

  • 探索性数据分析
  • 特征工程和预处理
  • 机器学习模型评估
  • 报告

他们在创建数据相关产品的关键步骤中发挥着关键作用。因此,我们应该接受数据可视化库,它使得用几行代码创建大范围的可视化变得容易。

在本文中,我们将发现 4 个常用的 Python 数据可视化库。我们将对每一个进行举例,以了解它们的基本属性。这些例子也有助于比较这些库的语法。

当然,我们需要一个数据集作为例子。我们可以使用 pandas datareader 库创建一个包含股票价格数据的数据框架。下面的代码片段给出了在指定的开始和结束日期之间的苹果股票价格。

import pandas as pd
from pandas_datareader import datastart = '2021-06-01'
end = '2021-12-31'
source = 'yahoo'df = data.DataReader(
   "AAPL", start=start, end=end, data_source=source
)df = df.reset_index()[["Date","Close","Volume"]]

df(作者图片)

数据框架包含苹果股票的收盘价和每日交易量。

先说 Matplotlib。

Matplotlib

Matplotlib 是一个非常流行的数据可视化库。它通常是数据科学课程中第一个涉及的内容。

我认为 Matplotlib 最大的优点是灵活性。您有许多选项来调整和定制绘图。

Matplotlib 由三个主要层组成,分别是后端层、艺术家层和脚本层。我们几乎总是使用脚本层来创建可视化。脚本层是 matplotlib.pyplot 接口。如果你想了解更多关于 Matplotlib 的结构,这里有一篇我不久前写的详细文章。

以下代码块创建了一个线形图。

import matplotlib.pyplot as plt# Create a figure object
plt.figure(figsize=(12,6))# Create the plot
plt.plot(df["Date"], df["Close"])# Add axis label and title
plt.ylabel("Closing Price", fontsize=15)
plt.title("Apple Stock Price", fontsize=18)# Add grid lines
plt.grid(True)

(图片由作者提供)

一旦我们创建了一个图,我们可以对它进行一些定制,例如修改标签和字体大小,添加网格线,等等。

下一个图是体积柱的直方图。直方图是一种常用的可视化类型,它为我们提供了连续变量分布的概况。

# Create a figure object
plt.figure(figsize=(10,6))# Create the histogram
plt.hist(df["Volume"])# Adjust ticks font size
plt.xticks(fontsize=14)
plt.yticks(fontsize=14)# Add title
plt.title("Histogram of Volume", fontsize=18)

(图片由作者提供)

除了对线图进行调整之外,我们还更改了 x 轴和 y 轴上记号的字体大小。

我们还可以对一个情节做许多其他的调整,使它更具知识性和吸引力。Matplotlib 提供了极大的灵活性,但代价是要编写额外的代码行。

海生的

Seaborn 是另一个流行的 Python 数据可视化库。它是基于 Matplotlib 构建的。

当我不需要做小的调整时,我更喜欢 Seaborn 而不是 Matplotlib。Seaborn 提供了一个更简单的语法,但是没有 Matplotlib 灵活。

要在 Seaborn 中创建一个线图,我们可以使用 relplot 或 line plot 函数。relplot 函数是一个图形级界面,用于绘制线图和散点图。

让我们首先使用 relplot 函数。

import seaborn as sns
sns.set_theme(style="darkgrid")sns.relplot(
    data=df, x="Date", y="Close",
    height=5, aspect=2, kind="line"
).set(
    title="Apple Stock Price"
)

高度和纵横比参数用于调整地块大小。

(图片由作者提供)

我们也可以使用 lineplot 函数来创建相同的图。由于 Seaborn 是基于 Matplotlib 构建的,因此我们可以利用 Matplotlib 特性来调整 Seaborn 创建的地块。

这里有一个例子来说明这种情况。

# Create a figure object
plt.figure(figsize=(12,6))# Adjust ticks font size
plt.xticks(fontsize=14)
plt.yticks(fontsize=14)# Create the lineplot
line = sns.lineplot(data=df, x="Date", y="Close")# Add axis label and title
line.set_title("Apple Stock Price", fontsize=18)
line.set_xlabel("Date", fontsize=15)
line.set_ylabel("Closing Price", fontsize=15)

(图片由作者提供)

感觉 Seaborn 比 Matplotlib 更高级。这也使得创建带有支线剧情的可视化效果变得非常容易。

我有一篇单独的文章详细解释了如何用 Seaborn 创建分布图(包括直方图)。

阿尔泰尔

Altair 是 Python 的统计可视化库。与 Matplotlib 和 Seaborn 相比,Altair 在统计特性上更重。它允许在创建可视化时进行多种数据转换和过滤。

让我们用 Altair 创建相同的线图。

import altair as altalt.Chart(df).mark_line().encode(
    alt.X("Date", title="Insurance Cost"),
    alt.Y("Close", title="Closing Price", scale=alt.Scale(zero=False))
).properties(
    height=300, width=600,
    title="Apple Stock Price"
).configure_title(
    fontSize=18
).configure_axis(
    titleFontSize=15,
    labelFontSize=14
)

第一步是创建一个顶级图表对象,它将熊猫数据帧的名称作为参数。然后,我们指定绘图类型(例如,标记圆、标记线等)。

我们指定要在编码函数中绘制的列名。剩下的步骤与根据大小、轴标签、标题等定制绘图相关。

下面是这段代码生成的图:

(图片由作者提供)

如果您想了解更多关于 Altair 的知识,我写了一系列文章来解释它的基本属性以及如何使用 Altair 进行数据转换和过滤。

Plotly

Plotly Python (plotly.py)是一个基于 Plotly Javascript (plotly.js)构建的开源绘图库。Plotly 提供了高级和低级 API。

高级 API 是 plotly express ,可以用很少的几行代码创建一个情节。图形对象是一个低级 API,它给了我们更多对可视化的控制,代价是编写更多的代码。

让我们用 plotly express 创建相同的线图。

import plotly.express as pxfig = px.line(
    df, x="Date", y="Close",width=800, height=500, 
    title="Apple Stock Price"
).update_layout(font_size=15)fig.show()

(图片由作者提供)

Plotly 是一个非常实用的库,可以用来创建交互式和动画可视化。如果你想了解更多关于 Plotly 的特性,这里有一个我写的文章列表:

最后的话

我们简要介绍了 4 个最常用的 Python 数据可视化库。在大多数情况下,任何一种都可以为您提供所需的解决方案。

正如我们在示例中看到的,语法方面只有微小的差异。但是,这些都是很基本的情节。随着我们添加更多的功能和自定义或创建更复杂的地块,差异也会增加。

别忘了 订阅 如果你想在我发表新文章时收到电子邮件。

你可以成为 的媒介会员 解锁我的全部写作权限,外加其余媒介。如果您使用以下链接,我将收取您的一部分会员费,无需您支付额外费用。

https://sonery.medium.com/membership

感谢您的阅读。如果您有任何反馈,请告诉我。

机器学习建模的 4 个关键过程

原文:https://towardsdatascience.com/4-key-processes-in-machine-learning-modeling-c82144372eaf

从数据中优化学习

康尼·施耐德在 Unsplash 上的照片

在本文中,我将介绍机器学习(ML)建模中的四个主要过程,作为一名数据从业者,您应该对这些过程了如指掌。

机器学习是人工智能的一个分支,它通过揭示数据模式(即特征和目标变量之间的关系)来模仿人类的学习能力。特征是独立变量,代表给定观察值或数据点的属性。另一方面,目标变量是一个因变量,我们感兴趣的是建模来进行预测。

ML 建模是数据科学项目生命周期中的一个重要步骤,也是项目中最有趣的部分之一。

作者图片

在上一篇文章中,我讨论了 ML 的主要组成部分,并提供了对 ML 建模的额外介绍。文章的链接可以在这里找到。

ML 建模中的 4 个关键过程

ML 建模过程(图片由作者提供)

现在,让我们深入研究 ML 建模中的四个主要过程。

训练

这是将最大似然算法与数据拟合以学习模式的过程,其结果是创建模型。此外,算法的选择可能会受到基于可用计算能力的训练时间要求的影响。

在执行进一步的实验之前,通常对基线模型进行训练,作为项目的基准。基线模型可以是简单的算法,如线性回归或具有默认设置的随机森林算法。基线模型的选择很大程度上取决于问题和数据从业者的经验。

大多数 ML 算法通过拟合方法进行训练。

以下是常见的培训术语:

串行训练:这种类型的训练主要在单个处理器上进行,广泛用于简单到中等的训练工作。

分布式训练:在这里,适合一个算法的工作量被分割并在多个微型处理器之间共享。这就是所谓的并行计算,它有助于加快进程。更多详情可在这里找到。

离线学习:在这种情况下,对所有可用的数据定期进行训练,只有当性能令人满意时,才把模型部署到生产中。

在线学习:在这里,随着新数据流的出现,模型权重和参数会不断实时更新。

在线学习和离线学习的详细对比可以在这里找到。

调谐

这是选择给出最佳模型的最优超参数集的过程。这是 ML 建模中最耗时的过程,包括创建具有不同超参数值集合的几个模型。诸如均方根误差(RMSE)、平均绝对误差(MAE)和精确度的相关度量可用于选择最佳模型。

在调优过程中要避免的一个常见缺陷是使用测试集来完成这个过程。相反,为此需要创建和使用一个验证集。更好的是,需要使用交叉验证等方法来防止过度拟合。

用于调整的四重交叉验证(图片由作者提供)

python 中已经实现了一些易于使用的模块,可用于超参数优化,即 GridSearchCVrandomsearccvBayesSearchCV

预测

一旦选择了最佳模型,就可以使用测试数据和其他新数据集进行预测,而无需在模型的输入数据中提供目标变量。这也被称为最大似然推断。

样本 ML 预测-时间序列预测(图片由作者提供)

评估

模型评估是评估最大似然模型预测性能的过程。主要想法是量化模型预测的质量。这里可以使用在超参数优化期间采用的相同度量,并且还可以添加新的度量用于结果呈现目的。

样本模型评估报告(图片由作者提供)

关于模型评估的更多细节,包括 ML 建模中使用的通用指标,可在这里找到。

结论

在本文中,我们讨论了机器学习建模的四个主要过程:训练、调整、预测和评估。必要时还提供了一些有用的资源链接。

我希望你喜欢这篇文章,直到下次。干杯!

你可以通过我下面的推荐链接订阅 Medium 来获得更多来自我和其他作者的启发性文章,这也支持我的写作。谢谢大家!

https://aolaoye.medium.com/membership

向 Python 列表添加新项目的 4 种方法

原文:https://towardsdatascience.com/4-methods-for-adding-new-items-to-python-lists-7c4243e93416

列表是 Python 的核心数据结构

凯利·西克玛在 Unsplash 上的照片

数据结构对于任何编程语言都非常重要,因为如何存储、访问和管理数据是设计高效程序的关键因素之一。

Python 有 4 种内置数据结构:

  • 目录
  • 一组
  • 元组
  • 词典

列表表示为方括号中的数据点集合,可用于存储不同数据类型的值。下面是一个列表示例:

mylist = [1, 2, 3, "Jane", True]

在本文中,我们将学习 4 种向 Python 列表添加新项的方法。

1.附加

append 方法用于向列表中添加单个项目。

mylist.append(7)

print(mylist)

# output
[1, 2, 3, 'Jane', True, 7]

如果您尝试使用 append 方法添加项目集合(例如列表、元组),该集合将作为单个项目追加到列表中。

mylist.append(["Max", "John"])

print(mylist)

# output
[1, 2, 3, 'Jane', True, 7, ['Max', 'John']]

变量 mylist 不单独包含项目“Max”和“John”。

"Max" in mylist
# output
False

["Max", "John"] in mylist
# output
True

提示 :如果你不小心把一个物品列表追加为单个物品,但需要新的物品在原列表中作为单独的物品,可以使用熊猫的分解功能。

import pandas as pd

mylist = [1, 2, 3, 'Jane', True, 7, ['Max', 'John']]

pd.Series(mylist).explode(ignore_index=True)
# output
0       1
1       2
2       3
3    Jane
4    True
5       7
6     Max
7    John
dtype: object

您可以使用 list 构造函数将输出转换回 list:

import pandas as pd

mylist = [1, 2, 3, 'Jane', True, 7, ['Max', 'John']]

list(pd.Series(mylist).explode(ignore_index=True))
# output
[1, 2, 3, 'Jane', True, 7, 'Max', 'John']

2.插入

append 方法将新项添加到列表的末尾(即作为最后一项)。如果要在开头或特定索引处添加项目,请改用 insert 方法。

它需要两个参数:

  1. 要添加的项的索引
  2. 项目本身

索引从 0 开始,所以我们需要使用索引 0 在开头添加一个新项。

mylist = ["Jane", "Jennifer"]

mylist.insert(0, "Matt")

print(mylist)
# output
['Matt', 'Jane', 'Jennifer']

让我们再做一个例子,添加新的条目作为第三个条目。

mylist = [1, 2, 3, 4]

mylist.insert(2, 10000)

print(mylist)
# output
[1, 2, 10000, 3, 4]

就像 append 方法一样,insert 方法只能用于向列表中添加单个项目。

3.扩展

extend 方法使用给定集合中的项扩展列表。

它也可以用于向列表中添加单个项目,但是 append 方法更适合于此任务。

mylist = ["Jane", "Jennifer"]

mylist.extend(["Max", "John"])

print(mylist)
# output
['Jane', 'Jennifer', 'Max', 'John']

现在“Max”和“John”作为单独的项目添加到列表中。

"Max" in mylist
# output
True

使用 extend 方法添加字符串的单个项时要小心。因为字符串可以被看作是字符的集合,所以 extend 方法将每个字符作为单独的项添加到列表中。

这里有一个例子:

mylist = ["Jane", "Jennifer"]

mylist.extend("Matt")

print(mylist)
# output
['Jane', 'Jennifer', 'M', 'a', 't', 't']

使用 append 方法将单个项目添加到列表中总是更好。

4.加法运算符(+)

加法运算符可用于连接列表,这也意味着将一个项目列表添加到另一个列表中。

mylist = [1, 2, 3, 4]

mylist = mylist + [8, 9]

print(mylist)
# output
[1, 2, 3, 4, 8, 9]

但是,我们只能使用这个方法将一个列表中的项目添加到另一个列表中。它不能用于向列表中添加不同类型的项目(例如,整数、元组、字符串)。

我们来做一个例子,用一个整数来演示这种情况。

mylist = [1, 2, 3, 4]

mylist = mylist + 10

# output
TypeError: can only concatenate list (not "int") to list

正如我们在上面的输出中看到的,这引发了一个类型错误。

结论

列表是 Python 中最常用的数据结构之一。因此,学习与列表交互的方法来创建健壮的程序是很重要的。在本文中,我们学习了如何通过添加新项目来修改列表。

你可以成为 媒介会员 解锁我的全部写作权限,外加其余媒介。如果你已经是了,别忘了订阅https://sonery.medium.com/subscribe如果你想在我发表新文章时收到电子邮件。

感谢您的阅读。如果您有任何反馈,请告诉我。

为您的下一个 ML 模型提供功能选择的 4 种方法

原文:https://towardsdatascience.com/4-methods-to-power-feature-engineering-for-your-next-ml-model-5d32fffbe511

另外,处理分类、数字和混合数据的技巧

照片由edu·格兰德Unsplash 上拍摄

什么是特征选择?

机器学习中的特征选择就是在数据集中选择最有影响力的特征,或者列。

你的数据集有很多列吗,你想看看哪个影响最大吗?你想放弃那些没有产生太多价值的东西吗?

通过执行特征选择,您不仅减少了需要处理以加速分析的数据量,而且简化了模型的解释,使其他人更容易理解。

根据您拥有的数据类型,可以使用多种技术,从统计方法到利用机器学习模型进行选择。我们将看看一些最常见的技术,看看它们在实践中是如何应用的!

  1. 使用卡方检验的分类数据
  2. 数值数据的皮尔逊相关系数
  3. 数字数据的主成分分析
  4. 特征重要性随机森林对于分类数据和数字数据

我们开始吧!

数据和导入

对于我们今天的演示,我们将使用银行营销 UCI 数据集,可以在 Kaggle 上找到。该数据集包含关于营销活动中银行客户的信息,并且包含一个可以在分类模型中使用的目标变量。该数据集位于 CC0:公共领域下的公共领域,可用于任何目的。

有关构建分类模型的更多信息,请查看:构建令人惊叹的二进制分类器所需要知道的一切使用多类和多标签模型超越了二进制分类

我们将从导入必要的库和加载数据开始。我们将利用 Scikit-Learn 来学习每一种不同的技术。除了这里演示的,还有许多其他支持的方法

import pandas as pd

from sklearn.model_selection import train_test_split
from sklearn.feature_selection import chi2
from sklearn.feature_selection import SelectKBest
from sklearn.preprocessing import LabelEncoder, OrdinalEncoder
from sklearn.ensemble import RandomForestClassifier
from sklearn.preprocessing import MinMaxScaler
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import LabelEncoder
from sklearn.compose import make_column_selector as selector
from sklearn.pipeline import Pipeline

import matplotlib.pyplot as plt
import seaborn as sns

df = pd.read_csv("bank.csv", delimiter=";")

分类值的特征选择

如果你的数据集是分类的,我们可以使用皮尔森卡方检验。根据维基百科:

卡方检验是一种应用于分类数据的统计检验,用于评估数据集之间观察到的差异偶然出现的可能性。

当您的特征数据是分类的,并且您的目标数据分类的时,您应用卡方检验,例如,分类问题。

注意: 虽然该数据集包含分类值和数值的混合,但我们将分离分类值来演示如何应用卡方检验。下面将通过特征重要性来描述该数据集的一种更好的方法,以跨类别和数值类型选择特征。

我们将开始只选择那些在熊猫中是分类的或类型object的类型。Pandas 将文本存储为对象,所以在简单使用object类型之前,您应该验证这些是否是分类值。

# get categorical data
cat_data = df.select_dtypes(include=['object'])

然后我们可以分离出特性和目标值。目标变量y,是数据框中的最后一列,因此我们可以使用 Python 的切片技术将它们分成Xy

X = cat_data.iloc[:, :-1].values
y = cat_data.iloc[:,-1].values

接下来,我们有两个函数。这些函数将使用OrdinalEncoder作为X数据,使用LabelEncoder作为y数据。顾名思义,OrdinalEncoder将把分类值转换成数字表示,遵循特定的顺序。默认情况下,编码器会自动选择此顺序。但是,您可以为订单提供一个值列表。LabelEncoder将把相似的值转换成数字表示。根据 Scikit-Learn 的文档,您应该只在目标变量上使用LabelEncoder

def prepare_inputs(X_train, X_test):
    oe = OrdinalEncoder()
    oe.fit(X_train)
    X_train_enc = oe.transform(X_train)
    X_test_enc = oe.transform(X_test)
    return X_train_enc, X_test_enc

def prepare_targets(y_train, y_test):
    le = LabelEncoder()
    le.fit(y_train)
    y_train_enc = le.transform(y_train)
    y_test_enc = le.transform(y_test)
    return y_train_enc, y_test_enc

接下来,我们将把我们的数据分成训练和测试组,并用上述函数处理数据。请注意,上面的函数只将编码器与训练数据相匹配,并转换训练和测试数据。

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=1)
# prepare input data
X_train_enc, X_test_enc = prepare_inputs(X_train, X_test)
# prepare output data
y_train_enc, y_test_enc = prepare_targets(y_train, y_test)

现在,这个函数将帮助我们利用SelectKBest方法中的卡方检验来选择最佳特征。我们可以从设置参数k='all'开始,这将首先在所有特性上运行测试,然后我们可以将它应用于特定数量的特性。

def select_features(X_train, y_train, X_test, k_value='all'):
    fs = SelectKBest(score_func=chi2, k=k_value)
    fs.fit(X_train, y_train)
    X_train_fs = fs.transform(X_train)
    X_test_fs = fs.transform(X_test)
    return X_train_fs, X_test_fs, fs

我们可以从打印出每个特性的分数开始。

# feature selection
X_train_fs, X_test_fs, fs = select_features(X_train_enc, y_train_enc, X_test_enc)
# what are scores for the features
for i in range(len(fs.scores_)):
    print('Feature %d: %f' % (i, fs.scores_[i]))
Feature 0: 11.679248
Feature 1: 0.248626
Feature 2: 3.339391
Feature 3: 0.039239
Feature 4: 11.788867
Feature 5: 12.889637
Feature 6: 64.864792
Feature 7: 4.102635
Feature 8: 10.921719

然而,用直观地检查这些分数更容易。

# what are scores for the features
names = []
values = []
for i in range(len(fs.scores_)):
    names.append(cat_data.columns[i])
    values.append(fs.scores_[i])
chi_list = zip(names, values)

# plot the scores
plt.figure(figsize=(10,4))
sns.barplot(x=names, y=values)
plt.xticks(rotation = 90)
plt.show()

作者图片

联系人在这里得分最大,而婚姻默认月份得分最低。总的来说,看起来有大约5个特性值得考虑。我们将使用SelectKBest方法来选择顶部的5特征。

X_train_fs, X_test_fs, fs = select_features(X_train_enc, y_train_enc, X_test_enc, 5)

我们可以打印顶级特性,这些值对应于上面的索引。

fs.get_feature_names_out()
[OUT:]
array(['x0', 'x4', 'x5', 'x6', 'x8'], dtype=object)

最后,我们可以打印出X_train_fsX_test_fs数据的形状,并看到第二维度是所选特征的5

print(X_train_fs.shape)
print(X_test_fs.shape)
(3029, 5)
(1492, 5)

数值的特征选择

当处理纯数值数据时,有两种方法我更喜欢使用。第一个是皮尔逊相关系数,第二个是主成分分析PCA

皮尔逊相关系数

先说皮尔逊相关系数。虽然这不是一个明确的特征选择方法,但它有助于我们可视化高度相关的特征。当两个或更多特征高度相关时,它们在训练时向模型贡献非常相似的信息。通过计算和绘制相关矩阵,我们可以快速检查是否有任何值高度相关,如果有,我们可以选择从模型中删除一个或多个值。

corr = df.corr()

f, ax = plt.subplots(figsize=(12, 8))

sns.heatmap(corr, cmap="Blues", annot=True, square=False, ax=ax)
plt.title('Pearson Correlation of Features')
plt.yticks(rotation=45);

作者图片

在这个例子中, pdaysprevious 具有最强的相关性0.58,其他的都是相互独立的。0.58的相关性不是很强。因此,我将选择在模型中保留这两者。

主成分分析

在所有数据都是数字的模型中,主成分分析是最有效的特征选择方法。 PCA 不是特征选择方法,而是降维方法。然而,PCA 的目标类似于特征选择,我们希望减少计算模型所需的数据量。

下图显示了应用于照片的 PCA。该图表示每个主成分的累积解释方差的量。在这个例子中,我们能够用图像的 3000 多个主成分中的 54 个来解释图像中 95%的变化。

作者图片

有关 PCA 如何工作和执行的更多信息,请查看以下文章: 2 种可视化 PCA 的美丽方式通过图像压缩实现主成分分析的魔力

随机森林的要素重要性

最后,我选择特性的首选方法是利用随机森林及其计算特性重要性的能力。Scikit-Learn 将计算功能列表及其对整体性能的相对贡献,作为训练模型的输出。该方法也适用于其他袋装树,如额外树梯度推进进行分类和回归。

这种方法的好处是它非常适合构建模型的整个流程。让我们来看看这是如何工作的。让我们从获取数据框中的所有列开始。注意,在这种情况下,我们可以利用分类数据和数字数据。

print(df.columns)
Index(['age', 'job', 'marital', 'education', 'default', 'balance', 'housing', 'loan', 'contact', 'day', 'month', 'duration', 'campaign', 'pdays', 'previous', 'poutcome', 'y'],
      dtype='object')

当阅读这个数据集的文档时,您会注意到持续时间列是我们不应该用来训练您的模型的。我们将手动将其从我们的列列表中删除。

持续时间 :最后一次联系持续时间,单位为秒(数字)。此属性对输出目标有很大影响(例如,如果 duration=0,则 y='no ')。然而,在执行呼叫之前,持续时间是未知的。还有,结束通话后 y 显然是已知的。因此,该输入应仅用于基准测试目的,如果目的是获得现实的预测模型,则应丢弃。

此外,如果我们愿意,我们可以删除任何其他可能没有用的功能。在这个例子中,我们将把它们都排除在持续时间之外。

# Remove columns from the list that are not relevant. 
targets = ['age', 'job', 'marital', 'education', 'default', 'balance', 'housing', 'loan', 'contact', 'day', 'month', 'campaign', 'pdays', 'previous', 'poutcome']

接下来,我们将利用列转换器将我们的数据转换成机器学习可接受的格式。每当我为可重复性建立模型时,我更喜欢使用管道

查看我的文章:停止一步一步地构建你的模型,以获得更多关于它们的信息:用管道自动化这个过程!

我为数值选择了MinMaxScaler,为分类值选择了OrdinalEncoder。在最终的模型中,我最有可能使用OneHotEncoder (OHE)作为分类特征,但是为了确定特征的重要性,我们不想用 OHE 扩展列;如果将它们视为一个带有顺序编码值的列,我们将获得更多的价值。

column_trans = ColumnTransformer(transformers=
       [('num', MinMaxScaler(), selector(dtype_exclude="object")),
       ('cat', OrdinalEncoder(), selector(dtype_include="object"))],
        remainder='drop')

接下来,我们用一些首选设置创建一个分类器实例,比如class_weight='balanced',这有助于处理不平衡的数据。我们还将设置random_state=42,以确保得到相同的结果。

有关不平衡数据的更多信息,请查看:在构建您的 ML 模型时,不要陷入不平衡数据的陷阱

# Create a random forest classifier for feature importance
clf = RandomForestClassifier(random_state=42, n_jobs=6, class_weight='balanced')

pipeline = Pipeline([('prep',column_trans),
                     ('clf', clf)])

接下来,我们将把数据分成训练集和测试集,并使我们的模型适合训练数据。

# Split the data into 30% test and 70% training
X_train, X_test, y_train, y_test = train_test_split(df[targets], df['y'], test_size=0.3, random_state=0)

pipeline.fit(X_train, y_train)

我们可以对分类器调用feature_importances_方法来查看输出。注意如何通过调用分类器的名称clf来引用管道中的分类器,类似于 Python 中的字典。

pipeline['clf'].feature_importances_
array([0.12097191, 0.1551929 , 0.10382712, 0.04618367, 0.04876248,
       0.02484967, 0.11530121, 0.15703306, 0.10358275, 0.04916597,
       0.05092775, 0.02420151])

接下来,让我们按照它们的最大和累积重要性来显示它们。“累积重要性”列有助于直观地显示总数是如何累加到1的。还有一个循环,可以砍掉任何对整体重要性贡献小于0.5的特征。这个截止值是任意的。你可以寻找0.80.9的总累积重要性。试验一下你的模型如何执行更少或更多的功能。

feat_list = []

total_importance = 0
# Print the name and gini importance of each feature
for feature in zip(targets, pipeline['clf'].feature_importances_):
    feat_list.append(feature)
    total_importance += feature[1]

included_feats = []
# Print the name and gini importance of each feature
for feature in zip(targets, pipeline['clf'].feature_importances_):
    if feature[1] > .05:
        included_feats.append(feature[0])

print('\n',"Cumulative Importance =", total_importance)

# create DataFrame using data
df_imp = pd.DataFrame(feat_list, columns =['FEATURE', 'IMPORTANCE']).sort_values(by='IMPORTANCE', ascending=False)
df_imp['CUMSUM'] = df_imp['IMPORTANCE'].cumsum()
df_imp
 FEATURE  IMPORTANCE    CUMSUM
1         job    0.166889  0.166889
0         age    0.151696  0.318585
2     marital    0.134290  0.452875
13   previous    0.092159  0.545034
6     housing    0.078803  0.623837
3   education    0.072885  0.696722
4     default    0.056480  0.753202
12      pdays    0.048966  0.802168
8     contact    0.043289  0.845457
7        loan    0.037978  0.883436
14   poutcome    0.034298  0.917733
10      month    0.028382  0.946116
5     balance    0.028184  0.974300
11   campaign    0.021657  0.995957
9         day    0.004043  1.000000

最后,基于这个循环,让我们打印出我们选择的所有特性。基于这个分析,我们从我们的模型中删除了大约 50%的影响,我们可以看到哪些影响最高!

print('Most Important Features:')
print(included_feats)
print('Number of Included Features =', len(included_feats))
Most Important Features:
['age', 'job', 'marital', 'education', 'default', 'housing', 'previous']
Number of Included Features = 7

感谢您的阅读!你可以在 GitHub 上找到这篇文章的所有代码

结论

特征选择是模型构建过程的关键部分,它不仅有助于提高性能,还可以简化模型及其解释。我们开始考虑利用卡方检验来选择分类特征。接下来,我们查看了皮尔逊相关矩阵,以直观地识别高度相关的数值特征,并介绍了主成分分析(PCA)作为自动降低数值数据集维数的工具。最后,我们将随机森林中的feature_importances_作为一种选择分类值和数值的方法。我们希望这能让你开始你的特性选择之旅!

如果你喜欢阅读这样的故事,并且想支持我成为一名作家,那就考虑成为一名灵媒吧。一个月 5 美元,让你可以无限制地访问成千上万篇文章。如果您使用 我的链接 注册,我将为您赚取一小笔佣金,无需额外费用。

4 个鲜为人知的 NLP 库是隐藏的瑰宝

原文:https://towardsdatascience.com/4-more-little-known-nlp-libraries-that-are-hidden-gems-e77a71d1bc57

带有代码示例和解释

作者使用 DALL E 2 生成的图片(提示:“一颗巨大的蓝色宝石从地下被挖出”)

发现新的 Python 库经常会激发新的想法。这里有 4 个隐藏的珍宝图书馆,非常值得了解。

让我们开始吧。

1)预识别分析器和匿名器

由微软开发的 Presidio 提供了一种自动匿名敏感文本数据的方法。首先,在非结构化文本中检测私人实体的位置。这是通过结合使用命名实体识别(NER)和基于规则的模式匹配以及正则表达式来实现的。在下面的例子中,我们查找姓名、电子邮件和电话号码,但是还有许多其他的预定义识别器可供选择。然后,来自分析器的信息被传递到匿名器,匿名器用去敏感化的文本替换私有实体。

安装

!pip install presidio-anonymizer
!pip install presidio_analyzer
!python -m spacy download en_core_web_lg

示例

from presidio_analyzer import AnalyzerEngine 
from presidio_anonymizer import AnonymizerEngine 
from presidio_anonymizer.entities import OperatorConfig# identify spans of private entities
text_to_anonymize = "Reached out to Bob Warner at 215-555-8678\. Sent invoice to [bwarner_group@gmail.com](mailto:bwarner_group@gmail.com)" 
analyzer = AnalyzerEngine() 
analyzer_results = analyzer.analyze(text=text_to_anonymize,  
                                    entities=["EMAIL_ADDRESS", "PERSON", "PHONE_NUMBER"],  
                                    language='en')# pass Analyzer results into the anonymizer
anonymizer = AnonymizerEngine() 
anonymized_results = anonymizer.anonymize( 
    text=text_to_anonymize, 
    analyzer_results=analyzer_results     
) 
print(anonymized_results.text)

结果

**ORIGINAL:** Reached out to Bob Warner at 215–555–8678\. Sent invoice to [bwarner_group@gmail.com](mailto:bwarner_group@gmail.com)**OUTPUT:** Reached out to <PERSON> at <PHONE_NUMBER>. Sent invoice to <EMAIL_ADDRESS>

用例

匿名化是保护个人信息的关键一步。如果您在工作场所收集或共享敏感数据,这一点尤为重要。

文献

2)符号拼写

用于自动拼写纠正的 Python 库:SymSpell。它提供了快速的性能,并涵盖了各种各样的常见错误,包括拼写问题和丢失或额外的空格。虽然 SymSpell 不会修复语法问题或考虑单词的上下文,但您将受益于它的快速执行速度——这在处理大型数据集时很有帮助。SymSpell 建议根据单词的频率(即疗法出现的频率更高)以及关于键盘布局的单个字符编辑距离进行更正。

安装

*!pip install symspellpy*

示例

*from symspellpy import SymSpell, Verbosity
import pkg_resources# load a dictionary (this one consists of 82,765 English words)
sym_spell = SymSpell(max_dictionary_edit_distance=2, prefix_length=7)
dictionary_path = pkg_resources.resource_filename(
    "symspellpy", "frequency_dictionary_en_82_765.txt"
)# term_index: column of the term 
# count_index: column of the term's frequency
sym_spell.load_dictionary(dictionary_path, term_index=0, count_index=1)def symspell_corrector(input_term): # look up suggestions for multi-word input strings 
  suggestions = sym_spell.lookup_compound( 
      phrase=input_term,  
      max_edit_distance=2,  
      transfer_casing=True,  
      ignore_term_with_digits=True, 
      ignore_non_words=True, 
      split_by_space=True 
  ) 
  # display the correction
  for suggestion in suggestions: 
      return f"OUTPUT: {suggestion.term}"text = "the resturant had greatfood."
symspell_corrector(text)*

结果

***ORIGINAL:** the resturant had greatfood.**OUTPUT:** the restaurant had great food*

用例

无论您是在处理客户评论还是社交媒体帖子,您的文本数据都可能包含拼写错误。符号拼写可以用作 NLP 预处理过程中的另一个步骤。例如,单词袋或 TF-IDF 模型会以不同的方式看待餐馆和拼错的单词餐馆,即使我们知道它们有相同的意思。运行拼写纠正可以解决此问题,并有助于降低维数。

文档

3) PySBD ( python 句子边界消歧)

终于!一个智能、简单的 Python 库,可以将文本分割成句子单元。虽然这是一项看似简单的任务,但人类的语言是复杂而嘈杂的。仅仅基于标点符号将文本分割成句子只能在一定程度上起作用。pySBD 的伟大之处在于它能够处理各种各样的边缘情况,例如缩写、十进制值以及法律、金融和生物医学语料库中常见的其他复杂情况。与大多数其他利用神经网络完成这项任务的库不同,PySBD 使用基于规则的方法来识别句子边界。在他们的论文中,这个库的作者展示了 pySBD 在基准测试中比替代者得分更高的准确性。

安装

*!pip install pysbd*

示例

*from pysbd import Segmentersegmenter = Segmenter(language=’en’, clean=True)text = “My name is Mr. Robert H. Jones. Please read up to p. 45\. At 3 P.M. we will talk about U.S. history.”print(segmenter.segment(text))*

结果

***ORIGINAL:** My name is Mr. Robert H. Jones. Please read up to p. 45\. At 3 P.M. we will talk about U.S. history.**OUTPUT:** ['My name is Dr. Robert H. Jones.',
 'Please read up to p. 45.',
 'At 3 P.M. we will talk about U.S. history.']*

用例

有很多次,我需要在句子层面上处理或分析文本。最近的基于方面的情感分析(ASBA)项目就是一个很好的例子。在这项工作中,确定顾客服装评论中特定相关句子的极性非常重要。这只能通过首先将文本分解成单独的句子来实现。因此,与其花时间编写复杂的正则表达式来涵盖许多边缘情况,不如让 pySBD 来帮您完成繁重的工作。

文献

4)文本攻击

TextAttack 是一个很棒的 Python 框架,用于在 NLP 模型上开发对抗性攻击。

NLP 中的对抗性攻击是对文本数据创建小扰动(或编辑)以欺骗 NLP 模型做出错误预测的过程。扰动包括用同义词替换单词、插入新单词或从文本中删除随机字符。这些编辑应用于从模型的数据集输入中随机选择的观测值。

图片由作者提供。一次成功的攻击。对抗性的干扰愚弄了 NLP 分类模型,使其预测出不正确的标签。

TextAttack 提供了一种无缝的、低代码的方式来生成这些对抗性的例子以形成攻击。一旦攻击运行,将显示 NLP 模型执行情况的摘要。这将提供对你的模型的稳健性的评估——或者换句话说,它对某些扰动的敏感程度。在将 NLP 模型引入现实世界时,鲁棒性是一个需要考虑的重要因素。

安装

*!pip install textattack[tensorflow]*

举例

TextAttack 功能太多,无法简单介绍,所以我强烈推荐查看它写得很好的文档页面

在这里,我将通过命令行 API(Google Colab 中的**)对拥抱脸中基于 BERT 的情感分类模型进行攻击。使用烂番茄电影评论数据集,这个预先训练好的模型被微调以预测正面负面**

该攻击包含一个单词交换嵌入转换,它将通过在单词嵌入空间中用同义词替换随机单词来转换从烂番茄数据集中选择的观察值。

让我们来看看这个 NLP 模型如何抵挡 20 个对立的例子。

*!textattack attack \
    --model-from-huggingface RJZauner/distilbert_rotten_tomatoes_sentiment_classifier \
    --dataset-from-huggingface rotten_tomatoes \
    --transformation word-swap-embedding \
    --goal-function untargeted-classification \
    --shuffle `True` \
    --num-examples 20*

结果

图片由作者提供。对微调后的 BERT 模型的 19 次成功攻击之一。可以说,最初负面评论的意义在扰动后保持不变。理想情况下,模型不应该对这个对立的例子进行错误分类。

图片由作者提供。攻击的结果!

有意思!没有任何干扰,这个模型达到了令人印象深刻的 100%的准确性。然而,在总共 20 次攻击中——平均只有 18%的单词被改变 NLP 模型被愚弄了 19 次错误分类!

用例

通过测试 NLP 模型对抗对抗性攻击,我们可以更好地理解模型的弱点。然后,下一步可以是通过在扩充数据上进一步训练 NLP 模型来提高模型准确性和/或稳健性。

关于我如何使用这个库来评估定制的 LSTM 分类模型的完整项目示例,请查看本文。它还包括一个完整的代码脚本。

*

文献

结论

我希望这些库能在你未来的 NLP 工作中派上用场!

这是我最近写的一篇类似文章的延续。因此,如果你没有听说过有用的 Python 库,如缩写库蒸馏标点符号库文本统计库,那么也去看看吧!

</5-lesser-known-python-libraries-for-your-next-nlp-project-ff13fc652553>

感谢阅读!*

Python 集合比较的 4 个必备方法

原文:https://towardsdatascience.com/4-must-know-methods-for-python-set-comparison-f5b612bef62e

实用指南

(图片由作者提供)

Set 是 Python 中 4 种内置数据结构之一。其他的是字典、列表和元组。

根据官方文档,集合是不同可散列对象的无序集合。因此,器械包的两个特征是:

  • 它们不包含重复的元素
  • 元素必须是可散列的(即不可变的)。虽然集合是可变的,但是集合中的元素是不可变的。

在这篇文章中,我们将讨论 4 个必须知道的比较集合的方法。让我们从创建一个 set 对象开始。

myset = {1, 2, 3, 4, 5}type(myset)
**# Output**
set

我们将介绍的方法有:

  • 交集
  • 差异
  • 联盟
  • 对称差

差分和对称差分

差分法寻找存在于一个集合中而不存在于另一个集合中的元素。

(图片由作者提供)

如上图所示,集合 A 与集合 B 的区别包括集合 A 中存在但集合 B 中不存在的所有元素。

让我们做一些例子来看看这些方法是如何使用的。

A = {1, 2, 3, 4, 5}
B = {3, 4, 5, 6, 7} A.difference(B)
**# Output**
{1, 2} B.difference(A)
**# Output**
{6, 7}

集合 A 包含 1 和 2,而集合 B 不包含。因此,差值 B 返回 1 和 2。

差值法可用于两个以上的集合。例如,“A.difference(B,C)”查找存在于 A 中但不存在于 B 或 C 中的元素。让我们看看它的实际应用:

A = {1, 2, 3, 4}
B = {3, 4, 10, 11}
C = {2, 4, 20, 21}A.difference(B, C)
**# Output**
{1}

对称差分法寻找仅存在于集合 A 或仅存在于集合 B 中的元素。因此,它返回“A 差 B”和“B 差 A”的并集。下面是这种方法的使用方法:

A.symmetric_difference(B)
**# Output**
{1, 2, 6, 7}

由于对称差覆盖了“A 差 B”和“B 差 A ”,我们可以交换 A 和 B 的位置:

(图片由作者提供)

交集和并集

两个集合的交集包含两个集合中都存在的元素。并集包含存在于任何集合中的元素。

(图片由作者提供)

A = {1, 2, 3, 4, 5}
B = {3, 4, 5, 6, 7} A.intersection(B)
**# Output**
{3, 4, 5}

注:“A .交集(B)”与“B .交集(A)”相同。

让我们也找到 A 和 B 的并集:

A.union(B)
**# Output**
{1, 2, 3, 4, 5, 6, 7}

union 方法获取集合的并集。尽管 3、4 和 5 在两个集合中都存在,但结果集合中每一个都只包含一个。重复项将被删除。

并集和交集方法可用于两个以上的集合。

A = {1, 2, 3, 4}
B = {3, 4, 10, 11}
C = {2, 4, 20, 21} A.union(B, C)
**# Output**
{1, 2, 3, 4, 10, 11, 20, 21} A.intersection(B, C)
**# Output** {4}

我们已经介绍了用于比较两组或更多组的 4 种不同方法。如果你想了解更多关于集合的知识,这里有一篇我以前写的更详细的文章:

</12-examples-to-master-python-sets-71802ea56de3>

你可以成为 媒介会员 解锁我的全部写作权限,外加其余媒介。如果你已经是了,别忘了订阅https://sonery.medium.com/subscribe如果你想在我发表新文章时收到电子邮件。

*https://sonery.medium.com/membership

感谢您的阅读。如果您有任何反馈,请告诉我。*

Python Pandas 中的 4 个必须知道的参数

原文:https://towardsdatascience.com/4-must-know-parameters-in-python-pandas-6a4e36f6ddaf

这使得函数更加有用。

Jari hytnen 在 Unsplash 上拍摄的照片

Pandas 是最流行的数据分析和操作库之一。它提供了许多功能来有效地解决问题。大多数 Pandas 函数都有增强其功能的参数。

参数自定义函数的行为,使函数更加灵活和实用。

大多数参数对于一个特定的函数是唯一的,但是有一些参数无论与什么函数一起使用都是一样的。它们可以被认为是通用的熊猫参数:)

了解并使用这些参数对充分利用熊猫非常有帮助。在这篇文章中,我们将讨论很多 Pandas 函数使用的 4 个参数。

让我们从创建一个样本数据帧开始。

import numpy as np
import pandas as pddf = pd.DataFrame(
    np.random.randint(10, size=(5,5)), 
    columns=list("ABCDE")
)

df(作者图片)

我们创建了一个 5 行 5 列的数据帧。

1.轴

轴参数用于为要应用的功能选择轴。0 表示索引,1 表示列。默认值通常为 0。我从未使用过默认轴参数值为 1 的函数。

考虑 sum 函数。当我们将它应用于数据帧时,它会计算行或列中值的总和。

df.sum(axis=0)A    13.0
B    33.0
C    18.0
D    25.0
E    22.0
dtype: float64--------------
df.sum(axis=1)0    28.0
1    14.0
2    27.0
3    20.0
4    22.0
dtype: float64

当轴为 0 时,求和运算是沿着索引进行的,因此输出给出列和。当轴为 1 时,计算行和。

对于 mean、sort_values、groupby、fillna、dropna、rank 等许多函数来说,轴是一个有效的参数。

2.忽略 _ 索引

默认情况下,使用整数索引创建数据帧。索引可以被认为是行标签。

有些函数会改变行的顺序,比如 sort_values 函数。在这种情况下,指数也会混淆。

另一个混合索引的函数是组合多个数据帧的 concat 函数。原始数据帧的索引没有改变,这可能导致重复的索引。

在这种情况下,ignore_index 参数会忽略当前数据帧的索引,结果数据帧会被赋予一个全新的好看的整数索引。

让我们用 sort_values 函数做一个例子。

df.sort_values(by="A")df.sort_values(by="A", ignore_index=True)

(图片由作者提供)

左边的 dataframe 是没有 ignore_index 参数的输出。

3.原地

有许多函数可以更新数据帧中的值或修改数据帧。使用此类函数时,为了保存更改,需要将 inplace 参数设置为 True。

下面是一个使用 sort_values 函数的示例。

df.sort_values(by="A", ignore_index=True)df

(图片由作者提供)

根据列 A 中的值对行进行排序,但是我们无法观察到数据帧中的任何变化。原因是更改没有保存。我们可以将排序后的数据帧赋给另一个变量,或者简单地将 inplace 参数设置为 True。

df.sort_values(by="A", ignore_index=True, inplace=True)df

(图片由作者提供)

这些行现在已排序。

Fillna、dropna、reset_index 和 sort_values 是一些具有 inplace 参数的 Pandas 函数。

4.上升的

每当我们做一个涉及排序值的操作时,我们都需要指定如何去做。它们可以按升序或降序排序。

升序参数用于确定如何对值进行排序。rank、value_counts 和 sort_values 函数有一个升序参数。

我们来做一个 rank 函数的例子。

df["rank_ascending"] = df["D"].rank(ascending=True)
df["rank_descending"] = df["D"].rank(ascending=False)

我们已经创建了两个列,其中包含基于列 d 中的值的等级。其中一个列基于按升序排序的值分配等级,因此最低值的等级为 1。另一个正好相反。

这是我们新列的数据框架:

(图片由作者提供)

这些参数通常执行特定于功能的调整,但是我们在本文中讨论的那些参数也用于相同的目的。如果您正在使用 Pandas 进行数据分析和操作,您可能会频繁使用这些参数。

别忘了 订阅 如果你想在我发表新文章时收到电子邮件。

你可以成为 媒介会员 解锁我的全部写作权限,外加其余媒介。如果您使用以下链接,我将收取您的一部分会员费,无需您支付额外费用。

https://sonery.medium.com/membership

感谢您的阅读。如果您有任何反馈,请告诉我。

4 个 NLP 库,用于 Python 中文本数据的自动语言识别

原文:https://towardsdatascience.com/4-nlp-libraries-for-automatic-language-identification-of-text-data-in-python-cbc6bf664774

自动语言检测开源库综述

图片来自 Unsplash 上的 Soner Eker

介绍

大多数处理文本数据的行业更注重使用数字功能,因为这是处理这些文档的最快方式。在国际层面上,在任何进一步处理之前自动识别文档的基础语言可能是有益的。一个简单的用例可能是公司检测传入文本信息的语言,以便将其路由到相关部门进行处理。

本文旨在提供四个可以执行此类任务的 python 库的概述。

语言检测库

本节的目标是向您介绍一些用于文本语言检测的库及其实现。所有的源代码都在我的 Google colab 上。

1.LangDetect

这个库是 Google 的语言检测库从 Java 到 Python 的直接端口,可以识别 50 多种语言。由 Cybozu Labs,Inc .的 Nakatani Shuyo 开发的lang_detect有两个主要功能,都将文本作为输入进行分析:

  • detect输出对应于所识别语言代码的双字母 ISO 693。
  • detect_langs输出检测到的所有候选顶级语言及其相应概率得分的列表。

lang_detect.py

text变量中,为了加噪音,我故意用法语加了最后一句。

text = """This library is the direct port of Google's language-detection library from Java to Python. **Elle est vraiment éfficace dans la détection de langue**."""

第一次案例测试,第一次和第五次执行语言检测(图片由作者提供)

第二次案例测试,第一次和第四次执行语言检测(图片由作者提供)

  • 测试第一种情况 ( detect):第一次执行( fr 为法语)和第五次执行( en 为英语)中确定的语言不相同。
  • 测试第二种情况 ( detect_langs):我们得到两种候选语言法语和英语。在第一次执行中,语言是法语的概率得分高。第 4 次执行后,英语的概率变高了。

所有这些结果中的不一致都是因为遮光罩下的算法是非确定性的,文本中的噪声越高,不一致性就越高。通过在运行语言检测指令之前将种子设置为:

fix_non_deterministic.py

由于使用了DetectorFactor,前面代码的结果总是相同的。这个库即使易于使用,也可能与简单的用例有关。

2.Spacy-langdetect

Spacy 是一个 NLP 库,其功能包括从标记化、命名实体识别到预训练模型的所有内容。Spacy 提出spacy-langdetect 是为了给它的文本处理管道增加语言检测的味道。

spacy_langdetect.py

  • model可以是任何定制的语言检测器,意味着你自己的预训练模型或来自 Spacy 模型中心的模型。
  • LanguageDetector是执行语言检测并在幕后使用detect_langs功能的类。
  • name参数设置为language_detector可以访问管道中的语言检测功能。
  • ._.language属性对应于包含在文档中检测到的候选语言信息的字典。

下面是关于英文和法文文本都 免执照 的结果,分别摘自actuia.comjeuneafrique.com

spacy_langdetect_examples.py

  • 第 14 行 显示{'language': 'en ',' score': 0.9999963977276909},几乎 100%确信文本是英文。
  • 第 17 行 显示{'language': 'fr ',' score': 0.9999963767662121},几乎 100%确信文本是法语。

3.快速文本

这个库是由脸书人工智能研究实验室开发的。它是为工业化用例而不是研究而构建的,这使它成为一个快速、准确、轻便的工具,内存不到 1MB,能够识别 170 多种语言。它带有以下两个版本的预训练模型。

  • 这个更快,也更精确,但是可能有点大(大小= 126MB)
  • lid.176.ftz :这是模型的压缩版本,文件大小为 917kB

让我们关注第一个模型(lid.176.bin),因为它是最准确的。

fasttext_lang_detect.py

  • ft_model是从我的pretrained _ model文件夹中加载的 fasttext 预训练模型的实例。
  • .replace("\n", " ")习惯于fasttext不抛出错误。

下面是 第 16 行第 17 行 中先前打印语句的输出。['__label__en']表示第一个文本被预测为 89%可信的英文文本。['__label__fr']表示以 99%的置信度检测到第二个是法语。

([['__label__en']], [array([0.8957091], dtype=float32)])
([['__label__fr']], [array([0.99077034], dtype=float32)])

4.gcld3

这是 Google Compact 语言检测器 v3,是 Google 开发的神经网络语言识别库。在撰写本文时,这个预先训练的模型支持 107 种语言,并具有两个主要的语言识别功能。

  • FindLanguage对应 第一特征 ,并连同置信度得分一起返回被检测语言对应的 BCP-47 风格码
  • FindTopNMostFreqLangs对应于 第二特征 ,其替代地生成顶级候选语言(使用num_langs参数)及其置信度得分。

在使用这些特性之前, 我们需要 来实例化一个检测器 ,在推理过程中需要以下两个参数。

  • min_num_bytes最小字节数。
  • max_num_bytes最大字节数。

注意:请记住,强烈建议在实现这个库时使用虚拟环境。

下面是这两个特性的实现。

gcld3_lang_detect.py

  • 第一个特征的结果

功能 _1.py

{'language': 'en', 'probability': 0.9998331069946289}
{'language': 'fr', 'probability': 0.9999961853027344}
  • 第二个特征的结果

我将num_langs初始化为两个,因为我想为每个文本确定前两种语言。

功能 _2.py

[{'language': 'en', 'probability': 0.9998331069946289}, {'language': 'und', 'probability': 0.0}]
[{'language': 'fr', 'probability': 0.9999961853027344}, {'language': 'und', 'probability': 0.0}]

我们注意到结果中的und语言类型,因为没有发现第二种语言,尽管我们想要前 2 种。当第一语言被确定为具有非常高的置信度得分时,这种情况经常发生,在我们的例子中几乎是 100%。

感谢阅读!

祝贺您走到这一步,我希望您喜欢阅读这篇文章,并且它让您清楚地看到了使用预训练模型进行自动语言检测的好处。请在下面找到更多资源来帮助您进一步学习。

不要犹豫在 LinkedIn上添加我或者在 YouTube和 Twitter 上关注我。讨论人工智能,人工智能,数据科学,自然语言处理的东西总是令人愉快的!

Google colab 上文章的源代码

空间-语言检测

谷歌的 langdetect

快速文本语言识别

python 中 Google 的紧凑型语言检测器 v3 介绍

再见🏃🏾

你应该知道的 4 个数字提示!

原文:https://towardsdatascience.com/4-numpy-tips-you-should-know-64d0c59ec109

让 NumPy 的工作变得更好

照片由蒂姆·莫斯霍尔德Unsplash 上拍摄

NumPy 是 Python 中最典型的数据科学库之一。能够有效地使用它可以让你的日常工作变得更加容易。你将在本教程中学到的四个技巧将让你更好地控制库的工作方式以及你能从中获得什么!让我们开始吧。

生成特殊数组

在数据科学、深度学习和线性代数中,您经常需要生成特殊的数组,如 0 和 1 的数组和矩阵,或单位矩阵。

谢天谢地,NumPy 让这变得非常容易!让我们看看如何使用np.zeros()函数轻松创建一个 0 数组:

在上面的代码中,我们使用了np.zeros()函数来生成一个包含零的数组。当只传入一个值时,就会创建一个一维数组。

类似地,我们可以传入多个值来创建一些其他的特殊数组:

在下一节中,您将学习如何使用np.where()函数来过滤数组。

用 Where 过滤

np.where()函数可以用来过滤(和替换)数组中的值。这是一个非常强大的功能,非常生动地模仿了查找和替换。

让我们先看一个过滤数据的非常基本的例子:

同样,我们可以使用函数替换满足或不满足条件的值。这是通过传入第二个和第三个参数来完成的:

在上面的例子中,我们将想要替换满足条件的值的值传递给第二个参数。在第三个函数中,我们传递不满足条件的值。

用 NumPy 重塑数组

重塑数组可能是 NumPy 中最常见的活动之一。例如,当使用深度神经网络时,确保数组具有特定的大小非常重要。和其他例子一样,NumPy 让这变得非常非常简单!

让我们来看看如何将一维数组转化为多维数组:

在上面的例子中,我们通过使用np.reshape()函数将一个一维数组转换成一个 3x3 的矩阵。

类似地,我们可以使用 np .tranpose()函数转置一个数组:

计算唯一值

在这最后一节中,您将学习如何使用np.unique()函数对数组中的唯一值进行计数。默认情况下,该函数将简单地返回数组中的唯一值。

但是,您可以传入counts=True参数,函数将返回一个包含值和计数的元组。

让我们看一个计算数组中唯一值的例子:

在上面的示例中,第一个返回的数组包含唯一值,按照它们出现的顺序排列。第二个包含每个值出现的频率。例如,值 1 出现五次!

结论

在本教程中,您学习了使用 NumPy 的四种重要方式。这个库非常大,有很多很多有用的特性。我希望这篇教程能让你更深入地了解如何有效地使用这个库!

更好的数据科学的 4 个强大规则

原文:https://towardsdatascience.com/4-powerful-rules-for-better-data-science-128bb51f6fd3

遵循这些规则极大地提高了我作为数据科学家的效率,让我从工作中获得更多价值

数据科学中有很多东西你只能通过经验来学习(图片由斯科特·格雷厄姆Unsplash 上拍摄)

成为一名高效的数据科学家很难

现在是 2016 年末周一早上 08:55。我刚刚走进我第一份“正式”数据科学工作的办公室。我攻读了博士学位,学习了数学和统计学,自学了 Python 和 SQL,学习了吴恩达的机器学习课程,还练习了随机森林和聚类。我觉得准备好了。我过去几年在机器学习和计算物理领域的工作让我对此有了充分的准备——这是类似科学的探索和技术挑战的完美结合。

我有这个。

我想大概是这样。

我挣扎过。努力产生影响。努力创造价值。挣扎着拿着东西离开地面。

感觉好像我在旋转轮子。我正在做我过去几年一直在读的那些让你成为优秀数据科学家的东西。我在用我辛苦获得的技能来测试一些假设。

为什么这不容易?

我非常相信对事物的完全所有权——如果有些事情不太对劲,我会思考我做错了什么。最常见的不是工具或环境,你可以做些事情来影响结果。

最终,我后退一步,认真审视自己在做什么。像解决抽象问题一样思考。在我的过程中,哪里有裂缝和漏水的管道?

原来我关注的是错误的事情。有时甚至挣扎着决定下一步要改进或调整什么。这大大降低了我的速度,浪费了时间和精力,并导致了大量的挫折。

我没有马上找到所有的答案。事实上,我下面要指出的许多规则花了我多年的分析和自我反省才发现。这些启发来自多年的头痛和经验。还有更多的,但这些是开始他们的旅程的良好开端。

我发现这些简单的规则是无价的。

1 .有用性>复杂性

当开始的时候,在对更好模型的永恒追求中,很容易被构建更复杂的解决方案冲昏头脑。我记得我在 Kaggle 上读到了所有关于模型堆积的潜在危险。我开始将越来越复杂的模型层层叠加,以改进我正在优化的任何指标。

这种方法会严重损害您的输出:

  • 认知负荷 —要完全理解你的模型是如何组成的,以及你下一步应该如何调整你的方法,变得很困难,最终也很棘手。
  • 可解释性——每增加一点复杂性,你就让你的模型变得更加不透明,让其他人更加困惑。利益相关者不可能信任它。
  • 井底之蛙——你为了模型而迷失在模型中。就像一些奇怪的游戏,所有重要的是高分。通常,更重要的是缩小范围,看看它将如何被使用,或者考虑达到预期结果的其他方法。
  • 最终,你回家度周末,或者从工作中休息一段时间,当你回来的时候,整个事情看起来超级令人生畏。或者它从有趣变成了折磨,开始让你疲惫不堪。你做同一件事似乎已经很久了。

这可能会导致数周的辛苦工作被搁置或束之高阁。优先级改变或者事情继续发展。团队得出结论,这太难了,你把它归因于“吸取的教训”。你什么也没送来。

你如何应对这种情况?

问问自己,我能交付的最有用的东西是什么,能多快交付?

如果你只是在一天之内推出一个超级简单的线性回归模型会怎么样?这就引出了一个你会在很多博客和会议上听到的常见短语:

"生产中的平均水平胜过货架上的优秀水平."

专注于有用的东西完全改变了框架。几个百分点的准确性很少能胜过在 1/10 的时间内将东西送到最终用户手中。随着您构建越来越多的解决方案,您会意识到,一旦您将最终产品交付给最终用户,需求几乎总是会发生变化。

为什么不把中间难的部分删掉呢?

这种方法将极大地改变你对团队的贡献。您将能够更快地交付真正的价值,并在此过程中通过可靠的反馈迭代复杂性。

2 .数据质量>超参数调整

这一个将几乎立刻成为你的一根巨大的刺。问题是发现它需要一段时间。就像老板的新衣服,没有人有足够的信心指出来,我们只是继续做我们所期待的。

我说的是数据质量。

我很高兴看到许多行业领导者现在正在推动“以数据为中心的人工智能”和数据质量的重要性。这是一个非常广泛的话题,吸引了许多人的注意力。

这不是性感的东西,是吗?这是为什么呢?

当我们进入数据科学时,有一些关于调整损失函数和玩纪元的东西吸引着我们。这让你觉得自己像一个飞行员或什么人完成了一些复杂的精确操作。问题是,超参数只能带你走这么远。此外,现在有很多工具和库——比如 HyperOpt——不管怎样,它们都会把所有这些有趣的东西强行带走。

当你真正开始挖掘丑陋的东西时,大胜利就来了。

为什么这个数据这么乱?

从表面上看,寻找流氓空白和不可靠的日期格式并不像我希望的那样是令人兴奋的数据科学职业。当你真正进入其中时,你会意识到数据质量变得更加重要。这是一个需要解决问题的技能、分析思维、编码和领域知识的挑战(等等,这听起来像数据科学吗?!).

当涉及到提高模型性能时,陷入数据质量通常是最大的损失。这是一个非常棘手的问题,没有一个工具可以通过点击按钮来解决。

3 .简单>新颖

我们都经历过——现在是凌晨 02:12,你整晚都在搜索 Kaggle 笔记本。你看到了一些不可思议的事情,你只是渴望去尝试。你明天去上班,说服你自己、你的团队或任何人,这是你问题的解决方案。埃舍尔可能会称之为“稍微复杂和不清楚”的事实不会影响你——你是一名数据科学家,这种东西应该是复杂的。

这比你想象的要多花一点时间,但是你明天会完成的。

然后再久一点。

然后你就卡住了。

现在很多时间过去了,你已经忘记了你从哪里开始。你向社区伸出援手,因为这与你预期的结果不符。这么花哨,为什么不表演?

这可能很难接受,但您会注意到许多更高级的数据专业人员都完成了这一旅程的某些版本。你开始你的职业生涯时,渴望使用最好最精致的工具——老实说,它们很有趣。随着你的进步,你开始意识到不仅仅是建模,精彩的部分总是在后面。

找个管用的就行了!

事实上,它不需要工作。什么都可以。在一家公司,我曾经告诉我的团队使用随机数生成器作为模型。这意味着所有的 ETL、监控、部署、日志等等。最重要的是,评分和跟踪过程。然后,当一切顺利时,你就已经有了一个不错的低目标要达到了。

从那里开始迭代。

从现在开始,当你着手一个项目时,问问自己“什么是最简单的可能的解决方案,能让我在这里得到答案?”。如果你到了一个简单的解决方案就能完成工作的地步,你的同事和利益相关者就会意识到它是多么容易维护和理解。你不会后悔的。

4.沟通>一切

在你的职业生涯中,有一个时刻,你开始意识到许多死胡同和重大胜利都可以归结为一件事——沟通。

许多技术人员抱怨的一件事是,当他们变得更高级时,他们必须参加的会议大量增加。随着你专业知识的增长,越来越多的团队想要占用你更多的时间。这是你能力的副作用,应该接受。

这都是关于杠杆。

在雷伊·达里奥的《原则》中,作者谈到了管理者应该如何寻求增加他们一天中每个小时的工作时间。也就是说,对于你——经理——一个小时的沟通,5 个小时、10 个小时甚至 20 个小时的工作都会畅通无阻。

这是一个强大的思想。你给人们提供信息和建议的时间可以让他们提供更多的价值,你应该建立系统来最大化这个乘数。当然,这个指标并不完美——它衡量的是投入而不是结果,但这个想法仍然有价值。

它还很好地将自己引入团队,以及组成许多数据角色的昂贵而稀有的技能。这些天不可能跟上。你不可能成为所有工具的专家。这需要一个混合技能的团队来真正做到这一切。但是,如果你不能有效地将你的需求或工作传达给团队中必要的成员,那该怎么办呢?导致令人沮丧的工作和有限的产出。通过磨练你在团队中的沟通,你会让自己和周围的人更有效率。

以上两点几乎都是关于做更多的事情。但是把正确的事情做好呢?

你猜对了,通讯又罢工了。

没有什么比拒绝和提炼你的利益相关者可能有的所有糟糕的想法更能让你更有效率和更有成效。说真的。我们中的许多技术人员都沉迷于尽可能地提供帮助,并为每个问题提供最佳解决方案。然而,我们中的大多数人很少会停下来质疑这些问题是否是正确的。

沟通的很大一部分是进入利益相关者的头脑,倾听他们的担忧,并深刻理解是什么驱使他们寻求你的帮助。一旦你明白了这一点,你就可以开始引导他们解决挑战,这将真正推动他们关心的结果。不只是福特所说的更快的马。

这里还有一点需要说明的是,如何最好地向不同的受众传达深入的技术内容——但沟通的很大一部分是知道何时停止谈论,并且这篇文章足够长。也许下次吧。

摘要

数据科学是一个庞杂复杂的职业。我在这个过程中犯了很多错误,但随着时间的推移,我学到了一些松散的一般经验法则。

在构建解决方案时,您应该始终优化有用性和影响。数据科学家拥有稀缺的技术技能,可以解决许多问题,但在寻找完美解决方案的过程中,他们很容易迷失在复杂的技术中。

对于大多数数据科学家来说,数据质量技能将比机器学习技能更重要。作为这种学习的结果,我们看到了以数据为中心的方法的兴起。花点时间让自己熟悉一些数据质量工具和方法,以便立竿见影。

简单是一种强大的东西。机器学习领域的变化很快,尝试复杂的解决方案来弥补边际收益可能很有诱惑力,但你应该始终意识到,更简单的解决方案往往更容易采用和维护。

最后,沟通是这个职业最重要的部分。花时间练习和提高你在写作、展示和(最重要的)倾听方面的沟通技巧。

这些规则让我受益匪浅。

希望他们对你有帮助。

如果我想起更多,我一定会分享它们。

如果你有任何问题,请在评论中或其他平台上告诉我——我将非常感激。

强大云计算基础的 4 个先决条件

原文:https://towardsdatascience.com/4-prerequisites-for-a-strong-cloud-computing-foundation-5d45f9de19f4

如何巩固你对云计算技术的理解

Unsplashengin akyurt 拍摄的照片

我在大学里学了一门云计算课程,马上意识到自己力不从心。尽管阅读了云计算平台提供的令人难以置信的全面和精心编写的文档,但我经常发现自己会问这样的问题:

  • 这个云服务实际上是做什么的?
  • 它如何/为什么创造价值?
  • 我如何将这项服务整合到我自己的云系统中?

总的来说,我要么不理解某些云原则背后的理论,要么不知道如何在实践中利用某些云技术。

很明显,在那一点上,我钻研了云计算技术,却没有打下良好的基础。实际上,在我有资格进入云计算领域之前,我需要学习许多主题和概念。

对于那些发现自己处于类似位置的人,这里有 4 个主题是学习云计算之前应该学习的。

1.建立工作关系网

掌握云原理和技术需要了解网络原理。毕竟,构建云解决方案需要找到将数据或资源从一个位置转移到另一个位置的最佳方式。

研究云服务而不真正理解其基本原则和概念类似于本末倒置。例如,如果你甚至不知道 CDN 是什么,你就不可能理解云平台的 CDN 服务(例如 AWS CloudFront)。

当然,在学习云计算之前,不需要成为一名成熟的 IT 专家。但是,了解设备如何相互通信是很重要的。此外,熟悉常用的网络术语也很重要,如“IP 地址”、“DNS”和“互联网”。

幸运的是,这些概念中的大部分都包含在许多免费且易于获取的网络 101 课程中。对于那些从头开始的人来说,这个来自 IBM 的博客将是一个很好的起点。

仅仅通过入门课程,你不太可能学到你需要的所有东西,但它将作为一个起点,帮助你更轻松地消化更高级的概念。

2.安全和网络安全

安全性可能不是构建和维护云解决方案最吸引人的部分,但对于成功的企业来说却是必不可少的。未能保护您的资源可能会导致不必要的后果,如财务损失、客户损失和声誉损失。

云计算平台提供的服务有助于避免这种结果,但用户需要对潜在的安全威胁和最佳安全实践有一个基本的了解,以便正确地利用这些服务。

总体而言,系统容易受到外部网络威胁(如 DDoS)和内部安全风险的影响,前者由不良行为者实施,后者可能由粗心大意或心怀不满的员工造成。

许多受欢迎的云提供商都提供了解决外部和内部风险的方法。它们使管理员能够采取安全措施,如限制用户访问、轮换访问密钥、加密数据和配置防火墙。

类似于网络,学习云计算不需要完全掌握安全原理。一个简单的入门课程将教会用户他们需要知道的一切。

虽然网上有很多课程,但我发现 Codecademy 的网络安全入门简单易懂。

3.Linux 操作系统

部署到云中的应用程序或数据库将在 Linux 上运行,因此学习编写 Linux 命令是学习在云平台上工作的自然前提。

至少,用户应该能够编写日常使用的命令,比如移动文件和安装包。

有无数的资料显示了一套全面的 Linux 命令。这里有一张 Linux 命令的备忘单供参考。

4.程序设计语言

许多人说,你可以在不了解任何编程语言的情况下学习使用云。这是真的,但是没有对一门编程语言的精通,你只能在一定程度上应用你的云计算知识。

云平台的用户界面(UI)足以供应、配置和利用资源。然而,当操作需要缩放时,单独使用 UI 是不可行的。

对于规模不断扩大的系统来说,仅通过点击来执行任务更加耗时,而且容易出错。毕竟,维护云系统通常需要执行简单、重复的任务,如果手动完成,这将需要付出艰苦的努力。

云平台提供功能即服务(FaaS)产品,可用于自动化这些任务(例如,AWS Lambda、GCP 云功能)。这些服务提供无服务器计算能力,执行用户提供的代码作为对某些事件的响应。当然,要利用这些服务,至少需要一门编程语言的知识。

云平台还使用户能够使用 API 将云服务集成到他们的应用程序和脚本中。

简而言之,即使一个人能够掌握给定平台提供的云服务,他们无法用编程语言编写也会限制他们对这些服务的使用。

因此,那些没有编码经验的人应该专注于在某种程度上精通一种编程语言。我个人的建议是学习 Python。它简单直观,网上到处都有免费的语言教程。

结论

照片由 Unsplash 上的 Prateek Katyal 拍摄

总而言之,希望学习云计算的用户需要熟悉网络、安全性、Linux 命令和至少一种编程语言。

初学者可能犯的最大错误是立即学习特定的云平台,因为这将阻碍他们长期的学习。

用户可能不愿意放弃自我和修改基本主题,但在这些主题上打下坚实的基础将使他们能够理解云原则并更有效地将其付诸实践。

感谢您的阅读!

指导数据团队领导的 4 项原则

原文:https://towardsdatascience.com/4-principles-to-guide-data-team-leaders-ef02eaef6b7

建立高绩效团队的管理哲学

马文·迈耶在 Unsplash 上的照片

W 帽子造就伟大的领袖?在从个人贡献者转变为数据科学团队领导之前,我一直在纠结这个身份问题。如果结果是习惯的函数,而习惯是身份的函数,那么这个问题的答案就像是一个使命宣言。当你接受建立或领导团队的责任时,你的领导价值观会影响你的决策和互动。

我的管理理念源于我的核心使命和价值观;我努力成为一名有思想的领导者,为个人赋权,为他人拓展机会。反思这个使命,我决定作为一名领导者实践这四个核心价值观。这篇文章将讨论这四个原则,以及为什么它们对于建立高绩效、持久且适应性强的团队至关重要。

1)委托个人在战略背景下指导他们的决策。

持久团队的基础是信任。没有信任,交流就变得不清晰和不规范,团队就变成了独立行动的松散的个人团体,而不是利用彼此优势的合作者。更糟糕的是,缺乏信任会导致内部竞争,因为信息在小团体中变得孤立,或者当个人感知到群体内和群体外的动态时,会恶化成怨恨。培养心理安全是领导者的首要责任,这是团队的共同特征,团队可以团结在共同的目的感周围,自由交流思想,以确定最佳解决方案,而不用担心失败。

那么,一个领导者该怎么做才能创造一种有凝聚力的目标感和心理安全感呢?首先,将你作为领导者所能接触到的所有战略背景委托给你的团队。仅仅分享什么——比如公司目标、项目优先级或组织变化——阐明为什么至关重要是不够的。计量信息很少是明智的策略——如果你不信任掌握信息的人,那你当初为什么要雇佣他们呢?如果他们发现你在没有充分理由的情况下隐瞒信息,他们对你领导能力的信心可能会降低。在这种情况下,忽略事实和故意误导一样具有破坏性。

数据从业者团队之间的信任对于维护高质量的数据产品至关重要。小组之外的利益相关者不具备批判临时分析或即将投入生产的数据产品的能力。引入质量控制是团队的责任,如果没有基本的信任,就很难提供诚实的批评。缺乏信任意味着人们不会说出来,错误得不到纠正,利益相关者会注意到,这会影响团队的可信度。

例如,考虑一下网飞的文化,在那里(几乎)所有信息在所有员工之间自由流动。思想的自由交流产生了同事之间的信任,打破了孤立沟通的障碍,并增加了战略讨论中观点的多样性。正如 Erin Meyer 所写的,如果你信任你的团队处理敏感信息,你可以增加彼此之间的主人翁感和责任感[1]。

领导者有责任通过尽可能多地与每个人分享来传达透明的信息。大事小事,不管是好是坏——如果你的第一反应是把大部分信息公布出来,其他人也会这么做。

—雷德·哈斯汀斯

2)授权他人围绕目标进行自我组织,并确定通往成功的最佳路径。

在团队中创造自主感是信任的自然延伸。如果你已经将组织可用的所有战略背景委托给你的团队,让他们告诉你如何最好地实现团队或公司的目标。毕竟,如果你不相信他们能找到最好的解决方案,那你为什么还要雇佣他们呢?

赋予您的团队围绕目标进行自组织的自主权,还有一个附带的好处,就是灌输解决方案的所有权。这里的“所有权”超越了组织角色和责任——我们更有可能对自己创造的东西,而不是交给我们的东西,感到一种真正的联系和自豪感、承诺和责任感。此外,允许团队成员自我识别他们解决问题的战术方法,然后允许他们按照计划执行,这为他们创造了更多的成长机会。通过这种方式,他们可以发展规划技能,解释结果,从错误中学习,为成功邀功,并结合所有这些学习来改进他们的方法。

在分析团队和数据产品开发的背景下,这通常意味着阐明业务目标、产品需求或“北极星”指标,并遵从数据从业者关于正确数据、EDA、数据产品和实验的意见来满足这些需求。让分析团队设计他们的解决方案是展示对他们专业知识的信任的另一种方式。同时,个人有机会战略性地思考如何支持更高层次的目标(相对于实施解决方案的战术、技术细节)。

一个要小心的陷阱:如果你准备授权你的团队确定实现集体目标的最佳策略,你需要准备好贯彻并信任他们的方法。被告知你可以自主地围绕一个共同的目标组织起来,但你的建议却被忽视或忽略(在协作、建设性反馈的背景之外),这令人沮丧。否认自主肯定会破坏信任,更不用说对不是你设计的解决方案(也许是你选择的而不是你喜欢的方法)很难有真正的所有权和责任感。另一方面,授权团队自组织也意味着后退一步,信任他们的方法,尤其是当这需要看着他们在通往最优解决方案的路上蹒跚而行的时候。

3)为团队成员提供工具、技术、培训和时间,让他们脱颖而出。

你已经将成功所需的环境托付给了你的团队,并赋予他们应对挑战的能力。也许他们对解决一些商业问题的新的或新颖的方法感到兴奋,但是从来没有人测试过所需的技术或技巧。为你的团队配备成功所需的资源——工具、培训或时间——其实就是倾听。如果你已经培养了一种心理安全感,并且相信你的团队能够找到正确的方法,你的团队会告诉你他们需要什么才能成功。

卢卡·布拉沃Unsplash 上拍摄

对于数据从业者的领导者来说,这意味着听取对您的技术堆栈的反馈,保护团队成员的学习时间,并为问题空间或领域的发展提供机会。每一个新项目都代表着另一个机会,让人们评估竞争格局,提炼领域知识,并定义解决问题的最佳技术方法。在这个关键的学习阶段保护他们的时间可以为项目带来回报,并表明你重视个人成长。能够不断学习的数据从业者不仅会随着时间的推移生产出最好的产品,而且更有可能留在团队中,为团队提供成长空间。

在高绩效团队中,保护个人发展的时间可能会变得特别成问题,在这种团队中,个人贡献者自然会推动自己达到并超过集体目标。随着项目截止日期的临近,很容易让个人发展计划半途而废,或者当您可以开始发展时,花更少的时间做一些文献综述。在这些时刻,以身作则至关重要。许多团队从公司文化的领导那里得到暗示,尤其是在为个人发展留出时间的时候。如果你的团队看到你花时间进行个人成长、深思熟虑的项目规划等。,他们会觉得自己更有能力去做。

当然,有时以身作则是不够的,尤其是在远程工作环境中,一些个人或技术投资可能不太明显。设定标准是通过设定期望值来创造心理安全的一种方式。例如,说“鼓励每个人参加行业会议”是一回事,说“我们团队的每个人都应该计划每年至少参加一次个人发展会议是另一回事。”后者表明你会优先考虑这些时间,并且会和团队一起保护它们。同样,如果你提示你的团队告诉你他们需要什么才能成功,你最好准备好交付!

4)鼓励透明、开放的支持性反馈和诚实沟通的文化。

你的团队正在自主地实现组织的目标。你用工具、培训和时间来装备他们,让他们成功并粉碎他们的项目。为了保持事情顺利进行,鼓励公开对话。一个诚实、开放的文化既要关心个人的需求,也要确保团队成员相互挑战。

你也许可以很快地委托你的团队,在一对一和团队会议上交流策略和改变优先事项。然而,坦诚的交流是建立开放、诚实文化的必要但不充分的因素——这需要时间和脆弱性。这个原则放在最后,但对于那些希望建立持久的团队和适应性强的团队的领导者来说,这当然不是最不重要的;这可能是你需要花费最多时间和精力去深入理解团队中每个人的动机和驱动力的地方。

脆弱始于领导者,他们永远不应该害怕展示他们与团队的成长空间。征求反馈是提供反馈的一种强大的方式,可以成为持续改进文化的一部分,在这种文化中,每个人都感到相互负责。也就是说,重要的是建设性的反馈是为了成长,而不是成为“聪明的混蛋”[2]。

谦逊、乐于助人,当面立即提供指导,公开表扬,私下批评,不要个人化。

—金·斯科特

对于已经是高影响高产出的团队来说,脆弱性对于防止倦怠是至关重要的。高绩效的个人和团队——对重要产品或项目的所有权培养了责任感——自然倾向于超出预期。你需要你的团队告诉你什么时候他们被拉得太紧了,这只有在他们感到安全的时候才会发生。可以通过定期检查个人带宽来鼓励这种行为。抓住机会接触工作中的感受(“现在什么项目让你压力最大?”),表明你关心某人的幸福和生活在工作之外(“你周末过得怎么样?”),并可能根据需要通过授权和优先级排序来指导他们。在工作场所之外,我们都有优先考虑的事情,有效的管理者会在他们生活中发生的每一件事情的背景下支持他们的团队。

培养脆弱文化的另一个结果是适应性。当你不知道如何解决一个新问题时,承认这一点需要谦虚和开放,能够公开讨论这个问题或与你讨论的队友更有可能对新的挑战做出快速反应。所以,如果你想让你的团队坚持下去——在响应组织不断变化的需求的同时避免精疲力竭——优先考虑脆弱性。

结论

作为组织文化的管理者,杰出的领导者在每一次互动中体现他们的价值观,他们如何表现自己,并从他们的团队和同事那里寻求反馈。要建立高绩效、适应性强的团队,您可以:

  1. 将战略背景委托给个人来指导他们的决策。
  2. 授权他人围绕目标进行自我组织,并确定通往成功的最佳路径。
  3. 为团队成员提供工具、技术、培训和时间,让他们脱颖而出。
  4. 鼓励透明、开放的支持性反馈和诚实沟通文化。

我一直在寻找机会改进和重复我的风格,并在这样做的过程中,形成一种信任和授权的文化,让他人能够茁壮成长。在建立高绩效、令人满意的团队时,找到与你的核心价值观相共鸣的理念,并让我知道什么对你有效。

[1]雷德·哈斯汀斯和艾琳·迈耶斯,没有规则的规则(2020)
【2】金·斯科特,激进的坦率 (2019)

4 数据科学家的项目管理技能和框架

原文:https://towardsdatascience.com/4-project-management-skills-and-frameworks-for-data-scientists-77141196239b

在本帖中,我们将学习 3 个项目管理框架和 1 个帮助数据科学家将项目引向成功的技巧

照片由 @halacious @unsplash.com 拍摄

M ost 数据科学项目是时间固定、预算有限的项目。尽管数据科学项目由于其科学性而拥有一些宽松的“自由时间”是有益的,但资源(时间、金钱或人员)有限的事实证明,必须仔细规划数据科学项目。最后,你想让涉众高兴,好的计划设定期望并控制项目的执行。

这一点与咨询活动特别相关,因为在咨询活动中,偏离最初的计划可能是灾难性的。财务激励必须与项目实施相一致,任何超出预算或不完整的项目通常都是由糟糕的规划造成的。

虽然数据科学项目确实有失败的可能性,但失败的原因应该是统计假设,而不是缺乏规划。

是的,从上到下管理项目不是数据科学家的主要职责,但学习一些框架肯定会有助于理解某些项目决策,并建设性地参与指导项目走向成功。另一个好处是,学习一些项目管理技能和框架将有助于你在职业生涯中晋升到高级职位,因为随着你责任的增加,这些技能变得更加重要。

在本帖中,我们将学习一些相关的项目管理框架或数据科学家的技能。因此,让我们进入一些概念,这些概念可能对您作为数据科学家或数据世界中的管理者的日常工作有用!

顺便提一下:由于它们的特殊性,大多数数据科学项目都包含大量的不确定性(因此有了科学的名称),并且这些框架应该总是有所保留,不能盲目应用。

IPECC —框架

IPECC 代表启动—计划—执行—控制—结束。这是一个由项目经理使用的通用框架,用于跟踪项目并了解项目是如何展开的。

虽然 IPECC 框架在每个阶段都有一些标准任务,但我将解释如何在典型的数据科学项目环境中使用它们。让我们探索每个阶段。

开始

初始阶段是项目框架中最相关的阶段之一。这是项目范围界定发生的地方,也是您定义重要涉众的地方。在数据科学背景下,此阶段涉及的一些常见任务:

  • 了解项目的主要利益相关者;
  • 了解哪些数据源可用于项目
  • 评估数据集成的复杂性和预期的时间工作量;
  • 定义问题并绘制可用解决方案的计划;
  • 确定项目的到期日

规划

在规划阶段,在整个启动阶段收集的所有英特尔信息将被推广到高级计划中,该计划应得到所有利益相关方的批准。

规划阶段也有助于两个要点:在团队成员之间划分任务,并绘制项目的整体流程。与数据科学项目相关的一些规划任务有:

  • 制定模型开发的时间表 —包括关键检查点和利益相关者会议的召开地点。
  • 制定数据整合、基线模型开发和模型改进的时间表。
  • 评估项目开发的可用约束(例如,模型的可解释性、合理的培训时间等。);

给“创造性任务”留些空间也很重要。在项目开发过程中会出现新的想法是很常见的,计划好时间进行一些实验将是设定利益相关者期望的关键。

执行和控制

这两个阶段通常同时发生,是项目开发的支柱。执行是项目的发展,控制是对执行和原始计划的不断评估。

两个阶段的共同任务:

  • 跟踪时间表和计划。比较是否有项目延期或评估项目风险。
  • 保持对商业利益相关者管理的跟踪——特别是当最初的需求得到满足的时候。
  • 技术团队和商业利益相关者之间的定期交流。
  • 当然还有车型本身的开发。

关闭

在收尾阶段,项目被提交,主要结论与业务涉众进行讨论。对于数据科学项目,以下是最重要的任务:

  • 了解业务目标是否已经实现。
  • 讨论项目结果——在假设失败的情况下,讨论从新发现的知识中获得的收益。一个失败的假设可能和一个被验证的假设一样有价值,这取决于商业环境。
  • 封装相关文档并将项目移交给最终利益相关方 —每个数据科学家都必须关注两个角度:1)将来需要维护解决方案的其他开发人员/数据科学家— 2)将在特定用例中使用输出的业务用户。

风险管理—框架

风险管理框架有助于为不确定性做好计划,并围绕可能破坏您的数据科学项目的事件更好地构建概率。

识别和评估这些风险是制定逃生路线和计划以避免混乱的关键。项目的每个阶段都涉及风险对于数据科学项目来说,最常见的风险围绕着资源和数据。

以下是项目生命周期中可能与 map 相关的一些风险示例:

  • 如果我的一名数据科学家离开团队会怎么样(由于生病、自愿离职等原因)。)?
  • 如果我们无法使用训练模型所需的数据源会发生什么?
  • 我的数据源中包含的任何数据是否存在监管风险

思考风险会迫使你制定一个计划来减轻风险。风险管理框架将有助于针对项目固有的不确定性进行规划和计划。

如果你想了解更多关于风险和处理风险的 6 步框架,请查看这篇博文。

史诗和用户故事—框架

史诗用户故事对于在敏捷团队中工作的数据科学家来说并不陌生。

史诗是可能代表几个用户故事的高层次任务的集合——编写一个好的史诗是符合利益相关者期望的关键。设想一个数据科学项目,构建一个“预测系统,为一家冰淇淋公司预测销售额”——两个史诗的一个例子是:

  • "作为一名销售经理,我需要根据销售预测了解哪些地区是我需要重点拓展的"
  • “作为一名物流经理,我需要评估需求,以便相应地准备我们的生产”

对于数据科学, Epics 有助于绘制模型结果,并为项目定义正确的利益相关者。

基于上面的例子,我们会立即知道我们应该在项目循环中包括后勤和销售团队。这有什么关系?假设您后来发现物流经理需要每日预测,而销售经理更喜欢每周预测— 这将立即改变您整个开发的工作方式,改变您组织数据管道的方式,因为您需要每日粒度。

用户故事是更小的史诗块,包含了对特定需求的更细粒度的描述——拿我们的后勤团队的例子来说:

  • “作为物流经理,我需要在我的生产仪表板上看到预测”;
  • “作为一名物流经理,我需要模拟天气预测如何改变预测”;

这些低级的故事可能会改变你的可交付成果,并帮助你将工作分成具体的块。正如你所想象的,史诗用户故事与项目计划有着内在的联系。

集成在敏捷框架中,这些概念与涉众管理高度相关,并且它们旨在避免项目中两个最常见的错误:

  • 建造错误的东西;
  • 构建只适合组织一小部分的东西;

持续沟通——技巧

项目经理发展的另一项技能是持续的沟通和有价值的反馈。

为什么这对数据科学家很重要?数据科学家需要能够以清晰的方式传达他们的结果,并为业务利益相关方解释数据科学模型的复杂性。特别是,数据科学家应该避免成为“象牙塔工程师”——培养良好的沟通技能是与同事和利益相关者建立更牢固关系的良好步骤。

持续的沟通和清晰的反馈是一项非常特殊的技能,可以在项目的多个阶段使用,例如:

  • 沟通模式的改进;
  • 征求利益相关者的反馈;
  • 将新信息纳入项目开发;
  • 向其他开发人员反馈他们的代码;

总而言之,持续的沟通是一种防止项目开发中保护利益相关者的方法,提高了项目成功的可能性。

感谢你花时间阅读这篇文章!这些是我一直在努力提高的一些技能,也是我为了成为更好的数据科学家而尝试应用的一些框架。正如我所说的,应用它们并不是数据科学家的强制要求——截至目前,数据科学家的主要目标仍然是开发良好的模型——但我真的相信它们是一个很好的附加物,可以提高良好项目结果的可能性,最终,我们都希望引导我们的项目走向成功。

想补充点什么?写在下面的评论里!

我在 R 从零开始在Udemy上开设了一门学习数据科学的课程——这门课程是为初学者设计的,包含 100 多个练习,我希望您能在身边!

你应该知道的 4 个 Python 技巧

原文:https://towardsdatascience.com/4-python-hacks-you-should-know-29acbc45addd

数据科学

列表上的一堆用例以及字典理解

卡洛斯Unsplash 上拍照

Python 更好!

在现实世界中,对于数据科学来说,Python 通常被广泛用于转换数据。它提供了强大的数据结构,使得处理数据更加灵活。

我所说的“灵活性”是什么意思?

这意味着,在 Python 中,总是有多种方法可以获得相同的结果。总是选择易于使用、节省时间并能更好地控制转换的方法。

当然,不可能全部掌握。因此,我列出了在处理任何类型的数据时都应该知道的 4 个 Python 技巧。

这里有一个快速索引供你参考。

· [Duplicate a List using List Comprehension](#0451)
· [Multiply elements in a list using List Comprehension](#a8b8)
· [Remove negative elements in a List using List Comprehension](#4c90)
· [Convert two lists into Dictionary Key-Value pair using dict()](#11af)

先从经典的东西开始。

列表理解 是创建列表的一种优雅且最有技巧的方式。与 for 循环和 if 语句相比,list comprehensions 具有更短的语法来基于现有列表的值创建新列表。因此,让我们看看这个特性如何获得一个列表的副本。

使用列表理解复制列表

有时您需要创建现有列表的副本。最简单的答案是.copy(),它让你将一个列表的内容复制到另一个(新的)列表中。

例如,假设您有一个由整数组成的列表— original_list

**original_list = [10,11,20,22,30,34]**

你可以简单地用下面的.copy()方法复制这个列表。

duplicated_list = **original_list.copy()**

然而,使用列表理解方法可以得到完全相同的输出。复制列表是理解列表理解工作的最佳用例。

你需要做的就是执行下面这段代码。

duplicated_list = **[item for item in original_list]**

当然,决定使用哪个选项是你的选择。知道实现相同结果的多种方法是有益的。

接下来,让我们看看当您想要对列表中的每个元素执行数学运算时,列表理解是如何让您的生活变得简单的。

使用列表理解将列表中的元素相乘

乘法最简单或直接的方法是使用乘法运算符,即*****

例如,假设您想用一个标量(即数字 5)乘以列表中的每一项。在这里,你可以不做**original_list*5**,因为它将简单地创建列表的 5 个副本。

在这种情况下,最好的答案是列表理解,如下所示。

original_list = [10,11,20,22,30,34]
multiplied_list = **[item*5 for item in original_list]**# Output
[50, 55, 100, 110, 150, 170]

简单!

乘法不仅限于一个数字。相反,您可以对原始列表的每个元素执行复杂的操作。

例如,假设您想计算每一项的平方根的立方。使用列表理解,你可以只用一行就解决它。

multiplied_list = **[math.sqrt(item)**3 for item in original_list]**# Output
[31.6227766016838,
 36.4828726939094,
 89.4427190999916,
 103.18914671611546,
 164.31676725154983,
 198.25236442474025]

请注意,用于计算数字平方根的函数**sqrt**属于库 math,因此在使用它之前需要导入。

类似于上面显示的内置函数,您也可以在列表的每个元素上使用用户定义的函数。

例如,假设您有一个如下所示的简单函数。

def simple_function(item):
    item1 = item*10
    item2 = item*11
    return math.sqrt(item1**2 + item2**2)

您可以对列表中的每个项目应用此用户定义的函数。

multiplied_list = [simple_function(item) for item in original_list]# Output
[148.66068747318505,
 163.52675622050356,
 297.3213749463701,
 327.0535124410071,
 445.9820624195552,
 505.4463374088292]

嗯,列表理解在实际场景中会更加有用。通常,在您的分析任务中,您需要从列表中删除某种类型的元素,例如负面或正面元素。列表理解是完成这些任务的完美工具。

使用列表理解删除列表中的负面元素

根据特定条件过滤数据是选择所需数据集的常见任务之一。并且在列表理解中使用相同的逻辑来从列表中移除负面元素。

假设你有下面提到的数字列表。

original_list = [10, 22, -43, 0, 34, -11, -12, -0.1, 1]

并且您希望只保留列表中积极的项目。因此,从逻辑上讲,您希望只保留那些评估条件**item > 0**为真的项目。

你可以如下使用列表理解。

new_list = **[item for item in original_list if item > 0]**# Output
[10, 22, 34, 1]

上表理解中的**if clause**是去除负面价值的真正原因。这意味着您可以使用这个if clause应用任何条件从列表中删除任何项目。

例如,当您想要删除所有平方小于 200 的项目时。你所需要做的就是在下面的列表理解中提到条件**item**2 > 200**

new_list = [item for item in original_list **if item**2 > 200**]# Output
[22, -43, 34]

在处理真实数据集时,过滤列表项的条件可能会复杂得多,因此最好知道最快的方法。

接下来,让我们了解字典理解如何将两个列表转换成一个键-值对,即转换成一个字典。

使用 dict()将两个列表转换成字典键值对

有时,您需要从两个列表中的值创建一个字典。不用一个一个打,可以用字典理解法。

字典理解是一种优雅简洁的创建字典的方法!

它的工作方式与列表理解完全相似,唯一的区别是——要创建列表理解,您需要将所有内容括在方括号内,而在字典理解中,您需要将所有内容括在花括号内

让我们用一个例子来更好地理解它。

假设您有两个列表——fieldsdetails——如下所示。

fields = [‘name’, ‘country’, ‘age’, ‘gender’]
details = [‘pablo’, ‘Mexico’, 30, ‘Male’]

您想用它创建一个字典,其中键是来自字段的项,值是来自细节的项。

一个简单的方法是使用字典理解,就像这样—

new_dict = **{key: value for key, value in zip(fields, details)}**# Output
{'name': 'pablo', 'country': 'Mexico', 'age': 30, 'gender': 'Male'}

这里需要理解的重要事情是函数 zip 是如何工作的。

在 Python 中,zip 函数将字符串、列表或字典等可重复项作为输入,然后将它们聚合为元组返回。

所以在这种情况下,zip 已经形成了列表fieldsdetails中每个项目的配对。当您在字典理解中提到**key: value**时,简单地说,这个元组被分解成单独的键-值对。

当您使用 Python 中的内置**dict()**构造函数(用于创建字典)时,这个过程会变得更快。

dict()比字典理解至少快 1.3 倍!

同样,您需要将这个构造函数与 zip()函数一起使用,以获得与上面完全相同的输出。它有更简单的语法— **dict(zip(fields, details))**

仅此而已!

正如我最初提到的,Python 是灵活的,因为有多种方法可以达到相同的结果。根据任务的复杂程度,你需要选择最好的方法来完成它。

因此,了解所有这些备选方案以获得相同的结果是一个更好的想法。

希望这篇文章能让你耳目一新,大有裨益。让我也知道,如果有任何其他的方法来做同样的事情,正如我在这篇文章中提到的。

看看我以前写的关于 Python 中的列表和字典的文章,就知道更多的技巧了。

  1. Python 字典:你需要知道的 10 个实用方法
  2. 轻松掌握 Python 的 5 种方法

请注意,免费媒体会员只能阅读 3 篇会员专用的文章。在媒体上阅读无限故事 今天用我下面的推荐链接成为媒体会员 。当你这么做的时候,我会从你的费用中得到一小部分。

https://medium.com/@17.rsuraj/membership

还有,别忘了 订阅我的邮件列表

感谢阅读!

4 个 Python 包来创建交互式仪表盘

原文:https://towardsdatascience.com/4-python-packages-to-create-interactive-dashboards-d50861d1117e

使用这些包来改进您的数据科学项目

卢克·切瑟在 Unsplash上的照片

数据科学项目本质上是一个为观众讲述故事的项目。你的项目有多好并不重要;如果对方不理解你的数据洞察和发现,就无法采取行动。

向观众展示项目的一种方法是创建交互式仪表板。为什么要互动?因为动作比静态的洞察力更能让观众记住。这就是为什么,如果可能的话,创建一个数据科学项目到一个交互式仪表板中是明智的。

在本文中,我想概述 4 个 Python 包,您可以使用它们为您的数据科学项目创建一个交互式仪表盘。这些包裹是什么?让我们开始吧。

1.小工具

Ipywidgets(通常简称为 widgets)是一个交互式包,为 Jupyter 笔记本中的 GUI 提供 HTML 架构。该软件包允许我们直接在 Jupyter 笔记本单元中创建一个交互式仪表板。我会在下面的 GIF 中展示这个例子。

作者 GIF

通过几行代码,您可以将您的 Jupyter 笔记本改进为一个仪表板。让我用几行代码展示一下我们是如何做到的。

首先,我们需要安装所需的软件包。

pip install ipywidgets

然后我们需要在 Jupyter 笔记本中启用 Ipywidgets。要启用它,请在命令提示符下传递以下代码。

jupyter nbextension enable --py widgetsnbextension

我们可以在我们的 Jupyter 笔记本中创建我们的交互式仪表板,所有必要的包都在适当的位置。对于我们的例子,我会使用泰坦尼克号样本数据。

import seaborn as snstitanic = sns.load_dataset('titanic')
titanic.head()

作者图片

准备好数据集后,我们将创建交互式仪表板。例如,我想创建一个交互式仪表板,在那里我可以得到按分类变量分组的泰坦尼克号票价平均值。在这种情况下,我会使用下面的代码。

#Creating the interactive dashboard
from ipywidgets import interact@interact
def create_fare_plot(col = titanic.drop(['fare', 'age'], axis =1).columns):
    sns.barplot(data = titanic, x = col, y ='fare')
    plt.title(f'Mean Bar Plot of the Fare grouped by the {col}')

作者图片

通过添加@interact代码,我们启动了交互过程。在下面的代码中,您将通过创建一个过滤函数来启动仪表板。

代码简单直观;然而,它可能无法回答您需要的所有过程,因为 Ipywidgest 只限于您的 Jupyter 笔记本。让我们看看其他的包裹。

2.瞧

这是一个简单的 Python 包,可以将一个简单的 Jupyter 笔记本变成一个像样的 web 应用仪表板。只需一行安装代码,我们就可以快速呈现我们的 Jupyter 笔记本。让我们试着安装一下仪表盘。

pip install voila

当您完成安装 Voila 软件包后,刷新您的 Jupyter 笔记本并查看笔记本选项卡。在那里你会发现一个新的 Voila 按钮。

作者图片

现在试着按下按钮,你会自动被带到另一个网页,这就是瞧仪表板。

作者图片

还记得之前我用 Jupyter 笔记本中的 Piywidgets 创建泰坦尼克号仪表盘的交互代码吗?现在,它们被转化成了笔记本之外的交互式仪表盘。此外,我们输入的所有代码并没有显示在 Voila 仪表板上。这很好,因为我们只想关注结果。

瞧,仪表板对于一个简单的 Jupyter 笔记本仪表板来说已经足够了,但是如果我们想要更多的灵活性呢?让我们进入下一个包裹。

3.神秘地闪过

Dash by Plotly 是一个开源的 Python 包,它使用 Python 语言提供了一个交互式仪表盘,并提供了创建 web 应用程序的灵活性。

如果你不熟悉 Plotly,它是一个交互式可视化软件包。Dash 是一个低代码框架包,用于开发基于 Plotly 可视化的 web 应用程序。

要试用 Dash,让我们先安装这个包。

pip install dash

安装完成后,我将使用下面的代码创建一个简单的 Titanic 仪表板。

import dash
from dash import dcc, html
import plotly.express as px
import pandas as pd
import seaborn as snsapp = dash.Dash()df = sns.load_dataset('titanic')fig = px.scatter(
df,
x="fare",
y="age",
size="pclass",
color="alive",
hover_name="embark_town",
log_x=True,
size_max=60
)app.layout = html.Div(children = [
html.H1(children='Titanic Dashboard'),
dcc.Graph(id="fare_vs_age", figure=fig)]) if __name__ == "__main__":
    app.run_server(debug=True)

我用 Visual Studio 代码运行上面的代码,并将脚本保存为 app.py。

作者图片

运行上面的代码后,我们将以默认的( http://127.0.0.1:8050/ )方式启动仪表板,您可以在以后更改它。

作者图片

通过额外的代码,我们可以添加一个回调函数,使用户的输入具有一定的输出。

import dash
from dash import dcc, html, Input, Output
import plotly.express as px
import pandas as pd
import seaborn as snsapp = dash.Dash()df = sns.load_dataset('titanic')fig = px.scatter(
df,
x="fare",
y="age",
size="pclass",
color="alive",
hover_name="embark_town",
log_x=True,
size_max=60
)app.layout = html.Div(children = [
html.H1(children='Titanic Dashboard'),
dcc.Graph(id="fare_vs_age", figure=fig),#Add interactive callback here
html.H4("Change the value in the text box to see callbacks in action"),
html.Div([
"Input: ",
dcc.Input(id='my-input', value='initial value', type='text')
]),
html.Br(),
html.Div(id='my-output'),
])@app.callback(
Output(component_id='my-output', component_property='children'),
Input(component_id='my-input', component_property='value')
)def update_output_div(input_value):
    return f'Output: {input_value}'if __name__ == "__main__":
   app.run_server(debug=True)

作者图片

通过一些调整,我们可以改进我们的交互过程。

Dash by Plotly 在创建仪表板方面非常方便,因为它提供了许多有用的 APIs 然而,有时代码结构很难阅读,因为使用的语言是低级的。我们将使用另一个包来创建我们的交互式仪表板来解决这个问题。

4.细流

什么是 Streamlit? Streamlit 是一个开源 Python 包,旨在为数据科学家和机器学习项目创建一个 web 应用。下面是一个你可以用 Streamlit 制作的数据应用的例子。

作者图片

Streamlit 提供的 API 对任何初学者来说都很容易使用,对任何想要交互式构建数据组合的人来说都是完美的。此外,Streamlit 提供了一个免费的应用程序部署,我们可以利用它来在线传播我们的项目。让我们先安装 Streamlit 包。

pip install streamlit

安装过程完成后,我们可以创建我们的交互式仪表板。让我给你下面的代码示例。

import streamlit as st
import pandas as pd
import plotly.express as px
import seaborn as snsdf = sns.load_dataset('titanic')st.title('Titanic Dashboard')st.subheader('Dataset')
st.dataframe(df)st.subheader('Data Numerical Statistic')
st.dataframe(df.describe())st.subheader('Data Visualization with respect to Survived')left_column, right_column = st.columns(2)with left_column: 'Numerical Plot'
    num_feat = st.selectbox(
   'Select Numerical Feature', df.select_dtypes('number').columns) fig = px.histogram(df, x = num_feat, color = 'survived') st.plotly_chart(fig, use_container_width=True)with right_column: 'Categorical column'
    cat_feat = st.selectbox(
    'Select Categorical Feature', df.select_dtypes(exclude =   'number').columns)
    fig = px.histogram(df, x =cat_feat, color = 'survived' )st.plotly_chart(fig, use_container_width=True)

使用 Visual Studio 代码,我将文件保存为 titanic_st.py,并使用以下代码在终端中运行该文件。

streamlit run titanic_st.py

作者图片

Streamlit 应用程序现在运行在上述地址上,您可以选择任何一个,我们可以访问我们的仪表板。

作者 GIF

通过上面的简单代码,我们已经创建了一个交互式仪表板 web 应用程序,它直观并且可以在我们的浏览器中流畅地运行。API 不难理解,因为我们只使用了最少的代码。

Streamlit 还提供免费的应用部署,您可以将其用作您的数据科学产品组合。

结论

当您展示您的数据科学项目时,交互式仪表板将改善观众体验。我介绍了 4 个 Python 包,您可以使用它们来创建交互式仪表板,使之变得更容易。它们是:

  1. 小工具
  2. 神秘地闪过
  3. 细流

希望有帮助!

访问我的 社交媒体进行更深入的交谈或有任何问题。

如果您没有订阅为中等会员,请考虑通过 我的推荐 订阅。

学习因果分析的 4 个 Python 包

原文:https://towardsdatascience.com/4-python-packages-to-learn-causal-analysis-9a8eaab9fdab

通过这些包学习因果分析

法比奥Unsplash 拍摄的照片

因果分析是实验统计学中证明和建立因果关系的一个领域。在统计学中,利用统计算法在严格假设下推断数据集内的因果关系,称为探索性因果分析 ( ECA )。

反过来,ECA 是一种用更可控的实验证明因果关系的方法,而不仅仅是基于相关性。我们经常需要证明反事实——其他情况下的不同条件。问题是我们只能近似因果效应,而不能近似反事实。

图片作者。

因果分析已经是数据科学中一个不同的学习领域,因为它与机器学习建模的预测有着内在的不同。我们可以从现有数据中预测最大似然结果,但无法预测现有数据之外的结果。

为了学习更多关于因果分析的知识,本文将向您展示 4 个 Python 包,您可以使用它们作为学习材料。让我们开始吧。

1.因果关系

Causalinference 是一个 Python 包,提供了各种用于因果分析的统计方法。这是一个简单的包,用于基本的因果分析学习。这些软件包的主要功能包括:

  • 倾向得分估计和子类化
  • 通过修整改善协变量平衡
  • 治疗效果评估
  • 协变量分布中重叠的评估

我们可以在他们的网页上找到关于每个术语的更长的解释。

让我们试试 Causalinference 包。首先,我们需要安装软件包。

pip install causalinference

安装完成后,我们将尝试实现一个因果模型来进行因果分析。我们将使用来自因果参考包的随机数据。

from causalinference import CausalModel
from causalinference.utils import random_data#Y is the outcome, D is treatment status, and X is the independent variableY, D, X = random_data()
causal = CausalModel(Y, D, X)

CausalModel 类将分析数据。我们需要再做一些步骤来从模型中获取重要的信息。首先,让我们得到统计摘要。

print(causal.summary_stats)

作者图片

通过使用summary_stats属性,我们将获得数据集的所有基本信息。

因果分析的主要部分是获取治疗效果信息。最简单的方法是使用普通的最小二乘法。

causal.est_via_ols()
print(causal.estimates)

作者图片

ATE、ATC 和 ATT 分别代表平均治疗效果、对照的平均治疗效果和治疗的平均治疗效果。利用这些信息,我们可以评估与对照组相比,治疗是否有效果。

使用倾向评分法,我们也可以获得关于独立变量的治疗概率的信息。

causal.est_propensity_s()
print(causal.propensity)

作者图片

使用倾向评分法,我们可以评估给定独立变量的治疗概率。

仍然有许多方法你可以探索和学习。建议大家访问 causalinference 网页,进一步了解。

2.考萨利布

Causallib 是 IBM 开发的用于因果分析的 Python 包。该包提供了与 Scikit-Learn API 统一的因果分析 API,这允许使用拟合和预测方法的复杂学习模型。

Causallib 软件包的好处是我们可以在学习过程中使用的示例笔记本的数量。

作者图片

然后,让我们尝试使用 causallib 包进行学习。首先,我们需要安装软件包。

pip install causallib

之后,我们将使用 causallib 包中的一个示例数据集,并使用 Scikit-Learn 中的模型估计因果分析。

from sklearn.linear_model import LogisticRegression
from causallib.estimation import IPW 
from causallib.datasets import load_nhefsdata = load_nhefs()
ipw = IPW(LogisticRegression())
ipw.fit(data.X, data.a)
potential_outcomes = ipw.estimate_population_outcome(data.X, data.a, data.y)
effect = ipw.estimate_effect(potential_outcomes[1], potential_outcomes[0])

上述代码将加载一项关于吸烟对健康影响的跟踪研究。我们使用逻辑回归模型作为因果模型来建立和评估因果效应。

让我们检查一下治疗的潜在结果和效果。

print(potential_outcomes)

作者图片

检查潜在的结果,我们可以看到,如果每个人都戒烟(1)的平均体重差异是 5.38 公斤,而如果每个人都一直吸烟(0)的平均体重差异是 1.71 公斤。

这意味着我们的平均体重相差约 3.67 公斤。因此,我们可以得出结论,吸烟治疗将减少体重增加约 3.67 公斤。

如需更多信息和学习材料,请访问 Causallib 页面上的笔记本。

3.因果影响

Causalimpact 是一个用于因果分析的 Python 包,用于估计时间序列干预的因果效应。该分析试图看出事实发生之前和之后的处理之间的差异。

Causalimpact 将分析响应时间序列(例如,点击、药物效应等)。)和一个控制时间序列(你的反应,但在一个更受控制的环境中)与贝叶斯结构时间序列模型。这个模型预测反事实(如果干预从未发生会发生什么),然后我们可以比较结果。

让我们通过安装软件包来开始使用它。

pip install causalimpact

完成安装包后,让我们创建模拟数据。我们将创建一个具有 100 个观察值的示例数据集,其中在时间点 71 之后将有一个干预效应。

import numpy as np
from statsmodels.tsa.arima_process import arma_generate_sample
from causalimpact import CausalImpactnp.random.seed(1)x1 = arma_generate_sample(ar=[0.999], ma=[0.9], nsample=100) + 100
y = 1.2 * x1 + np.random.randn(100)y[71:100] = y[71:100] + 10
data = pd.DataFrame(np.array([y, x1]).T, columns=["y","x1"])
pre_period = [0,69]
post_period = [71,99]

作者图片

上面,我们获得了一个因变量(y)和一个自变量(x1)。通常,我们会有不止一个独立的,但让我们坚持使用当前的数据。让我们用这些数据进行分析。我们需要具体说明干预之前和之后的时间。

impact = CausalImpact(data, pre_period, post_period)
impact.run()
impact.plot()

作者图片

上面的图给了我们三组信息。上图显示了治疗后时期的实际数据和反事实预测。中间的面板显示了实际数据和反事实预测之间的差异,这是逐点的因果效应。底部面板是干预的累积效果图,其中我们累积了中间面板的逐点贡献。

如果我们想从每个数据点获得信息,我们可以使用下面的代码。

impact.inferences

作者图片

此外,通过下面的代码获得一个汇总结果。

impact.summary()

作者图片

该总结允许我们评估干预的发生是否有因果关系。如果您想要更详细的报告,您可以使用下面的代码。

impact.summary(output = 'report')

作者图片

如果你想了解更多关于时间干预因果分析的知识,请查看他们的文档页面

4.为什么

DoWhy 是一个 Python 包,它用一个简单的 API 和完整的文档提供了最先进的因果分析。

如果我们访问文档页面,为什么通过 4 个步骤进行因果分析:

  1. 使用我们创建的假设对因果推理问题建模,
  2. 确定假设下因果效应的表达式,
  3. 使用统计方法估计表达式,
  4. 验证评估的有效性。

让我们试着用 DoWhy 包开始一个因果分析。首先,我们必须通过运行下面的代码来安装 DoWhy 包。

pip install dowhy

之后,作为样本数据集,我们将使用来自 DoWhy 包的随机数据集。

from dowhy import CausalModel
import dowhy.datasets# Load some sample data
data = dowhy.datasets.linear_dataset(
    beta=10,
    num_common_causes=5,
    num_instruments=2,
    num_samples=10000,
    treatment_is_binary=True)

首先,给定我们创建的图表和假设,我们可以将其发展成因果模型。

Create a causal model from the data and given graph.
model = CausalModel(
    data=data["df"],
    treatment=data["treatment_name"],
    outcome=data["outcome_name"],
    graph=data["gml_graph"])model.view_model()

作者图片

接下来,我们需要用下面的代码来确定因果关系。

#Identify the causal effect
estimands = model.identify_effect()

作者图片

我们确定一个因果效应,然后我们需要从统计上估计这个效应有多强。

estimate = model.estimate_effect(identified_estimand,                              method_name="backdoor.propensity_score_matching")

作者图片

最后,因果效应估计是基于数据的统计估计,但因果关系本身并不基于数据;相反,它是基于我们以前的假设。我们需要用健壮性检查来检查假设的有效性。

refute_results = model.refute_estimate(identified_estimand, estimate,                                     method_name="random_common_cause")

作者图片

这样,我们就完成了因果分析,并可以利用这些信息来决定治疗是否有因果影响。

DoWhy 文档提供了大量的学习材料;您应该访问网页以了解更多信息。

结论

因果分析是实验统计学中证明和建立因果关系的一个领域。这是数据科学中的一个不同领域,需要它的学习材料。

在本文中,我概述了 4 个 Python 包,您可以用它们来学习因果分析。它们是:

  1. 因果关系
  2. 考萨利布
  3. 因果影响
  4. 为什么

希望有帮助!

访问我的 社交媒体进行更深入的交谈或有任何问题。

如果您没有订阅为中等会员,请考虑通过我的推荐订阅。

posted @ 2024-10-18 09:28  绝不原创的飞龙  阅读(359)  评论(0)    收藏  举报