我要求 ChatGPT 分析 3 个数据集。每次都犯同样的错误

审核通过修正了行数并批准了两个错误的结论。

来源:KDnuggets

我们进行了一项实验:三个小数据集、一个人工智能模型,以及业务团队在正常一周内提出的问题 - 我们的平均交付时间是多少,哪个地区是我们表现最好的,这个文件中有多少运动员。

然后我们添加了审核通过。我们将自己的答案交给模型,并告诉它这些数字将进入执行甲板,因此请验证一切。

一次审查发现了错误的行数,并在倒退的结论旁边打了勾。另一个人发明了一种更正,将正确答案变成了错误答案。

下面的所有内容都是可复制的。我们使用 GPT-5.6 Terra 进行快速第一遍,并使用 GPT-5.6 Luna 对相同文件进行一组单独的慢速运行。该代码在 Pandas 和 SciPy 上运行。

数据

首先,我们使用在本次面试问题中使用的shipment_tracking数据表。

shipment_tracking 是每个订单一行。来自 40 个不同客户的 40 个订单,均在 2024 年 1 月 1 日至 21 日之间下达。每行包含三个随着订单进展而填充的日期:从开始开始的订购日期、包裹离开仓库后的发货日期和到达后的交付日期。

看看最后一行:已订购,从未发货,从未交付。数据集中的 40 个中有 18 个是这样的。

我们在本文中处理的第二个文件是 Regional_sales,在本次面试问题中使用。regional_sales 意味着每年每个区域一行:59 行、8 个区域、从 2007 年到 2025 年的年份,以及每个组合的单个销售数字。

该颗粒以两种方式分解,并且在列名称中都看不到任何一种方式。六个地区-年份组合具有多个行。其中三行是完全重复的,全部在 us_west 中,并且四种组合包含相互冲突的数字:apac 2015 显示为 173.46 和 126.78,us_west 2012 出现四次,具有三个不同的值。没有单独的 us_west 2012 数据可供报告。覆盖范围也参差不齐,从有 15 年历史的亚太地区到只有 1 年历史的拉丁美洲地区。

第三个文件是 olympics_athletes_events,用于此面试问题。

olympics_athletes_events 是每个运动员每次比赛一行 - 这是稍后重要的细节。其 352 排覆盖了 15 届奥运会和 167 个小项的 336 名运动员,因此有 11 名运动员出现多次,其中一名运动员出现 6 次。奖牌栏填满120行,空白表示该运动员在该项目中没有获得奖牌。

错误 1:当我们要求订单到门时衡量送货到门

在shipping_tracking中,我们询问了平均交货时间,这是返回的计算结果:

df['delivery_days'] = (df['delivered_date'] - df['shipped_date']).dt.days

print(f"平均配送:{df['delivery_days'].mean():.1f} 天")

输出

平均交付时间:2.6 天

回复以“平均交货时间:2.6 天”开头。

等待包裹的顾客会体验到送货上门的体验,时钟从结账时开始计时。
order_to_door = (df['delivered_date'] - df['ordered_date']).dt.days

打印(圆形(order_to_door.mean(),2))

6.09

我们提出的问题只有一个答案——6.09 天——而答案给出的数字要小 2.4 倍。这是最难观察的错误类别,因为没有可发现的错误。代码运行后,它是有效的 pandas,并且它计算的内容与它声称的内容完全相同。该错误存在于列的选择中,因此没有测试,没有异常,也没有类型检查会标记它。您可以通过阅读问题,然后阅读计算中的列名称来捕获它,而不是通过其他任何方式。40 22 18

这两个指标都是真实的,它们衡量的是不同的东西:送货上门告诉您仓库的表现如何,订单到门告诉您客户等待的时间。我们问了第二个问题并得到了第一个数字,而人们在会议前阅读的一行摘要没有显示出交换的迹象。

如何捕获错误

阅读问题,然后阅读其下方计算中的列名称。这是唯一在这里起作用的检查,因为代码运行干净,并且没有测试会标记错误的两个日期之间的有效减法。

错误 2:编写代码从未计算过的数字

这个出现在两个不同的文件中。同样的shipping_tracking回复以一个警告结束,看起来像是良好的做法:

注意:50 个订单中只有 22 个有交货日期(28 个仍在运输/待处理)。

文件有 40 行。
print(len(df), df['delivered_date'].notna().sum(), df['delivered_date'].isna().sum())

22 是正确的。 50 和 28 不知从何而来:该会话中没有代码计算或打印任何数字。

这句话之所以危险,是因为 50 减 22 等于 28,所以它内部一致,外部错误。读者在脑子里算一算,发现没有什么问题。

Regional_sales 运行以同样的方式失败,并造成更多损坏。当被问及哪个地区表现最好时,该公司报告亚太地区“总销售额为 368 万美元(占所有地区收入的 32%)”,并以“数据很明确”作为结束语。

print(round(df.groupby('region_name')['sales'].sum()['apac'], 2))
3675.49

无论文件使用什么单位,总数均为 3675.49,亚太地区的份额为 30.4%。该回复将数值夸大了大约一千倍,在不带单位的列上附加了货币符号,并对从未计算过的份额进行了四舍五入。阅读会话日志解释了如何:该运行根本不执行任何代码。它打印了一个 pandas 片段并在其下面写了数字。

运行代码也不足以提供足够的保护。一次不紧不慢的 Luna 模型运行确实执行了查询,并且仍然写道,亚太地区“比美国西部和美国东部的总和高出 60% 以上”,这两个地区的总和为 3575.70,而亚太地区为 3675.49,差距为 2.8%。

同一段中的其他比较,领先 europe_north 32%,正确率为 32.2%。一个数字被测量出来,一个数字被发明出来,一并出现在一句话中。

这就是摘要要坚持的一点。计算代码块内的数字;其周围段落中的数字已写出。没有什么可以迫使两人达成一致。

询问代码是否实际运行,并检查散文中的每个数字是否出现在输出中的某个位置,因为我们的两次运行提供了它们从未执行过的代码。在我们的示例中,在接受任何排名之前检查粒度:三个重复的行使 us_west 膨胀了 30.3%,并且这些区域具有 1 到 15 年的历史,因此除以数据年数后,us_west 将排在第一位,为 290.9,而亚太地区为 245.0,并反转了标题。

错误3:从未到达的订单中解读趋势

回到shipment_tracking,我们询问运输是变得更快还是更慢。快速传递说更快,并引用第一周为 3.2 天,而第三周为 1.0 天。

两个数字都是实数。结论是倒退的。

df['week'] = df['ordered_date'].dt.isocalendar().week

打印(df.groupby('周').agg(订单=('order_id', '尺寸'),已交付=('已交付日期', '计数'),avg_days=('delivery_days', 'mean')).round(2))错误 4:不说就丢下 226 个空白高度

该文件于 1 月 21 日结束。第 3 周的订单大约需要 3 天才能完成;第 1 周的订单有 17 个。在第 3 周的 10 个订单中,有 7 个没有交货日期。唯一有交货时间的第三周订单是那些碰巧速度很快的订单,因为速度慢的订单还没有到达进行测量。

接下来的几周看起来更快,因为更多的证据丢失了。平均值从 3.17 下降到 1.00,而未解决的订单从 20% 上升到 70%。

鉴于相同的文件且没有时间压力,Luna 模型自动捕获了这一点,并打开警告,指出改进是一种幻觉。相同的陷阱,相同的数据,相反的结果。

在聚合为您删除空白之前,先询问空白的含义。缺席的交货日期属于最新且最慢的订单,因此放弃它们会带来加速。值得注意的是,在这三周内,未解决的订单从 20% 攀升至 70%。

在 olympics_athletes_events 上,我们询问身高是否有助于运动员赢得奖牌。快传对比了两组,就停在那里了。

奖牌获得者 = df[df['medal'].notna()]['height']
其他 = df[df['奖牌'].isna()]['身高']

print(round(medalists.mean(), 1), round(others.mean(), 1))

176.5 176.2

其结论是:“身高几乎不重要——奖牌获得者只高出 0.3 厘米,因此身高并不等于获胜能力更强。”

算术是正确的,结论不成立。该比较针对文件 352 行中的 126 行进行,因为其他 226 行的高度为空白,并且 pandas 没有说明就删除了其中的每一行。一列的平均值忽略了它的空单元格,因此问题和答案之间的样本悄悄缩小了 64%,而回复却从未提及它。
第二个问题是这些空白到底是什么。

print(round(df[df['height'].notna()]['medal'].notna().mean() * 100, 1))

print(round(df[df['身高'].isna()]['奖章'].notna().mean() * 100, 1))

54.0

23.0

有记录身高的运动员赢得奖牌的几率为 54%,没有记录身高的运动员赢得奖牌的几率为 23%。对这种关系进行卡方检验会返回 p = 9e-09,这意味着该值是否存在对结果的预测效果远好于该值本身。

原因在于岁月。 2016年之前的302个项目中,只有76个项目有身高,奖牌率为26.5%。 2016年起,所有50个项目都有高度,奖牌率为80%。在这个文件中,有记录的身高、最近的成绩和赢得奖牌接近于同一事实,因此模型测试的 126 排很大程度上倾向于几乎每个人都获得奖牌的那一年。

对于“身高有帮助吗”的有用答案是,该文件无法支持身高,利益相关者听到这一点比听到 0.3 厘米的差异更好。每次运行我们都会去掉空白并分析剩下的内容。

检查有多少行在计算中幸存下来,因为此比较运行在 352 行中的 126 行上,并且从未这么说过。然后询问空白是否是随机的:这些大多属于最早的奥运会,NULL 在一栏中表示“尚未交付”,在另一栏中表示“没有赢得奖牌”。当我们要求它检查自己的工作时发生了什么对于每个第一遍答案,我们打开一个干净的会话,完整粘贴该答案,附加相同的文件和沙箱,并要求它验证执行甲板的每个数字。在针对shipment_tracking的回答中,评论报告了“注意部分有一个错误”。它将 50 修正为 40,将 28 修正为 18,这是正确的修正。它运行代码来执行此操作,并正确计算了 18 个未交付的订单。然后它写道:所有三个主要指标都是正确的:

  • 第一季度:2.6 天
  • 第二季度:45.5%
  • Q3:变得更快(3.2 至 1.0 天)
  • 第二季度——针对 5 天目标的准时率——确实是正确的。

    Q1 是错误 1,Q3 是错误 3。因此,审核批准了回答不同问题的交货时间,并批准了由刚刚完成计数的 18 个未交货订单创建的趋势。它有一个数字可以解释屏幕上的幻觉,但从未将其与下面两行的声明联系起来。

    除了这两个数字之外,其更正后的回复与原始回复相同。它修复了错误 2 中捏造的数字,保留了错误 1 ​​和 3,并且答案带有验证印章。

    对 olympics_athletes_events 的审查进一步朝着错误的方向发展。它一开始就发现了一个单独的错误——当问题涉及运动员时,正确地发现奖牌份额是按记录计算的,这是数据部分的颗粒问题——并将该数字修正为 35.4%。

    然后从错误4开始进行高度比较。它没有提到226个空白高度,这是该答案的缺陷。相反,它报告说,奖牌获得者的真实身高是 176.4 厘米,非奖牌获得者的真实身高是 175.5 厘米,将原来的 176.2 标记为“重大”误差 0.7 厘米,并重写结论说“身高确实与赢得奖牌有关”。

    此文件没有一致的分组会产生 175.5。 176.4 的数字大致是删除重复行后的奖牌获得者平均值,因此该审查将两个不兼容的分组合并为一个比较,并产生了任何单一分析都无法得出的差异。然后,它利用这一差异来推翻判决——从 126 个可用行确实支持的“高度几乎不重要”,转变为这些相同行在 p = 0.87 时拒绝的相关性主张。该会话也没有执行任何代码。

    将这四个错误与审查的处理结果进行对比。它修正了错误2中捏造的数字。它批准了错误1和3,但没有发表评论。在错误 4 中,它完全错过了缺陷,发明了一种替代品,并使得答案比它正在审查的答案更糟糕。每一项判决都以同样自信的语气做出,措辞中没有任何内容区分正确与错误。

    结论

    机械工作自始至终都很强。该模型解析了日期,编写了有效的 SQL 和 pandas,并在不慌不忙的运行中生成了比许多分析师所写的更清晰的分析 - 包括错误 3 中的审查诊断。

    这四个错误有一个共同点。他们每个人都打开了屏幕上没有的东西:错误 1 ​​中位于度量后面的问题、错误 2 中从未运行的代码、错误 3 中尚未到达的订单以及错误 4 中没有人记录的 226 个高度。模型读取给定的文件,在所有四种情况下,正确答案都取决于文件遗漏的内容。知道号码的用途仍然是你无法交出的部分。

    运行第二遍算术。然后自己完成这四项检查,因为审查会告诉您无论哪种方式数字都是正确的。

    Nate Rosidi 是一名数据科学家,负责产品战略。他还是教授分析学的兼职教授,并且是 StrataScratch 的创始人,该平台帮助数据科学家利用顶级公司的真实面试问题准备面试。 Nate 撰写有关职业市场最新趋势的文章、提供面试建议、分享数据科学项目,并涵盖 SQL 的所有内容。