TowardsDataScience-2023-博客中文翻译-四十九-

TowardsDataScience 2023 博客中文翻译(四十九)

原文:TowardsDataScience

协议:CC BY-NC-SA 4.0

使用 Matplotlib 可视化数据范围

原文:towardsdatascience.com/visualize-data-ranges-with-matplotlib-df815363a619

基准测试 NOAA 的飓风展望

李·沃恩数据科学进阶 李·沃恩

·发表于数据科学进阶 ·阅读时间 10 分钟·2023 年 9 月 26 日

--

莱昂纳多 AI DreamShaper_v7 模型的太空飓风

绘制离散数据很简单;表示范围数据则更复杂。幸运的是,Python 的 matplotlib 库提供了一个内置函数fill_between(),可以轻松可视化数据范围。在这个快速成功的数据科学项目中,我们将利用它来基准测试国家海洋和大气管理局的年度飓风展望。

数据集

每年 5 月,NOAA 发布其“大西洋飓风展望”报告,涵盖 6 月至 11 月的飓风季节。这些展望包括对命名风暴、飓风和主要飓风(定义为三级及以上)的预测范围。你可以在这里找到 2021 年的示例报告[1]。NOAA/国家气象局的数据由美国政府提供,作为开放数据,可以自由使用。

为了基准测试这些预测的准确性,我们将使用维基百科提供的年度飓风季节总结。这些总结提供了每年的实际风暴和飓风数量。你可以在这里找到 2021 季节的条目[2]。维基百科页面在CC BY-SA 4.0许可下提供。

维基百科还包括拉尼娜厄尔尼诺事件的列表[3][4]。这些代表了每隔几年在太平洋发生的天气模式。在拉尼娜年,东太平洋的水温低于正常水平,导致其上方的空气变冷。厄尔尼诺年则相反。

拉尼娜现象有利于大西洋盆地飓风活动的增强,而厄尔尼诺则抑制飓风发展 [5]。为此,我们还将对这些事件进行颜色编码。

为了方便,我已经将 2001–2022 年的所有信息汇总并存储为 CSV 文件,保存在这个Gist中。

NOAA 每年八月都会发布更新的飓风预测,因此在选择数据和引用预测时需要小心。我们将使用五月的预测。

安装库

我们将使用 pandas 进行数据处理,使用 matplotlib 进行绘图。可以通过以下任一方式进行安装:

conda install matplotlib pandas

pip install matplotlib pandas

代码

以下代码在 JupyterLab 中编写,并按单元描述。

导入模块

除了进行数据分析和绘图,我们还将制作一个自定义标记来表示飓风。为此,我们需要导入 NumPy(Python 的数值分析包)和一个用于处理折线的 matplotlib 模块,称为mpath

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.path as mpath
import pandas as pd

加载数据集

CSV 文件包含了预测飓风(H)和主要飓风(MH)的低值和高值。它还包括实际的飓风和主要飓风数量,以及是否属于拉尼娜或厄尔尼诺事件。过渡年被标记为“弱事件”。

df = pd.read_csv('https://bit.ly/44YgahT')
df.head(3)

定义绘制飓风标记的函数

虽然我们可以使用一个简单的圆圈来在散点图上标记实际的飓风数量,但经典的飓风图标岂不是看起来更好?

不幸的是,matplotlib 没有自带飓风标记。然而,在 Stack Overflow 上提供了绘制飓风标记的代码,我在下面重复了这段代码(Stack Overflow 内容是cc-wiki 许可的) [6]。

这个函数使用了 matplotlib 的mpath模块,该模块返回一个[<class 'matplotlib.path.Path'>](https://matplotlib.org/stable/api/path_api.html)对象,表示一系列的线段和曲线段。该代码如何工作对于这个项目并不重要,但如果你想看到详细的解释,可以访问代码片段开始处的 Stack Overflow 链接。

# The following code was adapted from Stack Overflow:
# https://stackoverflow.com/questions/44726675/custom-markers-using-python-matplotlib
# Asked by: https://stackoverflow.com/users/5689281/kushal
# Answered by: https://stackoverflow.com/users/4124317/importanceofbeingernest

def get_hurricane_symbol():
    """Return a hurricane warning symbol as a matplotlib path."""
    # Create a numpy array for the symbol's coordinates and codes:
    coordinates = np.array([[2.444, 7.553],
                            [0.513, 7.046],
                            [-1.243, 5.433],
                            [-2.353, 2.975],
                            [-2.578, 0.092],
                            [-2.075, -1.795],
                            [-0.336, -2.870],
                            [2.609, -2.016]])

    # Shift the x-coordinates:
    coordinates[:, 0] -= 0.098

    # Define path codes:
    codes = [1] + [2] * (len(coordinates) - 2) + [2]

    # Duplicate and reverse the coordinates:
    coordinates = np.append(coordinates, -coordinates[::-1], axis=0)

    # Duplicate the codes:
    codes += codes

    # Create and return the matplotlib path:
    return mpath.Path(3 * coordinates, codes, closed=False)

绘制实际飓风与预测飓风

以下代码使用 matplotlib 的[fill_between()](https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.fill_between.html)方法来捕捉 NOAA 对每年的飓风预测数量。它需要 DataFrame 列名作为x参数,y1的最小值和y2的最大值。添加label参数可确保范围阴影会在图例中进行引用。

# Call the function to build the hurricane marker:
symbol = get_hurricane_symbol()

# Initialize the figure:
plt.figure(figsize=(10, 4))

# Plot the actual number of hurricanes per year:
plt.plot(df.Year, df['Actual H'], 
         label='Actual Value', 
         marker=symbol, 
         markersize=17, 
         c='darkblue', 
         linestyle='None', 
         lw=1)

# Shade NOAA's predicted range of hurricanes for each year:
plt.fill_between(x=df.Year, 
                 y1=df['Predicted H Low'], 
                 y2=df['Predicted H High'],
                 alpha=0.3, 
                 label='Predicted Range')

plt.xlabel('Year')
plt.ylabel('Number of Hurricanes')
plt.legend(loc='lower right')
plt.grid(True, c='lightgrey', alpha=0.5)
plt.title('Actual Number of Atlantic Hurricanes vs. \
NOAA May Prediction (2001-2022)');

# Optional code to save the figure:
# plt.savefig('range_plot.png', bbox_inches='tight', dpi=600)

范围图(作者)

这个简单而优雅的图表充满了有用的信息。例如,在过去的 22 年中,实际的飓风数量有11 次落在预测范围内。这与掷硬币的准确性相同。最近,NOAA 开始使用更广泛的范围,这增加了准确性但降低了精确度。

改变填充样式

我非常喜欢之前的预测范围填充样式,但确实还有其他选择。在这个例子中,我们将step参数传递给fill_between()方法。现在,我们得到的是离散的垂直条,而不是连续的多边形。

plt.figure(figsize=(10, 4))
plt.plot(df.Year, df['Actual H'], 
         label='Actual Value', 
         marker=symbol, 
         markersize=17, 
         c='darkblue', 
         linestyle='None', 
         lw=1)
plt.fill_between(x=df.Year, 
                 y1=df['Predicted H Low'], 
                 y2=df['Predicted H High'],
                 step='mid',
                 alpha=0.3, 
                 label='Predicted Range')
plt.xlabel('Year')
plt.ylabel('Number of Hurricanes')
plt.legend(loc='lower right')
plt.grid(True, c='lightgrey', alpha=0.5)
plt.title('Actual Number of Atlantic Hurricanes vs. \
NOAA May Prediction (2001-2022)');

使用“step”参数的范围图(作者)

添加厄尔尼诺和拉尼娜事件

为了评估厄尔尼诺和拉尼娜事件对飓风数量和强度的影响,让我们利用数据框中的“事件”列。

首先,我们需要制作一个将事件映射到颜色的字典。由于拉尼娜代表冷却事件,我们将使用蓝色。厄尔尼诺的暖事件将是红色,而弱事件将是无特征的灰色。

我们将在图形标题下方添加一个单独的自定义图例。注意使用$\u25CF$来绘制圆圈。这是来自实用的STIX 字体集合的一个符号。

# Plot the predicted ranges and color the actual values by event.
# Define a dictionary to map text colors to matplotlib colors:
color_mapping = {'Nina': 'blue', 
                 'Nino': 'red', 
                 'Weak Event': 'grey'}
# Map the Event column to colors. Use black if x not found:
df['colors_mapped'] = df['Event'].apply(lambda x: color_mapping.get(x, 'k'))

plt.figure(figsize=(10, 4))
plt.scatter(df.Year, df['Actual H'], 
            label='Actual Value', 
            marker=symbol, 
            s=300, 
            c=df.colors_mapped, 
            linestyle='None', 
            lw=1)
plt.fill_between(x=df.Year, 
                 y1=df['Predicted H Low'], 
                 y2=df['Predicted H High'], 
                 alpha=0.3, 
                 label='Predicted Range')
plt.xlabel('Year')
plt.ylabel('Number of Hurricanes')
plt.legend(loc='lower right')
plt.grid(True, c='lightgrey', alpha=0.5)

# Add event legend as title:
plt.suptitle('Actual Number of Atlantic Hurricanes vs. NOAA May Prediction (2001-2022)')
plt.figtext(0.4, 0.9, '$\u25CF$ La Nina', fontsize='medium', c='b', ha ='right')
plt.figtext(0.5, 0.9, '$\u25CF$ El Nino', fontsize='medium', c='r', ha ='center')
plt.figtext(0.6, 0.9, '$\u25CF$ Weak Event', fontsize='medium', c='grey', ha ='left');

按天气事件着色的范围图(作者)

这些结果似乎支持了厄尔尼诺事件抑制大西洋飓风形成的理论,至少相对于拉尼娜事件。为了查看它们是否也影响飓风强度,让我们绘制主要飓风数据。

绘制主要飓风

主要飓风定义为 3 级或更高级别的飓风。以下代码更新了这些值的图示。

plt.figure(figsize=(10, 4))
plt.scatter(df.Year, df['Actual MH'], 
            label='Actual Value', 
            marker=symbol, s=300, 
            c=df.colors_mapped, 
            linestyle='None', 
            lw=1)
plt.fill_between(x=df.Year, 
                 y1=df['Predicted MH Low'], 
                 y2=df['Predicted MH High'], 
                 alpha=0.3, 
                 label='Predicted Range')
plt.xlabel('Year')
plt.ylabel('Number of Major Hurricanes (Cat 3+)')
plt.legend(loc='lower right')
plt.grid(True, c='lightgrey', alpha=0.5)

# Add event legend as title:
plt.suptitle('Actual Number of Major Atlantic Hurricanes vs. NOAA May Prediction (2001-2022)')
plt.figtext(0.4, 0.9, '$\u25CF$ La Nina', fontsize='medium', c='b', ha ='right')
plt.figtext(0.5, 0.9, '$\u25CF$ El Nino', fontsize='medium', c='r', ha ='center')
plt.figtext(0.6, 0.9, '$\u25CF$ Weak Event', fontsize='medium', c='grey', ha ='left');

按天气事件颜色编码的主要飓风范围图(作者)

除了 2004 年,某些来源将其归类为弱事件,这张图表支持了在厄尔尼诺事件期间飓风形成被抑制的观点[7]。对于主要飓风,预测准确性也稍好,22 个中有 13 个落在预测范围内。

使用垂直线绘制范围

另一种绘制范围的方法是使用 matplotlib 的vlines()方法来绘制垂直线。这是fill_between()方法的一个有吸引力的替代方案,尽管它更费力且不会自动将范围包含在图例中。

# Redraw plot with vertical lines for ranges:
plt.figure(figsize=(10, 4))

# Use a scatter plot for actual values:
plt.scatter(df.index, df['Actual H'], 
            label='Actual Value', 
            marker=symbol, 
            c='darkblue', 
            s=350)

# Draw vertical lines for the predicted ranges:
for i, row in df.iterrows():
    plt.vlines(x=i, 
               ymin=row['Predicted H Low'], 
               ymax=row['Predicted H High'], 
               alpha=0.4, 
               lw=6, 
               zorder=0)

x = range(len(df))
plt.xticks(x, df.Year, rotation=90)
plt.xlabel('Year')
plt.ylabel('Number of Hurricanes')
plt.legend(loc='lower right')
plt.grid(True, color='lightgray', alpha=0.5)
plt.title('Actual Number of Atlantic Hurricanes vs. NOAA May Prediction');

使用垂直线表示范围的范围图(作者)

评估大西洋多年代际振荡

我们现在已经涵盖了fill_between()方法,但既然我们手头有所有这些数据,不妨花点时间研究一个关于飓风形成的有趣理论,这涉及到大西洋多年代际振荡(AMO)[8]

AMO 是由北大西洋海表温度的几十年变率定义的特征。关于 AMO 知之甚少;它可能代表一个持续的周期性气候驱动因素或只是一个短暂特征[9]。

AMO 指数是通过从全球平均海表温度(SST)异常中减去北大西洋SST 异常来计算的[9]。当 AMO 指数较高时,海表温度通常较温暖,可能会促使飓风活动和强度增加。

由于这是一个长波长现象,我们需要一个从 1920 年左右开始计算飓风的数据库。我已经记录了维基百科在这一时间段的飓风列表,并将其存储在这个Gist中。

应注意,在使用飞机(20 世纪 40 年代中期)和卫星数据(20 世纪 60 年代中期)之前的风暴计数不够可靠。例如,1886 年到 1910 年的计数估算被认为有每年零到四场风暴的低估偏差[10]。

在下一个图中,AMO 指数的边界取自维基百科NOAA [8][11]。

# Load the 1920-2022 hurricane dataset:
df = pd.read_csv('https://bit.ly/3sZnvQX')

# Plot major hurricanes per year with regression line and AMO shading:
plt.figure(figsize=(10, 4))

plt.plot(df.Year, df.MH, 
         label='Actual Value', 
         marker=symbol, 
         markersize=17, 
         c='darkblue', 
         linestyle='None', 
         lw=1)

plt.xlabel('Year')
plt.xticks(range(1920, 2021, 10))
plt.ylabel('Number of Major Hurricanes (Cat 3+)')
plt.grid(True, c='lightgrey', alpha=0.5)
plt.title('Number of Major Atlantic Hurricanes by Year 1920-2022', 
          fontsize=18)

# Add a shaded span for AMO highs:
plt.text(1940, 6.5, 'AMO High', c='firebrick')
plt.axvspan(1926, 1964, 
           color='red', 
           alpha=0.2)

plt.text(2005, 6.5, 'AMO High', c='firebrick')
plt.axvspan(1995, 2022, 
           color='red', 
           alpha=0.2)

# Calculate m (slope) and b (intercept) of linear regression line:
m, b = np.polyfit(df.Year, df.MH, 1)

# Add linear regression line to plot:
plt.plot(df.Year, m*df.Year+b, c='darkblue', ls=':');

每年主要飓风数量,包括回归线和 AMO 指数高期(作者提供)

以下是以柱状图形式呈现的相同数据:

包含 AMO 指数高期的主要飓风柱状图(作者提供)

这是这段时间内所有大西洋飓风的散点图。AMO 效应在风暴频率上的表现不太明显。

每年总飓风数量,包括回归线和 AMO 指数高期(作者提供)

尽管科学家认识到 AMO 指数与主要飓风数量之间的明显关系,但目前的数据还不足以得出确切结论。正如你可能预料的那样,最近 AMO 高期主要飓风增加的最流行解释是人为气候变化。

总结

matplotlib 的fill_between()方法是显示图上范围值的便捷方式。在这个项目中,我们用它来展示 NOAA 的年度飓风预测与实际结果的对比。此外,我们还使用了 matplotlib 的mpath模块绘制自定义标记来表示飓风。最终结果是一个吸引人且易于解析的信息图。

我们还在图中添加了厄尔尼诺、拉尼娜和 AMO 事件。结果支持了既有观察结果,即厄尔尼诺似乎抑制了大西洋飓风,而 AMO 指数高期事件似乎促进了它们。

引用

  1. 气候预测中心互联网团队, 2001, “NOAA 2021 年大西洋飓风季节展望,” 气候预测中心 — 大西洋飓风展望 (noaa.gov)

  2. 维基百科贡献者,“2021 年大西洋飓风季节,” 维基百科,自由百科全书, en.wikipedia.org/w/index.php?title=2021_Atlantic_hurricane_season&oldid=1175731221 (访问日期:2023 年 9 月 19 日).

  3. 维基百科贡献者,“厄尔尼诺,” 维基百科,自由百科全书, en.wikipedia.org/w/index.php?title=El_Ni%C3%B1o&oldid=1174548902 (访问日期:2023 年 9 月 19 日).

  4. 维基百科贡献者,“拉尼娜,” 维基百科,自由百科全书, en.wikipedia.org/w/index.php?title=La_Ni%C3%B1a&oldid=1174382856 (访问日期:2023 年 9 月 19 日).

  5. Bell, Gerry, 2014, “厄尔尼诺和拉尼娜对飓风季节的影响,” NOAA 气候.gov, Impacts of El Niño and La Niña on the hurricane season | NOAA Climate.gov.

  6. ImportanceOfBeingErnest, “使用 matplotlib 的自定义标记,” Stack Overflow, 2017 年 6 月 24 日, Custom markers using Python (matplotlib) — Stack Overflow (访问日期:2023 年 9 月 19 日).

  7. Null, Jan, 2023, “厄尔尼诺和拉尼娜年份及强度,” 金门大桥天气服务, El Niño and La Niña Years and Intensities (ggweather.com) (访问日期:2023 年 9 月 19 日).

  8. 维基百科贡献者,“大西洋多年代际振荡,” 维基百科,自由百科全书, en.wikipedia.org/w/index.php?title=Atlantic_multidecadal_oscillation&oldid=1175329341 (访问日期:2023 年 9 月 19 日).

  9. Knudsen, M., Seidenkrantz, MS., Jacobsen, B. 等, “追踪过去 8,000 年的大西洋多年代际振荡,” 自然通讯 2, 178 (2011). doi.org/10.1038/ncomms1186.

  10. 维基百科贡献者,“大西洋飓风记录列表,” 维基百科,自由百科全书, en.wikipedia.org/w/index.php?title=List_of_Atlantic_hurricane_records&oldid=1168214070 (访问日期:2023 年 9 月 19 日).

  11. NOAA, 2017 年,“大西洋多年代振荡低频气候模式”,大西洋海洋气象实验室墨西哥湾 ESR (noaa.gov).

谢谢!

感谢阅读。我的目标是帮助你提升 Python 技能,并且在过程中享受乐趣。请关注我,未来会有更多快速成功的数据科学项目。

视觉化线性代数以入门机器学习:第一部分

原文:towardsdatascience.com/visualized-linear-algebra-to-get-started-with-machine-learning-part-1-245c2b6487f0

图片由 Michael Dziedzic 提供,来源于 Unsplash

掌握线性代数的基本元素,从简单且直观的基本概念解释开始

Marcello PolitiTowards Data Science Marcello Politi

·发表于 Towards Data Science ·11 分钟阅读·2023 年 2 月 22 日

--

许多人在开始机器学习之旅时遇到的主要困难是理解数学概念。如果你没有扎实的线性代数、统计学、概率论、优化理论等方面的基础,这可能会很困难。 🤔💭🔢✖️🧮

在这篇文章中,我想先提供线性代数基本概念的直观解释,这些概念在深入了解机器学习之前是必不可少的。显然,本文并不打算详尽无遗,关于这一主题还有很多知识,但也许可以作为入门的第一步!

  • 介绍

  • 什么是向量?

  • 简单的向量运算

  • 投影

  • 基础、向量空间与线性独立

  • 矩阵与方程求解

介绍

线性代数为何对数据科学重要?

线性代数 使我们能够解决实际问题,尤其是数据科学中非常常见的问题。

假设我们去市场买了 3 个鳄梨和 4 个西兰花,花了 8 美元。第二天我们买了 11 个鳄梨和 2 个西兰花,花了 12 美元。

现在我们想要找出单个鳄梨和单个西兰花的价格。我们必须同时解答以下表达式。

线性代数问题(图源自作者)

另一个典型问题是找到函数的最佳参数,使其符合我们收集的数据。所以假设我们已经知道需要使用什么类型的函数,但这个函数可以改变其形式,因为它依赖于某些参数。我们想要找到最佳形式和因此最佳参数

数据拟合(图片来源:作者)

比如,我们可以称 µ = param1θ = param2

通常,在机器学习中,我们希望迭代地更新 [µ, θ],最终找到一些适合我们数据的良好曲线。

假设远离最佳绿色曲线的曲线误差很大,而与绿色曲线相似的曲线误差很小。我们通常说我们要找到那些参数 [µ, θ],以最小化误差,所以找到与绿色曲线尽可能接近的曲线。

让我们看看线性代数如何帮助我们解决这些问题!

什么是向量?

物理学中的向量是一个数学实体,具有方向、符号和大小。因此,它通常用箭头来直观表示。

向量(图片来源:作者)

计算机科学中,向量的概念被推广。事实上,你会多次听到用列表代替向量的术语。在这种观念中,向量不过是一个属性列表,我们可以用来表示任何事物。

假设我们想根据 3 个属性来表示房子:

1. 房间数量

2. 浴室数量

3. 平方米

列表(图片来源:作者)

例如,在上图中我们有两个向量。第一个表示一个有 4 间卧室、2 间浴室和 85 平方米的房子。第二个则表示一个有 3 个房间、1 间浴室和 60 平方米的房子。

当然,如果我们对房子的其他属性感兴趣,我们可以创建一个更长的向量。在这种情况下,我们会说这个向量将有 n 维在机器学习中,我们通常会有数百或数千维

简单向量运算

我们可以对向量进行的操作,其中最简单的无疑是两个向量之间的加法,以及向量与标量即一个简单的数字)的乘法。

添加两个向量你可以使用平行四边形法则。也就是说,你画出与要添加的向量平行的向量,然后画对角线。对角线将是加法的结果向量。相信我,通过直接查看下面的例子,你会更容易理解。

向量加法(图片来源:作者)

同时,标量乘法将向量拉伸 n 单位。见下例。

向量-标量乘法(作者提供的图片)

模与内积

一个向量实际上总是用其他向量表示。例如,让我们以参考向量 i 和 j 为例,它们的长度都为 1,并且相互正交

单位长度向量(作者提供的图片)

现在我们定义一个新的向量 r它从原点开始,也就是 ij 相交的点,并且它的长度是 ia 倍,jb 倍。

空间中的向量(作者提供的图片)

更常见的是,我们用坐标表示一个向量 r = [a,b],这样我们可以在向量空间中识别各种向量。

现在我们准备定义一个新的操作,即向量的模也就是它的长度可以通过其坐标推导出来,定义如下。

向量模(作者提供的图片)

内积则是另一种操作,给定两个向量,它将所有组件相乘并返回其和。

内积(点积)(作者提供的图片)

内积有一些在某些情况下可能有用的属性:

  • 对称性:rs = sr

  • 对加法具有分配性:r(st) = rs + rt

  • 对标量乘法具有结合性:r(as) = a(rs),其中 a 是标量

请注意,如果你计算一个向量与自身的内积,你将得到其模的平方!

内积(点积)(作者提供的图片)

余弦(点积)乘积

到目前为止,我们只看到了基于向量坐标的内积数学定义。现在,让我们查看它的几何解释。让我们创建三个向量 rs 及其差 r-s,从而形成一个具有三条边 abc 的三角形。

三角形(作者提供的图片)

我们从高中时期知道,我们可以使用简单的三角函数规则来推导 c

三角函数(作者提供的图片)

但我们可以从上述推导出:

(作者提供的图片)

因此,夹角对这个操作的结果有很大的影响。实际上,在一些特殊情况下,当夹角为 0°、90° 和 180° 时,余弦值分别为 0、1 和 -1。因此,这个操作会有特别的效果。例如,两个相互垂直的向量的点积总是等于 0

投影

让我们考虑两个向量 rs。这两个向量从一侧接近,并在它们之间形成一个夹角 θ让我们把一只手电筒放在 s 上面,我们会看到 sr 上的投影这就是 sr 上的投影

投影(作者提供的图片)

有 2 种基本投影操作:

  • 标量投影:给出投影的大小

  • 向量投影:给出投影向量本身

投影(作者提供的图片)

改变基

线性代数中的基变换指的是将向量表示为不同坐标系中的过程这些坐标系称为基基是一组线性无关的向量,可以用来表示向量空间中的任何向量当一个向量在不同的基上表示时,其坐标会发生变化

我们已经看到,例如,在二维空间中,每个向量可以表示为两个基向量 [0,1] 和 [1,0] 的和。这两个向量是我们空间的基。但我们是否可以使用其他两个向量作为基,而不仅仅是这两个?当然可以,但在这种情况下我们空间中每个向量的坐标都会发生变化。让我们看看如何变化。

新基(作者提供的图片)

在上面的图像中,我有两个基。基 (e1, e2),和基 (b1, b2)。此外,我还有一个向量 r(红色)。这个向量在 (e1, e2) 这个基中坐标为 [3,4],这是我们默认使用的基。但是当用 (b1, b2) 表达时,它的坐标会变成什么呢?

要找到这些坐标,我们需要分步骤进行。首先,我们需要找到向量 r 在新基 (b1, b2) 上的投影。

改变基(作者提供的图片)

很容易看出,我们创建的这些投影的总和正好是 r。

r = p1 + p2。

此外,为了改变基,我必须检查新基是否也是正交的,即这些向量彼此成 90 度,这样它们才能定义整个空间。

要检查这一点,只需查看角度的余弦是否为 0,即角度为 90 度。

检查正交归一基(作者提供的图片)

现在我们继续计算 r 在向量 (b1, b2) 上的投影,使用我们在上一章看到的公式。

向量投影(作者提供的图片)

向量投影中用红色圈出的值将给出新向量 r 在基 b : (b1, b2) 中的坐标,而不是在 e : (e1, e2) 中的坐标。

新基 b 中的向量 r(作者提供的图片)

要检查计算是否正确,我们需要检查投影的总和是否在基 e : (e1, e2) 中正好是 r。

[4,2] + [-1,2] = [3,4]

基、向量空间和线性无关

我们已经看过并讨论了基。但让我们更精确地定义向量空间中的向量基是什么。

基是一组 n 个向量,其满足:

  • 彼此不是线性组合(线性无关)

  • 张成空间:空间是 n 维的

第一点意味着,如果例如我有 3 个向量a, b, c形成一个基,那么就没有办法将这些向量相加并通过标量相乘得到零!

如果我用x yz表示任意三个标量(两个数字),这意味着:

xa + yb + zc != 0

(明显地排除平凡情况 x = y = z = 0)。在这种情况下,我们将说这些向量是线性无关的。

这意味着,例如不能通过标量相乘和将ab相加得到c。这意味着如果ab位于二维空间中,则c则位于第三维度中

而第二点意味着我可以将这些向量乘以标量并将它们相加,从而在三维空间中得到任何可能的向量。所以这 3 个基向量足以让我定义整个维度为 n=3 的空间

矩阵和求解线性方程组

到现在你应该很擅长处理向量并进行运算了。但是它们在现实生活中有什么用呢?我们在开始时看到,我们的目标之一是同时解多个方程,例如,确定超市里蔬菜的价格。

线性方程组(图像由作者提供)

但现在我们知道了向量后,可以以更简单的方式重写这些方程。我们将系数向量[2,10]和[3,1]并排放置形成一个矩阵(向量集)。然后我们将得到未知向量[a, b],最后是结果[8,3]。

向量化形式(图像由作者提供)

现在你可能会问这种新的问题书写形式是否真的更好。如何在矩阵和向量之间进行乘法? 非常简单。只需将矩阵的每一行与向量相乘。如果我们有两个矩阵之间的乘法,我们将不得不将第一个矩阵的每一行与第二个矩阵的每一列相乘。

所以通过对行和列应用这个规则,我们应该能恢复原始形状。

矩阵乘法(图像由作者提供)

这种形式还有其他优点。它给我们提供了发生情况的几何解释。每个矩阵定义了一个空间中的变换。所以如果我在空间中有一个点并应用一个矩阵,我的点将以某种方式移动。

矩阵变换(图像由作者提供)

但我们也可以说矩阵不过是一个函数,它接受一个点作为输入并生成一个新的点作为输出

所以我们的初始问题可以解释为,“在什么情况下,原始向量[a, b]的变换结果是[8, 3]?”

这样,你可以把解决联立方程看作是对向量空间中的向量进行变换。此外,矩阵操作具有以下一些非常有用的特性。

给定 A(r) = r2 其中 A 是一个矩阵,r 和 r2 都是标量:

  • A(nr) = ns 其中 n 是一个标量

  • A(r+s) = A(r) + A(s) 其中 s 是一个向量

矩阵和空间变换

要理解矩阵的效果,我们可以查看它们如何变换施加在其上的向量。特别是,我们可能会看到矩阵在特征基上的影响。

如果我们有一个 2x2 矩阵,并且我们处于二维空间中,那么矩阵的第一列将告诉我们对向量 e1 = [1,0] 的效果,而第二列则会告诉我们对向量 e1 = [0,2] 的效果。

然后我们看看一些已知矩阵的效果。这些变换在机器学习中经常用于数据增强,例如,你可以拉伸或缩小这些图像。

矩阵变换(图片由作者提供)

我们还可以对一个向量应用多个连续的变换。所以,如果我们有两个由矩阵 A1 和 A2 表示的变换,我们可以将它们连续应用 A2(A1(vector))。

但这与反向应用它们不同,即 A1(A2(vector))。这就是为什么 矩阵之间的乘积不具备交换律。

最终思考

在我关于线性代数的文章的第一部分中,你应该已经理解了为什么这个主题对机器学习如此重要,也许你已经快速而直观地学习了基本概念。

你知道什么是向量和矩阵,如何在向量空间中表示这些实体以及如何对这些元素进行操作。继续关注,以免错过这篇文章的后续内容! 😊

结束

马尔切洛·波利提

LinkedinTwitter简历

通过可视化线性代数入门机器学习:第二部分

原文:towardsdatascience.com/visualized-linear-algebra-to-get-started-with-machine-learning-part-2-2ef075edb28b

图片来源:Michael DziedzicUnsplash

掌握线性代数的基本元素,从简单和直观的基本概念讲解开始

Marcello PolitiTowards Data Science Marcello Politi

·发表于Towards Data Science ·阅读时间 7 分钟·2023 年 2 月 28 日

--

介绍

在这篇文章中,我们继续在通过可视化线性代数入门机器学习:第一部分中开始的工作。我们以简单直观的方式探讨线性代数的新概念。这些文章旨在向你介绍线性代数的世界,并让你理解学习这一学科及其他数学学科与数据科学的紧密关系。

索引

  • 解方程

  • 行列式

  • 高级换基

  • 特征值和特征向量

  • 计算特征值和特征向量

解方程

最后,让我们尝试理解如何同时解决方程。到现在你应该已经熟悉了如何使用矩阵和向量紧凑地写出方程,如本例所示。

方程(图像由作者提供)

寻找未知向量 r = [a,b]非常直接;我们只需将方程的左右两侧分别乘以矩阵 A 的逆矩阵

解方程(图像由作者提供)

我们看到A^-1 和 A 相互抵消因为矩阵与其逆矩阵的乘积总是得到单位矩阵(即主对角线上的所有元素都是 1,其余位置为零的矩阵)。因此,我们找到了 r 的值。

但为了做到这一点,我们必须计算 A^-1,这可能并不简单。通常编程语言中已经实现了非常高效的算法来计算逆矩阵,所以你将始终需要使用这些算法。但如果你想学习如何手动进行这个计算,你将需要使用高斯消元法

这就是如何使用 numpy 在 Python 中计算逆矩阵的示例

import numpy as np

A = np.array([[6, 1, 1],
   [4, -2, 5],
   [2, 8, 7]])

# Calculating the inverse of the matrix
print(np.linalg.inv(A))

行列式

行列式是线性代数中的另一个基本概念。它通常在大学中教授如何计算,但不一定解释它的含义。我们可以将一个值与每个矩阵关联,这个值正是行列式。然而,你可以将行列式视为变形空间的面积。

我们已经看到每个矩阵实际上都是空间的变形。让我们举个例子。

行列式(图源作者)

如果我们计算新空间的面积,如图所示,这个面积正是与起始矩阵相关的行列式。在这种情况下,行列式 = a*d。

当然,我们有能够描述较复杂空间变形的矩阵,在这种情况下,计算面积即行列式可能并不那么简单。

为此,有已知的公式用于计算行列式。例如,我们来看一下计算 2x2 矩阵的行列式的公式。

计算 2x2 矩阵的行列式(图源作者)

你可以查看这里了解如何在更大的矩阵的一般情况下计算行列式。

然而,有些变换不会产生任何面积。让我们看一个例子。

行列式等于零(图源作者)

在这个例子中,矩阵不允许我们创建任何面积,所以行列式等于零

那么了解行列式有什么用呢?我们已经看到了解决联立方程时需要能够计算矩阵的逆。

但是如果行列式等于零,矩阵的逆不存在!这就是为什么了解如何计算行列式非常重要,以便知道是否存在问题的解决方案。

你可以将逆矩阵视为将空间转换回原始空间的一种方法。但当一个矩阵造成的不是一个面积,而只是一个线段,然后使我们从二维空间变到一维空间时,逆矩阵没有足够的信息,永远无法使我们从一维空间回到二维的原始空间。

高级基变换

我们已经在之前的文章中看到了基本的基变换示例,但现在让我们看一个稍微复杂一点的例子。

让我们想象存在两个世界我们的世界和纳尼亚的世界。在我们的世界中,我们使用向量 e1 和 e2 作为我们的参考向量,即基向量。感谢这些向量,我们能够创建其他向量并给它们指定坐标。例如,我们可以创建向量[1,1]和[3,1]。

我们的世界(图像作者提供)

然而,在纳尼亚的世界中,他们使用不同的向量作为基。你能猜到他们使用的是哪些吗?就是我们称为[1,1]和[3,1]的那些。

纳尼亚的世界(图像作者提供)

纳尼亚的人们将使用他们的这个基来定义空间中的其他向量,例如,他们可能会定义向量[3/2, 1/2]。

纳尼亚世界中的向量(图像作者提供)

好的,现在我想要找出的就是:如何根据我的世界中的坐标定义那个红色向量

我们已经看到这一点,我们取纳尼亚基的向量,但用我们世界中的坐标表示,即[1,1]和[3,1]。我们将它们放入一个矩阵中,并将这个矩阵与红色向量相乘。

改变基(图像作者提供)

现在我们问:我们也能反向操作吗?我能根据纳尼亚使用的坐标来表达我们世界中的一个向量吗?当然可以!

只需做相同的过程,但改变视角。但我们为什么要这么做?当我们需要描述向量或变换时,如果使用不同的基,通常会有更简单的表示方法

假设我们想对一个向量应用 R 变换。但是这个变换难以应用。那么我们可以先通过应用矩阵 N 将我的向量转换成纳尼亚世界中的向量。然后应用所需的变换 R。最后,用 N^-1 将一切带回到我们原来的世界。

这在处理复杂变换时可以非常有用,使生活变得更简单。我希望我至少给你提供了一些见解;还有很多内容可以讨论。

特征值和特征向量

我们已经多次提到对向量应用线性变换(一个矩阵)会改变那个向量

然而,在某些情况下,向量保持在相同的初始方向上。比如说,如果我们只是缩放空间。如果我们可视化水平和垂直向量,它们虽然变长或变短,但仍保持在相同的方向上

缩放空间(图像作者提供)

从上面的图像中我们可以看到,这里的线性变换是缩放变换。但是如果我们试图理解每个单独向量发生了什么,我们会发现红色向量仍然保持相同的方向。

这些保持相同方向的向量被称为描述该变换的矩阵的特征向量。

具体来说,垂直的红色向量保持不变,所以我们可以说它的特征值是 =1,而另一个红色向量则翻倍了,所以我们可以说它的特征值是 =2。

显然,根据矩阵的不同,因此变换的不同,特征向量的数量可能会有所不同。

计算特征值和特征向量

现在让我们尝试将我们用文字表达的内容转换为数学公式。所以特征向量是指当矩阵作用于它们时,它们不发生变化,最多只是变长或变短。

计算特征向量(图片来源:作者)

在公式中,A 是一个矩阵,x 是一个向量,lambda 是一个标量。如果条件满足,我们称 x 是 A 的特征向量,对应的特征值为 lambda。

通过解前面的方程,我们可以找到解决该方程的特征值,来看一下如何做。

特征多项式(图片来源:作者)

一旦找到了特征值,只需将它们代入以下方程即可找到特征向量。

查找特征向量(图片来源:作者)

最终想法

我希望你在这篇文章中找到了一些有用的见解,并且能够毫费力气地理解它们。目的是让你对这些术语和线性代数元素有一点了解。这样,我希望下次你查看 sklearn 或其他库的文档时,能够更好地理解你使用的特定函数实际上在做什么! 😊

结束

Marcello Politi

Linkedin, Twitter, CV

使用 Google Trends 可视化 AI 和技术炒作

原文:towardsdatascience.com/visualizing-ai-and-tech-hype-using-google-trends-chatgpt-bc1c5113b701

可视化教程

一份关于如何创建斜坡图可视化以评估技术趋势变化(如虚拟现实和生成性 AI)的教程。

Christabelle PabalanTowards Data Science Christabelle Pabalan

· 发表在 Towards Data Science · 9 分钟阅读 · 2023 年 12 月 19 日

--

2021 年末,马克·扎克伯格向我们展示了‘元宇宙’ — 一个可以通过虚拟现实头显访问的数字宇宙,旨在在逼真的虚拟环境中创造一种真实的存在感。因此,在 2022 年,我们目睹了对虚拟现实的兴趣复苏,既激发了兴奋,也引发了存在主义的恐惧。

图片由Minh Pham拍摄,来自Unsplash

虽然元宇宙在 2022 年引发了兴趣,但它并不是唯一的变革力量;生成性 AI 的爆炸性发展迅速改变了集体关注点。

元宇宙与生成性 AI:展望人机交互的未来 中,Ian Hughes 和 Sudeep Kesh 解释道,

“2022 年和 2023 年在某些人工智能分支中尤为多事。尽管人工智能和机器学习的许多方面[…]到目前为止一直未引起广泛关注,但普通网民突然能够通过 OpenAI 的 ChatGPT 和 Google 的 Bard 等界面与大型语言模型(LLMs)进行互动。[…]这一发展伴随着生成式 AI 在图像领域的崛起,DALL-E 和 Midjourney 等引领了潮流。[…] 一些搜索引擎已开始实现这一技术。[…] 像元宇宙一样,生成式 AI 有潜力影响我们与数字内容及彼此的每一次互动。”

过去几年证明了科技领域变化的速度和趋势的变革。面对不断的讨论,我们自然会对趋势波动产生直观感受。然而,这种不断增长的直觉常常引发对这些变化更客观、定量理解的需求。

幸运的是,我们可以访问数据和软件,这些工具允许我们量化和可视化对热门话题的兴趣升降。在本文中,我想介绍两个工具,这些工具结合使用可以帮助我们通过网络搜索捕捉公众兴趣:Google Trends 和斜率图。

Google Trends 主页。作者截图。

Google Trends 是一个突出显示人们好奇和搜索内容的工具。它通常用于市场研究和内容规划,因为它使用户能够快速查看公众兴趣和在线搜索行为的变化。

Google Trends Cybertruck 示例。作者截图。

在上面的截图中,你可以看到 Google Trends 提供了一个“Interest Over Time”(兴趣随时间变化)得分,代表特定术语在指定时间段和区域内的相对受欢迎程度或搜索兴趣。得分经过标准化和缩放,其中 100 代表该术语的最高受欢迎程度。

这意味着该指标提供的是相对数据,而非绝对搜索量。得分相对于时间序列中的最高点,而实际的搜索量或该术语的搜索次数并未披露。此外,Google Trends 允许你在同一图表中比较多个术语的搜索兴趣,使你更容易看到它们的受欢迎程度如何随时间变化。

斜率图是什么?

斜率图是一种有效的可视化工具,用于比较两个时间点之间类别排名的变化。它不仅展示了每个时期类别之间的排名情况,还展示了这两个时期之间这些排名如何变化。

作者截图

初始排名 — 坡度图左侧每个点的垂直位置表示该类别在第一个周期的初始排名。

最终排名 — 同一数据点在右侧的垂直位置表示该类别在第二个周期的最终排名。

线条 — 连接这些点的线条显示排名的变化。线条的坡度表示类别或项目的排名是上升还是下降,坡度的陡峭程度反映了变化的程度。

通过检查线条的坡度和方向,我们可以快速识别出排名发生变化的类别或项目,以及变化的方向(例如,提升或下降)。这使得坡度图在传达类别或项目相对位置如何演变方面非常有价值。

使用颜色来突出显著的变化

此外,你可以使用颜色来突出特定的坡度,从而强调特定的变化或趋势。例如,你可以使用醒目的颜色(例如紫色)来突出排名显著提升的类别。

作者截图

最后,进入教程…

AI / 技术趋势应用

首先,你需要点击+ Compare按钮,添加所有你感兴趣的比较项。

作者截图

在下方截图中,我添加了以下术语:生成性 AI、虚拟现实、AI 伦理、计算机视觉和 NLP。

作者截图

接下来,选择你感兴趣的时间范围进行分析。

最后,使用蓝色高亮的下载图标导出数据。

作者截图

数据预处理以供可视化

1. 加载数据

df = pd.read_csv('data.csv', skiprows=1)

作者截图

2. 预处理数据

# Rename columns
df.columns = ['week',
              'generative_ai',
              'virtual_reality',
              'ai_ethics',
              'computer_vision',
              'nlp']

# Replace `<1` values with `1`
df = df.replace('<1', 1)

# Set index to the week
df = df.set_index('week')

# Change all data types to 'int'
df = df.astype(int)

# Extract Month and Year Columns
df['month'] = df.index.astype('datetime64[ns]').month
df['year'] = df.index.astype('datetime64[ns]').year.astype(str)

# Filter to use only data in the last 4 months of the year
df_end_year = df[df['month'].isin([9, 10, 11, 12])]

# Group by year and take the average interest score
df_average_interest = df_end_year.groupby('year').mean().round(1)

# Drop the month column
df_average_interest = df_average_interest.drop(columns='month')

作者截图

# Change all values into integers and tranpose the dataframe
df_combined = df_average_interest.astype(int).T.reset_index()

# Rename the 'index' column to 'category'
df_combined = df_combined.rename(columns={'index': 'category'})

# Filter dataframe to only the years of interest
year1 = '2022'
year2 = '2023'
df_final = df_combined[['category', year1, year2]].copy()

def percent_change(new, old):
    return (100 * ((new - old)/old)).astype(int)

# Calculate the interest change between the two years and the % change
df_final['change'] = df_final[year2] - df_final[year1]
df_final['percent_change'] = percent_change(df_final[year2], df_final[year1])

# Sort the DataFrame by the absolute change for better visualization
df_final = df_final.sort_values(by='change', ascending=False)

作者截图

3. 创建坡度图

# Create a dictionary to map categories to colors
dict_colors = {
    'generative_ai': 'seagreen',
    'ai_ethics': 'grey',
    'computer_vision': 'grey',
    'nlp': 'grey',
    'virtual_reality': 'purple'
}

# Set the figure size
plt.figure(figsize=(5, 7))

# Create a slopegraph by plotting lines between 2022 and 2023 values
for index, row in df_final.iterrows():

    # set color 
    color = dict_colors[row['category']]

    # Set the label color and pct change labels to match the line color 
    plt.text(-.03, 
             row[year1], 
             str(row[year1]), 
             ha='right', 
             va='center', 
             color=color, 
             fontsize=12)
    plt.text(1.03, 
             row[year2], 
             str(row[year2]), 
             ha='left', 
             va='center', 
             color=color, 
             fontsize=12)
    plt.text(1.2, 
             row[year2], 
             f'{row["percent_change"]:.0f}%', 
             ha='center', 
             va='center', 
             color=color, 
             fontsize=12)
    plt.text(-.12, 
             row[year1], 
             row['category'], 
             ha='right', 
             va='center', 
             fontsize=12, 
             color=color)

    # plot lineplot for each category
    x_values = [0, 1]
    y_values = [row[year1], row[year2]]
    plt.plot(x_values, y_values, marker='o', color=color)

# Set x and y ticks
plt.yticks([])
plt.xticks([0, 1], ['2022', '2023'])

# Remove spines
for spine in plt.gca().spines.values():
    spine.set_visible(False)

# Add vertical light grey lines at x-values 0 and 1
plt.axvline(x=0, color='lightgrey', linestyle='--', alpha=0.6)
plt.axvline(x=1, color='lightgrey', linestyle='--', alpha=0.6)

# Set title
plt.text(x=-.45,
         y=58,
         s='AI / Tech Trends Interest Change',
         ha='left',
         va='center',
         color='black',
         fontsize=30)

# Show plot
plt.show()

作者截图

在下图中,我将标题上移,并添加了副标题,以增强可视化叙事的效果。副标题提供背景信息,引导解读,并有助于整体叙事流程,使数据对更广泛的观众更具可访问性和吸引力,同时提升了图表的视觉美感。

作者截图

坡度图分析

生成性 AI 的崛起

生成式 AI 是人工智能的一个子领域,它包含能够基于数据中的潜在学习模式和结构生成原创输出的算法。生成式 AI 兴趣的 2100%激增紧随 2022 年底 OpenAI 的 ChatGPT 上线,该聊天机器人以其先进的语言生成能力而闻名。

对生成式 AI 的高度关注得到有影响力的科技领袖的积极反馈的支持。埃隆·马斯克称其为“有史以来最强大的创造力工具”。比尔·盖茨设想它在从日常便利到解决重大全球问题的方面以无法想象的方式改变世界。他表示,“生成式 AI 有潜力以我们无法想象的方式改变世界。它有能力创造新的想法、产品和服务,使我们的生活更轻松、更高效、更富有创造力。它也有潜力解决一些世界上最大的难题,比如气候变化、贫困和疾病。”

多面的数字时代

相比之下,虚拟现实 (VR) 的兴趣下降了 19%,但在科技领域的公众兴趣中仍保持强劲的相对地位。它创造沉浸式环境的能力持续革新游戏、教育和医学培训等领域。随着生成式 AI 的崛起,VR 的沉浸能力继续持有变革性潜力,提供其他技术无法复制的独特体验。在 VR 的确立存在与生成式 AI 的新兴主导地位之间,我们可以期待(或紧张地预期)一个多面的数字时代。

Slopegraph 概述

适用性和优势

Slopegraphs 非常适合可视化多数据系列随时间的变化。它们在需要强调总体趋势的情况下表现出色,例如某个系列显著上升或下降,而不是关注每个期间的波动。这种方法减少了在值波动的折线图中常见的视觉混乱。

Slopegraphs 的局限性

  • 排除了中期数据: Slopegraphs 的一个主要限制是它们关注起点和终点,忽视了中期数据。如果被遗漏的数据对背景很重要,这可能会造成问题。在这种情况下,折线图可能是更好的选择。

  • 不适合无关的分类数据: Slopegraphs 在没有内在联系的分类数据中效果较差。不当使用时,可能会导致令人困惑的视觉效果。

  • 强调相对变化: Slopegraphs 突出系列之间的相对变化或比较速率,而非绝对值。对于精确量化(例如确切的销售增长百分比),条形图更为合适。

最终说明

希望这篇文章能作为一个信息丰富且赋能的指南,帮助你深入了解如何有效使用 slopegraphs。

如果你正在寻找一些创意来为你的下一个项目增添活力,我强烈推荐你查看数据故事讲述的 6 月 SWDChallenge 回顾:斜线图。这个资源包含了来自世界各地的数据可视化爱好者创作的多样化斜线图作品集。

数据故事讲述

对于那些不熟悉的人来说,数据故事讲述社区是一个数据可视化爱好者交流和学习的平台。他们每月举办一次挑战,鼓励参与者以创意和深刻的方式探索和展示数据。在斜线图挑战中,"#BREAKTHESTIGMA"条目给我留下了最深刻的印象,突显了 2014 年至 2015 年菲律宾自残事件的惊人上升。这一提交展示了数据故事讲述如何成为推动对关键社会和心理健康问题对话的强大催化剂。

我希望这篇文章和斜线图作品集能够激励你创造自己的作品!如果你有这样的计划,请随时联系我,我很乐意通过这里、LinkedIn,或者通过 christabellepabalan@gmail.com 听到你的消息。

可视化气候变化:用 Python 重现气候条纹的逐步指南

原文:towardsdatascience.com/visualizing-climate-change-a-step-by-step-guide-to-reproduce-climate-stripes-with-python-ea1d440e8e8d

快速的 Matplotlib 教程,帮助你创建出色的可视化

Guillaume WeingertnerTowards Data Science Guillaume Weingertner

·发布于 Towards Data Science ·6 分钟阅读·2023 年 2 月 17 日

--

全球温度变化(1850–2022)— 作者提供的图像 — 创意来自Ed Hawkins

动机

气候变化是我们时代最紧迫的问题之一。为了提高意识并传达问题的紧迫性,科学家和数据分析师们开发了多种可视化气候数据的方法。其中一种特别有效的方法是“气候条纹”可视化,最早由Ed Hawkins(雷丁大学的气候科学家)推广。在这篇文章中,我们将逐步演示如何使用 Python 重现气候条纹,为任何有兴趣制作自己气候条纹可视化的人提供详细的指南。无论你是气候科学家、数据分析师,还是只是对这个问题感兴趣的普通人,这个指南将为你提供制作自己气候条纹和与他人分享的工具。

这种可视化的美在于其简洁。只需一瞥,读者就能理解信息,而无需陷入其背后的技术细节中。

自从发布以来,气候条纹已被广泛应用于各种媒体。2019 年 9 月,这一可视化甚至登上了《经济学人》的封面,进一步提升了其知名度。

Ed Hawkins 实际上不久前更新了条纹数据,增加了 2022 年的数据点,并在推特上发布了相关内容。剧透一下,趋势没有改变。

Ed Hawkins 更新气候条纹的新推文

#1 数据

HadCRUT5 数据集包含相对于 1961-1990 年参考期的全球历史地表温度异常数据。可以在 www.metoffice.gov.uk/ 上找到,并在 Morice、Kennedy 等人的论文中介绍 [1]。

HadCRUT5 是一个结合了来自船只和浮标的海表温度测量数据与来自陆地表面的气象站的近地面气温测量数据的综合数据集。

这个简短的解释无法体现测量方法的复杂性和处理数据偏差的工作。参考部分链接的论文提供了更完整的图景。

在这种项目中,我们处理的数据集往往干净到不需要任何数据清理,但这个数据集实际上确实是干净的。

我们只需导入经典库来读取和绘制数据,就基本完成了准备工作:

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib as mpl
from matplotlib.colors import ListedColormap

df = pd.read_csv('HadCRUT.5.0.1.0.analysis.summary_series.global.annual.csv')
df.head()

数据集提取—文中使用的列已突出显示 — 作者提供的图片

#2 前提条件

色图

为了构建图表,我们将使用“ColorBrewer 9 类单色调色板中的八种最饱和的蓝色和红色”,这在原始条纹中也有使用,感谢维基百科和辛西娅·布鲁尔 — [2] 和 [3]。

图表构建方法

本文中我们将使用的图表类型是一个简单的条形图,我们将去掉大部分元素。

我在另一篇文章中解释了如何构建引人注目的条形图,这在这里同样适用:

## 使用 Python 构建漂亮条形图的 5 个步骤

如何利用 Matplotlib 的全部功能讲述更引人入胜的故事

towardsdatascience.com

#3 代码部分

不再多说,让我们开始构建吧。

实际上,按照下面的步骤,只需几行代码就能生成第一个版本:

  • 创建图形对象

  • 创建色图

    使用前面部分描述的相关颜色

  • 将温度异常数据线性化到 [0,1] 区间 这是在图表上正确使用色图的关键

  • 绘制条形图,使用 X 轴上的年份和嵌入色图中的异常值,而不是 Y 轴。这里的技巧是对所有条形图使用相同的高度(这里设为 1 单位),让色图讲述故事

# Create the figure and axes objects, specify the size and the dots per inches 
fig, ax = plt.subplots(figsize=(13.33,7.5), dpi = 96)

# Colours - Choose the colour map - 8 blues and 8 reds
cmap = ListedColormap([
    '#08306b', '#08519c', '#2171b5', '#4292c6',
    '#6baed6', '#9ecae1', '#c6dbef', '#deebf7',
    '#fee0d2', '#fcbba1', '#fc9272', '#fb6a4a',
    '#ef3b2c', '#cb181d', '#a50f15', '#67000d'])

# linearly normalizes data into the [0.0, 1.0] interval
norm = mpl.colors.Normalize(df['Anomaly (deg C)'].min(), df['Anomaly (deg C)'].max())

# Plot bars
bar = ax.bar(df['Time'], 1, color=cmap(norm(df['Anomaly (deg C)'])), width=1, zorder=2)

这就是我们得到的结果:

气候条纹第一部分 — 作者提供的图片

现在,只需清理图表并在其下方添加数据来源,一旦完成这一步骤就会变得非常简单:

  • 去除脊柱 使图表尽可能简洁

  • 重新格式化 X 轴和 Y 轴 无标签,无刻度,定义限制以避免空白区域

  • 添加来源

    数据图表下方的部分

  • 调整边距

    以确保图表居中

  • 设置白色背景

    以避免以后出现任何透明度问题

# Remove the spines
ax.spines[['top', 'left', 'bottom', 'right']].set_visible(False)

# Reformat x-axis label and tick labels
ax.set_xlabel('', fontsize=12, labelpad=10)
ax.set_xticks([])
ax.set_xlim([df['Time'].min()-1, df['Time'].max()+1])

# Reformat y-axis label and tick labels
ax.set_ylabel('', fontsize=12, labelpad=10)
ax.set_yticks([])
ax.set_ylim([0, 1]) 

# Set source text
ax.text(x=0.1, y=0.12, s="Source: Met Office - https://www.metoffice.gov.uk/hadobs/hadcrut5/index.html / Original idea - Ed Hawkins", transform=fig.transFigure, ha='left', fontsize=10, alpha=.7)

# Adjust the margins around the plot area
plt.subplots_adjust(left=0.1, right=None, top=None, bottom=0.2, wspace=None, hspace=None)

# Set a white background
fig.patch.set_facecolor('white')
ax.patch.set_facecolor('white')

这就是最终的气候条纹,去除所有元素,尽可能整洁,并显示数据来源:

气候条纹 — 作者图片

如果我们愿意,我们还可以:

  • 在 X 轴上添加刻度以显示年份

  • 将源文本设置为白色

  • 为图表添加标题

  • 重新调整边距,以考虑 X 刻度

  • 将背景颜色设置为黑色

# Reformat x-axis label and tick labels
ax.set_xlabel('', fontsize=12, labelpad=10)
ax.xaxis.set_tick_params(pad=2, labelbottom=True, bottom=True, labelsize=12, labelrotation=0, labelcolor='white')
ax.set_xlim([df['Time'].min()-1, df['Time'].max()+1])

# Set source text
ax.text(x=0.1, y=0.12, s="Source: Met Office - https://www.metoffice.gov.uk/hadobs/hadcrut5/index.html / Original idea - Ed Hawkins", transform=fig.transFigure, ha='left', fontsize=10, alpha=.7, color='white')

# Set graph title
ax.set_title('Global Temperature Change (1850 - 2022)', loc='left', color='white', fontweight="bold", size=16, pad=10)

# Adjust the margins around the plot area
plt.subplots_adjust(left=0.11, right=None, top=None, bottom=0.2, wspace=None, hspace=None)

# Set a black background
fig.patch.set_facecolor('black')
ax.patch.set_facecolor('black')

并获取最终版本:

气候条纹 — 最终版本 — 作者图片

#4 最终思考

气候条纹已被证明是传达气候变化现实的一个极其强大的工具。通过提供一个简单但有影响力的温度趋势表示,这种可视化已成为突出问题紧迫性的广泛使用且易于识别的方式。

在这篇文章中,我试图强调,最令人惊叹和相关的可视化,有时并不是最复杂的构建。

希望有人会觉得它有用!

参考文献

[1] — Morice, C.P., J.J. Kennedy, N.A. Rayner, J.P. Winn, E. Hogan, R.E. Killick, R.J.H. Dunn, T.J. Osborn, P.D. Jones and I.R. Simpson (in press) An updated assessment of near-surface temperature change from 1850: the HadCRUT5 dataset. Journal of Geophysical Research (Atmospheres) doi:10.1029/2019JD032361

开放政府许可 v3

[2] — en.wikipedia.org/wiki/Warming_stripes

[3] — colorbrewer2.org/#type=sequential&scheme=Reds&n=9

感谢你读到文章的最后。

关注以获取更多信息!

如果你有任何问题或意见,请随时在下面留言,或通过* LinkedIn 与我联系!

使用 Basemap 和 mplleaflet 可视化地理空间网络图

原文:towardsdatascience.com/visualizing-geospatial-network-graphs-using-basemap-and-mplleaflet-76a7f3d0c923

学习如何在地图上绘制网络图

Wei-Meng Lee Towards Data Science Wei-Meng Lee

·发表于 Towards Data Science ·阅读时间 9 分钟·2023 年 3 月 6 日

--

照片由 Z 提供,来源于 Unsplash

在我之前关于网络图的文章中,我展示了如何使用 NetworkX 和 pyvis 包绘制有向图和无向图。在本文中,我将使用航班延误数据集来可视化不同机场之间的航线,特别是展示如何使用地理空间网络图来进行可视化。

## 使用 Python 绘制网络图

学习如何使用 NetworkX 包来可视化复杂的网络

## 使用 pyvis 构建互动网络图

学习如何让你的网络图生动起来

## 使用 pyvis 构建互动网络图

使用航班延误数据集

像往常一样,我将使用 2015 年航班延误 数据集。

2015 年航班延误数据集airports.csv)。来源www.kaggle.com/datasets/usdot/flight-delays许可证CC0: 公共领域

我将使用这个数据集中的两个文件:

  • flights.csv

  • airports.csv

首先,让我们将 flights.csv 文件加载到 Pandas DataFrame 中:

import pandas as pd
df = pd.read_csv('flights.csv', 
                 usecols = ["ORIGIN_AIRPORT", "DESTINATION_AIRPORT","YEAR"])
df.head()

我们不需要加载文件中的所有列(文件很大!)——三列足够用于这篇文章。你应该能看到如下的数据框:

所有图片均由作者提供

一旦数据框加载完毕,我将继续统计从一个机场到另一个机场的航班数量:

df_between_airports = df.groupby(by=["ORIGIN_AIRPORT", "DESTINATION_AIRPORT"]).count()
df_between_airports = df_between_airports['YEAR'].rename('COUNT').reset_index() 
df_between_airports = df_between_airports.query('ORIGIN_AIRPORT.str.len() <= 3 & DESTINATION_AIRPORT.str.len() <= 3')
df_between_airports = df_between_airports.sort_values(by="COUNT", 
                                                      ascending=False)
df_between_airports

结果输出如图所示:

由于航班组合超过 4500 个,让我们只选择前 800 个组合:

top = 800
df_between_airports = df_between_airports.head(top)
df_between_airports

创建图形

NetworkX 包有一个叫做 from_pandas_edgelist() 的函数,你可以用来从 Pandas DataFrame 创建一个边列表。它返回一个图对象:

import networkx as nx

G = nx.from_pandas_edgelist(df_between_airports, 
                            'ORIGIN_AIRPORT', 
                            'DESTINATION_AIRPORT',
                            create_using = nx.DiGraph())

在上述语句中,G 是一个有向图(networkx.classes.digraph.DiGraph)。如果你想创建一个无向图(networkx.classes.graph.Graph),只需省略 creating_using 参数。

现在图包含了从提供的数据框中得出的所有节点和边。在我们的案例中,节点是来自ORIGIN_AIRPORTDESTINATION_AIRPORT列的所有机场。

现在你可以检查图中的节点:

G.nodes()

你应该能看到如下内容:

NodeView(('SFO', 'LAX', 'JFK', 'LAS', 'LGA', 'ORD', 'OGG', 'HNL', 'ATL', 
'MCO', 'DFW', 'SEA', 'BOS', 'DCA', 'FLL', 'PHX', 'DEN', 'TPA', 'SAN', 
'PHL', 'KOA', 'ANC', 'MSP', 'SJC', 'MIA', 'CLT', 'HOU', 'DAL', 'OAK', 
'SLC', 'LIH', 'BWI', 'MSY', 'SMF', 'JAX', 'EWR', 'DTW', 'IAH', 'MKE', 
'ITO', 'RDU', 'SAT', 'AUS', 'MDW', 'SJU', 'SNA', 'PBI', 'PDX', 'CLE', 
'CVG', 'RSW', 'IND', 'BUR', 'IAD', 'BNA', 'RIC', 'STL', 'MCI', 'CMH', 
'DSM', 'PIT', 'RNO', 'BHM', 'CHS', 'MSN', 'GEG', 'SAV', 'MEM', 'GRR', 
'ONT', 'CID', 'GRB', 'SDF', 'CHA', 'OKC', 'DAY', 'CAE', 'ORF', 'GSO', 
'TUS', 'TUL', 'GRK', 'XNA', 'PVD', 'BTR', 'GSP', 'ABQ', 'HSV', 'BUF', 
'AGS', 'BDL', 'ABI', 'JAN', 'LEX', 'SHV', 'PNS', 'FWA', 'MOB', 'SGF', 
'MHT', 'VPS', 'MGM', 'ICT', 'PIA', 'LFT', 'PSP', 'CRP', 'TLH', 'FAR', 
'TYS', 'SBA', 'GNV', 'COS', 'OMA', 'MAF', 'CAK', 'FSD', 'LIT'))

同样,你可以检查边:

G.edges()

这是返回的部分边列表:

EdgeView(('SFO', 'LAX'), ('SFO', 'JFK'), ('SFO', 'LAS'), ('SFO', 'ORD'), 
('SFO', 'SAN'), ('SFO', 'SEA'), ('SFO', 'DEN'), ('SFO', 'EWR'), 
('SFO', 'PHX'), ('SFO', 'DFW'), ('SFO', 'SNA'), ('SFO', 'PDX'), 
('SFO', 'BOS'), ('SFO', 'IAD'), ('SFO', 'IAH'), ('SFO', 'SLC'), 
('SFO', 'ATL'), ('SFO', 'MSP'), ('SFO', 'ONT'), ('SFO', 'PSP'), 
('SFO', 'SBA'), ('SFO', 'PHL'), ('SFO', 'HNL'), ('SFO', 'AUS'), 
('LAX', 'JFK'), ('LAX', 'LAS'), ('LAX', 'ORD'), ('LAX', 'SEA'), 
('LAX', 'PHX'), ('LAX', 'DFW'), ('LAX', 'SJC'), ('LAX', 'OAK'), 
('LAX', 'DEN'), ('LAX', 'ATL'), ('LAX', 'SMF'), ('LAX', 'SLC'), 
...
...

绘制图形

现在你可以绘制显示前 800 个机场之间航班的网络图:

import matplotlib.pyplot as plt

plt.figure(figsize=(8, 8))

options = {
    'node_color':'yellow',
    'node_size': 1500,
    'width': 1,
    'arrowstyle': '-|>',
    'arrowsize': 18,
}

nx.draw_circular(G, with_labels = True,  **options)

网络图看起来是这样的:

![哎呀!显然我们有太多机场,这让网络图变得非常混乱。让我们通过将从数据框中提取的行数减少到 140 来减少机场数量:pytop = 140df_between_airports = df_between_airports.head(top)df_between_airports现在网络图看起来是这样的:

这现在是一个更干净的图!

地理空间映射

我们的数据集包含地理空间数据,如果不把数据映射到地图上,就无法充分利用我们的数据集!

在这一部分,我将展示如何将网络图绘制到地图上。我将使用以下包:

  • basemap

  • mplleaflet

安装 basemap

我将使用的第一个地图是basemap

Basemap 是一个非常有用的 matplotlib 扩展,适用于在 Python 中创建地图。

要安装 basemap,请使用 pip 命令:

!pip install basemap

如果你使用的是 Windows,安装应该不会有问题。然而,在 Mac 上,你可能会收到一些关于缺失geos库的错误信息。要解决这个问题,请执行以下步骤:

$ brew install geos

如果你还没有安装 Homebrew,请访问 brew.sh/

观察geos的安装位置。对于我的机器,geos安装在/opt/homebrew/Cellar/geos/3.11.1。接下来,在终端中输入以下命令,将目录指向geos的安装位置:

$ export GEOS_DIR=/opt/homebrew/Cellar/geos/3.11.1

最后,重新启动你的 Jupyter Notebook。Basemap 应该现在已正确安装。

加载机场位置

为了在地图上绘制机场的位置,你需要每个机场的纬度和经度。幸运的是,这已经在airports.csv文件中提供:

import pandas as pd

df_airports = pd.read_csv('airports.csv')
df_airports

这个 CSV 文件包含了所有机场的 IATA_CODE 以及它们对应的纬度和经度:

但是,有一件事需要注意。还有三个机场没有位置信息。你可以通过以下语句验证这一点:

# check which airport does not have location information
df_airports[(df_airports['LATITUDE'].isna()==True) |
            (df_airports['LONGITUDE'].isna()==True)]

现在你可以看到以下机场没有位置信息——ECPPBGUST

有两种解决办法:

  • 删除所有没有位置信息的机场,或者

  • 为这三个机场提供位置信息

我们将通过填写缺失的位置信息来完成后者:

# ECP airport
df_airports.at[96,'LATITUDE'] = 30.354984
df_airports.at[96,'LONGITUDE'] = -85.79934

# PBG airport
df_airports.at[234,'LATITUDE'] = 44.6597091
df_airports.at[234,'LONGITUDE'] = -73.46722069999998

# UST airport
df_airports.at[313,'LATITUDE'] = 29.954352
df_airports.at[313,'LONGITUDE'] = -81.342935

绘制基础地图

我们现在准备绘制基础地图:

from mpl_toolkits.basemap import Basemap as Basemap
import matplotlib.pyplot as plt

plt.figure(figsize = (10,9))

basemap = Basemap(
    projection = 'merc',
    llcrnrlon = -180, 
    urcrnrlon = -50,     
    llcrnrlat = -10,  
    urcrnrlat = 70,    
    lat_ts = 0,
    resolution = 'l',
    suppress_ticks = True)

上述代码片段使用墨卡托投影(merc)显示基础地图。

有关配置基础地图的更多详细信息,请参见:basemaptutorial.readthedocs.io/en/latest/

为了在基础地图上显示机场位置,你需要将纬度、经度转换为 x 和 y 地图投影坐标:

# pass in lon, lat to convert to x/y map projection coordinates
basemap_x, basemap_y = basemap(df_airports['LONGITUDE'].values, 
                               df_airports['LATITUDE'].values)

接下来,我们需要创建一个如下格式的字典:{IATA_CODE: (x,y)}。你可以使用以下语句来完成:

pos = {}
for i, IATA_CODE in enumerate (df_airports['IATA_CODE']):    
    pos[IATA_CODE] = (basemap_x[i], basemap_y[i])

pos变量现在看起来是这样的:

{'ABE': (11626491.577256551, 6073282.907509623),
 'ABI': (8930961.032284452, 4930788.720997522),
 'ABQ': (8160681.891600923, 5282318.28670927),
 'ABR': (9071074.35752435, 6803760.994159843),
 'ABY': (10653083.864127252, 4815986.333659503),
 'ACK': (12224744.463780478, 6161722.945706454),
 ...

绘制节点、标签和边缘

获取到 x 和 y 地图投影坐标后,你现在可以开始将网络图绘制到基础地图上:

ax = plt.figure(figsize=(13, 13))

nx.draw_networkx_nodes(G = G, 
                       pos = pos, 
                       nodelist = G.nodes(), 
                       node_color = 'r', 
                       alpha = 0.7, 
                       node_size = [sum(df_between_airports.query(f'DESTINATION_AIRPORT == "{x}"')['COUNT']) / 400 for x in G.nodes()]
                       )

nx.draw_networkx_labels(G = G, 
                       pos = pos,
                       labels =  {x:x for x in G.nodes()},
                       font_size = 10
                       )

nx.draw_networkx_edges(G = G, 
                       pos = pos, 
                       edge_color='g',
                       alpha=0.2, 
                       arrows = False)

basemap.drawcoastlines(linewidth = 0.5)

上述代码片段将节点、标签和边缘绘制到基础地图上:

如果你尝试使用正射投影(ortho)绘制地图:

basemap = Basemap(projection='ortho',
                  lon_0 = -105,
                  lat_0 = 40,
                  resolution = 'l')

地图现在看起来是这样的:

很酷,对吧!

使用 mplleaflet 进行绘制

虽然你可以使用基础地图绘制网络图,但最大的缺点是你无法真正与其互动。能够平移地图以更详细地检查每个机场将是很有用的。这就是mplleaflet的用武之地。

mplleaflet 是一个 Python 库,它将 matplotlib 图转换为包含可平移、缩放的 Leaflet 地图的网页。你可以在 Jupyter Notebook 中嵌入 Leaflet 地图。

让我们首先通过将所有位置转换为字典来准备每个机场的位置:

import matplotlib.pyplot as plt
import mplleaflet
import networkx as nx

# load the nodes and edges
G = nx.from_pandas_edgelist(df_between_airports, 
                            'ORIGIN_AIRPORT', 
                            'DESTINATION_AIRPORT')

# create a dictionary of this format: { IATA_CODE: [LONGITUDE, LATITUDE] }
pos = df_airports[['IATA_CODE','LONGITUDE','LATITUDE']].set_index('IATA_CODE').T.to_dict('list')

pos变量现在是如下格式的字典:{ IATA_CODE: [LONGITUDE, LATITUDE]}

{'ABE': [-75.4404, 40.65236],
 'ABI': [-99.6819, 32.41132],
 'ABQ': [-106.60919, 35.04022],
 'ABR': [-98.42183, 45.44906],
 'ABY': [-84.19447, 31.53552],
 'ACK': [-70.06018, 41.25305],
 'ACT': [-97.23052, 31.61129],
 'ACV': [-124.10862, 40.97812],
 ...
 ...

现在你可以在mplleaflet地图上绘制节点和边缘:

fig, ax = plt.subplots(figsize=(15,15))

# draw the nodes
nx.draw_networkx_nodes(G,
                       pos = pos,
                       node_size = [sum(df_between_airports.query(f'DESTINATION_AIRPORT == "{x}"')['COUNT']) / 1500 for x in G.nodes()],
                       node_color='red',
                       alpha = 0.8)

# draw the edges
nx.draw_networkx_edges(G,
                       pos = pos,
                       edge_color = 'gray', 
                       alpha=0.3)

# display the map
mplleaflet.display(fig=fig)

每个节点的大小与到达机场的航班数量成比例。地图现在显示了网络图:

如果你遇到像“AttributeError: ‘XAxis’ object has no attribute ‘_gridOnMajor’”这样的错误,你可能需要使用pip命令降级 matplotlib 版本:pip install matplotlib==3.3.2

你可以缩放地图以及平移地图:

如果你删除代码的早期部分,其中我们仅选择了前 140 个航班组合:

# top = 140
# df_between_airports = df_between_airports.head(top)
# df_between_airports

这就是显示所有机场后的地图样子:

如果你喜欢阅读我的文章,并且这些文章对你的职业/学习有所帮助,请考虑注册成为 Medium 会员。每月费用为 5 美元,它可以让你无限制地访问 Medium 上的所有文章(包括我的文章)。如果你通过以下链接注册,我将获得一小笔佣金(对你没有额外费用)。你的支持意味着我可以花更多时间写像这样的文章。

[## 使用我的推荐链接加入 Medium — Wei-Meng Lee

阅读 Wei-Meng Lee(以及 Medium 上成千上万的其他作者)的每一篇故事。你的会员费用直接支持…

weimenglee.medium.com](https://weimenglee.medium.com/membership?source=post_page-----76a7f3d0c923--------------------------------)

总结

希望你在尝试本文中的代码时感到愉快!为了在basemap上绘制网络图,你需要做的主要工作是将纬度和经度转换为地图投影坐标的字典,而对于mplleaflet地图,你需要将纬度和经度放入字典中。basemap允许你尝试不同类型的投影(如墨卡托投影、正射投影等),但主要的缺点是它不具备交互性。另一方面,mplleaflet允许你与地图进行交互,但它不支持像basemap那样的投影。

可视化 3 种 Sklearn 交叉验证:K-Fold、Shuffle & Split 和 Time Series Split

原文:towardsdatascience.com/visualizing-sklearn-cross-validation-k-fold-shuffle-split-and-time-series-split-a13221eb5a56

绘制 Sklearn K-Fold、Shuffle & Split 和 Time Series Split 交叉验证的过程,并使用 Python 显示验证结果

Boriharn KTowards Data Science Boriharn K

·发表于 Towards Data Science ·阅读时间 11 分钟·2023 年 7 月 10 日

--

图片由 Ryoji IwataUnsplash 提供

什么是交叉验证?

基本上,交叉验证是一种评估学习算法的统计方法。设置一个固定数量的折(数据组)来运行分析。这些折将数据分成 2 个集合:训练集和测试(验证)集,这些集合在轮次中交叉,使每个数据点都能被验证。

主要目的是测试模型预测独立数据的能力,这些数据在模型创建过程中没有使用。它也有助于应对诸如 过拟合选择偏差 等问题。

这篇文章中的交叉验证结果示例。图片由作者提供。

在本文中,我们将应用 Python 来可视化来自 Scikit Learn 库的 3 种交叉验证类型的过程:

  • K-Fold 交叉验证

  • Shuffle & Split 交叉验证

  • Time Series Split 交叉验证

此外,验证结果也可以绘制出来以表达有见地的信息。

开始吧

1. K-Fold 交叉验证

K-fold 是一种常见的交叉验证方法。首先,将所有数据划分为折。然后,从训练集(k-1 折)创建学习模型,并使用测试集(剩下的折)进行验证。

通常,从 K 折交叉验证中获得的折叠被尽可能均匀地划分。接下来,我们将深入了解 K 折交叉验证的过程。

导入库并加载数据

例如,本文将使用葡萄酒数据集,可以从 Sklearn 库下载。该数据集是UCI ML 葡萄酒数据的副本,采用CC BY 4.0许可证。

总共有 13 种成分在三种类型的葡萄酒中发现。这些属性将用于构建一个用于分类葡萄酒类别的分类模型。

import numpy as np
import pandas as pd
from sklearn.datasets import load_wine

data = load_wine()
X = pd.DataFrame(data=data.data, columns=data.feature_names)
y = pd.DataFrame(data=data.target, columns=['class'])
df = pd.concat([X, y], axis=1)
df.head()

下一步的过程可以解释为:我们将首先应用KFold function来将数据分组为训练集和测试集。可以通过n_splits参数指定折数。

然后,将创建支持向量机(SVMs)以在每次迭代中使用svm function来分类葡萄酒类别。最后,将使用score function来衡量模型性能的平均准确性。

这些步骤可以使用 Python 中的 for-loop 函数来完成,如下方代码所示。

from sklearn.model_selection import KFold
from sklearn import svm

kf = KFold(n_splits=10)
# a list for keeping training index, testing index and obtained score
keep = []      
for train, test in kf.split(df):
    X_train = df.iloc[list(train),:-1]
    y_train = df.iloc[list(train),-1]
    X_test = df.iloc[list(test),:-1]
    y_test = df.iloc[list(test),-1]
    clf = svm.SVC(kernel='linear').fit(X_train, y_train)
    score = clf.score(X_test, y_test)

    keep.append([train, test, score])
    print(score)

现在我们拥有来自迭代的数据和准确性分数,让我们定义一个函数来创建一个用于绘图的 DataFrame。

def create_df(input_):
    df_train = pd.DataFrame(zip(input_[0], len(input_[0])*['train']),
                            columns = ['index','group'])
    df_test = pd.DataFrame(zip(input_[1], len(input_[1])*['test']),
                           columns = ['index','group'])
    df_comb = pd.concat([df_train, df_test])
    df_comb['score'] = len(df_comb)*[input_[2]]
    return df_comb

#create a DataFrame from the list
keep_df = [create_df(i) for i in keep]
df_in = pd.concat(keep_df)
df_in.reset_index(inplace=True, drop=True)
df_in.head()

将迭代的顺序编号分配给 DataFrame。

#create a list of numbers for assigning the n th iteration
list_num = [i[0] + 1 for i in list(enumerate(keep))]
list_num.reverse()

list_it = [len(df)*[i] for i in list_num]
df_kf = pd.DataFrame(sum(list_it,[]), columns=['CV iteration'])
df_kf.reset_index(inplace=True, drop=True)

df_cv = pd.concat([df_in, df_kf], axis=1)
df_cv.head()

可视化 K 折交叉验证的迭代过程

接下来,我们可以使用Plotly绘制散点图,这是一种有用的数据可视化库,可以用几行代码构建交互式图表。

import plotly.express as px
fig1 = px.scatter(df_cv, x='index', y='CV iteration', color='group',
                  color_discrete_map={'test':'red','train':'blue'})

fig1.show()

绘制 K 折交叉验证的迭代过程。图片来源:作者。

从散点图中可以注意到,在每次迭代中,K 折交叉验证中的训练集和测试集在连续的轮次中交叉。

可视化 K 折交叉验证结果

让我们继续在图表上绘制准确性分数,以获取更多信息。通过选择仅包含测试集的行来过滤 DataFrame,以获取准确性分数。

df_score = df_cv[df_cv['group'].isin(['test'])]
df_score.head()

使用颜色刻度绘制分数值。

import plotly.express as px
fig2 = px.scatter(df_score, x='index', y='CV iteration', color='score',
                  color_continuous_scale=px.colors.sequential.YlOrRd_r,
                  range_color=(0.6,1))
fig2.update_layout(coloraxis_colorbar_x=-0.15)
fig2.show()

绘制 K 折交叉验证的结果。图片来源:作者。

绘制分数有助于比较结果。我们可以从图表中看出,SVM 在第 7 次迭代中获得的准确率与其他迭代相比最低。

奖励!!

幸运的是,我们可以使用 Plotly 将散点图合并,以在同一图表中查看过程和验证分数。结果将以交互式图表形式呈现。

import plotly.express as px
fig1 = px.scatter(df_cv, x='index', y='CV iteration', color='group',
                 color_discrete_map={'test':'red','train':'blue'})

fig2 = px.scatter(df_score, x='index', y='CV iteration', color='score',
                  color_continuous_scale=px.colors.sequential.YlOrRd_r,
                  range_color=(0.65,1))
fig2.update_layout(coloraxis_colorbar_x=-0.15)

fig2.add_traces(list(fig1.select_traces()))
fig2.show()

哒哒……

合并 K-fold 交叉验证迭代图和结果图。图片由作者提供。

2. Shuffle & Split 交叉验证

正如其名,这种交叉验证技术将首先打乱数据,然后将其分为训练集和测试集。

通过应用 Sklearn 的 ShuffleSplit 函数,我们可以设置参数以控制拆分次数和数据集之间的比例。如果需要控制比例大小,这种方法可以作为 K-fold 的替代方案。

from sklearn.model_selection import ShuffleSplit

kf = ShuffleSplit(n_splits=10, test_size=0.25, random_state=15)
keep = []
for train, test in kf.split(df):
    X_train = df.iloc[list(train),:-1]
    y_train = df.iloc[list(train),-1]
    X_test = df.iloc[list(test),:-1]
    y_test = df.iloc[list(test),-1]
    clf = svm.SVC(kernel='linear', C=1).fit(X_train, y_train)
    score = clf.score(X_test, y_test)
    keep.append([train, test, score])
    print(score)

由于创建 DataFrame 的过程与之前提到的相同,我们将重复如下所示的代码。

#create a DataFrame from the list
keep_df = [create_df(i) for i in keep]
df_in = pd.concat(keep_df)
df_in.reset_index(inplace=True, drop=True)

#create a list of numbers for assigning the nth iteration 
list_num = [i[0] + 1 for i in list(enumerate(keep))]
list_num.reverse()

list_it = [len(df)*[i] for i in list_num]
df_kf = pd.DataFrame(sum(list_it,[]), columns=['CV iteration'])
df_kf.reset_index(inplace=True, drop=True)

df_cv = pd.concat([df_in, df_kf], axis=1)
df_cv.head()

可视化 Shuffle & Split 交叉验证迭代

现在我们已经准备好 DataFrame,让我们使用散点图来展示从 shuffle & split 交叉验证中获得的数据集。

import plotly.express as px
fig1 = px.scatter(df_cv, x='index', y='CV iteration', color='group',
                  color_discrete_map={'test':'red','train':'blue'})

fig1.show()

绘制 shuffle & split 交叉验证迭代。图片由作者提供。

可以看出,在 shuffle & split 中,数据都被随机分为训练集和测试集,而在 K-fold 交叉验证中,数据被分组到训练集和测试集中。

让我们继续绘制验证结果。

可视化 Shuffle & Split 交叉验证结果

过滤 DataFrame 以获取准确率分数。

df_score = df_cv[df_cv['group'].isin(['test'])]
df_score.head()

使用颜色尺度绘制结果以表达分数值。

import plotly.express as px
fig2 = px.scatter(df_score, x='index', y='CV iteration', color='score',
                  color_continuous_scale=px.colors.sequential.YlOrRd_r,
                  range_color=(0.6,1))

fig2.update_layout(coloraxis_colorbar_x=-0.15)
fig2.show()

绘制 shuffle & split 交叉验证结果。图片由作者提供。

获取的图表效果不好。由于测试集中的数据没有分组,因此难以阅读。我们可以通过更改散点大小来改善结果。这可以通过添加大小参数来完成,如下面的代码所示。

import plotly.express as px
fig2 = px.scatter(df_score, x='index', y='CV iteration',
                  size=[i**20 for i in df_score['score']], color='score',
                  color_continuous_scale=px.colors.sequential.YlOrRd_r,
                  range_color=(0.8,1))
fig2.update_layout(coloraxis_colorbar_x=-0.15)
fig2.update_traces(marker_line_width = 0.2)
fig2.show()

使用颜色和大小绘制 shuffle & split 结果以显示分数值。图片由作者提供。

更改散点大小有助于区分验证结果。从上面的结果来看,第 6 次迭代中测试集的 SVM 准确率返回了最低分,而第 1 次和第 3 次迭代返回了最高分。

3. 时间序列分割交叉验证

该技术有助于在滚动基础上验证时间序列模型。时间序列拆分和 K 折的主要区别在于:每次迭代中的前K折是训练集,第K+1折是测试集。

导入库并加载数据

本文将使用气象数据作为示例。我们可以使用Meteostat 获取某地的温度随时间变化的数据。该库是一个有用的工具,提供了通过 Pandas 简单访问开放天气和气候数据的方式。

气象数据在CC BY-NC 4.0许可证下使用。例如,让我们获取 2010–2022 年间纽约市的平均温度。

from datetime import datetime
import matplotlib.pyplot as plt
import seaborn as sns
from meteostat import Point, Daily

# set date and GPS location
start = datetime(2010, 1, 1)
end = datetime(2022, 12, 31)
location = Point(40.75, -73.98)

data = Daily(location, start, end)
data = data.fetch()
data.head()

用折线图绘制平均温度数据。

plt.figure(figsize=(10,5))
sns.set_style('darkgrid')
sns.lineplot(data=data, x="time", y="tavg")
plt.show()

折线图显示了纽约市 2010–2022 年的每日平均温度。图片作者提供。

将日期时间列分组以获得平均月温度,以便后续进行时间序列模型分析。

# add a 'month-year' column 
data.reset_index(inplace=True)
data['my'] = [str(i)[0:7] for i in data['time']]

# group by to get average monthly data
data_g = data.groupby(['my']).mean()
data_g.reset_index(inplace=True)
data_g['my'] = data_g['my'].astype('datetime64[ns]')
data_g.set_index('my', inplace=True)
data_g.head()

现在进入交叉验证部分。我们将使用TimeSeriesSplit 函数来自 Sklearn 库进行时间序列拆分交叉验证。可以指定n_splits参数来设置拆分的数量。

from sklearn.model_selection import TimeSeriesSplit
tscv = TimeSeriesSplit(n_splits=5)

keep = []
for train_p, test_p in tscv.split(data_g.tavg):
    keep.append([train_p, test_p])

# create DataFrame from each TimeSeriesSplit and keep them in a list
keep_df = []
for i in keep:
    df_train = pd.DataFrame(zip(i[0], ['train']*len(i[0])),
                            columns=['index','group'])
    df_test = pd.DataFrame(zip(i[1], ['test']*len(i[1])),
                           columns=['index','group'])
    df = pd.concat([df_train, df_test], axis=0)
    keep_df.append(df)

为每次迭代分配行号以进行绘图。

list_num = [i[0] for i in list(enumerate(keep))]
list_num.reverse()
list_r = []
for i,j in zip(keep_df, list_num):
    i['k_fold']=[j]*len(i)
    list_r.append(i)

df_p = pd.concat(list_r, axis=0)
df_p.head()

可视化时间序列拆分交叉验证迭代

创建一个散点图,以显示时间序列拆分交叉验证的迭代。

import plotly.express as px
fig = px.scatter(df_p, x='index', y='k_fold', color='group',
                 color_discrete_map={'test':'red','train':'blue'})

fig.update_layout(yaxis_showticklabels=False)
fig.show()

绘制时间序列拆分交叉验证迭代。图片作者提供。

尽管上述可视化可以展示过程,但气象数据并不是这条直线。接下来,我们将把实际数据和预测结果绘制在图表中。

可视化时间序列拆分交叉验证结果

对于交叉验证,我们可以使用自回归积分滑动平均(ARIMA)模型,这是一种基于历史时间序列数据进行预测的强大方法。本文中的 ARIMA 模型将使用pmdarima 创建。

该过程可以解释为:在每次迭代中,ARIMA 模型是从训练集中的数据建立的。之后,将预测结果和测试集中的数据绘制在同一图表中以比较结果。

import pmdarima as pm

for train_p, test_p in tscv.split(data_g.tavg):
    train = np.array(list(data_g.iloc[train_p,:]['tavg']))
    test = np.array(list(data_g.iloc[test_p,:]['tavg']))
    # fiting the model
    model = pm.auto_arima(train, seasonal=True, m=3)
    # forecasting
    forecasts = model.predict(len(test))

    df_tr = pd.DataFrame(data_g.iloc[train_p,:]['tavg'])
    df_tr.reset_index(inplace=True)
    df_ts = pd.DataFrame(data_g.iloc[test_p,:]['tavg'])
    df_ts.reset_index(inplace=True)
    df_ts['forecast'] = forecasts
    df_c = pd.concat([df_tr, df_ts], axis=0)
    df_index = pd.DataFrame(data_g.index)
    df_p = pd.merge(df_index, df_c, on='my', how='left')

    # Visualize the forecasts
    fig, ax = plt.subplots(figsize=(10.6,2))
    ax.set(xlim=(data_g.index[0], data_g.index[-1]))
    sns.lineplot(x=df_p.my, y=df_p.tavg, lw=2)
    sns.lineplot(x=df_p.my, y=df_p.forecast, lw=2, linestyle='dashed')
    plt.show()

瞧!

绘制时间序列拆分交叉验证与 ARIMA 预测结果。图片作者提供。

从图表中可以看出,ARIMA 模型在迭代过程中得到了改进。尽管第一次预测与测试集中的数据不完全匹配(重叠),但后续预测会越来越好。

摘要

交叉验证技术有助于验证学习算法。其主要概念是将数据分为训练集和测试集。然后,使用训练集创建模型,并使用测试集对模型进行验证。

这些方法也可以用来标记过拟合或选择偏差。

显然,交叉验证的类型比本文中提到的要多。顺便说一下,主要概念是相同的,它们都具有相同的目的:评估模型。

感谢阅读。

这里是一些你可能会感兴趣的文章:

  • 可视化多重共线性对多重回归模型的影响 (link)

  • 8 个用 Python 处理多时间序列数据的可视化 (link)

  • 7 个用 Python 表达排名随时间变化的可视化 (link)

  • 9 个用 Python 显示比例或百分比而不是饼图的可视化 (link)

  • 9 个用 Python 制作的比条形图更引人注目的可视化 (link)

参考文献

通过 Python 的 NetworkX 库可视化社交网络以获取更好的洞察:分析和映射社交关系

原文:towardsdatascience.com/visualizing-social-networks-for-better-insights-analyzing-and-mapping-social-relationships-with-efeb82ab853e

初学者使用 Python 的 NetworkX 库进行社交网络分析的指南

Christine EganTowards Data Science Christine Egan

·发表于 Towards Data Science ·阅读时长 6 分钟·2023 年 5 月 20 日

--

在侦探节目中,包含相关证据的软木板常常被描绘为一种方法,帮助调查人员可视化和追踪调查中个人和事件之间的联系。红色线条用于将不同的节点(通常用照片或便条表示)物理连接在一起,显示它们之间的关系。

图片由 Volodymyr Hryshchenko 提供,来源于 Unsplash

这种普遍的情节被一些人描述为 “线索理论”(不是那个 弦理论),有些人将其称为 “疯狂墙”“线索板”。在网络理论领域,这种分析人与组织或文件之间链接和联系的技术被称为 链接分析,并且在执法、欺诈检测、社会学研究以及其他各种背景下已经使用了一个多世纪。

链接分析与社交网络分析

链接分析指的是分析任何类型实体之间的链接(或关系)的过程。这可以包括分析网页、电子邮件、金融交易或任何其他数据类型中实体之间的关系。社会网络分析是一种专注于人群及其相互关系的特定链接分析。

社会网络分析(SNA)之所以成为一个强大的工具,是因为能够在图中可视化这些关系,使用节点来表示个体,边来表示它们之间的连接。可视化个体和关系使我们能够更容易地直观理解社会影响的动态、社会群体的形成以及群体和个体之间信息的流动。

我们都像一张看不见的网那样相互连接。

出租车司机的智慧(1996)

使用 Python 和 NetworkX 进行社会网络分析

NetworkX是一个用于创建、操作和研究复杂网络的 Python 库。它可以处理拥有数百万个节点和边的网络,并提供生成随机网络、计算网络度量和可视化网络结构的功能。它还拥有广泛的社区检测、链接预测网络可视化算法。尽管 NetworkX 功能强大,Python 用户会发现它易于使用和直观。

社会网络分析的基本概念

那么我们可以使用什么概念来分析社会网络呢?一个好的起点是节点,它们是网络的基本组成部分。

节点代表网络中的个体,而构成个体之间的关系。

一个节点和边标记的图示例。

为了演示,让我们用 Python 和 NetworkX 构建一个简单的网络,表示Billy CorganSmashing Pumpkins其他创始成员之间的对称关系。

这将输出一个看起来像这样的网络图:

用中心性描述社会网络

用于描述网络中个体和关系的一个标准是中心性中心性是衡量网络中节点重要性或影响力的指标。中心性的两个衡量标准包括度中心性介数中心性

度中心性 是基于一个节点的连接数来衡量网络中节点重要性的指标。度中心性高的节点在网络中被认为更具影响力或更为中心。度中心性可以通过将节点的连接数除以网络中最大可能的连接数来计算。网络中一个节点的度中心性为 1 意味着该节点与网络中的所有其他节点直接连接。

中介中心性 衡量了每个节点在网络中的重要性,基于它出现在其他节点对之间最短路径上的频率。中介中心性允许我们评估网络中哪些节点被认为更具影响力,因为它们在连接网络的不同部分中发挥了关键作用。

中介中心性可以通过计算通过一个节点的最短路径数量并除以网络中所有最短路径的总数来计算。

使用 NetworkX 计算中心性

在下面的代码中,我们演示了如何使用我们用 NetworkX 构建的图对象来计算网络中节点的度中心性和中介中心性。

在下面的代码中,我们演示了如何使用我们用 NetworkX 构建的图对象来计算网络中节点的度中心性和中介中心性。在这段代码中,我们生成了一个图对象 nx,它表示 Billy Corgan 与 Smashing Pumpkins 成员之间的对称关系。然后,使用 .degree_centrality 方法生成一个字典,其中每个节点及其度中心性作为键值对存储。我们使用 .betweenness_centrality 方法重复这个过程,生成一个包含 nx 中每个节点及其中介中心性计算的字典。结果如下表:

 node                degree        betweenness        
 ------- ------------------- ------------- ------------
     0    Billy Corgan          1.000000    1.0  
     1    James Iha             0.333333    0.0  
     2    D'arcy Wretzky        0.333333    0.0  
     3    Jimmy Chamberlin      0.333333    0.0 

那么我们如何解释这些结果呢?

解释度中心性

Billy Corgan 的度中心性为 1,这意味着他与其他乐队成员有最大数量的连接。如果你记得的话,这与我们的输入和我们构建网络以展示 Billy Corgan 和每个乐队成员之间的对称关系的方式是一致的。由于 Billy Corgan 出现在每个元组中,他将与每个其他节点都有一个链接。

另一方面,其他乐队成员只出现了一次。那么我们如何将度中心性公式应用于其他乐队成员以得到 0.333 的值呢?

作为回顾,度中心性是这样计算的:

degree(node) / (total nodes — 1)

由于度数是指与节点相连的边的数量,每个与 Billy Corgan 通过边连接的乐队成员将增加一个度数。

如果 degree(node) = 3(total nodes — 1) = (4–1) = 3,那么 degree centrality = 3/3 = 1

我们可以以类似的方式应用于每个乐队成员。由于他们每个人的度数都是 1,那么 1/3 = .333

解读中介中心性

节点的中介中心性计算为所有最短路径中经过该节点的部分的总和,除以这些节点对之间的最短路径总数。

在我们的例子中,这并不是特别有意义,因为我们有一个小型网络,而且我们仅仅可视化了比利与 Smashing Pumpkins 乐队成员之间的关系,而没有涉及与其他乐队成员及其他可能参与的乐队的关系。

那么我们是如何得出比利·科根在这种情况下的中介中心性呢?一个节点的中介中心性为 1 意味着该节点位于网络中所有其他节点对之间的所有最短路径上。换句话说,它作为网络中不同部分之间的关键桥梁或连接点。

比利·科根与 The Smashing Pumpkins 2008–02–18; CC BY 2.0

当一个节点的中介中心性为 1 时,它意味着在网络内对信息或资源流动的影响和控制程度很高。任何通过网络传递的信息或互动很可能会经过该节点。因此,它可以被视为网络通信中的关键瓶颈或中介。

节点的中介中心性高通常被认为在网络动态中至关重要,因为它们可以控制信息传播,影响决策过程,或作为网络内高效沟通的关键连接点。

需要注意的是,中介中心性的解读应考虑分析网络的背景和特定特征。中介中心性为 1 的意义可能因网络的大小、结构和目的而异。在即将到来的教程中,我们将扩展比利的网络,探索这如何改变他的中介中心性。

🤖 Christine Egan | Medium | LinkedIn | GitHub

更好洞察的社会网络可视化:使用 Python 的 NetworkX 库分析和映射社会关系 — 第二部分

原文:towardsdatascience.com/visualizing-social-networks-for-better-insights-analyzing-and-mapping-social-relationships-with-f4a9cf6b6d57

继续介绍使用 Python 的 NetworkX 库进行社会网络分析的初学者指南

Christine Egan数据科学前沿 Christine Egan

·发布于 数据科学前沿 ·阅读时间 6 分钟·2023 年 6 月 10 日

--

在第一部分,我们探讨了链接分析,特别是社会网络分析 在调查和理解个体与实体之间的关系时。社会网络分析(SNA)是一种特定类型的链接分析,专注于人群和群体及其关系。我们回顾了 SNA 的基本概念,包括节点(代表个体)和边(代表个体之间的连接)。然后,我们讨论了如何利用度中心性和中介中心性等指标,通过比利·科根及其与 Smashing Pumpkins 创始成员的关系这一简单示例来理解社会影响、群体形成和信息流。

图片由 Gordon Johnson 提供,自 Pixabay

在那个例子中,我们保持了网络的小规模和简单性。在本教程中,我们将继续使用 Python 和 NetworkX 来研究比利·科根的影响范围。我们还将扩展比利·科根的网络,使其更复杂,并加深对度中心性中介中心性的理解。在处理这个例子时,我们将讨论上下文,以及如何利用领域知识来最大化社会网络分析的收益。

上下文中的社会网络分析

领域知识和研究是社会网络分析的重要组成部分,因为它们提供了必要的背景、理论框架,以及对塑造社会网络的社会和文化因素的理解。没有这种理解,你有可能得出误导性或不正确的结论,未能准确捕捉社会网络数据的复杂性和细微差别。

在你开始之前……

  1. 你对 Python 有基本的了解吗?如果没有, 从这里开始

  2. 你是否熟悉社会网络分析中的基本概念,比如节点和边,或者中心性等指标?如果没有, 从这里开始**。

收集数据以分析社会网络

那么,我们需要什么样的数据来开始调查比利·科根的影响力范围?让我们从 Smashing Pumpkins 的所有乐队伙伴开始,无论是现任还是前任。

使用维基百科,我们可以获得自 1988 年以来在 Smashing Pumpkins 中演奏的所有音乐家的一个相当可靠的列表。顺便问一下——你知道比利·科根(短暂地)有另一个叫 Zwan 的乐队早期的零年代吗?剧透警告,这并没有一个好的结局。让我们也列出这些人。

然后,打开你喜欢的 IDE,导入相关库,并创建两个列表——一个用于 Smashing Pumpkins,一个用于 Zwan。

描述社会网络中的关系

我们的下一步任务是构建一些元组列表,以表示比利·科根与这些乐队成员之间的关系。我们还需要考虑每个乐队成员与所有其他乐队成员之间的关系。

在图论中,这种关系被称为对称的。如果比利与吉米在一个乐队中,那么吉米也在一个乐队中与比利。

为了实现这一点,我们可以使用 Python 构建一个简单的函数,该函数将接收每个乐队成员列表,并返回所有可能的配对组合。

然后,我们可以应用到每个列表,并结合结果,创建一个包含 Zwan 和 Smashing Pumpkins 所有乐队成员之间关系的元组列表。

输出将类似于以下内容:

[('Billy Corgan', 'James Iha'),
 ('Billy Corgan', 'Jimmy Chamberlin'),
 ('Billy Corgan', 'Katie Cole'),
 ('Billy Corgan', "D'arcy Wretzky"),
 ('Billy Corgan', 'Melissa Auf der Maur'),
 ('Billy Corgan', 'Ginger Pooley'),
 ('Billy Corgan', 'Mike Byrne'),
 ('Billy Corgan', 'Nicole Fiorentino'),
 ('James Iha', 'Jimmy Chamberlin'),
 ('James Iha', 'Katie Cole'),
 ('James Iha', "D'arcy Wretzky"),
 ('James Iha', 'Melissa Auf der Maur'),
 ('James Iha', 'Ginger Pooley'),
 ('James Iha', 'Mike Byrne'),
 ('James Iha', 'Nicole Fiorentino'),
 ('Jimmy Chamberlin', 'Katie Cole'),
 ('Jimmy Chamberlin', "D'arcy Wretzky"),
 ('Jimmy Chamberlin', 'Melissa Auf der Maur'),
 ('Jimmy Chamberlin', 'Ginger Pooley'),
 ('Jimmy Chamberlin', 'Mike Byrne'),
 ('Jimmy Chamberlin', 'Nicole Fiorentino'),
 ('Katie Cole', "D'arcy Wretzky"),
 ('Katie Cole', 'Melissa Auf der Maur'),
 ('Katie Cole', 'Ginger Pooley'),
 ('Katie Cole', 'Mike Byrne'),
 ('Katie Cole', 'Nicole Fiorentino'),
 ("D'arcy Wretzky", 'Melissa Auf der Maur'),
 ("D'arcy Wretzky", 'Ginger Pooley'),
 ("D'arcy Wretzky", 'Mike Byrne'),
 ("D'arcy Wretzky", 'Nicole Fiorentino'),
 ('Melissa Auf der Maur', 'Ginger Pooley'),
 ('Melissa Auf der Maur', 'Mike Byrne'),
 ('Melissa Auf der Maur', 'Nicole Fiorentino'),
 ('Ginger Pooley', 'Mike Byrne'),
 ('Ginger Pooley', 'Nicole Fiorentino'),
 ('Mike Byrne', 'Nicole Fiorentino'),
 ('Billy Corgan', 'Jimmy Chamberlin'),
 ('Billy Corgan', 'Paz Lenchantin'),
 ('Billy Corgan', 'David Pajo'),
 ('Billy Corgan', 'Matt Sweeney'),
 ('Jimmy Chamberlin', 'Paz Lenchantin'),
 ('Jimmy Chamberlin', 'David Pajo'),
 ('Jimmy Chamberlin', 'Matt Sweeney'),
 ('Paz Lenchantin', 'David Pajo'),
 ('Paz Lenchantin', 'Matt Sweeney'),
 ('David Pajo', 'Matt Sweeney')]

接下来,我们可以遍历元组列表,以使用 Network X 生成图形。

这将生成以下图形:

让我们讨论从这个图中可以提取出的两个关键观察点。

  1. Smashing Pumpkins 乐队成员出现在右上角的位置比 Zwan 的成员出现在左下角的地方要复杂,因为 Zwan 的成员较少。

  2. 比利·科根和吉米·钱伯林出现在中心位置,因为他们在两个乐队中都出现过。

接下来,让我们考虑这些观察结果如何反映在度中心性和中介中心性中。

使用 NetworkX 的度中心性和中介中心性

在第一部分中,我们计算了比利·科根和 Smashing Pumpkins 的创始成员的度中心性和中介中心性。为此,我们调用了 NetworkX 中的两种方法,并编写了一个简单的脚本来执行它们。这次,由于我们已经组装了图形,我们可以直接输入图形来计算中心性指标。

这将生成以下输出:

让我们讨论如何解读这些结果。

这张表告诉我们所有乐队成员的度中心性如何?

1. 比利·科根的度中心性得分为 1.000,表示他在 Smashing Pumpkins 和 Zwan 中有最多的联系或合作。他与两个乐队的每个其他成员都有直接联系。

  1. 吉米·查伯林的度中心性得分也是 1.000,这表明他和比利·科根一样,与两个乐队的每个成员都有直接联系。

3. James Iha、Katie Cole、D’arcy Wretzky、Melissa Auf der Maur、Ginger Pooley、Mike Byrne、Nicole Fiorentino、Paz Lenchantin、David Pajo 和 Matt Sweeney 的度中心性得分均为 0.727273,这表明他们在乐队中的联系或合作水平相似。

Jimmy Chamberlin, 约 2014 年 — 来自芝加哥的 swimfinfan,CC BY-SA 2.0 <creativecommons.org/licenses/by-sa/2.0>, 通过维基共享资源

这张表告诉我们所有乐队成员的中介中心性如何?

1. 比利·科根和吉米·查伯林的中介中心性得分也最高,为 0.190909,表明他们可能是乐队成员之间在沟通或合作方面的重要中介或桥梁。

2. 除比利·科根和吉米·查伯林外,乐队成员的中介中心性得分均为零,这表明他们在乐队成员之间的桥接连接中并不重要。

通过领域知识加强推断

虽然中心性指标提供了我们可以推断的数据点,但这些推断仅基于表中提供的信息。

要对比利·科根的影响范围得出更具体的结论,你需要了解九十年代的另类音乐及音乐家,以便对这些乐队成员之间的动态提出完整的假设。

所以如果你是九十年代音乐爱好者,请在评论中告诉我你对这些结果的看法。务必关注第三部分,在那里我们将扩展网络,以便探讨紧密中心性、聚类和社交网络分析中的社区。

如果你想要这个教程的完全注释 Python 脚本,请访问我的GitHub!

👩🏻‍💻 Christine Egan | medium | github | linkedin

可视化反卷积操作

原文:towardsdatascience.com/visualizing-the-deconvolution-operation-8dad71577912?source=collection_archive---------12-----------------------#2023-02-17

对转置卷积操作的详细拆解

Vitalii PogribnyiTowards Data Science Vitalii Pogribnyi

·

关注 发表在 Towards Data Science ·11 分钟阅读·2023 年 2 月 17 日

--

图片由 Markus Spiske 提供,来源于 Unsplash

介绍

转置卷积用于生成图像,尽管它们已经存在一段时间,并且解释得相当清楚——我仍然难以理解它们是如何完成工作的。本文描述了一个简单的实验来说明这个过程。我还包含了一些提高网络性能的技巧。

总体而言,本文描述了几个读者可能感兴趣的话题:

  • 反卷积操作的整体可视化

  • 通过分离更重要的组件来优化网络

  • 解决合成数据集问题

插图的任务是我能想到的最简单的任务:为合成数据构建一个自动编码器。尽管它是合成的,可能会引发一些问题。确实,基于这样的数据训练的模型在真实数据上表现可能不佳。但我们稍后会看到这是为什么以及如何解决这个问题。模型由一个用于编码器的卷积层和一个用于解码器的反卷积(即转置卷积)组成。

以下所有图像和字符均为我自己的。

1. 数据集

数据是看起来像以下内容的一维 Bezier 曲线集合:

数据示例

这是生成数据的代码:

这些曲线包含 15 个点。每条曲线将作为一维数组(而不是为每个点传递[x, y]坐标,只传递[y])输入网络。

每条曲线可以用两个参数来表征,这意味着我们的网络应该能够将任何曲线编码/解码成一个大小为 2 的向量。

2. 方法

这是一个可以用来编码曲线的示例网络:

网络架构

在上图中,输入信号(底部)被分成 3 个 7 像素大小的补丁(通过应用窗口大小为 7 且步幅为 4 的卷积层)。每个补丁被编码成一个大小为 3 的向量,生成一个 3x3 矩阵。然后,这个矩阵被编码成一个大小为 2 的向量;然后在解码器中反向重复这个操作。

网络可以分为两部分。第一部分能够编码/解码曲线的一部分(7 像素的补丁);而第二部分仅处理 3x3 矩阵。这样,我可以分别训练每一部分。我可以做一个只处理 7 像素补丁的小型自动编码器:

简化的网络架构

所以我打算将每个示例分成补丁,并训练网络以编码/解码这些补丁。然后,我将组装这个网络来生成整个曲线。

我不会进一步对这个 3x3 矩阵进行编码,因为这个过程不会带来任何新信息。

3. 网络

使用的模型

我将为编码器和解码器使用独立的模型。它们非常简单:

步幅设置为 4 是因为在“方法”部分的图像中提到,滤波器每次移动 4 像素。由于我们这里只实现了一个阶段,这个步幅完全是可选的;它只会在我们组装一个更大的网络时产生影响。

训练过程

首先,我将设置一组不同种子值的训练。

训练的代码尽可能简单:

这里是这些实验中损失的表现:

图像显示了 10 次实验中不同种子下损失的均值和标准差。

如果我现在将标签与网络输出进行视觉比较,它们看起来如下:

网络评估 — 原始曲线与网络输出的比较

这看起来不错,似乎网络在正常工作,损失值低于 1e-4 是足够的。

接下来,我将说明编码器和解码器在这个示例中的工作原理。

解码器

解码器旨在将代码(3 维向量)转换为曲线补丁。作为反卷积操作,它有一组过滤器,每个过滤器按某些值缩放,然后进行求和;换句话说,过滤器的加权和应该匹配期望的输出。

下面的图像包含恢复曲线的两个示例。左侧的示例是从向量 [0.0, 0.1, 0.2] 解码的,右侧的是 [0.1, 0.1, 0.0]。每个示例都包含顶部的缩放过滤器和底部的未缩放过滤器。

解码器过滤器组合

当然,我们可以一次变化一个向量组件并实时渲染网络输出,形成一个很酷的动画。所以,这里就是:

网络操作的可视化

上述每个动画包含多个图。左下角的点显示输入向量。它的 X 和 Y 坐标以及大小代表输入的第一、第二和第三个组件。右下角的图显示原始过滤器,并在所有动画中保持不变。右上角的图显示缩放后的过滤器和输出。由于只有一个参数在变化,因此只有一个过滤器被缩放,输出与该过滤器匹配。

左上角的图可能是最有趣的,因为它旨在显示输出如何同时依赖于两个组件。图上的每一条曲线代表第三个组件不同值的输出。可以看到在第三个动画中,图形没有移动,只有不同的曲线变得更粗。在前两个动画中,只有中间的曲线保持粗体,因为第三个组件保持为零,但总体上这给出了如果第三个组件发生变化,输出会是什么样的一个概念。

这是所有组件同时变化的情况:

网络操作的可视化

编码器

这个示例中的编码器看起来有点不直观,但无论如何它以某种方式完成了工作。(其质量将在后续章节中进行评估)

编码器组件

左侧展示了原始滤波器,以及一个示例输入。右侧的图显示了这些滤波器应用于示例输入的结果(即每个输入点乘以每个滤波器点)。标签还包含每个滤波器的输出(即滤波器 1 的每个点乘以输入的每个点的总和为 0.02)。

上图中的示例将被编码为一个向量 (0.02, 0.08, -0.08)。解码器将以下面的方式恢复输入:

编码器性能示例

左侧的图显示了解卷积滤波器。右侧的图——每个滤波器乘以其代码向量值以及它们的总和(这也是解码器的输出)。

那么问题是什么?

解决方案似乎有效——网络将其 7 值输入编码成 3 值代码;然后再用低误差解码回来。但我看到两个改进的可能性:

  1. 当网络使用不同的种子进行训练时,滤波器差异很大。这意味着网络的灵活性过大,我们可以对其进行约束。

  2. 编码器的鲁棒性。我们如何确保编码器能适用于各种真实数据?

为了说明第一种情况,我将简单地绘制通过不同种子训练获得的滤波器:

解码器滤波器

显然,我们需要考虑滤波器的符号和顺序:第一幅图中的滤波器 3 和第二幅图中的滤波器 1 是相同的。滤波器集合,考虑符号和顺序的补偿,如下所示:

解码器滤波器,重新组织

滤波器在这里明显变化很大。

3. 改进

代码噪声

不同的滤波器集给出相同结果的事实表明滤波器可能受到约束。约束滤波器的一种方法是对其进行优先级排序。类似于 PCA 技术,分离出编码最多信息的滤波器和编码少量细节的滤波器。这可以通过向编码图像添加噪声来实现:

上图中,左侧的图像展示了一个传统的自编码器:输入被编码到一个 2D 平面上;然后被解码回来。网络从中间图像的 2D 平面解码一个稍微偏移的点。这迫使网络将类似的图像编码为在平面上保持接近的点。右侧的图像展示了当解码点可能在 Y 轴上漂移超过 X 轴时的情况。这迫使网络将最重要的特征编码到 X 分量中,因为它的噪声较少。

这是在代码中实现的相同概念:

重新运行实验后,我将获得一组更一致的滤波器:

经过噪声训练后的编码器滤波器

如果我像之前一样补偿符号和顺序,在“问题是什么”部分:

编码器在经过噪声训练后的滤波器——重新组织

可以清楚地看到,一些滤波器在一侧是曲线的,在另一侧是锐利的,而一个组件在中间是曲线的。滤波器 2 和 3 似乎同等重要,因为它们有时被编码在第一个组件中,有时被编码在第二个组件中。然而,第三个滤波器的幅度较小,并且总是被编码在最嘈杂的组件中,这表明它的重要性较低。

噪声的影响可以通过比较模型在将编码向量的不同组件归零时的表现来检查:

模型性能的比较,禁用其一个组件

上图显示了通过归零第一个、第二个或第三个组件而导致的损失变化,对于左侧的噪声模型和右侧的原始模型。对于原始模型,禁用每个组件都会导致相对相同的损失下降。

下面是视觉上的比较。请查看图中的模型输入和输出。从左到右:完整模型;禁用滤波器 1 的模型;禁用滤波器 2 的模型;禁用滤波器 3 的模型。

经过噪声训练的模型:

网络评估,原始曲线与网络输出的比较——对于具有一个组件禁用的模型,从左到右:完整模型,没有禁用的组件;组件 1 禁用;组件 2 禁用;组件 3 禁用。

对于原始模型:

网络评估,原始曲线与网络输出的比较——对于具有一个组件禁用的模型,从左到右:完整模型,没有禁用的组件;组件 1 禁用;组件 2 禁用;组件 3 禁用。

经过噪声训练的模型在仅禁用噪声组件时,误差明显较小。

输入噪声

现在我们再来看一下编码器滤波器。它们一点也不平滑,而且有些看起来彼此相似。这很奇怪,因为编码器的目的是发现输入的差异,而你不能通过一组相似的滤波器发现差异。网络是如何做到的?答案是我们的合成数据集过于完美,无法训练出正确的滤波器。网络可以通过一个点轻松分类输入:

相似点的示例

在上述每个图中,都有一个较大图上的曲线示例(称为“原始”),以及 3 个与这个原始示例具有类似点的示例。这些示例本身不同,但鉴于点上的精确值(例如 -0.247 或 -0.243),网络能够对整个示例做出决策。

这可以通过向原始输入中添加噪声来轻松修复。

重新训练模型后,我得到了平滑的滤波器:

编码器组件——添加噪声后

可以看到,滤波器 1,即噪声最强的一个,比其他滤波器增长得更大。我的猜测是,它试图让其输出大于噪声,以减小噪声的影响。但由于我有一个 tanh 激活函数,它的输出不能大于 1,所以噪声仍然存在。

4. 完整模型

组装

既然我们已经有了模型的一个工作组件,我们可以多次应用它,使其适用于对整个 15 点曲线的编码/解码。这个没有什么特别之处,我只需要避免将示例切成小块:

这将给我以下输出:

重叠问题

好吧,也许我需要更改一些东西。问题是,反卷积会将图像的重叠部分相加。所以下面图中的这些部分被重复计算:

重叠的反卷积窗口

有一个简单的解决方法:我可以将输出重叠的滤波器的权重减半:

经过这种操作后,我会得到以下输出:

带有重叠的反卷积——更新版

或者,我可以逐渐减少滤波器的值,从中心附近的小值开始,然后在边缘强烈减少:

这会导致输出更加平滑:

带有重叠的反卷积——最终版

这会导致另一个问题——边界点没有重叠的对象,解码图像与实际情况不同。对此有几种可能的解决方案。例如,给编码图像添加填充,使得边界也被编码,或忽略这些边界(也许还可以将它们排除在损失计算之外)。我将在这里停下,因为进一步的改进超出了本文的范围。

结论

这个简单的示例说明了反卷积如何工作,以及如何利用噪声(有时是不同幅度的噪声)来训练神经网络。

所描述的方法在较大的网络上表现良好,噪声幅度成为一个需要实验的超参数。该方法可能不适用于 ReLu 激活函数:它们的输出可能会比噪声幅度大得多,从而使噪声失效。

可视化多重共线性对多重回归模型的影响

原文:towardsdatascience.com/visualizing-the-effect-of-multicollinearity-on-multiple-regression-model-8f323ef542a9

使用 Python 进行数据可视化,解释多重共线性对多重回归的影响

Boriharn KTowards Data Science Boriharn K

·发布在Towards Data Science ·11 分钟阅读·2023 年 6 月 12 日

--

图片由Alex提供,发布在Unsplash

什么是多重共线性?

在多重回归中,多重共线性发生在预测变量(自变量)与模型中的一个或多个其他预测变量高度相关时。

为什么这很重要?

### Multiple regression equation:

Y = β₀ + β₁X₁ + β₂X₂ + ... + βᵢXᵢ + ε

理论上,如我们在方程中所见,多重回归使用多个预测变量来预测因变量的值。

顺便提一下,多重回归通过确定在保持其他预测变量不变的情况下,预测变量单位均值变化对因变量的影响来工作。

如果一个预测变量与其他变量高度相关,那么在不改变其他变量的情况下很难改变它。

多重共线性的影响

简单来说,多重共线性会影响模型系数。数据的微小变化可能会影响系数估计。因此,解释每个自变量的作用变得困难。

本文将通过数据可视化解释和展示这一现象。在开始之前,让我们讨论如何判断模型是否存在多重共线性。

本文中的一个结果示例。图像来源:作者。

如何检测多重共线性?

### VIF (Variance Inflation Factor) equation:

VIF = 1/(1 - Rᵢ²)

我们可以使用 VIF(方差膨胀因子)来估计由于多重共线性而导致的回归系数方差的膨胀程度。

计算是通过将一个预测变量与其他预测变量回归以获得 R 平方值完成的。然后,获得的 R 平方值将用于计算 VIF 值。方程中的'i'代表预测变量。

可以使用以下标准来解释结果:

#1 : not correlated
#1–5 : moderately correlated
#> 5 : highly correlated

现在我们完成了解释部分。让我们继续到模型创建部分。

多重回归模型

开始为绘图准备多重回归模型。首先,我们将从数据集中创建两个模型;一个具有中等相关变量,另一个具有高度相关变量。

然后我们将稍微修改数据,看看哪个模型会受到更大的影响。首先导入库。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

%matplotlib inline

获取数据

例如,这篇文章将使用汽车数据数据集,该数据集具有公有领域许可。可以通过Seaborn库的seaborn.load_dataset()函数自由直接下载。

数据集包含 1970 年至 1982 年间在美国、欧洲和日本的 392 辆汽车的价格和特征。有关数据集的更多信息可以在这里找到:链接

data = sns.load_dataset('mpg')
data.dropna(inplace=True)       #remove null rows
data.head()

进行探索性数据分析以了解数据集总是一个好主意。

data.describe()

列中的范围(最大值 - 最小值)差异较大。因此,执行标准化有助于后续解释系数。

data = data.iloc[:,0:-2]    # select columns

from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
df_s = scaler.fit_transform(data)
df = pd.DataFrame(df_s, columns=data.columns)
df.head()

接下来绘制一个热图以展示变量之间的相关性。

plt.figure(figsize=(9, 6))
sns.heatmap(df.corr(), cmap='coolwarm', annot=True)
plt.show()

结果显示有些变量与其他变量高度相关。如果每个预测变量都被放入多重回归模型来预测'mpg'值,多重共线性将影响模型。

计算 VIF 值

这可以通过计算Statsmodels库中的 VIF 值来快速证明。

from statsmodels.stats.outliers_influence import variance_inflation_factor as vif

vif_data = pd.DataFrame()
vif_data["feature"] = df.columns
# calculating VIF for each feature
vif_data["VIF"] = [vif(df.values, i) for i in range(len(df.columns))]

print(vif_data)

一些 VIF 值相当高(> 5),可以解释为高度相关。如果我们直接将每个预测变量放入多重回归模型中,该模型可能会遭受多重共线性问题。

接下来,将仅选择一些预测变量。这篇文章将使用两个模型:一个包含中等相关的变量,另一个包含高度相关的变量。

第一个多重回归模型使用'气缸数'和'加速度'来预测'mpg',而第二个模型使用'气缸数'和'位移'。让我们再次计算 VIF 值。

df1 = df[['mpg', 'cylinders', 'acceleration']]
df2 = df[['mpg', 'cylinders', 'displacement']]

# VIF dataframe1
vif_data1 = pd.DataFrame()
vif_data1['feature'] = df1.columns
vif_data1['VIF'] = [vif(df1.values, i) for i in range(len(df1.columns))]
print('model 1')
print(vif_data1)

# VIF dataframe2
vif_data2 = pd.DataFrame()
vif_data2['feature'] = df2.columns
vif_data2['VIF'] = [vif(df2.values, i) for i in range(len(df2.columns))]
print('model 2')  
print(vif_data2)

两个模型的 VIF 值。图片由作者提供。

这两个模型之间的区别在于将变量从'加速度'改为'位移'。然而,可以注意到第一个模型中的 VIF 值都没有超过 5,而第二个模型的 VIF 值则相对较高,超过了 10。

创建多重回归模型

我们将使用OLS函数来自 statsmodels 库创建一个多重回归模型。

import statsmodels.api as sm
y1 = df1[['mpg']]
X1 = df1[['cylinders', 'acceleration']]

lm1 = sm.OLS(y1, X1)
model1 = lm1.fit()
model1.summary()

具有中等相关变量的多重回归模型的总结表。图片由作者提供。

绘制模型

从获得的模型中,我们将定义一个函数,在网格上运行模型,以便在下一步中使用。

def run_model(v1, v2, pd_):
    mesh_size = 0.02
    x_min, x_max = pd_[[v1]].min()[0], pd_[[v1]].max()[0] 
    y_min, y_max = pd_[[v2]].min()[0], pd_[[v2]].max()[0] 
    xrange = np.arange(x_min, x_max, mesh_size)
    yrange = np.arange(y_min, y_max, mesh_size)
    xx, yy = np.meshgrid(xrange, yrange)
    return xx, yy, xrange, yrange

这部分非常有趣。让我们使用Plotly库绘制模型,它可以轻松创建交互式图表。因此,我们可以与可视化进行互动,比如缩放或旋转。

import plotly.express as px
import plotly.graph_objects as go
from sklearn.svm import SVR

#run and apply the model
xx1, yy1, xr1, yr1 = run_model('cylinders', 'acceleration', X1)
pred1 = model1.predict(np.c_[xx1.ravel(), yy1.ravel()])
pred1 = pred1.reshape(xx1.shape)

# plot the result
fig = px.scatter_3d(df1, x='cylinders', y='acceleration', z='mpg')
fig.update_traces(marker=dict(size=5))
fig.add_traces(go.Surface(x=xr1, y=yr1, z=pred1, name='pred1'))
fig.show()

具有中等相关变量的多重回归模型。图片由作者提供。

我们可以对第二个存在多重共线性问题的模型执行相同的过程。

y2 = df2[['mpg']]
X2 = df2[['cylinders', 'displacement']]

lm2 = sm.OLS(y2, X2)
model2 = lm2.fit()
model2.summary()

多重回归模型与多重共线性的总结表。图片由作者提供。

#run and apply the model
xx2, yy2, xr2, yr2 = run_model('cylinders', 'displacement', X2)
pred2 = model2.predict(np.c_[xx2.ravel(), yy2.ravel()])
pred2 = pred2.reshape(xx2.shape)

# plot the result
fig = px.scatter_3d(df2, x='cylinders', y='displacement', z='mpg')
fig.update_traces(marker=dict(size=5))
fig.add_traces(go.Surface(x=xr2, y=yr2, z=pred2, name='pred2'))
fig.show()

具有高度相关变量的多重回归模型。图片由作者提供。

修改数据集

如前所述,数据中的小修改可能会影响系数估计。为了证明这一点,我们将随机选择一行并更改其值。例如,它们将乘以 1.25。

然后,我们可以进行相同的过程,并将新的和原始的多重回归模型绘制在同一个图中以查看结果。

# randomly modify a row in the dataframe 
from random import *
x = randint(1, len(df))
mod_list = [i*1.25 for i in df.iloc[x,:]]   #multiply by 1.25
df_m = df.copy()
df_m.iloc[x] = mod_list
df_m

计算 VIF 值

从修改后的数据集中计算 VIF 值以比较差异。

df_m1 = df_m[['mpg', 'cylinders', 'acceleration']]
df_m2 = df_m[['mpg', 'cylinders', 'displacement']]

# VIF dataframe1
vif_data1 = pd.DataFrame()
vif_data1['feature'] = df_m1.columns
vif_data1['VIF'] = [vif(df_m1.values, i) for i in range(len(df_m1.columns))]
print('model m1')
print(vif_data1)

###
# VIF dataframe2
vif_data2 = pd.DataFrame()
vif_data2['feature'] = df_m2.columns
vif_data2['VIF'] = [vif(df_m2.values, i) for i in range(len(df_m2.columns))]
print('model m2')  
print(vif_data2)

从原始模型和修改后的模型计算的 VIF 值。图片由作者提供。

从修改后的数据集中计算的新 VIF 值略有变化。两个模型保持相同的条件:第一个模型的预测变量为中等相关,第二个模型的预测变量则为高度相关。

创建多重回归模型

为了比较模型系数的变化,让我们从新数据集中构建模型并进行绘制。

y_m1 = df_m1[['mpg']]
X_m1 = df_m1[['cylinders', 'acceleration']]

lm_m1 = sm.OLS(y_m1, X_m1)
model_m1 = lm_m1.fit()
model_m1.summary()

中等相关变量的模型总结:原始模型和修改后的模型,分别如图所示。图像由作者提供。

接下来,对具有高度相关预测变量的第二个模型进行相同的处理。

y_m2 = df_m2[['mpg']]
X_m2 = df_m2[['cylinders', 'displacement']]

lm_m2 = sm.OLS(y_m2, X_m2)
model_m2 = lm_m2.fit()
model_m2.summary()

高度相关变量模型的总结:原始模型和修改后的模型,分别如图所示。图像由作者提供。

从上表来看,它们的系数变化似乎很小。顺便提一下,这种情况发生是因为我们随机修改了数据集中的一行。这还不够,也过早地假设多重共线性影响模型系数是不成立的。

根据目前的概念和代码,for loop函数将在 Python 中应用于逐行修改每个值。然后,比较与原始模型的系数绝对变化。

首先定义一个函数来比较系数值。

def compare_cef(base_m, mod_m, col):
    val_base = base_m.summary().tables[1].as_html()
    ml = pd.read_html(val_base, header=0, index_col=0)[0]

    val_diff = mod_m.summary().tables[1].as_html()
    ml_m = pd.read_html(val_diff, header=0, index_col=0)[0]

    df_ = pd.DataFrame(abs(ml.iloc[:,0] - ml_m.iloc[:,0]))
    df_.rename(columns={'coef': 'r '+str(col+1)}, inplace=True)
    return df_

使用for loop函数一次修改一行。

keep_df1, keep_df2 = [], []
for n in range(len(df)):
    mod_list = [i*1.25 for i in df.iloc[n,:]]
    df_m = df.copy()
    df_m.iloc[n] = mod_list

    df_m1 = df_m[['mpg', 'cylinders', 'acceleration']]
    y_m1, X_m1 = df_m1[['mpg']], df_m1[['cylinders', 'acceleration']]
    lm_m1 = sm.OLS(y_m1, X_m1)
    mdl_m1 = lm_m1.fit()

    df_m2 = df_m[['mpg', 'cylinders', 'displacement']]
    y_m2, X_m2 = df_m2[['mpg']], df_m2[['cylinders', 'displacement']]
    lm_m2 = sm.OLS(y_m2, X_m2)
    mdl_m2 = lm_m2.fit()

    df_diff1 = compare_cef(model1, mdl_m1, n)
    df_diff2 = compare_cef(model2, mdl_m2, n)
    keep_df1.append(df_diff1)
    keep_df2.append(df_diff2)

df_t1 = pd.concat(keep_df1, axis=1)
df_t2 = pd.concat(keep_df2, axis=1)
df_t = pd.concat([df_t1, df_t2], axis=0)
df_t

使用热力图可视化获得的 DataFrame。

plt.figure(figsize=(16,2.5))
sns.heatmap(df_t, cmap='Reds')
plt.xticks([])
plt.show()

热力图显示模型系数的绝对差异。图像由作者提供。

从热力图绘制中可以看出,前两行显示了中等相关变量模型在数据轻微变化前后的系数绝对变化。

最后两行比较了高度相关变量模型在数据轻微修改前后的系数绝对变化。

可以解释为,当数据发生变化时,具有高度相关预测变量的模型系数趋向于更加不稳定,而具有中等相关预测变量的模型则受到的影响较小。

绘制多重回归模型

为了可视化系数的变化,以一个示例,我将修改数据集中的一行,创建一个新模型,并将其与原始模型进行比较。新模型将使用'viridis'色盘(黄绿),而原始模型则用默认颜色(橙蓝)绘制。

如果你想手动选择和修改其他行,请更改下面的代码。

x = 6     #select row number
mod_list = [i*1.25 for i in df.iloc[x,:]]
df_m = df.copy()
df_m.iloc[x] = mod_list

y_m1 = df_m[['mpg']]
X_m1 = df_m[['cylinders', 'acceleration']]
lm_m1 = sm.OLS(y_m1, X_m1)
model_m1 = lm_m1.fit()

y_m2 = df_m[['mpg']]
X_m2 = df_m[['cylinders', 'displacement']]
lm_m2 = sm.OLS(y_m2, X_m2)
model_m2 = lm_m2.fit()

运行并绘制中等相关预测变量的多重回归模型。

# run the model
pred_m1 = model_m1.predict(np.c_[xx1.ravel(), yy1.ravel()])
pred_m1 = pred_m1.reshape(xx1.shape)

# plot the result
fig = px.scatter_3d(df_m, x='cylinders', y='acceleration', z='mpg')
fig.update_traces(marker=dict(size=5))
fig.add_traces(go.Surface(x=xr1, y=yr1, z=pred1, name='pred'))
fig.add_traces(go.Surface(x=xr1, y=yr1, z=pred_m1, name='pred_m1',
                          colorscale = 'viridis_r'))
fig.show()

绘制中等相关预测变量的模型。图像由作者提供。

可以看到,两种模型重叠,因为两个平面的颜色在结果中混合在一起。最后,对中等相关预测变量的模型进行相同的处理。

# run the model
pred_m2 = model_m2.predict(np.c_[xx2.ravel(), yy2.ravel()])
pred_m2 = pred_m2.reshape(xx2.shape)

# plot the result
fig = px.scatter_3d(df_m, x='cylinders', y='displacement', z='mpg')
fig.update_traces(marker=dict(size=5))
fig.add_traces(go.Surface(x=xr2, y=yr2, z=pred2, name='pred'))
fig.add_traces(go.Surface(x=xr2, y=yr2, z=pred_m2, name='pred_m2',
                          colorscale = 'viridis_r'))
fig.show()

绘制具有多重共线性的模型。图像由作者提供。

结果显示,两个模型并没有完全重叠。它们相互交叉,模型之间产生了一个小的间隙。

请注意,这些图表是通过随机修改数据集中的一行进行选择的。第一个模型并不完全没有多重共线性。它仍然有中等相关的预测变量。从热图中也可以看出,在某些情况下,它受到了变化的影响。然而,与第二个模型相比,这种变化造成的后果较少。

总结

本文通过比较两个模型,一个具有中等相关预测变量,另一个具有高度相关预测变量,应用数据可视化来表达多重共线性对多元回归模型的影响。同时,也进行了修改原始数据的操作,以查看哪些模型在数据的小变化中受影响更大。

结果显示,模型中具有高度相关预测变量的情况越多,模型系数在数据不稳定变化时受影响的程度越大。因此,解释每个存在多重共线性问题的模型中的预测变量可能会变得困难。

这些是我认为你可能感兴趣的数据可视化文章:

  • 8 种使用 Python 处理多个时间序列数据的可视化方式 (链接)

  • 9 种比条形图更引人注目的 Python 可视化方式 (链接)

  • 7 种使用 Python 表达排名随时间变化的可视化方式 (链接)

  • 大逃杀 — 7 种用于互动金融图表的 Python 库比较 (链接)

参考文献

直观地展示维度诅咒的真实程度

原文:towardsdatascience.com/visualizing-the-full-extent-of-the-curse-of-dimensionality-5556ff6852bb?source=collection_archive---------6-----------------------#2023-06-29

使用蒙特卡洛方法来直观展示具有非常多特征的观察值的行为

Florin AndreiTowards Data Science Florin Andrei

·

关注 发表在 Towards Data Science ·10 min read·2023 年 6 月 29 日

--

想象一个数据集,由若干观察值组成,每个观察值都有 N 个特征。如果你将所有特征转换为数值表示,你可以说每个观察值是在一个 N 维空间中的一个点。

当 N 较低时,点之间的关系就是你直观上所期望的样子。但有时 N 会变得非常大——例如,如果你通过独热编码创建了很多特征等。在 N 的非常大值下,观察值的行为就像是稀疏的,或者它们之间的距离比你期望的要大。

这个现象是真实的。随着维度 N 的增加,而其他条件保持不变,包含你观察的 N-体积确实会在某种意义上增加(或者至少自由度变得更大),观察之间的欧几里得距离也会增加。点的分布实际上会变得更加稀疏。这是维度诅咒的几何基础。模型和技术在数据集上的表现会受到这些变化的影响。

如果特征数量非常大,很多事情可能会出错。特征比观察值多是模型在训练中过拟合的典型设置。在这样的空间中进行任何暴力搜索(例如 GridSearch)变得效率更低——你需要更多的试验才能覆盖相同的线性区间限制。一个微妙的效应会影响任何基于距离或邻近度的模型:随着维度的增长到非常大的值,如果你考虑观察中的任何一点,所有其他点似乎都远离,并且几乎是等距离的——由于这些模型依赖于距离来完成工作,距离差异的平衡使得它们的工作变得更加困难。例如,如果所有点似乎几乎等距离,聚类效果不会很好。

出于这些原因,还有更多原因,创建了诸如 PCA、LDA 等技术——旨在远离具有非常多维度的空间的特殊几何,并将数据集精炼到与其中实际信息更兼容的维度数。

直观上很难感知这个现象的真正规模,而超过 3 维的空间极其难以可视化,因此我们来做一些简单的 2D 可视化来帮助我们的直觉。维度如何成为问题的几何基础就是我们要在这里可视化的内容。如果你以前没有见过这些结果,可能会感到惊讶——高维空间的几何远比典型直觉所能建议的要复杂得多。

体积

考虑一个大小为 1 的正方形,位于原点。然后在正方形中内切一个圆。

一个内切于正方形的圆

这是 2 维的设置。现在考虑一般的 N 维情况。在 3 维中,你有一个内切于立方体的球体。再往上,你有一个内切于 N-立方体的 N-球体,这是最一般的描述方式。为了简化,我们将这些对象称为“球体”和“立方体”,不论它们有多少维度。

立方体的体积是固定的,总是 1。问题是:当维度 N 变化时,球体的体积会发生什么?

我们通过实验来回答这个问题,使用蒙特卡洛方法。我们将生成大量点,这些点在立方体内均匀但随机分布。对于每个点,我们计算它到原点的距离——如果该距离小于 0.5(球体的半径),那么这个点就在球体内部。

随机点

如果我们将球体内部的点数除以总点数,这将近似球体体积和立方体体积的比例。由于立方体的体积为 1,比例将等于球体的体积。当总点数较大时,近似值会更好。

换句话说,比例inside_points / total_points将近似球体的体积。

代码相当直接。由于我们需要很多点,必须避免显式循环。我们可以使用 NumPy,但它仅支持 CPU 并且是单线程的,因此速度较慢。潜在的替代方案:CuPy(GPU)、Jax(CPU/GPU)、PyTorch(CPU/GPU)等。我们将使用 PyTorch——但 NumPy 代码看起来几乎相同。

如果你跟随嵌套的torch语句,我们生成 1 亿个随机点,计算它们到原点的距离,统计在球体内的点数,并将点数除以总点数。ratio数组将包含不同维度中球体的体积。

可调参数设置为 24 GB 内存的 GPU——如果你的硬件不同,请调整这些参数。

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
# force CPU
# device = 'cpu'

# reduce d_max if too many ratio values are 0.0
d_max = 22
# reduce n if you run out of memory
n = 10**8

ratio = np.zeros(d_max)

for d in tqdm(range(d_max, 0, -1)):
    torch.manual_seed(0)
    # combine large tensor statements for better memory allocation
    ratio[d - 1] = (
        torch.sum(
            torch.sqrt(
                torch.sum(torch.pow(torch.rand((n, d), device=device) - 0.5, 2), dim=1)
            )
            <= 0.5
        ).item()
        / n
    )

# clean up memory
torch.cuda.empty_cache()

让我们来可视化结果:

球体的体积

N=1 是简单的:“球体”和“立方体”都是线段,它们是相等的,所以“球体”的“体积”是 1。对于 N=2 和 N=3,你应该记住高中几何的结果,并注意到这个模拟非常接近实际值。

但随着 N 的增加,会发生非常戏剧性的变化:球体的体积急剧下降。当 N=10 时,它已经接近 0,并且在 N 约为 20 之后,它会低于此模拟的浮点精度。超过这一点,代码计算球体的体积为 0.0(这只是一个近似值)。

>>> print(list(ratio))
[1.0, 0.78548005, 0.52364381, 0.30841056, 0.16450286, 0.08075666, 0.03688062, 0.015852, 0.00645304, 0.00249584, 0.00092725, 0.00032921, 0.00011305, 3.766e-05, 1.14e-05, 3.29e-06, 9.9e-07, 2.8e-07, 8e-08, 3e-08, 2e-08, 0.0]

一种解释是:对于较大的 N 值,几乎整个立方体的体积都集中在角落中。与之相比,包含球体的中心区域变得微不足道。在高维空间中,角落变得非常重要。大部分体积“迁移”到角落。这种变化随着 N 的增加极其迅速。

另一种看法:球体是原点的“邻域”。随着 N 的增加,点会从那个邻域中消失。原点实际上并没有特别之处,因此原点的邻域发生的情况,必须发生在所有邻域中。 “邻域”的概念经历了巨大的变化。随着 N 的增加,邻域会变得空旷。

我几年前第一次运行了这个模拟,我清楚地记得这个结果是多么震惊——当 N 增加时,球体的体积迅速下降到 0。检查代码后没有发现错误,我的反应是:保存工作,锁定屏幕,出去散步,思考刚才看到的内容。😃

线性距离

让我们计算立方体的对角线作为 N 的函数。这是很简单的,因为对角线实际上是sqrt(N),所以代码过于简单,不需要在这里展示。这些是结果:

对角线长度

再次,对于 N=2 和 N=3,你应该能从几何学中识别出结果(正方形和普通三维立方体的对角线)。但随着 N 的增加,对角线也会增加,其增长是无限的。

这可能听起来非常违反直觉,但即使立方体的边长保持不变(等于 1),其对角线也可以随着 N 的增加而无限变大。已经对于 N=1000,对角线长度约为 32。如果立方体的边长是 1 米,那么在非常多维度的空间中,立方体的对角线长度将达到 1 公里。

即使沿边的距离保持不变,对角线也会无限增长,与维度数量一起增长。

每次向空间中添加一个新维度时,更多的边、面等就会出现,角落区域的配置变得更加复杂,具有更多的自由度,对角线的测量会稍微长一点。

观测之间的距离

观测点或点之间的距离怎么样?假设我们生成固定数量的随机点,然后计算任意两个点之间的平均距离,以及任何点到最近邻居的平均距离。所有点始终都包含在立方体中。随着 N 的增加,平均距离会发生什么变化?让我们再运行一次模拟。

请注意内存管理的保守方法。这很重要,因为这里使用的数据结构相当大。

n_points_d = 10**3
# how many pairs of points are there
dist_count = n_points_d * (n_points_d - 1) / 2
# we use the full pair-wise matrix of distances,
# so each distance will be counted twice
dist_count = 2 * dist_count
d_max = d_max_diag

avg_dist = np.zeros(d_max)
avg_dist_nn = np.zeros(d_max)

for d in tqdm(range(d_max, 0, -1)):
    torch.manual_seed(0)
    # generate random points
    point_coordinates = torch.rand((n_points_d, d), device=device)
    # compute differences of point coordinates on all axes
    coord_diffs = point_coordinates.unsqueeze(1) - point_coordinates
    del point_coordinates
    # square the coordinate differences
    diffs_squared = torch.pow(coord_diffs, 2)
    del coord_diffs
    # compute distances between any 2 points
    distances_full = torch.sqrt(torch.sum(diffs_squared, dim=2))
    del diffs_squared
    # compute average distance between points
    avg_dist[d - 1] = torch.sum(distances_full).item() / dist_count
    # compute distances to nearest neighbors
    distances_full[distances_full == 0.0] = np.sqrt(d) + 1
    distances_nn, _ = torch.min(distances_full, dim=0)
    del distances_full
    # compute average distance to nearest neighbors
    avg_dist_nn[d - 1] = torch.mean(distances_nn).item()
    del distances_nn

torch.cuda.empty_cache()

我们在这里使用的点数远少于此(仅 1000 个),因为主要数据结构的大小随着增加,因此如果生成太多点,我们很快就会耗尽内存。即便如此,近似结果应该足够接近实际值。

这是任何两个点之间的平均距离,基于 1000 个点,作为 N 的函数:

点之间的平均距离

对于小的 N 值,平均距离大约是 0.5 或 1。然而,随着 N 的增加,平均距离开始增长,当 N=2000 时已经接近 18。增长是显著的。

这是到最近邻居的平均距离,作为 N 的函数:

到最近邻居的平均距离

增加的效果更为显著,因为当 N 低于 10 时,值相当微小,点在低维空间中挤在一起。对于大的 N 值,最近邻的平均距离实际上接近任何两个点之间的平均距离——换句话说,临近空旷的情况主导了测量结果。

距离比率

这就是为什么我们一开始说在高维空间中点变得几乎等距——平均距离和最短距离变得几乎相同。这里有来自模拟的证据,以及对现象强度的直观理解。

随着维度 N 的增加,所有点彼此逐渐远离,即使它们的坐标被限制在相同的狭窄范围(-0.5, +0.5)。通过仅仅增加更多维度,点的群体变得越来越稀疏。当维度从几单位增加到几千单位时,这种增加跨度达到几个数量级。这是一个非常大的增加。

结论

维度诅咒是一个真实的现象,其基础在于 N 维空间的几何。

在其他条件相同的情况下,当你增加维度(或特征)数量时,点(或观测值)会迅速远离彼此。实际上,虽然轴上的线性间隔保持不变,但这里的空间变得更大了。所有邻域都变得空旷,每个点最终都孤立地坐在一个高维空间中。

这应该提供一些直观的理解,即一些技术(如聚类、各种模型等)在特征数量大幅变化时表现不同。少量观测值结合大量特征可能会导致次优结果——尽管维度诅咒不是唯一原因,但它可能是原因之一。

一般来说,观测值的数量应该“跟上”特征的数量——具体规则依赖于许多因素。

如果没有其他,这篇文章应该提供了一个对高维空间特性的直观概述,这些特性难以可视化。一些趋势极为强烈,现在你应该对它们的强度有一些了解。

本文中使用的所有代码都在这里:

[## misc/curse_dimensionality_article/n_sphere.ipynb 在 master · FlorinAndrei/misc

随机内容。通过在 GitHub 上创建一个账户来贡献于 FlorinAndrei/misc 的开发。

github.com](https://github.com/FlorinAndrei/misc/blob/master/curse_dimensionality_article/n_sphere.ipynb?source=post_page-----5556ff6852bb--------------------------------)

本文中使用的所有图像都是作者创作的(见上面的代码链接)。

使用 Python 地图可视化贸易流量 — 第一部分:双向贸易流量地图

原文:towardsdatascience.com/visualizing-trade-flow-in-python-maps-part-i-bi-directional-trade-flow-maps-639f39c19bba?source=collection_archive---------4-----------------------#2023-12-16

Himalaya Bir ShresthaTowards Data Science Himalaya Bir Shrestha

·

关注 发表在 Towards Data Science ·7 分钟阅读·2023 年 12 月 16 日

--

商品和服务的交换以及它们相应的价值是我们日常生活中的复杂部分。同样,国家之间也会进行各种类型的贸易关系,交换产品和服务,如电力、能源商品、原材料、加工品、旅游等。理解国家之间的贸易流动(进出口)对于评估一个国家的收入和支出、经济实力、供应安全以及国家之间的关系性质至关重要。

在这个两部分系列中,我将分享如何使用 Python 将国家之间的贸易流动可视化在地图上。本系列的第一部分将重点介绍可视化双向(进口和出口)贸易流动。第二部分将重点介绍可视化净贸易流动。我将使用一个假设产品的虚拟数据集来进行这种可视化。我将以我的国家和地区(尼泊尔/南亚)作为演示的例子。让我们开始吧。

照片由GeoJango Maps提供,发布在Unsplash上。

查找箭头的坐标

在贸易流动地图中,我的目标是表示国家之间的双向贸易关系。例如,从尼泊尔到印度的出口将由第一个箭头(A1-A2)表示,从印度到尼泊尔的进口将由第二个箭头(A3-A4)表示。这样,每对国家关系将需要四个坐标点来定义箭头的起点和终点,以分别表示出口和进口。

尽管也可以假设一个可以自动检测到的坐标(例如,国家几何形状的中心点),我打算在地图上标记这些点并逐一获取其坐标。为此,可以在类似 Google Earth 的应用程序中创建一个项目,导出 KML 文件,并通过转换器提取坐标(例如,MyGeodata Cloud网站上的 GIS 数据转换器)。

Keyhole Markup Language (KML)是一种用于在应用程序中显示地理数据的文件格式,例如 Google Earth。它使用基于标签的结构,具有嵌套的元素和属性,并基于 XML 标准(Google, 2023)。

数据

我的输入数据结构如下图所示。它包含了五种不同的邻国之间的贸易关系:尼泊尔-印度,尼泊尔-孟加拉国,尼泊尔-中国,印度-巴基斯坦,以及印度-斯里兰卡。对于每对国家,有四个坐标点用于表示两个箭头的起点和终点。Value1 表示从 Country1 到 Country2 的出口。Value2 表示 Country1 从 Country2 的进口。目标是将这种关系在 Python 地图中展示出来。

贸易流动地图的数据输入。图片由作者提供。

我将上述数据读入 pandas dataframe df。此外,我创建了包含每对国家之间出口和进口量的字典对象,例如transfers,以及包含第一个箭头起点坐标的字典对象startarrow1_dict

创建必要的字典对象。图片由作者提供。

代码描述

在本节中,我将描述用于可视化贸易流图的代码。我将主要使用 matplotlib 和 cartopy 包。我还使用了相同的包来可视化全球表面温度异常中的全球表面温度异常。

  1. 导入所需包

我从导入主要的必需包和依赖项开始,如下所示:

import cartopy.crs as ccrs
import cartopy.io.shapereader as shpreader

import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from matplotlib import colormaps
from matplotlib.colors import Normalize
from matplotlib.cm import ScalarMappable

import numpy as np
import pandas as pd
import os

2. 读取形状文件

作为形状文件,我使用了 Natural Earth Vector。矢量文件可以直接通过 cartopy 包的 shapereader 模块读取。

# get the country border file (10m resolution) and extract
shpfilename = shpreader.natural_earth(
                           resolution=”10m”,
                           category=”cultural”,
                           name=”admin_0_countries”,
                          )
reader = shpreader.Reader(shpfilename)
countries = reader.records()

使用名为 Fiona 的包,可以读取所有国家的列表,如下所示。

使用 Fiona 包来打开形状文件并提取所有国家名称的列表。图片由作者提供。

3. 提取所需国家的信息

接下来,我创建了required,这是一个包含六个有贸易关系的国家的列表。我还创建了一个字典对象c,其中包含 FionaRecord,即所有相关的国家信息,可用于绘图。

# required countries
required = [“Nepal”, “India”, “Bangladesh”,”China”,”Pakistan”,”Sri Lanka”]

# extract the specific country information
c = {
     co.attributes["ADMIN"]: co
     for co in countries if co.attributes["ADMIN"] in required
    }

4. 绘制 **required** 国家及裁剪

在这一步,我首先绘制了required国家在 PlateCarree 投影中的几何形状,如下所示:

绘制所需的国家。图片由作者提供。

接下来,我希望裁剪掉其余世界的几何形状,以便只查看六个国家的放大视图。我确定了能够覆盖所有六个国家的最大和最小经纬度值,设置了坐标轴的范围,并绘制了这些国家。在 for 循环中,我还添加了一个代码,显示每个国家的名称在其重心几何形状上。

matplotlib 包的zorder 属性 将决定艺术家的绘制顺序。具有较高zorder的艺术家会被绘制在顶部。

# get overall boundary box from country bounds
extents = np.array([c[cn].bounds for cn in c])
lon = [extents.min(0)[0], extents.max(0)[2]]
lat = [extents.min(0)[1], extents.max(0)[3]]

ax = plt.axes(projection=ccrs.PlateCarree())

# get country centroids
ax.set_extent([lon[0] - 1, lon[1] + 1, lat[0] - 1, lat[1] + 1])

for key, cn in zip(c.keys(),c.values()):
    ax.add_geometries(cn.geometry,
                      crs=ccrs.PlateCarree(),
                      edgecolor="gray",
                      facecolor="whitesmoke",
                     zorder = 1)

    # Add country names
    centroid = cn.geometry.centroid

    ax.text(
        centroid.x,
        centroid.y,
        key,  # Assuming 'name' is the attribute containing the country names
        horizontalalignment='center',
        verticalalignment='center',
        transform=ccrs.PlateCarree(),
        fontsize=8,  # Adjust the font size as needed
        color='black',  # Set the color of the text
        zorder = 2
        )

plt.axis("off")
plt.show()

5. 设置色彩图,添加箭头补丁和颜色条。

这是代码中最重要的部分。首先,我选择了viridis_r,即viridis的反向颜色调色板作为我的色彩图。接下来,我确定了任何国家之间的贸易值的最小和最大值,分别为tmintmax。这些值被标准化,使得tmin对应于色彩图cmap的最低端(0),tmax对应于最高端(1),并在随后的代码中相应使用。

然后,我遍历了transfers,并使用了FancyArrowPatch对象在国家之间绘制箭头。每个箭头对象都与一个独特的颜色col相关联,表示从一个国家到另一个国家的贸易流。虽然也可以使用第一个箭头坐标的偏移量来绘制第二个箭头,但我在代码中指定了第二个箭头的坐标。在代码中,mutation_scale属性用于控制箭头头部的长度,而linewidth属性用于控制主线的宽度。

最后,我在主图下方添加了水平颜色条。

ax = plt.axes(projection=ccrs.PlateCarree())

# get country centroids
ax.set_extent([lon[0] - 1, lon[1] + 1, lat[0] - 1, lat[1] + 1])

for key, cn in zip(c.keys(),c.values()):
    ax.add_geometries(cn.geometry,
                      crs=ccrs.PlateCarree(),
                      edgecolor="grey",
                      facecolor="whitesmoke",
                     zorder = 1)

    # Add country names
    centroid = cn.geometry.centroid

    ax.text(
        centroid.x,
        centroid.y,
        key,  # Assuming 'name' is the attribute containing the country names
        horizontalalignment='center',
        verticalalignment='center',
        transform=ccrs.PlateCarree(),
        fontsize=8,  # Adjust the font size as needed
        color='black',  # Set the color of the text
        zorder = 2
       )

# set up a colormap
cmap = colormaps.get("viridis_r")
tmin = np.array([v for v in transfers.values()]).min()
tmax = np.array([v for v in transfers.values()]).max()
norm = Normalize(tmin, tmax)

for tr in transfers:
    c1, c2 = tr.split(",")
    startarrow1 = startarrow1_dict[tr]
    endarrow1 = endarrow1_dict[tr]

    startarrow2 = startarrow2_dict[tr]
    endarrow2 = endarrow2_dict[tr]

    t1 = transfers[tr][0]
    col = cmap(norm(t1))

    # Use the arrow function to draw arrows
    arrow = mpatches.FancyArrowPatch(
        (startarrow1[0], startarrow1[1]),
        (endarrow1[0], endarrow1[1]),
        mutation_scale=20,    #control the length of head of arrow 
        color=col,
        arrowstyle='-|>',
        linewidth=2,  # You can adjust the linewidth to control the arrow body width
        zorder = 3
    )
    ax.add_patch(arrow)

    #OTHER WAY
    offset = 1
    t2 = transfers[tr][1]
    col = cmap(norm(t2))
    arrow = mpatches.FancyArrowPatch(
        (startarrow2[0], startarrow2[1]),
        (endarrow2[0], endarrow2[1]),
        mutation_scale=20,
        color=col,
        arrowstyle='-|>',
        linewidth=2,  # You can adjust the linewidth to control the arrow body width
        zorder = 4
    )
    ax.add_patch(arrow)

sm = ScalarMappable(norm, cmap)
fig = plt.gcf()
cbar = fig.colorbar(sm, ax=ax,
            orientation = "horizontal",
            pad = 0.05,  #distance between main plot and colorbar
            shrink = 0.8, #control length
            aspect = 20  #control width
            )
cbar.set_label("Trade flow")

plt.title("Trade flow in South Asia")
plt.axis("off")

plt.savefig("trade_flow2_with_labels.jpeg",
           dpi = 300)
plt.show()

下面展示了最终产品。在我的虚拟数据集中,贸易流最少的是从斯里兰卡到印度的出口(53 单位),用黄色表示。贸易流最多的是从孟加拉国到尼泊尔的出口(98 单位),用紫色表示。

通过箭头表示的国家间双向贸易流。图像由作者提供。

结论

在这篇文章中,我展示了如何通过使用两个箭头在 Python 地图中可视化国家之间的贸易流,包括出口和进口关系。我使用了 cartopy 和 matplotlib 包来实现这一目的。在本系列的第二部分,我将展示如何可视化“净”贸易流关系,并突出显示净出口国和净进口国。

本帖的笔记本可以在这个 GitHub 仓库中找到。感谢阅读!

参考文献

Google Developers, 2023. KML 教程 | Keyhole 标记语言 | Google 开发者。本页面的内容根据知识共享署名 4.0 国际许可证进行许可。

vLLM:PagedAttention 实现 24 倍更快的 LLM 推理

原文:towardsdatascience.com/vllm-pagedattention-for-24x-faster-llm-inference-fdfb1b80f83

在推理过程中,更高效地计算 Transformer 的注意力

Benjamin MarieTowards Data Science Benjamin Marie

·发表于 Towards Data Science ·6 分钟阅读·2023 年 6 月 24 日

--

PagedAttention 用于提示“the cat is sleeping in the kitchen and the dog is”。用于注意力计算的键值对张量存储在映射到 GPU 内存中非连续块的虚拟连续块中。— 图片由作者提供

几乎所有的大型语言模型(LLM)都依赖于 Transformer 神经架构。虽然这一架构因其高效性而受到赞誉,但也存在一些众所周知的计算瓶颈。

在解码过程中,一个瓶颈是在计算每个输入标记的键值对张量的注意力。这些张量必须全部存储在内存中。

注意:本文不会解释这些键值对的作用。这是 Transformer 架构中最复杂且最有趣的方面之一。如果你对此不了解,我强烈建议阅读 Jay Alammar 的《图解 Transformer》

随着 LLM 接受越来越长的输入,例如,LLM Claude 接受 100k 标记长的输入,这些张量消耗的内存可能变得非常大。

盲目地将所有这些张量存储在内存中会导致内存过度预留和碎片化。这种碎片化会使内存访问变得非常低效,特别是对于长序列的标记。至于过度预留,系统这样做是为了确保为张量分配足够的内存,即使它没有完全使用这些内存。

为了缓解这些问题,UC Berkeley 提出了 PagedAttention。

PagedAttention 被实现于 vLLM(Apache 2.0 许可),该项目由 LMSYS 部署,LMSYS 是一个由 UC Berkeley 的学生和教师以及 UCSD 和 CMU 的帮助下成立的开放研究组织。

在这篇文章中,我解释了什么是 PagedAttention 以及它为何显著加速解码。我将在文章的最后部分展示如何开始使用 vLLM 利用 PagedAttention 来进行推理和在你的计算机上服务 LLMs。

Transformer 的 PagedAttention

Kwon 等人 (2023) 提出了 PagedAttention。

目标是在 GPU VRAM 的不连续空间中更高效地存储键值张量。

简而言之,PagedAttention 背后的思想是创建映射到 GPU 内存中物理块的连续虚拟块。

每个块被设计用来存储预定义数量标记的键值对张量。所有块在虚拟上是连续的,并且映射到物理上不连续的块,这些块在推理过程中按需分配,在碎片化的 GPU 内存中。内存中还创建了一个简单的索引表,以将虚拟块与物理块关联起来。

PagedAttention 的内核根据需要提取这些块。这是高效的,因为系统由于块的大小限制而提取较少的键值张量。

让我们用以下提示进行说明:

猫正在厨房里睡觉,而狗则

我们为每个标记提供了键值张量。使用 PageAttention,我们可以(任意地)将块大小设置为 4。每个块包含 4 个键值张量,除了最后一个块,只包含 3 个键值张量。块在虚拟上是连续的,但在 GPU 内存中不一定是连续的,如本文引言中的图所示。

在注意力计算中,对于每个查询标记,系统逐个提取块,如下所示。

说明包含最多 4 个标记的虚拟块 —— 作者提供的图像

通过按块提取键值张量,而不是整个张量序列,注意力计算要快得多。

推理的并行采样

PagedAttention 的另一个优势是虚拟块在推理时可以共享。所有通过采样或束搜索并行生成的序列可以使用相同的虚拟块,从而避免重复。

在他们的实验中,LMSYS 观察到束搜索解码的内存使用减少了 55%。

LMSYS 报告的 PagedAttention 性能

在我们亲自尝试之前,先看看作者(UC Berkeley/LMSYS)在使用 vLLM 中实现的 PagedAttention 与 Hugging Face 开发的文本生成推理库相比的性能报告。

LLaMa 模型在输出完成任务中的性能,包括原始 Hugging Face 库 (HF)、文本生成推理库 (TGI) 和使用 PagedAttention (vLLM) 的 vLLM —— 由 UC Berkeley 和 LMSYS 绘制的图

根据这些结果,vLLM 看起来要快得多,特别是在多次输出完成的情况下。TGI 和 vLLM 之间的差距在更大的模型中会增加。这是预期中的,因为更大的模型需要更多内存,因此更容易受到内存碎片化的影响。

总体而言,vLLM 的速度比 Hugging Face Transformers 库快多达 24 倍。

注意:实际上,我对 HF 到 TGI 的改进也感到很惊讶。我还没有在我的博客上覆盖 TGI,但我可能会写一篇关于它的指南。TGI 在 Hugging Face 的生产环境中使用。虽然它似乎比 vLLM 慢很多,但 TGI 还有其他优点,比如支持更多的模型和功能。

如何在你的计算机上设置 vLLM

注意:vLLM 还不支持 CUDA 12。请使用较低版本,例如 11.8。

在本节中,我只会讲解如何在你的计算机上设置和运行 vLLM 的基本步骤。有关更高级的用法,你可以查看 vLLM 文档

当我写这篇文章时,vLLM 仅支持几种类型的模型

  • GPT-2

  • 基于 GPT-NeoX 和 Pythia

  • 基于 LLaMa

  • 基于 OPT

你可以通过遵循 这些说明 来添加对其他模型的支持。

在下面的代码中,我使用 Dolly V2(MIT 许可证)。这是一个基于 Pythia 的聊天模型,由 DataBricks 训练。

我选择了 最小的 30 亿参数版本。它可以在配备 24 GB VRAM 的消费级 GPU 上运行,例如 nVidia RTX 3080/3090。

安装 vLLM 最直接的方法是使用 pip:

pip install vllm

注意:这可能需要最多 10 分钟。

但在我的情况下,无论是在我的计算机上还是 Google Colab 上,pip 都无法安装 vllm 库。vLLM 的作者确认某些 nvcc 版本和环境存在问题。然而,对于大多数配置,pip 应该能够顺利安装 vLLM。

如果你和我处于相同的情况,解决方法就是使用 Docker 镜像。这一个对我有效:

docker run --gpus all -it --rm --shm-size=8g nvcr.io/nvidia/pytorch:22.12-py3

注意:进入 docker 后,作者建议在安装 vLLM 之前卸载 Pytorch:pip uninstall torch。然后,“pip install vllm” 应该可以正常工作。

然后,我们可以开始编写 Python 代码。

我们首先需要导入 vllm,然后用 vllm 加载模型。推理通过 llm.generate() 触发。

from vllm import LLM

prompts = ["Tell me about gravity"] #You can put several prompts in this list
llm = LLM(model="databricks/dolly-v2-3b")  # Load the model
outputs = llm.generate(prompts)  # Trigger inference

你也可以使用 vLLM 来服务 LLM。它的工作方式类似于 TGI。它也比 我在之前文章中描述的 NVIDIA Triton 推理服务器 更加简单。

你首先需要启动服务器:

 python -m vllm.entrypoints.openai.api_server --model databricks/dolly-v2-3b

注意:服务器将监听 8000 端口。确保该端口可用或在 vLLM 配置文件中更改它。

然后,你可以使用以下提示查询服务器:

curl http://localhost:8000/v1/completions \
    -H "Content-Type: application/json" \
    -d '{
        "model": "databricks/dolly-v2-3b",
        "prompt": "Tell me about gravity",
        "max_tokens": 200
    }'

就这样!你在计算机上运行了一个非常高效的 LLM 服务器。

结论

PagedAttention 显著加速了推理。这是向更实惠的 AI 迈出的另一大步。

在进一步的实验中,我确认 vLLM 在处理批量提示时特别高效。为了充分利用 vLLM,请考虑优化你的推理批处理策略。

尽管大束的束搜索可能在标准注意力计算中是不可行的,但使用 PagedAttention 的束搜索更快且内存更高效。

我的一个下一个实验是将 PagedAttention 与 QLoRa 结合,以减少内存使用。这应该很简单。它将使在消费级硬件上运行 LLM 更加高效。

如果你喜欢这篇文章并且有兴趣阅读接下来的文章,支持我工作的最佳方式是通过这个链接成为 Medium 会员:

[## 通过我的推荐链接加入 Medium - 本杰明·玛丽

作为 Medium 会员,你的一部分会员费将会转到你阅读的作家那里,而且你可以全面访问每一篇故事…

medium.com](https://medium.com/@bnjmn_marie/membership?source=post_page-----fdfb1b80f83--------------------------------)

如果你已经是会员并且想要支持这项工作, 只需在 Medium 上关注我

语音助手的可访问性

原文:towardsdatascience.com/voice-assistant-accessibility-dc737cde0394?source=collection_archive---------12-----------------------#2023-03-31

确保每个人都能被理解

安格斯·阿德尔斯Towards Data Science 安格斯·阿德尔斯

·

关注 发布于 Towards Data Science ·10 分钟阅读·2023 年 3 月 31 日

--

我多年来一直从事使用大型语言模型(如 GPT-4)的对话式 AI 工作。由于 chatGPT 的流行大爆发,令人非常兴奋,但它们如何改进呢?当然,对于这个问题有很多答案,但在这篇文章中,我将重点关注可访问性。

我们如何调整未来的机器学习模型以利用有限的数据集?我们应该如何设计我们的代理以确保每个人都能利用语音人工智能的进步?

这是对 IWSDS 2023上发表的论文的缩写。如果你想引用本文中讨论的内容,请引用标题为“语音助手的可访问性”的论文。

**Harvard**:
Addlesee, A., 2023\. Voice Assistant Accessibility. Proceedings of the 13th International Workshop on Spoken Dialogue Systems Technology (IWSDS).

**BibTeX**:
@inproceedings{addlesee2023voice,
  title={Voice Assistant Accessibility},
  author={Addlesee, Angus},
  journal={Proceedings of the 13th International Workshop on Spoken Dialogue Systems Technology (IWSDS)},
  year={2023}
}

全球有超过十亿人生活在某种形式的残疾中,而语音助手有可能改善人们的生活。例如,在我访问一个名为Leuchie House的休养院时,一位多发性硬化症(MS)患者解释了这种疾病的进展如何逐渐侵蚀了他们的独立性。一台亚马逊 Alexa 设备使这位患者能够在无需护理人员帮助的情况下关闭卧室灯。他们告诉我们,这是自诊断以来,他们第一次重新获得一些个人独立性。

像上面这样的故事激励着慈善机构推广语音助手的使用,因为它们能产生 真实的积极影响*。

我(右侧)于 2021 年 9 月与同事们访问了Leuchie House

语音助手的创作者正在获得 HIPAA 合规认证,以便在医疗保健领域进一步应用,并发布了专门针对脆弱用户群体的功能。我们同样看到早期研究者与其他学科合作,将他们的工作应用于更具体的医疗保健应用(请参见我关于语音研究趋势的 TDS 文章)。

语音助手的可及性因此至关重要,以确保未来系统在设计时考虑到最终用户的互动模式和需求。今天的语音助手在大量代表“平均”用户的数据集上进行训练和评估,但我们知道随着认知能力的下降,语音会发生变化。现有的商业系统在帮助视力障碍者方面存在巨大的隐私问题,而人们在公共场所与语音助手互动时需要公开宣布自己的残疾(下文讨论)。

随着研究和工业界推动语音助手的巨大利益超越大众市场应用,新的挑战和伦理问题也随之出现,这些问题必须被突出讨论。在本文中,我探讨了最先进的研究和当前可用的商业系统,针对多个用户群体,例如痴呆症患者、运动神经元病患者、视力丧失者、心理健康状况患者等。

我首先讨论了为认知障碍和心理健康状况人群设计语音助手,其次讨论了为身体残疾者设计系统,然后讨论了公共环境中的语音隐私,最后总结。

针对认知障碍和心理健康状况的对话系统

认知障碍影响记忆、注意力、解决问题的能力、决策、言语产生等。认知障碍的发生和进展通常与个人的年龄相关,但某些病症(如早发性痴呆)可能由中风或头部创伤引起。轻度认知障碍(MCI)具有上述症状,但不会显著干扰个人的生活。虽然 MCI 患者通常也是老年人,但另一个影响所有年龄段的脑健康子集是心理健康状况。

下文提到的 SPRING 项目中使用的 ARI 机器人(由 PAL Robotics 生产)。

痴呆症和 MCI

随着认知能力的下降,人们在句子中途的停顿变得更频繁且时间更长。其他言语产生的变化也包括:增加重复、说话速度减慢、介词使用增多,等等。如今的语音助手常常将这些长时间的停顿误认为是用户发言的结束,迫使用户不得不挫败地重复整个陈述。

推荐痴呆症和 MCI 患者使用标准语音助手(如 Google Home 和 Amazon Alexa)进行日常使用。像 CogniHealth 这样的公司致力于策划内容,以帮助痴呆症患者及其家人——通过语音助手提供有价值的信息、建议和支持——但这些系统的语音处理和理解组件没有针对上述特定挑战的无障碍选项。

由于数据不足,该领域的研究受到限制。收集自然语言对话数据,尤其是与脆弱的老年人进行对话,在伦理上具有挑战性,特别是近年来由于 COVID,需要 定制工具 来保障数据安全。像 EU H2020 SPRING 项目 这样的研究正在医院记忆门诊候诊室中收集数据,以应对这些挑战。在这种环境下,患有痴呆症或 MCI 的患者通常会有家庭成员或看护者陪同,带来更多的多方复杂情况(剧透:这是我下一篇文章的主题)。数据收集后,可以利用 TalkBank 的子库 DementiaBank 将数据与其他研究痴呆症交流的研究人员共享。

心理健康状况

某些心理健康状况也会影响人们的语言表达和行为。焦虑症患者的语速较快,停顿时间较短,而抑郁症或创伤后应激障碍(PTSD)患者说话较慢且沉默较多。

目前似乎没有商业语音助手能够调整其语音处理以更好地理解心理健康状况的人——尽管存在针对这些用户群体的公司。像UB-OKKindspace这样的语音助手应用提供了一个安全的空间,让人们可以在没有评判的情况下分享他们的忧虑。人们,特别是年轻人,可以询问关于心理健康和其他他们可能不愿向朋友、老师或家人提问的问题。

Michael McTernan 在 2019 年苏格兰 Edge Awards 上展示 UBOK

人机交互(HRI)研究在这一领域十分丰富。系统的语音处理仍然保持标准,但机器人的交互方式有所调整。例如,可以借鉴心理学的沟通技巧来促进自我反思,并帮助缓解孤独(这与抑郁症常常伴随)。

应用范围确实非常广泛。自闭症的语言能力较弱的儿童使用了语言生成设备,长期使用后这些设备鼓励他们自发说话并使用新词汇。类似的工作有效地利用互动社交机器人进行自闭症治疗。

上述所有内容都令人兴奋,但关键是,没有研究专注于改善系统的语音处理和理解

身体障碍人士设计对话系统

身体障碍会影响用户可能向语音助手提出的问题以及在收到回应后如何采取行动。例如,视力受损的人会询问他们的视觉环境,而有听力困难的人则会期待多模态的回应。

视觉障碍

盲人和视力受限的人往往会遭受似乎无关的健康问题,如营养不良。这主要是因为他们在完成日常任务(如购物、准备食物和烹饪)时遇到困难。一组视觉障碍计算机科学家在计算机视觉与模式识别会议(CVPR 2020)上讨论了在看不到时刻表、站台号、车厢字母或方向标志时,如何在火车站内导航的困难。

类似于火车站,人们会询问有关食品包装上的文本信息。这张图片来自一篇关于厨房中这一问题的文章 (here)。

也有“人机协作”解决方案,你可以联系有视力的人来回答问题。必须同时发送照片或视频以传达视觉场景。 BeMyEyesBeSpecular 依赖视力正常的志愿者及时回答问题,而 Aira 则有一支经过培训的专业团队。

当依赖志愿者时,一个明显的问题是:视力受限的人无法知道发送的图像中是否能看到敏感信息。因此,志愿者可能会看到邮件中有姓名、地址、身份证号码或个人家中的贵重物品。Aira 通过招聘和培训专注于安全和保障的工作人员来缓解这个问题,但这需要付出代价。

也存在端到端 (E2E) 系统,如 TapTapSeeMicrosoft Seeing AI。这些系统在云端安全运行,并加密处理,因此隐私问题最小,但它们引入了一个新的问题——准确性。视力受限的人无法验证系统的回答是否正确。由于无法进行对话,用户只能依赖系统的回答。这可能导致像药物问题这样的困境。E2E 系统可能不正确,可能对用户造成伤害,但人机协作系统需要他们将药物照片发送给未知的志愿者。

这张图片展示了尝试回答视力障碍者问题的一些工作实例。目标是让用户知道系统何时不确定 (here)。

有限行动能力

家庭开放域语音助手非常方便:我们可以在手上沾满油的时候设定定时器,或者在沙发上舒适的温暖毯子下调高音乐。

这些功能不仅对行动不便的人很方便,它们对心理健康至关重要。手部、手臂或腿部有行动限制的人可以通过语音保持一定的个人独立性。

移动能力丧失本身通常不会影响语言生成,但语音助手仍可以设计得更具可及性。虽然存在提高人们舒适度和完成日常任务能力的硬件(如先进的轮椅),但这些技术目前尚未与现有的语音助手整合。在访问一个名为Leuchie House的临时护理之家时,一位居民描述了他们的沮丧,语音助手可以打开窗帘和关闭电视,但他们不得不请护理人员调整电动轮椅的靠背。这突显了包容性设计的必要性。

听力障碍

有听力困难的人对语音助手感到沮丧,从而完全放弃使用它们。对于那些在年轻时就出现听力问题的人,这种情况更加严重,因为这往往会导致语言障碍。例如,如果听不到对话,就无法学习发音。下面将讨论语言障碍的影响,但即使没有这些障碍,现有的语音助手似乎也存在局限。研究指出,有部分听力丧失的人在嘈杂环境中(如公共场所)很难跟上对话,但当设置了实时转录对话的屏幕时,他们在对话中感到更有融入感。实时说话者识别将更为有效。因此,我们应确保语音助手和社交机器人在公共多方环境中包含屏幕,以实现这一功能。

本田的 Asimo 机器人用手语说“我爱你”(来源

许多听力障碍者懂得大约 200 种手语中的一种。研究表明,助手可以学习手语,但 NLP 社区的更多努力可以利用现有资源来改进手语处理和生成。听力障碍者渴望参与语音助手的包容性设计,以确保无障碍进展。

语音多样性

语言生成具有细微差别且因人而异,但自动语音识别(ASR)学习的是一般语音模式,因此难以理解非母语者或口音很重的人(例如苏格兰人)。然而,这一问题还进一步扩展。有口吃的人被误解,有发音困难的人(如因早期听力丧失导致)被误解,还有图雷特综合症患者被排除在对话研究之外。非标准语音也可能由影响我们用来生成语言的肌肉的疾病引起,例如肌营养不良症。

谷歌在这方面通过三个项目进行创新。项目 Euphonia项目 Relate 是谷歌的举措,旨在帮助那些说话方式不标准的人更好地被理解,项目 Understood 是他们的计划,旨在更好地理解唐氏综合症患者。谷歌甚至开设了 无障碍发现中心 来与学术界、社区和慈善/非营利组织合作,旨在“消除无障碍障碍”。

项目 Relate

言语丧失

像运动神经元病(MND)这样的某些疾病患者会逐渐失去完全说话的能力。斯蒂芬·霍金因 MND 使用了合成语音,但今天在质量和多样性方面已经有了巨大的改善。像 Cereproc 这样的公司合成具有个性、引人入胜和情感化的语音,带有不同的口音,帮助 MND 患者选择最能代表自己的声音。

语音克隆技术也变得可能,这使得面临失语风险的人能够使用语音银行技术。人们录制自己的语音以便在需要时进行克隆。像 SpeakUnique 这样的公司,甚至可以在语音在诊断后部分退化的情况下,重新构建一个人的原始声音。

隐私

个人语音助手通常仅由单一用户在私人空间中使用。因此,语音助手可以高度定制以满足该用户的需求。然而,这在公共空间中的助手并非如此。博物馆、医院、机场等公共场所的社交机器人每天会被许多人使用。一些无障碍设计的实现惠及所有人(例如,我们有时在句子中会忘记词汇),但其他则不然。

一个购物中心的 Pepper 机器人(来源)。人们在公共场所与其他人一起时,可能会感到不舒服地披露个人无障碍需求。

大多数残疾是看不见的,因此人们必须在公共场所大声描述自己的残疾,以激活某些无障碍功能。这在没有语音助手的情况下同样成问题——残疾人士通常需要在商店里宣布自己的残疾和帮助需求。

Neatebox 这样的技术正在迅速普及,以解决这一问题。残障用户可以下载应用程序并注明他们希望如何得到个人化帮助(例如,被手臂引导)。然后,当他们进入商店或机场时,客户服务团队会收到通知并提供个性化帮助。类似的技术也可以用于公共空间的社交机器人,当与需要可访问语音助手的人互动时,激活特定功能。

结论

语音助手可以超越简单的便利来改善人们的生活,这可以通过道德的数据收集和包容性设计来实现。然而,这并不简单,每个语音助手系统组件在设计针对所有人的系统时都必须被考虑在内。

我已经总结了为了使语音助手对本文讨论的用户群体更具可访问性,必须调整的具体组件:

论文 的表格 1

你可以通过 MediumTwitterLinkedIn 联系到我。

Voronoi 网格:一种实际应用

原文:towardsdatascience.com/voronoi-grids-a-practical-application-7e6ee3b1daf0

快速成功数据科学

在墨尔本,澳大利亚,绘制学校区域

李·沃恩走向数据科学 李·沃恩

·发表于 走向数据科学 ·10 分钟阅读·2023 年 11 月 28 日

--

被 Leonardo.ai DreamShaper v7 设想为彩绘玻璃窗的墨尔本

Voronoi 网格,也称为 Voronoi ,用于将平面划分为围绕一组给定种子点的离散区域。对于每个种子点,都有一个对应的区域,称为 Voronoi 单元,其中平面上的所有点都比其他点更接近种子点。

Voronoi 图在许多领域都有应用,包括计算机科学、地理学、生物学和城市规划。一个特别重要的应用是绘制需要紧急降落的飞机的最近机场。

澳大利亚墨尔本政府使用该工具制作学校学区地图。“学区”指的是那些居住在特定区域内并且被保证入读特定学校的学生。由于学生有资格就读离家最近的小学或中学——以欧几里得距离为标准——学校区域地图默认是一个 Voronoi 图。

墨尔本学校学区地图 (维多利亚州教育部,CC-BY 4.0)

在这个快速成功数据科学项目中,我们将通过制作自己版本的墨尔本学区地图来深入了解 Voronoi 图的概念。我们将使用大都市区的小学子集,并用 SciPy 库的Voronoi类对其进行网格化。然后,我们将使用 Folium 库将 Voronoi 图叠加在墨尔本的街道地图上。

数据集

为了生成数据集,我使用了维多利亚政府的Find My School网站查找墨尔本大都市区 109 所小学的地址。然后使用LatLong.net将地址转换为十进制度数,并将结果存储在这个GitHub Gist的 CSV 文件中。

该项目使用的墨尔本地区小学位置(由作者提供)

SciPy Voronoi 实现

Python 的SciPy科学库旨在数学、科学和工程领域,解决科学计算中的许多标准问题。它基于并补充了Numerical Python (NumPy),并提供了许多用户友好且高效的数值例程。

为了制作 Voronoi 图,SciPy 提供了scipy.spatial.voronoi()类,该类使用Qhull 库来计算 Voronoi 网格。如前所述,网格单元内的所有位置应该比其他种子点更接近生成该单元的种子点。

下图取自 SciPy 文档,种子点按正交方式排列,形成了一个简单的网格模式,其中种子点位于单元格的中心

正交 Voronoi 网格(来自 SciPy 文档)

种子点显示为蓝色。图中线条交汇的顶点为橙色。种子点之间的(线条)为黑色,这些脊构成了 Voronoi 单元的边界。

由于前图中的大多数种子点位于地图的边缘,只有中心种子点与有限的单元或区域相关联,因此它被有限的脊包围。其他脊为虚线,因为它们延伸到无穷大,从而界定了无限的单元,这些单元永远不会“闭合”,因为没有外部种子点来计算插入的脊。

下图也来自文档,由非正交排列的种子点构建,因此单元格更为复杂。请注意,一些脊用实线绘制,另一些则用虚线绘制。

非正交 Voronoi 网格(来自 SciPy 文档)

实线绘制的脊在某处汇聚,形成一个封闭且有限的区域。虚线是发散的,永不相交,因此它们的单元具有无限的面积。在实际应用中,这些无限单元通常被忽略或人为地限制,比如使用地图边缘多边形。

我们可以通过 voronoi.regionsvoronoi.verticesvoronoi.ridge_verticesvoronoi.ridge_points 等属性访问区域(单元格)的列表和用于定义这些区域的坐标。我们稍后会用这些来创建可以绘制的 Voronoi 单元格多边形。

代码

下面的代码在 JupyterLab 中编写,遵循以下步骤:

  1. 加载学校名称和位置的 CSV 文件。

  2. 使用学校位置创建 Voronoi 网格。

  3. 将 Voronoi 网格转换为可以绘制的多边形。

  4. 使用方形边界框截断边缘单元格。

  5. 在墨尔本的街道地图上绘制学校和 Voronoi 网格。

导入库和准备数据

为了完成任务,我们需要 pandas、geopandas、shapely(与 geopandas 捆绑)、Folium 和 SciPy。pandas 和 geopandas 库允许数据的加载和处理,shapely 创建可绘制的多边形,Folium 允许映射,SciPy 提供构建 Voronoi 网格的算法。

如果你不熟悉,GeoPandas 是一个开源的第三方库,旨在支持 Python 中的地理空间映射。它扩展了 pandas 库使用的数据类型,使地理空间矢量数据的处理类似于表格数据的处理。它还使 Python 中的操作成为可能,而这些操作通常需要专用的地理空间数据库,如 Post GIS。

import pandas as pd
import geopandas as gpd
import folium
from shapely.geometry import Polygon
from scipy.spatial import Voronoi

# Load the school locations CSV file into a DataFrame:
df = pd.read_csv('https://bit.ly/3MYYegT')

# Create a GeoDataFrame with Point geometries:
gdf = gpd.GeoDataFrame(df, 
                       geometry=gpd.points_from_xy(df['Longitude'], 
                                                   df['Latitude']), 
                       crs='EPSG:4326')

导入必要库后,我们使用 pandas 读取 CSV 文件,并使用 geopandas 将学校坐标转换为 点几何

GeoDataFrame 是一个 pandas DataFrame,具有一个特殊的“几何”列用于位置数据。此列将几何对象类型(如点、线串、多边形等)与绘制它所需的坐标(经度和纬度)捆绑在一起。

示例“几何”列(框选)来自 GeoDataFrame(作者的 Python Tools for Scientists)。

注意,在创建 GeoDataFrame 时,我们需要使用 crs=EPSG:4326 参数提供 坐标参考系统。“EPSG” 代表 “欧洲石油勘探组” 数据集,4326 代码由 全球定位系统GPS)使用。该系统将我们 3D 行星上的纬度和经度坐标投影到地图的平面表面上。你可以在 这里 阅读更多信息。

创建 Voronoi 网格

下一步是通过将 GeoDataFrame 的“经度”和“纬度”列传递给 SciPy 库的 Voronoi() 类来创建 Voronoi 网格。

# Create a Voronoi diagram using the GeoDataFrame.
# Use -1 to check for and exclude regions that extend to infinity:
vor = Voronoi(gdf[['Longitude', 'Latitude']])
voronoi_polygons = [Polygon(vor.vertices[region]) 
                    for region in vor.regions 
                    if region and -1 not in region]

# Create a GeoDataFrame with the Voronoi polygons:
gdf_voronoi = gpd.GeoDataFrame(geometry=voronoi_polygons, 
                               crs='EPSG:4326')

接下来,我们制作一个 Voronoi 多边形的列表,并删除空区域和延伸到无穷远的区域。这需要使用 Voronoi() 类返回的 vor 对象的 regions 属性。如果该属性以 -1 开头,那么我们知道该区域永远不会关闭。作为过程的一部分,我们将 vertices 属性传递给 shapely 的 Polygon() 类,该类生成可绘制的多边形,我们将其添加到新的 GeoDataFrame 中。

截断 Voronoi 单元

因为我们没有使用该区域内的所有小学,许多边缘单元将没有约束,可能会延伸到极其远的距离。为了处理这些情况,我们将创建一个边界框,并使用它来截断任何超出其范围的 Voronoi 单元(多边形)。

无约束的网格。天哪!(由作者提供)

# Define the bounding box lat-lon limits:
max_lat, min_lat, max_lon, min_lon = (-37.75, -37.9, 
                                      145.18, 144.84)

# Create the bounding box as a Shapely Polygon
bounding_box = Polygon.from_bounds(min_lon, min_lat, 
                                   max_lon, max_lat)

# Truncate each Voronoi polygon with the bounding box:
truncated_polygons = [polygon.intersection(bounding_box) for 
                      polygon in gdf_voronoi.geometry]

# Create a GeoDataFrame with the truncated polygons:
gdf_truncated = gpd.GeoDataFrame(geometry=truncated_polygons, 
                                 crs='EPSG:4326')

我们首先定义边界框的经纬度限制,使用比 CSV 文件中找到的值略大的值。然后再次调用 Polygon() 创建可绘制的多边形,然后使用列表推导式和 shapely 的 Polygon intersection() 方法来截断 GeoDataFrame 中的每个多边形。注意我们如何使用特殊的 geometry 列(gdf_voronoi.geometry)。最后,我们创建一个新的 GeoDataFrame 来保存截断后的多边形。

绘制地图

如果没有将其与现实世界关联的方式,Voronoi 图是无用的。因此,我们将使用 Folium 将其绘制在城市的街道地图上(通过选择 OpenStreetMap 作为 tiles 参数)。

我们还需要学校的位置和相关信息。这需要遍历 GeoDataFrame 并将每个标记添加到地图中。我们可以通过将 icon 参数设置为“家”符号来控制标记内部的图标。你可以在 Glyphicons 页面 上找到类似的图标列表。你也可以创建自定义图标,如 这篇文章 中所述。

# Create a Folium map centered on the average coordinates of the schools:
map_center = [gdf['Latitude'].mean(), gdf['Longitude'].mean()]
school_map = folium.Map(location=map_center, 
                        zoom_start=12, 
                        tiles='OpenStreetMap')

# Plot the truncated Voronoi polygons on the map:
folium.GeoJson(gdf_truncated).add_to(school_map)

# Add markers for each school:
for index, school in gdf.iterrows():
    folium.Marker(
        location=[school['Latitude'], school['Longitude']],
        popup=f"{school['School']}\n\
        {school['Street Address']}\n{school['Town']}",
        icon=folium.Icon(color='blue', icon='home')
    ).add_to(school_map)

# Save the map as an HTML file (optional):
# school_map.save('school_voronoi_map_truncated.html')

# Display the map in the notebook:
school_map

这是结果地图,允许缩放和平移。

最终地图(由作者提供)

图示边缘的一些学校没有被着色,因为它们的“山脊”延伸到无穷远而没有收敛。这些可以通过将 Voronoi 单元与其他多边形合并来“修复”。我们稍后会讨论这个选项。

点击标记会弹出一个包含学校名称和地址的窗口。

带有学校信息的弹出窗口(由作者提供)

要关闭多边形的蓝色填充颜色,只需在创建 folium.GeoJson 对象时修改 style_function 参数,如下所示。

folium.GeoJson(gdf_truncated, 
               style_function=lambda x: {'fillColor': 'none'}).add_to(school_map)

现在你只会看到单元边界。

设置填充颜色为“无”的最终地图(由作者提供)

合并市政多边形

你可以在本文开头查看实际的墨尔本集水区地图,访问Find My School网站(点击学校图标以激活网格),或在mangomap.com上查看。

与我们的地图不同,真实的学校区域融合了 Voronoi 多边形与其他边界,例如 Port Philip 湾沿岸线。将所有这些附加边界纳入超出了本文的范围,但我们可以通过使用墨尔本市的市政边界多边形来了解其实现方法。

城市提供了一个shapefile格式的多边形。Shapefile 是一种地理空间矢量数据格式,用于地理信息系统(GIS)软件。尽管它的名字是“shapefile”,但它不是一个单一的文件,而是一个文件集合,位于一个文件夹中。你可以在这里了解更多信息。

要下载 shapefile,首先访问City of Melbourne’s Open Data site市政边界页面,然后导出 shapefile(作为“完整数据集”)。这些数据在CC Attribution 4.0 International license下共享。

将压缩文件夹存放在与你的 Python 脚本或笔记本相同的文件夹中,以便使用下面提供的代码。请勿解压缩文件夹。

市政边界文件夹

这是剪裁并将现有多边形与市政边界合并的代码。它类似于用于边界框的剪裁过程,并假设你已经运行了之前的代码(针对在笔记本中运行代码的用户)。

# Read in shapefile of Melbourne City Limits as GeoDataFrame:
city_limits = gpd.read_file('municipal-boundary.zip')

# Truncate Voronoi polygons by the city_limits polygon:
truncated_polygons = [polygon.intersection(city_limits.geometry.iloc[0]) 
                      for polygon in gdf_voronoi.geometry]

# Create a GeoDataFrame with the truncated polygons:
gdf_truncated = gpd.GeoDataFrame(geometry=truncated_polygons, 
                                 crs='EPSG:4326')

# Create a Folium map centered on the average coordinates of the schools:
map_center = [gdf['Latitude'].mean(), gdf['Longitude'].mean()]
school_map = folium.Map(location=map_center, 
                        zoom_start=12, 
                        tiles='OpenStreetMap')

# Plot truncated Voronoi polygons on the map:
folium.GeoJson(gdf_truncated).add_to(school_map)

# Add markers for each school:
for index, school in gdf.iterrows():
    folium.Marker(
        location=[school['Latitude'], school['Longitude']],
        popup=f"{school['School']}\n\
        {school['Street Address']}\n{school['Town']}",
        icon=folium.Icon(color='blue', icon='home')
    ).add_to(school_map)

# Display map in notebook:
school_map

新地图,如下所示,只包含墨尔本市界内的 Voronoi 单元。许多单元边界现在符合与 Voronoi 无关的特征,如 Yarra 河、码头和主要道路。

剪裁到墨尔本市政边界的 Voronoi 多边形(作者提供)

一些单元与其各自的学校隔离。这是因为墨尔本市政多边形实际上并未用于定义学校区域。我们在这里使用它来演示如何在你拥有所有正确的多边形集合后创建最终地图。如你所见,这是一个简单的过程。

摘要

Voronoi 图是一种最近邻映射,让你将平面用n个生成点划分为n个凸多边形。每个多边形包含一个生成点,并且每个位置在给定的多边形中距离其生成点比距离其他任何生成点都近。

在这个例子中,我们使用 Voronoi 图将澳大利亚墨尔本的地图划分为学校招生区域。每个区域的学生离关联的主要学校比其他任何城市中的主要学校都要近。由于我们没有使用所有学校或包含所有修改多边形(如河流和海岸线),因此这张地图与实际情况有所不同。

Python 的 SciPy 库包含生成 Voronoi 网格的内置功能。借助额外的第三方库,如 geopandas 和 Folium,你可以将这些网格投影到地图上,用于实际应用。

进一步阅读

如果你想了解更多关于 Voronoi 图的信息,可以查看 Francesco Bellilli 的这篇信息丰富的文章。

对 Voronoi 图的迷人世界 [## Voronoi 图的迷人世界

关于这个普遍模式及其应用的简要介绍

对 Voronoi 图的迷人世界

谢谢!

感谢阅读,请关注我,了解未来更多快速成功的数据科学项目。

Vosk:高效企业级语音识别的评估与实施指南

原文:towardsdatascience.com/vosk-for-efficient-enterprise-grade-speech-recognition-an-evaluation-and-implementation-guide-87a599217a6c

对实现和评估基于 Vosk 的语音识别系统的全面指南

Luís RoqueTowards Data Science Luís Roque

·发表于 Towards Data Science ·9 分钟阅读·2023 年 5 月 15 日

--

引言

在我们最新的文章中,我们广泛地使用了不同的模型和方法来进行语音识别。开源社区在过去几年中一直在开发这方面的解决方案,给我们提供了许多选择。我们尝试了 Whisper、WhisperX 和 Whisper-JAX。它们都基于最近由 OpenAI 训练并开源的 Whisper 模型。它是一个在多语言和多任务上训练的自动语音识别(ASR)系统,使其在语音甚至语言任务中都具有通用性。

Whisper 的一个缺点是运行所需的资源,特别是在较长音频文件的执行时间方面。在本文中,我们将引导你通过使用 Vosk,一个开源离线语音识别工具包,来开发企业级语音识别模型。这些模型显著更快,在许多使用案例中,这是一个决定性因素。

我们深入探讨了四个 Vosk 语音识别模型的性能,突出了它们在准确性、执行时间和模型大小方面的优缺点。我们的发现揭示了有趣的见解,比如从较小的模型过渡到更大的模型时准确性提高了 20%。我们还揭示了速度和准确性之间的权衡。

图 1:语音转文本使我们更接近机器(来源

本文属于“大型语言模型编年史:探索 NLP 前沿”这一新周刊系列文章,将探讨如何利用大型模型的力量来处理各种 NLP 任务。通过深入研究这些前沿技术,我们旨在帮助开发者、研究人员和爱好者掌握 NLP 的潜力,开启新的可能性。

到目前为止发表的文章:

  1. 使用 ChatGPT 总结最新的 Spotify 发布内容

  2. 在大规模下掌握语义搜索:使用 FAISS 和 Sentence Transformers 索引数百万文档,实现闪电般快速的推理时间

  3. 释放音频数据的力量:使用 Whisper、WhisperX 和 PyAnnotate 进行高级转录和分段

  4. Whisper JAX 与 PyTorch:揭示 GPU 上 ASR 性能的真相

一如既往,代码可在我的 Github 上找到。

理解语音识别

语音识别是使计算机和其他设备能够理解和处理人类语音的技术,将口语转换为书面文本。这些系统学习将语音转换为文本的过程包括几个步骤。它们自动提取原始音频波形,实质上是音频信号的声学特征。然后,它们将这些特征映射到音素,并使用语言模型将音素映射到单词。更先进的系统还结合了上下文信息和语义理解,以精炼转录结果。

语音识别面临着许多挑战,因为人类语音的复杂性以及引入变异性和模糊性的因素。一些挑战包括说话人变异、背景噪声、言语流畅性问题和填充词、以及同音词和共鸣现象。说话人变异源于不同说话人的独特口音、说话风格和发音。背景噪声,如嘈杂环境中的噪音,会干扰语音信号的清晰度,对准确识别构成挑战。言语流畅性问题和填充词是另一个障碍,因为在自然语言中常出现犹豫、重复和填充词(例如“呃”和“嗯”)。最后,同音词和共鸣现象带来额外的障碍。一些单词发音相同但含义不同(同音词)。另一些单词的发音可能会根据其在句子中的位置而改变(共鸣现象)。所有这些因素都为识别任务引入了模糊性,使得我们的模型在某些任务中更难准确执行。

《构建企业级语音识别模型的实用指南》

我们利用 Vosk 的强大功能,这是一个开源的离线语音识别工具包,用于构建自定义语音识别系统。Vosk 提供了一个灵活高效的解决方案,能够在包括 Android、iOS、Windows、Linux 和 Raspberry Pi 等各种平台上实现语音识别。其关键特性包括支持多种语言、说话人识别、与小型设备兼容以及大规模服务器部署。

在接下来的部分中,我们将指导您如何使用 Vosk 创建语音识别系统。我们将讨论流行的框架和库,概述数据收集、预处理和模型训练的步骤,并提供针对特定用例的模型微调技巧。

数据收集

为了评估不同的模型,我们将使用 LibriSpeech ASR 语料库数据集(CC BY 4.0)。该数据集包括大约 1000 小时的朗读英语语音录音。LibriSpeech 数据集非常适合用来评估语音识别模型,因为它提供了多种口音、说话风格、发音和背景噪声。正如我们之前讨论的,这些因素通常会对模型的表现产生重大影响。我们希望测试 Vosk 是否能够在这些具有挑战性的环境中有效工作。

转录与单词表示

Vosk API 非常丰富;我们可以访问每个转录单词的几个属性。它返回以下属性:

  • conf:识别单词的置信度,范围从 0 到 1。

  • start:发音开始时间,以秒为单位。

  • end:发音结束时间,以秒为单位。

  • word:识别出的单词。

为了简化我们的过程,我们创建了一个 WordVosk 类,用于表示 Vosk API 返回的每个单词:

class WordVosk:
    """A class representing a word from the JSON format for Vosk speech recognition API."""

    def __init__(self, conf: float, start: float, end: float, word: str) -> None:
        """
        Initialize a Word object.

        Args:
            conf (float): Degree of confidence, from 0 to 1.
            start (float): Start time of pronouncing the word, in seconds.
            end (float): End time of pronouncing the word, in seconds.
            word (str): Recognized word.
        """
        self.conf = conf
        self.start = start
        self.end = end
        self.word = word

    def to_dict(self) -> Dict[str, Union[float, str]]:
        """Return a dictionary representation of the Word object."""
        return {
            "conf": self.conf,
            "start": self.start,
            "end": self.end,
            "word": self.word,
        }

    def to_string(self) -> str:
        """Return a string describing this instance."""
        return "{:20} from {:.2f} sec to {:.2f} sec, confidence is {:.2f}%".format(
            self.word, self.start, self.end, self.conf * 100
        )

    def to_json(self) -> str:
        """Return a JSON representation of the Word object."""
        return json.dumps(self, default=lambda o: o.__dict__, sort_keys=True)

由于我们主要关注获取转录,我们创建了一个 Transcription 类,该类接受一个 WordVosk 对象的列表。to_raw_text 方法生成最终的原始转录:

class Transcription:
    def __init__(self, words: List[WordVosk]) -> None:
        self.words = words

    def to_dict(self) -> List[Dict[str, Union[float, str]]]:
        """Return a dictionary representation of the Transcription object."""
        return [word.to_dict() for word in self.words]

    def to_raw_text(self) -> str:
        """Generate raw transcription text from the list of WordVosk objects."""
        return " ".join(word.word for word in self.words)

这些类有助于更高效地管理 Vosk 语音识别 API 的输出,从而更方便地处理转录结果。

实现主模型类

ModelSpeechToText 类旨在使用 Vosk API 处理语音转文本转换。它接受一个音频文件和一个 Vosk 模型作为输入,并返回一个转录后的单词列表。

class ModelSpeechToText:
    def __init__(self, audio_path: str, model_path: str) -> None:
        self.audio_path = audio_path
        self.wf = wave.open(self.audio_path)
        self.model = Model(model_path)

speech_to_text 方法使用 Vosk API 将语音转录为文本。它按块读取音频文件,并使用 KaldiRecognizer 处理每块。转录结果被收集到 results 列表中。

 def speech_to_text(self) -> List[Dict[str, Any]]:
        """Transcribe speech to text using the Vosk API."""
        rec = KaldiRecognizer(self.model, self.wf.getframerate())
        rec.SetWords(True)

        results = []
        frames_per_second = 44100
        i = 0
        print("Starting transcription process...")
        while True:
            data = self.wf.readframes(4000)
            i += 4000
            if len(data) == 0:
                break
            if rec.AcceptWaveform(data):
                part_result = json.loads(rec.Result())
                results.append(part_result)
            if i % (frames_per_second * 60) == 0:
                print(f"{i / frames_per_second / 60} minutes processed")
        part_result = json.loads(rec.FinalResult())
        results.append(part_result)
        self.wf.close()
        print("Transcription process completed.")
        return results

results_to_words 方法接受转录结果,并将其转换为 WordVosk 对象的列表。这个方法使我们能够轻松地处理和处理转录后的单词。

 @staticmethod
    def results_to_words(results: List[Dict[str, Any]]) -> List[WordVosk]:
        """Convert a list of Vosk API results to a list of words."""
        list_of_words = []
        for sentence in results:
            if len(sentence) == 1:
                continue
            for ind_res in sentence["result"]:
                word = WordVosk(
                    conf=ind_res["conf"],
                    start=ind_res["start"],
                    end=ind_res["end"],
                    word=ind_res["word"],
                )

                list_of_words.append(word)
        return list_of_words

ModelSpeechToText 是我们高效使用 Vosk API 所需的最终抽象。它允许我们对音频文件进行转录,并获得转录后的单词列表,这些单词以 WordVosk 对象的形式表示。

使用字错误率评估语音识别模型

要评估语音识别模型,我们可以使用字错误率(WER)指标。它是将假设转录转换为参考转录所需的插入、删除和替换的平均数量,除以参考转录中的总单词数。WER 值越低,表示性能越好。

calculate_wer 函数计算参考转录和假设转录之间的平均 WER:

def calculate_wer(
    reference_transcriptions: List[str], hypothesis_transcriptions: List[str]
) -> float:
    """Calculate the average Word Error Rate (WER) between reference and hypothesis transcriptions.

    Args:
        reference_transcriptions: List of reference transcriptions.
        hypothesis_transcriptions: List of hypothesis transcriptions.

    Returns:
        The average Word Error Rate (WER).
    """
    assert len(reference_transcriptions) == len(
        hypothesis_transcriptions
    ), "Reference and hypothesis lists should have the same length"
    total_wer = 0
    for ref, hyp in zip(reference_transcriptions, hypothesis_transcriptions):
        total_wer += wer(ref, hyp)
    return total_wer / len(reference_transcriptions)

evaluate_models 函数使用给定的评估数据集评估多个语音识别模型:

def evaluate_models(
    models: List[ModelSpeechToText],
    evaluation_dataset: List[Tuple[str, str]],
) -> List[Tuple[float, float, float]]:
    """Evaluate multiple speech-to-text models using a given evaluation dataset.

    Args:
        models: A list of ModelSpeechToText instances.
        evaluation_dataset: A list of tuples containing the paths of the WAV files and their transcriptions.

    Returns:
        A list of tuples containing WER, execution time, and RAM usage for each model.
    """
    if not evaluation_dataset:
        print("The evaluation dataset is empty. Please check the dataset processing.")
        return []

    audio_files, reference_transcriptions = zip(*evaluation_dataset)

    metrics = []
    for model in models:
        start_time = time.time()

        hypothesis_transcriptions = transcribe_audio_files(model, audio_files)

        memory = psutil.Process().memory_info().rss
        elapsed_time = time.time() - start_time

        wer = calculate_wer(reference_transcriptions, hypothesis_transcriptions)

        metrics.append((wer, elapsed_time, memory / 1024 ** 3))

        del model
        gc.collect()

    return metrics

评估 Vosk 语音识别模型:准确性、执行时间和内存消耗

首先,让我们介绍一下我们正在测试的四个模型。这些模型在大小和复杂性上有所不同,这可能会影响它们的性能。我们从准确性、执行时间和内存消耗方面对它们进行了比较。这些模型及其各自的大小如下:

  1. vosk-model-small-en-us-0.15(大小:40M)

  2. vosk-model-en-us-0.22(大小:1.8G)

  3. vosk-model-en-us-0.22-lgraph(大小:128M)

  4. vosk-model-en-us-0.42-gigaspeech(大小:2.3G)

比较模型性能

在对含有丰富口音和复杂句子的 数据集 上评估四种 Vosk 模型后,我们观察到了它们性能的显著差异。就准确性而言,最佳模型是 0.42-gigaspeech 和 0.22,其中后者相比更小的 0.15 和 0.22-lgraph 模型的准确性提高了约 20%。这种改进可以归因于 0.42-gigaspeech 和 0.22 模型的更大尺寸,使它们能够更好地处理各种口音和复杂的语言结构。

图 2:每个测试模型的词错误率(WER)(图片由作者提供)

在执行时间方面,0.22 和 0.15 模型表现最佳,完成转录过程大约需要 150 秒。另一方面,0.22-lgraph 模型所需时间较长,超过 750 秒。这突显了准确性和速度之间的有趣权衡,0.22 模型作为一个吸引人的选择,在性能和准确性之间达到了良好的平衡。

图 3:每个测试模型的执行时间(图片由作者提供)

考虑到结果,0.22 模型提供了准确性和效率的有希望的组合,使其适用于广泛的应用场景。

结论

在这篇文章中,我们评估了四种不同的 Vosk 语音识别模型,以比较它们在准确性和执行时间方面的表现。我们观察到,0.42-gigaspeech 和 0.22 模型的准确性优越,其中 0.22 模型比较小的 0.15 和 0.22-lgraph 模型表现出 20%的改进。这一改进归因于 0.42-gigaspeech 和 0.22 模型的更大尺寸,使它们能够更好地处理不同的口音和复杂的语言结构。

在考虑执行时间时,0.22 和 0.15 模型表现最佳。特别是 0.22 模型,作为一个吸引人的选择,它在性能和准确性之间达到了良好的平衡。需要注意的是,选择最佳模型取决于每个项目的具体要求。始终考虑速度和准确性之间的权衡。

保持联系:LinkedIn

想成为更好的数据科学家吗?写编程教程!

原文:towardsdatascience.com/want-to-be-a-better-data-scientist-write-coding-tutorials-9c1312897633

提升你的技术和沟通技能,学习编写可读的代码,并开始写关于任何话题的文章。

Conor O'SullivanTowards Data Science Conor O'Sullivan

·发布于Towards Data Science ·阅读时间 5 分钟·2023 年 4 月 15 日

--

Mimi Thian拍摄的照片,发布在Unsplash上。

当我刚开始写作时,我几乎不会编程。我的一点 Python 经验来自大学项目。与此同时,我认为自己是一个出色的写作者!现在回头看,我对早期的一些文章感到羞愧。

这使我意识到,写教程提升了我的技术沟通技能。最终,它让我成为了一个更好的数据科学家。我想分享我的经验,并讨论一些具体的好处。这包括编写可读的代码,并提供写作困难话题的第一步。

编程

技术技能对开发人员和数据科学家显然很重要。同时,我们的工作领域不断变化。这意味着我们需要跟上最新的工具。这可能既困难又耗时,因此需要真正的承诺才能不断学习。

写作激励我不断学习新的技术技能,并对这些主题进行深入了解。

写作是一种很好的激励方式。我不仅可以学习新东西,还可以将这些经验分享给世界。这种感觉令人上瘾——有人阅读和互动你的作品。不断发布新文章的愿望促使我不断学习新知识。

不仅如此,我发现写作是最好的学习方式。通常,只有在尝试解释某些东西之后,我才意识到自己实际上并不理解它。此外,我总是力求为一个主题增加价值。引入新颖性需要良好的理解。通过这种方式,写作成为了我知识的检验。这推动我真正理解我所写的技术概念。

编写可读的代码

一个相关的技能是编写可读的代码。好的代码应该自我解释。同样,基于可读代码的教程更容易编写。我花在解释代码做了什么的时间更少,而且通常你根本不需要解释。我发现这种好处扩展到了行业合作中。

任何傻瓜都可以写出计算机能理解的代码。优秀的程序员编写人类能理解的代码。

— 马丁·福勒

一个例子来自我最近的一篇文章——使用 SHAP 调试 PyTorch 图像回归模型。在教程中,我处理了一个 5 维数组中的 SHAP 值。我想用包的一个函数来可视化这个数组。为此,数组首先需要重新排序。最初,代码是这样的:

# Reshape shap values for plotting
shap_numpy = [np.swapaxes(np.swapaxes(s, 1, -1), 1, 2) for s in shap_values]

嵌套的swapaxes函数解释起来并不有趣。简而言之,代码将数组的第 3 维与第 5 维进行了转置。我发现自己不得不写一大段文字来解释代码是如何做到这一点的。因此,我重新编写了代码:

# Reshape shap values for plotting
shap_numpy = list(np.array(shap_values).transpose(0,1,3,4,2))

转置函数更直观,代码也更容易解释。当为教程编写代码时,我总是寻找这样的例子。可读的代码使得写作过程更加顺畅,教程也更易于理解。

我发现这个技能在与其他专业人士合作时特别有用。你无法逃避交接和代码审查。在这些过程中解释代码与在在线教程中解释代码没有区别。最终,编写可读的代码意味着我花在向同事解释代码上的时间更少。

写作

当我刚开始工作时,我迅速意识到非技术技能也同样重要。你不仅需要取得结果,还需要解释这些结果和你的过程。我必须每天撰写电子邮件、演示文稿或技术文档。没有办法逃避写作!

…传统上,不同的人在职业生涯中选择不同的路径——有些人更偏向技术性,有些人则更具创意和沟通能力。数据科学家必须兼具这两者。

―莫妮卡·罗加提

编写编码教程是很好的实践。写得越多,我在工作中的沟通能力就越强。复杂的分析变得更容易解释,我需要澄清的工作也少了。我迅速看到了明显的好处。然而,这只是开始。

使用教程作为写作的起点

与其他文章相比,编程教程更容易编写。没有深奥的思考或细致的论证。你只需解释代码。这意味着它们可能是进入更复杂写作的一种方式。

写作是需要练习才能变得擅长的。教程帮助我迈出了第一步。我开始尝试在说明和结论中添加吸引人的故事。通过这些磕磕绊绊的过程,我开始转向不同类型的文章。

在更加自信的步伐下,我开始撰写基于数据科学家经验的文章。这些文章基于更抽象的概念、我的个人经历和感受。我发现这些比任何编程教程都难写。然而,如果没有那些最初的教程,我不会达到现在的水平。

回顾过去,编写编程教程带来了许多好处。我提高了技术知识,学会了编写可读的代码。编写教程还让我感到自信,可以写几乎任何内容。我还没有提到对我的声誉和财务补偿的好处。

所以,如果你对写作感兴趣,编程教程是一个很好的起点。如果你在想法上挣扎,你可能会觉得这篇文章很有用:

## 永不枯竭的文章主题:5 个可靠来源

回顾过去的项目、你想学习的东西以及你的职业和个人经历

writingcooperative.com

希望你喜欢这篇文章!你可以通过成为我的推荐会员来支持我😃

## 通过我的推荐链接加入 Medium — Conor O’Sullivan

作为 Medium 会员,你的部分会员费会分配给你阅读的作者,并且你可以完全访问每一个故事…

conorosullyds.medium.com

| Twitter | YouTube | Newsletter — 免费注册以获得Python SHAP 课程的访问权限

想提升你的短期预测?试试需求感知

原文:towardsdatascience.com/want-to-improve-your-short-term-forecasting-try-demand-sensing-50baa4380de3

当传统的预测方法在准确性上达到瓶颈时,我们如何推动进一步的改进?

Ramkumar KTowards Data Science Ramkumar K

·发布在Towards Data Science ·12 分钟阅读·2023 年 6 月 20 日

--

照片由JJ Ying拍摄,发布在Unsplash上。

介绍

需求预测是一个估算组织在未来某一时间范围内销售情况的过程。短期需求预测通常考虑 1–3 个月的时间范围,而中期预测可以涵盖 6–18 个月。长期预测通常可以达到 3–5 年。预测帮助企业决定销售什么、何时销售以及销售多少,持有多少库存,并确定未来在容量上的投资以应对动态的客户需求。公司通常依赖于历史趋势,并结合客户的反馈,同时考虑促销活动或清仓销售来创建需求预测。

需求预测重要的原因有几个。它位于销售与运营规划(S&OP)过程的顶端,在这个阶段生成的预测会传递到其他阶段,包括供应规划、生产调度、物流规划和库存优化。需求预测的准确性至关重要,以避免由于库存过多或过少而产生的成本。预测过高可能导致过多的流动资金被锁定在库存中。另一方面,持续的预测不足可能会导致库存短缺或需要在紧急情况下使用更昂贵的原材料进行订单处理,并且需要在短时间内通过更昂贵的运输进行发货。准确的计划有助于避免这些情况,通过驱动在正确的地点和时间制造适量的产品,促进高服务水平和降低储存成本。

挑战在预测中

“预测是非常困难的,特别是当它涉及未来时。”

这句名言通常归于 20 世纪的杰出物理学家尼尔斯·玻尔(虽然是否确实是他所说还有一些争议),虽然这是对预测的轻松看法,但它突显了预测的内在挑战。除了无法预测未来,还有其他与预测方法相关的挑战。

· 商业环境的变化 — 例如,替代品可能会取代某个产品,从而导致其需求下降。或者,产品的新应用可能会导致需求相比历史趋势上升。

· 商业模式的变化 — 组织可能会改变其运营模式和商业战略。例如,一家化工公司可能选择将其业务从普通化学品转向更多的特种产品,因此历史需求模式可能不再适用。

· 数据可用性 — 历史销售数据、客户和产品层级数据以及实时订单数据可能存储在不同的系统中。

· 数据质量 — 这可能包括由于输入错误导致的不准确数据,或数据在不同数据元素之间以不同且不一致的粒度进行捕获的问题。

预测方法

Chris Liverani 拍摄的照片,刊登在 Unsplash

预测可以基于定量或定性方法。定量方法主要是时间序列分析,我们尝试基于历史数据捕捉趋势(例如增长、季节性)。在其他定量情况下,我们可能会构建经济计量模型,将需求预测与业务相关因素相关联。采用定性方法时,我们依赖于“群体智慧”,并尝试基于专家的集体意见或调查来估计未来。网络上有许多关于预测技术的有见地的资源;以下是部分示例:

[## 需求预测方法终极指南:提升销售和优化库存 - nexocode

在我们的指南中发现需求预测的秘密!了解方法、挑战、好处以及人工智能的作用……

nexocode.com](https://nexocode.com/blog/posts/what-is-demand-forecasting/?source=post_page-----50baa4380de3--------------------------------) [## 需求预测:你需要知道的一切

对于在快速增长或动荡市场中的公司来说,需求预测至关重要,因为它帮助他们了解未来的……

www.netsuite.com](https://www.netsuite.com/portal/resource/articles/inventory-management/demand-forecasting.shtml?source=post_page-----50baa4380de3--------------------------------) [## 如何选择合适的预测技术

每位经理应了解不同类型的预测及其使用时机。

hbr.org](https://hbr.org/1971/07/how-to-choose-the-right-forecasting-technique?source=post_page-----50baa4380de3--------------------------------) [## 6 种需求预测及其预期收益

需求预测帮助企业做出更明智的库存和能力决策。我们回顾了需求的类型…

www.thefulfillmentlab.com](https://www.thefulfillmentlab.com/blog/demand-forecasting?source=post_page-----50baa4380de3--------------------------------)

短期需求感知

短期需求感知是一种利用领先指标预测产品销售的预测技术,主要在短期内进行预测。它结合了历史数据和实时信息,以每日或每周为单位进行预测。通过这种方式,它捕捉到市场中的一些关键动态,尤其是在波动时期。因此,它帮助计划人员调整生产和物流计划,使预测更精确,从而提高供应链的韧性,并减少库存和运输成本。关于需求感知的在线资源有很多,以下是一些例子:

[## 什么是需求感知 - AI/ML 解决方案与服务 | 顶级 Google Cloud 合作伙伴

参数 传统需求预测 需求感知 传统的需求预测方法依赖于历史数据…

pluto7.com](https://pluto7.com/what-is-demand-sensing/?source=post_page-----50baa4380de3--------------------------------) [## 文章 - Kearney

编辑描述

www.kearney.com](https://www.kearney.com/service/analytics/article/-/insights/modern-retail-requires-modern-demand-sensing?source=post_page-----50baa4380de3--------------------------------)

需求感知预计将具有很高的经济价值(在节省成本或避免收入损失方面),仅仅因为运输量的巨大。由于预测的粒度和刷新频率,需求感知可能在数据和计算上非常密集。但是随着计算能力的提升,预计可行性会很高。需求感知的结果通常具有较高的解释性,因为我们通常使用基于线性回归的模型进行这些应用。结果往往可以分析得很清楚,从而向利益相关者解释预测。需求感知提供的预测更新建议是可操作的,因为更改生产基于预测变化是组织的内部决策。需求感知应用在输入数据刷新方面也大多是可持续的,因为它们依赖于每日生成的实时订单数据。

一个简化的需求感知方法

需求感知依赖相关的领先指标来估计销售预测。客户订单的下达速度可能是短期需求的一个领先指标。在一些行业,如石化行业,客户通常会提前几周下订单以进行预定。在本文中,我们讨论了一种基于客户订单的需求感知方法,适用于化工公司。

在这种方法中,前提是如果订单的下达速度比历史订单下达趋势更快,最终的月需求量将会很高,反之亦然。建议的做法是通过在每个月中旬进行客户订单趋势分析,以预测下个月的产品需求,从而增强传统的预测过程。这种提前的洞察对于供应链和产品经理在调整生产和定价方面将非常有帮助。分析还会识别那些可能下订单低于预测的客户,从而使剩余的量可以提供给那些希望购买超出其预测量的客户。这将有助于主动“调换”两个客户群体之间的产品,减少订单阻塞和延迟,并提升客户体验。

为了构建一个需求感知用例的机器学习解决方案,我们遵循一系列步骤,包括数据收集、探索性数据分析、数据处理(清洗和特征工程)、模型开发和优化、可操作的洞察以及建议。主要目标是基于客户订单属性,以给定的粒度(例如产品系列、客户类别)预测当前和下个月的需求。每个步骤的详细信息列在下面:

a. 数据收集 — 根据在商品公司环境中这一用例的典型情况,我们假设每个产品(或产品系列)都有数十或数百个客户提前下订单。为了捕捉客户订单的年度和季节性趋势,我们收集至少过去 36 个月的数据。我们收集包括请求量、销售订单日期、需求预定月份、客户信息(包括客户类别和地理位置)、产品属性(包括产品系列、市场细分)的销售订单。我们从需求预定月份开始,寻找从前一个月的第一个工作日(CM-1)到需求预定月份结束(CM)期间每天(工作日,排除周末和节假日)的总产品需求量。这假设在该日期之前没有订单(前一个月的第一个工作日)。我们还需要从分析中去除取消订单或退货订单。表 1 显示了数据框中的样本数据。

表 1. 来自历史销售订单的样本数据(数据框格式)

WD — 工作日

b. 探索性数据分析 — 我们首先了解数据的大小(行和列)以及特征的数量和类型(数值型 vs 分类型)。我们还识别每列中的空值数量。我们通过直方图和箱线图可视化数值列,以查看数据的形状(包括均值、中位数、偏度、异常值),通过条形图可视化分类数据,以确认唯一值并识别需要处理的任何异常值。

c. 数据处理 — 在此步骤中,我们去除异常值(例如,数值列中的负值或极高值)。我们还选择特征并进行特征工程。在这个用例中,我们选择的特征是在预测变量之上的更高层次的聚合。例如,如果我们预测产品系列需求,我们选择市场细分、地理位置、累计订单量和每月基线销售预测作为预测特征。给定工作日的累计订单(表 2)是通过日订单量作为特征工程的一部分得出的。图 1 显示了累计订单如何随工作日变化的示例。

表 2. 历史订单数据框(具有特征工程属性)

图 1. 选择月份的工作日累计订单百分比

d. 模型开发与优化 — 推荐使用多元线性回归来处理这种情况。预计这是一个‘分段’解决方案,其中我们为每个工作日有不同的回归函数。通过 36 个月的数据,每个产品系列有数百个客户,我们将为每个产品系列拥有数千个训练数据点。我们从定义损失函数开始,以帮助我们建立提供最准确需求预测的模型。我们选择几个准确性测量指标,包括平均绝对误差(MAE)、平均绝对百分比误差(MAPE)和 R2,并测试不同模型在这些指标上的表现(我们希望 R2 高而误差低)。原始误差只是月度需求预测与产品系列历史实际值之间的差异。在数据准备方面,我们首先将数据分为训练集(80%的数据)和测试集(20%的数据)。缺失或空值在每个数据集中分别处理,以避免数据泄露。如果缺失值占特征的大部分,我们可能会完全删除该特征,因为它几乎没有预测能力。如果空值只出现在少数几行中,我们可以删除这些缺失值的行。我们也可以用中央趋势来填补缺失值,比如列的中位数(如果是数值型)或众数(如果是分类变量)。此外,我们还将分类变量转换为独热编码的数值格式。为了将数据缩放到线性回归模型中,我们将因变量(每月需求预测)除以基线销售预测,并将累计订单(自变量)除以基线销售预测。回归模型系数提供了特征在解释预测变量变化中的重要性。

e. 可操作的见解和建议 — AI 应用预测的需求可能高于或低于基线销售预测。为向利益相关者解释结果,一种方法是将历史订单曲线与实时订单进行比较(见图 2)。

图 2. 累计订单百分比比较:历史数据与实时数据

这里仅展示了 3 个月的历史累计订单百分比曲线以作说明;在实际讨论中,我们会包含至少 12 个月的数据。

在该图中,历史累计订单百分比曲线以实线绘制,而实时累计订单(作为下个月基线销售预测的百分比)则以虚线绘制。我们可以看到,在选择的历史月份中,大约 12%的总需求在前一个月的第 10 个工作日已下单,但我们当前的趋势约为 5%的预测,表明需求比基线预测预期的要低。以此例子为例,通过更新需求预测获得利益相关者的支持后,我们可以通知决策者减少相关产品系列的生产,同时识别出下单低于其提供的预测的客户。一般来说,预测可以每天运行,以向制造部门提供生产和库存信号,并向销售团队提供需求弱点或强度的信号。人工智能/机器学习模型可以每季度重新训练一次或在业务重组时进行重新训练。

经济价值估算

图片由 Ibrahim Boran 提供,来自 Unsplash

预测不准确的货币化思路可以通过库存短缺导致的收入损失和由于过剩未售库存而增加的储存成本来考虑。虽然预测波动在较长时间内可能会平衡,但预测的一致性偏差可能会导致产品组合的不平衡。短期库存短缺的收入损失可能对业务产生长期影响,如果客户选择永久离开组织而转向竞争对手。我们通过下表中的简单例子来说明收入损失,其中一个关键假设是组织没有足够的库存来覆盖预测不准确性。该表提供了基线预测(未应用人工智能)和每月来自客户的实际需求,涵盖了 10 个产品系列:PF1 到 PF10。每个产品系列的价格也提供了。这些数字的规模代表了商品化学品。

表 3. 假设性示例以说明由于预测不准确而导致的收入损失

我们可以看到,对于一些产品,我们的预测过高(预测 > 实际),而对于其他产品,我们的预测过低(预测 < 实际)。对于预测不足的产品,我们假设缺乏库存来弥补这一不足,并通过将价格与缺口相乘来计算损失的收入。总的损失收入估计约为 ~$58MM。通过一个能够利用每日实时订单感知未来每月需求的 AI 应用,更新预测并生产适量的产品,我们可以减少这一损失收入。即便预测误差改善 20%(这种应用中并不罕见),组织每月的损失收入也会减少$11.6MM。

总结

使用实时客户订单进行短期需求感知可能比传统预测方法更进一步,因为它利用实时信息来提高预测的准确性。不过,我们需要注意的是,这种方法可能并不适用于所有用例或业务情况。当订购模式有一定规律且订单提前下达时,这种方法效果最佳。结合市场情报来理解观察背后的商业洞察,这种技术效果更佳。由于客户通常不会提前下单超过 6-8 周,因此该方法不适用于更长期的预测。

本文中描述的方法也可以用于其他目的。例如,我们可以使用这种方法来估计每个客户/产品组合之间的预期需求和实际订单的偏差。这可以帮助识别那些下单量过少或过多的客户,这些订单量与其基线销售预测相比偏离了历史订购模式。

最后,我们希望建立机制,以便在更新的预测可用时采取行动。这可能包括增加/减少生产量或跟进那些超出预测分配量或尚未提取任何量的客户。

感谢阅读。希望你觉得这篇文章有用。欢迎将你的评论发送至 rkumar5680@gmail.com。我们可以在 LinkedIn 上联系。

注意你的束搜索超参数

原文:towardsdatascience.com/watch-out-for-your-beam-search-hyperparameters-9c4daf6668d6

默认值永远不是最佳的

Benjamin MarieTowards Data Science Benjamin Marie

·发表于Towards Data Science ·阅读时间 6 分钟·2023 年 1 月 11 日

--

图片由Paulius Dragunas提供,来源于Unsplash

在使用神经模型开发应用时,尝试不同的超参数来训练模型是很常见的。

例如,学习率、学习计划和丢弃率是对模型学习曲线产生重要影响的超参数。

更少见的是最佳解码超参数的搜索。如果你阅读深度学习教程或处理自然语言处理应用的科学论文,很可能用于推理的超参数甚至未被提及

大多数作者,包括我自己,不会费心寻找最佳解码超参数,而是使用默认值。

然而,这些超参数实际上可能对结果产生显著影响,无论你使用什么解码算法,总会有一些需要微调以获得更好结果的超参数

在这篇博客文章中,我展示了使用简单 Python 示例和机器翻译应用程序的解码超参数的影响。我专注于束搜索,因为这是迄今为止最受欢迎的解码算法,以及两个特定的超参数。

框架和要求

为了展示每个超参数的效果和重要性,我将展示一些使用Hugging Face Transformers 包在 Python 中生成的示例。

要安装此包,请在终端中运行以下命令(我建议在单独的 conda 环境中执行):

pip install transformers

我将使用 GPT-2(MIT 许可证)生成简单句子。

我还将使用 Marian (MIT 许可证) 运行其他机器翻译示例。我在 Ubuntu 20.04 上安装了它,按照官方说明

Beam Size 和 Length Penalty

Beam search 可能是语言生成任务中最受欢迎的解码算法。

它在每一步,即为每个新生成的标记,保持模型推断中最可能的k 个假设,其余的假设被丢弃。

最终,在解码结束时,概率最高的假设将作为输出。

k,通常称为“beam size”,是一个非常重要的超参数。

更高的k会得到更可能的假设。注意,当k=1 时,我们称之为“贪心搜索”,因为我们只保留每一步中最可能的假设。

默认情况下,在大多数应用中,k任意设置在 1 到 10 之间。这个值可能看起来非常低。

这有两个主要原因:

  • 增加 k 会增加解码时间和内存需求。换句话说,它变得更加昂贵。

  • 更高的 k 可能会产生更可能但更差的结果。这主要是由于假设的长度,但不仅仅是由于长度。较长的假设往往概率较低,因此 beam search 会倾向于促进较短的假设,这对于某些应用可能不太可能。

第一点可以通过进行更好的批量解码和投资更好的硬件来直接解决。

长度偏差可以通过另一个超参数来控制,该超参数通过每一步的长度(标记数)来标准化假设的概率。执行这种标准化的方法有很多。最常用的方程之一是由Wu et al. (2016) 提出的:

lp(Y) = (5 + |Y|)α / (5 + 1)α

其中 |Y| 是假设的长度,α 是一个通常设置在 0.5 和 1.0 之间的超参数。

然后,分数 lp(Y) 用来修改假设的概率,以便在给定 α 的情况下,偏向于解码并生成较长或较短的假设。

Hugging Face transformers 中的实现可能略有不同,但有一个α可以作为“length_penalty”传递给generate函数,如以下示例所示(改编自Transformers’ documentation):

from transformers import AutoTokenizer, AutoModelForCausalLM

#Download and load the tokenizer and model for gpt2
tokenizer = AutoTokenizer.from_pretrained("gpt2")
model = AutoModelForCausalLM.from_pretrained("gpt2")

#Prompt that will initiate the inference
prompt = "Today I believe we can finally"

#Encoding the prompt with tokenizer
input_ids = tokenizer(prompt, return_tensors="pt").input_ids

#Generate up to 30 tokens
outputs = model.generate(input_ids, length_penalty=0.5, num_beams=4, max_length=20)

#Decode the output into something readable
print(tokenizer.batch_decode(outputs, skip_special_tokens=True))

这个代码示例中的“num_beams”是我们的另一个超参数k

使用这个代码示例,提示“Today I believe we can finally”,k=4 和 α=0.5 时,我们得到:

outputs = model.generate(input_ids, length_penalty=0.5, num_beams=4, max_length=20)
Today I believe we can finally get to the point where we can make the world a better place.

当 k=50 和 α=1.0 时,我们得到:

outputs = model.generate(input_ids, length_penalty=1.0, num_beams=50, max_length=30)
Today I believe we can finally get to where we need to be," he said.\n\n"

你可以看到结果并不完全相同。

kα应在你的目标任务上独立微调**,使用一些开发数据集。

让我们在机器翻译中举一个具体的例子,看看如何进行简单的网格搜索来找到最佳超参数及其在实际应用中的影响。

机器翻译实验

在这些实验中,我使用了 Marian 和训练在 TILDE RAPID 语料库(CC-BY 4.0)上的机器翻译模型进行法语到英语的翻译。

我仅使用了数据集的前 100k 行进行训练,最后的 6k 行作为开发测试集。我将开发测试集分成两部分,每部分 3k 行:第一部分用于验证,第二部分用于评估。注意:RAPID 语料库的句子按字母顺序排列。因此,我的训练/开发测试集划分在实际使用案例中并不理想。我建议在划分语料库之前,先打乱语料库的行顺序,同时保留句子对。在本文中,我保持了字母顺序,并没有打乱,以使以下实验更具可重复性。

我使用 COMET(Apache 许可证 2.0)来评估翻译质量。

要通过网格搜索来寻找 kα 的最佳值对,我们首先必须定义每个超参数的一组值,然后尝试所有可能的组合。

由于我们在这里搜索的是解码超参数,因此这一搜索相对快速且直接,与搜索训练超参数相比。

我为此任务选择的值集如下:

  • k: {1,2,4,10,20,50,100}

  • α: {0.5,0.6,0.7,0.8,1.0,1.1,1.2}

我将机器翻译中默认使用的最常见值加粗。对于大多数自然语言生成任务,应该尝试这些值集,除了 k=100,通常这个值不容易产生最佳结果,同时解码代价较高。

我们有 7 个 k 的值和 7 个 α 的值。我们想尝试所有组合,所以我们需要对评估数据集进行 7*7=49 次解码。

我们可以通过一个简单的 bash 脚本来实现:

for k in 1 2 4 10 20 50 100 ; do
  for a in 0.5 0.6 0.7 0.8 0.9 1.0 1.1 1.2 ; do
    marian-decoder -m model.npz -n $a -b $k  -c model.npz.decoder.yml < test.fr > test.en
  done;
done;

然后,对每个解码输出运行 COMET 以评估翻译质量。

根据所有结果,我们可以绘制出每对值的 COMET 分数表:

作者提供的表格

如你所见,使用默认超参数(下划线)获得的结果低于 26 个其他超参数值获得的结果。

实际上,所有加粗的结果在统计上都显著优于默认结果。注意:在这些实验中,我使用了测试集来计算表中展示的结果。在实际情况中,这些结果应该在另一个开发/验证集上计算,以决定在测试集上使用的值对,或用于真实世界应用。

因此,对于你的应用程序,确实值得微调解码超参数,以在付出非常小的工程努力的情况下获得更好的结果。

结论

在这篇文章中,我们只调整了 beam search 的两个超参数。还应微调更多参数。

其他解码算法,如温度采样和核采样,具有一些超参数,你可能想要查看这些参数,而不是使用默认值。

显然,随着我们增加超参数的数量进行调整,网格搜索的成本会更高。只有你在应用中的经验和实验才能告诉你是否值得对特定的超参数进行调整,以及哪些值更有可能产生令人满意的结果。

水接触时间与浓缩咖啡中的萃取:一个实验

原文:towardsdatascience.com/water-contact-time-and-extraction-in-espresso-an-experiment-9987bd24d35d?source=collection_archive---------18-----------------------#2023-02-10

咖啡数据科学

一个短期实验以隔离变量

Robert McKeon AloeTowards Data Science Robert McKeon Aloe

·

关注 发表在 Towards Data Science ·5 分钟阅读·2023 年 2 月 10 日

--

咖啡是一种奇妙的饮料,像茶一样,需要一定的浸泡时间来提取其精华。这段浸泡时间或水接触时间需要与从咖啡中提取的风味平衡。在浓缩咖啡中,这尤其具有挑战性,因为水在较短的浸泡时间内以压力流过咖啡,比其他冲泡方法更具挑战。

有一种理论认为,较高的水接触时间会导致浓缩咖啡中的提取率更高。虽然有人对这种观点提出了异议,但像许多事情一样,这个理论是可以测试的。关键是设计一个良好的实验(DOE),所以我们来设计一个实验并收集一些数据来开始回答这个问题。

总溶解固体 (TDS) 使用折射仪测量,这个数字与射击的输出重量和咖啡的输入重量结合使用,以确定杯中提取的咖啡百分比,称为提取产率 (EY)。这是我们试图测量的主要变量。

DOE:修改研磨颗粒大小

最简单的实验设计是修改研磨颗粒大小,这将减慢流量。然而,这会混合两个其他变量:

  1. 较小的研磨颗粒会在局部层面上更快地提取。

  2. 较小的研磨颗粒更容易受到通道效应的影响,从而在全球层面上导致提取不足。

EY 和时间与研磨颗粒大小的关系,所有图像均由作者提供

在这两个变量之间是提取产率的火山图。因此,如果你使用了这个实验,你会看到随着研磨变小,提取产率上升直到某个峰值,之后提取产率会下降。从这样的实验中可能得出较长的水接触时间不会导致更高提取的结论,而这个结论是不准确的。

所以实验必须更好,并减少变量。

DOE:使用流量控制

使用带有流量控制的浓缩咖啡机(例如我拥有的 Decent Espresso (DE)),可以使用单一的研磨度,并进行 3 种不同的流量配置。这可以控制由于颗粒分布变化导致的提取速率变化。

恒定流量控制的电子邮件。

然而,这仍然可能受到群头设计的影响。许多机器在水进入篮子时将水推到边缘,从而导致侧面通道效应。DE 由于水分配器的独特水分布导致水在左侧稍微比右侧流入得快。

DOE:流量控制 + 混合废咖啡

为了减少水输入变量,我们可以使用一些废咖啡。废咖啡不容易受到通道效应的影响,因为它没有 CO2 和可提取的溶解物质很少。因此,我们可以混合单一咖啡研磨度,并使用多种流量配置。

另一个改进是拉取一种萨拉米咖啡,以便更好地理解提取速率。

测试用废咖啡

对于这个测试,我制作了一些使用过的咖啡,与以前的测试一样。然而,我认为可以借此机会在更大实验前获取一些数据。这些咖啡渣来自多个使用过的咖啡饼,我将它们彻底混合在一起。然后,我打算进行 2:1 的萃取并分成两个杯子。然而,第一个萃取时间稍长,所以我对其他两个萃取保持了相同的比例。

这个结果表明,较高的流速会降低 EY,并且通常支持水接触时间更长更好的观点(即较慢的流速)。

然后我对这些咖啡饼进行了 4 ml/s 105C 的萃取,直到液体变清。我把咖啡饼晾干,并通过一个 800um 的 Kruve 筛网去除任何结块。

那么让我们进入大实验吧。

大实验

这个实验是在 Decent Espresso 机器上完成的,使用了 3 种不同的平流速率控制曲线。我在 90C 下进行这些萃取,因为我想避免过多的蒸汽,因为蒸汽对咖啡的影响仍在被发现。

然后我将新鲜研磨的咖啡与使用过的咖啡混合,并进行简单的 WDT 和自动水平压实。8 克新鲜咖啡与 13 克使用过的咖啡混合。

我在 1 ml/s 的流量下对使用过的咖啡进行了对照萃取,以去除使用过的咖啡对其他测量的影响。

提取过程使用了 5 杯来处理三种流量曲线。对于 TDS,尽管 4 ml/s 的样品提取时间稍长,但每个样品的 TDS 趋势仍然较高。这一结果由 EY 标准化。

4 ml/s 流量的提取结果难以得到相同的输出重量。我还去除了这些累计 EY 数字中使用过的咖啡渣的影响。

添加了 Pump&Dump 作为参考。

这些结果显示,随着流量的增加,提取产率会下降。这在所有的萃取比例中都成立,并支持了较长水接触时间能够提取更多咖啡的观点。

咖啡的提取在浓缩咖啡中具有挑战性,因为有许多变量相互影响。我希望这个实验能帮助揭示如何将单一变量隔离并进行检查。这个实验表明,较长的水接触时间会导致更高的提取,而以前对接触时间的看法与细磨浓缩咖啡的通道效应混淆在一起。

这个实验也可以只使用新鲜咖啡进行重复,这将是一个有趣的实验。我不确定其他变量如何可能混淆测量结果。

如果你喜欢,可以在TwitterYouTubeInstagram上关注我,我会发布各种机器上的浓缩咖啡镜头和相关内容。你还可以在LinkedIn找到我,也可以在Medium订阅上关注我。

进一步阅读

我的书

我的链接

浓缩咖啡文章合集

工作与学校故事合集

我们应该早就看到 ChatGPT 了

原文:towardsdatascience.com/we-should-have-seen-chatgpt-coming-9292b4648174

观点

我们这些年来一直在为此做贡献

Samantha HodderTowards Data Science Samantha Hodder

·发表在 Towards Data Science ·10 分钟阅读·2023 年 2 月 9 日

--

图片来自 Susan WilkinsonUnsplash

我的姐夫是英国一所顶尖大学的教授,教授商学院的创新研究。了解 ChatGPT 后,我丈夫问他对这件事的看法:

嗯,有一段时间,人们担心汽车发明后,所有的马会怎样

… 在汽车发明之后。

我不知道你发现 ChatGPT 时在哪里

我在海滩上度假,与我的青少年孩子们开玩笑,谈论一个看似不切实际的时尚行业商业创意。

青少年们都说,不,那是个愚蠢的想法,我的朋友说:“哦,是吗,让我们看看这个想法到底有多愚蠢吧!

他拿出手机,在搜索栏中输入一个简单的短语,然后点击纸飞机图标。

立即,闪烁的光标开始以流畅和准确的方式解释这个“愚蠢的想法”。它有示例和细节,引用了实际的人物和项目。随后,它开始概述一个相当有说服力的商业计划。

我不是投资者;我撰写创意,并将其作为项目和故事向人们和机构推介。但这个解释,加上附带的工作流程、合理性和人口统计分析,足够好到我可以将文本拆分、设计成幻灯片,稍加点缀,走进任何董事会进行推介。

这让我有种奇怪的感觉。

我们应该预料到 ChatGPT 吗?

近十年来,我一直将自己的语音采访输入 AI 转录机器……无论如何,我都不想手动完成,或按每分钟音频 1.00–2.00 美元的当时费用请别人做……一个 45 分钟的采访可能需要高达 90.00 美元的转录费用,直到 2017 年。在我的工作中,一小时只是记录片或音频项目所需转录采访时间的一小部分。直到最近,这一直是需要考虑的费用项。

我找到的最早的一个大约在 2013 年,与IBM Watson 项目有关……我记得它需要一些奇怪的登录协议,然后你必须去演示,点击 JSON 选项卡,上传 MP3 文件,然后等待转录结果。

Watson 听不清楚口音;它更喜欢标准的中西部英语,语法和发音正确。当我开始处理需要转录重澳大利亚口音的项目时,我发现转录结果既有趣又无用;整理转录文本的时间和从头转录的时间差不多。Watson 也明显无法识别英语以外的其他语言。

当我最初开始使用 Watson 时,我发现考虑这些机器学习文件会在哪里结束有些微妙的趣味,但我没有深入研究。今天,当我在谷歌上搜索这个问题时,我发现我上传的 Watson 转录采访可能在某种程度上推动了一些视频游戏的发展。

很久以前,我会随意使用“机器学习”这个术语来解释这些转录工具为何越来越好;尽管我不完全理解这意味着什么,也不清楚它会发展到哪里,尽管我已经读过并基本接受了 Donna Haraway 在Cyborg Manifesto中阐述的观点。

当我意识到这些‘机器’在完成工作方面变得越来越出色时,我短暂地自我庆贺了一下,觉得自己也在这里完成了工作;所有那些从各种来源的采访中获得的有用数据。也许这是我对这项工作的女性主义回应。

对我而言,这是一种免费的帮助。我点击了上传,然后下载。非常感谢

最近,我使用了 Otter.ai、Descript 以及较少使用的 Sonix.ai。对我来说,这些程序简直是救星:免费转录(每月“免费”账户有时间或字数限制)用于音频采访,否则需要我用当时的工具如Wreally花费数小时,或花费数百美元请别人做。

但随着 ChatGPT 和其他 AI 写作工具的出现,我恍若大悟。我现在明白了那些工作的去处;这些转录软件平台都对NLP(自然语言处理)做出了贡献。

我上传的那些访谈时长,使得“机器”能够排序发音和重音,区分辞令和方言,然后观察和计算重复的词组……它们都对建立一个庞大的数据库起到了很大帮助,这个数据库让机器能够学习人类的语言和思维方式。

而且,猜猜看,你也在做出贡献。

在最近使用过的 NLP 技术旁边给自己打个小勾:

  • Siri 语音转文本请求

  • Alexa 相关

  • 嘿 Google……给我展示一个……的食谱

  • Apple.com 技术支持聊天机器人

  • 谷歌翻译

  • Grammarly

  • 预测文本

  • Netflix 推荐

  • 遵循建议

  • 转录软件

这只是显而易见的部分。如果你想深入了解这个领域,还有很多更深层次的内容。

如果我只看转录软件,我可以说在短短几年内,我见证了准确率的巨大提升。它们从只能准确转录那些清晰且分开的单词发展到现在:可以以大约 90%的准确率转录四方对话,其中包括不同口音的说话者,包括非英语母语者。

我曾经犯过这种“头埋沙子”的错误

在这些“早期的互联网时代”,即上世纪初,公众与技术以及控制和创造技术的公司互动的方式截然不同。

以谷歌为例:在 2004 年公开上市之前,对于非硅谷内部人士来说,谷歌只是一个简洁、零广告的单页搜索引擎,你可以提出基本问题,并获得基本答案。谷歌并不是从一开始就具备从门铃到硬盘的端到端解决方案的。

Google 搜索的早期仅能提供来自网站的信息(那时的网站是个新概念)。或者是从已经上传到互联网上的现有文本,或为互联网新创建的文本(那时也不多)。再加上你必须考虑数据速率……谁还记得拨号上网的声音?互联网刚开始时是小众的。

学者们依然局限于实际的图书馆和精装书,或者在黑暗的房间里翻阅微缩胶卷做研究,这种情况持续了十年。维基百科刚刚从 1990 年代的概念起步,到 2001 年上线时才真正起步。

早期的互联网足以发现人名、已发布的内容、旅行信息和在 Mapquest 上打印出冗长的驾驶说明……它还不像今天这样存在着广泛的信息池。

还有另一点需要考虑……当时的计算机并不是“个人”的。计算机主要用于工作,通常是在工作场所,如果你家里有一台,它们通常会放在角落的桌子上,盖上防尘罩。除非你能买得起昂贵的 Macbook,否则“笔记本电脑”更像是可折叠的台式机,其价格是其他任何计算机的五倍。

在 2018 年,网站 24/7 Wall St 发布了一项分析 ,分析了根据出生年份计算计算机的成本,然后调整了通胀。如果你出生于 1978 年,著名的 IBM 5110 的价格接近 10000 美元,调整通胀后超过 38000 美元。

在 2001 年,一台 Apple Powerbook G4 的价格是 3500 美元,调整通胀后几乎达到了 5000 美元;在 2002 年,一台 Toshiba Satellite 1995 的价格是 2499 美元,调整通胀后约为 3500 美元。在 2018 年(使用这种相同方法的最后一年),一台 Huawei Matebook Pro 的价格仅为 1200 美元……而今天,如果你想订购一台新款的配备 M2 芯片的 Macbook Air,入门级价格为 1199 美元。

将计算机视为除昂贵但必要工具以外的东西需要远见;这是在 2000 年代初大多数人所不具备的。

要解释一些人的局限性,我只需照照镜子。2001 年,当我在 SXSW 互动节上展示我的前沿互动项目时,我错过了 Eric Schmidt 的主题演讲。我甚至在这个世界里工作过,那是在 2000 年首个互联网泡沫破灭后的初期计算机混乱时期,而我实际上记得曾对我的同事们大声说:

一个关于搜索引擎的演讲有什么有趣的呢?!

这是我在这个阶段如何合理化这个严重错误的方式:世界大致分为极客和非极客。极客理解计算机的力量、相关性和重要性。极客能看出计算机最终会触及每个人和一切;非极客仍在电影院里,看书,狂看《24》和《黑道家族》的 DVD 套装,或在他们的 PVR 上录制定时电视节目。像我这样的某些人甚至使用计算机创造了讲故事的新方式……

是的,我在 2001 年德克萨斯州奥斯汀的会议上去喝了免费的咖啡,而 Eric Schmidt 正在给一个小型礼堂做主题演讲。就是这样。我已经接受了这个事实。

这个故事在某种程度上揭示了我的年龄——快 50 岁了——但它也揭示了另一点:虽然我一直在媒体领域工作,这个领域与技术密不可分,但我必须也要承认,我也参与了它们的建设。

我是的,你可能也是,曾经是那些喂养聊天机器人的人之一。我甚至在某种意义上因为这样做而获得了报酬(通过获取免费的转录)。我是自愿和半知情地这样做的。

直到现在,我才看到这一切的重要性。我还看到,借助事后的洞察,基于所有的语音命令、面试交流和偏好选择,我们已经喂养了“机器”十年。而我们所诞生的正是我们应有的预期:

一种具有自然和本地语言能力的人工智能聊天机器人,包括模式和连接,具有深度和创新的想法,由丰富的客户数据支持……还有一个完整的社交媒体营销计划。

这不正好总结了现代人类/媒体/企业家的现状吗?

我们应该感到害怕吗?

我们应该担心计算和技术的这一演变吗?将其称为改变生活是激进的吗,还是只是为了引起头条的夸张说法?

回到文章开头的那个见解:

嗯,曾经有人担心所有的马会发生什么事情。

……在汽车发明之后。

你自己问问自己:你愿意为了上班而回到骑马通勤的时代吗?你下一次骑马度假会感到愉快吗?

显然,汽车的到来完全重新排序了我们对文明的所有认知:它决定了我们如何生活、住在哪里、如何工作、在哪里工作以及我们如何娱乐。汽车还帮助我们破坏了大气层,并加速了气候变化。

但我们应该害怕吗?我们应该害怕人工智能聊天机器人的到来来帮助我们完成工作吗?

这是一个更复杂的问题,但并不是完全可以忽视并当作工匠的复仇。

现在我们拥有一个多世纪的信息来分析汽车的到来对我们社会产生的影响,我坚守这个观点:

是的,我们应该意识到,甚至略微感到害怕,新的发明会取代以前或现有的系统。

但这并不意味着我们应该希望它们消失;想象没有汽车的文明基本上是荒谬的。

也许看待像 ChatGPT 这样的工具(包括它自己的 GTP-3,据说 将轻松超越 1.0 版本的能力)的方式是向前看的……而不是回头看马厩的大门。

其他的会出现,而且很快。谷歌在 2023 年 2 月 8 日直播了一场活动……这通常不是谷歌年度日历上的日期……毫无意外,我们了解到谷歌的竞争对手 ChatGPT,谷歌 Bard 即将推出。显然,他们对在人工智能聊天机器人挑战中被超越感到威胁。

人工智能聊天机器人需要一种不同的技术方法——不仅仅是兴奋地抓住然后跑掉。

也许更重要的是创建一个安全使用的文化,然后建立一套规则和行为规范来规范其使用。这些机器人将促使我们变得更加聪明,既要识别出人与机器人的区别……也要知道何时使用它们来提高效率,并以增加我们自身生产力的方式使用它们。它们还会让我们变得懒惰,就像技术已经做到的那样(我以前能记住大约 100 个电话号码……现在只剩下约五个了)。

就像汽车催生了郊区一样,AI 机器人肯定会让我们形成新的生活习惯和工作流程。AI 机器人无疑会影响教育、创业、信息和文案写作行业……仅仅是我在自己的经验领域中看到的一些例子。

不知怎么的,或许甚至违背了我们自己的判断,我们将不得不将 AI 聊天机器人视为我们所生活的知识和信息经济的显而易见的演变。

确实,考虑到这只是一个开始令人感到气馁;安全带并不是汽车最初设计的一部分。但汽车变得更快,道路变得更长更直,限速提高了,汽车的使用模式也发生了变化。车祸一直是现实;但在有人分析了数据并意识到一个小发明——安全带——可以拯救生命之后,法律被修改了,使用模式也被调整了。结果,许多生命得到了拯救。

ChatGTP(以及后续的其他机器人)的安全带测试是什么?

所以,是的。是的,我们应该早就预料到 ChatGTP,因为我们这些年来一直在帮助创建它。我们通过各种节省时间或便利的技术互动来实现这一点。

但与其试图想象它不存在,或在它已经到来后我们可以改变它,不如我们应该适应它,让它为我们服务而不是与我们对抗。并且想办法因为它而变得更聪明,或者减少工作量。

Samantha Hodder 是一位音频制作人和作家。如果你和我一样喜欢叙事播客,请订阅我的 Substack Bingeworthy

[## 想要听到更多来自 Samantha Hodder 的内容吗?

想要听到更多来自 Samantha Hodder 的内容吗?请点击我的链接关注我的个人资料,或者订阅以接收通知……

samanthahodder.medium.com](https://samanthahodder.medium.com/subscribe?source=post_page-----9292b4648174--------------------------------)

Web Speech API:什么有效,什么无效,以及如何通过将其与 GPT 语言模型连接来改进它

原文:towardsdatascience.com/web-speech-api-what-works-what-doesnt-and-how-to-improve-it-by-linking-it-to-a-gpt-language-dc1afde54ced

系列文章的一部分,探讨现代人工智能和其他技术如何帮助更高效的人机交互

LucianoSphere (Luciano Abriata, PhD)Towards Data Science LucianoSphere (Luciano Abriata, PhD)

·发表于Towards Data Science ·阅读时间 15 分钟·2023 年 12 月 6 日

--

照片由palesa提供,来源于Unsplash

我认为现代技术使得人机交互变得比目前的软件所提供的要简单和自然得多。实际上,我认为技术已经足够成熟,我们可以不依赖传统接口,向用户体验的革命迈进。

大型语言模型无疑引发了这场革命的一个阶段,特别是在我们询问信息的方式上。然而,我认为技术仍然可以提供更多。例如,尽管虚拟现实头显的成本在降低,我们仍然主要使用平面屏幕;尽管眼动追踪、语音识别和身体部位追踪等技术已达到较高水平,我们仍然使用鼠标、键盘和触控手势来操作设备;尽管语音合成技术取得了重大进展,我们仍然在大量阅读。

我认为,当前的技术已经足够成熟,能够提供几乎像《星际迷航》中那样的人机交互(如果你不明白我的意思,请查看这个),然而我们却仍然想停留在过去。

在这篇文章中,我开始了一系列短文,专注于现代技术如何使人机交互发生根本性改变,这些技术已经非常成熟,你将通过我分享的代码片段和示例应用来亲自测试。

忠于我的风格,我将特别讨论这些现代技术的基于网页的实现。我将从集成到网页浏览器中的 Web Speech API 开始,讨论其功能,展示一些用例,强调其局限性,并举例说明如何通过将其与大型语言模型结合来克服这些局限性。

本系列基于我最近参与的一个项目,旨在构建一种首创的网络应用程序,提供沉浸式、多用户的分子图形和建模功能,名为 HandMol:

[## 结合四种 AI 模型以提供终极沉浸式可视化和建模体验

继续阅读关于这款名为 HandMol 的新免费应用程序如何实现沉浸式、协作式的可视化和建模…

pub.towardsai.net](https://pub.towardsai.net/coupling-four-ai-models-to-deliver-the-ultimate-experience-in-immersive-visualization-and-modeling-9f52a4bd1443?source=post_page-----dc1afde54ced--------------------------------)

(现代)语音识别和语音合成

特别是语音识别和语音合成这两项技术,已经存在近二十年,并在推动更自然的人机互动方面提供了很多可能性。

语音识别,或称 ASR(自动语音识别)或 STT(语音转文本),将口语语言转换为书面文本。它有两个主要的广泛应用:

  • 通过口头指令控制如智能手机或计算机等硬件,最好以自然的方式进行。想象一下你如何通过语音命令使用智能手机、Alexa 或 Siri。

  • 转录(或许随后显示、存储或分析)对话中所说的内容。考虑一下会议转录、视频字幕等。

这两个应用程序直接相关于本博客文章的主题,并通过 Web Speech API 实现了对网页程序员的支持。

语音合成,或称 TTS(文本转语音),将书面文本转换为口语语言。它使计算机和其他设备能够生成类似人类的语音,使信息能够以听觉方式访问,就像你在 Medium 文章中看到的那样。

语音合成在各种场景中都有应用,包括为视力障碍用户提供的辅助功能、交互式语音响应系统以及多媒体内容的丰富化。

语音转录(STT)和语音合成(TTS)使与数字内容的互动更加包容和多样化,开辟了免提和免屏操作以及个性化用户体验的机会。

语音识别和语音合成技术的简要历史

语音识别和合成在近年来取得了显著进展,特别是随着现代 AI 模型的整合和机器学习技术的进步。它们可以追溯到 20 世纪中期,当时首次尝试使用计算机进行语言处理。早期模型在处理口音、方言、同音词和语音细微差别时面临挑战,无论是在语音生成还是理解方面。统计模型和符号自然语言处理的进步逐步改善了 ASR 系统,但在 2010 年代末期,随着变换器的引入,尤其是对 ASR 的突破性进展:通过利用注意机制,新的语音识别方法能够捕捉长期依赖关系和上下文理解,从而显著提高了语音转文本转换的准确性。

STT 比 TTS 更复杂一些,因为需要考虑更多的变量。然而,最现代的方法表现非常出色。虽然不深入细节,但现代 STT 涉及一个复杂的过程,多个阶段和 AI 模型协同工作。关键阶段包括音频输入的预处理、特征提取、音素提取、语言模型决策和解码成单词序列。现代 ASR 模型通常在所有阶段使用变换器,保留信息中的长期耦合,以提高准确性和连贯性。最先进的 ASR 系统包括直接内置在核心模块中的语言模型元素;这种原生集成被证明对高转录和识别准确性至关重要。

现代 ASR 和 TTS 技术确实能做得远远不止单纯的语音识别或合成,实际上接近于“对口语的理解”。比如,最先进的 STT 和 TTS 模型可以将音频转录为文本或从文本合成音频,支持多种语言,有些甚至能够自动识别语言,适应上下文,检测或模拟不同的说话者,用时间戳注释转录词汇,处理标点符号和非语言发声,允许自定义词典等。

如果你对 Web Speech API 中所有这些功能以及在你的 Web 应用中利用它们感到兴奋,你需要了解一些限制,这可能会让你失望,因为浏览器支持的功能还不是最先进的。然而,幸运的是,将 Web Speech API 与大型语言模型结合使用可以缓解这些问题,就像许多现代 ASR 和 TTS 技术一样,我将在这里通过编程使用 GPT-3.5-turbo 或 GPT-4 来展示这一点。如果这还不够,你还会发现有些公司提供他们自己的(付费)API 来进行最先进的 ASR 和 TTS。

Web Speech API、其组件及其可用性

Web Speech API 是一个网络标准,允许 web 应用将语音数据融入其功能中。它有两个部分:SpeechRecognition,允许语音输入和识别,以及 SpeechSynthesis,允许语音输出和合成。

Web Speech API 最早由 Google 在 2010 年提出,并在 2013 年的 Chrome 25 中实现。从那时起,它得到了其他浏览器的支持,但兼容性和功能性各不相同。根据 caniuse.com 的报告,截至 2023 年 12 月,支持情况非常不均衡,尤其是在语音识别方面:

截图来自caniuse.com/?search=web%20speech%20api

根据我的经验,我发现 API 的语音识别模块仅在 Safari 和 Chrome 中表现良好,包括它们的 iOS 和 Android 版本。请注意,其他基于 Chromium 的浏览器,如 Brave 或 Oculus Browser(Meta 的 Quest 虚拟现实浏览器)不支持语音识别。这是因为 Google 的语音识别服务是专有的,需要许可证使用,而 Google 不授予其他浏览器使用许可证。值得注意的是,由于 Chrome 中的语音识别由基于云计算的系统处理,以用户隐私为中心的浏览器如 Brave 将面临一个艰难的决定,如果 Google 允许它们使用自己的资源进行语音识别。哦,顺便提一下,谈到隐私,请注意,所有通过 Web Speech API 进行的语音识别都需要调用的网页通过 https 提供服务!

与语音识别相反,语音合成在计算机上的所有主要浏览器(除了已被 Microsoft 的 Edge 替代的旧版 Internet Explorer,它现在支持语音合成)和大多数智能手机浏览器中都能得到妥善处理。对于 TTS,当前不强制要求 https。

接下来,我将专注于 Web Speech API 以及如何在 Chrome 中使用它,尽管原则上核心元素在所有其他支持该 API 的浏览器中应该工作相同。

使用 Chrome 的 Web Speech API

要以编程方式使用 Web Speech API,你需要创建 SpeechRecognition 或 SpeechSynthesis 接口的实例,具体取决于你想使用语音输入还是输出——或者你也可以创建两者,并在同一个应用中使用它们!

语音识别

例如,要创建一个语音识别对象,你可以简单地这样做:

var recognition = new SpeechRecognition();

然而,你最好检查一下 ASR 在浏览器中是否实际上已启用。然后,最简单的代码块看起来如下:

const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;

window.onload = function () {
  if (typeof SpeechRecognition === “undefined”) {  //Check browser can do speech recognition
    console.log(“Speech api failed”);
  } else {
    console.log(“Speech api ok”);
    const recognition = new SpeechRecognition();  //Create speech recogn object
    recognition.continuous = true;                //Define behaviour and properties, for ex. ask for continuous ASR,
    recognition.interimResults = true;            //Show partial results of ASR (i.e. when results are not yet final because speech recognition keeps going as audio progresses)
    recognition.lang = "en-US";                   //Language must be defined upfront
    recognition.onresult = (event) => {           //Triggered when a word or sentence has been recognized
      const res = event.results[last];            //If there's a list of several recognized words/sentences, retrieve the last one
      var text = res[0].transcript.trim();        //Extract and clean up text
      … //Process text
    }
    recognition.start();            //With all setup ready, start recognition
  }
}

你可以使用如上所示的对象的方法和属性来控制语音识别服务,并以最佳方式使用它。最常用的命令和属性包括startstopabortlanginterimResults等。你还可以添加事件监听器来处理对象触发的事件,例如onstartonendonresultonerror等。

一个特别值得关注的属性,遗憾的是因为负面的原因,是“grammars”。语音识别的“grammars”应该允许一个进行 ASR 的代码理解它通常无法理解或排名较低的词汇。这个功能对于纠正发音和使用名字、行话、地方表达等尤其重要。你可以在这里找到一些信息,但我不会深入细节,因为……它确实不起作用,很多人对此表示抱怨;此外,还有一个整体的趋势是从 API 中删除“grammars”,因为目前没有浏览器支持它(见这里)。

要了解有关 SpeechRecognition 对象的属性和事件的更多信息,查看此处

以及如何使用 Web 语音 API 进行语音识别的全球完整示例,请查看这个官方示例,它展示了如何通过口头命令更改网页的背景颜色:

## dom-examples/web-speech-api/speech-color-changer/script.js at main · mdn/dom-examples

附带各种 MDN DOM 和 Web API 文档页面的代码示例……

github.com

语音合成

类似地,要创建一个语音合成对象,你可以写:

var synthesis = window.speechSynthesis;

然后,你可以创建SpeechSynthesisUtterance接口的实例,这些实例代表你希望合成的特定语音请求。你可以设置 utterance 的属性,例如文本、声音、语速、音调、音量等。你可以使用对象的方法和属性来控制语音合成服务,例如 speak、pause、resume、cancel、getVoices 等。你还可以添加事件监听器来处理 utterance 触发的事件,例如 onstart、onend、onerror 等。例如,要合成文本并在开始和结束时记录日志,你可以这样写:

var utterance = new SpeechSynthesisUtterance(‘Hello world, I'm talking thanks to the Web Speech API!’);
utterance.onstart = function(event) {
  console.log(‘Speech started’);
};
utterance.onend = function(event) {
  console.log(‘Speech ended’);
};
synthesis.speak(utterance);

我在我的 Web 应用程序中真正喜欢做的是创建一个可以接收字符串并将其朗读出来的函数。我称这个函数为 speakUp(),它看起来是这样的:

function speakup(TextToSpeak) {
  if (“speechSynthesis” in window) {                            //Check TTS is supported
    const toSpeak = new SpeechSynthesisUtterance(TextToSpeak);  //Create utterance
    toSpeak.lang = “en-US”;                                     //Set language
    window.speechSynthesis.speak(toSpeak);                      //Speak!
  } else {
    console.log(“Speech synthesis not supported by browser.”);
  }
}

通过 Web Speech API 进行 ASR 和 TTS 的问题,以及如何使用大型语言模型纠正其中的一些问题

Web Speech API 使用起来非常简单,如你所见。它也是免费的,不需要任何 API 密钥,也没有调用次数和频率的限制。

然而,通过反复尝试,我发现系统经常出现故障,尤其是在 ASR 方面。此外,API 有时似乎会自行关闭,许多人对此提出了问题但没有明确的解决方案。最糟糕的是,虽然免费的 API 在某些应用中可以使用,但无论是语音识别还是合成,都远未达到最先进的水平。与我在介绍中提到的现代 ASR 系统相比,Chrome 的 ASR 服务几乎无法提供任何实质性的功能!

语音识别的准确性和可靠性都不高,也不耐受口音和方言。即使有一些噪音,它也几乎没有用。它无法自动检测语言,无法识别同一对话中的多个人,标点处理还可以,但对声音化表达感到困惑等。

语音识别服务存在隐私和安全问题,因为语音数据被传输到外部服务器或第三方,而未经用户同意或了解。

语音合成服务的声音不够自然或富有表现力,尤其是对于英语以外的语言。

此外,正如我们所见,语音识别和合成服务在浏览器和设备上非常依赖,可能在不同的平台和地区不可用或不一致。

由于其能力有限,它们可能会带来伦理和社会影响,如偏见、歧视、欺骗、操控或冒充。

作为开发者和用户,你应该意识到这些局限性和挑战,并负责任且恰当地使用 Web Speech API。

通过使用大型语言模型缓解语音识别问题

上述问题中,与 ASR 相关的问题是最重要的。解决这些问题中的许多需要在最基础的识别层面采取行动。然而,与转录准确性和术语补全相关的最重要的问题可以通过大型语言模型解决,正如我通过 GPT-3.5-turbo 或 GPT-4 在 JavaScript 中编程实现的那样。

这如何工作

本质上,你通过一个提示调用语言模型,解释输入内容的样子和这些输入的输出应该是什么,然后是来自 API 识别的实际(原始)转录。

触发所有这些工作的 Web 应用程序中,语音识别用于触发命令。例如,如果用户说“放大”或“扩大”或类似的命令,那么可视化(该应用程序用于分子图形)必须放大。该应用程序的提示如下:

let theprompt = [];         //Initializing an array that will contain the prompt

theprompt.push({
  role: "system",           //Tell the mode what it will be doing
  content: "You receive texts from speech recognition and act accordingly by triggering commands, effectively correcting speech recognition as in the examples provided below. If you don't understand the request or the request is not in the list, you run the command didntUnderstand()",
  });

theprompt.push(                                      //Provide examples from hereon
 { role: “user”, content: “Make molecules bigger” },
 { role: “assistant”, content: “scale(+)” }
);
theprompt.push(
 { role: "user", content: "Zoom in" },
 { role: "assistant", content: "scale(+)" }
);
theprompt.push(
 { role: "user", content: "Enlarge" },
 { role: "assistant", content: "scale(+)" }
);
theprompt.push(
 { role: "user", content: "Zoom out" },
 { role: "assistant", content: "scale(-)" }
);
theprompt.push(
 { role: "user", content: "Make smaller" },
 { role: "assistant", content: "scale(-)" }
);

让我们详细了解一下。以下是提示的系统元素:

你从语音识别中接收文本并据此执行命令,实际上纠正语音识别,如下面提供的示例。如果你不理解请求或请求不在列表中,你将运行命令 didntUnderstand()。

然后,看看用户/助手对的示例如何提供可能的输入,这些输入会产生相同或相关的输出,例如“放大”和“扩大”都导致调用 scale(+),而“缩小”调用 scale(-)。

在代码的其他部分,你会发现一些条目“教”语言模型以一种可以防止程序崩溃的方式来纠正输入,同时增加产生正确输出的机会。例如,我说的“最小化”经常被识别为“mini mice”,“ANI”这个非标准英语单词被识别为“Annie”。然后我可以用这样的示例来指导语言模型:

theprompt.push(
 { role: "user", content: "Minimize with ANI" },
 { role: "assistant", content: "minimize(ANI)" }
);
theprompt.push(
 { role: "user", content: "Minimize with Annie" },
 { role: "assistant", content: "minimize(ANI)" }
);
theprompt.push(
 { role: "user", content: "Mini mice with Annie" },
 { role: "assistant", content: "minimize(ANI)" }
);
...etc.

这个技巧效果非常好,这并不奇怪,因为归根结底,这正是现代语言模型如 Whisper 的核心,这些模型将语言模型直接嵌入到语音识别过程中!

在结束这一部分时,为了完整性,当然完整的提示必须包含在从语言模型获取的承诺中,在我的情况下,通常是 OpenAI 的 GPT-3.5-turbo 或 GPT-4:

fetch(`https://api.openai.com/v1/chat/completions`, {    //Main call to speech API
  body: JSON.stringify({
  model: “gpt-3.5-turbo”,                     //Or GPT-4, as of December 2023
  messages: theprompt,                    //The prompt just created
  temperature: 0,                         //Keep this low to avoid hallucination
  max_tokens: 20,                         //The outputs should be small commands, so this should be low
}),
  method: “POST”,
  headers: {
    “content-type”: “application/json”,
    Authorization: “Bearer “ + stringWithYourAPIKey,    //API key from openAI for GPT models!
  },
}).then((response) => {
  if (response.ok) {
    response.json().then((json) => {
    var command = json.choices[0].message.content.trim();    //Extract text, which will contain commands
    console.log(command);
    if (command == ....                 //List and execute tasks 

Chrome 的 Web Speech API 的一些应用案例

除了触发这一系列博客文章的应用程序(在这里),我还可以与你分享其他使用语音识别和/或合成 API 的项目:

在这个示例中,我结合了 Chrome 的语音识别功能和 GPT-3,创建了一个从你的口述笔记和指南中编写电子邮件的 Web 应用程序:

[## 一个基于 GPT-3 的自动化电子邮件写作 Web 应用程序,来自语音笔记

我将 Chrome 的语音识别引擎与 GPT-3 结合起来,创建了一个从你的口述笔记中编写电子邮件的 Web 应用程序……

pub.towardsai.net

在这里,我展示了如何构建一个类似 chatGPT 的机器人,它可以听你说话并口头回复;同样,这将 Chrome 的 Web Speech API 用于识别和合成,与 GPT-3 作为驱动聊天机器人“脑力”的语言模型结合:

## 将 GPT-3 与语音识别和合成结合,实现一个完全对话的聊天机器人...

我是如何创建这个网页应用的,你可以自然地与 GPT-3 谈论任何你想要的话题,全基于网页的...

towardsdatascience.com

在这个其他示例中,使用 Chrome 的语音识别功能来控制一个网页应用,在这种情况下使用 GPT-3 将口头请求转化为命令:

## 通过将语音转化为命令来控制网页应用,与 GPT-3 一起使用

最后一篇文章展示了 GPT-3 的实际应用,详细解释了工作流程和细节...

towardsdatascience.com

超越 Web Speech API

我在上面描述了某些网页浏览器不支持语音合成,大多数也不支持语音识别。我还解释了 Chrome 的内置语音 API 并不出色,尤其是对于语音识别,并且这些限制的一些问题可以通过语言模型来克服;然而,并非所有问题都可以用这种策略解决,因此许多现代 ASR 系统具有的功能是完全缺失的。

在这种情况下,了解浏览器可能支持语音识别和合成是重要的,通过使用替代服务或解决方案——这些服务或解决方案是付费的,相比于 Chrome 的免费 API,原则上更强大。

仅提及一些提供此 API 服务的公司,可以查看 Gladia、Speechly、AssemblyAI、Deepgram、Spechmatics(这个有一个很棒的示例在这里),以及其他一些公司。即使是 Google 也有一个与他们在 Chrome 中免费提供的系统不同的 ASR 系统,它显然效果更好,其他科技巨头如 Microsoft 和 AWS 也通过 API 提供了他们自己的产品。你甚至可以下载 OpenAI 的开源 Whisper,并设置一个专门为你运行的服务,甚至可以根据你的需求进行定制——不过你还是直接去找一个通过 API 提供的公司,比如Gladia.io

当然,除非你做的是封闭实现(例如在本地服务器上使用 Whisper),否则大多数这些服务都需要你将音频发送到他们的服务器,这可能会危及隐私。然而,对于非敏感任务来说,它们可能是一个完美的选择,即使在许多情况下成本相对较低。

进一步阅读

[## Web Speech API - Web APIs | MDN

Web Speech API 使你能够将语音数据集成到网络应用程序中。Web Speech API 有两个部分…

developer.mozilla.org](https://developer.mozilla.org/en-US/docs/Web/API/Web_Speech_API?source=post_page-----dc1afde54ced--------------------------------) [## Using the Web Speech API - Web APIs | MDN

语音识别涉及通过设备的麦克风接收语音,然后由语音…

developer.mozilla.org](https://developer.mozilla.org/en-US/docs/Web/API/Web_Speech_API/Using_the_Web_Speech_API?source=post_page-----dc1afde54ced--------------------------------)

www.lucianoabriata.com 我写关于我广泛兴趣领域的一切:自然、科学、技术、编程等。 订阅以获取我的新故事 通过电子邮件。要 咨询小型工作 请查看我的 服务页面在这里。你可以 在这里联系我 你可以 在这里给我小费.

权重衰减在没有残差连接的情况下能有效吗?

原文:towardsdatascience.com/weight-decay-is-useless-without-residual-connections-ef65197e5944?source=collection_archive---------13-----------------------#2023-02-21

残差连接如何秘密地对抗过拟合?

Guy DarTowards Data Science Guy Dar

·

关注 发布于 Towards Data Science ·9 min read·2023 年 2 月 21 日

--

图片由 ThisisEngineering RAEng 提供,来源于 Unsplash

引言

在这篇文章中,我们将用数学方法(使用简单的数学,别担心!)展示如果没有残差连接,LayerNorm 可能会导致神经网络的过拟合问题。过拟合是机器学习中的一个严重问题,科学家们真的希望避免这种情况。粗略来说,过拟合意味着网络记住了训练集,而不是学习任务并推广到新的未见数据上。权重衰减是一种用于对抗过拟合的正则化技术。然而,我们将展示在相当标准的前馈网络中,它们需要残差连接才能有效(在下面的解释中我会进一步澄清)。残差连接以其在反向传播过程中稳定训练的作用而闻名。另一方面,Normalization 层(如 LayerNorm)则在输入通过网络层时稳定输入。Normalization 层的想法是我们希望内部表示的范数保持在一定范围内。在 LayerNorm 中,我们通过其范数来除以每个内部表示向量(此时我省略了一些细节)。一些先前的工作建议将 LayerNorm 添加到残差网络中[Liu et al, 2020],这有助于提高它们的性能。我们的研究则是另一个方向——为什么从理论上讲,你可能不应该在没有残差连接的情况下使用 LayerNorm。实际上,即使是后规范残差连接(无论那是什么意思……)也会遭遇同样的问题。

从广义上讲,思想相当简单:通过将权重衰减设得非常小(除了最后一层,它虽然令人头疼,但仍使大部分权重衰减变得无用),我们可以使权重衰减几乎没有实际用处。简单回顾一下什么是权重衰减:权重衰减是一种正则化技术,用于防止神经网络收敛到不能推广到未见数据的解决方案(即过拟合)。如果我们训练神经网络只去最小化训练数据上的损失,我们可能会找到一个专门为这特定数据及其特性量身定制的解决方案。为避免这种情况,我们添加一个与网络权重矩阵的范数相关的项。这旨在鼓励优化过程收敛到可能对训练数据不是最优的解决方案,但在范数上具有较小权重矩阵的解决方案。其思路是,具有高范数权重的模型不够自然,可能试图拟合特定的数据点以进一步降低损失。在某种程度上,这是一种将奥卡姆剃刀(哲学观点认为简单的解决方案可能是正确的)集成到损失中的方式——其中简单性由权重的范数来体现。我们在这里不会讨论权重衰减的更深层次的理论依据。

TL;DR:在这篇文章中,我们展示了在没有残差连接的 ReLU 前馈网络中,添加 LayerNorm 后,权重衰减正则化不会改变最优损失值(*除了讨厌的最后一层,我们稍后会讨论为什么我们认为这还不够)。

理论游戏时间

ReLU 网络的正尺度性

线性网络和 ReLU 网络具有以下尺度特性:设 a > 0 为正标量。那么 ReLU(ax) = a ReLU(x)。最终,在任何由矩阵乘法堆叠后跟 ReLU 激活组成的网络中,这个属性仍然有效。这是最普通的神经网络——没有归一化层,也没有残差连接。然而,这种之前曾广泛存在的前馈 (FF) 网络展示了这样一种结构化行为确实令人惊讶:将输入乘以正标量,结果输出正好按相同的因子缩放。这就是我们所称的 (正向) 尺度等变性(这意味着输入的尺度变换会传递到输出的尺度变换,而 不变性 则表示输入的尺度变化不会对输出产生影响)。但还有更多:如果我们在过程中对任何权重矩阵(以及相应的偏置项)进行同样的操作——效果也是一样的:输出将按相同因子放大。不错吧?当然。但是我们能利用它吗?让我们看看。

让我们看看添加 LayerNorm 后会发生什么。首先,什么是 LayerNorm?简单回顾一下:

其中 µx 条目的平均值, 表示逐元素乘法,β, γ 是向量。

那么,当我们添加 LayerNorm 时,尺度特性会发生什么变化?当然,在添加 LayerNorm 之前,情况不会改变,因此如果我们在此之前将权重矩阵缩放了 a > 0,那么 LayerNorm 的输入会被 a 缩放,然后发生的情况是:

所以,我们得到一个新的属性,这次尺度缩放只是使输出 保持不变—— 正尺度 不变性。而且,这即将变得令人遗憾……

注意: 当我们讨论 LayerNorm 时,其他形式的归一化,如 BatchNorm,满足正尺度不变性属性,因此它们也像 LayerNorm 一样容易受到讨论中提到的问题的影响。

如何完全消失

让我们提醒自己我们正在尝试最小化什么:

其中训练集表示为一组 {(x_i, y_i)} 的对,神经网络的参数(权重)fΘ 指定。这个表达式由两部分组成:需要最小化的经验损失——神经网络在训练集上的损失,以及旨在使模型达到“更简单”解决方案的正则化项。在这种情况下,简单性被量化为网络权重具有低范数。

但问题在于,我们发现了一种绕过权重规模限制的方法。我们可以将每个权重矩阵按任意小的因子进行缩放,仍然能得到相同的输出。换句话说——函数 f,即原始网络和缩放网络实现的函数是完全相同的!内部可能不同,但输出是相同的。这适用于每一个具有这种架构的网络,不管参数的实际值是什么。聪明的读者可能会注意到β, γ也是参数,因此也应考虑,但由于下一个 LayerNorm 的尺度不变性,它们也可以被缩放(*除了那个恼人的最后一层)。

记住,我们的目标是对未见数据进行泛化。如果正则化项趋近于零,网络就可以自由地过拟合训练数据,正则化项也就变得无用。正如我们所见,对于每一个具有这种架构的网络,我们可以设计一个等效的网络(即计算完全相同的函数),其权重矩阵范数可以任意小,这意味着正则化项可以趋近于零而不影响经验损失项。换句话说,我们可以去掉权重衰减项,它不会有太大影响。

最后一层的技术细节仍然是我们面临的一个小问题,我们不能去掉它的权重衰减项,因为最后一层通常没有跟随 LayerNorm,而且:最后的 LayerNorm 无法重新缩放,因为它后面没有任何 LayerNorm,因此我们还要考虑它的β, γ。所以我们剩下的只有最后一层的范数和 LayerNorm 的参数。为什么这并不是那么糟糕?过拟合可能发生在整个网络中,因此我们可以几乎所有参数进行过拟合。更重要的是,模型的内部层是学习关注点的特征提取器,而最后一层是对学习到的特征进行分类的分类器。至少从直观上看,它在过拟合中的作用可能相比于特征提取要小得多。

还有一句警告:尽管理论上,模型应该找到一个过拟合训练数据的解决方案,但观察到优化可能会收敛到泛化解决方案,即使没有显式正则化。这与优化算法有关。我们使用局部优化算法,例如梯度下降、SGD、Adam、AdaGrad 等。它们不能保证收敛到最全局最优的解决方案。这有时反而是一种福气。一项有趣的研究(例如,[Neyshabur, 2017])表明,即使没有显式正则化,这些算法也属于隐式正则化的一种形式!虽然并非万无一失,但有时模型会收敛到一个泛化解决方案——即使没有正则化项!

残差连接如何解决这个问题?

让我提醒你什么是残差连接。残差连接将层的输入加到输出上。如果该层正在计算的原始函数是 f(x) = ReLU(Wx),那么新函数是 x + f(x)

现在,这一新层的权重缩放特性被打破了。这是因为在表达式的残差部分前没有学习到系数。因此,f(x) 部分由于权重缩放而被一个常数缩放,但x 部分保持不变。现在,当我们对其应用 LayerNorm 时,缩放因子无法再被抵消:LayerNorm(x + a f(x)) ≠ LayerNorm(x + f(x))。重要的是,只有在残差连接应用在 LayerNorm 之前 时才会出现这种情况。如果我们先应用 LayerNorm,然后再进行残差连接,则会发现我们仍然获得 LayerNorm 的缩放不变性:x + LayerNorm(a f(x)) = x + LayerNorm(f(x))

第一个变体通常被称为 pre-norm 变体(更准确地说,实际上是 x + f(LayerNorm(x)) 被称作这种方式,但我们可以将 LayerNorm 归因于前一层,并将下一层的 LayerNorm 视为上面的表达式,除了第一层和最后一层的边缘情况)。第二个变体被称为 post-norm 变体。这些术语常用于 transformer 架构中,而这些超出了本文的范围。然而,值得一提的是,一些研究如 [Xioang et al, 2020] 发现 pre-norm 更易于优化(他们讨论了不同的原因)。然而,请注意这可能与这里讨论的缩放不变性无关。Transformer 预训练数据集通常包含大量数据,过拟合问题变得不那么严重。此外,我们还没有讨论 transformer 架构本身。但这仍然值得考虑。

结论

在本文中,我们观察到了一些没有预归一化残差连接的前馈神经网络的有趣特性。具体来说,我们注意到,如果它们不包含 LayerNorm,它们会将输入缩放和权重缩放传播到输出。如果它们包含 LayerNorm,它们是尺度不变的(除了最后一层),而权重/输入缩放完全不会影响输出。我们利用这一特性展示了这样的网络的最佳解决方案可以避免特征提取中的权重范数惩罚(仅保留分类器惩罚),因此网络可以收敛到一个或多或少相同的函数,这个函数是它在没有这些技术的情况下会收敛的。虽然这是一个关于最优性的声明,但是否这些解决方案实际上是通过梯度下降找到的仍然是一个问题。我们可能会在未来的文章中探讨这一点。我们还讨论了(预归一化)残差连接如何破坏尺度不变性,从而似乎解决了上述理论问题。仍然可能存在一些残差连接无法避免的类似特性,我可能未曾考虑。像往常一样,感谢你的阅读,我们下篇文章见!

参考文献

F. Liu, X. Ren, Z. Zhang, X. Sun, 和 Y. Zou. 重新思考带有层归一化的残差连接,2020.

B. Neyshabur. 深度学习中的隐式正则化,2017. 网址 arxiv.org/abs/1709.01953.

R. Xiong, Y. Yang, D. He, K. Zheng, S. Zheng, C. Xing, H. Zhang, Y. Lan, L. Wang, 和 T.-Y. Liu. 关于 Transformer 架构中的层归一化,2020. 网址 arxiv.org/abs/2002.04745.

使用 Keras 进行测井数据预测的神经网络

原文:towardsdatascience.com/well-log-measurement-prediction-using-neural-networks-with-keras-ef7dfed94077

使用 Keras 预测体积密度(RHOB)的示例,并说明归一化对预测结果的影响

Andy McDonaldTowards Data Science Andy McDonald

·发布于 Towards Data Science ·阅读时间 11 分钟·2023 年 10 月 26 日

--

代表神经网络与自然景观相结合的图像。图像由 DALL-E 3 生成。

全球每天都有大量数据从井中获取。然而,这些数据的质量可能会显著变化,从缺失数据到受到传感器故障和钻孔条件影响的数据。这可能对地下项目的其他部分产生连锁反应,例如延误和不准确的假设与结论。

由于缺失数据是我们在测井数据质量中最常遇到的问题之一,因此已经开发了许多方法和技术来估计值并填补空白。这包括应用机器学习技术——在过去几十年中随着 TensorFlow 和 PyTorch 等库的普及而越来越受欢迎。

在本教程中,我们将使用 Keras,它是一个运行在 TensorFlow 之上的高级神经网络 API。我们将利用它来演示构建机器学习模型的过程,从而允许预测体积密度(RHOB)。这是一个常见的测井测量,但它可能会受到孔眼条件不良的显著影响,或者在某些情况下,工具可能会出现故障,导致关键区间没有测量数据。

我们将从一个非常简单的模型开始,该模型不考虑输入的归一化,这是机器学习工作流程中的一个常见步骤。然后,我们将建立一个具有归一化输入的第二个模型,并说明其对最终预测结果的影响。

导入库和加载数据

本教程的第一步是导入我们将使用的库。

对于本教程,我们需要 4 个库:

这些是按以下方式导入的:

import pandas as pd
from sklearn.model_selection import train_test_split
import tensorflow as tf
import matplotlib.pyplot as plt

一旦导入了库,我们需要加载将用于训练和测试模型的数据。

对于本教程,我们将使用一个包含来自挪威西海岸 Volve 油田 3 口井的系列测井数据的数据集。这些数据来自公开的 Equinor Volve 数据集。

该数据集的完整详细信息可以在文章末尾找到。

要读取我们的 CSV 文件,我们只需调用:

df = pd.read_csv("Data/Volve/VolveNN.csv")
df

当我们查看数据框时,我们可以看到其中包含哪些测井数据,以及数据的前 5 行和最后 5 行。

用于神经网络建模的三个选定 Volve 井的数据框视图。图像由作者提供。

对于本教程,我们将假设所有的数据准备步骤已经完成,并且数据已由岩石物理学家/地球科学家进行了质量检查。

不过,如果我们想要再次检查是否所有列都充满了数据且没有空值行,我们可以调用df.describe()。当我们这样做时,我们需要检查所有列/测量中的计数行是否为 24,111。

值得注意的是,在应用机器学习之前确保数据质量非常重要,因为这可能导致错误和其他问题。

数据拆分为训练和测试

对于本教程,我们将尝试预测体积密度(RHOB)。由于各种原因,这种测井测量有时会在测井数据集中缺失。这些原因包括数据对钻井目标并不重要,或者为了节省钻井和测井成本,数据被简单地排除在外。

因此,我们通常需要使用现有的测井数据集,其中包含 RHOB 测量,以构建一个机器学习模型,该模型可以用于预测其他井中的测量结果,尽管这些井中并未获取这些测量。

我们的下一步是将数据拆分为两个部分。

X变量中放置的数据将作为我们模型的输入,而y包含我们的目标输出——在这种情况下是 RHOB。

# Define feature variables (X) and target variable (y)
X = df[['DTS', 'GR', 'NPHI', 'PEF', 'DT']]
y = df['RHOB']

我们可以继续使用现有的数据进行构建、训练和预测,但我们将无法真正了解模型的表现情况。

这是我们将数据拆分为两个子集的地方。一个子集用于训练模型,另一个子集用于验证和调整模型。理想情况下,我们还会有第三个数据集,用于测试模型在完全未见数据上的表现。

不过,在这个例子中,我们将坚持使用两个子集。

为了拆分数据,我们调用 sklearn 的 train_test_split 方法,并传入我们的 Xy 变量。

我们还将设置拆分比例为 70% 进行训练,其余 30% 用于验证和微调数据。这个比例可以根据数据集的大小进行调整。例如,对于较小的数据集,您可能希望有更大的训练子集。

# Split the dataset into 70% training and 30% testing
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)

我们可以通过检查 X_train 和 X_test 的长度来验证拆分是否成功。

len(X_train), len(X_test)

它返回一个包含子集大小的元组:

(16877, 7234)

在标准工作流程中,我们通常会对数据进行归一化/标准化,以考虑不同的数据范围。然而,对于我们的第一个模型,我们将使用未归一化的数据,然后在第二个模型中应用归一化,以查看是否能改善结果。

构建和训练 Keras 模型

在使用 keras 构建模型时,有两种主要的方式来创建神经网络模型。这些是 Sequential API 和 Functional API 方法。

使用 Sequential 方法,我们只需将层线性地堆叠在一起,而 Functional API 提供了更多灵活性,可以用于创建具有多个输入和输出及共享层的更复杂模型。

在本教程中,我们将使用 Sequential API,因为它是最简单的使用方法,容易上手。

定义 Keras 神经网络模型

要开始使用 Sequential API,我们首先创建模型如下。

在构建神经网络时,最好从简单和小规模开始,逐渐增加复杂性,直到对结果满意。

在这个例子中,我们将创建一个非常简单的神经网络,由一个包含 8 个神经元的隐藏层组成,relu 作为激活函数。这个层通过应用多个权重、偏差和激活函数来转换输入数据,然后将其传递到最终的输出层。这个层设置为提供一个代表声学剪切迟缓曲线的数值输出。

要了解更多关于不同激活函数及其工作原理的信息,我建议查看以下页面:

# Define a simple Neural Network using Keras Sequential API
model = tf.keras.Sequential([
    tf.keras.layers.Dense(8, activation='relu'),
    tf.keras.layers.Dense(1)
])

编译 Keras 神经网络模型

一旦我们定义了模型,接下来需要对其进行编译。这将配置和设置模型如何学习。

为了保持模型简单,我们将使用平均绝对误差(MAE)作为损失函数(用于量化模型对目标特征的表现)和指标(也用于判断模型表现——但如果使用不同的损失函数,它可以是更易于理解的评分)。

我们还将优化器设置为‘Adam’。这是一个常见的优化器模型,用于根据选择的损失函数确定模型如何更新其权重。

# Compile the model
model.compile(loss='mae',
             optimizer='Adam',
             metrics='mae')

拟合/训练 Keras 神经网络模型

创建模型的最后一步是将模型“拟合”到训练数据中。这将开始我们定义模型的训练过程。

我们还将设置训练的周期数为 30。这代表数据在神经网络中的一次完整传递。每次传递后,模型权重会被更新,以最小化所选的损失函数。

在构建模型时,将模型拟合结果保存到历史变量中是一个好主意。这将允许我们绘制结果并记录训练历史。

history = model.fit(X_train, y_train, epochs=30, 
                    validation_data=(X_test, y_test))

一旦我们开始运行模型,我们将获得以下文本输出,详细说明模型的进展以及每个周期的表现。

Keras 神经网络模型训练输出。图像由作者提供。

模型完成后,我们可以通过生成一个 matplotlib 图形来以图形形式查看历史记录。

plt.figure(figsize=(10, 8))
pd.DataFrame(history.history).plot()
plt.xlabel('Epochs')
plt.ylabel('Mean Absolute Error (MAE)')

Keras 神经网络模型训练过程中的损失曲线。图像由作者提供。

在上面的图像中,蓝色曲线(损失)和橙色曲线(mae)分别表示训练损失和性能指标(MAE)。

两条曲线在开始时急剧下降,这表明模型正在学习并改善其在初始周期中的表现。然而,随着周期数的增加,损失和指标的下降变得更加缓慢。这可能表明我们的模型已达到收敛并得到了最终解决方案。

将 Keras 模型应用于测试数据

一旦我们的模型经过训练,我们可以应用该模型并预测测试子集目标特征中的值。

这是通过调用以下代码来完成的。

y_pred = model.predict(X_test)

一旦我们运行这一行,我们将看到 Keras 进行预测。

227/227 [==============================] - 0s 1ms/step

评估模型性能

在模型进行预测后,我们可以通过调用 Keras 中的几个指标来评估其在测试数据上的表现。

这些是平均绝对误差(MAE)——表示实际值和预测值之间的平均绝对差异——和均方根误差(RMSE)——表示实际值和预测值之间的平均误差幅度。

为了将我们预测的变量传递到这些指标中,我们首先需要去除生成结果中的任何额外维度。这确保了y_testy_pred的形状是相同的。

mae_1 = tf.keras.metrics.mae(y_test, tf.squeeze(y_pred)).numpy()
mse_1 = np.sqrt(tf.keras.metrics.mse(y_test, tf.squeeze(y_pred)).numpy()
mae_1, mse_1

当我们查看指标时,我们得到以下分数。

(0.07578269, 0.11054294)

这告诉我们,平均而言,我们的预测结果与实际结果相差 0.0757 g/cc,RMSE 为 0.1105,表明我们有一些结果与实际值差异显著的实例。

误差结果的可视化

仅仅查看指标虽然很好,但仅凭这两个数字来判断我们模型的表现可能会很困难。

我们可以通过实际和真实测量值的简单散点图来可视化我们的结果。

def create_scatter_comparison(ytrue, ypreds):
    # Auto calculate the min and max scales for the data
    minscale = min(ytrue.min(), ypreds.min())*0.95
    maxscale = max(ytrue.max(), ypreds.max())*1.05

    plt.figure(figsize=(10, 10))
    plt.scatter(ytrue, ypreds)

    # Create a 1:1 relationship line
    line_points = np.linspace(minscale, maxscale, 100) 
    plt.plot(line_points, line_points, c='red')

    plt.xlim(minscale, maxscale)
    plt.ylim(minscale, maxscale)
    plt.xlabel('Actual Measurements')
    plt.ylabel('Predicted Measurements')
    plt.show()

然后,我们可以通过传入实际值和预测值来调用我们的图表。

create_scatter_comparison(y_test, y_pred)

当我们运行这个时,我们会得到以下图表。

预测测量值与实际测量值的散点图。图片由作者提供。

总体来说,模型在预测体积密度(RHOB)方面表现良好——大多数数据点接近 1:1 关系线。然而,还有一些领域可以通过改进模型来受益。

我们可以看到在 2.2g/cc 到 2.6 g/cc 之间的数值分布更广,这表明我们的模型在这个范围内低估了体积密度。

通过对输入数据应用 MinMaxScaler 来改进 Keras 模型

一些机器学习模型,包括神经网络,当数据归一化到标准范围时表现更好。

在井测量中,我们有时会有数据缩放从 0 到 0.5,而其他数据达到几万。这可能导致某些输入曲线比其他曲线具有更大的权重。

为了在建模时让每个输入曲线具有相同的基础,我们需要将输入数据更改为标准范围。此外,这也可以提高模型训练时间和模型预测准确性。

归一化值的一种方法是使用MinMaxScaler来自sklearn

这个函数会将数据缩放到 0 和 1 之间。

一旦MinMaxScaler被导入,我们就可以拟合和转换我们的X_trainX_test数据。

我们不需要改变目标特征。

from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()

X_train_s = scaler.fit_transform(X_train)
X_test_s = scaler.transform(X_test)

然后,我们可以传入我们新缩放的变量并重新运行模型。

# Create a model
model = tf.keras.Sequential([
    tf.keras.layers.Dense(8, activation='relu'),
    tf.keras.layers.Dense(1)
])

# Compile model
model.compile(loss='mae',
             optimizer='Adam',
             metrics='mae')

# Fit the model
history = model.fit(X_train_s, y_train, epochs=30)

再次,Keras 将在运行时报告模型的进展。

我们立即注意到,mae 值比原始运行时更小。希望这意味着模型更好。

使用缩放输入进行预测时 Keras 的进展。图片由作者提供。

然后,我们可以通过重新评估关键指标来进行新的预测。

y_pred = model.predict(X_test_s)

mae_1 = tf.keras.metrics.mae(y_test, tf.squeeze(y_pred)).numpy()
rmse_1 = np.sqrt(tf.keras.metrics.mse(y_test, tf.squeeze(y_pred)).numpy()) 

这给我们提供了 0.0292 g/cc 的 MAE 和 0.0455 的 RMSE。这表明,通过应用我们的 MinMaxScaler,模型得到了改进。

(0.029252911, 0.04554793)

我们可以通过将新的预测结果传入散点图并将结果与之前的模型进行比较来进一步确认这一点。

Keras 预测的比较,归一化前(左)和归一化后(右)使用 MinMaxScaler。比较时请注意不同的尺度。图片由作者提供。

尽管图表的尺度不同,我们可以看到在 2.2g/cc 和 2.6 g/cc 范围内有显著改善。这证实了将归一化应用于数据已产生更好的预测结果。

总结

在本教程中,我们已经看到如何构建一个非常简单的 Keras 神经网络模型,以使用其他可用的井日志数据来预测常见的井日志测量。这在数据缺失或受差井条件(如洗井)影响的数据的情况下极其有用。

尽管本教程在对模型进行一次修订后停止,但尝试不同的模型设置变体和不同的输入组合总是明智的。

请记住,构建成功的机器学习模型的整个过程涉及多次迭代以达到最终模型。即使模型已经部署,也可以在有新数据时进行修订。

最后,使用机器学习技术进行预测不应被视为领域专业知识的直接替代品。相反,领域专业知识应与建模和预测过程相结合。这可以确保准确性,并捕捉到任何错误结果。

数据集使用情况

本教程中使用的数据是 Equinor 在 2018 年发布的 Volve 数据集的一个子集。数据集的详细信息,包括许可证,可以在以下链接找到

[## Volve 领域数据集

Equinor 已发布 2008-2016 年 Volve 领域的完整数据集。点击此处下载以供研究、学习……

www.equinor.com](https://www.equinor.com/energy/volve-data-sharing?source=post_page-----ef7dfed94077--------------------------------)

Volve 数据许可证基于 CC BY 4.0 许可证。许可证协议的详细信息可以在这里找到:

cdn.sanity.io/files/h61q9gi9/global/de6532f6134b9a953f6c41bac47a0c055a3712d3.pdf?equinor-hrs-terms-and-conditions-for-licence-to-data-volve.pdf

感谢阅读。在您离开之前,您绝对应该订阅我的内容,将我的文章送入您的收件箱。 您可以在这里进行订阅!此外,如果您喜欢这些内容并想表示感谢,请考虑为它点赞。

50 多次机器学习面试(作为面试官)教会了我什么

原文:towardsdatascience.com/what-50-ml-interviews-as-an-interviewer-have-taught-me-6a72f7344eb1

作为面试官,你能做些什么以在结果不论如何的情况下给候选人留下积极的印象?

Thushan GanegedaraTowards Data Science Thushan Ganegedara

·发表于 Towards Data Science ·6 分钟阅读·2023 年 7 月 7 日

--

图片由 charlesdeluvio 提供,来自 Unsplash

如果你觉得面对技术面试很困难,那么尝试进行面试吧。我说的不是那些给人留下刺耳印象的尴尬面试官,他们傲慢地看着你,你只希望痛苦早点结束。我说的是那些留下积极印象、你会珍惜的面试官。

面试是一项巨大的责任。你是某人职业生涯的把关人。因此,你必须尽你所能对他们尽量公平。

我将提到的所有要点都围绕一个关键价值展开:

同理心!

如果你掌握了同理心,你可能甚至不需要阅读这篇文章。我在这里讨论的一切都是我的个人观点,不代表我雇主的看法。

为了提供背景,我是一名机器学习工程师,我讨论的是技术或编码面试。

阅读完这篇文章后,你将(希望)获得一些经验,这些经验将使你成为一个更好的面试官,给候选人留下积极的印象(无论结果如何)。

让我们先跳过候选人的明显检查,先理清思路:

  • 展现出对语言和工具的扎实技术知识

  • 在解决问题时思考

  • 友好与合作

任何没有打勾的项都是值得关注的。

协作优于审查

图片由 Mitchell Luo 拍摄,发布在 Unsplash

面试官进行面试的风格对面试结果起着重要作用。如果面试官表现得像一个无法满足的权威人物,即使是最优秀的候选人也可能会紧张并感到不安。当候选人面前有一个亲切的人时,他们的表现会更好。

我的一种方法是将面试几乎变成一场对偶编程的会话,我们两个人共同努力解决问题,而不是默默地(有些悲惨地)观察候选人对问题的痛苦挣扎。

我不会撒谎,我曾经支持“审查团队”。那时,我认为评估候选人的最重要标准是看他们是否能自己找到解决方案。在工作中,解决问题的时间很少仅仅依赖于你的技术知识。相反,它更多地受到以下因素的影响……

  • 知道应该问什么问题(当然是对的人)

  • 交流你到目前为止的工作

  • 解释和执行他人的提示/建议

对偶编程给了你一个黄金机会来测试候选人的这些“软技能”。因此,与其孤军奋战,不如组成一个团队,共同努力达到最终解决方案。为了推动候选人朝正确方向前进或在他们卡住时打破僵局,我会使用诸如“告诉我你在想什么”或“也许从伪代码开始”这样的短语。我不是说你应该把解决方案直接交给他们,而是帮助他们成功。

这种方法不仅有助于你评估候选人的一系列硬技能和软技能,而且还让候选人感受到成就感(而不是在他们遇到困难时被抛弃)。

情境意识

图片由 Timon Studler 拍摄,发布在 Unsplash

你必须培养的一个关键技能不是记住问题的答案(尽管这很重要),而是具有敏锐的情境意识。每个候选人都是不同的,每次面试的体验也是不同的。作为面试官,你必须能够适应那个独特的情境。

如果候选人显得紧张,多微笑一点,问问天气,并让他们知道你在这里如果需要帮助。如果候选人在解决问题时需要一些个人空间,给予他们这些空间。如果候选人在面试开始时遇到技术困难,给他们一点额外的时间来弥补丧失的时间。

不仅在面试过程中需要这样做,而且在面试后也要这样做。在评估候选人时,通过排除噪音建立他们表现的公平形象。问自己一些问题,例如,

  • 如果他们不紧张的话,表现是否会更好?

  • 候选人是否有文化/语言障碍?

  • 这是一个我会期待与之合作的人吗?

候选人通常会随着面试阶段的进行变得越来越自信/舒适。也许候选人正经历非常糟糕的一天!因此,作为面试官,你需要能够穿透这些,评估候选人的技能。我不是说你应该完全忽略这些事实。记下它们并与其他面试官/招聘人员沟通。但如果你期待面试者总是处于最佳状态,你会感到失望。记住我们都是人!这也引出了第二点。

写详细的反馈

Aaron BurdenUnsplash 提供的照片

这是作为面试官最难掌握的事情之一:写出全面且公平的评估。为什么困难?因为在一个小时或 45 分钟的时间窗口内,你需要评估候选人的许多方面,同时你的精神带宽有限。和其他事情一样,掌握这项技能需要时间。

一些可以帮助你的事项有,

  • 使用模板在面试过程中记笔记。可以是面试中的每个任务,他们做得好的地方和做得不好的地方。一个重要的点是要有具体的例子,而不是模糊的陈述。

  • 查看其他人写的反馈(如果你能看到的话)

  • 不要拖延记笔记——确保在面试结束时你的笔记是完整的。否则,你将总是忘记在面试过程中做出的重要观察。

准时

Aron VisualsUnsplash 提供的照片

作为面试官,容易产生一种皇室感。可能会出现这样的想法:“他们应该在等我进来,而不是我等他们。”个人而言,更重要的是我以他们(或我)对待自己时间的方式来珍惜别人的时间。

我不必提醒你面试前的兴奋(以一种可怕的方式)是怎样的。而且 99%的候选人肯定会准时参加面试。作为面试官,我也应当对候选人做到这一点,这才公平。

结论

进行一次出色的面试不是一门科学,没有一个万能的配方可以总是奏效。这更多地依赖于你解读情况和候选人的能力。

重要的是将这些建议/学习看作参考。它们不是精确的规则,也没有确切的衡量标准。例如,我并不是说你应该仅仅因为候选人紧张而放弃他们。但如果候选人回答了 80%的问题,并且你知道他们已经很久没有面试,并且他们非常紧张,那么可以给他们第二次机会。

此外,作为一个“善良的人”可以帮助使面试过程更加愉快。遗憾的是,我曾见过面试官在面试后嘲笑候选人的弱点。对大多数人来说,面试是一个非常紧张的经历,我们都有过犯错的时候。所以尽量避免这样做。

感谢你的阅读!我希望这些建议能帮助你成为更出色的技术面试官!

如果你喜欢这个故事,欢迎 订阅 Medium,你将会收到我发布的新内容通知,并且可以解锁访问成千上万来自其他作者的精彩故事。

## 通过我的推荐链接加入 Medium — Thushan Ganegedara

作为 Medium 的会员,你的会员费的一部分会支付给你阅读的作者,你将获得每个故事的全面访问权限……

thushv89.medium.com

什么是梯度,为什么会爆炸?

原文:towardsdatascience.com/what-are-gradients-and-why-do-they-explode-add23264d24b

阅读这篇文章,你将对深度学习中最重要的概念有一个坚定的理解。

Daniel WarfieldTowards Data Science Daniel Warfield

·发布于 Towards Data Science ·10 分钟阅读·2023 年 6 月 12 日

--

“梯度爆炸”,由 MidJourney 制作。所有图像均由作者提供,除非另有说明。

梯度可以说是机器学习中最重要的基础概念。在这篇文章中,我们将探讨梯度的概念、使梯度消失和爆炸的原因,以及如何控制梯度。

这对谁有用? 对初学者到中级的数据科学家有用。我将包括一些可能对更高级读者有用的数学参考。

你将从这篇文章中获得什么? 对梯度的深入概念理解,它们如何与机器学习相关,梯度带来的问题,以及用来减轻这些问题的方法。

目录

点击链接以导航到特定部分

1) 什么是梯度? 2) 实际梯度(数学上) 3) 简单模型中的梯度(一个例子) 4) 什么是梯度爆炸和消失? 5) 为什么梯度爆炸和消失不好? 6) 我们如何修复梯度爆炸和消失?

什么是梯度?

目录

想象你有一些表面,有山丘和山谷。这个表面由一些多维函数(具有多个输入的函数)定义。

"""
Making a 3d surface with hills and vallys, for demonstrative purposes
"""

import matplotlib.pyplot as plt 
from matplotlib import cm
from matplotlib.ticker import LinearLocator
import numpy as np

#creating wide figure
fig, ax = plt.subplots(subplot_kw={"projection": "3d"})

# Make data.
X = np.arange(-5, 5, 0.25)
Y = np.arange(-5, 5, 0.25)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
Z = 0.2*np.sin(X+Y + R) - 1*np.sin(X/2)

# Plot the surface.
surf = ax.plot_surface(X, Y, Z, cmap=cm.viridis,
                       linewidth=0, antialiased=False)

plt.show()

一些表面,有山丘和山谷

梯度告诉你, 对于表面上的任何给定点,它既指明了到达更高点的方向,也描述了该点表面的陡峭程度。

因为这是一个三维表面(输入是 x 和 y,输出是 z),我们可以通过计算在 X 轴和 Y 轴上某个点的坡度来计算梯度的简化版本。

"""
Calculating a simplified gradient using slopes along the X and Y direction
"""

def computeZ(x,y):
    """
    calculates any point on the surface
    """
    r = np.sqrt(x**2 + y**2)
    z = 0.2*np.sin(x+y + r) - 1*np.sin(x/2)

    return z

def plot_pseudo_gradient(x,y):
    """
    Calculates an approximation of the gradient using slope calculations
    of neighboring points offset by a small dx and dy.
    """

    #computing value at point
    z = computeZ(x,y)

    #defining some small distance to traverse 
    dx = 0.9
    dy = 0.9

    #getting the change in Z as a result of the change in X and Y
    dzx = (computeZ(x+dx,y) - computeZ(x,y))
    dzy = (computeZ(x,y+dy) - computeZ(x,y))

    #calculating the slope along the x and y axis.
    #these together tell you the direction of increase
    #and the slope of the current point, so these together
    #are the actual pseudo gradient
    slope_x = dzx/dx
    slope_y = dzy/dy

    #to scale the vectors for visability
    scale = 7

    #calculating the value at the end of the pseudo gradient
    #so I can draw a tangent line along the surface in the direction
    #of the gradient
    dz = computeZ(x+slope_x*scale,y+slope_y*scale)

    xs = [x, x+slope_x* scale]
    ys = [y, y+slope_y* scale]
    zs = [z, z+dz]

    #plotting the actual gradient
    ax.plot([xs[0], xs[1]],
            [ys[0],ys[1]],
            [zs[0],zs[0]], 'b')

    #plotting the tangent line
    ax.plot(xs, ys, zs, 'r')

    #plotting vector components of the tangent line
    ax.plot([xs[0],xs[1],xs[1],xs[1]],
            [ys[0],ys[0],ys[1],ys[1]],
            [zs[0],zs[0],zs[0],zs[1]], '--k')

    ax.scatter([x],[y],[z], marker='x', c=['k'])

#creating a figure
fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
ax.computed_zorder=False #unfortunatly, zorder has pervasive bugs in 3d plots

# Plot the surface.
surf.set_zorder(1)
surf = ax.plot_surface(X, Y, Z, cmap=cm.viridis, linewidth=0, antialiased=False, alpha=0.2)
surf.set_zorder(1)

#plotting the pseudo gradient at x=0 and y=0
plot_pseudo_gradient(0,0)

#rendering
plt.show()

#for later use in traversal with the gradient
return slope_x, slope_y

蓝色的梯度描述了“x”标记的点的最大增加方向。红线描述了如果你沿着梯度走一段距离,你会到达哪里。

所以,从概念上总结一下,梯度计算了最大增加的方向,以及这种增加的陡峭程度,通过计算输出相对于函数所有输入的斜率。

实际梯度

目录

在之前的示例中,我计算了我称之为“简化梯度”的内容。我计算了 z 相对于 x 和 y 的小变化的斜率。

用于计算伪梯度的比率。 SlopeZvsX 和 SlopeZvsY 被用来构造图像中的蓝线。

实际上,梯度是使用偏导数计算的,这意味着它是相对于单个变量(x 或 y)的函数的导数。 如果你对微积分不熟悉,你可以观看一个关于导数的 视频 和另一个关于 偏导数 的视频来快速了解数学。不过,无论数学如何,简化梯度和实际梯度的概念是相同的。

这是一个具有 x 和 y 维度的函数的梯度的数学符号。梯度是一个由函数相对于每个输入的偏导数组成的向量,表示为一个向量。真实梯度比我在之前示例中计算的“伪梯度”更加准确且计算更快。从概念上讲,你仍然是在计算给定 x 和 y 变化时的斜率。

简单模型中的梯度

目录

在研究机器学习时,你会发现到处都是可微性;可微损失函数、可微激活函数等等。原因是,如果一切都是可微的,你可以快速计算梯度(你需要调整输入以获得更好输出的方向)。

例如,假设我们有一个具有两个参数 x 和 y 的机器学习模型。我们还有一个函数,告诉我们这些参数如何将模型拟合到一组数据。我们可以使用梯度通过在梯度方向上采取一系列步骤来尝试找到最佳模型参数。

"""
Using Gradients to iteratively search for the maximum of the surface
"""

#creating a figure
fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
ax.computed_zorder=False #unfortunatly, zorder has pervasive bugs in 3d plots

# Plot the surface.
surf.set_zorder(1)
surf = ax.plot_surface(X, Y, Z, cmap=cm.viridis, linewidth=0, antialiased=False, alpha=0.3)
surf.set_zorder(1)

#iteratively following the gradient
x,y = 0,0
for _ in range(10):
    dx,dy = plot_pseudo_gradient(x,y)
    x,y = x+dx, y+dy

#rendering
plt.show()

#printing result
print("ideal parameters: x={}, y={}".format(x,y))

从 x=0 和 y=0 进行迭代梯度搜索到局部最大值。 “x” 点标记了每次迭代的位置。在这种情况下,梯度优化的结果是 x=-3.104,y=0.789。

当人们谈论训练时,他们有时会提到“损失景观”。当你将一个问题转化为机器学习问题时,你实际上是在创建一个参数的景观,这些参数表现得比其他参数好或差。你定义什么是好,什么是坏(损失函数),以及一个复杂的函数,它具有一组可微分的参数,可以调整以解决问题(机器学习模型)。这两者共同创建了一个理论上的损失景观,通过梯度下降(模型训练)来遍历这个景观。 什么是梯度下降?

数学上,梯度用于指向函数中的更大值。在机器学习中,我们通常优化以减少错误率,因此我们希望我们的损失函数(错误数量)更小,而不是更大。数学上几乎是相同的;你只需将一些 + 变成 -。

"""
reworking the previous example to find the minumum with gradient descent
"""

fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
ax.computed_zorder=False

surf.set_zorder(1)
surf = ax.plot_surface(X, Y, Z, cmap=cm.viridis, linewidth=0, antialiased=False, alpha=0.3)
surf.set_zorder(1)

x,y = 0,0
for _ in range(10):
    dx,dy = plot_pseudo_gradient(x,y)
    x,y = x-dx, y-dy #<----------- this is the only part that changed

plt.show()

print("ideal parameters: x={}, y={}".format(x,y))

梯度下降,通常在机器学习中使用的方法。

什么是梯度爆炸和梯度消失?

目录

首先,让我们看一个简化的神经网络。我们将忽略激活函数和偏置,仅将神经网络视为一系列权重。在这种简化的条件下,神经网络看起来像这样:

这是一个小型神经网络的例子,它仅使用权重。Hidden 1 的值是 input1w1 + input2w2,这等于 0.5。在一般情况下,感知器将每个输入乘以其各自的权重,然后将这些值加在一起。

当我们有更深层的神经网络时,梯度爆炸和梯度消失的问题就会出现。想象一个网络,其中有几个更多的层在进行乘法和加法,不断地进行乘法和加法等等。

神经网络深层部分的快照

如你所见,当你持续乘以大于 1 的数字时,值会迅速增大。如果权重小于 1,值会因为乘以越来越小的值而迅速缩小。

我们可以看到,网络中的值会因为模型中的权重而迅速变大或变小,但我们也可以将每个感知器中的值看作变化,而不是具体的值。

想象一下感知器中的数字不是感知器的值,而是感知器值的变化。正如你所看到的,由于重复的乘法,当你深入网络时,变化的速度会增加。

关键点是:如果权重大于 1,重复的乘法会导致变化率(梯度)变得非常大;如果权重小于 1,变化率会变得非常小。 换句话说,梯度可能会爆炸或消失

为什么梯度爆炸和梯度消失不好?

目录

大梯度,小梯度,那又如何?

小梯度移动缓慢,并且有可能陷入浅层的局部最小值。因此,梯度消失可能导致模型无法改进。另一方面,梯度爆炸移动过快,并可能出现不稳定的情况,从而导致模型无法收敛到最小值。

"""
Plotting 3 similar landscapes scaled vertically
to have small, moderate, and large gradients
"""

def f(x, scale):
    """
    Function to represent the landscape we are attempting to optimize
    scaling the function vertically will scale the gradients proportionally
    """
    return scale*(0.3*np.sin(x*0.1) +0.5* np.sin(np.cos(x)) + 0.1*np.sin(x*0.3+2) + 4*np.cos(x*0.1) + 6*np.sin(x*0.05))

def f_slope(x, scale):
    """
    Using a pseudo derivative instead of computing the actual derivative
    """
    dx = 0.00001
    slope = (f(x+dx, scale)-f(x, scale))/dx
    return slope

#defining range
X = np.linspace(50,125,10000)

for gradient_scale, color in zip([1,10,100], ['r', 'y', 'b']):
    #computing landscape
    Y = np.array(list(map(f, X, [gradient_scale]*len(X))))

    point = 58
    explored_x = []
    explored_y = []
    for _ in range(20):

        #marking point as explored
        explored_x.append(point)
        explored_y.append(f(point,gradient_scale))

        #traversing along gradient
        point = point-f_slope(point, gradient_scale)

    #plotting landscape
    plt.plot(X,Y)
    #plotting traversal
    plt.plot(explored_x, explored_y, 'x-'+color)
    #rendering
    plt.show()

三种形状相似的景观,一种梯度几乎为零(左),一种梯度适中(中),一种梯度爆炸(右)。梯度消失导致模型改进不足,而梯度爆炸则导致不稳定性。

当你考虑到不仅仅是更大的模型有梯度,每个感知机也有自己的梯度时,这个问题变得更加普遍。这意味着网络中的不同感知机可以有非常不同的梯度。理论上,一个模型在不同的部分可以同时存在梯度消失和梯度爆炸

我们如何解决梯度爆炸和梯度消失的问题?

目录

1) 调整学习率

学习率通过梯度进行乘法运算,以控制每次迭代沿梯度方向的步长。较小的学习率会导致较小的步伐,而较大的学习率则会导致较大的步伐(我在之前的示例中做了大致等效的操作)。这在一定程度上可能有用,但梯度消失和梯度爆炸的问题在于梯度在模型中会发生变化(一些感知机的变化很小,其他的变化很大)。因此,虽然学习率是一个关键的超参数,但通常不被视为专门处理梯度消失和梯度爆炸的解决方法。

2) 更改激活函数

出于各种原因,感知机并不会只是将其输入乘以某些权重,将结果加在一起,然后输出结果。几乎所有网络都会将这一操作的结果通过一个称为激活函数的函数。激活函数都是可微分的,因此在影响网络深度中的梯度方面具有多种特性。

4) 更改模型架构

简单地缩短网络可以有所帮助。然而,如果这不是一个选项,几种网络架构被专门设计来处理这个问题。LSTM 被设计得比经典 RNN 在处理梯度爆炸方面更具鲁棒性,残差和跳跃连接也被设计用来帮助解决这种现象。

5) 使用批量归一化

批量归一化是机器学习中的一种主要正则化策略。它不是通过单一梯度来更新模型参数,而是通过使用一批样本的平均梯度来更新参数。

6) 梯度裁剪

你可以设置梯度的最大允许阈值。如果梯度超过这个值,就将梯度的大小设为这个阈值。

7) 使用权重正则化

L1 和 L2 正则化用于对高权重值的模型施加惩罚。添加这种形式的正则化可以减少梯度爆炸。

8) 截断上下文窗口

无论你使用的是递归网络还是其他使用上下文窗口的网络,缩小窗口的大小可以帮助最小化复合梯度问题。

结论

就这样!在这篇文章中,我们了解了梯度以及其背后的数学。我们了解到,你可以使用梯度在某些维度空间中上下移动表面,并且了解了如何利用这来优化机器学习模型。我们还了解到,随着模型规模的增大,梯度可能会爆炸成很大的数值,或消失成很小的数值,这两者都可能破坏模型的学习能力。我们还讨论了修正梯度消失和梯度爆炸的一些方法。

关注以获取更多信息!

在未来的文章中,我将描述一些机器学习领域的标志性论文,重点介绍实用和直观的解释。我还会有关于不常讨论的机器学习概念的文章。

如何使用 Hugging Face 代理进行 NLP 任务

原文:towardsdatascience.com/what-are-hugging-face-agents-48c175bd33e3

一步步教程,教你如何使用 Transformers 工具和代理。

Farzad MahmoodinobarTowards Data Science Farzad Mahmoodinobar

·发表于Towards Data Science ·阅读时间约 11 分钟·2023 年 5 月 17 日

--

Alev Takil拍摄,图片来自Unsplash

Hugging Face,一个为机器学习从业者提供的开源 AI 社区,最近将工具和代理的概念集成到了其流行的Transformers库中。如果你已经使用 Hugging Face 进行自然语言处理(NLP)、计算机视觉和音频/语音处理任务,你可能会好奇工具和代理为生态系统带来了什么价值。代理为用户增加了一个可以说是重要的便利性——让我来解释一下。

假设我想使用 Hugging Face Hub 上的模型将英文翻译成法文。在这种情况下,我需要进行一些研究以找到一个好的模型,然后弄清楚如何实际使用该模型,最后编写代码生成翻译。但是,如果你已经有一个 Hugging Face 专家在手,他们已经知道所有这些信息呢?换句话说,你只需告诉专家你想将一个句子从英文翻译成法文,然后专家会负责寻找一个好的模型、编写代码并返回结果——而且专家的速度远远快于你和我能做的。这正是代理的作用!我们用简单的英文描述我们想要的,然后代理查看其工具箱中的可用工具并执行它!这非常类似于请求 ChatGPT 翻译一个句子,然后 ChatGPT 处理剩下的。但是现在,代理不仅限于 ChatGPT 使用的少数几个模型(即 Open AI 模型,例如 GPT 3.5 或 GPT-4),代理还可以访问 Hugging Face 上的许多模型。

现在我们了解了代理和工具的作用,让我们看看如何实现它们。

## 通过我的推荐链接加入 Medium

阅读 Farzad(以及 Medium 上的其他作者)的每个故事。你的会员费直接支持 Farzad 和其他…

medium.com

Transformers 代理 — 实现

对于这一部分,我主要依赖于 Hugging Face 文档 关于代理,并使用我自己的示例进行了实现。

步骤 1 — 要求

让我们开始导入我们在这个练习中将要使用的一些库。请注意,我在结果中包含了这些库的版本,以便你想创建一个相同的环境。

import transformers, huggingface_hub, diffusers, torch
from platform import python_version
print(f'python: {python_version()}')
print(f'transformers: {transformers.__version__}')
print(f'huggingface_hub: {huggingface_hub.__version__}')
print(f'diffusers: {diffusers.__version__}')
print(f'torch: {torch.__version__}')

结果:

如果你的环境中没有一个或多个这些库,你可能会从上述代码块中遇到错误。如果是这样,你可以运行下面的单元格来安装这些库。我假设如果你正在阅读这篇文章,你的环境中已经有 Python,因此下面没有包含。

技巧提示: 如果你需要运行一行命令,例如在 Jupyter notebook 或类似环境中安装 transformers,你可以使用 !pip install transformers==4.29.0。在下面的代码块中,我使用了 %%sh,这是一个魔法命令,表示此单元格中的所有内容都作为命令运行。

%%sh

pip install transformers==4.29.0

pip install huggingface_hub==0.14.1

pip install diffusers==0.16.1

pip install --upgrade torch torchvision

pip install openai==0.27.6

步骤 2 — Hugging Face 登录

现在我们的环境已经准备好,我们需要登录到 Hugging Face 以访问他们的推理 API。此步骤需要一个免费的 Hugging Face 令牌。如果你没有,可以按照这个链接中的说明(我花了不到 5 分钟)为自己创建一个。

让我们登录。

import huggingface_hub
from huggingface_hub import login

my_hf_token = 'ADD_YOUR_TOKEN_HERE'

login(my_hf_token)

结果:

结果显示登录成功。

在下一步中,我们将实例化代理。请注意,Hugging Face 支持各种代理(本质上是大型语言模型或 LLM)。有些代理是收费的,如 Open AI 的,有些是开源的,如 BigCode 和 OpenAssistant。对于这篇文章,我选择了 BigCode 提供的一个免费开源选项Starcoder,因为这将更方便刚入门的用户尝试这些模型。如果你对使用其他代理感兴趣,Hugging Face 提供了一个易于阅读的教程,链接在这里

让我们继续进行下一步并实例化我们的代理。

第 3 步 — 实例化代理

下面的代码块实例化了来自 BigCode 的Starcoder代理。

import transformers
from transformers import HfAgent

# Starcoder
agent_starcoder = HfAgent("https://api-inference.huggingface.co/models/bigcode/starcoder")

现在我们的代理准备好了,让我们看看它能做什么!

第 4 步 — 执行任务

我们将要求模型生成一张图片,这是第一个任务。我们的做法是将我们想要的内容传达给代理,然后代理会完成它。让我们来看一个例子。

task = "Draw me a picture of the ocean"

picture_ocean = agent_starcoder.run(task)

picture_ocean

结果:

Hugging Face Agent生成的海洋图片

这很有趣!从结果来看,我们可以看到代理解释了它采取的一些步骤。例如,代理使用了image_generator工具来生成我们要求的图片。

我们提到我们的代理是一个 LLM,我们知道输出是随机生成的,并且期望在重新运行模型时会有所变化。让我们看看如果再运行一次相同的任务会得到什么结果。

picture_ocean = agent_starcoder.run(task)

picture_ocean

结果:

Hugging Face Agent生成的海洋图片

正如预期的那样,图片不同。但是,如果在看到图片后,我们想对图片进行修改会怎么样呢?例如,看到这张图片中有一艘船会很不错。让我们要求我们的代理在同一张图片上添加一艘船。

picture_ocean_updated = agent.run("Transform the image in `picture_ocean` to add a ship to it.", picture=picture_ocean)

picture_ocean_updated

结果:

Hugging Face Agent生成的海洋和船只图片

如我们所见,这次代理使用了一个不同的工具叫做image_transform,因为它不再需要生成整张图像,而是通过在提供的图像中添加一艘船来转换图像。我们可以看到图像左上角的那个小船。表现得还不错!

不过这时候你可能会问,代理实际上在做什么?我们将在接下来回答这个问题。

第 5 步 — 代理实际上做了什么?

正如我们之前所学,代理是执行我们提供的提示的 LLM。换句话说,代理接收我们的提示,然后根据要求,代理收集他们认为有用的工具并运行这些代码。Hugging Face 提供了一种查看代理代码的方法,即在我们的运行命令中添加return_code=True。换句话说,我们可以要求代理仅返回代码块,然后我们可以自己修改和/或运行代码。

让我们重新运行我们的命令,如下所示,并查看结果:

task = "Draw me a picture of the ocean"

agent_starcoder.run(task, return_code=True)

结果:

我已经清理并重新编写了代理返回的内容如下:

from transformers import load_tool
image_generator = load_tool("huggingface-tools/text-to-image")
image = image_generator(prompt="ocean")

让我们运行这段代码并查看结果。

 from transformers import load_tool

image_generator = load_tool("huggingface-tools/text-to-image")

image = image_generator(prompt="ocean")

image

结果:

海洋的图片,由Hugging Face 代理生成

结果如预期那样工作。换句话说,我们不再需要依赖代理为我们创建代码,我们可以直接使用huggingface-tools/text-to-image工具生成图片。

现在我们了解了代理如何选择工具并工作的过程,让我们看看一些额外的工具。

第 6 步 — 额外工具

在本节中,我们将涵盖代理可以使用的其他一些工具,如下所示:

  • 图像描述

  • 问题解答

  • 翻译

  • 混合请求

6.1. 图像描述

这是一个有趣的练习。首先,我们将使用text-to-image工具生成一张玩具车的图片。然后我们将保存该图片,并要求代理对其进行描述。

让我们开始创建一张玩具车的图片。

from transformers import load_tool

image_generator = load_tool("huggingface-tools/text-to-image")

image_generator(prompt="toy car")

结果:

玩具车的图片,由Hugging Face 代理生成

然后,我将其保存到本地驱动器,然后使用Python Imaging Library 或 PIL读取它。之后,我们将提示代理对该图像进行描述。

下面是代码块:

from PIL import Image

task = 'Caption the following image'

image = Image.open('/content/picture.png')

agent_starcoder.run(task, image=image)

结果:

看看最后一句话——这是一个很好的描述!代理描述了这辆车,这似乎相当准确。如果你对幕后发生的事情感到好奇,让我们让代理返回代码,看看使用了哪些工具以及如何使用,如下所示:

agent_starcoder.run(task, image=image, return_code=True)

结果:

让我们将代码块清理如下:

from transformers import load_tool
image_captioner = load_tool("image-captioning")
caption = image_captioner(image)

代理所做的是加载image-captioning工具,然后为我们提供的图像生成标题。听起来很简单!让我们继续下一个例子。

6.2. 问答

问答是显而易见的,但让我们让它更有趣。与其提供一段文字给代理并询问有关提供信息的问题,不如提供一张图像,并询问代理有关图像的内容。

我在一个 Word 文档中写了几行文字,然后将其保存为*.jpg图像在本地。我们首先使用 PIL 查看如下图像:

from PIL import Image
image = Image.open('/content/jack.jpg')
image.show()

结果:

如你所见,图像中有几句关于我在西雅图的虚构朋友 Jack 的句子。接下来,让我们向代理提问,并看看它如何回应。我想问代理 Jack 最喜欢的颜色是什么,如下所示:

task = "in the following 'document', what is Jack's favorite color?"

agent_starcoder.run(task, document=image)

结果:

再次查看底部的最后一句——这相当不错!我们可以看到文本提取并不完美,例如,它将 Tesla 提取为‘tesia’,但代理仍然返回了相关的图像部分,回答了我们的问题。

让我们看看代理究竟使用了哪些工具:

task = "in the following 'document', what is Jack's favorite color?"

agent_starcoder.run(task, document=image, return_code=True)

结果:

让我们将代码清理如下:

from transformers import load_tool

document_qa = load_tool("document-question-answering")

answer = document_qa(document, question="What is Jack's favorite color?")
print(f"The answer is {answer}.")

我们可以看到代理使用了document-question-answering工具,然后以问答任务的形式提出了问题。

接下来,让我们看看代理是否能执行翻译。

6.3. 翻译

这部分相当简单。让我们让代理翻译一个句子,然后看看它使用了哪些工具。

text = 'this is a sentence in English'

task = "translate the following 'document' to French"

agent_starcoder.run(task, document=text)

结果:

太棒了!我们看到了结果,这是所提供句子的法语翻译。让我们看看代理使用了什么工具:

agent_starcoder.run(task, document=text, return_code=True)

结果:

让我先清理一下代码:

from transformers import load_tool
translator = load_tool("translation")
translated_document = translator(document, src_lang="English", tgt_lang="French")

这看起来相当简单。代理使用了translation工具,并且代理正确地识别了源语言(src_lang)和目标语言(tgt_lang),这是基于我们要求的!

到这一步,我在想代理是否能够处理更复杂的任务。我们接下来会看看。

6.4. 混合请求

如果我们将问答和翻译结合起来呢?让我们问代理 Jack 最喜欢的颜色是什么,同时要求答案必须用法语返回。

task = "in the following 'document', what is Jack's favorite color? After you answer the question, translate the answer to French"

agent_starcoder.run(task, document=image)

结果:

看看最后一句——这很好!我们看到代理首先返回了英文答案,然后按照我们的要求将响应翻译成了法语!

结论

  • 代理和工具是一个强大的组合。我认为代理对技术用户(即机器学习和 AI 从业者)和非技术用户都很有益。对于技术用户,代理可以加快过程——代理可以帮助选择多个工具中的一个,并返回代码供技术用户根据需求进行修改。另一方面,不熟悉机器学习的非技术用户,只需用简单的英语提出需求,代理将处理其余的工作。

  • 希望你喜欢这篇关于代理和工具的简要教程!如果你对在 Hugging Face 中实现自然语言处理(NLP)任务感兴趣,请查看下面的帖子。

## 使用 Hugging Face 实现 NLP 任务

- 介绍如何使用 Hugging Face 进行 NLP 任务的教程。

[towardsdatascience.com

- 感谢阅读!

  • 如果你觉得这篇帖子有帮助,请 在 Medium 上关注我 并订阅以接收我最新的帖子!

  • (除非另有说明,所有图片均由作者提供。)

什么是多模态模型?

原文:towardsdatascience.com/what-are-multimodal-models-fe118f3ef963

赋予大型语言模型(LLM)视觉能力!

Omer MahmoodTowards Data Science Omer Mahmood

·发表于 Towards Data Science ·阅读时间 6 分钟·2023 年 10 月 16 日

--

在 Atlas by Nomic 上运行的 Mecari 文本与图像嵌入演示 截图。

这篇文章适合谁?

  • 读者群体 [🟢⚪️⚪️]: AI 初学者,熟悉流行概念、模型及其应用

  • 等级 [🟢🟢️⚪️]: 中级话题

  • 复杂度 [🟢⚪️⚪️]: 容易理解,没有数学公式或复杂理论

❓为什么这很重要

基础的大型语言模型(LLM),经过在庞大数据集上的预训练,在通过零-shot、few-shot 或迁移学习的提示下处理通用、多任务时相当高效。

确实,这些模型的例子如 PaLM2GPT4 已经彻底改变了我们与计算机交互的方式,使用文本作为输入,但是……

  • 如果有一种方法可以通过使这些模型使用不同的输入模态,如照片、音频和视频,来扩展它们的智能会怎样?换句话说,让它们变成多模态的!

  • 这可能会大大改善我们在网络上搜索信息的方式,甚至在现实世界应用中,例如医学和病理学,帮助我们理解周围的世界。

  • 有解决方案!多模态深度学习模型可以结合不同类型输入的嵌入,使得例如一个大型语言模型(LLM)能够“看到”你所询问的内容,并返回相关结果。

⚡️继续关注 如果你想了解更多关于这一切如何运作的知识,并试用一个实际的演示!

🔥 这如何运作?

它从嵌入开始

训练深度学习模型的最强大构建模块之一是创建嵌入向量。

在训练过程中,模型将遇到的不同类别(例如,人、食物和玩具)编码成其数值表示,即嵌入,这些嵌入存储为数字向量。

嵌入在我们想从类别(或类)的稀疏表示(例如一长串文本或图像)转变为更紧凑的形式,并且可以在其他模型中重用时非常有用。

简而言之,嵌入为我们提供了一种以简写形式存储事物含义的方法,机器可以用来快速比较和搜索!

更具体地说,通过对不同图像进行训练的视觉模型,具有相似外观和含义的图像将在它创建的嵌入空间中被紧密放置在一起。

图 1:表示不同类别图像和同一嵌入空间中相似图像的嵌入可视化。由作者插图。

“模型可以将图像映射到嵌入,这是空间中的一个位置。因此,如果你在嵌入周围查看,你可以找到其他具有相似外观和含义的图像。这就是图像相似性搜索的工作原理!”[1]

图像和文本对的训练

类似于前面的示例,深度学习模型也可以通过相关的文本和图像配对进行训练。这是通过结合其他模型来实现的,如下图所示:

图 2:使用模型组合对图像和文本对进行训练,即“CoCa”。由作者插图。

让我们来解析一下当我们传入一个图像和文本对时发生了什么:

  • 图像编码器: 用于获取图像嵌入的模型,

  • 单模态文本编码器: 一种用于获取文本嵌入的模型。该模型由图像编码器模型输入,接受源图像嵌入作为输入,产生图像和文本对的序列表示,即自注意力

  • 多模态文本编码器: 一种学习图像和文本之间关系的模型。更正式地说,这种技术称为交叉注意力:一种在 Transformer 架构中混合两种不同嵌入序列的注意力机制,或者在我们的案例中是图像和描述它们的文本。

这种设计,或结合模型的一种方式,被称为对比字幕或简单地‘CoCa’,如果你想深入了解,可以查看这里

“结果:一个基础的‘视觉语言模型(VLM)’…

我们建立了一个具有固定维度的共享嵌入空间,用于图像和文本,按照它们的含义组织。在这个空间中,含义相似的图像和文本被放在一起。”[1]

图 3:相关图像和文本的嵌入可视化。由作者插图。

这意味着你可以根据文本搜索图像(文本到图像搜索),或者根据图像搜索文本(图像到文本搜索)。

这是 Google 搜索如何在图像和文本中找到相关结果的基本思路。

🔍 试一下快速演示!

想看看文本和图像嵌入在现实世界应用中的效果吗?

你可以通过使用在 Nomic 提供的 Altas 上运行的演示免费进行体验。

“Atlas 使你能够与非结构化文本、图像和音频数据进行互动、发现洞察并进行构建。”[2]

这里有一个搜索演示,将 Mercari 网站(一个日本电子商务零售商)上可用的项目的文本和图像嵌入结合在一起。

1. 导航至:atlas.nomic.ai/map/vertex-mercari(你可能需要创建一个免费账户以获得访问权限)。

图 4:Nomic 的 Atlas 用户界面的截图,运行 Mecari 嵌入演示。

2. 你可以在表示嵌入空间的“点云”可视化上移动鼠标光标,以进行搜索。

在界面右上角的“选择工具”中,你可以输入文本搜索查询,按某些属性进行筛选或使用‘套索’工具进行自定义选择。

真的就这么简单!如果你想了解更多关于它的组装过程,可以查看 这里

🍱 多模态语言模型

是的,这比我们讨论的内容还要多。对于大型语言模型,复杂的 变换器 架构用于通过标记化、位置编码和嵌入层将文本和其他数据转换为向量并进行反向转换。

但总的来说,我们之前讨论过的相同原理,使得我们可以利用图像来补充传递给大型语言模型(即多模态语言模型)的文本提示,这允许用户指定任何视觉或语言任务。

多模态语言模型是最近的一个强大发展,像 GPT-4VMedPalm M 这样的例子正在推动我们使用大型语言模型的边界,因为它们可以根据图像和文本输入提供丰富的响应。

例如,MedPalm M 使得基于 X 射线图像让模型对患者进行诊断成为可能,结果可与合格的医生相媲美!

重要的是要注意,多模态语言模型并不完美,仍然可能受到早期模型局限性的影响。

它们仍然不是完全可靠的(即,它们可能“幻想”事实并产生推理错误)。在使用语言模型输出时,尤其是在高风险情境下(如医疗诊断),应特别小心。

确保适当的保护措施和流程到位是至关重要的(例如人工审核、附加背景信息的基础,或甚至完全避免高风险用例)。

这是一个令人兴奋的领域,代表了大型语言模型的下一次进化!

🏁 总结

在这篇文章中,我们介绍了:

  • 嵌入是如何被用于使模型捕捉(编码)它们训练时输入的数据的。

  • 多模态深度学习模型的概念通常由多个单模态神经网络组成,这些网络分别处理每种输入模态。

  • 一个简单的演示,结合文本和图像嵌入,以说明在网站上搜索产品时的多模态搜索用例。

  • 最后,我们还讨论了一些潜在的用例以及实际的多模态 LLM 应用实例。

👋🏼感谢你的光临,希望你喜欢这篇文章,我们下次见!

📚 参考资料及进一步阅读

[1] “什么是多模态搜索:‘具有视觉能力的 LLM’如何改变业务” - cloud.google.com/blog/products/ai-machine-learning/multimodal-generative-ai-search

[2] atlas.nomic.ai/

出版物:

Transformer 架构中的 Query、Key 和 Value 是什么?它们为什么被使用?

原文:towardsdatascience.com/what-are-query-key-and-value-in-the-transformer-architecture-and-why-are-they-used-acbe73f731f2

对 Transformer 架构中 Key、Query 和 Value 概念背后的直觉进行分析,以及为何使用它们。

Ebrahim PichkaTowards Data Science Ebrahim Pichka

·发布于 Towards Data Science ·阅读时间 10 分钟·2023 年 10 月 5 日

--

作者提供的图像 — 由 Midjourney 生成

介绍

近年来,Transformer 架构在自然语言处理(NLP)领域引起了轰动,在机器翻译、语言建模、文本摘要等多种任务中取得了最先进的成果,并且在其他 AI 领域(如视觉、语音、强化学习等)也有所应用。

Vaswani 等人(2017 年)首次在他们的论文“Attention Is All You Need”中介绍了 Transformer,其中他们使用了自注意力机制,而没有加入递归连接,同时模型可以选择性地关注输入序列的特定部分。

Transformer 模型架构 — 来自 Vaswani 等人(2017 年)论文的图像(来源:arXiv:1706.03762v7

特别是,之前的序列模型,例如递归编码器-解码器模型,在捕捉长期依赖关系和并行计算方面存在限制。实际上,在 2017 年 Transformer 论文发布之前,大多数 NLP 任务的最先进性能是通过在 RNN 上使用注意力机制获得的,所以注意力在 Transformer 之前就已存在。通过引入多头注意力机制,并去掉 RNN 部分,Transformer 架构通过允许多个独立的注意力机制解决了这些问题。

在这篇文章中,我们将深入探讨该架构的一个细节,即查询(Query)、键(Key)和值(Value),并尝试理解这部分所使用的直觉。

请注意,这篇文章假设你已经熟悉一些基本的自然语言处理和深度学习概念,如嵌入线性(密集)层,以及一般的简单神经网络的工作原理。

注意!

首先,让我们了解注意力机制试图实现什么。为了简化起见,我们从一个简单的例子开始,了解我们要解决的具体问题,而不深入讨论注意力机制的所有术语。

上下文很重要

考虑平滑时间序列数据的情况。时间序列已知是最基本的序列数据之一,因为它已经是数值化和结构化的形式,并且通常处于低维空间。因此,提出一个好的起始示例是合适的。

为了平滑一个高度变化的时间序列,一种常见的技术是计算每个时间步的“加权平均值”,如图 1 所示,权重通常基于相邻时间步距离目标时间步的远近来选择。例如,在高斯平滑中,这些权重是从以当前步为中心的高斯函数中提取的。

时间序列平滑示例 — 作者提供的图像。

从某种意义上说,我们所做的是:

  1. 我们取了一系列值

  2. 对于序列中的每一步,我们添加了(加权的)上下文来自其邻近值,而添加的上下文(权重)仅与它们的接近度相关。

  3. 最后,我们获得了一个新的上下文化的序列,这使得我们可以更容易地理解和分析。

这个示例中有两个关键点/问题:

  • 它仅使用接近度顺序位置的值来获取上下文的权重。

  • 权重是通过对所有点应用固定的任意规则来计算的。

语言的案例

在机器学习中,文本数据通常需要用实值向量(即嵌入)来表示。因此,我们假设标记(或单词)的主要含义被编码在这些向量中。现在,对于文本序列数据,如果我们想要像上述示例那样对序列中的每个标记进行上下文化,使每个标记的新嵌入包含更多关于其上下文的信息,我们将遇到一些问题,接下来我们将讨论这些问题:

首先,在上面的示例中,我们仅仅使用了标记的接近度来确定要添加的上下文的重要性(权重),而单词的工作方式并非如此

在语言中,单词在句子中的上下文不仅仅基于顺序距离和接近度。我们不能仅仅依赖接近度来融入其他单词的上下文。

其次,仅通过对上下文标记的嵌入的(加权)平均值来添加上下文可能不够直观。一个标记的嵌入可能包含有关该标记的不同句法、语义或词汇方面的信息。所有这些信息可能与要添加的目标标记无关。因此,最好不要将所有信息作为整体添加为上下文。

那么,如果我们有一些(向量)表示序列中的词,我们如何获得权重相关的上下文以重新加权和上下文化序列中的每个标记?

从广义上讲,答案是我们必须基于标记意义的某些特定方面(可以是语义的、句法的或其他任何方面)“搜索”它。在此搜索过程中,根据相关性或重要性分配权重上下文信息

这意味着,对于序列中的每个标记,我们必须遍历序列中的所有其他标记,并根据我们用来比较目标标记与其他标记的相似性度量,为它们分配权重上下文信息它们在期望上下文中的相似性越大,权重就越大

因此,一般来说,我们可以说注意力机制基本上是(1)为序列中的其他标记分配权重,(2)从其他标记中提取相关上下文,以根据它们与目标标记的相关性或重要性(即关注它们)。

我们说过,为了找到相关性/重要性,我们需要在序列中进行搜索并逐一比较标记。

在序列中搜索与标记相关的上下文以进行添加——图片由作者提供。

这就是查询找到意义的地方。

查询**

为了更清楚地理解,可以想象一下你在 YouTube 上搜索内容的情形。例如,假设 YouTube 将所有视频存储为一对“视频标题”和“视频文件”本身。我们称之为键值对,其中键是视频标题,值是视频本身。

你在搜索框中输入的文本在搜索术语中称为查询。所以从某种意义上讲,当你搜索某个内容时,YouTube 将你的搜索查询与所有视频的键进行比较,然后衡量它们之间的相似性,并根据相似性从高到低排序它们的

一个基本的搜索过程展示了键、查询和值的概念——图片由作者提供。

在我们的问题中,我们有一个标记向量的序列,我们想要搜索权重以重新加权和上下文化序列中的每个标记(词)嵌入,我们可以从以下方面考虑:

  1. 你想要查找的是查询

  2. 你正在搜索的是键值对

  3. 查询会与所有的键进行比较,以衡量相关性/重要性/相似性

  4. 根据分配的相似性度量来使用。

另一个有用的相关类比是字典(或哈希表)数据结构。字典以键值对的形式存储数据,将键映射到其相应的值对。当你尝试获取特定的值时,你必须提供一个查询来匹配其对应的,然后它在这些键中搜索与查询进行比较如果匹配,则返回所需的值。

然而,这里的区别在于这是一个“硬匹配”情况,其中查询要么完全匹配键,要么不匹配,中间的相似性不会被测量。

字典查询与键值对匹配 — 图片来源于作者

我们之前提到,我们只处理实值向量(标记嵌入)。因此,查询、键和值也需要是向量。然而,到目前为止,我们只有每个标记的一个向量,即其嵌入向量。那么,我们应该如何获得查询、键和值向量呢?

我们构造它们使用线性投影(线性变换即单个密集层,具有不同的权重集合:Wq、Wₖ、Wᵥ)对每个标记的嵌入向量进行变换。这意味着我们为查询、键和值分别使用可学习的权重向量,对词嵌入进行线性变换,以获取相应的查询、键和值向量

对词嵌入进行线性变换以获取查询、键和值向量 — 图片来源于作者

一个标记的嵌入可能代表该标记的不同上下文、结构和语法方面或含义。通过使用可学习的线性变换层来从标记的嵌入构造这些向量,我们允许网络:

  1. 提取并将信息的有限特定部分传递到QKV向量中。

  2. 确定一个更狭窄的上下文,在其中进行搜索和匹配。

  3. 学习在嵌入中哪些信息更重要。

现在,手中有了QKV向量,我们能够执行之前讨论的“搜索和比较”过程。这导致了注意力机制的最终推导,如(Vaswani et al 2017)中所提。

对于每个标记:

  • 我们将其查询向量与所有其他标记的键向量进行比较。

  • 计算每两个之间的向量相似性分数(即原始论文中的点积相似性)

  • 将这些相似性分数转换为权重,通过将它们缩放到 [0,1](即 Softmax)

  • 并通过加权其对应的值向量来增加加权的上下文。

点积注意力过程 — 图片来源于作者

因此,QKV向量的整个概念就像是一个词典,用于模拟搜索与匹配过程,从中我们学习两个序列令牌的相关性(权重)以及应该添加什么作为上下文(值)。还要注意,这一过程不必按顺序进行(一个令牌一次)。这一切通过矩阵操作并行进行。

请注意,在下面的插图中,矩阵的维度与原始论文中的维度有所不同(n_tokensdim 而不是 dimn_tokens)。稍后在本文中,您将看到注意力机制的原始和完整公式,其顺序与此相反。

点积注意力的矩阵形式 — 作者绘制的图片

这导致了对每个令牌的上下文感知嵌入,其中添加的上下文基于令牌之间的相关性,并通过QKV向量转换学习得到。因此,使用了点积注意力机制。Vaswani 等人(2017)的原始注意力机制也缩放了KQ向量的点积,即将结果向量除以sqrt(d),其中d是查询向量的维度。因此得名“缩放点积注意力”。这种缩放有助于在传递到 Softmax 函数之前减少点积的方差。

注意力机制公式 — Vaswani 等人(2017)(来源:arXiv:1706.03762v7

最后,我们提到将嵌入转换为QKV的线性层可能只提取嵌入中的特定模式以找到注意力权重。为了使模型能够学习序列令牌之间的不同复杂关系,创建并使用这些QKV的多个不同版本,以便每个版本关注嵌入中存在的不同模式。这些多个版本称为注意力头,因此得名“多头注意力”。这些头部也可以向量化,并使用当前流行的深度学习框架并行计算。

多头缩放点积注意力 — 图片来自 Vaswani 等人(2017)的论文(来源:arXiv:1706.03762v7

结论

总结一下,在这篇文章中,我试图描绘和分析 Query、Key 和 Value 的直觉,这些是注意力机制中的关键组件,初次接触时可能有点难以理解。

本文讨论的注意力机制是提出在变换器架构中,这种架构在(Vaswani et al, 2017)的论文“Attention is all you need”中介绍,并且自此以来,在深度学习的多个任务和基准中一直是表现最优的架构之一。鉴于其广泛的应用和适用性,了解这一架构中的细节和使用原因将会很有帮助。

我在解释这个话题时尽量做到清晰和基础,通过举例和插图尽可能地说明。

参考文献

[1] Vaswani, Ashish, Noam Shazeer, Niki Parmar, Jakob Uszkoreit, Llion Jones, Aidan N. Gomez, Lukasz Kaiser, and Illia Polosukhin. “Attention Is All You Need.” arXiv, 2023 年 8 月 1 日。 doi.org/10.48550/arXiv.1706.03762

GPT 模型背后的数据中心 AI 概念是什么?

原文:towardsdatascience.com/what-are-the-data-centric-ai-concepts-behind-gpt-models-a590071bb727

解读 ChatGPT 和 GPT-4 中使用的数据中心 AI 技术

Henry LaiTowards Data Science Henry Lai

·发表于 Towards Data Science ·阅读时间 8 分钟·2023 年 3 月 29 日

--

arxiv.org/abs/2303.10158。作者提供的图像。

人工智能(AI)在改变我们的生活、工作和与技术互动的方式上取得了令人难以置信的进展。最近,取得显著进展的一个领域是大型语言模型(LLMs)的发展,例如 GPT-3ChatGPTGPT-4。这些模型能够以令人印象深刻的准确性执行语言翻译、文本摘要和问答等任务。

尽管很难忽视大型语言模型(LLMs)模型尺寸的不断增长,但同样重要的是认识到它们的成功在很大程度上归功于用于训练它们的大量高质量数据。

在本文中,我们将从数据中心 AI 的角度概述大型语言模型(LLMs)的最新进展,借鉴我们最近的调查论文 [1,2] 以及在 GitHub 上的相关技术资源。特别是,我们将通过 数据中心 AI 的视角,深入探讨 GPT 模型。我们将通过讨论三个数据中心 AI 目标来解读 GPT 模型背后的数据中心 AI 概念: 训练数据开发、推理数据开发和数据维护

大型语言模型(LLMs)和 GPT 模型

LLM 是一种自然语言处理模型,经过训练以在上下文中推断单词。例如,LLM 的最基本功能是根据上下文预测缺失的标记。为此,LLM 通过海量数据训练来预测每个标记候选的概率。

一个示例,展示了如何在上下文中用 LLM 预测缺失标记的概率。图片由作者提供。

GPT 模型指的是一系列由 OpenAI 创建的 LLM,例如 GPT-1GPT-2GPT-3InstructGPTChatGPT/GPT-4。与其他 LLM 一样,GPT 模型的架构主要基于 Transformers,该架构使用文本和位置嵌入作为输入,并通过注意力层建模标记之间的关系。

GPT-1 模型架构。图片来自论文 cdn.openai.com/research-covers/language-unsupervised/language_understanding_paper.pdf

后来的 GPT 模型使用了与 GPT-1 相似的架构,但模型参数更多,层数更多,上下文长度更大,隐藏层大小等也有所增加。

GPT 模型的模型大小比较。图片由作者提供。

什么是数据驱动的 AI?

数据驱动的 AI 是一种新兴的思考方式,旨在构建 AI 系统。它得到了 AI 先驱 Andrew Ng 的倡导。

数据驱动的 AI 是系统地工程化用于构建 AI 系统的数据的学科。 — Andrew Ng

过去,我们主要关注在数据基本不变的情况下创建更好的模型(模型驱动 AI)。然而,这种方法可能会在现实世界中导致问题,因为它没有考虑到数据中可能出现的不同问题,如标签不准确、重复和偏差。因此,"过拟合" 一个数据集不一定会带来更好的模型表现。

相比之下,数据驱动的 AI 侧重于提高用于构建 AI 系统的数据的质量和数量。这意味着关注点在于数据本身,而模型则相对固定。采用数据驱动的方法开发 AI 系统在现实世界场景中具有更大的潜力,因为用于训练的数据最终决定了模型的最大能力。

需要注意的是,“数据中心”与“数据驱动”在根本上有所不同,因为后者仅强调使用数据来指导 AI 开发,通常仍然侧重于开发模型,而不是工程化数据。

数据中心 AI 与模型中心 AI 的比较。 arxiv.org/abs/2301.04819 图像由作者提供。

数据中心 AI 框架 由三个目标组成:

  • 训练数据开发是为了收集和生成丰富且高质量的数据,以支持机器学习模型的训练。

  • 推断数据开发是为了创建新的评估集,这些评估集可以提供对模型更细致的见解,或通过工程化的数据输入触发模型的特定能力。

  • 数据维护是为了确保在动态环境中数据的质量和可靠性。数据维护至关重要,因为现实世界中的数据不是一次性创建的,而是需要持续的维护。

数据中心 AI 框架。 arxiv.org/abs/2303.10158。图像由作者提供。

数据中心 AI 如何让 GPT 模型取得成功

几个月前,Yann LeCun 在推特上表示 ChatGPT 并没有什么新意。确实,ChatGPT 和 GPT-4 中使用的所有技术(变换器、从人类反馈中学习的强化学习等)都并不新颖。然而,它们确实取得了之前模型无法达到的惊人结果。那么,它们成功的驱动力是什么呢?

训练数据开发。 通过更好的数据收集、数据标注和数据准备策略,用于训练 GPT 模型的数据的数量和质量有了显著提升。

  • GPT-1: BooksCorpus 数据集 被用于训练。该数据集包含 4629.00 MB 的原始文本,涵盖了来自冒险、奇幻和浪漫等多种类型的书籍。

    - 数据中心的 AI 策略: 无。

    - 结果: 关于这个数据集的 GPT-1 可以通过微调提高下游任务的表现。

  • GPT-2: WebText 被用于训练。这是一个由 OpenAI 创建的内部数据集,通过抓取 Reddit 上的外链生成。

    - 数据中心的 AI 策略: (1) 通过仅使用来自 Reddit 的外链(获得至少 3 个 Karma)来策划/筛选数据。 (2) 使用工具 DragnetNewspaper 提取干净的内容。 (3) 采用去重和一些其他基于启发式的清洗方法(论文中未提及具体细节)。

    - 结果: 经过筛选后获得了 40 GB 的文本。GPT-2 在未经过微调的情况下实现了强大的零样本结果。

  • GPT-3: GPT-3 的训练主要基于 Common Crawl

    - 数据中心 AI 策略:(1)训练分类器,根据每个文档与 WebText 的相似性来筛选低质量文档,WebText 是高质量文档的代理。 (2)使用 Spark 的 MinHashLSH 进行模糊去重。 (3)用 WebText、书籍语料库和维基百科来增强数据。

    - 结果: 经过筛选后,从 45TB 的纯文本中获得了 570GB 的文本(仅 1.27% 的数据在此质量筛选中被选择)。GPT-3 在零样本设置中显著优于 GPT-2。

  • InstructGPT: 让人类评估答案以调整 GPT-3,使其更好地符合人类期望。他们为标注员设计了测试,只有通过测试的标注员才有资格进行标注。他们甚至设计了一项调查,以确保标注员喜欢标注过程。

    - 数据中心 AI 策略:(1)使用人工提供的答案来调整模型,进行监督训练。 (2)收集比较数据来训练奖励模型,然后使用此奖励模型通过人类反馈强化学习(RLHF)来调整 GPT-3。

    - 结果: InstructGPT 显示出更好的真实性和更少的偏见,即更好的对齐。

  • ChatGPT/GPT-4: OpenAI 并未公开详细信息。但已知 ChatGPT/GPT-4 大体上遵循之前 GPT 模型的设计,并且仍然使用 RLHF 来调整模型(可能使用了更多、更高质量的数据/标签)。普遍认为 GPT-4 使用了更大的数据集,因为模型权重有所增加。

推理数据开发。 由于最近的 GPT 模型已经足够强大,我们可以通过调整提示(或调整推理数据)来实现各种目标,而不需要调整模型。例如,我们可以通过将待总结的文本与“总结一下”或“TL;DR”这样的指令一起提供来进行文本摘要,从而引导推理过程。

提示调优。 arxiv.org/abs/2303.10158。图像由作者提供。

设计适当的推理提示是一项具有挑战性的任务。这在很大程度上依赖于启发式方法。一项不错的 调查 总结了不同的促销方法。有时,即使是语义上相似的提示也可能产生非常不同的输出。在这种情况下,可能需要 软提示基础校准 来减少方差。

基于软提示的校准。图像来自论文 arxiv.org/abs/2303.13035v1,已获原作者许可。

LLM 的推理数据开发研究仍处于初期阶段。更多 推理数据开发技术在其他任务中 的应用可能会在不久的将来应用于 LLM。

数据维护。 ChatGPT/GPT-4 作为一种商业产品,不仅仅是训练一次,而是会持续更新和维护。显然,我们无法了解 OpenAI 外部的数据维护是如何执行的。因此,我们讨论一些用于 GPT 模型的数据中心 AI 策略,这些策略现在或将来很可能会被使用:

- 持续的数据收集: 当我们使用 ChatGPT/GPT-4 时,我们的提示/反馈可能会被 OpenAI 进一步用于提升他们的模型。质量指标和保证策略可能已经被设计和实施,以在此过程中收集高质量的数据。

- 数据理解工具: 可能已经开发出各种工具来可视化和理解用户数据,从而更好地理解用户的需求并指导未来的改进方向。

- 高效的数据处理: 随着 ChatGPT/GPT-4 用户数量的快速增长,需要一个高效的数据管理系统来实现快速的数据获取。

ChatGPT/GPT-4 使用“赞”和“踩”来收集用户反馈,以进一步发展他们的系统。截图来自 chat.openai.com/chat

数据科学社区能从这波 LLM 中学到什么?

LLM 的成功已经彻底改变了 AI。展望未来,LLM 可能会进一步革新数据科学生命周期。我们做出两个预测:

  • 数据中心 AI 变得更加重要。 经过多年的研究,模型设计已经非常成熟,特别是在 Transformer 之后。工程数据将成为未来提高 AI 系统的关键(或可能是唯一)途径。此外,当模型变得足够强大时,我们在日常工作中无需训练模型。相反,我们只需设计合适的推理数据(提示工程)以从模型中探测知识。因此,数据中心 AI 的研究与发展将推动未来的进步。

  • LLM 将推动更好的数据中心 AI 解决方案。 许多繁琐的数据科学工作可以借助 LLM 更高效地完成。例如,ChatGPT/GPT-4 已经能够编写可用的代码来处理和清理数据。此外,LLM 甚至可以用于创建训练数据。例如,最近的工作 表明,使用 LLM 生成合成数据可以提升临床文本挖掘中的模型性能。

使用 LLM 生成合成数据以训练模型。图片来自论文 arxiv.org/abs/2303.04360 并获得原作者的许可。

资源

我希望这篇文章能激发你在自己的工作中。你可以通过以下论文了解更多关于数据中心 AI 框架以及它如何使 LLM 受益的信息:

我们维护了一个GitHub 仓库,该仓库将定期更新相关的数据驱动 AI 资源。敬请关注!

在后续文章中,我将深入探讨数据驱动 AI 的三个目标(训练数据开发、推理数据开发和数据维护),并介绍代表性的方法。

对编码分类受保护属性的公平性影响是什么?

原文:towardsdatascience.com/what-are-the-fairness-implications-of-encoding-categorical-protected-attributes-2cc1dd0f5229?source=collection_archive---------5-----------------------#2023-05-06

探讨编码受保护属性对机器学习公平性的影响

Carlos MouganTowards Data Science Carlos Mougan

·

关注 发表在Towards Data Science ·7 分钟阅读·2023 年 5 月 6 日

--

曙光中的公正女神来自Unsplash

我们将探讨分类属性编码的世界及其对机器学习模型在准确性和公平性方面的影响。分类属性,如出生国家或族裔,在确定数据中敏感信息的存在方面起着关键作用。然而,许多机器学习算法难以直接处理分类属性,因此需要使用编码方法将其转换为模型可以利用的数值特征。此外,我们还研究了交叉公平性工程的影响。

本博客包含了我们AI、伦理和社会(AIES'23)会议论文编码保护分类属性的公平性影响的总结,[link]。

总结: 编码保护属性提高了模型性能,但也增加了公平性违背。这可以通过目标编码正则化来调和。工程化交叉保护属性(性别-种族)提高了性能,但大幅增加了公平性违背。

引言

敏感属性在公平性中至关重要,其处理贯穿整个机器学习流程。许多机器学习算法要求将分类属性适当地编码为数值数据,然后再输入到算法中。

编码分类保护属性的影响是什么?

诱导偏差的类型

我们研究了这些编码方法可能引发的两种偏差:不可减少的偏差和可减少的偏差:

  • 不可减少的偏差: 这是指由于将群体分类到标签中而产生的(直接)群体歧视:关于比较群体的更多数据无法减少这种类型的偏差。在 COMPAS 数据集中,犯罪分子的族裔在确定再犯评分时至关重要;对像非洲裔美国人白人这样的大族裔群体的数值编码可能导致歧视,这是一种源于不可减少偏差的不公平效应。

  • 可减少的偏差: 由于对具有小统计代表性的群体进行编码时的方差而产生,有时甚至只有非常少的实例。当对族裔类别阿拉伯裔进行编码时,常常会引发较大的采样方差,最终导致几乎是随机和不现实的编码,从而发现和引入可减少的偏差。

编码方法

独热编码: 这是分类特征中最成熟的编码方法,也是公平性文献中的默认方法。

One Hot Encoding 的示例。图片来源:作者

  • 目标编码: 分类特征被替换为各自类别的均值目标值。这种技术处理高基数分类数据,并对类别进行排序。目标编码的主要缺点出现在样本较少的类别被替换为接近期望目标的值时。这会引入模型偏差,因为它过度信任目标编码特征,并使其容易过拟合和减少偏差。

此外,这种类型的编码允许正则化。在本文中,我们研究了两种类型的正则化(在博客中我们只研究了高斯正则化)

目标编码示例说明。作者提供的图像

实验

对于预测性能,我们使用 AUC 和公平性指标。参考组(r)与我们想要比较的组(i)之间。Z 是受保护的属性,\hat{Y}是模型预测。

人口统计学平等

不受特权组与受特权组获得的有利结果之间的差异

平等机会公平性

确保公平机会而非原始结果。该值是

受保护组与

参考组

平均绝对赔率

不受特权组与受特权组的真实正例率和假正例率之间绝对差异的总和

实验假设

对受保护属性的编码

  1. 提高性能

  2. 增加了公平性违反

  3. 性能和公平性可以通过目标编码正则化来调和。

图:比较 OHE 和目标编码正则化(高斯噪声)在 COMPAS 数据集上的逻辑回归。红点表示不同的正则化参数:红色越深,正则化越高。蓝点表示独热编码。作者提供的图像。

高斯噪声正则化参数\(\lambda\)对 COMPAS 数据集测试集上的性能和公平性指标的影响,使用 L1 惩罚的逻辑回归。在左侧图像中,所有受保护组的 AUC 都超过了正则化超参数。在右侧,平等机会公平性、人口统计学平等和平均绝对赔率在正则化超参数中的变化。作者提供的图像

在实验中,我们展示了公平机器学习文献中最常用的分类编码方法——独热编码,在平等机会公平性方面比目标编码更具歧视性。然而,目标编码表现出了良好的结果。使用高斯正则化的目标编码在存在两种偏见时显示了改善,但在过度参数化的情况下风险会显著丧失模型性能。

交叉公正性

在机器学习中追求公平时,必须认识到属性的复杂相互作用及其对歧视的影响。本节将深入探讨分类属性编码对交叉公正性的影响,重点关注从 COMPAS 数据集中获得的见解。我们提出了有关通过属性工程可能导致公正性下降的假设、分类编码可能增加歧视的倾向以及正则化技术在缓解交叉偏见中的有效性。

为了探讨编码对交叉公正性的影响,我们分析了 COMPAS 数据集中连接的“民族”和“婚姻状况”属性。通过选择“白人已婚”组作为参考,我们比较了所有组的最大公平性违规。为了便于理解,我们利用了上一节的广义线性模型,并强调平等机会公平性指标,这与其他公平性指标的行为一致。

编码分类保护属性的平等机会公平性及其在 Compas 数据集上的正则化效果。水平线是保护属性未包含在训练数据中的基线。正则化目标编码不会损害公平性指标,但可以提高该数据集的预测性能。图片由作者提供。

上图直观地展示了属性连接如何创建交叉属性并加剧公平性违规,为我们的第一个假设提供了实证支持。值得注意的是,即使在未编码保护属性的情况下(由水平线表示),最大公平性违规也显著增加,从“民族”0.015 或“婚姻状况”0.08 增加到交叉属性的 0.16。这一发现证实了金伯莉·克伦肖 1958 年的开创性工作,揭示了不同形式的压迫如何交织在一起并加剧对边缘化群体的歧视。

此外,我们的第二个假设得到了验证,即观察到这两种编码技术导致的平等机会违反率高于不编码受保护属性的情况。这突显了编码在放大歧视方面的作用。然而,仍有一线希望:通过目标编码的正则化,可以提升公平性。这个结果与我们的理论理解一致,因为属性连接可能会通过增加不可减少偏差和可减少偏差来恶化公平性。

结论

我们的研究强调了类别属性编码在平衡机器学习模型的准确性和公平性方面的重要作用。我们已识别出编码类别属性时可能出现的两种偏差:不可减少偏差和可减少偏差。

通过理论分析和实证实验,我们发现独热编码(one-hot encoding)表现出比目标编码(target encoding)更多的歧视。然而,经过正则化的目标编码表现出有希望的结果,它在保持可接受的模型性能的同时,展现了提高公平性的潜力。

我们强调了考虑编码类别受保护属性的影响的重要性,因为对编码方法进行轻微修改可以在不显著牺牲预测准确性的情况下实现公平性改善。

潜台词

近年来,我们看到许多算法方法从数据收集、预处理、处理过程中以及后处理步骤等多个角度来提高数据驱动系统中的公平性。在这项工作中,我们集中研究了如何通过编码类别属性(一个常见的预处理步骤)来调和模型质量和公平性。

许多公平机器学习工作的一个共同基础假设是,公平性与准确性之间的权衡可能需要复杂的方法或困难的政策选择 [Rodolfa et al.]

由于正则化的目标编码易于执行且不需要对机器学习模型进行重大更改,因此它可以作为公平机器学习中处理方法的合适补充,值得在未来进一步探索。

我们鼓励行业从业者考虑编码类别受保护属性的影响。通过对编码方法进行轻微调整,可以在不显著影响预测性能的情况下实现公平性改善。然而,必须理解的是,使用公平人工智能方法并不保证复杂社会技术系统的公平性。

限制:本工作旨在展示在任何时刻对分类保护属性进行编码的一些影响。应理解为,在任何情况下对分类保护属性的编码不会增加公平性指标;我们提倡在公平性轴上考虑编码正则化的效果,而不仅仅是在预测性能轴上。Fair-AI 方法并不一定保证基于 AI 的复杂社会技术系统的公平性。

致谢

本工作得到了欧洲联盟 Horizon 2020 研究与创新计划资助,资助项目为 Marie Sklodowska-Curie Actions(资助协议编号 860630),项目名称为‘’NoBIAS — Artificial Intelligence without Bias’’

免责声明

本工作仅反映作者的观点,欧洲研究执行局(REA)对其包含的信息的任何使用不承担责任。

引用

@inproceedings{fairEncoder,
author = {Mougan, Carlos and Alvarez, Jose M. and Ruggieri, Salvatore and Staab, Steffen},
title = {Fairness Implications of Encoding Protected Categorical Attributes},
year = {2023},
url = {https://arxiv.org/abs/2201.11358},
booktitle = {Proceedings of the 2023 AAAI/ACM Conference on AI, Ethics, and Society},
location = {Montreal, Canada},
series = {AIES '23}
}

成为初创公司全栈数据科学家的体验

原文:towardsdatascience.com/what-being-a-full-stack-data-scientist-at-a-startup-is-like-fa54b6be4c26

持续加速,高度协作,并且不断学习

Ani MadurkarTowards Data Science Ani Madurkar

·发表于 Towards Data Science ·阅读时间 7 分钟·2023 年 8 月 5 日

--

冰岛的午夜日落。作者提供的图像

在过去大约 12 个月里,我在一家健康科技领域的初创公司担任数据科学家。我作为团队中的两名数据科学家之一加入,这基本上意味着我们需要成为全栈工程师和科学家,以完成工作并建立可扩展的系统,为公司的未来成功奠定基础。

在这段时间里,我学到了比在其他任何角色中学到的更多,这篇文章展示了三种主要理念,最好地总结了我迄今为止的经验。

从本质上讲,你需要成为一个矛盾体。你必须在通常彼此对立的世界之间保持微妙的平衡。这项工作的这一方面可能很难出色,因为它通常要求你比其他大多数角色付出更多。但对于那些渴望获得极具回报的学习经历的人来说,这是无可比拟的。

成为建设者和战略家

你需要构建的内容实际上取决于初创公司的早期阶段以及数据科学/机器学习、数据工程和数据分析团队的人员数量。无论如何,最终可能还是要由你来操作完整的 ML 堆栈(从数据摄取到部署),并且还要构建一个平台以提升未来项目的效果。

这种情况通常表现为与关键业务利益相关者开会,并创建直接影响公司底线的模型。这在大多数数据项目中很常见,但这种场景下的噪音往往会更多。按定义,你正在一个尝试做新颖事情或以一种比竞争对手提供更大价值的方式解决问题的领域工作。这意味着你很可能不会参与传统的机器学习项目,做大家都在做的事情,你肯定不会拿到一个现成的项目;你将负责尝试构建一些新的东西。无论是数据集策划的新方法、特征工程、建模、模型应用,还是上述所有内容——你都应该尝试创新(当然仍需遵守伦理和法律约束)。

项目通常从一个深刻理解问题和/或客户及其当前需求的领域专家开始。作为数据科学家,你需要在各种想法中筛选出哪些是及时的、哪些需要更多高质量数据以及哪些是长期目标。这需要与领域专家进行策略规划,以便你可以朝着正确的方向执行。这里的策略规划由于组织的初创性质而显著不同,这意味着我们通常需要从可信赖的网站抓取数据来增强数据集,或需要与数据工程师紧密配合,建立 ETL 流程或为你的想法构建数据策划架构,而这些想法目前甚至尚不存在。

在实践中,制定正确的策略要困难得多,因为通常你需要尝试构建错误的东西以获得具体反馈,从而最终构建正确的东西。迭代是核心原则,但高效执行是宗旨。你必须能够比以往任何时候都更快地行动。由于速度的本质,你被迫只关注真正重要的事情,收集反馈,并继续前进。

寻找问题的关键点、从信号中解析噪音、每周发布代码以及不断响应反馈是非常宝贵的特质。通常,很难长时间保持这种状态,因此一个紧密而强大的团队对于实现这一目标至关重要。

成为工程师和科学家

尽管我强调了快速的重要性,但这奇怪地并不完全正确。更准确地说,你需要以一种方式进行构建,以便你明天能够更快。速度很重要,但加速是必不可少的。这对数据科学家来说本质上意味着你需要具备两个坚实的基础:Python 和统计学。这在数据科学家被聘用时总是需要的,但我所需要做的工作有时看起来像纯粹的软件工程,有时又像纯粹的统计学工作。

我的工作最初涉及了大量的数据工程类型的工作——收集优质数据集、设置 ETL 流程、为下游分析或建模策划数据集等。我并不是专业的数据工程师,所以这项工作是尽我所能地进行,以保持团队的速度。在我开始从事机器学习工作后,单独在 Jupyter notebooks 中操作每个模型是一种繁琐的方法,这不会进一步加速我们。解决方案是逐步构建一个 ML 平台,这样每次模型迭代变得更容易构建和部署。这项工作主要是软件工程类型的工作,如果没有对 Python 的强大掌握,我认为我不会有机会。在我构建这一平台的过程中,由于需要阅读大量使用各种 ML 方法的医疗数据研究论文——我们能否复制这些工作?他们有没有忽略的空白?我们可以采用他们测试过的哪些技术?了解如何快速阅读论文并将其转化为代码很快成为我需要发展的一个特质。

在这个角色中,数据科学家维恩图的每个角落对我来说都放大了 10 倍。为了达到预期的水平,我需要尽可能多地深入每一个领域。作为回报,我几乎消除了自己的冒名顶替综合症,同时在过程中学到了大量的知识。我绝对不是要美化这一点——做所有这些工作可能不是数据科学家角色的常态,但如果你发现自己想在初创公司做这些工作,这可能就是它的样子。正如那句老话所说,“万事通不精通,但往往胜过一技之长者”。

成为一个所有者和合作者

这是大多数人在职业发展中不得不面对的一个方面,但在初创公司中做这件事就像是蒙着眼睛做。你通常没有交付大规模项目的缓冲或安全网,这些项目除了浪费工作/时间之外没有任何影响。每个人都稍显紧张,客户始终是第一位的,所以你需要完全拥有你负责的项目。我几乎没有哪个团队成员等待被告知该做什么,他们通常看到需要完成的工作并在完成要求的工作之外也把它做得对。

在这里,所有权通常意味着端到端的所有权。对于一个数据项目,这包括从数据可以被整理的那一刻开始(从哪里?多频繁?需要如何清洗?需要存储在哪里?等等)到数据分析/处理(需要创建哪些指标?如何分析这些数据?需要跟踪哪些相关模式?等等),再到数据建模(数据应该如何建模?哪些模型效果最好?当前文献有什么说法?等等),再到评估和部署(如何衡量成功?失败意味着什么?模型部署在哪里?客户如何访问?等等)。这种端到端的思维不仅仅停留在部署阶段,因为你还需要进行模型监控和重新训练的触发。这需要承担很多责任,而不是一个人能完成的。

对于一家高速增长的公司而言,协作尤其困难,因为新员工不断加入,角色不断被定义。你需要快速建立朋友,这样你才能推动这些项目完成。说实话,公司的文化在很大程度上可以量化为有多少人愿意为他人提供帮助。如果你碰巧进入一个在快速的 Slack 会议后,大家都愿意迅速交朋友并帮助你完成工作的组织,你最好确保你表达深切的感激之情。聪明的人很少,聪明且有强烈工作伦理的人更是稀有,而那些聪明且有强烈工作伦理并且总是愿意帮助你的聪明人则是独角兽。

我所做的一切都离不开那些愿意伸出援手,帮助我完成目标的人的慷慨。在长期的时间里,这种行为会形成一种深具韧性和强大的文化。这种文化可以通过你首先成为一个愿意快速帮助他人的人来建立。不要等待其他人来帮助你,而要主动伸出橄榄枝,只为了看到一个朋友成功。随着时间的推移,你将建立一个围绕你的团队,其中充满了那些不会让你失败而无法东山再起的人。

希望这个故事能让你对我过去的一年有一些了解(并部分解释为什么我最近有点远离写作)。我特别希望能与有类似经历或处于类似位置的人交流,并从你们那里学习。我相信我的世界中还有许多可以改进的地方,希望了解如何做到这一点。

当然,如果你希望我写关于我工作的更多方面,请告诉我!非常感谢你阅读这些内容。

使用我的推荐链接成为 Medium 会员

Medium 是我进行日常阅读的大型资源库,如果你在数据领域,这个平台是一个宝贵的金矿。如果你希望订阅,这是我的推荐链接。完全公开:如果你使用这个链接订阅 Medium,你的部分订阅费用将直接进入我的账户。希望你能成为我们社区的一员。

## 通过我的推荐链接加入 Medium - Ani Madurkar

作为 Medium 会员,你的一部分会员费会用于支持你阅读的作者,同时你可以完全访问每一个故事……

animadurkar.medium.com

ChatGPT 对你的了解:OpenAI 在数据隐私方面的进展

原文:towardsdatascience.com/what-chatgpt-knows-about-you-openai-towards-data-privacy-science-ai-b0fa2376a5f6

管理 ChatGPT 个人数据的新方法

安德烈亚·瓦伦苏埃拉Towards Data Science 安德烈亚·瓦伦苏埃拉

·发布于 Towards Data Science ·阅读时间 11 分钟·2023 年 5 月 9 日

--

图片由 马修·亨利 提供,来源于 Unsplash

在 3 月 20 日 ChatGPT 数据中断引发的各种关注之后,我们迅速观察到外界的一些反应。最强烈的反应是什么? 意大利因数据隐私问题禁止 ChatGPT

近一个月后的事件,OpenAI 已经在用户数据隐私方面采取了一些措施:可以关闭聊天记录功能并导出你的个人数据,即他们从你与 ChatGPT 的互动中保留的数据。

这篇文章概述了 OpenAI 在强大 AI 生成技术 ChatGPT 的数据隐私方面采取的两项主要措施。我们将通过仔细查看 ChatGPT 从用户那里保留的数据,来尝试这两个新功能,以帮助你理解所给格式,从而解读你的数据。

#1. 关闭聊天记录

ChatGPT 的聊天记录不仅仅是存储你与聊天机器人对话的方式,让你可以随时登录查看过去的对话:你的聊天记录也被用来训练和改进 ChatGPT 背后的模型

聊天记录功能于 2022 年 12 月 15 日启用,老实说:我们都从存储对话中受益!但也确实,这一功能引发了一些数据隐私问题:ChatGPT 是否保存对话数据来训练其 AI 模型? 如果对话中涉及敏感或个人数据怎么办?

现在 OpenAI 赋予了用户控制权! 根据OpenAI 的公告,从 4 月 25 日起,可以禁用聊天记录,这样对话将不再出现在侧边栏中。此外,它们不会被用于进一步的训练,为用户提供了管理数据的选项。

之前,用户可以根据需求定期清除聊天记录,但任何对话仍然可以用于微调。目前,如果禁用聊天记录,对话只会保留 30 天。这是为了防止由于工具的误用需要审核对话,然后再永久删除它们。

设置控制中禁用聊天记录非常简单。要在网页界面中访问设置,请导航到主页左下角的部分。会弹出一个小窗口,你将在那里找到聊天记录和训练的控制:

自制的 ChatGPT 设置窗口截图。

在这一点上,我相信你也会注意到这个问题:

为什么 OpenAI 将保存聊天记录与使用这些数据训练其 AI 模型结合起来?

我猜这是一种微妙的方式,迫使用户继续使用他们的对话用于训练目的。 作为对 OpenAI 的支持点,从我的专业经验来看,我清楚地看到使用这些真实数据进行训练的好处。

#2. 导出你的个人数据

OpenAI 还在 ChatGPT 的设置中添加了第二个新功能:一个导出选项,以获取你的 ChatGPT 数据,并了解 ChatGPT 存储了关于你的哪些信息。

这个新选项可以看作是朝着欧盟通用数据保护条例(GDPR)迈出的一个步骤。GDPR 定义了处理数据的义务,以便利数据主体访问其个人数据。这就是为什么收集个人信息的平台,如GoogleNetflix,现在必须随时向用户提供他们拥有的数据。

在网页界面中,导出个人数据也非常简单。导出数据按钮就在聊天记录和训练按钮下方:

自制的 ChatGPT 设置窗口截图。

在导出数据的前几分钟,我在注册邮箱收到了一个包含我对话和其他相关信息的文件。

自制的 ChatGPT 设置窗口截图。

确认导出操作后,这是我在邮箱中收到的:

从 ChatGPT 的导出邮件中自制的截图。

点击下载按钮,我得到了一个包含 5 个htmljson格式文件的文件夹。

允许用户请求其个人数据的公司使其遵守上述 GDPR 法规。然而,有一个问题:文件格式可能使数据对大多数人不可读。在这种情况下,我们得到了htmljson文件。虽然html可以直接读取,json文件则可能更难以解释。我个人认为,新法规也应该强制要求数据具有可读格式。但目前为止……

让我们一个一个地探索这些文件,以充分利用这个新功能!

聊天记录

第一个文件是chat.html,其中包含我与 ChatGPT 的完整聊天记录。对话按其对应的标题存储。用户的问题和 ChatGPT 的回答分别标记为assistantuser

如果你曾经自己训练过 AI 模型,这个标记系统对你来说应该很熟悉

让我们观察一下我历史中的一个示例对话:

我从 ChatGPT 历史中自制的截图。对话标题用蓝色突出显示。用户/助手标签分别用红色和绿色突出显示。

用户反馈

你是否见过 ChatGPT 回答旁边的竖起大拇指和竖下大拇指图标 (👍👎)?

这些信息被 ChatGPT 视为对给定答案的反馈,这将有助于聊天机器人训练。

这些信息存储在message_feedback.json文件中,包含您通过竖起大拇指图标提供的任何反馈。信息以以下格式存储:

[{"message_id": <MESSAGE ID>, "conversation_id": <CONVERSATION ID>, "user_id": <USER ID>, "rating": "thumbsDown", "content": "{\"tags\": [\"not-helpful\"]}"}]

thumbsDown评分用于记录错误生成的答案,而thumbsUp用于记录正确生成的答案。

用户数据

还有一个文件(user.json)包含用户的以下个人数据:

{"id": <USER ID>, "email": <USER EMAIL>, "chatgpt_plus_user": [true|false], "phone_number": <USER PONE>}

一些平台因根据用户使用平台的情况创建用户模型而闻名。例如,如果Google的用户搜索大多与编程有关,Google可能会推断该用户是程序员,并利用这些信息显示个性化广告。

ChatGPT 可以用对话中的信息做同样的事情,但目前他们被要求将这些推测的信息包含在导出的数据中

⚠️ 仅供参考, 可以通过点击 Gmail 中的 账户 >> 数据与隐私 >> 个性化广告 >> 我的广告中心 来访问 Google 对他们的了解。

完整对话历史

还有一个包含对话历史的文件,还包括一些元数据。这个文件名为conversations.json包括诸如创建时间、多个标识符以及 ChatGPT 背后的模型等信息

⚠️ 元数据提供了关于主要数据的信息。它可能包括数据来源、意义、位置、所有权和创建等信息。元数据涉及与主要数据相关的信息,但并不构成主要数据的一部分。

让我们探讨同一对话关于 A320 液压系统故障json 格式。对话本身包含以下问答:

从这个简单的对话中,OpenAI 保留了相当多的信息。让我们回顾存储的信息:

  • json 文件的主要字段包含以下信息:

字段 moderation_results 是空的,因为 在这个具体案例中没有提供反馈给 ChatGPT。此外,mapping 字段中的 [+] 符号表示有更多信息可用。

  • 实际上,mapping 字段包含关于对话本身的所有信息。由于对话有四次交互,映射为每次交互存储一个 children 条目。

再次,[+] 符号表示有更多信息可用。让我们查看不同的条目!

  • mapping_id:它包含对话的 id 以及关于创建时间和内容类型等信息。据推测,它还创建了对话的 parent_id 和对应于用户与 ChatGPT 之间下一个交互的 children_id。以下是一个示例:

  • children_idX:每次交互(无论是来自用户还是助手)都会创建一个新的 children 条目。由于对话有四次交互,因此 json 文件显示了四个 children 条目。每个 children 条目具有以下结构:

第一个 children 条目在对话中被嵌套,具有 mapping_id 作为父项,第二次交互 — ChatGP 的回答 — 作为第二个子项。

  • Children 对应于 ChatGPT 答案的条目包含额外的字段。例如,对于第二次交互:

在 ChatGPT 的回答中,我们获得关于 ChatGPT 背后的模型和停止词的信息。它还显示了第一个 children 作为其 parent 和第三个 children 作为下一个交互。

完整的文件可以在这个 GitHub gist 中找到。

模型比较

你是否曾在对 ChatGPT 提供的回答不完全满意时使用过“重新生成回答”按钮?

ChatGPT 中“重新生成回答”按钮的自制截图。

这些反馈信息也被存储!

有一个名为 model_comparisons.json 的文件,它包含对话片段及每次 ChatGPT 重新生成回答时的连续尝试。信息仅包含文本,不包括标题,但包括其他一些元数据。以下是该文件的基本结构:

{
  "id":"<id>",
  "user_id":"<user_id>",
  "input":{[+]},
  "output":{[+]},
  "metadata":{[+]},
  "create_time": "<time>"
}

metadata字段包含一些重要信息,如对话发生的国家和大陆,以及https访问协议的信息等。该文件的有趣部分在于input/output条目:

输入

input包含来自原始对话的一系列消息。交互根据作者进行标记,并且如前所述,还存储了一些额外的信息。让我们观察一下我们样本对话中存储的消息:

User/Assistant条目是预期的,但我相信在这一点上我们都在想为什么会有一个 ***system*** 标签呢?

而且,为什么他们在每次对话开始时都要提供这样的初始声明呢?

ChatGPT 是否在任何新的对话中预先提供当前日期?

是的这些条目就是所谓的系统消息

系统消息

系统消息为助手提供总体指示。它们帮助设置助手的行为。在网页界面中,系统消息对用户是透明的,这也是我们看不到它们的直接原因。

系统消息的好处在于,它允许开发者在不将请求本身作为对话的一部分的情况下调整助手的行为。可以通过 API 提供系统消息。例如,如果你正在构建一个汽车销售助手,一个可能的系统消息可以是“你是一个汽车销售助手。使用友好的语气与用户交谈,直到了解他们的需求。然后,解释符合他们偏好的可用汽车”。你甚至可以提供车辆清单、规格和价格,以便助手也能提供这些信息。

输出

输出条目包含 ChatGPT 给出的回应以及每次点击再生回应按钮时的连续尝试:

如上所述,feedback_step_1条目存储了之前提到的点赞/点踩反馈信息。

再生信息存储在feedback_step_2条目中,其中第一个子条目original_turn用于原始回应,而重试的回应则在new_turn下。

这就是 OpenAI 对我们与 ChatGPT 互动的所有信息! 我认为了解哪些信息被存储对于两个主要目的是有用的。

首先,在当今的数据世界中,关注我们的隐私并了解平台存储和推测的关于我们的信息是非常重要的。其次,了解信息的结构和处理方式可以帮助我们使用 ChatGPT 作为起点来构建定制化的模型。例如,通过查看我们自己的数据,我们意识到你可以通过系统消息来引导 ChatGPT,以透明的方式将代理定向到我们希望其执行的目标。

总结

在这篇文章中,我们回顾了 OpenAI 在过去几个月中对用户数据隐私问题的回应措施。

关闭聊天记录的可能性以及随时导出个人数据的新功能都是保护 ChatGPT 用户的重要步骤。我个人认为这些措施承诺了优先考虑数据隐私,遵守相关数据保护法规。透明性和安全性是建立信任和确保负责任的 AI 使用的关键

从我们的角度来看— 用户端 —,我认为了解管理数据隐私的可能性是很有必要的。特别是关于这两个控制基本点的新功能,比如确保你的 ChatGPT 互动不会被用于训练目的(如果你不希望这样的话),或明确获得公司对你的数据。

当然,使用这项技术还有其他风险。例如,用户还应了解数据保留政策。即知道平台保留数据的时间,这个时间理想上应为最短必要时间。了解你提供给 AI 平台的数据的预期用途以及是否平台将你的数据与第三方共享及共享目的也是我们主要关注的内容。

考虑这些因素,用户可以在使用 ChatGPT 或其他大型语言模型时做出明智的关于数据隐私的决策

主动了解你的数据如何处理并采取措施保护你的隐私权利是很重要的。

就这些!非常感谢你的阅读!

我希望这篇文章能帮助理解 ChatGPT 在我们的对话中保留的信息,以及管理新 OpenAI 功能以保护数据隐私

你也可以订阅我的 通讯 以获取最新内容。特别是如果你对 ChatGPT 相关的文章感兴趣

## 解锁 ChatGPT 的新维度:文本转语音集成

提升 ChatGPT 交互中的用户体验

从 OpenAI 提供的提示工程课程中学到的内容 — 提示指南

了解 OpenAI 的更佳提示指南

提高 ChatGPT 性能的提示工程 [## 提升 ChatGPT 性能的提示工程

如何向 ChatGPT 提问以最大化成功回答的几率

levelup.gitconnected.com [## 使用迁移学习创建您自己的 ChatGPT

通过微调提升 ChatGPT 能力

medium.com [## 请 ChatGPT 帮助我使用您的 API!

使用 ChatGPT API 提升您的 Python 脚本

betterprogramming.pub

随时向我提出任何问题forcodesake.hello@gmail.com 😃

熵度量了什么?直观解释

原文:towardsdatascience.com/what-does-entropy-measure-an-intuitive-explanation-a7f7e5d16421

Tim Lou, PhDTowards Data Science Tim Lou, PhD

·发表于 Towards Data Science ·阅读时间 11 分钟·2023 年 1 月 4 日

--

熵可能看起来很抽象,但它有一个直观的方面:即看到数据中某些模式的概率。它是如何工作的呢?

背景来源:Joe Maldonado @unsplash

在数据科学中,有许多与熵的概念相关的概念。最基本的是香农信息熵,通过公式定义在任意分布 P(x) 中:

其中求和是对所有可能的类别 C 进行的。

还有其他相关的概念,其公式类似:

尽管熵类似的公式很普遍,但关于公式背后的直觉讨论却很少:为什么涉及对数?为什么我们要将 P(x) 和 log P(x) 相乘?虽然许多文章提到“信息”、“期望惊讶”等术语,但其背后的直觉却缺失。

事实证明,正如概率一样,熵可以通过计数练习来理解,并且可以与分布的某种对数似然性联系起来。此外,这种计数还可以与计算机中的字节数字面上的数量相关联。这些解释将使我们能够揭开熵的许多事实。好奇吗?那就开始吧!

计数熵

概率的计数定义使得它变得如此直观(照片由 Ibrahim Rifath 提供,来源于 Unsplash

概率可以从操作上定义:当我们说一枚硬币有 50%的机会落到正面时,这意味着如果我们将硬币抛掷一百万次,正面的次数将接近五十万。随着试验次数的增加,这一比例会越来越接近 50%的概率。这一定义使得概率变得如此直观。

熵是否有类似的解释?有的,不过计数会稍微复杂一些:这将需要一些基础的组合数学。

有多少种方法可以排列 N 个不同的球?第一个球有 N 种选择,第二个球有 N − 1 种选择……等等。答案是 N!,或者阶乘符号:

就像在概率的定义中,我们将处理非常大的数字。因此,通过 斯特林近似 来近似这个对象是有帮助的:

其中 log 表示自然对数;如果我们使用其他基数如 log₂ 和 log₁₀,也存在类似的公式(这将决定我们测量熵的单位)。大 O 符号表明近似在 N 很大时的有效性。术语 N log N 将成为熵定义中 p log p 的来源。

我们现在准备推导熵所计数的内容。想象有大量可区分的对象或可区分的数据点。这些 N 数据点被分组为 c 个类别,如下图所示:

这种情况的总排列方式是多少?记住我们不关心任何类别中数据的排序,答案由经典的多项式系数给出:

我们用 Ω 符号来表示配置的数量。

就像概率的情况一样,我们只对大的 N 行为感兴趣。当处理如此大的数字时,取对数是有帮助的,这样我们可以使用斯特林近似来使事情更可控:

公式可以通过利用所有 nᵢ 总和等于 N 的事实来简化,

如果我们将 nᵢ/NP(i) 代入,我们就得到了熵的公式。或者,对于大的 N,我们可以写成:

所以我们达到了熵的操作定义:

熵计算了将大量数据分类成给定概率分布的方式数(以对数单位和每个数据点计算)。

这个计数练习是信息理论的核心,我们接下来会讨论它。

熵作为信息

那么,我们的熵概念如何与计算机中的字面 0 和 1 比特相关呢?

当我们将熵应用于 1 和 0 的模式时,熵的概念可以与信息相关(信用:Gerd Altmann)。

想象一个固定长度为N的二进制序列。直观上我们知道它包含N比特的信息:因为实际上需要N比特来存储序列到硬盘或内存中。

但如果序列有一些有趣的模式,例如下面的呢?

  • 000000000000000000000000000

  • 010101010101010101010101010

  • 000000010000000000000000000

在这些情况下,二进制序列表示会非常低效。我们直观地知道有更高效的存储方式:我们可以指定模式,而不是所有的字面比特,这些序列中的有效信息量应该更小。

所以,如果我们忽略数字重复的微妙模式,只看数字的基本统计属性(0 和 1 的比例),在存储这些序列时我们能做得更好吗?

这是我们的熵计数公式可以帮助我们的地方:它可以计算给定固定比例的 0 和 1 的总序列数。

在 0 和 1 的比例为 50/50 的情况下,总的可能性数量是(在大的N极限下):

我们看到这大致上产生了所有可能的二进制序列的数量 2。所以存储序列所需的比特数仍然是N。这并不令人惊讶,因为我们知道随机序列应该无法压缩:它具有最大N比特的信息。

但如果比例不再是 50/50 呢?我们应该期望有一些潜在的节省。在这种情况下,存储一个序列所需的比特总数将是:

让我们 sanity check 当 0 的数量远小于 1 的数量时的情况,比如nN。在这种情况下,可以忽略P₁项,所需的比特数为:

因此,信息量与n成正比,而不是N。这是因为我们现在只需要存储每个 0 的位置,而不是整个序列。

这说明了熵与计算机中物理比特和字节相关的力量。总之,

信息熵指定了每单位长度所需的比特数,用于存储由给定概率分布生成的序列。

换句话说,熵是一种针对序列中固定比例字符的最佳压缩比。这是熵与信息相关联的方式。

除了将序列视为我们的研究对象,我们还可以将注意力转向分布本身。这种观点使我们能够将熵解释为一种概率(或对数似然)。

熵作为对数似然

熵计算的是可能性的数量。我们想将其转换为一种概率。为此,我们只需对计数进行归一化。

N 个数据点分为 c 类别的总方法数是多少?答案很简单,因为每个数据点有 c 种选择:

我们现在可以将熵的计数除以总数以获得概率(替换 nᵢ/NP(i)):

这样,熵变成了观察到特定分布的概率(由于 N 很大,趋近于最终值):

熵可以视为观察给定分布的对数似然(每个数据点)。

然而,我们的讨论中存在一个隐含的假设,即我们在计算中将每种配置视为同样可能。如果某些类别比其他类别更受青睐会发生什么?

我们可以考虑一些参考分布 Q(x)。如果每个数据点有 Q(x) 的机会进入特定类别 x,那么观察到类别 1 中的 n₁、类别 2 中的 n₂ 等的概率由多项式概率给出:

我们可以再次使用斯特林近似。计算过程与之前类似,只是最后多了一个 Q(i)。

替换 nᵢ/NP(i),指数内的项变成了 Kullback–Leibler 散度。因此,我们的方程可以总结为

在这里,我们使用了指数内的 KL-散度的常见表示法。KL-散度是香农信息熵的推广,我们的方程使我们的解释更加精准:

P 相对于 Q 的 Kullback-Leibler 散度是观察到 P 时按照 Q 采样的负对数似然(每个数据点)。

再次说明,所有这些都是假设 N 非常大。

关于 KL-散度的一些事实现在变得明显:

  1. KL-散度始终非负:这是因为概率永远不会大于 1。

  2. KL-散度可以是无限的:这发生在两个分布没有重叠时,因此计数的结果为 0 = exp[–∞]。

  3. KL-散度为零当且仅当 P = Q:当我们按照 Q 采样数据时,我们期望结果分布类似于 Q——这种期望在 N 很大时是准确的。

凭借这种新的理解,我们现在准备重新解释数据科学中各种熵概念的事实!

熵采样器

下面我们将讨论数据科学中一些常见的类似熵的变量的直觉。我们将再次提醒读者,大* N*极限是隐含假设的。

交叉熵

这对训练分类变量很有用。定义为

请注意,我们已经将定义重写为 KL 散度和香农信息熵的和。这可能看起来有点不熟悉,因为当我们训练机器学习模型时,我们仅通过样本(比如S)计算其估计值

利用我们的计数直觉,我们得出结论

最小化交叉熵等同于最大化观察到与我们从分布 Q 中采样的数据统计相同的对数似然性,如果我们从训练中的分布 Q 中采样数据

这使得交叉熵损失与回归中的 L2 损失处于类似的概念基础上:它们都是某种对数似然函数。

互信息

互信息可以被视为两个变量之间的一种广义相关性。用I表示,它通过 KL 散度定义

在 KL 散度计算中,我们比较两个变量的分布与考虑每个变量单独分布的分布。

我们的计数直觉给出了一个很好的解释:

互信息是获得两个变量给定分布的负对数似然性(每个数据点),当我们根据其边际分布独立地采样这两个变量时

这解释了为什么互信息是一个强大的工具,可以捕捉变量之间的非线性相关性。

熵的不可避免增加?

最后,我们准备讨论关于熵的最著名事实之一:热力学定律和熵的不可避免增加。

但需要记住的是,这里存在两个熵的概念:

  1. 数据科学中的香农信息熵

  2. 热物理学中的熵

熵的增加是一个仅适用于第二种情况的物理定律。然而,物理中的熵可以被视为应用于物理系统时香农熵的一个特例,所以两者之间有联系。

这意味着在计数练习中,可能性数量将不可避免地增加。这很直观,因为当一个物理(混沌)系统不受约束时,它最终应该会采样所有可能性。这有点类似于著名的墨菲定律,它说“任何可能出错的事情都会出错”。

从数据科学的角度来看,如果我们相信我们的数据是某些动力系统的结果,那么最大化熵可能是合理的:因为如果我们相信所有变量都已被考虑,就没有理由认为我们的数据不会探索所有可能性。换句话说,我们希望考虑所有可能性/组合——即使是那些在我们数据中不存在的。这或许赋予了熵的概念在数据科学中强大的超能力。

通过计算所有可能性,熵是我们无知的保守测量

这种观点在我另一篇关于的文章中得到了探讨。

结论

通过将熵的公式解释为计算可能性,我们能够理解熵在信息理论中的作用,并将熵视为一种概率。这种解释最终使各种熵的概念变得有意义和有用。

如果你有任何想法和反馈,请分享,祝阅读愉快!👋

如果你喜欢这篇文章,你可能对我的一些其他相关文章感兴趣:

[## 熵不是混乱:物理学家的视角

熵常被视为混乱的同义词。但它到底是什么呢?在本文中,我们探索了熵如何更多地……

medium.com ## 物理学家对机器学习的看法:机器学习的热力学

自然界中的复杂系统可以通过热力学成功研究。那么,机器学习呢?

[towardsdatascience.com [## 为什么我们不生活在模拟中

将现实描述为模拟大大低估了我们世界的复杂性。以下是为什么模拟……

medium.com

“最佳实践”到底是什么意思?

原文:towardsdatascience.com/what-does-following-best-practices-mean-anyway-41a255debc1b?source=collection_archive---------13-----------------------#2023-04-13

TDS EditorsTowards Data Science TDS Editors

·

关注 发表在 Towards Data Science · 作为 新闻通讯 发送 · 阅读时间 3 分钟 · 2023 年 4 月 13 日

--

当新工具、研究和流行词汇像近年来一样迅速涌现时,“最先进的技术”和“最佳实践”等术语可能显得毫无意义。上个月的前沿模型可能已经显得过时;对你上一个项目非常适用的工作流程,可能在你启动下一个项目时就变得过时。

当然:对更新、更好、更闪亮事物的不断追求可以带来兴奋感。它也容易引发焦虑和对落后的恐惧——这些都是我们不建议加入到数据科学学习中的成分。相反,我们喜欢提醒自己(以及任何愿意倾听的人),渐进的、累积的改进对于可持续的职业成长已绰绰有余。

本周我们为你挑选的文章体现了同样的精神——它们专注于优化你日常任务中的具体领域并培养稳健的习惯。祝你阅读愉快!

  • 如何为你的数据团队成功铺路。鉴于数据科学工作的迭代(有时重复)性质,Rebecca Vickery正确地提醒我们:“无论你是一个独自工作的数据科学家,还是一个共同合作的大团队,制定一套最佳实践都是非常重要的。”她提出了六个建议,帮助你制定适合你需求的最佳实践。

  • 为什么满足于平庸的图表呢?无论好坏,人们都无法读懂你的心思——这意味着即使是最好的数据分析,如果呈现方式难以解读,也不会产生太大影响。Aruna Pisharody提供了一个详细的、实践性的指南,教你如何使用 LaTeX 制作适合出版的图表。

  • 更有效的实验就在眼前Eryk Lewinson的最新贡献探讨了如何使用 DVC 的 Visual Studio Code 扩展,将你的 IDE 转变为一个机器学习实验平台。在这里,Eryk 演示了如何通过交互式图表监控模型性能和评估实验。

图片来源:Emma WaleijUnsplash

  • 享受简化代码的好处Susan Maina表示:“公司和雇主更倾向于优化过的代码,这样可以更容易地扩展,并使新开发者迅速上手。”但是,怎么判断你的代码是否经过优化呢?Susan 的教程带我们了解 Python 的魔法命令以及如何使用它们测试代码的效率。

  • 关于持续集成及其实施方法。如果你想了解 CI 的清晰而易懂的入门知识,以及它如何在你的机器学习管道中防止失败和痛点,请查看Khuyen Tran详细的逐步教程,其中包含了你需要的所有代码。

  • 应用邻近学科的强大经验。优先级排序是数据专业人员面临的长期挑战,他们常常需要平衡开发人员、市场营销人员、业务分析师等的竞争需求。Brian Roepke 借鉴成功产品经理的智慧,分享了可以帮助数据科学家在决策过程中获得的见解。

我们之前提到的学习大餐还在炖煮吗?我们希望如此——还有一些精彩的阅读内容不容错过:

  • 我们最新的月刊版提出了一个时代最关键的问题之一:人工智能能否被治理?

  • 如果你对增强扩散模型输出的方式感兴趣,Andrew Zhu 解释了如何克服令牌大小限制并实施自定义模型加载,以及其他技术。

  • Yennie Jun 的一篇引人入胜的新文章详细探讨了大型语言模型中的创作过程演变,追踪了它们从 GPT-2 到 GPT-4 的进展。

  • 谷歌的 Bard 和 OpenAI 的 GPT-4 对比分析。Cassie Kozyrkov “拆解”了这两个模型,并比较了它们在一些精心挑选任务中的表现。

  • 在 GPT 模型的持续探讨中,Mark Chen 提出了关于生成型 AI 使用和测试的综合研究第一部分,专注于文本总结以基准测试 GPT-3.5 的能力。

  • 数据工程师如何将“从批处理思维转变为流处理思维”?斯科特·海恩斯的深入探讨将帮助你建立正确的思维模型(并装备你所需的知识)以完成这一转换。

感谢你本周花时间与我们相伴!如果你喜欢在 TDS 上阅读的文章,可以考虑成为 Medium 会员。现在对学生来说特别适合加入,因为你们中的许多人现在可以享受会员的实质折扣

直到下一个变量,

TDS 编辑部

当机器学习出现错误时,这意味着什么?

原文:towardsdatascience.com/what-does-it-mean-when-machine-learning-makes-a-mistake-37b213200697?source=collection_archive---------2-----------------------#2023-09-17

我们对“错误”的定义在机器学习/人工智能领域是否合理?如果不合理,为什么?

Stephanie KirmerTowards Data Science Stephanie Kirmer

·

关注 发表在 Towards Data Science · 11 分钟阅读 · 2023 年 9 月 17 日

--

图片来源:Kind and CuriousUnsplash

我最近关于机器学习公众认知的帖子中有一个评论让我思考机器学习中“错误”的含义。读者问我是否认为机器学习模型会一直“犯错误”。正如我在那篇帖子中所描述的,人们有很强的倾向将机器学习模型拟人化。当我们与 LLM 聊天机器人互动时,我们会运用从与其他人交流中学到的技巧——说服、措辞、论证等。然而,这通常效果不好,最终会导致不满意的回应。

在我自己日常的工作中,我也会看到与分类器和回归模型相关的类似问题。我和我的团队花费了大量的时间和精力来帮助客户和同事理解机器学习并不完美(而且现实中也永远不会完美)。“为什么模型说 X,而事实是 X-5?”是一个永恒的主题。我不完全责怪提问者,因为正如我在上一篇文章中所写,我们广泛的机器学习社区在教授基础机器学习素养方面做得不够好。

但这提出了一个核心问题,我们需要更多的探讨才能真正解决这个素养问题。

当我们说一个模型犯了错误、失败了、产生了幻觉或说谎时,这是什么意思(以及其他人是什么意思)?

在我们能回答这个问题之前,我们需要从头开始。

什么是机器学习模型?

从一个非常、非常通用的角度来看,机器学习模型是一个接受一些输入或提示并返回某种概率确定的响应的算法。它决定响应应该是什么的方式可能会有很大差异——它可能使用决策树、神经网络、线性回归或其他任何类型的机器学习方法。

要创建一个模型,我们从反映我们寻找结果的样本数据开始。输入样本可以是各种各样的东西——对于生成式 AI,它们可能是大量的人类书写的文本、音乐或图像。对于其他类型的机器学习,它们可能是包含对象特征的大型数据集,或者将图像或文本等分类到类别中的数据集,或更多。

有时候,这些回应会被“标记”以便模型学习哪些是可取的,哪些不是,或者哪些属于特定类别,哪些不属于。其他时候,模型会学习底层样本中的模式,并形成自己对这些模式的理解,以复制输入的特征、在选项之间做出选择、将输入分组或进行其他活动。

生成式 AI 模型的训练方式

我们训练生成模型的方式是特定的,比训练一个简单的概率模型要复杂得多。相反,这些模型是估计许多不同元素的概率,并将它们组合在一起以生成响应。以下是我们进行这种训练的一些非常简单的解释。(这些都是极度的过度简化,请原谅细节的缺乏和任何概括。)

当我们生成声音或图像时,可能会使用生成对抗网络。在这种情况下,模型相互对抗,一个模型生成新内容,另一个模型尝试判断该内容是否来自某个模型,来回交替。这两个模型在成千上万的案例中竞争,每个模型在过程中逐渐变得更好。最终,生成模型将能够产生几乎无法与现实所产生的内容区分开来的内容。(作为副作用,区分模型也会变得非常擅长识别输入是否是人类生成的。)

对于大型语言模型(LLMs)和像 GPT 模型这样的文本生成,我们使用所谓的 Transformer。这种训练包括教模型理解单词的意义如何相互关联,以及如何生成接近于人类生产的文本内容。结果听起来非常有说服力,因为模型知道哪些单词可能会一起出现(基于训练中真实人类语言如何将它们组合在一起的概率)。

为了从文本输入生成图像,例如 Dall-E,我们使用扩散。在这种情况下,我们教模型计算图像中最可能需要的特征,基于所提供的文本。模型本质上从一个静态图像开始,根据你的文本应用细节/颜色/特征。这是基于模型关于文本通常如何与图像对应的学习结果。

使用这些技术,我们教会模型解读输入中的模式——有时是我们自己甚至无法真正解释或检测的模式(尤其对于深度学习来说),然后模型能够解释和应用这些模式。所有这些在表面下都是数学,即使模式可能存在于文本、图像或许多其他事物中。

现在我们知道了这些内容,我们可以讨论输出是什么,以及当输出不是我们想要的结果时意味着什么。

输出

机器学习模型生成的东西可以有很大的不同。特别是生成型人工智能生成的图像、视频、音频和各种文本无所不包。其他类型的模型则给出事件/现象的可能性、未知值的估计、文本翻译成不同语言、内容的标签或分组等等。

在所有这些情况下,复杂的数学计算被用来根据给定输入估算最佳响应。然而,“最佳”是一个非常具体的概念。在创建模型的过程中,你已经向模型指明了你希望其响应具备什么特性。

在创建模型的过程中,你已经向模型指明了你希望其响应具备什么特性。

当我们得到意料之外的结果时,这意味着什么?

这与我们本身一样重要,也与模型一样重要。 这基本上就像任何技术领域的产品一样。产品设计师和创作者在开发要出售给用户的产品时,会制定“用户故事”,这些故事包括谁将使用该产品、如何使用以及为什么使用,以及他们希望从中获得什么。

例如,假设我们正在设计一个电子表格工具。我们会使用用户故事来考虑安妮这位会计师,并与会计师交谈,以确定会计师在电子表格软件中需要什么样的功能。然后我们会考虑商业分析师鲍勃,并与商业智能分析师讨论他们的功能需求。我们会将所有这些列入电子表格工具的规划清单,并以此来指导我们的设计。你明白了吧。

谁是机器学习模型的用户? 这完全取决于模型的类型。例如,如果你的模型预测基于房产特征的房价,可能的用户是房地产经纪人、抵押贷款机构或购房者。具有明确、有限应用范围的模型容易为用户量身定制。我们数据科学家可以确保这个模型满足使用者的期望。

有时预测结果可能不准确,但这是一个数学问题,我们可能能够解码为什么会这样。也许我们给模型提供了错误的数据,或者这个房子有某种我们无法告诉模型的特殊原因。例如,如果模型从未被教会如何解释后院动物园对房价的影响,它将无法整合这些信息。如果出现了房价崩溃?我们不久前看到过这样的情况,你可以想象模型从崩溃前学到的模式将不再适用。

然而,在这种情况下,我们有两个问题:

  1. 模型旨在实现的明确目标,数据科学家和用户都知道;

  2. 一种可量化的方法来衡量模型是否接近其目标。

这意味着当我们想要定义模型是否成功时,这一过程是明确和简单的。在做出这个判断之后,我们可以探讨模型为何会有这样的表现——这就是在该领域中所说的“模型可解释性”或“模型解释性”。

但对于 LLMs(大语言模型)呢?

这个整体框架对像 LLM 这样的东西意味着什么?谁是 ChatGPT 的用户?(你刚刚在脑海里回答“每个人”了吗?)当模型的输出可以像 LLM 那样复杂和多样时,我们开始产生疑问。

对于那些构建生成性 AI 模型的数据科学家来说,虽然他们可能采用不同的训练方法,但我们通常始终尝试创造尽可能接近训练数据的内容,这些数据通常是由人类或自然生成的。为了实现这一目标,模型是通过人类或自然产生的样本内容进行训练的。我们尽力给模型一个数学方式来理解这些内容为何感觉“真实”,以便它可以复制这一点。这就是生成性 AI 模型能够创造效率并使某些人类工作变得过时的方式。

对于那些构建生成性 AI 模型的数据科学家来说,目标是创造尽可能接近训练数据的内容,这些数据通常是由人类或自然生成的。

这些模型在这方面做得非常出色!然而,这也带来了一些陷阱。由于 LLM 模型在模仿人类回应方面非常逼真,用户在思维上容易把它们当作人来看待。这就像孩子学习动物的方式——你教孩子说一只有四条腿和湿鼻子的毛茸茸的动物是狗,但当你把一只猫放在他们面前时,他们会倾向于认为那也是狗,因为基本特征似乎非常相似。只有当你解释猫是另一种动物时,他们才开始理解差异并建立不同的心理模型。

由于这些模型在模仿人类回应方面非常逼真,用户在思维上容易把它们当作人来看待。

目前,我认为大多数公众仍在建立不同的心理模型,以区分 LLM 和人类。(正如我之前所写,数据科学家需要像大人一样解释狗和猫的不同,以继续这个比喻。)

不过我稍微跑题了。这真正意味着与一个非常基础的模型(例如房价)互动的人理解这是一个有限的算法。它更像一个电子表格公式,而不像一个人,这塑造了我们的期望。但当我们使用 ChatGPT 时,它带有许多人类在线聊天的特征,这影响了我们。我们开始期望陈述总是准确的,结果包括连贯的批判性思维,并且期望从模型中检索到今天新闻的事实,即使它是去年训练的。

[P]与一个非常基础的模型互动的人理解这是一个有限的算法。……但当我们使用 ChatGPT 时,它带有许多人类在线聊天的特征,这影响了我们。

在模型结果中出现批判性思维的迹象,是因为模型学会了我们从真实人类来源中解释为“批判性思维”的文本排列听起来更“人类”,因此它模仿这些排列以达到这一目的。当我们与人交谈时,我们会从他们说的话中推断出他们正在进行批判性思维。然而,我们不能用机器学习来做到这一点。

记住我上面描述的房价模型的两个关键要素:

1. 模型旨在实现的明确目标,数据科学家和用户都应当了解;

2. 一种量化衡量模型是否接近其目标的方式。

对于生成式 AI,包括但不限于大语言模型,我们在第 1 点上存在问题,部分原因是目标实际上并不清晰(“返回与人类产生的内容无法区分的材料”),但主要原因是数据科学家确实没有成功地向用户传达这个目标。数据科学家在这些模型上达到了第 2 点,因为他们使用复杂的数学系统来教模型何时生成足够“真实”或类似人类的内容。然而,对于普通用户来说,这要困难得多。判断模型是否做得好的过程更像是评分论文,而不是检查数学问题的结果。主观性悄然渗入。

即使测量更为简单,我仍然坚决认为,即使是一些技术娴熟且受过高等教育的用户,也未必真正清楚这些模型已经训练成什么样,因此也无法知道什么是现实的期望,什么不是。因此,对于模型而言完全合适的结果,比如一个流畅、雄辩、完美“人类风格”的段落描述月亮是由绿色奶酪制成的,也会被视为“错误”。然而这并不是错误——这个输出达到了它的训练目标——这也是我们许多困惑的根源。

调整期望

这表明我们需要调整对这些模型的期望,我希望这篇文章能有所帮助。要成功使用机器学习模型,并区分错误和预期行为,你需要了解模型被训练来执行的任务以及训练数据的性质。如果你能更深入一点,你还需要清楚数据科学家如何衡量成功,因为这会极大地影响模型的行为。

通过融合这些元素,你将拥有理解模型结果含义所需的背景信息,并能够准确解读它们——你的期望将会是合理的,你也会知道这些期望是否得到了满足。而且,当涉及到机器学习时,你会真正理解“错误”意味着什么。

目前有一些有用的材料澄清了许多关于流行生成式机器学习模型的内容(如它们是如何训练的,回应的真正含义等),我在下面添加了一些链接。(我并不 endorsing 这些材料中的所有观点,只是提供给那些想了解生成式 AI 的人作为参考。)

[## AI 模型注定总是要产生幻觉吗? | TechCrunch

像 ChatGPT 这样的语言模型有一个不好的习惯,就是捏造事实。但这能在技术层面上解决吗?

techcrunch.com](https://techcrunch.com/2023/09/04/are-language-models-doomed-to-always-hallucinate/?source=post_page-----37b213200697--------------------------------) [## Google Cloud Skills Boost

Qwiklabs 提供真实的 Google Cloud 环境,帮助开发者和 IT 专业人员学习云平台以及其他相关内容……

www.cloudskillsboost.google](https://www.cloudskillsboost.google/journeys/118?source=post_page-----37b213200697--------------------------------)

Garon, Jon M., 《生成式 AI、合成媒体及最新媒体中的信息实用入门》 (2023 年 3 月 14 日)。可在 SSRN 上获取:ssrn.com/abstract=4388437dx.doi.org/10.2139/ssrn.4388437

查看更多我的工作请访问 www.stephaniekirmer.com.

注意:我通常说“机器学习”而不是 AI,但在“生成式 AI”这种情况下,我选择使用这个短语,因为它在这个领域中得到了广泛的应用。

算法“学习”到底意味着什么?

原文:towardsdatascience.com/what-does-it-really-mean-for-an-algorithm-to-learn-1f3e5e8d7884

两种一般观点和一些心理学

Andre YeTowards Data Science Andre Ye

·发表于 Towards Data Science ·阅读时间 20 分钟·2023 年 4 月 22 日

--

当人们第一次接触机器学习时,通常会快速浏览一个又一个算法、一个又一个技术、一个又一个方程。但之后,才有可能反思他们所掌握的知识中的一般趋势。

“学习”意味着什么是一个非常抽象的概念。本文的目标是提供机器学习中“学习”的两种一般解释。这两种解释,正如我们将看到的,是同一枚硬币的两面,并且在机器学习中普遍存在。

即使你在机器学习方面经验丰富,暂时脱离具体的机制,考虑学习的抽象概念,可能仍会有所收获。

在机器学习中,学习有两个主要的解释,我们称之为损失导向参数更新流形映射。正如我们将看到的,它们与心理学和心灵哲学有实质性的联系。

损失导向参数更新

一些之前讨论的机器学习算法采用了白板方法:它们从一个“空白”随机猜测开始,并迭代改进其猜测。这个范式对我们来说似乎很直观:当我们尝试掌握一项新技能,比如学习骑自行车或简化代数表达式时,我们犯了许多错误,并通过“实践”变得更好。然而,从算法的角度来看,我们需要明确识别两个实体的存在:状态损失

算法的状态由其一组参数的值定义。在这个上下文中,参数是决定算法行为的非静态值。例如,考虑优化你的保龄球游戏。有几个参数:保龄球的重量、你在指孔中的手指配置、准备投球时的速度、你手臂的速度、你投球的角度、释放时的旋转等等。每次你投球时,你都定义了一个新的状态,因为你作为一个优化算法正在尝试新的参数(除非你投球的方式完全相同,否则你是在返回到之前的状态,但在保龄球和机器学习中这种情况都很少见)。

线性回归和逻辑回归中的每一个系数都是一个参数。基于树的模型没有固定数量的参数,因为它们的深度是自适应的。相反,它们可以根据需要创建更多或更少的条件来优化信息增益标准,但这些都是参数。

然而,基于树的模型——以及所有算法——都受到超参数的影响。这些是参数自身必须遵循的系统级约束。决策树的最大深度和随机森林集成中的树的数量都是超参数的例子。在我们的保龄球示例中,元参数可能包括建筑物的湿度、你所穿的保龄球鞋的质量以及保龄球道的拥挤程度。作为一种优化算法,你存在于这些条件之中,必须优化你的内部参数(你选择哪个保龄球,你如何投球等),即使你不能改变基本条件。

损失,另一方面,是任何给定状态的‘坏 ness’或错误。损失必须制定如何从模型的行为中得出坏 ness。例如,假设我采取了某种状态——我选择了一个直径为 6.3 英寸的保龄球,以每小时 18 英里的速度、相对于球道边缘 9 度的角度释放球,距离球道四英尺远,等等——并击倒了 6 个球瓶。我的状态的行为是我击倒了 6 个球瓶。为了量化状态的坏 ness,我们计算我没有击倒的球瓶数量——4 个球瓶,给定这些确切的状态参数释放的保龄球。为了最小化我的坏 ness,我会在下一次投球时调整我的参数。

从算法的角度来说,状态通常是一组系数或标准,它们将输入转化为预测,而损失是模型预测与期望输出之间差异的数学量化。假设一个模型有n个参数,用{x_1, x_2, ..., x_n}表示。这些参数可能是线性回归模型的系数,k-均值模型中簇的中心,或是决策树模型中的分裂标准。我们可以推导出该模型在某些数据集上的误差——例如,均方误差。如果模型迭代地调整其参数集以改善损失,那么我们说它在学习

尽管我们可以大致称整个过程为学习,实际的学习算法发生在从损失到参数更新的转换过程中。当前状态的评估(即从参数到损失的转换或推导)可能被视为‘感知’或一种‘智能’过程。

一个心理学和进化学上受到启发的假设认为,我们作为人类不断地进行一种优化游戏,这种游戏在概念上类似于通过损失导向的参数更新范式进行学习的模型:我们不断观察状态的‘糟糕’程度,并通过调整状态来改进糟糕程度。然而,我们对糟糕程度的衡量比均方误差计算更复杂:我们同时处理各种信号,内部和外部,直观和计算的,并尝试将这些信号与我们当前可变特征集联系起来。例如,当你在保龄球时,你可能并不是直接尝试优化击倒的瓶数,即使你试图这样做。相反,你可能在尝试减少社交焦虑或最大化你约会对象或朋友的印象,这不一定会导致与最大化击倒瓶数相同的最优状态配置。

牢记这一点——我们可以将自己的行为视为对状态糟糕程度评估的响应中可变状态的不断更新——可以帮助我们更好地理解损失驱动的参数更新行为的问题和现象。例如,人们并不总是在改变他们的状态,即使他们不断地评估自己的状态。这展示了收敛——这些人已经达到了一个状态集,在这个状态集中,没有任何可行的状态变化会减少糟糕程度。

另外,一些人由于上瘾(对物质、赌博、社交媒体滚动等)或因严重的偏执(担心陷入经济困境、失去珍贵物品、失去尊重、大量人群等)而不幸陷入了重复的破坏性行为。在学习的技术语言中,我们将这些称为局部最小值。这些是代理人到达并“选择”不离开的汇聚点,要么是因为留在那里比立即采取任何步骤离开更容易(例如,摆脱上瘾),要么是因为,等效地,立即离开比留下来更糟(即担心因某些变化而损害或恶化自己的状态)。

算法通常表现出类似的行为,尽管当然在更少人性化的方式中。我们经常通过损失景观的概念,以几何和定量的方式来构思损失与状态之间的关系。在损失景观中,每个参数都有一个轴,额外还有一个损失轴。损失景观使我们能够将每组参数值映射到相应的损失值。

为了说明这个关键概念,假设你正在尝试学习测试的最佳学习策略。我们只考虑学习一个参数——你为测试学习的小时数。假设你之前参加过四次测试,那么——为了说明问题,假设这些测试在环境上是可比的——你有四个数据点可以学习。对于这四次测试中的每一次,你学习了不同的小时数,相应地获得了不同的表现:完全不学习时为 60%,学习 1.5 小时时大约为 75%,学习 4 小时时大约为 70%,学习 6 小时时大约为 60%。我们将这些数据绘制如下,显示损失——通常在损失较小时更为理想,因此在这种情况下将是错误率(表现的倒数)——如何随着优化参数的变化而变化。

利用这些信息,我们想要找到最佳的学习小时数,以获得最小的错误率。从我们收集到的信息来看,最佳的参数值似乎在两小时左右。但我们如何确定?我们如何考虑接近的答案或远离的答案?我们如何描述查看数据和寻找最小损失的过程?

损失景观是一个概念工具,帮助我们以物理的、定量的方式思考学习。我们设想可以获取每个参数值及其对应错误率之间的确切关系。这使我们能够在参数-损失空间中绘制出一条曲线或“景观”。我们可以理解每一个已知点是从景观中“采样”得到的。应该重复强调的是,在实际操作中,我们无法获取这个景观。它只是一个理论模型,用于辅助推理和理解。

现在,想象你正在观察一个二维世界的山丘。假设你是一个小旅行者,站在这个山丘的表面,寻找最低的海拔位置。你可以随意移动——你可以使用传送器随机跳跃到处,或者慢慢走,也可以大步跳跃。当你探索这个山丘时,你可能会发现没有新的地方比你之前访问的最低点还低。在一些无果的探索之后,你可能决定就此停留在之前访问过的最低位置。这就表明了收敛。

算法可以通过它们如何利用和导航损失景观来区分。你可以将每个算法视为具有自己个性的旅行者。一种简单的学习算法是随机多次改变参数,然后恢复到表现最好的参数——随机搜索。这是一种表现不稳定的旅行者,可能喝醉了,随机跳跃在损失景观中。

另一种保守的学习算法是以某种粒度搜索每组参数值。这是一个非常勤奋但效率低下的旅行者,慢慢走过损失景观的每一“寸”,做笔记并进行细致的测量。

一个更聪明的旅行者可能会尝试设计某个决策带来的收益的度量,或者通过分析当前站立的地面的坡度来确定哪个方向能够最快下降。

损失景观还让我们考虑像局部最小值这样的现象,其中学习算法会收敛到一个相对于“附近”解来说似乎是最好的解决方案,但实际上却比其他一些“全局”最小值更差。在我们之前优化学习时间的例子中,我们会将两小时学习识别为局部最小值。这将产生比学习半小时或四小时更好的考试错误率。然而,真正的全局最小值是学习 10 小时,这样可以获得完美的考试错误率零。可以将局部最小值视为视野的问题:旅行者在崎岖的地形中行走,只能看到前方的山脉,而看不到可能位于更远处的深谷,并决定眼前的浅谷足够了。

考虑一个务实的例子。我们有一个非常简单的模型,只有一个参数m,它控制着直线y = mx,我们希望找到一个最适合数据集的m值(即最小化直线与点之间的平均差异)。

损失景观在坡度值从 0 到 4 时看起来如下。

让我们考虑在这个损失景观上旅行的过程以及它对微调模型的影响。我们将从这个景观的高处开始,坡度值为 0.1316。这显然不适合我们的数据集,相应地我们处于损失景观的‘非常高地’。

让我们“学习”一下。假设我们向‘右’看一点,相应地找到较低的地面。

受到第一次成功阶段的鼓舞,我们将再次沿相同的方向迈进两步,使用坡度为 2.1053 的模型达到了最小错误。

假设我们再进一步,结果却是爬升而不是下降我们的损失景观,导致模型更差。这就是我们的学习陷入错误的地方;我们可能要么继续探索(也许能找到更好的解决方案),要么回到之前的最佳解决方案。这就是学习过程中的错误和修正。

然而,实际情况是,机器学习模型的参数比一个参数多得多。即使是线性回归模型——最简单的模型之一——也大约有和数据集中变量数量一样多的参数。

我们可以将这个想法推广到更高维空间,尽管有点不直观。例如,考虑一个有两个参数的模型。损失景观将具有三个维度,展示了两个参数值的每种组合如何映射到特定的损失。现在我们有一个三维的‘景观’,可以想象在其中进行导航。

大多数现代机器学习模型有数十个、数百个,甚至在深度学习的情况下有数十亿个参数。我们可以概念性地理解它们的学习过程——即“机器学习”或“深度学习”中的‘学习’——作为在对应的几十维、几百维甚至几亿维的损失景观中进行导航,搜索‘最低地面的位置’,即最小化损失的参数值组合。

流形映射

指向损失的参数更新是理解学习的直观方式:我们根据反馈信号更新内部参数,这些反馈信号可以是内部或外部的(例如,通过环境)。损失景观的概念使我们能够将学习的抽象问题转化为更物理的空间,并提供了对学习过程中观察到现象的具体解释,比如收敛到较差状态(局部最小值)。

指向损失的参数更新是一种 以模型为中心的学习解释:损失景观空间由模型的组件(参数值轴)和这些组件的总体性能(损失轴)物理定义。另一方面,流形映射解释是 以数据为中心的。与其将学习定义为模型作为一个代理,不如将学习视为在数据中发生的过程。(当然,正如你将看到的,这两者是同一个硬币的两个方面)。

假设你是 Hal 9001 的看护者,Hal 9001 对于在 2001: 太空漫游 中被忽视而未能获得角色仍然心怀怨恨。作为 Hal 9001 的看护者,你的一个责任是预测 Hal 是否会对今天的温度感到满意。你有一些关于之前温度和 Hal 9001 相应满意度的数据。今天的温度是 64 华氏度。你能预测 Hal 9001 是否会满意吗?

从数据中可以看出,Hal 9001 很可能会(幸运地)感到满意。你是如何得出这个结论的?你隐含地 构建了一个 流形特征空间 中。由于我们的数据只有一个特征,即温度(Hal 9001 的满意度是 目标,而不是特征),特征空间只有一个维度。这相当于一个数字线:

说得更宽泛一点,我们可以绘制一个 流形 来沿某一点分隔数据。在这种情况下,我们可以通过绘制以下流形来完美地分隔数据:

我们也可以将流形称为 决策边界,以便于理解。流形是分隔空间的边界,使我们能够决定将哪个类别与特征空间中的哪个点关联起来。

这里的关键见解是,流形不仅仅与它在特征空间中所占的那一小片空间相关:相反,它影响整个特征空间。它定义了哪些区域属于哪些类别。此外,它定义了你如何对未见过的点进行推断。如果我们在这个特征空间中标记出“64”这个点,我们会发现它属于满意度类别“是”。

让我们考虑二维空间中的另一个例子。图 2-x 展示了一个二维特征空间(这代表了一个具有两个特征/列的数据集),点的颜色根据它们的类别进行着色。

我们可以绘制如下流形来分隔数据。它完美地适应了数据集;也就是说,它完美地将数据分成了各自的类别。

然而,我们也可以绘制许多其他有效的流形。这些流形也完美地分隔数据。

尽管这些流形在训练集表现上都是相同的,因为它们在特征空间中以等效的完美表现分隔不同类别的项目,但它们在如何影响整个特征空间方面却有显著不同。坐标(1,7)处的点在顶部映射中的分类将与底部映射中的不同,因为流形的方向不同。

同样地,回到我们的一个维度示例,我们也可以用不同的方式绘制边界,这些方式在分隔已知数据时同样有效。

这也影响了我们对新数据的决策。假设气温为 55 度;顶部流形预测 Hal 9001 会满意,但底部流形预测 Hal 9001 不会满意。

这种随意性是需要考虑的重要问题。它表明对于系统可以学习的任何问题,有许多不同的同样好的解决方案。然而,通常情况下,我们希望模型学习一个‘真实流形’。这就是我们想象的‘真实流形’,它不仅完美(或至少最优地)分隔已知数据点,还分隔我们将来可能收集到的所有点。这个概念与我们从中收集数据的现象密不可分。

因此,学习的过程就是在特征空间中泛化差异;以一种有意义的方式绘制流形以分隔不同的数据点。在这个过程中,我们学习数据集中的一般规则。

关键是,流形映射的学习解释帮助我们强调学习如何‘影响’数据集。即使模型仅在有限数量的点上进行训练,我们确实理解它与特征空间中的每个点相关。因此,流形映射解释使我们能够理解模型如何泛化——它们如何学习我们希望它们学习的规则(‘真实流形’),而不是学习特征空间中那些便宜地分隔数据的捷径,这些捷径并不能准确反映真实的基本现象。

让我们考虑一个三维流形映射的例子:

在三维空间中,分隔这些点的流形是一个‘表面’,在更熟悉的意义上;它像一条覆盖空间的毯子,特征之间的真实有意义的关系(理想情况下)在其在特征空间中的轨迹中的每个弧线和曲线中体现出来。

现在,考虑一个将 100×100 像素的图像——这是一张相当低质量的图像——分类为狗或猫的模型。假设这张图像是灰度的,那么这张图像中有 10,000 个唯一的像素。每一个像素都是这个特征空间中的一个维度。这种猫/狗分类器的目标是发现 10,000 维空间中的流形,这个流形在这个庞大的理论空间中弯曲和曲折,捕捉区分狗和猫图像的相关视觉关系,呈现在这个表面的拓扑形状中。

这是一个复杂的想法。它比基于损失导向的参数更新解释更不直观,但却是一个值得深入思考的重要概念。

心理学和哲学的贡献

损失导向的参数更新解释将学习描述为对损失或反馈信号的内部状态集的迭代更新,反馈信号描述了当前状态的糟糕程度。流形映射解释将学习描述为在特征空间中形成一个流形(决策边界、表面),它最佳地分隔不同的数据点,同时也显然在整个空间中进行‘预测’(泛化)。

这些似乎是合理的,甚至是自然的解释学习过程的方式。然而,即便这些是主要的数学、技术和抽象的‘学习’概念描述,也重要的是认识到这种描述仍然肯定或符合某种哲学视角或世界观。

关于‘学习’是什么,‘学习’意味着什么,有许多不同的哲学立场和理论。一个常见的误解是将数学和科学等领域表面上的内部一致性(实际上,经过更仔细的调查,发现并不是如此一致)与‘客观性’和‘真理’的隐含标签联系在一起。正如我们在后续章节中进一步探讨的那样,这种误解常常导致对像 AI 这样的计算或数学系统的信任错位或过度信任。

我们从一开始就开始识别 AI 的各种隐含哲学假设,通过简要了解‘学习’在哲学上是如何被处理的,以及损失导向的参数更新和流形映射解释符合哪些路径。

联想主义是一个有着悠久发展历史的学习理论,从十八世纪的洛克和休谟到现代与人工智能相关的意义。它建议生物体通过经历呈现给它们的世界,基于因果推理的历史学习:如果它们经常遇到某种现象与另一种现象之间有某种联系,它们就开始联想这些现象。

例如,每当艾萨克把一个苹果抛向空中,它就会落下来。从联想主义的角度看,艾萨克形成了一条学习知识:每次苹果被抛向空中时,它都会落下来。艾萨克可能会把一个橙子抛向空中几次,发现每次橙子也会落下来。在尝试了几个其他物体后,艾萨克会学会概括这种联想:物体在空中被抛下后落下的特性不是苹果固有的,而是一般物体的特性。

联想主义者认为,只有一个核心的心理过程:通过经验联想思想。伊万·帕夫洛夫在心理学领域的工作或许是最著名的联想学习证据。帕夫洛夫的狗在遇到肉的气味时自动分泌唾液,这是由于嗅到肉(在吃之前)和分泌唾液之间历史上建立的联想。

在更流行的文化中,吉姆在《办公室》里利用联想学习过程来对付德怀特。每当吉姆重新启动他的电脑——播放标志性的 Windows “解锁工作站”声音——吉姆就会给德怀特一颗薄荷糖。德怀特每次都会接受,以至于当他听到声音时会本能地伸出手。一天,吉姆重新启动电脑,德怀特伸出手,期待常规的薄荷糖。吉姆问德怀特在做什么,德怀特回答“我不知道”——然后皱起眉头,发出唾液声,并问为什么他的嘴巴突然味道如此难闻。

在帕夫洛夫之后,爱德华·桑代克于 1911 年提出了“效果法则”。这一理论表明,与满足感相关的行为将导致该行为的重复。效果法则超越了帕夫洛夫的被动联想学习,迈向了主动学习:生物体主动参与(或抑制)行为,以最大化满足感或奖励。这是训练狗良好行为的逻辑,例如:狗在表现出期望的行为时获得奖励(而对不良行为给予惩罚,惩罚可以被视为奖励的否定)。

损失导向的参数更新范式直接与这种联想学习理论相一致。通过强化哪些行为(即状态,参数的集合)是“好的”(低损失)和“坏的”(高损失),模型旨在向更好的行为靠拢,远离更差的行为。

心理学习理论中的两个额外概念是区分统一。在区分中,受试者感知到以前被认为是单一属性的属性之间的差异;在统一中,受试者感知到一个以前被认为是多个属性的属性。这种分离与统一的双重系统有助于理解信息——能够发现区分表面上看似一致的现象的有意义的细微差别,并能够将表面上看起来不同但在某种程度上有意义的概念归为一类。

流形映射的学习解释与区分统一的双重概念在数学上直接对应。流形的目标最明显的是分离空间,但也包括确定不分离哪些空间——也就是统一。

鉴于流形映射和损失导向的参数更新是同一枚硬币的两面——模型的参数决定了流形的绘制方式,而流形的形状则是为了通过最优的分离来最小化损失——我们也可以看到关联学习理论与区分-统一感知学习理论的联系。这是应用如何可以启发理论的一个例子。早期和现代人工智能发展的实质性工作也同样将技术 AI 进展应用于指导哲学、心理学和神经科学中的新研究探讨。

总之……

我们可以把学习看作是损失导向的参数更新——一个试图调整各种自由变量以最小化误差的代理——也可以看作是流形映射——发现适用于观察空间的普遍规则,从而分离一些样本,同时将其他样本统一。如我们所见,这两种解释是同一枚硬币的两面:一种是以模型为中心的,另一种是以数据为中心的。虽然这两者在机器学习中常常使用,但我们也可以在其他领域,如行为科学中找到它们的应用。

感谢阅读!

所有图片均由作者创作。

数据科学家究竟做什么?

原文:towardsdatascience.com/what-exactly-does-a-data-scientist-do-42c53db57df5

我在 3 个不同数据科学团队工作的诚实反思(提示:PowerPoint 的使用比你想象的要多)

Matt ChapmanTowards Data Science Matt Chapman

·发表于 Towards Data Science ·阅读时间 7 分钟·2023 年 6 月 22 日

--

图片由 Hermansyah 提供,来源于 Unsplash

数据科学家被称为 许多 事物

  • “数据科学家是一个住在旧金山的统计学家”

  • “专业模型师,但不是那种”

  • “我拿钱去谷歌搜索 Stack Overflow”

  • “我向高管出售魔法”

或者,我个人最喜欢的:

  • “数据科学就是 Mac 上的统计学”

正如这份工作描述的百花齐放所示,很难清楚了解数据科学家角色的日常工作内容。很多现有的文章——虽然很出色——都来自 2012 年至 2020 年,而在数据科学这样快速发展的领域中,这些内容很快就会过时。

在这篇文章中,我的目标是揭开隐喻的面纱,给出 2023 年数据科学家的个人见解。

通过借鉴我在 3 个不同数据科学团队的工作经验,我会尽力帮助三类人群:

  1. 有志成为数据科学家:我会提供对这份工作的现实见解,帮助你更好地决定这是否适合你,以及需要掌握哪些技能。

  2. 数据科学家:为你的团队提供尝试新事物的灵感和/或回答“那么你实际做什么?”这个问题。

  3. 与(或想雇佣)数据科学家合作的人:了解我们实际做了什么(也许更重要的是,我们做什么)

这并不是全部都是自动驾驶汽车、ChatGPT 和深度学习。

一家大型科技公司的 AI 负责人曾告诉我,他遇到的最大误解是数据科学家总是在构建深度学习模型和做“炫酷的 AI 工作”。

现在不要误解我的意思——数据科学确实可以非常炫酷,但它包含的内容远超人工智能及其花哨的用例。将数据科学与 AI 等同起来,就像假设律师每天都在法庭上大喊“我反对!”一样;在幕后还有很多事情。

这不仅仅是“炫酷的 AI 工作”。

我最喜欢的关于数据科学的描述之一来自Jacqueline Nolis,她是总部位于西雅图的首席数据科学家。Nolis 将数据科学分为三大领域

  1. 商业智能——“将公司拥有的数据呈现给合适的人

  2. 决策科学——“利用数据帮助公司做出决策

  3. 机器学习——她描述为“将数据科学模型持续投入生产”,虽然我可能会更广泛地看待,包括实际的 ML 模型开发。

不同的公司会强调不同的领域,即使在这些领域中,方法和目标也会有所不同。例如:

  • 如果你是一名在决策科学领域工作的数据科学家,你的日常任务可能包括从运行 A/B 测试到解决线性规划问题的任何工作。

  • 如果你是一名花大部分时间在构建 ML 模型的数据科学家,这些模型可能是以产品为中心的(例如,构建一个推荐算法,将其整合到应用程序中),或以业务运营为中心的(例如,构建定价或预测模型,用于改善公司后台的商业运营)。

就个人而言,我发现数据科学最令人愉快的事情之一就是能够接触这三个领域,因此在我做的数据科学角色中,我总是努力确保有很多变化。这是尝试构建我之前提倡的“全能型人才,专精于一项”心态的好方法,作为框定数据科学家职业生涯的一种方式。

你可能没有想到(或者不想要)PowerPoint 的使用比你想象的要多得多。

图片由Teemu Paananen提供,Unsplash上发布

啊,PowerPoint。如果你以为数据科学家可以免于使用它,你就错了。

制作和展示幻灯片是任何数据科学家角色的关键部分,因为如果你无法沟通模型的价值,你的模型就无从发挥作用。正如 Andrew Young 所说:

多年来,我见过许多拥有博士学位的数据科学家花费数周或数月时间建立高效的机器学习管道,这些管道(理论上)能带来实际价值。不幸的是,如果他们未能有效传达自己工作的价值,这些辛勤的成果可能会无疾而终。

在我的团队中,我们非常重视与利益相关者的沟通,因此 PowerPoint 在我们日常工作中往往占据了很重要的位置。

对于每一个项目,我们都会制作一个主幻灯片文档,不同的团队成员可以在上面添加内容,然后每当需要向利益相关者展示时,我们就从这个文档中选择相关的幻灯片。在必要时,我们会尝试创建多个版本的关键幻灯片,以便能够量身定制我们的信息给不同的观众,他们有着不同的技术专长水平。

如果我说实话,我其实不介意花时间在 PowerPoint 上(请不要取消我),因为我发现制作幻灯片是提炼关键想法的一个很好的方法。说实话,这帮助我记住一些大问题,比如:(1)我在解决什么问题,(2)我的解决方案与基线方案相比如何,以及(3)有什么依赖关系和时间线。

清理数据?拿我的啤酒来

人们常说数据科学有 80%是准备数据…

… 以及 20%的时间在抱怨数据准备。

而且我不仅仅是在谈论数据科学是“新事物”的公司。

即使在有着成熟数据集的公司中,数据准备和验证也可能需要大量时间。至少,你会发现数据集(1)存储在不同的平台上,(2)发布的频率不同,或者(3)需要大量整理才能达到正确的格式。即使在你的模型投入生产后,你还需要持续检查数据集是否出现漂移、破损或缺失信息。

而且我真不想谈论用户输入的数据

在我之前的一份工作中,我们有一个在线表单,用户需要输入他们的地址,而我们的用户使用了 95 种不同的方式拼写“巴塞罗那”:我说的是从“barcalona”到“BARÇA”和“Barna”的所有拼写方式。

95 种“巴塞罗那”的拼写方式

故事的寓意是:除非你想花接下来几周的时间哭着看正则表达式文档,否则不要使用自由文本字段。

你总是在学习

图片由Christina @ wocintechchat.comUnsplash上提供

我最喜欢数据科学的一个方面就是它涉及持续学习。

对我来说,我一直害怕被困在一个做同样事情的工作中,我很感激地说数据科学并不是这样的职业。作为一名数据科学家,你会发现没有所谓的“标准”项目。所有项目都需要略微定制的方法,因此你总是需要调整现有知识并学习新事物。

我说的并不仅仅是像参加会议或做在线课程这样的“正式”学习。

更有可能的是,你会花费大量时间通过阅读编码文档、Towards Data Science 文章和 Stack Overflow 答案来进行“微学习”。如果你对我如何持续学习和保持更新的方法感兴趣,你可能会对阅读我最近的一篇文章感兴趣,在文章中我会更详细地讨论这一点:

## 我如何在全职数据科学家角色中保持对最新 AI 趋势的了解

不,我不仅仅是让 ChatGPT 告诉我

[towardsdatascience.com

这是一项团队运动

图片来自Marvin MeyerUnsplash

数据科学家并不是孤立存在的。

我们嵌入在团队中,为了有效地工作,你必须能够一起合作。我非常喜欢Megan Lieu 说的方式:

当我最终成为数据科学家时,最大的失望是了解到这不仅仅是整天埋头工作的事情。

“我迫不及待地想要不与任何人交谈,自己独自构建模型,做一些技术性的、数据科学的事情!”

令我这个内向者感到恐惧的是,我意识到我不仅需要与他人合作,还必须每天实际“交谈”商业和外部利益相关者

虽然我对团队合作的感觉比 Megan 轻微一些(我本质上更外向),但我也最初对这个角色通常有多么基于团队感到惊讶。在我的角色中,“合作”意味着:有每天的站会来讨论任务和阻碍,定期进行配对编程会话来调试和优化代码,并进行权衡不同技术方法的讨论(也就是说:争论)。

总的来说,我估计我大约花费了 50%–70%的时间在独立工作,其余时间用于配对或团队工作,尽管确切的比例在很大程度上取决于你的公司和资历水平。

就是这样!

感谢你阅读这篇关于我作为数据科学家的生活的小见解。

我希望你觉得这篇文章有帮助,如果你想聊天,请随时联系我 😃

还有一件事——你能成为我那 1%中的一员吗?

我在 Medium 上的读者中不到 1%点击我的‘Follow’按钮,所以无论是在 Medium、Twitter还是LinkedIn,你的点击对我都非常重要。

如果你希望无限访问我所有的故事(以及 Medium.com 上的其他内容),你可以通过我的推荐链接以每月 5 美元订阅。这对你来说不会增加额外费用,与通过一般注册页面订阅相比,它有助于支持我的写作,因为我会获得少量佣金。

GPT-4 带来的 AI 新视角

原文:towardsdatascience.com/what-gpt-4-brings-to-the-ai-table-74e392a32ac3?source=collection_archive---------9-----------------------#2023-04-14

自然语言处理

一种语言模型及更多内容

DozieTowards Data Science Dozie

·

关注 发表在Towards Data Science ·7 分钟阅读·2023 年 4 月 14 日

--

图片来自Unsplash

期待已久的最新生成预训练变换器(GPT)模型终于发布了。OpenAI 的 GPT 模型第四版在前几版的基础上有了一些改进,并且新增了一些扩展功能。像前几代模型一样,GPT-4 使用半监督训练进行训练和微调。GPT 模型中使用的半监督训练是通过两个步骤完成的:无监督生成预训练和有监督的判别微调。这些训练步骤帮助绕过了其他语言模型因标注数据不良而面临的语言理解障碍。

GPT-4 如何走到今天

OpenAI 于 2023 年 3 月 14 日发布了 GPT-4,距初次推出 GPT-1 已近五年。每次新版本发布时,这些模型的速度、理解能力和推理能力都有所提高。这些改进在很大程度上归因于训练过程中使用的数据量、模型的稳健性以及计算设备的新进展。GPT-1 在训练期间只能访问 4.5GB 的 BookCorpus 文本。GPT-1 模型的参数大小为 1.17 亿——相较于发布时存在的其他语言模型,这已经非常庞大。GPT-1 在它经过微调的不同任务中表现优异。这些任务包括自然语言推断、问答、语义相似性和分类任务。

对于那些仍对模型是否会超越 GPT-1 感到不确定的人来说,GPT-2 发布时的数字让他们大吃一惊。GPT-2 的参数大小和用于训练的文本大小大约是 GPT-1 的十倍。GPT-2 的尺寸并不是唯一的新增加内容。与 GPT-1 相比,OpenAI 去除了对特定任务进行额外微调步骤的需求。使用了少量样本学习,以确保 GPT-2 能够为单词赋予意义和上下文,而无需多次遇到这些单词。

就像 GPT-2 一样,GPT-3 和其他后续语言模型不需要针对特定任务进行额外的微调。GPT-3 的 1750 亿参数模型是在 570GB 的文本上进行训练的,这些文本来源于 Common Crawl、Web Text、英文维基百科以及一些书籍。GPT-3 的语言理解和推理能力非常深刻,进一步的改进导致了 ChatGPT 的开发,这是一个互动对话 API。OpenAI 开发了 ChatGPT,以便为用户提供一个基于网页的对话环境,使用户可以亲身体验扩展版 GPT-3 的能力,通过让语言模型根据用户的输入进行对话和响应。用户可以提出问题或请求有关模型训练范围内任何主题的详细信息。OpenAI 进一步规定了其模型能够提供的信息的范围。在涉及犯罪、武器、成人内容等的提示中,答案会特别小心。

GPT-4 的令人兴奋的特性

每一次 GPT 的新版本发布都带来了一系列在过去看似不可能的功能。ChatGPT 以其推理和理解能力给用户留下了深刻印象。用户能够获得关于任何主题的准确回应,只要这些主题是 ChatGPT 训练文本的一部分。但也有案例显示,ChatGPT 在回应发生在模型训练后事件的查询时遇到了困难。理解新主题的难度应是预期中的,因为 NLP 模型是对文本的再现,并尝试将时间和空间中的实体映射到期望的上下文中。因此,只有在其训练数据集中存在的主题才能被回忆起,对新主题进行概括将是相当雄心勃勃的。

GPT-3 模型的推理不仅相对有限,而且是单模态的。该模型只能处理文本序列。最新发布的 GPT 在前一版本的基础上进行了改进。由于其更高的推理水平,GPT-4 模型可以更好地估计句子的上下文,并根据该上下文进行一般理解。根据对新模型能力的初步了解,其他新特性如下:

  • 字数限制的增加,限制大小为 25,000 字,而 ChatGPT 的限制为 3,000 字。GPT-4 具有更大的上下文窗口,大小为 8,129 和 32,768 个标记,而 GPT-3 为 4,096 和 2,049 个标记。

  • 推理和理解的改进。文本理解得更好,并对文本进行更好的推理。

  • GPT-4 是多模态的。它接受文本输入以及图像。GPT-4 能够识别和理解图像的内容,并以人类水平的准确性从图像中做出逻辑推断。

  • 由 GPT-4 生成的文本更难被标记为机器生成文本。这些文本更具人类生成的特点,并利用诸如表情符号等句子特征,使文本感觉更个人化,并注入一些情感。

  • 最后,我想特别提到 GPT-4 附带的新动态标志。该标志展示了该模型的多变性以及其潜在应用场景的活力。我认为这个标志可能是赋予模型的最佳身份之一。

真实与虚构

GPT-4 的大小可视化表示

在等待 GPT-4 发布期间的某个时间点,这张图片曾在 Twitter 上流传。这张图片是 GPT-4 规模的传闻大小的视觉表现。与 ChatGPT 使用的参数大小相比,这张图片显示了新模型参数的显著增加。虽然这张图片传达的表现可能听起来是突破性的,但这可能并非完全真实。甚至 OpenAI 的 CEO 也驳斥了关于模型大小的传闻。关于训练多模式语言模型的架构和模型参数大小的官方文档尚未发布。我们无法确定创建这种模型的方法是通过缩放过去的模型还是一些新方法。一些 AI 专家认为,缩放不会提供 AI 世界正在努力实现的急需的通用智能。

OpenAI 在文本生成方面展示了 GPT-4 的巨大优势,但我们是否曾经想过生成文本与一些标准考试的生成文本相比如何?尽管 GPT-4 在某些考试中表现相当不错,但在需要更高推理能力的考试中表现不佳。Open AI 发布的技术报告显示,GPT-4 在两个版本的 GRE 写作考试中一直处于第 54 百分位¹。这门考试是许多考试中考验研究生推理和写作能力的考试之一。可以说,GPT-4 生成的文本几乎与大学毕业生一样好,这对于一台“计算机”来说并不差。我们还可以说,这种语言模型不喜欢数学,或者更确切地说,在微积分方面表现不佳。它在 AP 微积分 BC 考试中的表现处于第 43 至 59 百分位,与同一考试委员会的生物学、历史学、英语、化学、心理学和统计学对应学科的高百分位得分相比显得较低。随着难度的增加,该模型表现出了困难。目前人类仍然处于思维的顶端。

有没有想过这些语言模型在编码方面的表现如何?GPT-4 在一些 Leetcode 任务上进行了编码能力检验。它在简单任务上的表现相当不错,但随着任务难度的增加,其表现却在持续下降。值得注意的是,GPT-4 在 Leetcode 任务的总体得分几乎与 GPT-3 相似。OpenAI 这次的表现并不比以前好,或者说他们可能没有试图将 GPT 模型打造成下一个 Github Copilot。想象一台计算机在面试编码问题上表现优于一般程序员,真是太疯狂了!

尽管某些功能与前代模型相比并未见到许多改进,值得注意的是模型在其他任务上的表现如何。

结论

GPT 的第四个版本展示了语言模型的范围没有限制,因为这些模型并不是多模态的,能够接受文本以外的输入。这可以被视为未来版本更高级功能的先兆。我们可能会看到一个语言模型在图像识别任务中表现得和计算机视觉模型一样好,甚至更好,这得益于 GPT-4 的图像理解能力。我们正逐步朝着通用人工智能迈进。虽然还有很长的路要走,但我们显然有一个方向,并且知道我们要去哪里。

[1]: OpenAI. (2023 年 3 月 16 日). GPT-4 技术报告 cdn.openai.com/papers/gpt-4.pdf

谢谢!

如果你喜欢我的文章,请 关注我 ,这样你就会在我发布故事时收到通知。我将在这个领域发布更多文章。祝你一切顺利。

语义网发生了什么?

原文:towardsdatascience.com/what-happened-to-the-semantic-web-cbaaf547a09f

结果并没有如预期那样发展。

Rafe Brena, Ph.D.Towards Data Science Rafe Brena, Ph.D.

·发表于 Towards Data Science ·7 分钟阅读·2023 年 8 月 3 日

--

塞尔·蒂姆·伯纳斯-李设想的由稳定扩散生成的网络

还记得语义网吗?可能不记得了。大约二十年前,它曾风靡一时。但如今,关于它的提及已经很少了。

在开始时怀揣对新网络的大胆愿景(见下文),语义网逐渐失去了动力,逐渐被边缘化。然而,关于为什么会这样,从未有过“清算”——直到现在,语义网的愿景必须考虑到颠覆性和炫目的生成式人工智能技术的存在。

在这篇文章中,我将探讨为什么语义网尽管失去了最初的光彩,但仍然是网络拼图中的一个重要部分,即便与新的生成式人工智能共存,以及为什么数据科学专业人士也应该了解它。

但首先,让我们来看看创立语义网的那个人。

网络背后的男人

蒂姆·伯纳斯-李(TimBL)在 1999 年提出了语义网(SW)的概念,当时他在 万维网联盟(W3C)工作。这个想法是创建一个机器可以处理的数据网络,使它们能够理解信息的含义并在不同数据片段之间建立联系。

我们必须理解,语义网对蒂姆·伯纳斯-李来说是第二次尝试。1999 年,他已经是全球(不是开玩笑)知名人物,因为他早已创造了万维网。

在 1990 年,当他作为访问学者在瑞士的 CERN 时,他向他的老板迈克·森德尔提出了将网络变为现实的想法,后者认为这个提案“模糊但令人兴奋。” TimBL 说他几乎没有发明什么,因为超链接、互联网协议和许多其他元素已经存在。然而,没有人采取将它们全部整合起来的步骤。

正如 TimBL 所说,

我只需将超文本的理念与 TCP 和 DNS 的理念连接起来——瞧!——于是出现了万维网。

人类的一小步……

第一个构建的网页仍然可以在这个地址访问——没有花哨的格式,只是在顶部写着“第一个网站的首页。

现在你对 TimBL 有了了解……以及为什么在他的第二个提案,即语义网提案,几乎在世纪之交时发布时,他会被非常严肃地对待。

语义网的愿景

语义网被视为互联网发展的下一步,互联网直到那时还专注于将文档链接在一起。通过语义网,重点将转向连接数据,创建一个更智能和互联的网络。

语义网的愿景是使机器能够理解网络上信息的含义,并利用这种理解提供更智能和个性化的服务。在世纪之交时,显而易见的是,网络不仅仅是供人类使用的,但信息在网页中的存储方式完全无法自动化处理信息。根据 TimBL 的说法,传统网络正在成为网络处理自动化的瓶颈。

这一愿景非常吸引人:与传统的网络不同,传统网络的页面设计用于向人类展示信息,自描述的网页将使得自动化处理内容成为可能。因此,彻底改造我们所知的互联网是非常有意义的。正如他对网络所做的那样,TimBL 呼吁开始新的革命。

我当时在场,见证了这一运动的兴起——不仅仅是观察:我的几位研究生也在从事语义网相关的研究。

实现语义网的技术

但语义网不仅仅是一个理念——为使其成为现实,开发了一系列技术和标准,这些内容在以下几点中有所介绍:

  • 资源描述框架(RDF):用于在网络上表示信息的数据模型。RDF 使用 URI 来标识资源,使用谓词来描述资源之间的关系。

  • Web 本体语言(OWL):一种用于描述 RDF 数据含义的表达性语言。OWL 可用于定义资源之间的复杂关系以及定义在层次结构中组织的资源类。

  • SPARQL:一种用于 RDF 数据的查询语言。SPARQL 可以用来从 RDF 数据存储中提取信息。

  • 语义网服务:一种使用语义标记来描述服务能力以及它所消耗和产生的数据的网络服务。

一些重要的语义网发展,例如 DBpedia,一种按照上述标准组织的结构化信息的维基百科,已经开展。它包含超过 2.28 亿个实体,当我们不习惯谈论像大型语言模型中的节点数这样的大量数据时,这个数字显得非常庞大(见下文)。

DBpedia 类似于 Google 的“知识图谱”,它被用来解决搜索查询。Google 的知识图谱是一个概念和名称的网络,表现为 RDF 三元组的集合。我不能给你更多的信息,因为这主要是 Google 的内部信息。我相信知识图谱对 Google 提供了相对于竞争对手的优势。

例如,我相信你已经注意到,Google 有时会检索到关键词没有出现但与查询相关的页面。这是因为“语义搜索”。这种搜索超越了简单的关键词匹配,通过结合与查询相关的知识图谱中的术语来进行。语义搜索考虑了同义词和其他概念关系,以丰富搜索结果。

即使不完全了解每项技术,我们也可以看到,从技术角度来看,几乎所有的要素都已经存在。那么,为什么这次缺少了“哇哦!”的时刻?为什么 SW 花了这么长时间才显现?

生成式 AI 的崛起

SW 认为需要机器可读的格式来理解存储在 Web 上的信息的含义。TimBL 认为人类可读的信息对机器来说不可用。

而且时间不长。

直到 2022 年 11 月,ChatGPT 在抓取了数百万个网页文档后,才开始能够回答人类提出的问题,尽管不太可靠。

然后情况发生了快速而戏剧性的变化。ChatGPT 和其他聊天机器人的令人印象深刻的对话能力表明,存储在 Web 上的信息可以被机器“理解”。进一步地,它可以回答问题并向人类建议行动。

谁会想到这一点?我没想到,Tim Berners-Lee 也没想到。

生成式 AI 很快超越了语义网(SW)。它的能力吸引了开发者、研究人员和企业的关注。焦点从创建结构化的 SW 转向利用 AI 的力量生成内容。

会有复兴吗?

一旦 SW 的核心假设(即机器无法理解网页)被证明是错误的,它的未来变得不确定。许多人认为,SW 会变得过时,走向像渡渡鸟一样的灭绝。

不要那么快。

首先,像 RDF、SPARQL 和语义网服务这样的具体 SW 技术将会长期存在,因为它们是现有基础设施的一部分。事实上,它们是 Amazon Web Services 提供的一部分

此外,我认为,无论是在 Google 还是其他地方,知识图谱都将补充生成式 AI 解决方案。

让我给你一个具体的例子。

从今年春天开始,我与同事讨论了 Bing 如何使用知识图谱回答问题(是的,微软也有它的知识图谱版本)。然后我看到了一张 Bing 的技术图解,变得清楚它们是如何做到的。

事情是这样的:

当查询提交给 Bing 时,他们使用它来检索知识图谱的相关部分。结果类似于补充原始用户查询的一组陈述。这种“增强”的查询随后作为 ChatGPT 或其他大型语言模型的提示。就是这样。

从知识图谱获取的信息相比于没有它的聊天机器人有优势:主要的优势在于它由可靠的信息组成,而不是由 LLM 单独生成的虚假信息、幻想或其他虚假信息。

还有一个令人垂涎的可能性没有人提及:AI 可以用于注释常规网页,并使用 SW 标准使其自我描述。

你知道,拖慢 SW 的一个障碍是为每个特定网站采用它的成本。SW 从未成为许多公司的优先事项,所以他们避免将资源用于将页面改造为 SW 标准。

但有了 AI,转变普通网页为 SW 网页可能会变得便宜。实际上,聊天机器人特别擅长遵循格式:我自己验证过这一点。因此,AI 可能会去除 SW 采用的主要障碍,前提是对其仍有兴趣。

结束语

我认为知识图谱以及许多与 SW 相关的技术最终将保持有用。

讽刺的是,生成性 AI 起初看似会给 SW 最后一击,但最终可能会与其形成一种共生关系,使其再次变得相关。它们正在合作开发诸如新型 Web 搜索的生成性 AI 应用,未来可能会继续合作。

所以,回答“SW 会有复苏吗?”这个问题的答案是响亮的“是的”,但不是按照 TimBL 最初的设想,即全面改造 Web,而主要作为对其他系统的支持,确实少了些光彩,但同样有用。

让我们面对现实:TimBL 对语义网的原始愿景永远不会成为现实。那是一个(或看似)极好的想法,个人来说,我曾经坚信不疑地投入其中。但是技术并不促进优秀的想法,而是方便的想法。

那么,让我们结束于新的语义网愿景:

“愿沉闷、乏味、朴实、真实的语义网长命百岁,它将作为闪亮、花哨、迷人的人工智能的支持角色。”

Neo4j v5 中 APOC 发生了什么:核心版和扩展版

原文:towardsdatascience.com/what-happened-with-apoc-in-neo4j-v5-core-and-extended-edition-23994cdf0a2c?source=collection_archive---------9-----------------------#2023-04-04

Neo4j 的 APOC 插件在 v5 版本中被分为两个版本

Tomaz BratanicTowards Data Science Tomaz Bratanic

·

关注 发表于 Towards Data Science ·5 分钟阅读·2023 年 4 月 4 日

--

图片由 Markus Spiske 提供,Unsplash

你是否升级或下载了 Neo4j v5,现在一些你喜欢的 APOC 程序不再工作了?你并不孤单。

从 Neo4j v5 开始,APOC 已被拆分为两个版本。主要区别在于,一些过程在核心版中得到了官方支持并可用。APOC Core 包含经过严酷测试的过程和函数,没有外部依赖项。另一方面,扩展版包含可能需要外部依赖项的附加过程,并且没有官方支持。

我写这篇博客文章是为了帮助你理解两个版本之间的新区别。首先,现在有两个独立的文档网站:

此外,如果一个过程不是核心版的一部分,它在文档中会被标记为扩展标签。

APOC 扩展标签。图片由作者提供。

例如,apoc.load.json过程是核心版的一部分,因为它没有扩展标签。另一方面,apoc.load.csv过程是扩展版的一部分,如扩展标签所示。

现在让我们来看看安装过程。

Neo4j Desktop

我喜欢使用Neo4j Desktop在本地环境中进行任何原型设计。这是一个很好的应用程序,可以让你通过几次点击来设置和安装 APOC 插件。

在 Neo4j Desktop 中安装 APOC。图片由作者提供。

但是,目前并没有明确提到单击安装仅安装核心版。如果我们想添加扩展版,需要手动下载并将其复制到插件文件夹中。

扩展版的发布可以在GitHub上找到。我们需要确保 APOC 版本与 Neo4j 版本兼容。APOC 版本遵循 Neo4j 版本,例如,APOC v5.5.0 与 Neo4j v5.5.0 兼容。确保 Neo4j 和 APOC 之间的前两个版本号匹配。

APOC Extended v5.5.0。图片由作者提供。

我们需要下载适当版本的扩展 jar 文件。一些过程需要额外的依赖项,这些依赖项也可以下载。然而,大多数情况下,仅下载扩展 jar 文件就足够了。下载完成后,将 jar 文件复制到插件文件夹中。

选择插件文件夹。图片由作者提供。

你可以通过点击三个点选项,选择打开文件夹,最后点击插件来打开plugins文件夹。

文件夹中应已包含你在 Desktop 应用程序中安装的 APOC 插件核心版本。因此,最终应该有两个 APOC Jar 文件,一个用于核心版本,另一个用于扩展版 Docker 版本。

确保首先安装核心版,因为它总是设置适当的配置值,以允许我们执行 APOC 过程!

另一个变化是,我们不能将 APOC 配置设置添加到neo4j.conf文件中。相反,我们需要创建一个apoc.conf文件,并在其中设置任何 APOC 配置值。例如,我们需要设置以下配置,以允许 APOC 过程从本地磁盘读取文件。

apoc.import.file.enabled=true

你可以通过以下流程在 Neo4j Desktop 中设置此配置:

设置 APOC 配置值。图像由作者提供。

按照说明打开Configuration文件夹。接下来,创建一个新的apoc.conf文件,然后在新创建的文件中设置适当的配置值。

Neo4j Docker

在生产环境中,我喜欢在 docker 容器中运行 Neo4j。Neo4j 的 docker 容器提供了一个方便的环境变量,帮助我们安装适当版本的 APOC 插件。

docker run \
    -p 7474:7474 -p 7687:7687 \
    -e NEO4J_PLUGINS=\[\"apoc\"\] \
    neo4j:5.6.0

然而,使用环境变量在 Neo4j v5 中安装 APOC 插件将只安装核心版。不幸的是,如果我们想使用扩展版,我们需要手动下载并将其复制到插件文件夹中。

我更喜欢在与 docker 容器交互时使用docker-compose。因此,我将使用以下docker-compose设置来运行 Neo4j,并同时使用 APOC 核心版和扩展版。

version: '3.7'
services:
  neo4j:
    image: neo4j:5.5.0
    restart: always
    hostname: neo4j
    container_name: neo4j
    ports:
      - 7474:7474
      - 7687:7687
    volumes:
      - ./neo4j/data:/data
      - ./neo4j/plugins:/plugins
    environment:
      - NEO4J_AUTH=neo4j/pleaseletmein
      - NEO4J_PLUGINS=["apoc"]
      - NEO4J_apoc_import_file_enabled=true

在这个例子中,我们使用的是 Neo4j v5.5.0。我们还使用了环境变量来安装 APOC 核心库,并允许 APOC 过程从磁盘读取文件。然而,我们需要下载APOC Extended v.5.5.0并将其复制到neo4j/plugins文件夹中。所以,我们只需要手动复制扩展版,而核心版是通过NEO4J_PLUGINS变量安装的。此外,在大多数情况下,你还希望持久化数据库文件。因此,我们还挂载了data文件夹。

总结

在 Neo4j v5 中,APOC 被分为核心版和扩展版。如果你使用的是核心版的过程,安装过程没有变化。然而,如果你使用的是扩展版的过程,你需要手动下载并从 GitHub 发布页面复制扩展版。希望这篇博客文章能帮助解决你在 Neo4j v5 中遇到的任何 APOC 问题。

当大多数在线内容变成 AI 生成时会发生什么?

原文:towardsdatascience.com/what-happens-when-most-content-online-becomes-ai-generated-684dde2a150d?source=collection_archive---------9-----------------------#2023-10-17

了解生成模型在训练数据时如何退化,以及如何应对这一问题

Aicha BokbotTowards Data Science Aicha Bokbot

·

关注 发表在 Towards Data Science ·6 min read·2023 年 10 月 17 日

--

Spiral — 图片来源于 Ludde LorentzUnsplash

引言

最近,生成性 AI 的突破带来了可以生成高度逼真和复杂的文本、图像和声音的公开 AI 模型,这些模型正在彻底改变内容创作。

这些模型是在从互联网抓取的大型数据集上训练的。例如,在文本数据的情况下,像 ChatGPT 这样的高级语言模型(LLMs)主要是在在线找到的人类生成文本上进行训练的。

生成模型已经在社会上获得了广泛的声誉和快速的采纳,以至于越来越多的 AI 生成内容出现在互联网上,而这正是它们训练数据的主要来源。

我们在这里看到一个循环:生成模型将不可避免地在由生成 AI 而非人类生成的合成数据上进行训练。这就引出了一个问题:如果发生这种情况,模型会有什么表现?

生成模型与退化

一旦大型语言模型(LLMs)贡献了大量在线语言内容,GPT-{n}会发生什么?

这是一个由一组研究人员提出的问题,他们发表了论文 递归的诅咒:在生成的数据上训练使模型遗忘(I. Shumailov 等,2023)。

作者们通过让模型在生成的数据上进行多次迭代学习进行实验。他们将此应用于高斯混合模型(GMMs)、变分自编码器(VAE)和大型语言模型(LLMs)。对于这三种模型,这导致了他们称之为“模型崩溃”的现象:

一种退化过程,其中,随着时间的推移,即使在分布未发生变化的情况下,模型也会遗忘真实的基础数据分布。

模型崩溃 描述了模型遗忘真实分布的尾部(即不太可能、较少见但重要的事件)并过度代表分布中心的行为。随着这一过程的重复,模型会收敛到一个与原始分布相似度很低的分布。

在论文 自我消耗的生成模型会变得 MAD(S. Alemohammad 等,2023)中,其他研究人员类似地将这种逐渐远离原始分布的现象描述为“模型自噬紊乱”(MAD):

[…] 如果每次生成中没有足够的新鲜真实数据,未来的生成模型注定会陷入模型自噬紊乱(MAD),即它们的质量(以精确度衡量)或多样性(以召回率衡量)将逐渐退化。

结论很明确:当生成模型主要在它们生成的内容上进行训练时,它们往往会退化。考虑到它们的训练数据主要来自互联网,这种退化过程代表了多大的风险?

当人类生成的内容变得稀缺时

如果人类生成的内容与 AI 生成的内容的比例保持在目前的水平,并且在线内容中人类生成的内容占据明显多数,那么情况不应令人担忧,生成模型的表现也不应出现前述的退化问题。

然而,关于由 AI 生成的内容主导互联网的前景,确实存在合理的担忧。如果我们关注文本生成,支持这种预测的主要论点是 LLMs,如 GPT 提供的便利。这些工具在写作中解决了真正的痛点:找到合适的词汇、改善风格、获得灵感。那些尝试过这些工具的人可以证明,依赖这些工具是多么具有诱惑力和成瘾性:既然我们可以轻松地提示 LLM 生成在风格和时间效率上都更好的内容,为什么要挣扎呢?

如果人类生成的内容变得不那么普遍,我们可以采取什么措施来减轻将生成模型暴露于 AI 生成内容的风险?一种可能的方法是通过鼓励没有 AI 工具的内容创作来对抗这种趋势。另一种方法涉及开发检测 AI 生成数据的方法,并在模型训练过程中将其筛选出去。

第一个方法的想法是找到激励创作者减少使用生成模型的方式。然而,这种方法的可行性可能有限。即使我们能找到这样的激励措施(例如奖励或惩罚),挑战在于验证一段内容是否真正是人类生成的。这将我们引向第二种方法,这种方法也依赖于区分人类生成和 AI 生成数据的能力。

如何检测 AI 生成的数据

在 2023 年,公司 AI21 Labs 领导了迄今为止最大的图灵测试:超过 150 万用户与人类或 AI 聊天机器人进行在线聊天,并被要求猜测他们与谁对话。这一任务被证明并非易事,因为 68% 的人猜对了,显示了生成型 AI 能多么好地模仿人类。

有鉴于此,让我们回顾一些识别 AI 生成数据的可用技术。

水印

文献中讨论的主要方法来区分人类生成的数据和 AI 生成的数据是水印。水印是将隐藏的信号添加到数据中,这些信号对人类不可见但算法能够检测到。

水印将使检测 AI 生成的数据变得容易,但前提是生成型 AI 提供者将其添加到他们的产品中。目前情况并非如此,并且可能过于乐观地期望近期能实现。

在他的公开信《水印不可行》中,Andrew Ng 对水印的采用持悲观态度。他解释了在当前的生成 AI 竞赛中,水印如何看起来像是 AI 公司的一种竞争劣势。

使用 ML 分类器

一种替代水印的方法是训练一个机器学习分类器,让其学习标记内容是 AI 生成还是人类生成。

执行此任务的系统已经存在,例如 GPTzero。然而,这些系统显示出较高的错误率,并且未能提供可靠的解决方案。即使是机器学习模型,检测 AI 生成的数据也证明是一项困难的任务。

一种零样本方法

论文 DetectGPT: Zero-Shot Machine-Generated Text Detection using Probability Curvature(E. Mitchell 等,2023)中讨论的另一种方法不需要任何训练,基于观察 LLMs 对数概率函数的曲率。

作者发现的标准是,AI 生成的文本往往倾向于占据具有负对数概率曲率的区域,而不是人类撰写的文本。

这似乎是一种有前景的技术,尽管我们可能对其可扩展性存有疑虑:它不是模型无关的(它检测内容是否由特定的 LLM 生成,而不是任何给定的 LLM),并且需要访问模型的对数概率。

结论

我们了解到,训练生成模型时使用人类生成的数据非常重要,以避免性能下降。这带来了一个重大挑战,特别是因为互联网是它们主要的训练数据来源,并且越来越多的在线内容是 AI 生成的。

有两种方法可以解决这个问题:通过推动人类内容创作来扭转趋势,以及防止模型在合成数据上进行训练。然而,这两种解决方案都引发了复杂的开放性问题。我们如何激励在线内容创作者减少对 AI 的依赖?我们如何建立可靠、可扩展的 AI 生成内容检测方法?

令人鼓舞的是,白宫在 2023 年 7 月做出了一个重要的 声明。七家主要的 AI 公司——亚马逊、Anthropic、谷歌、Inflection、Meta、微软和 OpenAI——同意尊重一系列负责任的 AI 承诺,其中包括水印。未来将揭示这些承诺是否得到遵守。

进一步阅读

我作为数据分析师保持相关性的做法

原文:towardsdatascience.com/what-i-am-doing-to-stay-relevant-as-a-data-analyst-af15d714ac58

如何在竞争激烈的职业市场中导航职业发展

Rashi DesaiTowards Data Science Rashi Desai

·发表于 Towards Data Science ·7 分钟阅读·2023 年 5 月 5 日

--

Jonathan Chng 拍摄,来源于 Unsplash

技术和数据的世界不断发展,对数据专业人士的需求也在增长。数据相关的工作处于职业网站的前沿。数据分析师是一个不断增长的职业,薪酬优厚,对组织具有巨大价值,并承诺在数据生命周期内拥有平衡的工作内容。

我大约两年前开始担任医疗数据分析师,并逐步晋升为分析和报告顾问,使用我所在组织广泛使用的多个工具和平台。现在,我每天积累关于公司内特定产品的知识,努力做到卓越,却不知道这些工具和技术是否是当前行业中广泛使用的。它也让我时常怀疑,如果我开始寻找新的工作,我的技能是否仍然相关和适用。

从我在公司中看到的,以及听到的同行和网络讨论,我发现数据分析师在劳动力市场中的需求和供应都很旺盛。随着数据分析师和类似专业人士的涌入,我希望能保持敏捷和竞争力(至少为了保住我的工作),以下是我为保持相关性并脱颖而出的做法。

1. 从工作之外进行数据项目

我已明确不将职业成长和发展限制于日常工作。参与 9-5 工作之外的项目让我能够在主要工作之外提升技能,作为专业人士不断进步,并发展我处理各种问题陈述的思维方式。

对某些人来说,从事工作之外的项目可能是一个激情项目、创造机会,或只是拓展网络。例如,你可以 —

  • 参与研究项目并发表论文 — 你可以联系大学的教授(或你的母校),与研究生合作,进行从头到尾的项目,并获得明确的成果。

  • 写下你的学习和工作经验 — 基本上,就是博客/视频日志记录你的数据之旅。我在 2017 年开始写博客,这成为了保持更新世界和获得曝光的最有效方式之一。

  • 在技术社区活动或会议上做演讲 — 很多专业人士在技术技能方面表现出色,但在沟通技能上有所欠缺。在社区活动或会议上做演讲是了解观众的一种最佳方式,使你的工作适合各种知识水平的人群。你可以从小规模的演讲开始,逐步发展到更大的观众。这将帮助你保持更新,并让你的工作保持相关性。

这里的目标是通过新的技能来提升你的作品集,扩展你的网络和经验,以便在工作中加以利用。

2. 完成在线认证或微硕士学位

学习永无止境,无论你多年轻或多老。

我喜欢投资时间和金钱于在线认证,因为它需要更少的时间来在非常具体的主题领域内发展知识或技能。比如,你发现 Alteryx 是一个对你和你的团队有奇妙效果的工具,你想要具备工作知识,你会去哪里?互联网是当今社会的支柱,而在线认证可以很好地完成这项工作。

我最近发现了许多提供在线微硕士课程的顶级大学,你可以按照自己的节奏学习一年或更短的时间,并获得来自知名学校的微硕士学位,这为你打开了学校的网络、学习资料和教授。

这里的目标是提升你的生产力和成长,从而也增加你对雇主的价值。

你还可以探索在线认证,以便与你希望从事的职位对齐,或获得长期等待的晋升。

3. 与初创公司或新兴科技公司合作

咨询是我喜欢花时间做的事情之一 — 创建策略,从模糊或大型问题陈述中构想解决方案,并提供基于数据的可操作见解。这就像看着你在冬天种下的种子在夏天长成植物一样。这个过程需要时间和耐心,但结果 — aaaah!

在开始工作之后,我很幸运地结识了合适的人,这些人给了我机会,使我能够主要与医疗保健领域的初创公司交流,并与他们一起从零开始构建。首先,以下是如何建立联系的步骤 —

  • LinkedIn始终是寻找初创企业和创始人的好主意——与志同道合的人或具有类似或你梦想职业路径的专业人士建立联系,看看他们今天在做什么。

  • 参加社区活动——这是扩展网络和寻求新机会的最相关方法之一。

  • 安排咖啡聊天与那些让你感兴趣的人——来自Twitter、你的导师或旧工作的朋友,这些对话可能最终会变成一个顾问工作机会。

作为顾问,你可以从外部审视的角度来改进初创企业的潜在客户生成、战略、风险和评估方面,充当一个枢纽。通过公开曝光(如 Medium 博客),你可以为人们找到你打开了大门,而你永远不知道——这可能会引发与未来独角兽的激动人心的合作对话 😉

这里的目标是,首先,将自己展现出来,与那些你可以共同成长的人建立联系。

4. 与跨职能团队合作

许多组织允许专业人士参与次要项目,这正是你与新人员合作、分享知识、倾听新对话、尝试新工具和技术的信号。如果没有,至少要保持开放的心态去建立网络;坐下来向组织内的各个项目介绍自己,然后为你的团队进行基准测试并在内部引入创新。

过去,一次随机的 Teams 聊天让我有机会进行几次卓越的咖啡聊天,并能够向其他团队推荐数据策略——这只需要在公司内找到你喜欢的工作成果的人,并发送一条简短的信息或邮件。

这里的目标是拓宽你的视野,并感受到与更大愿景的连接。

每天,你的 9–5 工作时间表或多或少都遵循类似的结构。但令人兴奋的地方在于认识具有不同技能、责任和学科的人,并从中学习。

5. 探索世界提供的机会

对我来说,参与工作之外的内容和对话使我能够不断学习新知识并保持技能的更新。整天忙碌,你可能没有意识到世界随着新工具、新技术、新思维、商业语法等的变化有多快。

我们不知道我们不知道的事情。

  1. 阅读博客和新闻通讯:阅读世界上要说的内容。你阅读得越多,就越有可能记住单词、想法和短语,并将其应用于你下一个工作项目中。在与初创企业创始人的对话中,我听他说过“数据专业人士只能和他们的数据一样好”,因此现在,每当工作中有流程或准确性改进的对话时,我都会把这句话抛出来,以提高利益相关者的认识和支持。

  2. 听播客:虽然与数据相关的播客可能不多,但关于个人品牌创建、自我重塑、微习惯等的播客会有很多,这些都能塑造你。

    我从去年一个名为Take A Pause(现在已经成为一种习惯)的播客中得到的最大收获之一——记录你的每周工作情况。今天,我会记录下工作周、每日的小胜利和亮点、我如何为团队和组织增值,这些小笔记甚至对年终评估非常有价值。

  3. 加入技术/数据社区: 依然是与拥有共同兴趣、技能和目标的人网络联系的最佳方式之一。

  4. 与同事和联系的人社交: 安排与工作中的同事喝咖啡,发送冷邮件请求讲解你喜欢的新工具。基本上,建立有意义的关系 (这是一个互惠互利的过程),这在长期中能为你的职业生活增值。

目标是了解并适应数据领域的最新和最伟大的事物(无论是什么最适合你的角色),并与志同道合的人联系,学习一些东西。

就我来说,这篇博客就到这里。感谢阅读!希望你觉得这篇文章有趣。请在评论中告诉我你在数据领域的经历和旅程,以及你在 2023 年的期望!

如果你喜欢阅读这样的故事,可以通过这个 链接** 注册成为 Medium 会员**。

数据快乐露营!

Rashi 是一位来自芝加哥的数据达人,喜欢可视化数据并创建洞察故事来传达见解。她是一名全职的医疗数据分析师,并在周末用一杯好咖啡写关于数据的博客……

作为数据科学家,经过一年 AB 测试后我学到的东西 — 第 1/2 部分

原文:towardsdatascience.com/what-i-learned-after-running-ab-tests-for-one-year-as-a-data-scientist-part-1-2-5277911e89ec?source=collection_archive---------9-----------------------#2023-01-03

按照这些简单步骤像数据科学家一样设置你的 A/B 测试

Alex VamvakarisTowards Data Science Alex Vamvakaris

·

关注 发表在 Towards Data Science ·13 min read·2023 年 1 月 3 日

--

Nathan Dumlao 拍摄于 Unsplash

数据科学家工作的一大部分是测量差异。更具体地说,是比较产品或服务的不同版本,并确定哪个表现更好。这是通过随机对照试验 (RCT) 或其更高级的商业名称A/B 测试来完成的。

思路非常简单。我们想要改进一个特定的 KPI,比如结账页面的转化率。然后我们假设某些变化可能对我们的 KPI 产生积极影响。例如,我们可能想测试将结账按钮的颜色从灰色改为绿色。然后,我们将随机分配结账页面的访客,一半看到当前版本(灰色按钮),另一半看到新版本(绿色按钮)。当前版本和新版本的术语分别为控制处理。作为数据科学家,我们的工作是测量两个版本之间的转化率差异,并确定这是否具有统计显著性或仅仅是运气(随机变异)。

在这个系列中,我将带你全面了解 A/B 测试的整个过程,从设计实验到分析和展示结果。案例研究旨在模拟在现实环境中进行 A/B 测试时遇到的挑战,同时涵盖数据科学面试中常见的关键问题。指南将分为以下两部分:

第一部分

  • 思路: 商业案例研究概述

  • 设计测试: 选择目标人群和关注的 KPI

  • 测试前分析: 使用功效和模拟来估计样本量

第二部分:AB 测试分析

  • EDA: 合理性检查,时间序列可视化

  • 分析实验结果: P 值、置信区间、自助法等。

1. 思路

照片由 Riccardo Annandale 提供,来源于 Unsplash

对于我们的案例研究,假设一个电商零售商在英国销售巴西咖啡豆。每周五,公司提供每消费 50 英镑减 10 英镑的优惠。一个产品经理一直在尝试提高促销效果,并通过研究提出了一个想法。如果我们将优惠的描述改为百分比折扣,那么每消费 50 英镑将获得 20%的折扣。思路是 20 比 10 高,所以客户可能会认为同样的优惠具有更高的价值(尽管 20%和 10 英镑折扣是相同的交易)。

这时我们的主角登场了。对这个想法非常兴奋的产品经理安排了一次与公司数据科学家的电话会议,并向他讲解了这个想法。我们的数据科学家对 A/B 测试并不陌生,因为他过去多次帮助业务利益相关者做出这样的决策。于是,我们的旅程开始了。

2. 设计测试

图片由 Alex wongUnsplash 提供

目标人群

在进一步进行之前,重要的是明确我们实验的目标人群。在我们的例子中,就是任何在星期五(即优惠活动上线时)访问网站的人。这是一个重要的区别。如果用户在星期一访问了网站,那么将他们纳入实验没有意义,因为他们不会受到优惠活动变化的影响。

按照这个逻辑,你可能还会问是否适合包括所有星期五的访问者。优惠可能并非在所有页面上都有展示,因此只应包括访问了有优惠展示的页面的用户。你说得对。对于我们的案例研究,我们假设优惠是在网站每个页面顶部的横幅(如下所示),以简化问题。

为 A/B 测试设计两个版本 [图片来源:作者]

选择感兴趣的 KPI

无论实验的想法是来自 CEO 还是初级分析师,明确 KPIs 的需求总是存在的。但是为什么会这样呢?我们为什么不能先进行实验,然后查看所有可能受到影响的指标?

除了影响效率之外,还有另一个理由需要在开始测试之前定义我们的 KPI。为了估算(关键词)进行准确推断所需的样本量,我们还必须了解 KPI 的方差。一个波动性较大的指标,如平均支出,可能会偏斜,并具有更高的方差和异常值,因此需要比对称正态分布指标更高的样本量。

好的,让我们开始正式工作。对于我们的实验,我们关注两个 KPI。两者都在访客层面,并且与我们期望的新版本的效果有合理的关联。更多的访客兑换优惠(即更高的 ATPV),而不降低他们的整体支出(更高的 ARPV 或至少对 ARPV 没有负面影响)。

每访客平均收入 (ARPV): 总收入 / 总访客数

每访客平均交易数 (ATPV): 总交易数 / 总访客数

时间窗口

你可能已经注意到,周五没有出现在任何一个指标的公式中。这是因为如果周五的访客支出减少会影响到其他日期的销售,从而导致每周或每月支出保持不变,我们并不关心在周五增加访客支出。我们真正关心的是在设定的时间窗口内逐步增加他们的整体交易量和支出。

由于大多数公司每月报告其关键 KPI,我们也将以 28 天为窗口报告我们的两个 KPI(其他公司可能按周或每两周运营,因此 7 天或 14 天的 KPI 可能更合适):

  • 每个访客在测试上线后第一次访问网站的周五进入实验。这将是他们的第 1 天。

  • 接下来,我们收集接下来的 27 天的数据,从而获得每个访客的 28 天 KPI。

  • 因此,28 天 ARPV 将是访客进入测试后的 28 天内收入总和,除以访客数量。

  • 仅包括在测试中待满 28 天的访客(不是所有访客,因为我们希望给每个人相同的购买时间窗口)。

  • 28 天窗口还确保没有新奇效应(访客对变化最初感到兴奋,但这种兴奋在一两周后很快消退)。

KPI 的 28 天窗口示例 [由作者提供的图片]

这些都是面试中需要覆盖的重要点。展示你对总体情况的理解,以及用户进入测试的漏斗的哪个部分(是所有页面还是特定页面)。最后,始终将其与业务需求联系起来。解释清晰地与利益相关者沟通定义 KPI 的必要性,以及你如何设计实验以使其成为资产!

3. 预测试分析

图片来源于 AbsolutVisionUnsplash

这就是令人兴奋的部分开始的地方。我们在这一部分的主要目标是估计所需的样本量,以准确推断我们的两个 KPI。这部分被称为功效分析。功效分析 允许我们在给定以下三个量的情况下估计所需的样本量:

  1. 效应大小

  2. 显著性水平 = P(I 型错误)= 发现实际上不存在的效应的概率

  3. 功效 = 1 — P(II 型错误)= 发现实际上存在的效应的概率

我们将显著性水平设定为 5%,功效设定为 80%(我们将在第二部分中详细讨论这些概念)。然后我们只需要计算效应量来获得所需的样本量。幸运的是,Cohen 1988 为我们提供了在比较两个均值时计算效应量的公式(我还添加了比例的公式,因为它是一个常选的 KPI,例如付款率等)。

Cohen 1988 提供的效应量公式 [作者提供的图片]

但我们仍未脱离困境。我们需要找出当前版本和新版本的均值及其标准差。由于我们不知道我们的 KPI 在未来会如何表现,我们可以查看历史数据以找到这些数字(作为我们对测试上线时期望结果的最佳估计)。因此,我们将回溯两个月,假设我们当时开始了实验。然后我们将计算 28 天 ARPV 和 28 天 ATPV。这为 20000 名访问者提供了数据(这些用户至少在测试中待了 28 天)。

##########################################
# Load Libraries
##########################################
library("ggplot2")
library("dplyr")
library("scales")
library("patchwork")

#############
# ARPV
#############
# Plot
revenue_plot <- 
  dataset %>%
  ggplot(aes(revenue)) +                          
  geom_histogram(fill ="turquoise3", colour = "white", binwidth = 2, boundary = 0) +
  scale_x_continuous(breaks = seq(0, max(dataset$revenue), 14) ) +
  ylab("No of Visitors") +
  xlab("28-day Revenue (each bar is £2)") +
  ggtitle("Histogram of 28-day Revenue") +
  theme_classic()

# Statistics
dataset %>% select(revenue) %>% summary()
dataset %>% summarise(sqr_rt = sd(revenue))

#############
# ATPV
#############
# Plot
transactions_plot <- 
  dataset %>%
  ggplot(aes(x = transactions)) +                          
  geom_bar(fill ="turquoise3", colour = "white") +
  scale_x_continuous(breaks = seq(0, max(dataset$transactions), 1) ) +
  ylab("No of Visitors") +
  xlab("28-day Transactions") +
  ggtitle("Histogram of 28-day Transactions") +
  theme_classic()

# Statistics
dataset %>% select(transactions) %>% summary()
dataset %>% summarise(sqr_rt = sd(transactions))

#################
# Output plot
#################
revenue_plot + transactions_plot

历史收入和交易的直方图 [作者提供的图片]

从这些数据中,我们可以初步了解我们两个 KPI 的分布——从上述图表中可以看出,一半的用户(10000 人)在 28 天窗口期内没有进行任何购买(没有收入和交易)。我们还可以计算当前版本的均值(ARPV 和 ATPV)以及效应量公式的标准差。然而,我们仍然缺少新版本的均值数据。由于我们没有关于新版本表现的数据,这一点尚不可知。不过,我们可以声明我们感兴趣的最小可检测效应(MDE),在我们的情况下为 5%的差异。然后我们可以计算新版本的均值为当前版本增加 5%。

##########################################
# Load Libraries
##########################################
library("pwr")

##########################################
# Cohen's power for ARPV
##########################################
std_arpv <- dataset %>% summarise(std = sd(revenue))
arpv_current_vers <- dataset %>% summarise(avg = mean(revenue))
arpv_new_vers <- arpv_current_vers * 1.05
effect_size_arpv <- as.numeric(abs(arpv_current_vers - arpv_new_vers)/std_arpv)

pwr_results_arpv <- pwr.t.test(
  d = effect_size_arpv, 
  sig.level = 0.05, 
  power = 0.8, 
  type = c("two.sample")
  )
plot(pwr_results_arpv)
pwr_results_arpv

##########################################
#Cohen's power for ATPV
##########################################
std_atpv <- dataset %>% summarise(std = sd(transactions))
atpv_current_vers <- dataset %>% summarise(avg = mean(transactions))
atpv_new_vers <- atpv_current_vers * 1.05
effect_size_atpv <- as.numeric(abs(atpv_current_vers - atpv_new_vers)/std_atpv)

pwr_results_atpv <- pwr.t.test(
  d = effect_size_atpv, 
  sig.level = 0.05, 
  power = 0.8, 
  type = c("two.sample")
  )
plot(pwr_results_atpv)
pwr_results_atpv

ARPV的功效图 [作者提供的图片]

ATPV的功效图 [作者提供的图片]

从上述内容来看,我们估算 ARPV 和 ATPV 的样本量分别为 6464 和 7279。这些估算指的是控制组和处理组的样本量,因此总共我们需要大约 14000 名访问者的样本。

好奇的读者可能已经注意到,功效计算是基于我们将使用双样本 t 检验进行分析的假设,并向后推导,以给出对于给定效应大小、显著水平和功效所需要的样本量。但该技术有一些假设。特别是,它假设我们的数据大致遵循正态分布(即大致对称且围绕平均值中心)。通过观察直方图,可以清楚地看到营收和交易数据明显不同。这可能仍然可以,因为中心极限定理。我们将在第二部分详细介绍 CLT,但一般来说,具有足够样本量时,违背正态分布并不会导致问题(数据越倾斜和非对称,我们需要的样本量越大)。尽管如此,我还想估计无需假设即可估计所需样本量的方法,即使用非参数方法。

另一种方法是使用历史数据并生成给定大小的 2000 个样本。因此,我们可以从 20000 个观察值中模拟出 100 个大小的 2000 个随机样本。在这些样本中的每一个中,我们然后可以随机将一半用户分配到对照组,另一半用户分配到实验组,并计算指标之间的差异。最后,我们可以在 ARPV 和 ATPV 的差异的 2000 个 95%区间(从第 0.025 到第 0.975 分位数)中可视化,并了解 KPI 的可变性。通过尝试不同的样本量,我们可以找到我们的 MDE 所需的样本量。因此,让我们创建我们将用于模拟样本的函数。

##########################################
# Load Libraries
##########################################
library("caret")

##########################################
# Function for Simulation
##########################################
simulating_sample_size <-
  function(dataset, iterations, sample_sizes_vector, kpi) {

    n <- iterations
    output_df <- data.frame(NULL)

    for (j in sample_sizes_vector) {
      # create 2,000 samples for sample size j
      sampling_df <- data.frame(NULL)
      for (i in 1:n) {
        sampling_temporary <-
          data.frame(kpi = sample(dataset[[kpi]], j, replace = TRUE))
        trainIndex <-
          createDataPartition(
            sampling_temporary$kpi,
            p = 0.5,
            list = FALSE,
            times = 1
          )
        ## split into control and treatment
        sampling_df[i, 1] <- mean(sampling_temporary[trainIndex,])
        sampling_df[i, 2] <- mean(sampling_temporary[-trainIndex,])
        }

      # compute aggregates for sample size j
      # and union with old entries
      output_df <- output_df %>%
        union_all(
          .,
          sampling_df %>%
            mutate(diff = round((V2 - V1) / V1, 2)) %>%
            summarize(
              trim_0.05_diff = round(quantile(diff, c(0.025)),2),
              trim_0.95_diff = round(quantile(diff, c(0.975)),2),
              mean_0.05_abs = round(mean(V1),2),
              mean_0.95_abs = round(mean(V2),2)
            ) %>%
            mutate(iter = j)
        )
    }

    return(output_df)
}

我们现在可以使用我们的函数从我们的历史数据中生成给定大小的样本。我们将使用 500、1000、2000、3000、4000、10000、15000 和 20000 的样本量,并生成每个大小的 2000 个样本。

##########################################
# ARPV simulation
##########################################
simulation_arpv <- 
  simulating_sample_size (
    dataset = dataset,
    iterations = 2000,
    sample_sizes_vector = c(500,1000,2000,3000,4000, 10000, 15000, 20000),
    kpi = "revenue"
)

##########################################
# ATPV simulation
##########################################
simulation_atpv <- 
  simulating_sample_size (
    dataset = dataset,
    iterations = 2000,
    sample_sizes_vector = c(500,1000,2000,3000,4000, 10000, 15000, 20000),
    kpi = "transactions"
)
##########################################
# Plot ARPV from simulations
##########################################
arpv_sim_plot <- simulation_arpv %>%  
  ggplot(aes(x = as.factor(iter), y = trim_0.05_diff )) +                          
  geom_col(aes(y = trim_0.05_diff ), fill="turquoise3", alpha=0.9,width = 0.5) +
  geom_text(aes(label = scales::percent(trim_0.05_diff)), vjust = -0.5, size = 5) +
  geom_col(aes(y = trim_0.95_diff ), fill="turquoise3", alpha=0.9,width = 0.5) +
  geom_text(
    aes(x = as.factor(iter), y = trim_0.95_diff,  label = scales::percent(trim_0.95_diff)),
    vjust = -0.5, size = 5
  ) +
  scale_y_continuous(labels = scales::percent) +
  ylab("% Difference in ARPV") +
  xlab("Sample size") +
  theme_classic() +
  geom_hline(yintercept= 0, linetype="dashed", color = "red")

##########################################
# Plot ATPV from simulations
##########################################
atpv_sim_plot <- simulation_atpv %>%  
  ggplot(aes(x = as.factor(iter), y = trim_0.05_diff )) +                          
  geom_col(aes(y = trim_0.05_diff ), fill="turquoise3", alpha=0.9,width = 0.5) +
  geom_text(aes(label = scales::percent(trim_0.05_diff)), vjust = -0.5, size = 5) +
  geom_col(aes(y = trim_0.95_diff ), fill="turquoise3", alpha=0.9,width = 0.5) +
  geom_text(
    aes(x = as.factor(iter), y = trim_0.95_diff,  label = scales::percent(trim_0.95_diff)),
    vjust = -0.5, size = 5
  ) +
  scale_y_continuous(labels = scales::percent) +
  ylab("% Difference in ATPV") +
  xlab("Sample size") +
  theme_classic() +
  geom_hline(yintercept= 0, linetype="dashed", color = "red")

#################
# Output plot
#################
 (arpv_sim_plot + coord_flip()) + (atpv_sim_plot + coord_flip())

模拟不同大小的 2000 个样本中的指标变化[作者提供的图片]

上述结果与我们的功效分析的结果相吻合。看一个样本量为 15000,两个 KPI 的 95%区间在-2%和 2%变化之间。所以如果我们取一个 15000 的样本,并将 7500 分配给对照组和实验组,我们期望在没有差异的情况下,具有四个百分点的变异性(从-2%到 2%)。因此,如果新版本的提升为 5%,我们预计 15000 个样本会返回 3%至 7%的结果(5%-2% = 3%,5% + 2% = 7%)。

摘要

通过最后一步,我们已经准备好启动我们的RCT 实验了!让我们总结一下我们的现状:

✅ 我们定义了测试的两个版本

✅ 我们将人口定义为星期五的所有访问者

✅ 一旦访问者进入测试,他们将被随机分成对照组和实验组(50% — 50%)

✅ 我们定义了我们感兴趣的两个 KPI:28 天 ARPV 和 28 天 ATPV

✅ 我们使用功效分析和模拟估算了实验的样本量为 15000(对照组和处理组各 7500)。

在本系列的下一篇文章中,我们将深入探讨如何分析 A/B 测试的结果。如果你想自己动手操作数据,可以查看下面我用来生成 20000 个观察值的数据集的代码。

set.seed(15)

##########################################
# Create normal skewed ARPV attribute
##########################################
sigma = 0.6
mu = 2
delta = 1
samples = 10000
revenue <- rnorm(samples, rlnorm(samples, mu, sigma) , delta)
revenue <- revenue + 40

##########################################
# Create normal symmetric ATPV attribute
##########################################
transactions <- round(rnorm(10000, 2, 0.5),0)

##########################################
# Create data set with both attributes
##########################################
dataset <- 
  data.frame(revenue, transactions) %>%
  # fixing records with 0 or negative atpv but positive arpv
  mutate(transactions = case_when(transactions <= 0 & revenue > 0 ~ 1 , TRUE ~ transactions)) %>%
  # adding non purchasing visitors
  union_all(., data.frame(revenue = rep(0,10000), transactions = rep(0,10000)))

summary(dataset)

保持联系

如果你喜欢阅读这篇文章并想了解更多,不要忘记订阅以便直接将我的故事发送到你的收件箱。

在下面的链接中,你还可以找到一个免费的 PDF 指南,讲解如何在实际业务场景中使用数据科学技术和最佳实践在 R 中完成客户集群分析。

## 数据科学项目清单 - 渴望成为数据科学家

我是一名拥有 7 年以上分析经验的数据科学家,目前在英国伦敦的一家游戏公司工作。我的……

www.aspiringdatascientist.net

我作为数据科学家在进行了一年的 AB 测试后学到的东西——第二部分/2

原文:towardsdatascience.com/what-i-learned-after-running-ab-tests-for-one-year-as-a-data-scientist-part-2-2-4b30118fec26?source=collection_archive---------9-----------------------#2023-01-11

关于数据科学家如何处理和分析 AB 测试结果的真实案例研究

Alex VamvakarisTowards Data Science Alex Vamvakaris

·

关注 发布于 Towards Data Science ·10 分钟阅读·2023 年 1 月 11 日

--

图片由 Luca Bravo 提供,来源于 Unsplash

介绍

欢迎来到本系列的第二部分也是最后一部分!在 第一部分 中,我们讨论了实验设计和样本大小估算。在本部分中,我们将重点关注分析 AB 测试所需的知识和技能。这是数据科学家在业务中提供价值的核心。我们不再根据主观信念做决策,而是依靠数据和统计测试来引导公司朝着正确的方向前进。

第二部分

  • 理解基础知识: 制定测试假设并探索 I 型和 II 型错误

  • 探索性数据分析(EDA): 招募进入测试、时间趋势和 KPI 的分布

  • 分析 AB 测试结果: 解释中心极限定理、p 值、置信区间,并进行参数和非参数自助法

我们将继续使用第一部分的案例研究。你可以在下面的链接中探索 AB 测试的两个版本和 KPI 的选择 👇

## 我作为数据科学家运行 AB 测试一年后学到的东西 — 第 1/2 部分

通过以下这些简单步骤,像数据科学家一样设置你的 A/B 测试

towardsdatascience.com

1. 理解基础知识

图片由 Stefan Steinbauer 提供,来源于 Unsplash

制定假设

在每个统计测试中,都有一个初始假设替代假设。初始假设认为我们的两个 KPI 在控制组(£10 折扣)和处理组(20%折扣)之间没有差异,而替代假设认为存在显著差异。初始假设通常被称为零假设,因为它代表了默认或“正常”的状态(即没有差异)。

为我们的两个 KPI 制定初始假设和替代假设 [作者提供的图片]

数据科学面试中的一个棘手问题是如何表达你在这些假设中的目标。我们要么拒绝初始假设,要么无法拒绝初始假设。我们永远不能接受它。至于你如何向利益相关者传达结果,这不会有什么不同。但是对于数据科学家来说,这将有所不同!

让我们看看黑天鹅的例子。想象一个世界,我们只见过白天鹅。我们永远无法接受初始假设,即没有黑天鹅。我们可以收集无限的数据,但仍可能错过那只黑天鹅。因此,我们可以未能拒绝假设所有天鹅都是白色的但永远无法接受它!另一方面,如果我们看到一只黑天鹅,我们总是可以拒绝初始假设。现在,虽然黑天鹅代表罕见事件,我们在商业场景中几乎不会尝试测量(最小可检测效应,MDE,通常设为 2%),但这仍然是理解我们如何作为数据科学家进行 AB 测试的一个有用方式。

类型 I 和类型 II 错误

好吧,我们有了初始假设和备择假设,我们可以拒绝或未能拒绝初始假设。这会转化为下表中所示的四种可能性。

类型 I 和类型 II 错误 [作者提供的图片]

使用我们从实验中收集的数据,我们将要么接受(你看,我说的没错,记住是未能拒绝),要么拒绝零假设。但没有任何方法论是完美的,也就是说,不可能完全消除假阳性和假阴性(如上图中的红色框)。用 Neyman 和 Pearson(1933 年)的话说:

我们倾向于认为,就某个特定假设而言,基于概率理论的任何测试本身都无法提供关于该假设真伪的有价值证据

这听起来不太有希望,对吧?幸运的是,他们继续补充道:

但我们可以从另一个角度来看待测试的目的。我们不必希望知道每个独立假设的真伪,而可以寻找规则来指导我们对这些假设的行为,从而确保在长期经验中,我们不会过于频繁地犯错

上述内容是一个重要的理解点。在统计学中,我们不处理确定性。我们永远无法以 100%确定性做出推断。然而,我们拥有统计工具(如 p 值和置信区间,稍后会详细介绍),可以帮助我们做出决策。决策或规则,如果你愿意说是规则,长期来看会给我们一定的(可接受的)类型 I 或类型 II 错误概率。

类型 I 错误

  • 当我们得出存在差异的结论,即使实际上不存在时,这种情况就会发生。换句话说,即使零假设为真,我们仍然拒绝它。

  • 这种错误的概率称为测试的显著性水平,用希腊字母α表示。测试的显著性水平通常设置为 5%。

类型 II 错误

  • 当我们得出没有差异的结论,即使实际上存在差异时,这种情况就会发生。换句话说,即使零假设是错误的,我们仍未能拒绝它。

  • 这种错误的概率用希腊字母 β 表示。该概率的补充概率 (1 — β) 称为测试的 效能,通常设定为 80%

2. 探索性数据分析(EDA)

照片由 Scott Webb 提供,来源于 Unsplash

尽管所有主要框架中都包含这一部分,但这是最常被匆忙完成或完全跳过的步骤。然而,进行 EDA 确实有实际好处,因为它回答了我们在开始分析结果之前需要知道的重要问题。

测试中的招募

在这一部分,我们只是想检查是否在控制组和处理组之间分配访客时没有出现问题:

  • 招募仅发生在我们预定的星期五,控制组和处理组的访客招募量相同

  • 大多数访客在第一次星期五进入测试,然后招募数量下降。这是一个众所周知的趋势。最活跃的(现有)访客会立即被招募,然后在两到三周后,我们将主要招募新访客

按变体划分的测试访客招募 [作者提供的图片]

时间序列

接下来,我们想检查一下我们关注的关键绩效指标(KPI)是否存在任何趋势或季节性变化。让我们看下面的图表,它展示了平均每日收入(作为 28 天 ARPV 的代理):

  • 两个版本之间没有测试前的差异。如果两个版本在测试开始前的几周有所不同,我们需要调整测试期内的 KPI,以纠正任何测试前的偏差

  • 该指标波动性不大(日常波动不极端)

  • 自从我们启动测试以来,每个星期五处理组的表现都高于控制组(明显的峰值)。随着时间的推移,提升效果在增加(最后两个星期五的提升效果最高)

平均每日收入的时间序列 [作者提供的图片]

分布

最后,我们想检查控制组和处理组的分布情况:

  • 查看收入,没有极端异常值

  • 我们可以清楚地看到处理组收入的第三个峰值(在£70 到£90 之间)。第一个峰值为£0,第二个为£50

  • 处理组的 ARPV 比控制组高 19%(上涨了£4.70,£29.2–£24.5)

  • 查看 ATPV,处理组也有明显的提升(更多访客进行 3 或 4 次交易)

按变体划分的 ARPV 和 ATPV 分布 [作者提供的图片]

3. 分析 AB 测试结果

图片由 Tim Stief 提供,来源于 Unsplash

正如你可以想象的那样,如果我们取了相同大小的不同样本,我们会观察到不同的统计数据(ARPV 和 ATPV)。这意味着(样本)统计量是一个随机变量。像其他随机变量一样,统计量有一个称为抽样分布的分布。你可以把抽样分布看作是所有可能的统计量值的总体,如果我们从一个大小为 N 的总体中耗尽地抽取所有可能的大小为 n 的样本,并计算每一个样本的统计量。让我们看看抽样分布和自助法如何帮助我们分析 AB 测试的结果。

为什么要使用自助法?

让我们从大多数数据科学面试中的“英雄”——p 值开始。简而言之,p 值是指收集到数据后,让我们相信存在差异的概率,即使实际上没有差异。p 值越低,差异在统计上越显著。这是因为如果实际上没有差异,那么观察到给定的数据集将会更加不可能(仅仅由于运气)。如果 p 值低于我们可接受的统计显著性水平(p 值 < α),我们就会拒绝原假设。

如果你可以将结果写成置信区间而不是 p 值,你应该这样做

置信区间(CIs)可以回答与 p 值相同的问题,其优点在于它们提供了更多的信息,并且更容易解释。如果你想测试两个版本是否具有统计学上的差异,你可以构建一个 95% 的置信区间(1-a%)来查看它们的差异,并检查该区间是否包含零。在这个过程中,你还会额外获得关于你的估计值有多精确的洞察(区间越宽,表示不确定性越高)。

自助法是一种估计统计量抽样分布并计算置信区间的方法

普通自助法,也称为简单自助法,是这种方法的基本版本,也是我们在分析中将使用的方法。它涉及对与原始样本大小相同的样本进行重复抽取(有放回),并计算每一个样本的感兴趣的统计量。然后,我们可以使用所有这些不同的样本(及其相应的统计量)来计算一个 95% 的置信区间。这可以是基于百分位数的非参数方法(在 0.025 和 0.975 百分位之间),或者我们可以采用参数方法计算正态置信区间。我们将两者都进行。

使用自助法置信区间分析 AB 结果

对于我们的目的,我们将使用 boot 包。首先,我们需要创建以下输入:

  • 我们将在 boot 函数中使用的数据集(见下图)

  • 计算每个样本中统计量百分比差异的函数

##########################################
# Create bootstrap datasets
##########################################
boot_revenue <- data.frame(
    dataset %>% 
    filter(variant == "Treatment") %>% 
    select(revenue_treat = revenue_test),
    dataset %>% 
    filter(variant == "Control") %>% 
    select(revenue_contr = revenue_test)
  )

boot_transactions <- data.frame(
    dataset %>% 
    filter(variant == "Treatment") %>% 
    select(transactions_treat = transactions_test),
    dataset %>% 
    filter(variant == "Control") %>% 
    select(transactions_contr = transactions_test)
  )

##########################################
# Create function for bootstrap
##########################################
diff.means <- function(d, i) {    
  results <- 
    (mean(d[i,1]) - mean(d[i,2])) / mean(d[i,2])
  results
}

自助法输入数据集概述 [作者提供的图片]

我们将进行 2000 次取样,并分别计算对照组和治疗组之间的 ARPV 和 ATPV 百分比差异的 95%置信区间(使用boot.ci函数,以 boot 函数的结果作为输入)。

##########################################
# Run bootstrap for ARPV
##########################################
boot_results_revenue <- boot(boot_revenue, diff.means, R = 2000)
plot(boot_results_revenue)
boot.ci(
  boot_results_revenue, 
  type = c("norm", "basic", "perc"))

##########################################
# Run bootstrap for ATPV
##########################################
boot_results_transactions <- boot(boot_transactions, diff.means, R = 2000)
plot(boot_results_transactions)
boot.ci(
  boot_results_transactions, 
  type = c("norm", "basic", "perc"))

普通自助法的置信区间 [作者提供的图片]

那么我们来解读结果:

  • 治疗组和对照组之间 ARPV 百分比差异的 95%置信区间在 17.7%和 20.6%之间,支持治疗组

  • 治疗组和对照组之间的 ATPV 百分比差异的 95%置信区间在 14.7%和 18%之间,支持治疗组

  • 两者差异显著,因为 95%区间远离零

如果你在想为什么正常的 95%置信区间如此接近非参数百分位区间,有一个非常著名的定理可以提供一些见解。

根据中心极限定理,给定来自总体的足够大样本量,样本均值的(抽样)分布将近似正态

当基础分布为正态时,中心极限定理自动适用于均值。不过在其他所有情况下会发生什么呢?好吧,偏离正态分布越远,我们需要的样本量就越大。boot 函数提供了一个很好的图来检查你的统计量的抽样分布,你可以在下图中看到我们的 ARPV 百分比差异的抽样分布。这两个图都表明抽样分布近似正态,这也解释了为什么非参数置信区间和正态置信区间几乎相同。

从普通自助法检查正态性假设 [作者提供的图片]

总结

到此,我们成功完成了 AB 测试!🚀🚀

✅ 我们解释了基本概念,如 I 型和 II 型错误、p 值、置信区间和中心极限定理

✅ 我们运行了 AB 测试的 EDA 检查表

✅ 我们使用参数和非参数自助法置信区间分析了实验结果

我希望上述内容对你获得你的第一个数据科学工作目标有所帮助。我试图涵盖你在数据科学面试中需要的理论,并且还教给你像数据科学家一样运行和分析你自己的实验的技能!

保持联系!

如果你喜欢阅读这篇文章并想了解更多,不要忘记订阅以便直接将我的故事发送到你的收件箱。

在下面的链接中,你还可以找到一个免费的 PDF 指南,介绍如何在真实的商业场景中使用数据科学技术和最佳实践来完成客户聚类分析。👇

## 数据科学项目检查清单 - 有志数据科学家

我是一名拥有 7 年以上分析经验的数据科学家,目前在英国伦敦的一家游戏公司工作。我的……

www.aspiringdatascientist.net

成为高效的机器学习团队领导

原文:towardsdatascience.com/what-i-learned-from-the-best-and-the-worst-machine-learning-team-leads-c9331f56da4d?source=collection_archive---------4-----------------------#2023-02-06

我从最优秀和最差的机器学习团队领导那里学到了什么

管理沟通、基础设施和文档

Aliaksei MikhailiukTowards Data Science Aliaksei Mikhailiuk

·

关注 发表在 Towards Data Science ·12 min read·2023 年 2 月 6 日

--

作者提供的图片。

软件工程项目的技术管理已经非常成熟,团队领导可以使用多种工具和技术,如敏捷方法。然而,机器学习项目由于准确预测时间线、任务结果和任务可行性等方面的挑战,难以融入这些模式。

在每一步都面临高不确定性的项目需要机器学习团队负责人通过经验获得的技能和知识。在这篇文章中,我将总结我作为团队成员在良好和不良管理下的学习经验,以及我自己领导机器学习项目所获得的经验。

虽然文章重点关注管理机器学习项目的具体技术,但某些通用的项目管理方面特别重要,因此我也将强调这些方面。

首先,我谈论为何管理机器学习项目可能具有挑战性。然后,我讨论了如何通过改进沟通、更好地管理基础设施和文档来克服这些挑战。

领导机器学习项目的挑战

虽然软件工程和机器学习项目有很多相似之处,但由于若干原因,领导机器学习项目可能会有所不同:

  • 机器学习项目通常承担更高的风险。与软件项目不同,软件项目的任务是从确定性的模块中构建系统,而机器学习项目所处理的问题的可行性通常事先未知——我们是否会有足够的数据,数据是否具有合理的质量,模型是否足够大以捕捉关系,我们是否拥有足够的计算能力?

  • 设定截止日期、里程碑和计划更加困难。由于该领域仍在建立中,并且没有现成的解决方案来解决每一个问题,机器学习模型需要从头开始构建。因此,机器学习项目最终变成了以研究为导向的项目。对于这些项目,预测时间框架可能很困难,因为许多决策只能在某个阶段完成后才可以做出。

  • 缺乏性能指标使得跟踪和评估性能变得具有挑战性。有些问题有明确的目标——例如,评估一个垃圾邮件过滤器,我们可以客观地告诉它过滤了 99%的垃圾邮件,而对于更主观的问题,定义性能指标则更加困难。例如,考虑一个美化过滤器——我们如何在没有用户研究的情况下衡量它是否表现良好?而从用户那里获得足够的可靠数据往往是昂贵、缓慢且具有挑战性的,尤其是在严格的 GDPR 要求下。

  • 多学科项目非常常见。因此,团队成员往往会有非常狭窄的专业化方向,为了使项目进展顺利,团队内的沟通流动需要非常出色。

上述许多困难可以通过关注机器学习项目中重要的方面——沟通、基础设施和文档来克服。

沟通

软件工程团队通常不会为会议准备演示文稿。然而,机器学习项目则更常见——许多组件通过图表来沟通更为方便——如损失函数、数据分布、生成结果中的伪影等。

可视化有助于建立沟通技能,让每个人对自己的工作负责,促进信息共享,并鼓励团队其他成员提供反馈,因为在询问澄清时,指向幻灯片会更方便。

机器学习项目通常是跨学科的,当材料没有很好地传达时,保持所有人参与是困难的。为了保持注意力,重要的是从高层次的视角开始,并始终以简单的术语解释事物。

实用注意事项

  • 准时开始和结束。考虑在开始时留出几分钟让大家加入并聊天,以调整会议气氛。开场小聊不会占用太多技术讨论时间,但会提升团队士气。

  • 给人们时间聚集,解除静音并开始发言。询问是否有问题后,心里默数到十。

  • 一致性和以身作则。如果你把某事视为规则,就去实践它。要求团队展示?树立标准。

  • 如果不确定要点是否已经传达清楚,可以让团队成员讲解任务并识别潜在挑战。

  • 没有得到反馈?也许问题表述不够清晰。不要问“当前方法是否有问题或疑问?”,要更具体,让大家参与解决方案的制定,可以改成“有什么更好的方法来加载数据?”。

  • 公开表扬,私下批评——这是永恒的经典。想要鼓励某种行为模式?在小组会议上奖励它。例如,许多人对提问感到不安。但提出问题和指出问题是重要的——有人在一周中的小组聊天中提出了问题?小组会议是感谢他们的好时机。关于如何给予反馈的好书是“Radical Candor” by Kim Scott。

  • 不要试图同时做工程和管理。如果你在领导项目,就要领导和管理。委派任务。鉴于每个机器学习团队成员的专业性,微观管理不仅会让团队恼火,还会损害结果。

  • 团队成员需要知道他们所做的工作为何重要。让团队参与任务形成和优先级排序的过程,大多数团队成员都是领域专家。如果决定如何进行是来自团队的,那么委派任务会更容易——你的角色则转变为协调。

  • 诚实有助于建立你与团队成员之间的信任。如果你不理解某些事情,要诚实面对。如果你看到任务不是很有趣但却必要,不要试图美化它,而要如实解释。诚实会受到赞赏。

  • 在编辑或分享团队成员的工作之前,一定要征得他们的许可。

  • 每个人的优先级、期望和担忧都不同。了解一个人对工作的期望将有助于团队领导为其分配合适的任务。

  • 除非你了解对方,否则要小心假设他们的需求。在分配任务时随口提到“这对你的简历有好处”,可能会被视为廉价的操控。

基础设施

机器学习是一个系统化不可避免的领域。决策的质量取决于数据、代码和结果的组织方式。

然而,由于最终模型的各个方面——数据、架构和超参数之间的复杂关系,系统化也是非常具有挑战性的。此外,每个实验都会生成大量数据,并且由于项目是以研究为导向的,每个模块都可能频繁变化。

在提供反馈或指导团队构建代码或准备数据时——问问自己一个问题,新加入团队的人是否容易理解发生了什么?如果答案是否定的,你需要重新考虑这个过程。

基础设施

有趣的是,项目管理的一个优秀来源是战争书籍,例如,孙子所著的《孙子兵法》。书中分享的智慧之一是,战斗的命运在开始之前就已决定——准备最充分的人赢得胜利。

战斗中最重要的方面之一是补给线。基础设施就像补给线——为了让项目不断发展,基础设施不能有突发的中断或障碍,而且应该易于使用和扩展。

我目前遇到的数据和基础设施管理的最佳实践包括:

  • 为训练准备配置文件并记录它们。这将有助于可重复性,使你可以回溯查看解决方案的获得方式,并减少设置实验时的错误。

  • 为训练数据准备配置文件。这可以简单到模型的输入-输出对列表。这将帮助确保你确切知道模型使用了哪些数据,并简化数据加载器。

  • 对于参数使用合理的默认值——运行代码的人会期望它开箱即用,不需要深入挖掘。如果需要几个超参数,拥有一个执行命令的 bash 脚本会很方便,因为它比终端中的文本更易于修改。

  • 如果资源允许,部署的可自动化部分必须自动化。自动化通过消除重复工作节省团队时间,并防止错误发生。

  • 训练数据的组织方式对数据加载、训练速度、灵活性和分析结果的便利性有重大影响。确保数据按类型分开存储,不要将所有内容放在一个文件夹中——这样可以更方便地可视化现有数据并添加新数据。

  • 训练和测试管道必须尽可能相似——在数据预处理、后处理和模型加载的方式上。

模型跟踪

团队中的多个成员在同一个模型的不同部分工作时,我们需要比较所有结果。为每个团队成员提供一个本地 tensorboard 会非常低效。同时,将所有实验堆积在同一个文件夹中会非常麻烦。

有一些强大的替代工具可以用来分析模型性能,比如wandb(对于小团队可能是免费的)和aimstack(在撰写时完全免费)。

模型比较

机器学习项目会生成大量需要比较的模型。然而,在隔离的开发环境中运行测试以验证性能是不够的。为了突出潜在问题,测试和比较必须尽快作为完整管道的一部分在专用推理设备上进行。

拥有一个专门的测试数据集,最好能反映最终产品场景,并包含尽可能多的边缘案例,以帮助识别最终模型的潜在问题。例如,人类检测的计算机视觉问题应包括具有各种体型、肤色和肤质的多样化人群。

比较结果时,始终要有基准。最好在项目开始时设定一个基准。始终拥有反映生产所需模型属性的明确指标。可以是数学指标或产品试点结果中的用户数据数字。

跟踪模型的构建过程以及哪些方面对模型性能的提升至关重要。文档化——例如一个包含链接到演示、代码和评论的排名表,是一个好的起点。

代码管理

在进行多个实验时,分支爆炸问题不可避免。我看到过一些项目有 500 多个 GitHub 分支,很明显不可能对所有分支进行跟踪和良好文档记录。

鼓励分支合并和归档,否则很容易迷失方向。鼓励小的提交和 PR——大的提交审查时间长,最终会变得过时。

使用简化和抽象部分代码的框架——例如pytorch-lightning,它为训练代码提供结构,并移除与环境设置相关的部分。

另一个挑战是将实验与代码关联起来。模型是用什么代码训练的?是否容易追溯?有一个解决方案 — 要么保持一个文档齐全的项目,要么使用自动化日志记录工具 — MLFlow

文档

文档提供了可重复性、问责制、知识共享、质量和性能控制,以及一种结构化的看待问题的方法。尽管非常重要,但往往被忽视。

一般规则 — 如果一个问题出现超过两次,就需要记录下来。类似地,任何一次性的重要过程也必须记录。例如,数据准备或环境设置。

有几个重要的文档可以显著提高团队成员之间的沟通质量和解决方案的质量:设计文档、路线图和每周笔记。

设计文档

我曾经与我的博士导师在项目的早期阶段坚持开始撰写文章时产生了很多误解。后来在我的职业生涯中,我发现这是一种非常有用的做法。

写下项目的骨架会让你变慢,但会给你更多时间考虑解决方案的每个部分,帮助定义约束条件和指标。关键是消除项目结果中的模糊性。

设计文档解释了项目的来龙去脉并报告结果,并在项目的每个阶段不断演变 — 从项目计划开始,它变成了如何实现最终结果的解释。

在机器学习项目中,失败的实验很常见,虽然这些实验对最终解决方案可能无关紧要,但它们也作为知识的来源,应有一个专门的部分。

不要忘记包含数据 — 使用了哪些数据集以及如何进行清洗。由于在项目之间重复使用数据很常见,详细的部分将有助于未来的项目。

由于文档可能会在后期被某人浏览,或者被具有非技术背景的人阅读,因此总是以简单的术语开始介绍项目的动机和大局。类似于小组会议,视觉化流程 — 例如,建议的流程图将是设计文档的重要部分。

路线图

路线图是项目的逐步计划,包含关键里程碑和实现目标所需采取的步骤。一个好的路线图应包含目标、描述、时间框架、任务负责人以及主要发现和结果链接。

为机器学习任务设置时间框架可能会很困难,因为结果可能不明确 — 例如,将任务设置在一个期望 98%召回率的路线图上是不现实的,因为实验可能会成功也可能不会。相反,任务应该被拆分成小组件,交付物可以是一个代码块或一个数据集。

每周笔记

对于机器学习项目,数据可视化非常重要,因此理想的格式是包含尽可能多的视觉信息和与描述数据相关的代码链接的演示文稿。这些通常存储在共享空间中,每个团队成员可以查看和查找参考资料,而无需打扰负责人。

作为团队领导,会议前有每个人的每周结果/工作的总结是很有用的,因为这样可以在他们的展示中提出有针对性的问题。

实用笔记:

  • 由于需要维护的文档较多,保持一个包含主要文档快捷方式的单一文档并非不合理。

  • 需要接纳新成员,已有入职文档,但请确保你自己从头到尾完成了所有步骤,以免遗漏任何内容。

  • 鼓励团队成员记录已完成的任务,并附上代码和结果的链接——这将帮助他们在绩效评审时回忆起全年所做的工作。

  • 机器学习项目由研究指导。我参与的多数工业项目依赖于使用预训练模型或重新实现论文中的模型。为了有效管理和跟踪前沿进展,并向团队沟通现有工作,一个好的做法是保持一个包含链接的共享文档。

总结

由于团队领导负责项目交付,领导者的一个基本素质是对团队及每个个体成功的长期思考。

将项目视为帮助整个团队及每个团队成员成长的方式。为此,给予每个团队成员自主权,鼓励他们的责任感,主动奖励正确的行为和最佳实践,进行可视化,再可视化,并以身作则。一个很好的 品质列表 可供你在团队中鼓励。

喜欢这位作者?保持联系!

我是否遗漏了什么?请随时留下笔记、评论或直接通过 LinkedInTwitter 联系我!

## 精通机器学习面试

机器学习面试的准备指南和资源。

towardsdatascience.com ## 每个博士生都能免费获得的三种软技能

我在机器学习博士期间学到的关于研究、沟通和团队合作的综合技巧和窍门。

towardsdatascience.com ## 在向你的项目引入 AI 之前要问的七个问题

也就是机器学习的第一规则——不要使用机器学习。

towardsdatascience.com ## 我希望在攻读机器学习博士学位之前掌握的九个工具

无论你是在创建初创公司还是在取得科学突破,这些工具都能将你的机器学习管道提升到…

towardsdatascience.com

本博客中的观点仅代表我个人,并不代表 Snap 公司的立场或观点。

我在担任数据科学总监的第一年学到的东西

原文:towardsdatascience.com/what-i-learned-in-my-first-year-as-a-director-of-data-science-76b79f26b09c?source=collection_archive---------1-----------------------#2023-05-01

关于管理数据科学团队的持续学习和不断进步

CJ SullivanTowards Data Science CJ Sullivan

·

关注 发表在 Towards Data Science · 14 分钟阅读 · 2023 年 5 月 1 日

--

图片由 Brett Jordan 拍摄,来源于 Unsplash

六个月前,我注意到关于如何管理数据科学团队(与数据科学项目相比,后者有更多的内容)的帖子并不多。为了填补这一空白,我写了我的原创文章:“我作为数据科学总监的前六个月所学到的东西。” 这篇文章的反馈总体上是积极的,因此我决定,在我担任数据科学总监满 1 年后,根据接下来的 6 个月的经验更新原文。一些经验教训没有改变,尽管我观察到了一些新的情况或学习到了更多细节。其他的则随着科技界裁员情况的变化而有所改变。有关我自己以及我为什么开始写这些内容的更多背景信息,请参见我的原创文章。

照片由若昂·费拉奥拍摄,发布于Unsplash

招聘仍然是我最大的挑战

当我在 2022 年 11 月写下原文时,科技裁员刚刚开始加速。我开始对招聘市场的变化感到非常乐观。我的管理层也开始对数据科学家的薪资预期和报价的变化感到乐观。

简而言之,这种做法并没有取得预期效果。

我加入了几个旨在帮助被裁员的科技人员寻找新工作的在线论坛。然而,我很快注意到数据科学家和机器学习工程师并没有很多。我还发现我在这些公司的朋友们并没有被裁员。我的(轶事性的)结论是,数据科学家在科技界,包括 FAANG 公司中,仍然有相当程度的工作保障。我发现的那些被裁员的人员很快被其他科技公司录用。因此,在这方面,尽管科技界发生了变化,我的招聘情况在过去 6 个月里并没有改变。

话虽如此,我在招聘数据科学家方面又获得了 6 个月的经验和观察。我认为其中一些经验是值得分享的。

照片由阿诺德·弗朗西斯卡拍摄,发布于Unsplash

面试设计:编码还是不编码?

这是软件行业内一个长期争论的问题。我们招聘的人是为了编写代码,那么我们难道不想看看他们的代码吗?我们是否希望给他们布置类似于我们公司日常工作中的任务?我们是否希望看到他们实时编程?

这是我在当前角色中处理过的事情。我确实重视观察人们编码的方式。我会查看代码及其整体组织结构。候选人是否使用了精心设计的类?函数是否清晰,并包括文档字符串、类型提示和其他有用的调试工具?是否实施了某种测试?整体文档是什么样的?他们是否只是从 scikit-learn 文档中复制粘贴,还是考虑了超参数并超越了文档的示例问题?

是的,这绝对是我可以在家庭编码挑战或实时编码练习中查看的内容。然而,这些是否公平地评估了一个人的能力?作为 IC,我经历过这两者,各有利弊。这些在各种场合中都被讨论过,但我将简要总结一下。

家庭编码挑战或作业假设候选人有时间去完成它们。它没有考虑到他们可能还在 9 到 5 的“日常工作”中,可能还有家庭或其他义务,这些义务不允许他们花费足够的时间来解决挑战。所以你可能会对那些在闲暇时间有育儿职责的在职父母产生偏见。

当然,你可以进行实时编码会话,例如配对编程或令人畏惧的“我们将观看你编码”或白板练习。毕竟,大多数人,包括那些在另一份工作中接受面试的人,通常会抽出一小时进行面试。但是,那些在公司提供的电脑上被监控且没有其他电脑的人怎么办?他们可能不希望老板看到他们在公司资源上做编码挑战。此外,许多人在这样的高压环境下不会发挥最佳水平。而且,实际上,他们是否会在日常工作中处于这样的环境?(旁注:如果你的团队通常在这种高压情况下运作,你也许应该检查一下你为团队创造的文化。)

到头来,我们团队里不会做这些。我们仍然进行技术面试,但这些更多是讨论,而不是编码。

图片由Markus Winkler拍摄,来源于Unsplash

作品集的重要性

尽管如此,我仍希望能看到候选人编写的一些代码或分析。这可能与之前的观点相矛盾。我不需要一个带有华丽格式的个人网页,也不需要将内容部署到 Heroku。一个包含几个经过深思熟虑项目的 GitHub 账号就足够了。你的 GitHub 账号和这些代码应该在你的简历上提供。这些不应是他人仓库的克隆。(每次收到候选人克隆我的仓库的申请时,我总是觉得很有趣。)

再次强调,当你是一个工作中的父母,拥有有限的空闲时间,或者在工作以外没有计算机时,这种系统很难组建。这个系统并不完美。然而,以这种方式查看候选人的代码有一个(尽管是微小的)好处,就是候选人没有时间压力去整理代码。(尽管保持最新的包是个好主意,因为你永远不知道我什么时候会尝试运行你的代码!)

Tim Mossholder 拍摄的照片,来源于 Unsplash

阅读职位广告很重要!

我在之前的帖子中谈论过这个话题,但从那时起,根据申请者的数量和面试情况,我有了几个新的认识。

我们团队有两种不同类型的人:数据科学家和机器学习工程师。这些职位名称是在我加入公司之前创建的,为了保持一致性,我一直努力保持这些名称。然而,如果你在这个领域工作,你会知道这些术语可能会被过度使用。

为了尝试区分这两者,我在广告中(如果我这么说的话!)非常清楚地列出了每个职位的职责。再次说明,按照团队历史上的使用,团队中的数据科学家进行实验和模型创建,通常在笔记本中进行,可能还会有一些基本的 Python 脚本。机器学习工程师则将这些模型转化为生产代码和管道。在一些公司,这些可能被称为“数据工程师”或“MLOps”。在其他公司,机器学习工程师是编写模型的。

在过去的一年里,我学到,尝试招聘人员时使用这些模糊的职位名称时,明确日常职责非常重要。我在职位广告中越具体,匹配度就越高。

尽管如此,这仍然远非完美的解决方案。我常常对大量(我称之为)数据科学家申请(我称之为)机器学习工程师的职位感到惊讶。他们没有阅读职位广告。在数据科学的职位广告中,我已经指定了统计学、建模(传统机器学习、深度学习等)、探索性数据分析等经验。而在机器学习的广告中,我提到了 CI/CD、devops、Terraform 等等。也许我写的职位广告还是不对。根据申请机器学习职位的数据科学家的数量(我估计超过三分之二),问题一定出在我这里。肯定是这样,对吧?

这不仅仅涉及职位描述。包括我所在州在内的某些州有法律要求招聘经理披露职位的薪资范围。正如我们所讨论的,科技公司通常能支付比非科技公司更高的薪资,而我工作的是后者。这并不是说我们的工作问题不令人兴奋或有价值!这只是业务的本质。然而,申请者中有不少人声明他们期望的最低薪资完全超出了我所广告的范围,这一点非常显著。

作为招聘经理,鉴于以上情况,我只能得出结论,候选人没有阅读职位广告。这对候选人和招聘经理来说都很不幸。

图片由 Farzad 提供,来源于 Unsplash

在非科技领域工作的挑战

面对现实吧。我们有时不得不在公司中担任多个角色。然而,如果你在职业生涯中曾在科技公司和非科技公司工作过,你会知道,这在科技领域之外的意义更为重大。

在科技领域,你经常有机会真正专注于某一特定学科。例如,当我为某家雇主担任机器学习工程师时(在我当前的公司中,这意味着“数据科学家”),我开始深入参与图数据科学。这不仅在技术层面上吸引了我,还帮助公司解决了一些挑战。如果你关注过我在 Medium 上的其他文章,你可能已经注意到它们围绕图形展开,以至于我曾去一家图数据库公司工作过一段时间。

在科技行业之外,专业化的模式作为数据科学家变得更为困难。这一差异源于在非科技领域,你的工作是解决业务问题,而不是创造解决这些问题的技术。因此,你需要成为一个通才,而不是专家。

这不仅仅是知道你需要哪些 Python 包,并采用多样化的方式来解决这些问题。例如,我的团队对云基础设施非常熟悉。这是出于必要性。我们没有一支基础设施团队随时准备帮助我们完成这些工作。我们经常需要为公司提供关于这些基础设施的建议。我们不得不自学信息安全。这样做是否理想?不。但这就是非科技公司的人力资源运作方式。

从许多方面来看,这实际上非常有趣!如果你在一个通才角色中工作,你必须不断学习新事物。例如,我不期望我团队中的每个人都完全理解如何为我们的模型创建生产流水线。但每个人都在学习。我喜欢学习新事物。我认为这是数据科学家的一个要求。

图片由 Maklay62 提供,CC0,来自 Wikimedia Commons

管理有限预算

我这里有一个故事。当我在一家无名科技公司工作时,我们使用了一个非常受欢迎的云服务提供商。我的一个同事决定测试一下是否允许他们启动提供商提供的最先进的 GPU 实例,只是为了看看是否存在限制。他们让那个实例运行了一个多月而没有使用它进行计算。总账单达到了几万美元。没有人关心。

我目前角色中的一个责任是监控预算,特别是我们的云基础设施和 CI/CD 管道,我每周都会进行一次监控。我们有一个月度预算(远低于我之前的故事中花费的预算)。当预算设定时相当现实,因此我们通常不需要担心超支,但预算在那儿,我们会进行监控。有时我们会遇到对 CI/CD 运行时分钟数不太了解的人。例如,当我看到使用量激增并且可能超支时,我会要求团队中更资深的成员与那些在有问题的项目上工作的人员合作,以提高资源使用效率。正如我上面所说,每个人都在不断学习。

虽然这适用于我们的计算,但也适用于薪资。我之前提到过,科技行业的薪资通常高于非科技行业。看起来我应该能直接向管理层申请更多的薪资。不幸的是,企业的运作并非如此。我其中一个工作就是为我的团队争取尽可能好的薪资。团队中的另一个工作是保持公司内部薪资的公平一致,以及在更大的预算框架内。有时(总是?)这两者会发生冲突。考虑到数据科学家通常是公司中薪资最高的个体贡献者,去高级管理层争取更多薪资对我来说是个困难的挑战。这就是现实情况。

照片由Jason Goodman拍摄,来自Unsplash

与非技术团队沟通

这是非技术公司面临的最大挑战之一。我的团队必须为业务生成解决方案。这些解决方案的质量如何衡量?一种方式是投资回报率(ROI)。企业的存在是为了赚钱。这是显而易见的。每个人都必须为这个使命做出贡献。那些不贡献的模型是不应该被开发的模型。

但是谁是这些模型的最终使用者?在我这种情况下,通常是营销团队。我愿意承认我不是营销人员。(尽管在我上面关于持续学习的声明之后,我正在回学校读 MBA,以了解营销的工作原理。)营销人员在一个不是数据科学的领域中非常擅长技术。因此,在我当前的角色中,学习如何与他们沟通非常重要。

那可能显而易见,但它真正意味着什么呢?首先,这意味着我不能简单地扔一堆数学和图表过去,尤其是没有解释它们的含义。在我的职业生涯中,我参加过许多数据科学会议,有些事情我在那里说的话不需要思考就能解释清楚。其中一个很好的例子是用于评估模型的各种性能指标。在营销角色中的人通常能理解"准确率"这样的术语。但一提到"精确率/召回率"、"F1 分数"或其他我们认为标准的指标,他们就会一脸茫然地看着我。老实说,这很正常,我们不应该期待他们去拿个统计学学位来理解。我们可能认为他们应该关心,但归根结底,他们希望我们能提供一个好模型。

照片由Cytonn Photography拍摄,来自Unsplash

这种信任的重要性

然而,我工作中真正困难的一部分是向我们的营销团队传达模型不好的消息。希望这是团队自己发现的问题。如果团队错过了,他们发现了,那将是个糟糕的日子。

事实是,他们不会每天深入研究我们拥有的数据(或者更常见的情况是没有的数据)。观察模型的漂移不是他们应该担心的事情。最终,他们必须相信数据科学团队会处理好这些事情。

但是这种信任是如何获得的呢?

沟通是关键!在理想情况下,团队开发的每一个模型都应该是基于一个在数据科学人员动手之前已经广泛讨论过的业务问题。我努力让利益相关者聚在一起,详细说明业务需求。这通常无法在一次会议中完成,需要多次会议。有时,同一个会议需要重复多次,以便能够接触到那些日程安排无法参加原始会议的利益相关者。然后,还需要更多的会议来继续定义问题及解决方案的样子。

如果沟通是关键,那么文档就是钥匙链。我尽量在每次会议结束时总结所决定的内容。这些内容会被记录下来,并放在一个所有人都能访问的公共位置。这个位置在每次会议时都会共享。我在每次会议后都会请求对文档的反馈。我做得对吗?有没有需要修改、评论或问题?(专业提示:电子邮件不是记录这些讨论的好方法。需要放在更容易被发现的地方。)

然而,仍然会有模型表现不佳的情况。也许存在未被发现的 bug。也许没有数据来创建模型。可能是团队发现的,也可能是市场人员发现的。无论如何,信任通过诚实建立。这似乎是显而易见的,但我在职业生涯中见过太多数据科学家因为不想让团队或模型处于不利境地而默默掩盖问题的情况。

市场人员通常不是统计学家。当事情出现问题或他们不理解时,很容易将责任归咎于数学(或创建它的人)。而且,面对现实吧,机器学习的数学很容易被看作是一个黑箱,难以接受或相信。当存在诚实、开放、值得信任的关系时,团队或模型的信任缺失就不容易摧毁一切。

结论

如果我在这个角色的前六个月是适应从技术领域转变和学习数据科学招聘现状,那么我后六个月的工作则是尝试应对各自的挑战。挑战依然存在,我仍在学习。我如何才能让更多优质的候选人入门?我如何在非技术公司内工作,以为我的团队争取最好的资源,确保我们能够完成工作,并找出最有效的时间使用方法?

我每天都在继续学习。

我在推动提示工程极限时的所学

原文:towardsdatascience.com/what-i-learned-pushing-prompt-engineering-to-the-limit-c40f0740641f?source=collection_archive---------0-----------------------#2023-06-12

Jacob Marks, Ph.D.Towards Data Science Jacob Marks, Ph.D.

·

关注 发表在 Towards Data Science ·10 分钟阅读·2023 年 6 月 12 日

--

对提示工程的讽刺描绘。具有讽刺意味的是,DALL-E2 生成的图像是作者使用提示工程生成的,提示为“一个疯狂的科学家把卷轴递给一个人工智能机器人,以复古风格生成”,加上一些变化,以及扩展画布。

我花了过去两个月时间构建一个大型语言模型(LLM)驱动的应用程序。这是一次令人兴奋、智力激发且有时令人沮丧的经历。整个项目过程中,我对提示工程的理解——以及 LLM 的可能性——发生了变化。

我很乐意与你分享一些我最大的收获,旨在揭示一些常被忽视的提示工程方面。我希望在阅读了我的经历后,你能做出更明智的提示工程决策。如果你已经尝试过提示工程,我希望这能帮助你在自己的旅程中更进一步!

为了提供背景,这里是我们将要学习的项目的 TL;DR:

  • 我和我的团队构建了 VoxelGPT,这是一个将 LLM 与 FiftyOne 计算机视觉查询语言结合的应用,旨在通过自然语言在图像和视频数据集中进行搜索。VoxelGPT 还回答有关 FiftyOne 本身的问题。

  • VoxelGPT 是开源的(FiftyOne 也是!)。所有代码都可以在 GitHub 上找到。

  • 你可以在 gpt.fiftyone.ai 免费试用 VoxelGPT。

  • 如果你对我们如何构建 VoxelGPT 感到好奇,可以在 TDS 上阅读更多

现在,我已经将提示工程课程分为四个类别:

  1. 一般经验

  2. 提示技术

  3. 示例

  4. 工具

一般经验

科学?工程?黑魔法?

提示工程既是实验也是工程。从你提问的具体措辞,到你输入的上下文的内容和格式,有无穷无尽的提示写作方式。这可能会让人不知所措。我发现最简单的方法是从简单开始,建立直觉——然后测试假设。

在计算机视觉中,每个数据集都有自己独特的模式、标签类型和类别名称。VoxelGPT 的目标是能够处理 任何 计算机视觉数据集,但我们一开始只用了一个数据集:MS COCO。保持所有额外自由度固定使我们能够集中精力验证 LLM 在写出语法正确的查询方面的能力。

一旦你确定了在有限上下文中成功的公式,就可以找出如何将其概括和扩展。

使用哪个模型?

人们说,大型语言模型最重要的特征之一是它们是相对可互换的。理论上,你应该能够在不显著改变连接结构的情况下,替换一个 LLM 为另一个。

虽然改变你使用的 LLM 通常像更换 API 调用一样简单,但在实际操作中确实会遇到一些困难。

  • 一些模型的上下文长度比其他模型短得多。切换到上下文较短的模型可能需要重大重构。

  • 开源是很棒的,但开源 LLM 的性能(目前)还不如 GPT 模型。而且,如果你要部署一个使用开源 LLM 的应用,你需要确保运行模型的容器有足够的内存和存储。这可能比直接使用 API 端点更麻烦(也更昂贵)。

  • 如果你开始使用 GPT-4 然后因为成本问题切换到 GPT-3.5,你可能会对性能的下降感到震惊。对于复杂的代码生成和推理任务,GPT-4 要好得多。

何时使用 LLM?

大型语言模型是强大的。但仅仅因为它们可能能够完成某些任务,并不意味着你需要——甚至应该——将它们用于这些任务。思考 LLM 的最佳方式是将其视为赋能工具。LLM 不是解决方案的全部:它们只是其中的一部分。不要指望大型语言模型能做所有事情。

举个例子,可能你使用的 LLM 可以(在理想情况下)生成格式正确的 API 调用。但如果你知道 API 调用的结构应是什么样的,并且实际上对填充 API 调用的部分(变量名、条件等)感兴趣,那么只需使用 LLM 来完成这些任务,然后自己使用(经过适当后处理的)LLM 输出生成结构化的 API 调用。这将更便宜、更高效,也更可靠。

拥有 LLM 的完整系统肯定会有大量的连接部分和经典逻辑,以及一系列传统的软件工程和 ML 工程组件。找到最适合你应用的解决方案。

LLMs 有偏见

语言模型既是推理引擎也是知识存储库。通常,LLM 的知识存储库方面对用户非常有吸引力——许多人将 LLM 用作搜索引擎的替代品!到现在,任何使用过 LLM 的人都知道它们容易编造虚假的“事实”——这现象被称为幻觉

然而,有时 LLM 遇到的是相反的问题:它们过于固执于其训练数据中的事实。

在我们的案例中,我们尝试促使 GPT-3.5 确定将用户的自然语言查询转换为有效的 FiftyOne Python 查询所需的适当 ViewStages(逻辑操作的管道)。问题在于 GPT-3.5 了解 MatchFilterLabels ViewStages,这些在 FiftyOne 中存在了一段时间,但其训练数据不包括最近添加的功能,其中 SortBySimilarity ViewStage 可以用来找到与文本提示相似的图像。

我们尝试传入 SortBySimilarity 的定义、使用细节和示例。我们甚至尝试指示 GPT-3.5 绝对不能使用 MatchFilterLabels ViewStages,否则会受到惩罚。不管我们尝试什么,LLM 仍然倾向于其已知的内容,无论是否是正确的选择。我们在与 LLM 的本能作斗争!

我们最终不得不在后处理中处理这个问题。

痛苦的后处理是不可避免的

无论你的示例有多好;无论你的提示有多严格——大型语言模型总会产生幻觉,给出格式错误的响应,当它们无法理解输入信息时,还会发脾气。LLM 最可预测的特性就是其输出的不可预测性。

我花费了大量的时间编写例程来匹配模式并纠正幻觉语法。最终,后处理文件包含了近 1600 行 Python 代码!

这些子例程中有些非常简单,比如添加括号,或在逻辑表达式中将“and”和“or”更改为“&”和“|”。有些子例程则复杂得多,比如验证 LLM 响应中的实体名称,如果满足某些条件,将一个 ViewStage 转换为另一个,确保方法的参数数量和类型有效。

如果你在一个相对封闭的代码生成环境中使用提示工程,我推荐以下方法:

  1. 使用抽象语法树(Python 的ast模块)编写你自己的自定义错误解析器。

  2. 如果结果在语法上无效,将生成的错误消息输入到 LLM 中,让它再试一次。

这种方法未能解决更隐蔽的情况,即语法有效但结果不正确。如果有人对这个问题有好的建议(超出 AutoGPT 和“展示你的工作”风格的方法),请告诉我!

提示技术

人越多越好

为了构建 VoxelGPT,我使用了几乎所有的提示技术:

  • “你是一个专家”

  • “你的任务是”

  • “你必须”

  • “你将会受到惩罚”

  • “以下是规则”

任何这种短语的组合都无法确保某种行为。巧妙的提示是不够的。

话虽如此,你在提示中使用的这些技术越多,就越能将大型语言模型(LLM)引导到正确的方向!

示例 > 文档

现在已经是常识(也是常识!),示例和其他上下文信息如文档可以帮助引导大型语言模型生成更好的响应。我发现 VoxelGPT 确实是这样。

一旦你添加了所有直接相关的示例和文档,如果上下文窗口中还有额外的空间,你应该怎么做?根据我的经验,我发现间接相关的示例比间接相关的文档更重要。

模块化 >> 大一统

你将一个总体问题拆解成更小的子问题的程度越高,效果越好。与其提供数据集模式和端到端示例列表,不如识别单独的选择和推理步骤(选择-推理提示),并在每个步骤中仅提供相关信息。

这有三个优点:

  1. LLM 在一次处理一个任务时表现得比同时处理多个任务更好。

  2. 步骤越小,清理输入和输出就越容易。

  3. 对你作为工程师来说,理解应用逻辑是一个重要的练习。LLM 的目的不是让世界变成黑匣子,而是启用新的工作流程。

例子

我需要多少个例子?

提示工程的一个重要部分是确定你需要多少个例子来完成特定任务。这是高度依赖于问题的。

对于一些任务(有效查询生成根据 FiftyOne 文档回答问题),我们能够做到没有任何例子。而对于其他任务(标签选择聊天记录是否相关标签类命名实体识别),我们只需要几个例子就能完成工作。然而,我们的主要推理任务几乎有 400 个例子(这仍然是整体性能的限制因素),因此我们仅在推理时传入最相关的例子。

当你生成例子时,尝试遵循两个指南:

  1. 尽可能全面。如果你有一个有限的可能性空间,那么尝试为每种情况提供至少一个例子。对于 VoxelGPT,我们至少尝试为每种语法正确的 ViewStage 使用方式提供一个例子——通常每种方式会有几个例子,以便 LLM 进行模式匹配。

  2. 尽可能保持一致。如果你将任务拆分为多个子任务,确保例子在一个任务与下一个任务之间保持一致。你可以重用例子!

合成例子

生成例子是一个繁琐的过程,手工制作的例子只能做到有限程度。事先想到每种可能的情境几乎是不可能的。当你部署应用时,可以记录用户查询,并利用这些查询来改进你的例子集。

然而,在部署之前,你最好的选择可能是生成合成例子。

这里有两种生成合成例子的方式,你可能会发现有用:

  1. 使用 LLM 生成例子。你可以让 LLM 变换语言,甚至模仿潜在用户的风格!虽然这对我们没用,但我相信它对许多应用可能有效。

  2. 基于输入查询中的元素程序性地生成示例——可能带有随机性。对于 VoxelGPT,这意味着基于用户数据集中的字段生成示例。我们正在将其纳入我们的管道中,目前为止看到的结果很有希望。

工具

LangChain

LangChain 之所以受欢迎是有原因的:这个库使得以复杂的方式连接 LLM 的输入和输出变得简单,抽象掉了繁琐的细节。特别是模型和提示模块表现出色。

话虽如此,LangChain 绝对是一个不断进步的项目:他们的记忆、索引和链模块都有显著的限制。这只是我在尝试使用 LangChain 时遇到的一些问题。

  1. 文档加载器和文本拆分器:在 LangChain 中,文档加载器 应将不同文件格式的数据转换为文本,而 文本拆分器 则应将文本拆分成语义上有意义的块。VoxelGPT 通过检索文档中最相关的块并将其传入提示中来回答有关 FiftyOne 文档的问题。为了生成有意义的答案,我不得不有效地构建自定义加载器和拆分器,因为 LangChain 没有提供适当的灵活性。

  2. 向量存储:LangChain 提供了 Vectorstore 集成和基于 Vectorstore 的 检索器,以帮助找到相关信息并纳入 LLM 提示中。这在理论上很棒,但实现缺乏灵活性。我不得不使用 ChromaDB 编写自定义实现,以便预先传递嵌入向量,而不是每次运行应用程序时都重新计算它们。我还不得不编写自定义检索器,以实现所需的自定义预筛选。

  3. 带来源的问答:在构建对 FiftyOne 文档的问答时,我找到了一种合理的解决方案,利用了 LangChain 的 RetrievalQA Chain。当我想添加来源时,我以为只需将该链替换为 LangChain 的 RetrievalQAWithSourcesChain 就可以了。然而,不良的提示技术导致该链表现出一些不幸的行为,例如 关于迈克尔·杰克逊的虚假信息。我再次不得不 自己动手

这意味着什么呢?也许自己构建这些组件更简单!

向量数据库

向量搜索可能正处于 🔥🔥🔥 的热潮中,但这并不意味着你的项目必须使用它。我最初使用 ChromaDB 实现了类似的示例检索程序,但由于我们只有几百个示例,最终我转向了精确的最近邻搜索。我确实需要自己处理所有的元数据过滤,但结果是一个更快的程序,依赖性更少。

TikToken

TikToken 纳入计算是非常简单的。总的来说,TikToken 给项目增加了不到 10 行代码,但使我们在计数令牌和尝试将尽可能多的信息融入上下文长度时变得更加精确。这在工具选择上是唯一的明智选择。

结论

选择的 LLM(大语言模型)有很多,各种新工具琳琅满目,还有一堆“提示工程”技巧。这一切既令人兴奋又可能让人感到不知所措。使用提示工程构建应用程序的关键在于:

  1. 将问题分解;构建解决方案

  2. 将 LLM 视为 赋能工具,而不是端到端的解决方案

  3. 仅在工具能让你的生活更轻松时使用它们

  4. 拥抱实验精神!

去创造一些很酷的东西吧!

我在每个数据分析师候选人身上寻找的特质

原文:towardsdatascience.com/what-i-look-for-in-every-data-analyst-candidate-7d05c52bb19e?source=collection_archive---------5-----------------------#2023-01-03

从招聘经理的角度

Galen OkazakiTowards Data Science Galen Okazaki

·

关注 发表在Towards Data Science ·7 分钟阅读·2023 年 1 月 3 日

--

摄影:由Clem Onojeghuo提供,发布于Unsplash

介绍

我的职业生涯大部分时间都 spent 在数据分析领域。早期,我的工作性质更加技术化,因为我专注于数据仓库的设计和建设。随着时间的推移,我的工作变得不那么技术化,我逐渐倾向于分析的商业方面,最终进入了数据分析管理角色。这条职业道路让我对业务组织中的数据分析师角色有了独特的视角(和欣赏)。我写这篇文章是为了向那些希望将数据分析作为职业或当前是数据分析师并寻求职业发展的人员提供我的观点。尽管有大量的指导材料专注于成为数据分析师的技术方面,但我还未见到从招聘经理的角度发布的有意义的内容。我的希望是,你阅读这篇文章能在成为一名备受追捧的数据分析师的旅程中帮助你。

数据分析师的需求是真实的……而且在增长

准备好让你的思维被颠覆了吗?在 2012 年至 2022 年的十年间,数字宇宙中的数据量增加了 15 倍,从 6.5 泽字节(ZB)增加到 97 ZB,预计在接下来的三年内(到 2025 年底)这一数字将几乎翻倍至 181 ZB! 换成更易理解的术语,一个泽字节等于一万亿千兆字节的数据。随着数字化转型和物联网(IoT)的不断普及,收集的数据量和种类只会继续增长。这一数据爆炸得益于大数据构架的革命性进展,使得所有这些数据能够被捕捉、整理、存储、处理和近乎实时地分析。然而,随着我们生产的数据量的增加,我们从中获得的商业洞察却没有增加。实际上,尽管每年花费数十亿美元来缩小这个差距,但数据收集与洞察收集之间的差距只会继续扩大。这个差距存在的主要原因之一是缺乏合格的人才来完成这些工作。

集中你的技术技能

当我在 2000 年代初开始我的数据分析职业时,数据仓库正当风靡。我的技术工具箱包括关系数据库、数据库设计工具(Erwin)、提取转换加载(ETL)工具、商业智能(BI)工具以及当然的结构化查询语言(SQL)。这是一套直观的工具,学习曲线相对较易。但在今天的数据分析环境中,由于现在存储的数据量以各种不同形式和结构级别存在,需要大量的技能组合和角色来进行分析。这甚至催生了备受追捧的多技能数据科学家角色。

在许多不同的技术技能需求中,潜在的数据分析师如何选择学习哪些技能?虽然选择学习什么不是本文的具体重点,但我要告诉你的是,你应该将有限的时间花在掌握你所选择的技能上。旧谚语“全才不精通”在这里完全适用。根据我的招聘经理经验,许多新进入数据分析领域的人倾向于列出一长串他们有一定了解的技术技能,希望这能给他们带来优势。这是一个错误。

对我来说重要的是你能展示出将你学到的技能用于实际应用的能力。例如,如果你花时间学习了如何用 R 语言编程,我希望了解你如何利用它来回答实际问题,而不仅仅是能列出你可以调用的函数。描述一下你从业务角度想要解决的问题,以及你使用了哪些工具的功能来回答这个问题。能够做到这一点会向我展示两件事。首先,你掌握了技术技能,其次(而且更重要的是),你理解如何在业务背景下使用这些技能。

顺便提一下,许多数据分析师拥有出色的技术技能,但如果没有来自业务的详细指导,他们仍然无法有效应用这些技能。另一方面,如果你能展示出你已经掌握了某项技术技能,如我所描述的那样,我将会有信心,你能在我雇佣你后掌握并正确应用其他有价值的技术技能。

尽可能多地了解你支持的业务

作为招聘经理,我最看重的特质是好奇心。对于数据分析师而言,这种好奇心通过他们展示对所支持业务的真实理解来体现。在高层次上,你能告诉我公司是做什么的,以及它如何赚钱吗?它面临什么挑战?你能告诉我越多越好。在更详细的层次上,你所做的分析如何帮助公司?例如,如果你的公司在产品运输方面经历了极端的延迟,而你被指派找出原因,你的分析方法是什么?你能详细描述实际的运输过程吗?然后,基于你对这一过程的理解,你如何结构你的分析并识别出问题?如果你能做到这一点,我可以保证这将使你在大多数数据分析师候选人中脱颖而出。最优秀的数据分析师对他们所支持的业务运营有透彻的理解。

对于那些考虑将数据分析作为职业的新手,我建议你在学习技术技能时采取相同的方法。不要只是机械地学习编码或使用分析软件,这样会浪费时间。有很多公开的数据集可以用来创建你自己的数据分析场景。我鼓励你采取这种方法有两个原因。首先,当然是为了学习技术技能。其次(可能更重要的是),是为了了解这是否是你有天赋并可能真正喜欢的工作。成为数据分析师是一项巨大的承诺。将此视为一个提前体验这个角色的机会,以便你可以确定是否真的想要追求这个职业道路。

我将以个人的经历结束这一部分。在我作为数据分析师的期间,我总是设法尝试了解我所支持的业务,与他们一样深入理解。我发现这样做使我成为一个非常有效的数据分析师,进而使我成为一个不可或缺的团队成员。它还使我的工作更有成就感,因为我可以亲眼看到我所带来的价值。我不能过分强调这种方法对我职业生涯的重要性。如果你能从这篇文章中带走一件事,那就是它。

保持你的技术知识更新

数据分析的技术格局不断演变,随着越来越多的公司认识到从这些数据中获取洞察的巨大价值,这一进程正在以光速增长。人工智能、机器学习、云计算、Hadoop 集群、Apache Spark、数据湖、数据管道、数据织物、数据网格、数据可视化等新技术、架构和分析方法层出不穷。掌握这些技术显然是不可能的,但我强烈建议你对它们的功能及其在整体数据分析中的角色形成概念性的理解。我几乎可以保证,你会发现通过掌握其中的一项新技能获得极大的机会。此外,保持对数据和分析领域顶尖趋势的关注也很重要。备受尊敬的 Gartner 每年都会通过其“数据和分析领域的顶尖趋势”做出出色的记录。构建和维护这个知识库将有助于你全面理解数据分析的各个方面,并使你在这个不断发展的领域保持相关性。记住,保持好奇心!

结论

这篇文章是我一直想写的。在我的职业生涯中,我记下了那些在刚开始作为数据分析师时希望自己知道的事情。这个列表随着时间的推移不断增长、缩小、演变和明确。随着数据和数据分析的迅猛发展,我分享自己想法的紧迫感增加了,因为我只能想象自己在今天的环境中成为数据分析师时会感到的复杂性。感谢你花时间阅读这篇文章,我真心希望你能从中找到一些价值。祝你在最终选择的职业道路上万事如意。

我喜欢写关于影响数据分析领域的主题。如果你想关注我未来的文章,请在Medium上关注我。感谢。

我们是否可以轻松解释过于复杂的模型?

原文:towardsdatascience.com/what-if-we-could-easily-explain-overly-complex-models-54a8ff7ac917?source=collection_archive---------6-----------------------#2023-09-28

生成反事实解释变得容易多了,但什么是反事实解释,我该如何使用它们?

Raphael Mazzine, Ph.D.Towards Data Science Raphael Mazzine, Ph.D.

·

关注 发布于 Towards Data Science · 12 分钟阅读 · 2023 年 9 月 28 日

--

图像由 Illusion Diffusion 模型生成,CFNOW 文本作为幻觉(试着眯眼并从一定距离观察) | 作者使用 Stable Diffusion 模型(许可) 生成的图像

本文基于以下文章:www.sciencedirect.com/science/article/abs/pii/S0377221723006598

这里是 CFNOW 仓库的地址:github.com/rmazzine/CFNOW

如果你正在阅读这篇文章,你可能已经知道人工智能(AI)在我们今天的世界中变得多么关键。然而,需要注意的是,虽然看似有效的新颖机器学习方法及其广泛的普及可能会导致不可预见的/不良的后果。

这就引出了为什么可解释人工智能(XAI)在确保人工智能的伦理和负责任发展中是至关重要的。这一领域表明,解释包含数百万甚至数十亿参数的模型并非易事。对此的回答是多方面的,因为有许多方法揭示模型的不同方面,LIME [1] 和 SHAP [2] 是流行的例子。

然而,这些方法生成的解释复杂度可能导致复杂的图表或分析,这可能会导致那些未充分了解的专家产生误解。绕过这种复杂性的一个可能方法是一个简单自然的解释方法,称为反事实解释 [3]。

反事实解释利用了自然的人类行为来解释事物——创建“替代世界”,在这些世界中,通过改变一些参数可以改变结果。这是一种常见的做法,你可能已经做过类似的事情——“如果我早点起床,我就不会错过公交车”,这种解释以直接的方式突出结果的主要原因。

更深入地探讨,反事实不仅仅是简单的解释;它们可以作为变更的指导,帮助调试异常行为,并验证某些特征是否可能修改预测(虽然对评分的影响不大)。这种多功能性强调了解释你的预测的重要性。这不仅仅是负责任的人工智能问题;它也是改进模型并在预测范围之外使用它们的途径。反事实解释的一个显著特征是它们以决策为驱动,使其与预测变化直接相关 [6],这与 LIME 和 SHAP 更适合于解释评分的特性不同。

鉴于明显的好处,人们可能会想知道为什么反事实解释没有更受欢迎。这是一个合理的问题!反事实解释广泛采用的主要障碍有三方面 [4, 5]: (1) 缺乏用户友好且兼容的反事实生成算法,(2) 算法在生成反事实方面的低效,(3) 以及缺乏全面的可视化表现。

但我有一些好消息要告诉你!一个新的包,CFNOW(CounterFactuals NOW 或 CounterFactual Nearest Optimal Wololo),正致力于解决这些挑战。CFNOW 是一个多功能的 Python 包,能够为各种数据类型(如表格、图像和文本(嵌入)输入)生成多个反事实。它采用模型无关的方法,只需要最少的数据——(1)实际点(需要解释的点)和(2)预测函数。

此外,CFNOW 的结构允许开发和集成基于自定义逻辑的新策略来查找和微调反事实。它还具有 CounterPlots,这是一种用于视觉化表示反事实解释的新策略。

CFNOW 的核心是一个框架,它将数据转换为 CF 生成器可以处理的单一结构。接着,通过一个两步过程找到并优化反事实。为了防止陷入局部最小值,包实现了 Tabu Search,这是一种数学启发式方法,使其能够探索新的区域,以便在这些区域中可能更好地优化目标函数。

本文的后续部分将集中展示如何高效利用 CFNOW 生成表格、图像和文本(嵌入)分类器的解释。

表格分类器

在这里,我们展示了通常的内容,你有一个包含多种数据类型的表格数据。在下面的示例中,我将使用一个数据集,该数据集具有数值连续型、分类二元型和分类独热编码数据,以展示 CFNOW 的全部功能。

首先,你需要安装 CFNOW 包,要求 Python 版本高于 3.8:

 pip install cfnow

(这是该示例的完整代码: colab.research.google.com/drive/1GUsVfcM3I6SpYCmsBAsKMsjVdm-a6iY6?usp=sharing

在第一部分中,我们将使用成人数据集创建一个分类器。然后,这里没有太多新鲜事:

import warnings

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
warnings.filterwarnings("ignore", message="X does not have valid feature names, but RandomForestClassifier was fitted with feature names")

我们导入基本包来构建分类模型,同时我们还会禁用与在没有列名的情况下进行预测相关的警告。

然后,我们继续编写分类器,其中类 1 表示收入低于或等于 50k(<=50K),类 0 表示高收入。

# Make the classifier
import warnings

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
warnings.filterwarnings("ignore", message="X does not have valid feature names, but RandomForestClassifier was fitted with feature names")

# Load the Adult dataset
dataset_url = "https://archive.ics.uci.edu/ml/machine-learning-databases/adult/adult.data"
column_names = ['age', 'workclass', 'fnlwgt', 'education', 'education-num', 'marital-status',
                'occupation', 'relationship', 'race', 'sex', 'capital-gain', 'capital-loss',
                'hours-per-week', 'native-country', 'income']

data = pd.read_csv(dataset_url, names=column_names, na_values=" ?", skipinitialspace=True)

# Drop rows with missing values
data = data.dropna()

# Identify the categorical features that are not binary
non_binary_categoricals = [column for column in data.select_dtypes(include=['object']).columns 
                           if len(data[column].unique()) > 2]

binary_categoricals = [column for column in data.select_dtypes(include=['object']).columns 
                       if len(data[column].unique()) == 2]

cols_numericals = [column for column in data.select_dtypes(include=['int64']).columns]

# Apply one-hot encoding to the non-binary categorical features
data = pd.get_dummies(data, columns=non_binary_categoricals)

# Convert the binary categorical features into numbers
# This will also binarize the target variable (income)
for bc in binary_categoricals:
    data[bc] = data[bc].apply(lambda x: 1 if x == data[bc].unique()[0] else 0)

# Split the dataset into features and target variable
X = data.drop('income', axis=1)
y = data['income']

# Split the dataset into training and testing sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# Initialize a RandomForestClassifier
clf = RandomForestClassifier(random_state=42)

# Train the classifier
clf.fit(X_train, y_train)

# Make predictions on the testing set
y_pred = clf.predict(X_test)

# Evaluate the classifier
accuracy = accuracy_score(y_test, y_pred)
print("Accuracy:", accuracy)

使用上面的代码,我们创建了一个数据集,对其进行预处理,创建了一个分类模型,并对测试集进行了预测和评估。

现在,让我们选择一个点(测试集中的第一个)并验证其预测:

clf.predict([X_test.iloc[0]])
# Result: 0 -> High income

现在是时候使用 CFNOW 来计算我们如何通过最小修改特征来改变这个预测:

from cfnow import find_tabular
# Then, we use CFNOW to generate the minimum modification to change the classification
cf_res = find_tabular(
    factual=X_test.iloc[0],
    feat_types={c: 'num' if c in cols_numericals else 'cat' for c in X.columns},
    has_ohe=True,
    model_predict_proba=clf.predict_proba,
    limit_seconds=60)

上面的代码中,我们:

  • factual将实际实例添加为 pd.Series

  • feat_types指定特征类型(“num”表示数值连续型,“cat”表示分类变量)

  • has_ohe指示我们是否有 OHE 特征(它通过汇总那些具有相同前缀并以下划线开头的特征来自动检测 OHE 特征,例如,country_brazil,country_usa,country_ireland)。

  • model_predict_proba 包含预测函数

  • limit_seconds 定义了运行的总时间阈值,这一点很重要,因为微调步骤可能会无限期继续(默认是 120 秒)。

然后,经过一段时间,我们可以首先评估最佳反事实的类别(cf_res.cfs的第一个索引)。

clf.predict([cf_obj.cfs[0]])
# Result: 1-> Low income

这里出现了一些与 CFNOW 的不同之处,由于它还集成了 CounterPlots,我们可以绘制它们的图表,并获得更多有洞察力的信息,如下所示:

CounterShapley 图表 | 图片由作者提供

下面的 CounterShapley 图显示了每个特征在生成反事实预测中的相对重要性。在这里,我们得到了一些有趣的见解,显示 marial_status(如果组合在一起)占 CF 类别贡献的 50%以上。

我们的 CF 的贪婪图表 | 图片由作者提供

贪婪图表显示的内容与 CounterShapley 非常相似,主要区别在于变化的顺序。虽然 CounterShapley 没有考虑任何特定的顺序(使用 Shapley 值计算贡献),贪婪图表使用最贪婪的策略来修改实际实例,每一步都改变对 CF 类别贡献最大的特征。这在某些情况下可能很有用,即在贪婪的方式下给出一些指导(每一步选择实现目标的最佳方法)。

我们的 CF 的星座图 | 图片由作者提供

最后,我们有了最复杂的分析,即星座图。尽管它看起来令人望而却步,但其实很容易解释。每个大的红点代表一个特征的单独变化(相对于标签),而小的点代表两个或多个特征的组合。最后,大的蓝点代表 CF 评分。在这里,我们可以看到,获得这些特征的 CF 的唯一方法是将它们全部修改为各自的值(即,没有子集能生成 CF)。我们还可以深入探讨并研究特征之间的关系,可能会发现有趣的模式。

在这种特定情况下,有趣的是观察到,如果这个人是女性、离婚且有一个孩子,预测的高收入会发生变化。这一反事实可以引发对不同社会群体经济影响的进一步讨论。

图像分类器

如前所述,CFNOW 可以处理多种数据类型,因此它也可以为图像数据生成反事实。然而,对于图像数据集来说,拥有反事实意味着什么呢?

响应可能会有所不同,因为生成反事实的方法有多种。它可以是用随机噪声替换单个像素(对抗攻击使用的方法),也可以是更复杂的方法,涉及先进的分割技术。

CFNOW 使用了一种名为 quickshift 的分割方法,这是一种可靠且快速的“语义”分段检测方法。然而,可以集成(我建议你这样做)其他分割技术。

仅靠分段检测不足以生成反事实解释。我们还需要修改这些分段,用修改过的版本替换它们。对于这种修改,CFNOW 在 replace_mode 参数中定义了四种选项,我们可以选择:(默认)blur——为替换的分段添加模糊滤镜,mean——用平均颜色替换分段,random——用随机噪声替换,inpaint——基于邻域像素重建图像。

如果你想要完整的代码,可以在这里找到:colab.research.google.com/drive/1M6bEP4x7ilSdh01Gs8xzgMMX7Uuum5jZ?usp=sharing

接下来,我将展示 CFNOW 对这种数据类型的代码实现:

首先,再次,如果你还没有安装 CFNOW 包,请安装它。

pip install cfnow

现在,让我们添加一些额外的包来加载预训练模型:

pip install torch torchvision Pillow requests

那么,让我们加载数据,加载预训练模型,并创建一个与 CFNOW 必须接收的数据格式兼容的预测函数:

import requests
import numpy as np
from PIL import Image
from torchvision import models, transforms
import torch

# Load a pre-trained ResNet model
model = models.resnet50(pretrained=True)
model.eval()

# Define the image transformation
transform = transforms.Compose([
    transforms.Resize(256),
    transforms.CenterCrop(224),
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])

# Fetch an image from the web
image_url = "https://upload.wikimedia.org/wikipedia/commons/thumb/4/41/Sunflower_from_Silesia2.jpg/320px-Sunflower_from_Silesia2.jpg"
response = requests.get(image_url, stream=True)
image = np.array(Image.open(response.raw))

def predict(images):
    if len(np.shape(images)) == 4:
        # Convert the list of numpy arrays to a batch of tensors
        input_images = torch.stack([transform(Image.fromarray(image.astype('uint8'))) for image in images])
    elif len(np.shape(images)) == 3:
        input_images = transform(Image.fromarray(images.astype('uint8')))
    else:
        raise ValueError("The input must be a list of images or a single image.")

    # Check if a GPU is available and if not, use a CPU
    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    input_images = input_images.to(device)
    model.to(device)

    # Perform inference
    with torch.no_grad():
        outputs = model(input_images)

    # Return an array of prediction scores for each image
    return torch.asarray(outputs).cpu().numpy()

LABELS_URL = "https://raw.githubusercontent.com/anishathalye/imagenet-simple-labels/master/imagenet-simple-labels.json"
def predict_label(outputs):
    # Load the labels used by the pre-trained model
    labels = requests.get(LABELS_URL).json()

    # Get the predicted labels
    predicted_idxs = [np.argmax(od) for od in outputs]
    predicted_labels = [labels[idx.item()] for idx in predicted_idxs]

    return predicted_labels

# Check the prediction for the image
predicted_label = predict([np.array(image)])
print("Predicted labels:", predict_label(predicted_label))

大部分代码工作与构建模型、获取数据和调整数据有关,因为要用 CFNOW 生成反事实,我们只需要:

from cfnow import find_image

cf_img = find_image(img=image, model_predict=predict)

cf_img_hl = cf_img.cfs[0]
print("Predicted labels:", predict_label(predict([cf_img_hl])))

# Show the CF image
Image.fromarray(cf_img_hl.astype('uint8'))

在上面的示例中,我们使用了所有默认的可选参数,因此,我们使用 quickshift 对图像进行分割,并用模糊的图像替换这些分割区域。结果,我们得到了以下的实际预测:

实际图像被分类为“雏菊” | 图像标题:向日葵(Helianthus L)。Słonecznik,来自 Pudelek(由 YzmoVassil 编辑)来自 Wikimedia,根据 GNU 自由文档许可证 第 1.2 版

到以下内容:

CF 图像被分类为“蜜蜂” | 图像标题:向日葵(Helianthus L)。Słonecznik,来自 Pudelek(由 YzmoVassil 编辑)来自 Wikimedia,根据 GNU 自由文档许可证 第 1.2 版

那么,这项分析的结果是什么呢?实际上,图像反事实可以成为极其有用的工具,以检测模型如何进行分类。这可以应用于以下情况:(1)我们想验证模型为何做出正确分类——确保其使用了正确的图像特征:在这种情况下,尽管模型将向日葵误分类为雏菊,但我们可以看到,模糊化花朵(而不是背景特征)会使其更改预测。它还可以(2)帮助诊断误分类的图像,这可能为图像处理和/或数据采集提供更好的洞察。

文本分类器

最后,我们有基于嵌入的文本分类器。尽管简单的文本分类器(使用更像表格数据的数据结构)可以使用表格反事实生成器,但基于嵌入的文本分类器,这一点不那么明确。

理由是嵌入具有可变数量的输入和单词,这些都可以显著影响预测分数和分类。

CFNOW 通过两种策略解决这个问题:(1)通过移除证据或(2)通过添加反义词。第一种策略很简单,为了测量每个单词对文本的影响,我们只需移除它们并查看哪些需要移除以翻转分类。而添加反义词,我们可以可能保持语义结构(因为移除一个单词可能会严重损害语义结构)。

然后,下面的代码展示了如何在这个上下文中使用 CFNOW。

如果你想要完整的代码,可以在这里查看:colab.research.google.com/drive/1ZMbqJmJoBukqRJGqhUaPjFFRpWlujpsi?usp=sharing

首先,安装 CFNOW 包:

pip install cfnow

然后,安装文本分类所需的包:

pip install transformers

然后,如前面部分所述,首先我们将构建分类器:

from transformers import DistilBertTokenizer, DistilBertForSequenceClassification
from transformers import pipeline

import numpy as np

# Load pre-trained model and tokenizer for sentiment analysis
model_name = "distilbert-base-uncased-finetuned-sst-2-english"
tokenizer = DistilBertTokenizer.from_pretrained(model_name)
model = DistilBertForSequenceClassification.from_pretrained(model_name)

# Define the sentiment analysis pipeline
sentiment_analysis = pipeline("sentiment-analysis", model=model, tokenizer=tokenizer)

# Define a simple dataset
text_factual = "I liked this movie because it was funny but my friends did not like it because it was too long and boring."

result = sentiment_analysis(text_factual)
print(f"{text_factual}: {result[0]['label']} (confidence: {result[0]['score']:.2f})")

def pred_score_text(list_text):
    if type(list_text) == str:
        sa_pred = sentiment_analysis(list_text)[0]
        sa_score = sa_pred['score']
        sa_label = sa_pred['label']
        return sa_score if sa_label == "POSITIVE" else 1.0 - sa_score
    return np.array([sa["score"] if sa["label"] == "POSITIVE" else 1.0 - sa["score"] for sa in sentiment_analysis(list_text)])

对于这段代码,我们将看到我们的事实文本具有高置信度(≥0.9)的 NEGATIVE 情感,然后让我们尝试为其生成反事实:

from cfnow import find_text
cf_text = find_text(text_input=text_factual, textual_classifier=pred_score_text)
result_cf = sentiment_analysis(cf_text.cfs[0])
print(f"CF: {cf_text.cfs[0]}: {result_cf[0]['label']} (confidence: {result_cf[0]['score']:.2f})")

使用上述代码,只需更改一个单词(but),分类就从 NEGATIVE 变为 POSITIVE,并且置信度很高。这展示了反事实如何有用,因为这些最小的修改可以对理解模型如何预测句子和/或帮助调试不良行为产生影响。

结论

这是一篇对 CFNOW 和反事实解释的(相对)简要介绍。关于反事实的文献非常广泛(且不断增加),如果你想深入了解,必读的开创性文章是由(我的博士生导师,大卫·马滕斯教授)撰写的[3],这是对反事实解释有更好介绍的绝佳方式。此外,还有由 Verma 等人撰写的很好的综述[7]。总之,反事实解释是一种简单且方便的方式来解释复杂的机器学习算法决策,如果正确应用,它们还能做到远超过解释的效果。CFNOW 可以提供一种简单、快速和灵活的方式来生成反事实解释,使从业者不仅能解释,还能最大限度地利用数据和模型的潜力。

参考文献:

[1] — github.com/marcotcr/lime

[2] — github.com/shap/shap

[3] — www.jstor.org/stable/26554869

[4] — www.mdpi.com/2076-3417/11/16/7274

[5] — arxiv.org/pdf/2306.06506.pdf

[6] — arxiv.org/abs/2001.07417

[7] — arxiv.org/abs/2010.10596

作为数据科学家,是什么激励了你?

原文:towardsdatascience.com/what-inspires-you-as-a-data-scientist-ee43e922cae2?source=collection_archive---------19-----------------------#2023-01-05

TDS 编辑前往数据科学 TDS 编辑

·

关注 发布于 前往数据科学 ·发送为 新闻通讯 ·3 分钟阅读·2023 年 1 月 5 日

--

就这样,新的一年到了!我们希望你们已经享受了 2023 年的头几天。

我们知道许多数据科学家在这一年开始新的冒险和雄心勃勃的项目,而每一次新的尝试也是提升我们技能或获取新技能的机会。

学习是任何形式的成长的核心,无论是职业还是其他,但还有许多其他目标激励着我们的读者。为了帮助那些刚刚入门(或考虑入门)的人,我们的 1 月版提供了一系列资源来帮助你成为更好的学习者。

作为对该总结的补充,我们将今年的首个变量献给近期的文章,这些文章将激励你采取行动,并为你提供在未来几个月中探索的新想法。享受吧!

  • 利用数据的力量推动环境变化。没有数据科学家可以单独解决气候危机,这就是为什么扩大对气候问题敏感的从业者社区如此重要。梅布里特·席林格通过一篇 TDS 首发文章,为更好地理解气候变异性整合了物理学、统计学和时间序列分析,为这一努力做出了贡献。

  • 几个简单的决定可以对你的职业产生重大累积效果。新年的决心往往是宏大的且引人注目的——而且到二月份就容易被遗忘。相反,穆尔塔扎·阿里提出了 10 个具体的建议——从学习设计用户研究到选择个人项目——这些建议可以帮助你成为一个更强大、更全面的数据科学家。

  • 是时候推动角色转变了吗?如果你是一个数据分析师,并且把自己看作未来的数据科学家,玛丽·纽豪瑟的指南是必读的:它涵盖了这些角色之间转换的方方面面。(如果你考虑的职业变动是其他类型的,这也是一个非常有用的资源。)

图片由 安迪·凯利Unsplash 提供

  • 更具多样性的科技领域不会在没有行动的情况下到来。你是从事数据工作的专业人士,想知道如何在组织中促进包容性吗?托马斯·A·多费尔关于多样化团队好处的入门指南是一个很好的起点,可能会帮助你与利益相关者展开重要的对话。

  • 不仅要在解决问题上提高能力 — 还要在预防问题上有所进步。对于许多为内部(甚至可能是外部)用户开发数据产品的你们来说,让事情顺利进行不是一些平凡的活动;它正是你工作的核心。玛丽安·诺丁 的最新文章探讨了数据漂移和比特腐蚀的根本原因,并解释了如何以长期可持续性为目标来应对这些问题。

如果你在假期后充满了额外的精力—或者至少日程还不满,我们鼓励你抽出一些时间来关注这些其他近期的亮点:

  • 卡罗利娜·本托 带来了一份新的易于跟随(同时也非常详尽)的教程,这次讲解了 ROC 分析和曲线下面积。

  • 关于 AI 生成艺术的辩论在 2023 年肯定会继续激烈;史蒂夫·丹尼斯 的文章 讨论了削弱这一技术成就的伦理紧张关系,以及解决这些问题的思路。

  • 现在还不算晚,可以再回顾一下 2022 年—至少像 普鲁卡尔帕 的文章一样有洞察力,她评估了 她自己对现代数据栈未来的预测。

  • 图形机器学习在来年会走向何方? 迈克尔·加尔金 介绍了你需要跟踪的最新趋势和发展,这些在这个不断变化的领域中至关重要。

一如既往,感谢你对我们工作的支持。如果你希望帮助 TDS 在 2023 年及以后继续发布优质文章,请考虑 成为 Medium 会员

直到下次 Variable,

TDS 编辑部

什么是生命周期评估?LCA

原文:towardsdatascience.com/what-is-a-life-cycle-assessment-lca-e32a5078483a?source=collection_archive---------6-----------------------#2023-01-18

了解生命周期评估如何帮助企业评估产品在其整个生命周期中的环境影响并改善可持续性。

萨米尔·萨奇数据科学导向 萨米尔·萨奇

·

关注 发布于 数据科学导向 ·12 min read·2023 年 1 月 18 日

--

什么是生命周期评估?—(作者提供的图片)

随着消费者环保意识的提高,企业必须优先考虑可持续性以保持竞争力。

生命周期评估(LCA)评估产品在其整个生命周期中的环境影响,从原材料提取到处置。

生产我的 T 恤需要多少水?

生命周期评估旨在识别和量化产品的环境影响,以便报告和支持可持续性倡议。

如何使用数据分析来估算你在 Zara 购买的便宜 T 恤的环境影响?

你需要来自多个来源的数据,以追踪产品在价值链中的影响直到其生命周期结束。

资源使用和价值链中的 CO2 排放 ——(图像作者提供)

本文展示了数据分析如何通过从多个系统中提取和处理数据来支持生命周期评估(LCA),以进行诊断和模拟场景。

💌 免费订阅最新文章:通讯

📘 供应链分析的完整指南:分析备忘单

**I. Assessment in four steps**
**1\. Goal and scope definition**
Define the goals and scope of this assessment.
**2\. Inventory Analysis**
Gather data on the materials, energy, and other resources used 
**3\. Interpretation and evaluation**
Assessing the overall environmental performance of the product
**II. Life Cycle Assessment for Advanced Reporting**
**1\. ESG reporting**
Report the Environmental, Social and Governance of your company
**2\. Data Analytics to Fight GreenWashing**
Detect false claims of sustainability using public data
**3\. Business Intelligence for LCA**
Methodologies to collect and process from multiple sources
**III. Next Steps**
**1\. Simulate different scenarios with a Digital Twin**
What is the impact of localizing your production on your LCA?
**2\. Conduct Further Analysis with Brightway2**
Open source librairies with publicly available databases
**3\. Sustainable Supply Chain App**
Design the optimal manufacturing facilities to minimize CO2 emissions

四个步骤的评估

我们假设你是快时尚零售公司中的数据科学家,与你的可持续发展部门合作以实施自动化的可持续性报告。

我们希望通过生命周期评估实现什么?

第一步:目标和范围定义

要启动我们的生命周期评估(LCA),我们需要定义评估的目标和范围。

在快时尚零售公司中生产和销售一件 T 恤的环境影响是什么?

这包括识别正在研究的产品、关注的环境影响以及功能单位(用于比较不同产品或服务的测量单位)

生命周期评估的范围包括时间框架、生命周期阶段、地理边界和功能单位 ——(图像作者提供)

  1. 确定被评估的产品及其预期用途

    例如:包括所有尺码的常规版 T 恤

  2. 确定产品生命周期中要纳入评估的特定阶段:从原材料提取到处置。

  3. 确定评估的地理范围:生产设施的位置、运输路线和最终处置地。

    原材料提取和生产地点为印度

    储存、商店配送和欧洲的处置

  4. 确定评估的时间框架:评估期的开始和结束日期。

    从 2021 年 1 月 1 日到 2022 年 1 月 1 日

  5. 定义功能单位,这是比较不同产品环境影响的标准度量。

    销售单位:一件 T 恤

确保所有相关利益相关者对评估范围达成一致。

这确保生命周期评估结果有意义且具有代表性,不会受到挑战。

从系统中提取和处理数据以填充 LCA 报告 ——(图像作者提供)

该产品将在你的不同系统中与一个(或多个)SKU 代码关联(ERPWMS、TMS)

  • 您可能会有多个代码用于不同尺码和颜色的 T 恤。

  • 代码在不同系统之间可能有所不同(SKU 生产代码、销售包装中的 SKU 等):确保您拥有一致的 主数据 以跟踪价值链中的物品。

从原材料到成品,您的价值链涉及仓库、工厂和货运操作。

对于每个生命周期阶段,您可能会有不同的数据源/系统

  • 生产数据 可以在您的生产管理系统中找到,或者在您的 企业资源规划 系统中找到

  • 运输 将由运输管理系统进行管理

  • 仓库操作 数据存储在仓库管理系统中

  • 销售(及售后)数据可以从您的销售点(POS)和客户关系管理(CRM)系统中提取

原材料在印度采购,用于在孟加拉国制造并在欧洲零售。

地理边界可以由源系统和交易信息来定义

  • 原材料采购信息可以在 采购订单 中找到,该订单是在 ERP 中创建的

  • 生产 地点信息在 PMS 中(工厂、生产线) 运输 地点在您的 TMS 中被追踪(起点、目的地、跨越的国家)

确定时间范围可能具有挑战性,并会影响您的评估结果

  • 我们是否在讨论时间范围内销售的所有产品?

    如果是,这是否意味着我们必须查看 生产 、运输和仓储活动,这些活动发生在开始日期之前?

  • 或者我们查看时间范围内的活动? 如果是,我们来看看 生产 运输 在结束日期后销售的产品的影响。

请注意,范围可以根据您的需求和期望的举措来进行更详细或更简单的定义,以便从结果中受益。

对于此分析,您手头上有哪些数据?

第 2 步:库存分析

第二步是收集有关材料、能源和其他资源使用情况以及整个产品或服务生命周期中产生的废料的数据。

简化周期下的库存分析用于生命周期评估 —(图片由作者提供)

原材料 您的 T 恤由在印度种植和加工的 100%棉花制成

(表格由作者提供)

您现在可以量化每个功能单元排放的 CO2 以及使用的能源和水。

💡 原材料种植的影响

  • 我们有 1kg 原材料 = 1 功能单元。

  • 棉花和消耗的公用设施的数量可以由你的供应商估算或测量。

原材料转化的影响是什么?

生产 T 恤在你位于印度的工厂生产。

(作者提供的表格)

运输 你的 T 恤在印度生产,通过海运和公路运输到欧洲,

(作者提供的表格)

💡 你的物流网络的影响

  • 海洋运输的能源和排放数据极其不稳定,取决于船只、年份和航运路线。你的货运代理应验证(或提供)这些数据。

  • 运输的 CO2 排放可以估算其他运输方式(路线、航空和铁路)的排放,如这个CO2 排放报告方法论的例子。

  • 对于水和电力消耗、CO2 排放以及产生的废物,仓库操作也可以考虑。

T 恤售出后会发生什么?

使用和处置 你的产品在市场的国家内使用(使用和处置)

T 恤在被处理前使用两年。

  • 洗涤和烘干的能源消耗:100 MJ/件 T 恤

  • 洗涤和烘干的水消耗:500 L/件 T 恤

  • 电力生成的排放:10 kg CO2e/件 T 恤

T 恤在其销售的国家被丢弃在填埋场。

  • 分解排放:5 kg CO2e/件 T 恤

很好,现在我们已经覆盖了整个生命周期。

第 3 步:影响评估

现在我们已经收集了每个步骤的数据,我们可以开始评估功能单元(1 件 T 恤)的环境影响。

  • 空气、水和土壤

  • 人体健康和生态系统健康

  1. 能源消耗:870 MJ 58%在 生产过程中 消耗

  2. 温室气体排放:46 kg CO2e 大部分排放发生在 生产过程中

  3. 水消耗:3,500 L

    57%在 生产过程中 消耗

  4. 固体废物:0.5 kg

    生产过程中 产生的

  5. 空气污染:0.8 g SOx0.5 g NOx 排放

    运输过程中 排放

大多数影响在生产运输过程中产生。

第 4 步:解释和评估

这是评估产品整体环境性能并识别改进领域潜在缓解策略的过程。

生命周期开发评估的解释和评估的四个步骤 — (作者提供的图片)

与行业标准的比较 影响评估结果可以与行业标准或基准进行比较,以查看 T 恤在环境表现上如何与类似产品相比。

热点识别

影响评估结果可用于识别 T 恤在环境影响上最显著的“热点”。

在我们的例子中,这些热点是生产运输中的温室气体排放和能源消耗。

💡 自动化识别的诊断分析

如果你已经实施了数据管道以收集、处理和存储库存数据,可以实现诊断分析工具和方法进行自动化分析

  • 管理数千个具有不同价值链的 SKU

  • 实施自动化规则以进行监控、警报和根本原因分析,以回答诸如

    为什么 SKU 132897–98 的 CO2 排放增加了 20%?

潜在的缓解策略

根据识别出的热点,可以制定潜在的缓解策略,以减少 T 恤的环境影响。

  • 使用可再生能源进行生产设施的运作。

  • 本地化生产,以减少工厂和市场之间的运输距离。

  • 与使用替代燃料或拥有环保车队的货运公司合作,以减少每公里的 CO2 排放

  • 进行供应链网络优化研究,重点是通过选择合适的供应商和工厂位置来减少环境影响

持续改进

解释和评估结果应用于持续改进产品或过程的环境性能。

当然,你必须考虑环境影响与其他方面(如成本和性能)之间的权衡,以减少业务影响。

💡 更多细节,

## 使用蒙特卡洛模拟的稳健供应链网络

在设计供应链网络时,你是否考虑了需求的波动?

towardsdatascience.com ## 什么是供应链分析?

利用数据分析提高运营效率,通过数据驱动的诊断和战略决策来改进...

towardsdatascience.com

现在你已经实施了数据收集和处理的过程来生成洞察,你可以开始编写可持续性报告。

高级报告的生命周期评估

ESG 报告的生命周期评估

环境、社会和治理(ESG)报告是一种公司用来披露其环境足迹、治理结构和社会影响的方法论。

ESG 支柱展示 — (图片由作者提供)

随着利益相关者越来越要求企业社会责任(CSR),报告已成为公司长期战略中的关键部分。

你如何利用数据分析来支持 ESG 报告?

环境(E)报告的核心在于生命周期评估,因为你需要报告从原材料采购到店铺交付的产品影响。

ESG 报告的三个主要支柱 — (图片由作者提供)

环境部分的指标取决于生命周期评估中包含的参数。

💡 更多详情,请见

什么是 ESG 报告?

利用数据分析进行全面而有效的公司环境、社会和治理报告

towardsdatascience.com

你听说过“绿色洗涤”吗?

什么是绿色洗涤,我们如何利用分析来检测它

当你试图准确报告运营的环境影响时,其他公司却在撒谎。

使用数据分析来挑战可持续性报告。

一些公司对产品的环境效益做出误导性声明,以传达虚假的可持续性形象。

绿色洗涤的 5 种罪恶 — (图片由作者提供)

这种修饰或隐藏虚假的做法,随着公司寻求环保消费者的关注,对组织和政府构成了挑战。

我们能否通过高级分析来对抗绿色洗涤?

用于检测环境报告中的“绿色洗涤”的高级分析 — (图片由作者提供)

我们可以将数据科学生命周期评估方法结合起来,检测这些欺诈行为

  • 公开数据:财务和可持续性报告、足迹数据库、社交媒体

  • NLP、预测或统计模型这样的高级分析模型来检测欺诈行为

💡 更多详情,请见

什么是绿色洗涤?以及如何利用分析来检测它?

探索数据分析如何帮助我们检测和预防绿色洗涤,并促进真正的可持续性。

towardsdatascience.com

从多个系统中收集和处理数据的最佳实践是什么?

生命周期评估中的商业智能

商业智能是一个利用软件和服务将数据转化为支持决策的可操作情报的过程。

商业智能过程五步法——(作者提供的图片)

由于您的生命周期评估依赖于从多个来源收集和处理数据,您需要一种方法来实现自动化管道。

如何自动化这些数据的收集和处理?

通过构建数据架构,您可以检索更新的数据和指标,而不是使用估算或平均值。

从多个来源中心化提取数据——(作者提供的图片)

  • 管理您工厂的系统可能不会提供每单位的能源、水使用或废物生成信息。

    使用如 Excel 文件中的能源账单等外部来源

  • 您的供应商可以提供用于棉花种植的Excel 报告中的能源和水使用数据,这些数据将用于您的报告

  • 一些货运代理商有API来提取每次运输的路线信息、排放量和燃料消耗

这一架构将减少手动工作量,并通过使用最新的参数和输入数据提高报告的准确性。

如何使用分析解决方案创建具有统一数据的中央真实来源?

商业智能工具结合了各种应用,包括数据仓库、发现和可视化。

结合来自多个来源的数据的数据仓库——(作者提供的图片)

BI 解决方案与这些系统的交互方式:

  • 处理并将获取的数据转换为单一的统一来源

  • 构建用户友好的报告、图表和地图

💡 更多细节,

towardsdatascience.com ## 什么是商业智能?

发现适用于供应链优化的数据驱动决策工具。

[towardsdatascience.com

报告之后,下一步是什么?

您的公司可以利用结果和见解来实施具有可持续性举措的路线图。

您可以利用数据模拟这些举措的影响;接下来的部分将介绍如何操作。

下一步

本文主要集中在数据分析如何支持数据收集、处理和通过诊断工具进行可视化。

如果我们想估算再工程解决方案的影响呢?

使用数字双胞胎模拟不同场景

数字双胞胎是物理对象或系统的数字化复制品。

该模型表示您的 仓库运输网络生产 设施。

使用 Python 的数字双胞胎示例 — (图像由作者提供)

在这个数字世界中,您可以建模供应链中的每一个环节,包含成本、能源、排放和交货时间参数。

如果我们从英国的仓库向欧洲市场配送,会怎么样?

在头脑风暴潜在的脱碳策略时,您可以模拟它们对供应链的影响。

使用您的数字双胞胎模拟多个场景的示例 — (图像由作者提供)

例如,

  • 如果我们将 生产 本地化,对物流成本和 CO2 排放会有什么影响?

  • 如果我们在印度以外使用替代(绿色)种植方法,会对您的 库存店内交货时间 产生什么影响?

  • 实施一个物流网络来回收店内的二手物品成本是多少?

了解如何实施此解决方案的更多细节,

## 供应链数字双胞胎是什么?

使用 Python 发现数字双胞胎:建模供应链网络、提升决策能力与优化运营。

towardsdatascience.com

您听说过供应链优化吗?

可持续供应链优化应用程序

可持续供应链优化是一种将成本效益与环境责任相结合的网络设计方法。

供应链可持续性应用程序的工作流程 — (图像由作者提供)

最小化 CO2 排放的最佳工厂组合是什么?

假设您想设计一个供应链网络以生产和交付产品到特定市场。

您有

  • 每个市场的需求(单位/月)

  • 一组潜在的工厂,包括其固定/可变成本、环境影响和位置

  • 从工厂到每个市场的运输成本和环境影响

如果我们想要最小化 CO2 排放,成本影响会是什么?

多场景模拟 — (图像由作者提供)

通过这个解决方案,你可以模拟多个场景,调整目标(例如,减少二氧化碳、成本或水使用),以获得最佳网络。

使用我的网络应用程序模拟场景 — [应用]

我开发了一个网络应用程序,可以模拟绿色转型的多个场景(减少二氧化碳排放、水使用等),以估算对整体生产成本的影响。

试试吧! 👇

访问应用程序进行尝试! — [应用]

关于我

LinkedinTwitter上与我联系。我是一名供应链工程师,利用数据分析来改善物流操作并降低成本。

如果你对数据分析和供应链感兴趣,请查看我的网站。

## Samir Saci | 数据科学与生产力

专注于数据科学、个人生产力、自动化、运筹学和可持续性的技术博客…

samirsaci.com

参考文献

什么是卫星图像时间序列?

原文:towardsdatascience.com/what-is-a-satellite-image-time-series-c0516c534ba9

解决当前和未来全球挑战的基础

Mattia GattiTowards Data Science Mattia Gatti

·发表于 Towards Data Science ·阅读时间 7 分钟·2023 年 3 月 2 日

--

图片由 NASA 提供,来源于 Unsplash

在上一篇 文章中,我详细讨论了有关处理地理空间栅格数据的所有内容。这种数据与特定地理区域相关。然而,仅分析一个栅格文件无法研究该区域随时间的变化。本指南旨在介绍卫星图像时间序列,并解释为什么这些数据在应对地球当前和未来面临的挑战中至关重要。

介绍

卫星图像时间序列(SITS)可能是研究某个区域随时间变化的最重要资源:

SITS 是一组在不同时间从相同区域拍摄的卫星图像。

每张图像都存储为地理栅格文件。这些图像按日期排序,以便可以按顺序分析。这里展示的是一个作物区域的 SITS:

意大利伦巴第地区的作物区域卫星图像时间序列。图像来自 Copernicus Open Access Hub

SITS 图像通常按固定间隔拍摄。这有助于以恒定的速度监测变化。上面的时间序列由 Sentinel-2 卫星每 5 天拍摄的图像组成,但其中一些图像已被删除,因为它们包含云,例如:

一些被删除的图像。图像来自 Copernicus Open Access Hub

云层覆盖是卫星图像和 SITS 的一个严重问题,因为云层对 Sentinel-2 波段的反射效果很好。

Sentinel-2 捕获 13 个光谱波段,分为可见波段(较短波长)和红外波段(较长波长)。可见波段是我们能看到的,由红色、绿色和蓝色波段(可见波段)组成。其他波段可以获取有关下方区域的其他信息,但我们无法看到。这也是为什么 SITS 通常不是通过直接观察而是使用可以处理所有波段的不同算法进行分析的原因之一。

应用

卫星图像时间序列是未来全球挑战中广泛应用的宝贵信息来源。以下是一些例子:

农业

卫星图像时间序列在农业中极其有用,提供有关作物健康、生长和产量的信息。通过分析植被随时间的变化,农民可以做出关于灌溉、施肥和其他管理实践的明智决策。关键应用包括作物监测、产量预测、灌溉管理、病虫害检测和土地使用规划。

图片由 Timon Reinhard 拍摄,发布在 Unsplash

森林监测

卫星图像时间序列可以成为森林监测和管理的强大工具。通过追踪森林覆盖、健康和组成的变化,它们可以帮助识别关注区域并提供管理决策的信息。例如,SITS 可以用于跟踪森林覆盖的变化,帮助识别森林砍伐区域,并评估森林损失的范围和速度。因此,它们对于改善再造林、造林或森林恢复实践非常有用。

图片由 Sebastian Unrau 拍摄,发布在 Unsplash

气候监测

卫星图像时间序列可用于监测可能与气候变化相关的模式,并为气候研究和政策提供宝贵信息。它们可以用于监测海平面、海冰和雪覆盖的变化,追踪冰川和冰盖的移动,以及监测气候变化引起的植被变化。

图片由 Sophia Simoes 拍摄,发布在 Unsplash

城市规划

卫星图像时间序列可用于监测土地使用和覆盖的变化,提供有关城市增长、扩张和土地使用变化的信息。这些信息可用于规划和管理城市发展、基础设施和服务。此外,SITS 还可用于监测交通基础设施,如道路、高速公路和铁路,并评估其在城市地区的表现和影响。这有助于规划新的交通基础设施,优化现有网络,并评估交通对环境的影响。

照片由Andrea Cau提供,来自Unsplash

灾害响应

卫星图像可用于评估自然灾害如地震、洪水、飓风和野火造成的损害程度和严重性。SITS 可用于跟踪受影响地区的恢复情况,优先安排响应工作,并改善资源分配。

照片由Marc Szeglat提供,来自Unsplash

每个应用程序背后的主要思想是,卫星观测提供了理解地球变化的机会,识别这些变化的原因,并预测未来的变化。随着技术的进步和数据的增多,利用卫星图像来理解和解决全球挑战的可能性几乎是无限的。

SITS 分析

从非常实用的角度来看,SITS 通常以地理栅格文件的集合形式存储,其中文件名包含图像拍摄的日期。时间序列可以使用各种方法进行分析,具体取决于你想研究的变化。这些方法大多数需要使用 GIS 软件,如ArcGISQGIS,以及对相关领域的良好了解。尽管本指南是对 SITS 的介绍,但我可以简要介绍一些你可以尝试的技术:

图像差异

分析随时间变化的一种方法是减去不同时间拍摄的两张图像的像素值。这种技术称为图像差异,可以突出显示植被覆盖、土地使用和其他特征的变化。这是一种简单的技术,但可能足以完成一些简单的任务。然而,根据选择的波段进行差异计算时,图像差异可能会因为图像在不同条件下拍摄而突显变化,而不是真正的区域变化。减去属于同一时间序列的两个栅格的代码非常简单:

import rasterio as rio

first = rio.open("lombardia3/data2019/1208/20190308.tiff").read()
second = rio.open("lombardia3/data2019/1208/20190313.tiff").read()
diff = first - second

结果将类似于这样:

与前一张图像的差异。

黄色阴影突出显示与时间序列前一张图像相比变化较大的栅格部分。根据任务的不同,你可以选择减去哪些波段。此外,可以设置阈值以防止小变化被显示,仅突出显示较大的变化。

绘制波段

地理栅格的每个像素覆盖一定的平方米面积。可以绘制给定像素的波段,以显示它们随时间的变化。这是有用的,因为可以通过结合波段来量化该区域的变化。以下代码处理时间序列中的所有图像。然后,从最旧的图像到最新的图像,绘制左上角像素的不同波段的值:

在我的案例中,最终的折线图显示了该像素的 13 个波段从时间序列中的第一张图像到第十张图像的变化:

绘制特定位置的波段。

此外,你还可以使用波段值计算各种指数(在 这里 报告)。这些指数可以在时间序列中的每张图像上计算相同的像素。例如,归一化差异植被指数(NDVI)衡量卫星图像中植被的绿度和密度,其计算方式如下:

NDVI 公式。图像由 CodeCogs 生成。

在我的案例中(Sentinel-2 图像),NIR 波段是第 10 个波段,红色波段是第 4 个波段。我可以应用上述公式,并绘制 NDVI 随时间的变化:

绘制特定位置的 NVMI。

3D 神经网络

深度学习方法已成功应用于遥感应用。特别是,3D 神经网络(3D-NN)非常适合对卫星图像时间序列进行预测。3D-NN 是一种接受 3D 输入的神经网络,而 SITS 是一种三维输入,因为它是 2D 图像的集合。例如,I. Gallo 等人创建了一个 3D 特征金字塔网络模型,用于执行 Sentinel-2 图像时间序列的作物绘图[1]。他们制作的架构以 30 张图像作为输入,每张图像具有 48 × 48 像素和 13 个波段,并返回 48 × 48 的分割掩膜。输出的每个像素包含在该位置生长的作物类别。

3D 特征金字塔网络。图像来源于 I. Gallo 等人

我最近的研究方向是使用深度学习模型分析 SITS。如果你有具体问题,请随时在评论中提问。

结论

卫星图像时间序列可以通过多种卫星平台获得,包括 Landsat、MODIS 和 Sentinel。这些图像通常按照定期的间隔获取,从每日到每月不等,具体取决于卫星平台和特定应用。生成的图像序列可以用于多种目的,包括改进作物管理、跟踪森林健康、监测气候变化对环境的影响、规划城市基础设施,以及协助受自然灾害影响的地区。SITS 可以通过不同的方式进行分析,具体取决于你希望突出的变化。

除非另有说明,所有图像均为作者提供。

[1] I. Gallo, R. La Grassa, N. Landro, M. Boschetti, 使用 3D 特征金字塔网络和时间域类别激活间隔进行作物映射的 Sentinel 2 时间序列分析 (2021)

什么是时间序列单位根?

原文:towardsdatascience.com/what-is-a-time-series-unit-root-dba24fa099f4

解答时间序列分析中的一个重要问题

Egor HowellTowards Data Science Egor Howell

·发布于数据科学前沿 ·阅读时间 7 分钟·2023 年 10 月 11 日

--

图片由Icons8 Team提供,来源于Unsplash

背景

单位根在时间序列和预测文献中时常出现(请原谅这个双关语)。

维基百科将单位根定义为:

“在概率论和统计学中,单位根是某些随机过程(如随机游走)的一个特征,这可能会在涉及时间序列模型的统计推断中引发问题。如果 1 是过程特征方程的根,则该线性随机过程具有单位根。这种过程是非平稳的,但不总是有趋势。”

是的,这对我来说也没什么意义……

然而,上述陈述让问题变得过于复杂,实际上单位根并不是一个难以理解的概念。

什么是平稳性?

概述

为了理解单位根,我们首先必须清楚地理解平稳性。我在之前的博客和 YouTube 视频中已经讲解过这个话题,但我们将快速回顾一下关键点。

## 时间序列平稳性简单解释

对时间序列建模中平稳性需求的简单直观解释。

[towardsdatascience.com

一个平稳时间序列具有以下特性:

  • 随时间的常数均值

  • 随时间的常数方差(自协方差)

  • 统计特性不变且一致

换句话说,时间序列在长期内既没有上升也没有下降趋势,其波动也没有随着时间的推移而增加或减少。

示例

以下是一个 Python 中非平稳时间序列的例子,其中均值和方差不断增加:

数据来源于 Kaggle并具有 CC0 许可证。

作者的代码 GitHub Gist。

由作者在 Python 中生成的图表。

通过差分(稳定均值)和对数变换(稳定方差),时间序列被转换为平稳。

有关这些变换的更多信息,请参见上面的博客或视频:

作者的代码 GitHub Gist。

由作者在 Python 中生成的图表。

注意图表中的均值和方差大致保持不变,并且在整个图表中没有变化。

我们为什么需要它?

平稳性的要求来源于我们如何构建预测模型。大多数模型,如ARIMA,要求数据来自相同的分布,以便能够拟合参数到潜在的分布上。

如果时间序列是平稳的,则具有一致的统计属性。这意味着数据点之间的联合分布不会改变,因此它们可以视为属于相同的分布。因此,这使我们能够拟合预测模型。

弱平稳与强平稳

我想讨论的最后一个概念是弱平稳强平稳之间的区别。这不是非常重要,但对理解平稳性的概念非常有用。

  • 弱平稳的: 如果均值和方差是恒定的,时间序列就是弱平稳的。

  • 强平稳的:如果数据点的联合分布随时间不变,则时间序列是强平稳的。换句话说,它们属于相同的分布。*

起初,这个概念可能会让人感到困惑,但让我给你举个例子。如果我们的时间序列具有恒定的均值和方差,并且是从正态分布中生成的,那么它既是弱平稳的也是强平稳的。这是因为正态分布是两个参数的函数:均值和方差。

然而,有些情况下,均值和方差是恒定的,但数据点可能都属于不同的分布。第一个数据点可能是泊松分布,第二个可能是指数分布等。在这种情况下,它是弱平稳的但不是强平稳的。

如果你想了解更多关于弱平稳性与强平稳性的知识,可以查看 这里

单位根解释

平稳性 — 单位根链接

平稳性如何与单位根相关?好吧,如果我们的时间序列 包含单位根,那么它就是非平稳的

大多数平稳性统计检验都是单位根检验,因为它们寻找单位根以确定时间序列在给定的置信水平下是否平稳。检验包括增强型迪基-福勒检验和菲利普斯-佩龙检验

一个简单的例子

展示单位根的最佳方法是通过简单的 AR(1) 模型,自回归模型 带有 1 个滞后:

AR(1)。方程由作者在 LaTeX 中生成。

其中:

  • y:是不同时间步的时间序列 t.

  • φ:是第一个滞后项的系数。

  • ε: 是均值为 0 和方差为 σ²* 的相同分布的随机变量的某种随机噪声。

上述方程可以通过递归将 AR(1) 模型重写为 MA(∞) (移动平均%20model.)) 过程:

AR(1) 递归替代。方程由作者在 LaTeX 中生成。

继续这种替代,我们得到:

AR(1) 作为 MA(∞)。方程由作者在 LaTeX 中生成。

上述方程可以简化为:

AR(1) 作为 MA(∞) 简化。方程由作者在 LaTeX 中生成。

现在,对于 AR(1) 方程,当 |φ| = 1.

对于具有更多滞后的模型,单位根变得更难定义,并依赖于特征方程(记住我们在维基百科定义中看到过这个!) 不用过于担心这个问题,因为它超出了本文的范围,并且不需要掌握单位根的直观理解。

所以,在单位根存在的情况下,方程变为:

AR(1) 带单位根。方程由作者在 LaTeX 中生成。

你们中的一些人可能会将其视为著名的随机游走。上述方程可以递归形式重写为:

AR(1) 带单位根重写。方程由作者在 LaTeX 中生成。

现在,上述方程的均值(期望值)为:

时间序列的期望值。由作者在 LaTeX 中生成的方程。

这是因为 ε 来自标准正态分布,其均值为 0,方差为 σ²。因此,y_t 的期望值就是 y_0。这是好的,因为均值是恒定的,我们满足了平稳性的具体要求。

方差怎么样?

好吧,从上述方程来看,y_0 的值没有方差,但 ε 的方差是 σ²。因此,方差为:

由作者在 LaTeX 中生成的方程。

见 [这里](https://rinterested.github.io/statistics/time_series_var_cov.html#:~:text=AUTOREGRESSIVE ORDER ONE (AR (1,[Xt−1].) 以获取上述公式的全面证明。

我们可以看到,方差依赖于 tVar(y_1)σ²Var(y_2)2σ² 等等。所以,方差随着时间的推移变大。

方差随着时间的推移在增加,因此根据定义,时间序列是非平稳的!

因此,我们得出结论,时间序列中存在单位根使其变得非平稳。

直观解释

再次考虑 AR(1) 方程:

AR(1)。由作者在 LaTeX 中生成的方程。

φ 告诉我们的是今天的值依赖于前一个值,加上一些来自标准正态分布的随机噪声。如果 φ < 1,那么时间序列将自然回归原点,如果我们的起点是 0, y_0 = 0。乘以一个小于 1 的数字会使其更小,最终趋向于 0。因为它总是会回归,所以它是可预测的,其方差不会随时间变化。

在单位根情况下,|φ| = 1,那么时间序列不会回归原点。如果我们有一段良好的正值运行,时间序列将简单地停留在那里,因为下一个预测等于最后一个值。

例如,假设我们有两个不同的 AR(1) 模型:

由作者在 LaTeX 中生成的方程。

方程 1 没有单位根,但 方程 2 有。假设这两个模型都从 y_0 = 0 开始。现在,经过一段时间,我们得到两个模型的 y_5 = 5。那么,接下来会发生什么呢?

由于误差 ε 的均值是 0方程 1 将慢慢回归原点,因此 y_6 = 4y_7 = 3.2 等等。然而,方程 2 将简单地保持在该水平上,y_6 = 5y_7 = 5 等等。

因此,单位根的存在使时间序列在长期内不可预测,并受到系统“冲击”的影响。这就是为什么我们认为它是非平稳的。

总结与进一步思考

单位根是时间序列分析的一个基本概念,可以说是平稳性的基础,而平稳性是构建许多预测模型时最基本的要求。如果时间序列的特征方程的任何解为 1,则该时间序列具有单位根。这导致方差随时间变化,从而破坏了平稳性的一个要求。因此,大多数平稳性统计测试都会寻找单位根,以决定时间序列是否平稳。重要的是,我们不需要记住所有有关单位根的数学,而是要理解关键概念以及为什么它会导致非平稳时间序列!

参考文献及进一步阅读

另一个事项!

我有一个免费的新闻通讯,Dishing the Data,在其中我分享每周的技巧,以帮助你成为更优秀的数据科学家。没有“空话”或“点击诱饵”,只有来自实际数据科学家的纯粹可操作的见解。

[## Dishing The Data | Egor Howell | Substack

如何成为更优秀的数据科学家。点击阅读 Dishing The Data,由 Egor Howell 主办的 Substack 出版物...

newsletter.egorhowell.com

与我联系!

解锁 Presto 分布式 SQL 的力量:全面指南

原文:towardsdatascience.com/what-is-apache-presto-6986d1fbf951

关于 Presto 及其在数据环境中的使用,你需要知道的一切

Niklas LangTowards Data Science Niklas Lang

·发表于 Towards Data Science ·7 分钟阅读·2023 年 1 月 6 日

--

图片由 Anish Prajapati 提供,来源于 Unsplash

Presto 是一个开源的分布式 SQL 引擎,适用于查询大量数据。它由 Facebook 于 2012 年开发,并随后根据 Apache 许可证开源。该引擎不提供自己的数据库系统,因此通常与知名的数据库解决方案一起使用,例如 Apache HadoopMongoDB

Presto 是如何构建的?

Presto 的结构类似于传统的数据库管理系统(DBMS),它们使用所谓的大规模并行处理(MPP)。这使用了执行不同任务的不同组件:

  • 客户端:客户端是每个查询的起始点和结束点。它将 SQL 命令传递给协调器,并从工作节点接收最终结果。

  • 协调器:协调器从客户端接收要执行的命令,并将其拆解以分析处理的复杂程度。他规划或协调多个命令的执行,并在调度员的帮助下监控它们的处理。根据执行计划,命令随后会传递给调度员。

  • 调度员:调度员是协调器的一部分,最终负责将命令传递给工作节点。它根据协调器创建的计划监控命令的正确执行。

  • 工作节点:工作节点负责实际执行命令,并通过连接器从数据源接收结果。最终结果会传回客户端。

  • 连接器:连接器是支持的数据源的接口。它们了解不同数据库和系统的特殊性,因此可以调整命令。

Presto 有哪些应用?

当连接存储大量数据的不同数据源时,可以使用此 SQL 引擎。这些数据源,即使是非关系型数据库,也可以使用经典 SQL 命令进行控制。Presto 通常用于大数据领域,在那里低查询时间和高性能至关重要。它也可以用于对数据仓库的查询。

在行业中,许多知名公司已经依赖于 Presto。除了发明该查询引擎的 Facebook 外,还包括例如:

  • Uber 使用 SQL 查询引擎处理其超过 59PB 的数据湖仓库。各种数据科学家以及普通用户需要能够在短时间内访问这些数据。

  • 在 Twitter,数据量的急剧增加也成为了一个成本问题,因为 SQL 查询费用上升。因此,SQL 查询引擎被用来水平扩展系统。此外,还训练了一个机器学习模型,该模型可以在查询执行之前预测预期的查询时间。

  • 阿里巴巴依靠 SQL 查询引擎构建其数据湖

所有这些示例均取自Presto 网站上的用例部分

使用 Presto 有哪些优势?

Presto 在处理大量数据时提供了几个优势,包括:

开源

开源的可用性不仅提供了在没有许可费用的情况下使用该工具的可能性,而且源代码也可以查看,并且在有足够技术知识的情况下可以根据自身需求进行定制。

此外,开源程序通常还有一个大型活跃的社区,因此问题通常可以通过快速的互联网搜索解决。这些 Presto 的活跃用户也确保系统不断被开发和改进,从而使所有其他用户都受益。

高性能

由于其架构,这个 SQL 查询引擎也可以在几秒钟内查询大量数据,并且不会有较长的延迟。这种高性能得益于分布式架构,使系统能够进行水平扩展。

此外,Presto 可以在本地和云端运行,因此如果需要,将其迁移到云端可以进一步提升性能。

高兼容性

通过使用结构化查询语言,Presto 对许多用户来说非常易用,因为查询语言的处理已经熟悉,并且这一知识仍然可以使用。这使得即使是复杂的功能也能轻松实现。

兼容性通过各种可用的连接器进一步得到保证,这些连接器支持常见的数据库系统,如MongoDBMySQLHadoop 分布式文件系统。如果这些连接器不够,还可以配置或编写自定义连接器。

如何使用 Presto 查询数据?

使用 Presto 查询涉及连接到数据源并执行 SQL 查询。以下是使用 Presto 查询的基本步骤:

  • 安装:在集群或单台机器上安装 Presto。你可以从官方网站下载最新版本。

  • 配置:配置系统以连接到你想要查询的数据源。为此,你需要设置每个数据源的连接器,指定认证信息,并设置所需的参数。

  • 建立连接:使用客户端连接到 Presto 集群或机器。Presto 客户端可以是命令行界面或像 Presto CLI 或 SQL Workbench 这样的 GUI 工具。

  • 执行 SQL 查询:一旦连接成功,你可以对数据源执行 SQL 查询。这些查询可以是简单的 SELECT 语句,也可以是更复杂的查询,包括 JOIN、GROUP BY 和子查询。

  • 优化查询:Presto 提供了多种优化查询的选项,如设置节点数量、配置内存限制,以及使用查询优化技术,如基于成本的优化和动态过滤。

  • 监控查询执行:程序提供了多种监控查询执行的工具,如 CLI、Web 界面和查询日志。你可以使用这些工具跟踪查询的进展、监控资源使用情况并解决任何问题。

总之,使用 Presto 查询涉及连接数据源、执行 SQL 查询以及优化查询以提高性能。凭借其快速的查询执行和对多数据源的支持,该软件可以成为大数据处理和分析的宝贵工具。

Presto 和 Hadoop 如何一起使用?

Presto 本身没有内置的数据源来存储信息。因此,它依赖于使用其他外部数据库。在实践中,通常会使用Apache HadoopHadoop 分布式文件系统 (HDFS)来实现这一目的。

Hadoop 组件概览 | 来源:作者

HDFS 和 Presto 之间的连接是通过 Hive Connector 建立的。主要优点是 Presto 可以轻松搜索不同的文件格式,因此可以搜索所有 HDFS 文件。由于 Presto 针对快速查询进行了优化,而 Hive 不能提供这种优化,因此 Presto 经常被用作 Hive 的替代方案。

Presto 和 Spark 之间有什么区别?

Apache Spark 是一个分布式分析框架,可用于许多不同的 大数据 应用。它依赖于内存数据存储和进程的并行执行,以确保高性能。它是市场上最全面的 大数据 系统之一,提供批处理、图形数据库以及对 机器学习 的支持等功能。

Apache Spark 组件 | 来源:作者

它经常与 Presto 一起提及,甚至被理解为 Presto 的竞争对手。然而,这两个系统非常不同,相似之处不多。这两个程序都是在处理 大数据 时可用的开源系统。由于它们的分布式架构和扩展能力,它们都可以提供良好的性能。因此,它们既可以在本地运行,也可以在云中运行。

然而,除了这些(尽管相当少的)相似之处外,Apache Spark 和 Presto 在一些基本特征上有所不同:

  • Spark Core 目前不支持 SQL 查询,您需要额外的 SparkSQL 组件。另一方面,Presto 是一个用于 SQL 查询的引擎。

  • Spark 提供了非常广泛的应用可能性,例如,还可以通过构建和部署完整的机器学习模型来实现。

  • 另一方面,Presto 主要专注于对大数据量的快速查询处理。

这是你应该带走的内容

  • Presto 是一个开源的分布式 SQL 引擎,适用于查询大量数据。

  • 该引擎可以用于需要快速响应时间和低延迟的分布式查询。

  • Presto 与 Apache Spark 的区别在于它主要专注于数据查询,而 Spark 提供了广泛的应用能力。

  • 由于 Presto 没有自己的数据源,它通常与 Apache Hadoop 一起使用,作为它们 Hive Connector 的替代方案。

如果你喜欢我的作品,请订阅 这里 或查看我的网站 Data Basecamp!另外,medium 允许你每月免费阅读 3 篇文章 。如果你希望获得 无限 的访问权限,并查看我和其他许多精彩文章,请不要犹豫,通过点击我的推荐链接获取每月 $5 的会员资格: medium.com/@niklas_lang/membership

## 每个新数据科学家应该知道的 4 个基本 SQL 命令

结构化查询语言简介

towardsdatascience.com ## 8 个每个新手数据科学家应该知道的机器学习算法

简要解释机器学习背后的算法

towardsdatascience.com ## 数据库基础:ACID 事务

理解数据库的 ACID 属性

towardsdatascience.com

什么是贝叶斯误差?

原文:towardsdatascience.com/what-is-bayes-error-4bfadcc9c0ad?source=collection_archive---------5-----------------------#2023-06-06

对机器学习基本概念的简单介绍

Wanshun WongTowards Data Science Wanshun Wong

·

关注 发表在 Towards Data Science ·6 分钟阅读·2023 年 6 月 6 日

--

作者提供的图片

在做出不同的决定和估计时,例如

  • 决定是否开始或继续进行项目,

  • 估计项目的业务影响,

  • 选择提高模型性能的主要策略,

最重要的考虑因素之一是模型性能改善的空间有多大。例如,假设我们有一个二分类模型,其准确率为 85%。我们可能会认为仍然有很多改进的空间,并承诺在几周内提高至少 5% 的准确率。然而,这种从“85% 准确率”到“改进空间很大”的思维过程隐含假设了最佳模型性能是 100% 准确率。不幸的是,这种假设通常是不真实的,导致我们对项目有误解并做出错误决策。

在本文中,我们将重点关注二分类设置,并使用误差率(即 1 - 准确率)作为我们的模型性能指标。然后,为了对减少模型误差率的空间进行良好的估计,我们将使用一个被称为贝叶斯误差(也称为贝叶斯误差率)的概念。

贝叶斯误差的定义

数据集的贝叶斯误差是任何模型能够达到的最低可能误差率。特别是,如果贝叶斯误差非零,那么两个类别之间有一些重叠,即使是最好的模型也会有一些错误的预测。

数据集存在非零贝叶斯误差可能有很多原因。例如:

  • 数据质量差:计算机视觉数据集中某些图像非常模糊。

  • 标记错误的数据

  • 标记过程不一致:在决定是否将求职者进入下一轮面试时,不同的面试官可能有不同的意见。

  • 数据生成过程本质上是随机的:例如,从掷硬币中预测正面或反面。

  • 特征向量中缺少信息:在预测婴儿是否具有某些遗传特征时,特征向量包含父亲的信息而没有母亲的信息。

通常情况下,无法计算贝叶斯误差的确切值。然而,存在几种估计方法。我们将介绍的方法是最简单的一种,它基于软标签。

软标签

首先,让我们用 0 和 1 表示数据集中的两个类别。我们数据集中每个实例的类别标签都在 {0, 1} 集合中,并且没有中间状态。在文献中,这被称为硬标签(以与软标签对比)。

软标签通过允许中间状态并结合我们对类别标签的信心(以及不确定性)来泛化硬标签。它定义为实例属于类别 1 的概率:

*s_i = p*(*y* =1 *| x_i*)

特别是,s_i 取值范围在 [0, 1] 内。以下是一些示例:

  • s_i = 1 意味着我们 100% 确信该实例属于类别 1。

  • s_i = 0 意味着我们 100% 确信该实例属于类别 0,因为它属于类别 1 的概率为 0%。

  • s_i = 0.6 意味着我们认为实例更可能属于类别 1,但我们不是很确定。

注意我们总是可以通过检查s_i > 0.5 来将软标签转换为硬标签。

如何获得软标签

获取软标签的几种常见方法:

  • 最明显的方法是要求我们的数据集标注者提供类别标签及其对标签的置信水平。

  • 如果我们有多个标注者,我们可以要求他们为每个实例提供硬标签。然后我们可以将硬标签的比例作为软标签。例如,如果我们有 5 个标注者,其中 4 个认为x_i属于类别 1,剩下的一个认为x_i属于类别 0,那么s_i = 0.8

  • 如果类别标签来源于某些数据源,那么我们可以使用相同的数据源来计算软标签。例如,我们想预测一个学生是否能通过考试。假设考试总分为 100,及格分数为 50 或更高。因此,硬标签通过检查score ≥ 50 获得。为了计算软标签,我们可以应用如 Platt 缩放之类的校准方法到score

估计贝叶斯误差

从直观上讲,不难相信贝叶斯误差与软标签是相关的。毕竟,如果对类别标签存在不确定性,那么即使是最好的模型也会产生一些错误预测。使用软标签估计贝叶斯误差的公式非常简单:

*β* = (1 / n) · ∑ min(s_i, 1 - s_i)

这是 min(s_i, 1 - s_i)的平均值。这个公式的简便性使其易于使用,并适用于许多数据集。

具体示例

  • 首先,让我们考虑极端情况,其中软标签为 0 或 1。这意味着我们对类别标签 100%确定。术语 min(s_i, 1 - s_i)始终为 0,因此β也为 0。这与我们的直觉一致,即最好的模型能够避免对该数据集产生错误预测。

  • 考虑一个更有趣的情况,我们有 10 个实例,软标签为 0.1、0.2、0.3、0.4、0.5、0.6、0.7、0.8、0.9、1。然后

β = (1 / 10) · (0.1 + 0.2 + 0.3 + 0.4 + 0.5 + 0.4 + 0.3 + 0.2 + 0.1 + 0)
  = 0.25 

利用贝叶斯误差

对贝叶斯误差有一个良好的估计不仅可以让我们更好地理解数据集,还可以在以下方面帮助我们:

了解模型性能改进的空间

让我们回顾一下本文开头给出的例子。我们的模型准确率为 85%,这意味着错误率为 15%。假设贝叶斯误差估计为 13%。在这种情况下,改进的空间实际上只有 2%。最重要的是,我们不应该向老板承诺模型性能提高 5%。

确定我们是否需要新的数据集

我们的机器学习项目通常有最低模型性能要求。例如,我们的模型误差率要求 ≤ 10%,以免客服团队过于繁忙。如果我们数据集的贝叶斯误差估计为 13%,那么我们应该寻找新的数据集,而不是改进模型。也许我们需要更好的相机和传感器来收集数据,或者需要新的数据源来增加特征向量中的独立变量。

理解偏差-方差权衡

假设我们的模型训练误差为 8%,测试误差为 10%。如果我们知道贝叶斯误差接近 0%,则可以得出结论,训练误差和测试误差都很大。因此,我们应该尝试减少模型的偏差。

另一方面,如果贝叶斯误差为 7%,则

Training Error - Bayes Error = 1% < Test Error - Training Error = 2%

我们应当改进方差部分。

进一步阅读

  1. 上述贝叶斯误差估计公式在[2]中介绍。我们参考那篇论文了解公式的各种理论属性,如收敛速率。

  2. Andrew Ng 的讲座 应用深度学习的基本原理 讨论了将人类水平的表现作为贝叶斯误差的代理。

  3. 贝叶斯误差量化了给定任务的不可减少误差。模型误差的偏差、方差和不可减少误差的分解(包括零一损失函数和其他损失函数)在[1]中进行了研究。

  4. [3] 证明了训练于软标签上的分类器对样本外数据集的泛化能力更强,且对对抗攻击的抵抗力更强。

参考文献

  1. P. Domingos. 统一的偏差-方差分解及其应用 (2000),ICML 2000。

  2. T. Ishida、I. Yamane、N. Charoenphakdee、G. Niu 和 M. Sugiyama. 我的深度网络表现是否过于完美?一种直接估计二分类贝叶斯误差的方法 (2023),ICLR 2023。

  3. J.C. Peterson、R.M. Battleday、T.L. Griffiths 和 O. Russakovsky. 人类不确定性使分类更加稳健 (2019),ICCV 2019。

什么是商业智能?

原文:towardsdatascience.com/what-is-business-intelligence-bf1de730319c?source=collection_archive---------5-----------------------#2023-08-04

发现应用于供应链优化的数据驱动决策工具。

Samir SaciTowards Data Science Samir Saci

·

关注 发布于 Towards Data Science ·11 分钟阅读·2023 年 8 月 4 日

--

什么是商业智能?——(作者提供的图片)

商业智能是一个利用软件和服务将数据转化为支持决策的可操作情报的过程。

这种智能帮助企业洞察其运营情况,提高流程效率,并创造竞争市场优势。

商业智能过程的五个步骤——(作者提供的图片)

商业智能工具结合了多种应用,包括数据仓库、发现和可视化。

如何使用分析解决方案创建一个集中且和谐的数据源?

目标是通过将原始数据转换为总结性的洞察,以简化数据分析,从而进行战略决策。

在本文中,我们将探讨商业智能的概念,以理解它如何支持持续的运营改进,以实现更高效和可持续的供应链

💌 免费订阅新文章直达你的收件箱:新闻通讯

📘 你的供应链分析完整指南:分析备忘单

Summary
I. What is Business intelligence?
  1\. Distribution Operations for Fashion Retail
  2\. Business Intelligence for Operational Management
  3\. Business Intelligence is not Advanced Analytics
  4\. Supporting Operational Performance Improvement
II. The Mechanics of Business Intelligence
  1\. What is a Data Warehouse?
  2\. A central source of harmonized data for reporting
III. Why is Business Intelligence Significant?
  1\. Answering a simple business question
  2\. Become a data-driven green organization
  3\. Automate ESG Reporting
IV. Conclusion
  1\. Generative AI to boost Business Intelligence

什么是商业智能?

这可以定义为用于分析组织原始数据的一系列软件应用程序。

时尚零售的分销操作

我们可以用一个国际服装集团的例子来说明,该集团在全球范围内都有门店。

供应链网络 — (作者提供的图片)

门店从本地仓库交付,这些仓库由在亚洲生产服装的工厂补给。

作为分销计划经理,你会希望测量交付门店的提前期从订单创建到门店交付的时间)。

系统架构 — (作者提供的图片)

多个 IT 系统协调整个分销过程。

带有时间戳的交易数据会在这些系统的数据库中创建和存储。

分销过程时间戳 — (作者提供的图片)

  • ERP中创建订单后,第二个时间戳记录订单传输到WMS的时间。

  • 然后,订单由WMS跟踪,从准备到装载。

    [从开始准备到卡车离开]

  • 运输部分由TMS管理,时间戳跟踪货物直到商店交付

    [从到达机场到商店交付]

我们如何利用这些数据来分析过去的事件?

运营管理的商业智能

BI 可以帮助将这些数据转换为有意义的信息,以支持运营或战略决策的描述性和诊断性分析。

对于每个时间戳,BI 解决方案可以帮助自动比较预计时间与实际时间以检测延迟发生的地方。

两个货运示例(准时:顶部,延迟:底部)— (作者提供的图像)

目标是提供报告、仪表盘和数据可视化,自动向运营团队提供洞察。

让我们以跟踪交货订单为例

  • 订单创建时间: 21–04–2020 11:00

  • 订单接收预计时间: 21–04–2020 12:30

    订单接收实际时间戳: 21–04–2020 12:04 [准时]

  • 订单拣货预计时间: 21–04–2020 14:30

    订单拣货预计时间: 21–04–2020 15:12 [延迟]

你可以继续这个过程直到商店交付。

基于这些时间戳,你可以创建自动化规则:

  • 如果实际交货日期晚于预计日期,则为迟交货

  • 对于每个过程,如果实际日期晚于预计日期,你可以将其添加到原因代码列表中

    例如:由于[传输、装载、海关清关]导致的延迟交货

延迟交付根本原因分析 — (作者提供的图像)

这个甜甜圈图是一个显示迟到的商店交付不同根本原因的视觉示例

  • 1,842 个运输订单已被延迟交付

  • 37%的延迟仅由于订单传输问题

欲了解更多详细信息,可以查看这些简短的解释视频

为什么我们需要商业智能?

商业智能不是高级分析。

商业智能并不是为了建议操作最佳缓解计划或预测未来表现。

BI 与高级分析 — (作者提供的图像)

商业智能提供描述性和诊断性分析解决方案,专注于“理解过去的事件”。

  • 发生了什么? 有多少订单存在延迟交付?

  • 什么时候? 订单 1878497 是否已在仓库装载?

  • 谁? 上周哪个承运商交付了 12 号商店?

  • 为什么? 为什么订单 1878497 在机场晚到 1 小时?

商业智能与高级分析 — (作者提供的图像)

其他类型的分析,利用过去的数据提供预测和建议,更为先进,但仍需建立业务智能的基础。

支持操作绩效改进

然而,这种视觉辅助工具帮助计划经理更好地理解他们的数据,识别模式,并提取见解。

  • 37.8%的货物因传输问题而被耽搁

    行动:“我应该联系 IT 团队解决这些问题。”

  • 3.3%的货物因装载延迟而被耽搁

    行动:“与仓库运营对齐以增加装载能力

通常,BI 解决方案包含在一个绩效管理过程中,在该过程中数据被用来

  • 了解过去:衡量绩效,检测问题

  • 实施缓解计划优化流程增加资源,解决 IT 问题

  • 跟踪操作改进:实施关键绩效指标(KPI),记录问题

在接下来的部分,我们将深入探讨业务智能的细节以及如何在您的公司中实施它。

💡 关注我在 Medium 上的文章,获取更多关于 🏭 供应链分析、🌳 可持续发展和 🕜 生产力的内容。

业务智能的机制

业务智能平台传统上基于一个数据仓库,该数据仓库将来自多个来源的数据汇聚到一个集中源中。

什么是数据仓库?

这种整合简化了业务分析和报告。

数据仓库将来自多个来源的数据进行合并 —— (图像由作者提供)

在我们的示例中,我们试图跟踪配送订单:

  • ERP中创建,包含创建日期、预期交货日期、目的地、SKU、数量等

  • 传输到仓库管理系统(WMS),该系统跟踪订单接收时间、订单拣选时间和订单发货时间。

  • 运输管理系统(TMS)管理,以跟踪从仓库装载到商店交付的运输过程。

BI 解决方案与这些系统互动,以:

  • 处理并将获取的数据转换为一个统一的和谐源

  • 创建用户友好的报告、图表和地图

数据处理的简单示例用于和谐化 —— (图像由作者提供)

在这个简单的示例中,

  • 数据存储在三个不同的表中(来自WMSERPTMS),这些表有一个共同的键:订单编号

  • 通过合并这三张表格创建的协调数据集,用于获取从订单创建到店铺交付的完整流程。

结果是什么?

报告的中央真实来源

利用这个协调表格,我们可以通过查看最后一个非空时间戳来按状态分类订单。

可以实施自动化规则来标记订单

  • 如果交货时间为空,我们有 订单状态 = 运输中

  • 最后一个非空时间戳用于标记状态

    例如,如果之前的非空时间戳是订单拣货时间:订单状态 = 拣货包装

运输订单图表 — (作者提供的图像)

这个协调数据源是数据分析旅程的基石,因为它还可以提供支持

四种分析类型 — (作者提供的图像)

这些解决方案虽然超出了商业智能的范围,但仍依赖于商业智能解决方案建立的协调清理数据集。

在下一部分,我们将了解为什么商业智能对公司数字化转型如此重要。

💡 关注我在 Medium 以获取更多关于 🏭 供应链分析、🌳 可持续性和 🕜 生产力的文章。

为什么商业智能如此重要?

商业智能使组织能够将数据 转化为 可操作的洞察

公司还可以开发一个实际操作问题并寻求商业智能团队的帮助

让我们通过绿色转型的例子来说明这一点,这是我们时尚零售公司的实例。

回答一个简单的业务问题

公司的环境足迹的主要指标是生产、交付和销售产品过程中产生的二氧化碳排放量。

我们操作的环境影响是什么?

为了衡量这一点,BI 可以用于在供应链中创建单一的真实来源,并跟踪不同业务单元和时间段的排放。

什么是生命周期评估?

生命周期评估(LCA)是一种用于评估产品环境影响的方法。

生命周期评估 —(作者提供的图像)

它涵盖了从原材料提取到处置(生命周期结束)的整个生命周期。

正如你可以想象的,这种方法主要依赖于汇总和处理来自多个来源的数据。

成为一个数据驱动的绿色组织

我们的时尚零售商可以依靠 BI 成为一个绿色数据驱动的公司,通过在供应链中实施可持续性指标。

数据仓库可以集中来自多个来源的数据,以跟踪生命周期每一步的环境影响。

跟踪环境影响的数据架构 — (作者提供的图片)

  • 通过连接到工厂系统来测量生产输出

  • 从 Excel 文件中收集工厂、仓库和供应商的公用事业和原材料数据使用情况

  • 通过API接收物流公司提供的二氧化碳排放、燃料消耗和路线数据

你无法管理你无法测量的事物。

数据处理结果将提供从产品角度的环境足迹的详细视图。

例如,

  • 每件 T 恤的水消耗量为 3,500 升/单位

  • 25%的二氧化碳排放来自海运

  • 每件 T 恤的生产中排放 0.8 克 SOx 和 0.5 克 NOx

供应链中与 LCA 相关的 KPI 示例 — (作者提供的图片)

这些指标可用于制定可持续发展路线图:

  • 提高制造设施的效率,考虑每单位产品的水和能源使用

  • 挑战你的货运代理并跟踪他们的排放,以减少运输的足迹

  • 改善原材料采购以减少用水量

💡 欲了解有关环境足迹可视化解决方案的更多详细信息,

[## 什么是生命周期评估?LCA]

了解生命周期评估如何帮助企业评估产品在整个生命周期中的环境影响...

towardsdatascience.com](/what-is-a-life-cycle-assessment-lca-e32a5078483a?source=post_page-----bf1de730319c--------------------------------) [## 使用 Python 进行供应链可持续性报告]

4 个步骤来建立关于分销网络二氧化碳排放的 ESG 报告。了解如何测量和减少碳...

towardsdatascience.com](/supply-chain-sustainability-reporting-with-python-161c1f63f267?source=post_page-----bf1de730319c--------------------------------)

提高贵公司的 ESG 评分。

支持公司 ESG 报告

商业智能可以大力支持 ESG 报告,因为它主要依赖于清晰和可信的数据。

报告类别示例 — (作者提供的图片)

组织利用这种非财务报告向利益相关者和金融机构传达其环境绩效(E)、社会责任(S)以及治理结构的强度(G)

一家公司可能会报告

  • 供应链的碳排放(E)

  • 社区发展倡议(S)

  • 董事会成员的多样性(G)

随着客户和投资者对可持续性认识的提高,企业将越来越多地投资于先进的商业智能能力,以自动化此类报告。

💡 有关 ESG 报告数据分析的更多细节,

## 什么是 ESG 报告?

利用数据分析实现公司环境、社会和治理的全面而有效的报告

towardsdatascience.com

结论

最有效的 BI 工具促进运营管理,发现问题并支持你的业务转型之旅。

连接到各种数据系统可以提供有价值的见解,并揭示隐藏的模式。

商业智能工具提供描述性分析(仪表板、报告)的解决方案,并创建一个值得信赖的数据中心,供更高级的预测或处方算法使用。

你听说过生成式 AI 吗?

2022 年 11 月,OpenAI 发布了 ChatGPT 的第一个版本。

生成式 AI 已成为利用大型语言模型提升任何分析产品用户体验的机会。

想象一下用一个连接到智能代理的提示替代一个静态的“无聊”提示。

使用 LangChain SQL 代理的供应链控制塔代理 [文章链接] — (作者图片)

这个案例研究 中,我分享了我第一个使用 LLMs 来提升供应链分析的项目。

用户:昨天有多少订单延迟交付?

代理:[SQL 查询] → 24 个订单昨天延迟交付

这个代理可以通过自动查询数据库回答任何用简单英语书写的问题。

这是商业智能的未来,将提升仪表板和报告的用户体验。

有关我如何实现这个解决方案的更多细节,请查看这篇文章,

## 使用 LangChain 的 LLMs 进行供应链分析——一个由 GPT 驱动的控制塔

构建一个与运输数据库连接的 LangChain SQL 代理的自动化供应链控制塔……

[towardsdatascience.com

💡 关注我在 Medium 以获取更多关于 🏭 供应链分析,🌳 可持续性和 🕜 生产力的文章。

关于我

让我们在 LinkedinTwitter 上联系。我是一名供应链工程师,利用数据分析来改善物流操作和降低成本。

如果对数据分析和供应链感兴趣,可以查看我的网站。

[## Samir Saci | 数据科学与生产力]

一个专注于数据科学、个人生产力、自动化、运筹学和可持续性的技术博客……

samirsaci.com

参考文献

  • 什么是供应链数字双胞胎?,Samir Saci,数据科学前沿

  • 什么是供应链分析?,Samir Saci,数据科学前沿

  • 什么是供应链控制塔?,Samir Saci,数据科学前沿

  • 什么是生命周期评估?,Samir Saci,数据科学前沿

  • 使用 Python 进行供应链可持续性报告,Samir Saci,数据科学前沿

什么是数据质量?

原文:towardsdatascience.com/what-is-data-quality-f2c0274a6404?source=collection_archive---------7-----------------------#2023-08-15

发现确保供应链数据准确性、一致性和完整性的方法论

Samir SaciTowards Data Science Samir Saci

·

关注 发表在 Towards Data Science · 11 分钟阅读 · 2023 年 8 月 15 日

--

什么是数据质量? — (作者提供的图片)

数据质量定义了数据集如何被信任、理解和有效利用于其预期目的。

你如何管理你系统生成的数据?

供应链系统创建和交换信息 — (作者提供的图片)

确保数据准确、一致并适合其预期目的对于确保供应链管理的顺畅和高效至关重要。

你们组织中有哪些流程来确保良好的数据质量?

在这篇文章中,我们将深入探讨数据质量的概念,探索其维度并理解其在供应链管理中的重要性。

💌 新文章免费直接送到您的邮箱:Newsletter

📘 您的供应链分析完整指南:Analytics Cheat Sheet

Summary
I. The Pillars of Data Management
1\. Why is it key?
2\. Quality vs. Integrity vs. Profiling
II. What are the 6 Dimensions of Data Quality?
1\. **Completeness**: do we have all the data?
2\. **Uniqueness**: are features all unique?
3\. **Validity**: is the format respecting business requirements?
4\. **Timeliness**: up-to-date data
5\. **Accuracy**: does it reflect reality correctly?
III. Next Steps
**1\. Data Quality for Environemental Reporting: ESG & Greenwashing**
**2\. Generative AI: Automate Data Quality Check with GTP Agent**
3\. Conclusion

数据管理的支柱是什么?

为什么数据管理至关重要?

高质量的数据可能是您供应链运营成功与失败的分水岭。

从规划和预测到采购和物流,供应链管理的每个方面都依赖数据来有效运行。

供应链系统创建和交换信息 — (作者提供的图片)

  • 规划和预测算法依赖于WMS和 ERP 数据,以获取历史销售、库存水平和商店订单。

  • 运输管理系统依赖 WMS 数据来正确跟踪从仓库到商店的货物。

有哪些不同类型的分析?

供应链分析解决方案可以分为四种类型,每种类型提供不同级别的洞察和可见性。

四种类型的供应链分析 — (作者提供的图片)

描述性解决方案 通常代表您数字化转型的第一步:收集、处理和可视化数据。

一切都始于数据收集和处理,以分析您的过往表现。

不良数据对描述性解决方案的影响是什么?

让我们以一家时尚零售公司的门店配送过程为例。

零售公司配送过程的时间戳分析 — (作者提供的图片)

一个简单的操作指标是准时交付的订单百分比:On Time In Full: OTIF

OTIF 计算的数据处理简单示例 — (作者提供的图片)

这个指标可以通过合并交易表来建立

  • 用于订单创建的企业资源计划(ERP)

  • 仓库管理系统(WMS)用于订单准备

  • 用于订单交付的运输管理系统(TMS)

为什么我们在这里关注数据质量?

如果不确保数据的正确性,就不可能

一个无法自信测量的指标是无法分析和改进的。

质量、完整性和分析有什么区别?

在深入探讨数据质量之前,理解数据质量如何与相关概念如数据完整性数据分析有所不同是至关重要的。

数据完整性是数据质量的一个子集 —(作者提供的图片)

尽管这三者是互相关联的,但它们关注的领域各有不同

  • 数据完整性关注于在数据的整个生命周期内保持其准确性一致性

  • 数据分析涉及检查清理数据,以保持其质量

数据分析不应与数据挖掘混淆。

数据挖掘与数据分析 —(作者提供的图片)

  • 数据分析将重点关注数据的结构和质量,检查异常值、分布或缺失值。

  • 数据挖掘侧重于从数据中提取业务和运营洞察,以支持决策制定或持续改进计划。

现在我们已经澄清了这些差异,我们可以专注于定义数据质量。

数据质量的 6 个维度是什么?

数据质量是基于多个维度来评估的,这些维度在保持数据的可靠性和可用性方面发挥着至关重要的作用。

数据质量的 6 个维度 —(作者提供的图片)

数据完整性:我们是否拥有所有的数据?

目标是确保所有必要数据的存在。

缺失的数据可能导致误导性的分析和差劲的决策。

示例:主数据中的缺失记录

在公司中,主数据管理 (MDM)是确保不同部门之间数据一致性和完整性的关键方面。

示例主数据管理 —(作者提供的图片)

主数据专家在项目创建过程中将与产品相关的信息输入到 ERP 系统中。

  • 产品信息:净重、尺寸等

  • 包装:总重量、尺寸、语言等

  • 处理单位:每(箱、托盘)的物品数量、托盘高度

  • 商品销售:供应商名称、采购成本、市场定价

这些数据专家可能会犯错,主数据中可能会存在缺失的数据。

缺失数据可能带来哪些问题?

  • 缺失净重:与运输管理相关的问题,因为我们需要重量用于开票海关清关

  • 缺失成本:你的采购部门无法向供应商发送采购订单

价值链中的许多其他问题,从原材料采购到商店交付

💡 我们如何检查它?

  • 空值分析:识别和统计数据集中空值或缺失值的数量

  • 领域特定检查:确认每个预期的数据类别是否存在。

    例如,如果一个列本应包含五个不同的类别而仅出现四个,这将表明缺乏完整性。

  • 记录计数:比较数据集中的记录数与预期记录数

  • 外部数据源比较:使用已知完整的外部数据源作为基准

现在我们的数据完整,让我们去除重复项。

数据唯一性:特征是否都唯一?

目标是确保每条数据条目都是唯一的且没有重复。

我们希望准确地表示数据的全貌。

示例:用于 CO2 报告的运输货物

投资者和客户对可持续发展的透明度需求增长。

因此,公司正在投资分析解决方案,以评估其环境足迹。

第一步是测量 其运输的 CO2 排放 网络。

CO2 报告的数据处理 —(图片来源:作者)

运输和主数据记录从 ERP 系统中提取,并且从 WMS 中提取。

它们涵盖从仓库到商店或最终客户的订单范围。

我们可能面临哪些重复数据的问题

如果我们有重复的运输记录,可能会高估 运输的 CO2 排放,因为我们可能会多次计算排放。

💡 我们如何检查它?

  • 重复记录识别:使用 Python 的 Pandas 或 SQL 的功能识别重复记录

  • 关键约束分析:验证数据库中的主键是否唯一

有效性:格式是否符合业务要求?

目标是验证数据是否符合所需的格式和业务规则。

示例:生命周期评估

生命周期评估 (LCA) 是一种评估产品或服务在其整个生命周期内环境影响的方法。

它严重依赖于数据质量。

在下面的示例中,我们从不同来源收集数据,以估算生产和交付 T 恤所使用的公用设施和自然资源。

时尚零售生命周期评估的数据要求 —(图片来源:作者)

  • 生产管理系统提供每个时期的 T 恤数量

  • 垃圾库存、公用设施和平面 Excel 文件中的排放

  • 距离、路线和来自承运人 API 的 CO2 排放

最终结果,即一件 T 恤的整体环境足迹,取决于每个数据源的可靠性。

我们可能面临哪些无效数据的问题?

  • 如果某些记录的燃料消耗是(L/Shipment),而其他记录是(Gallons/Shipment),那么总评估将是错误的。

  • 如果不确保所有的公用事业消耗是按月的,就无法评估每单位生产的消耗。

💡 我们如何检查它?

  1. 数据类型检查:数据中的每个字段都是预期的数据类型

  2. 范围检查:将值与预期范围进行比较

  3. 模式匹配:对于像电子邮件或电话号码这样的数据,可以使用正则表达式来匹配预期的模式

时效性:数据是否是最新的?

目标是确保数据在预期时间范围内的准备情况。

示例:过程挖掘

过程挖掘 是一种分析方法,专注于发现、监控和改善运营和业务流程。

时间戳收集——(作者提供的图像)

在上述示例中,我们在订单到交付的每一步收集带时间戳的状态(来自不同系统)

如果我们没有及时获得数据,会面临什么问题?

  • 状态可能需要正确更新。

    这可能在追踪货物时产生“空白”。

    例如,我的货物在凌晨 12:05 送达,但状态仍显示“打包中”。

  • 事件可能会被报告

💡 我们如何检查它?

  • 时间戳分析:检查所有时间戳是否落在预期的时间范围内

  • 实时数据监控:监控数据流,当出现中断时生成警报

准确性:是否正确反映了现实?

目标是确保数据值的正确性。

这对于维持数据驱动决策的信任是必需的。

示例:零售销售预测的机器学习 这些算法使用历史销售数据记录来预测未来 X 天的按店铺和商品代码的销售情况。

零售销售预测的机器学习——(作者提供的图像)

对于这种业务案例,数据准确性比你预测模型的复杂程度更为重要(基于树的,深度学习,统计预测,…)。

不准确数据可能面临什么问题?

  • 错误的历史销售数据由于数据输入错误或系统故障可能会影响模型的性能。

  • 这可能导致库存过剩或缺货,产生财务和商业影响。

💡 我们如何检查它?

  • 来源验证:与其他权威来源交叉验证数据,以确保信息准确

  • 数据审计:定期审计数据可以通过手动检查数据记录样本来帮助发现不准确之处

一致性:它是否正确反映了现实?

目标是评估来自不同数据集的记录,以确保一致的趋势和行为。

💡 如何执行?

  1. 数据标准化:执行严格的数据录入和格式规范以确保一致性。

  2. 自动数据清洗:实施自动化工具或脚本来清洗和标准化数据。

  3. 错误报告:建立一个稳健的错误报告和解决流程。

这些示例为你提供了足够的洞见,以了解如何在你的组织中实施数据质量检查。

下一步

如果你的公司投资于供应链数字化转型,数据质量不再是奢侈品,而是必要条件。

这应纳入你的战略路线图中,以确保足够的质量水平,以做出明智的决策,简化操作并实现商业目标。

如果你有低质量的数据用于你的报告,会发生什么?

可持续报告的数据质量

数据质量将影响你公司所有的分析和数据产品。

其中包括影响组织财务和法律方面的战略报告。

战略报告示例:ESG——(作者图片)

环境、社会和治理(ESG)方法是一种公司用来报告其环境足迹、社会影响和治理结构的方法论。

生成 ESG 报告的数据处理能力——(作者图片)

这依赖于从多个来源收集、处理和协调数据集。

这种报告通常涉及在发布前对数据和假设进行全面审计。

绿色洗涤的五大罪恶——(作者图片)

为了打击绿色洗涤,审计员可能会进行审计

  • 涵盖端到端供应链的数据来源

  • 数据处理和协调

  • 环境足迹和治理关键绩效指标的最终计算

绿色洗涤是指对产品环境效益做出误导性声明的做法。

因此,你的可持续部门依赖于高质量的数据,以避免可能导致合规问题的错误计算。

💡 关于绿色洗涤和 ESG 报告的更多细节,

## 什么是 ESG 报告?

利用数据分析进行公司环境、社会和治理的全面有效报告

towardsdatascience.com [## 什么是绿色洗涤?以及如何使用分析检测它?]

探索数据分析如何帮助我们检测和防止绿色洗涤,并促进真正的可持续性。

towardsdatascience.com](/what-is-greenwashing-and-how-to-use-analytics-to-detect-it-15b8118031?source=post_page-----f2c0274a6404--------------------------------)

你听说过生成性 AI 吗?

生成性 AI:使用 GPT 代理自动化数据质量检查。

OpenAI 于 2022 年底发布了 ChatGPT 的第一个版本。

从那时起,生成性 AI 成为利用大型语言模型(LLMs)提升用户数据和分析产品体验的机会。

使用 LangChain SQL 代理的供应链控制塔代理 [文章链接]——(图片由作者提供)

作为首次尝试探索这项技术,我在这篇文章中分享了我的实验历程

由 GPT 增强的智能代理原型——(图片由作者提供)

目标是创建一个智能代理来

  1. 收集以自然语言(英语)形式制定的用户请求。

  2. 自动查询数据库以提取见解。

  3. 用专业的语气制定合适的答案。

初步结果令人印象深刻!

我们能否创建一个“数据质量”智能代理?

这种方法可以应用于我们的数据质量问题。

  • 我们可以将智能代理连接到不同的数据源。

  • 配备先进的 Python 脚本以进行特定分析。

  • 教会代理数据质量的基础知识。

💡 了解更多关于如何使用 LangChain 创建智能代理的详细信息,

[## 利用 LLM 和 LangChain 进行供应链分析——由 GPT 驱动的控制塔]

构建一个连接到运输数据库的 LangChain SQL 代理的自动化供应链控制塔……

towardsdatascience.com](/leveraging-llms-with-langchain-for-supply-chain-analytics-a-control-tower-powered-by-gpt-21e19b33b5f0?source=post_page-----f2c0274a6404--------------------------------)

关于我

让我们在LinkedinTwitter上联系,我是一名供应链工程师,利用数据分析来改善物流操作和降低成本。

如果你对数据分析和供应链感兴趣,可以看看我的网站。

[## Samir Saci | 数据科学与生产力

这是一个专注于数据科学、个人生产力、自动化、运筹学和可持续发展的技术博客。

samirsaci.com

💡 关注我在 Medium,获取更多与🏭供应链分析、🌳可持续发展以及🕜生产力相关的文章。

什么是 dbt(数据构建工具)以及何时使用它?

原文:towardsdatascience.com/what-is-dbt-data-build-tool-and-when-should-you-use-it-9dc1566d960d

发现 dbt 的隐藏优点和缺点

Khuyen TranTowards Data Science Khuyen Tran

·发表于 Towards Data Science ·8 分钟阅读·2023 年 4 月 30 日

--

图片由作者提供

动机

如果您的组织正在寻求创建数据驱动的产品,您应该考虑拥有高效的数据管道,以:

  1. 保持竞争力: 通过高效的数据管道快速访问数据及其分析加快决策过程,使您在竞争中保持领先。

  2. 降低成本: 通过高效的数据管道,可以显著减少收集和转换数据所需的时间和精力,这可以降低成本,并使员工能够专注于需要人类智慧的更高层次任务。

图片由作者提供

近年来,dbt(数据构建工具)在数据管道管理方面越来越受欢迎。

虽然 dbt 在管理和建模数据方面可以提供显著的好处,但它可能不是每种情况的最佳工具。在本文中,我们将探讨 dbt 的使用案例,以确定 dbt 是否适合您的组织。

随意播放并分叉本文的源代码:

[## GitHub - khuyentran1401/dbt-demo: dbt 演示

目前您无法执行此操作。您在另一个标签或窗口中登录了。您在另一个标签或…

github.com](https://github.com/khuyentran1401/dbt-demo?source=post_page-----9dc1566d960d--------------------------------)

什么是 dbt?

dbt 是一个用于在数据仓库中转换数据的开源工具。通过 dbt,用户可以编写 SQL 查询以转换数据,并创建可重复的工作流程,这些工作流程可以轻松地进行测试和自动化。

图片由作者提供

何时考虑使用 dbt

当您需要考虑使用 dbt 时:

  1. 你有一个数据仓库: dbt 是一个有效的工具,用于在数据仓库环境中组织、转换和测试数据。

  2. 你的数据管道很复杂: dbt 的模块化方法可以帮助将复杂的管道分解为更小的部分,使调试、测试和修改管道变得更容易。

  3. 你的数据经常变化: dbt 的快照功能可以让你跟踪数据随时间的变化。

  4. 透明度对你的组织至关重要: dbt 可以自动生成管道的文档。它还通过数据血缘提供对数据转换过程的洞察。

  5. 数据质量对你的组织至关重要: dbt 可以测试你的模型,帮助你早期发现错误并确保数据准确。

在深入了解 dbt 的一些有用功能之前,我们需要先设置 dbt 环境。这将帮助你更轻松地跟随讨论。

设置 dbt

安装 dbt

本文使用 BigQuery 作为 dbt 的数据仓库,要安装 dbt 的 BigQuery 适配器,请输入:

pip install dbt-bigquery

如果你想使用其他 dbt 适配器,请遵循此说明

创建项目

要初始化一个名为dbt_demo的 dbt 项目,请输入以下内容:

dbt init dbt_demo

以下是项目目录。

作者提供的图片

模块化

dbt 的模块化方法允许你将复杂的管道拆分为更小的部分。

为了演示这一点,我们将使用来自BigQuery 公共数据集austin_bikeshare数据集。

models目录下创建一个名为models/trips_per_property.sql的新 SQL 文件,文件内容如下:

-- models/trips_per_property.sql

WITH stations AS (
  SELECT
    station_id, council_district,
    CASE
      WHEN property_type IN ('parkland', 'sidewalk', 'nonmetered_parking') THEN 'free_parking'
      ELSE property_type
    END AS property_type,
  FROM
    `bigquery-public-data.austin_bikeshare.bikeshare_stations`
  WHERE
    property_type IN (
      'parkland',
      'sidewalk',
      'nonmetered_parking',
      'paid_parking'
    )
),
trips AS (
  SELECT
    start_station_id
  FROM
    `bigquery-public-data.austin_bikeshare.bikeshare_trips`
  WHERE
    start_station_id is NOT NULL
)
SELECT
  stations.property_type,
  COUNT(*) AS trips,
FROM
  trips
  JOIN stations ON trips.start_station_id = stations.station_id
GROUP BY
  stations.property_type

由于该模型包含多个数据转换,因此可能很难维护和测试。

我们可以通过以下方式将模型分成不同的模型:

  • models目录下创建两个文件stg_stations.sqlstg_trips.sql

  • 用以下 SQL 代码替换现有的stations CTE 和trips CTE:

作者提供的图片

  • stg_trips.sql文件中,编写原始模型中trips CTE 的 SQL 代码。
-- models/stg_trips.sql

SELECT start_station_id
FROM `bigquery-public-data.austin_bikeshare.bikeshare_trips`
WHERE start_station_id is NOT NULL
  • stg_stations.sql文件中,编写原始模型中stations CTE 的 SQL 代码。
-- models/stg_stations.sql

SELECT
    station_id, council_district,
    CASE
        WHEN property_type IN ('parkland', 'sidewalk', 'nonmetered_parking') THEN 'free_parking'
        ELSE property_type
    END AS property_type,
FROM
    `bigquery-public-data.austin_bikeshare.bikeshare_stations`
WHERE
    property_type IN ('parkland', 'sidewalk', 'nonmetered_parking', 'paid_parking')

通过将模型拆分为多个模型,你现在可以在其他模型中重用这些数据模型:

作者提供的图片

你的团队成员也可以同时在项目的不同部分工作。

作者提供的图片

因为每个模块都是自包含的,所以可以轻松进行测试和验证。

作者提供的图片

代码重用性

使用 dbt 中的宏可以简化在各种模型中重用 SQL 代码片段的过程。

为了演示,我们将在macros/get_end_time.sql文件中创建一个名为get_end_time的宏。这个宏基于开始时间和持续时间获取结束时间。

# macros/get_end_time.sql
{% macro get_end_time(start_time, duration_minutes) %}
    (SELECT TIMESTAMP_ADD({{ start_time }}, INTERVAL {{ duration_minutes }} MINUTE) AS end_time)
{% endmacro %}

get_end_time宏视为一个可以重复使用的 Python 函数,用于根据提供的输入生成一个值。

图片作者

现在,另一个模型可以使用这个宏,并指定start_timeduration_minutes的具体值:

SELECT
    start_station_id,
    start_time,
    end_station_id,
    {{ get_end_time('start_time', 'duration_minutes') }} AS end_time
FROM
    `bigquery-public-data.austin_bikeshare.bikeshare_trips`
WHERE
    start_station_id IS NOT NULL AND end_station_id IS NOT NULL 

测试

使用 dbt,您可以轻松验证模型的正确性。例如,要确保stg_stations模型正确,您可能需要检查:

  • station_id列不能为空,并且具有唯一值。

  • property_type列仅有‘free_parking’或‘paid_parking’值。

要测试stg_stations模型,请在models目录中创建一个新的 YAML 文件,命名为models/schema.yml,并包含以下内容。

version: 2

models:
  - name: stg_stations
    columns:
    - name: station_id
      tests: 
        # Should not contain null values.
        - not_null
        # Should be unique
        - unique
    - name: property_type
      tests:
        # Should be either 'free_parking' or 'paid_parking'.
        - accepted_values:
            values: ['free_parking', 'paid_parking']

然后运行dbt test以执行所有测试。

通过在转换过程中尽早捕捉潜在错误,测试可以降低下游应用程序和分析中的错误风险。

图片作者

此外,测试提供了一种跟踪数据随时间变化的方法,并确保在底层数据变化时转换逻辑保持正确。

图片作者

文档

使用 dbt,您可以轻松地记录模型并与团队共享文档。

要为您的模型创建文档,请遵循以下步骤:

  • 在您的models/schema.yml文件中添加描述。

图片作者

查看完整文件。

  • 运行dbt docs generate以生成项目文档。

  • 运行dbt docs serve命令以启动文档。

  • 通过在您的网页浏览器中导航到localhost:8080来访问文档。

图片作者

记录您的数据模型有助于确保每个与模型工作的人都能理解其功能和目的。

您还可以通过点击“查看血缘图”来检查文档中的数据血缘。

图片作者

跟踪数据变化

使用 dbt,您可以通过快照跟踪数据随时间的变化。

要了解这为何有用,请想象您有一个subscriber_type表,其中subscriber_type字段经常被覆盖,因为订阅者修改其会员状态。

如果用户将其会员资格从“试用”更改为“高级”,那么用户拥有“试用”会员资格的记录将丢失。

图片作者

如果我们想将这个记录用于其他评估,如计算用户更改订阅所需的平均时间,丢失这个记录可能会有问题。

dbt 可以快照这些更改,以帮助你了解行中值随时间的变化。以下是前面示例的快照表:

图片由作者提供

查看关于如何创建快照的教程。

你不应该使用 dbt 的情况

虽然 dbt 在管理和建模数据方面可以提供显著的好处,但在以下情况下你不应使用 dbt:

  1. 你没有数据仓库: dbt 专为数据仓库(如 Snowflake、Redshift 或 BigQuery)设计。如果你没有数据仓库,dbt 可能不是适合你的工具。

  2. 你想要一个一站式 ETL 解决方案: 尽管 dbt 是一个出色的数据转换工具,但它并不提供完整的 ETL(提取、转换、加载)解决方案。数据提取、数据清洗和数据加载等任务需要其他工具。

  3. 你想可视化你的数据: dbt 不是数据可视化工具。如果你想创建可视化,你需要使用其他工具或库,如 Tableau、Looker 或 PowerBI。

  4. 你想进行超出 SQL 语法限制的高级特征工程: 由于 SQL 是 dbt 的主要语言,在特征工程方面存在一些限制。如果你需要执行超出 SQL 能力的高级特征工程任务,可能需要使用 Python 或 R 等其他工具或语言。

图片由作者提供

结论

在这篇文章中,我们介绍了 dbt 的一些有用功能,并学习了何时使用和不使用 dbt。希望这篇文章能提供足够的知识,帮助你决定 dbt 是否是你的数据管道的正确解决方案。

我喜欢写关于数据科学概念的文章,并玩弄不同的数据科学工具。你可以在LinkedInTwitter上与我联系。

如果你想查看我写的文章的代码,可以给这个仓库点个星。关注我在 Medium 上的账号,以便获取最新的数据科学文章通知:

## DVC 简介:机器学习项目的数据版本控制工具

就像 Git 一样,但用于数据!

towardsdatascience.com [## 4 个预提交插件,用于自动化 Python 中的代码审查和格式化

使用 black、flake8、isort 和 interrogate 编写高质量的代码

4 个预提交插件以自动化代码审查和格式化 [## 使用 Pandera 验证您的 pandas DataFrame

确保您的数据符合预期

使用 Pandera 验证您的 pandas DataFrame [## pytest 为数据科学家

pytest 为您的数据科学项目提供全面指南

pytest 对数据科学家的指南

什么是 EDI?电子数据交换

原文:towardsdatascience.com/what-is-edi-electronic-data-interchange-92f7215bb699?source=collection_archive---------2-----------------------#2023-08-29

探索电子数据交换(EDI)如何促进现代供应链管理。

Samir SaciTowards Data Science Samir Saci

·

关注 发表在 Towards Data Science ·10 分钟阅读·2023 年 8 月 29 日

--

(图片由作者提供)

电子数据交换(EDI)是一种标准化的在计算机系统之间自动传输数据的方法。

随着供应链变得越来越数字化,有效的数据交换已成为任何大型公司的必备条件。

使用 EDI 进行通信的供应链系统示例 — (图片由作者提供)

在复杂的供应商和分销商网络中,高效的数据通信至关重要。

作为分析专家,我们如何利用 EDI 技术支持组织的数字化转型?

它们确保了重要交易数据的顺畅流动,例如采购订单、发票、装运通知等。

EDI 在采购管理中的应用 — (图像由作者提供)

在这篇文章中,我们将揭示电子数据交换(EDI)在推动供应链操作中的关键作用,以及它如何增强数据分析能力。

我们将使用 Python 脚本展示 EDI 消息如何在仓库操作中转化为实际行动。

💌 免费接收最新文章到您的邮箱:新闻通讯

📘 供应链分析的完整指南:分析备忘单

Summary
I. EDI for Supply Chain Management
1\. A must-have for any large business
2\. More than 60 years of history
3\. EDI Standards
4\. Supply Chain Processes that use EDIs
II. Data Interchange & Operational Management
1\. Warehouse Operations Simulation Model
2\. Build a simulation model with Python
III. Why is Business Intelligence Significant?
1\. What is the environmental impact of our operations?
2\. Become a data-driven green organization
IV. What's Next?
1\. EDI for ESG Reporting and GreenWashing
2\. Conclusion

什么是供应链管理中的 EDI?

这是任何大型企业的必备工具。

电子数据交换(EDI)旨在促进高效、可靠和安全的数据交换。

几十年来,它已经深刻地成为任何大型现代企业的必备工具。

它促进了以标准化格式自动传输业务文档。

应用示例 — (图像由作者提供)

这使得不同系统可以使用共同的语言进行通信。

  • 一家公司希望向供应商发送包含项目信息、数量和预计交货日期的采购订单。

  • 一个仓库希望通知承运人一个托盘已经准备好进行取件

  • 一家商店向中央配送中心发送补货订单

超过 60 年的历史

发展于 1960 年代末期,EDI 最初用于传输运输和物流文档。

电子数据交换的简要历史 — (图像由作者提供)

多年来,EDI 扩展了其能力,涵盖了各个行业,目前有超过 15 万家企业专注于供应链管理。

考虑到每天的巨大交易量,很难想象没有 EDI 的国际供应链如何运作。

EDI 标准是什么?

EDI 基于不同地区多个行业使用的既定标准进行操作。

按行业和地理位置列出的一些标准 — (图像由作者提供)

然而,存在两种主要标准

  • ANSI X12:主要在北美使用

  • EDIFACT:由联合国创建并在国际上使用

这些标准定义了 EDI 消息中的字符串格式和包含的信息。

它们确保了在各种系统间数据解释的一致性。

一个采购订单转换为 EDI 消息的示例 — (图像由作者提供)

在上面的示例中,采购订单被转换为 EDI 消息进行传输。

  • 订单由采购团队创建并由供应商接收

  • 订单信息包括客户、供应商、交货地址和日期、发票地址以及关于订购物品的详细信息。

  • 发票、交付和公司信息通过使用 ID(公司 ID、位置 ID 等)进行映射。

哪些供应链流程使用 EDI?

随着供应链操作的复杂化,EDI 消息成为关键事件(如)通信的支柱。

  • 入库货物到达仓库。

  • 正在进行入库的托盘。

  • 正在执行的拣货订单。

  • 一个已取消的出库发货。

EDI 消息使物流操作的运转得以维持。

为了说明这个想法,我们将使用 Python 来模拟创建和传输 EDI 消息以进行仓库操作管理。

数据交换与运营管理

仓库操作仿真模型的设计。

在我们的 Python 脚本中,我们将从 EDI 消息交换的角度复制多个仓储过程。

  • 包含 SKU 和数量等详细信息的入库发货消息。

  • 入库确认包括 SKU 和入库位置。

物流操作 — (作者提供的图片)

这些消息实现了ERP仓库管理系统(WMS)的同步,提升了效率并减少了错误。

  • 消息 1:通知仓库团队通过 WMS 即将到来的入库发货(ERP -> WMS)。

  • 消息 2:仓库团队通知分销规划团队托盘已入库并准备好进行订单(WMS -> ERP)。

让我们使用 Python 构建我们自己的 EDI 消息仿真工具。

使用 Python 构建仿真模型。

让我们使用 EDI 规范 ANSI X12 模拟这些消息交换。

  1. 入库:货物在仓库接收。

    EDI 消息(仓库发货订单 — 940)通知仓库即将到来的发货及其详细信息。

  2. 入库:收到货物后,货物存放在特定位置。

    确认 EDI 消息(仓库库存转移收据通知 — 944)被返回到 ERP,以确认入库。

  3. 拣货:根据订单,从存储位置挑选物品。

    该 EDI 消息(仓库发货订单 — 940)可以指示仓库要挑选哪些物品。

  4. 出库:发运给客户。

    EDI 消息(仓库发货通知 — 945)被发送到 ERP,以确认货物已被发运。

这是 Python 脚本的简化版本,

# Author: Samir Saci
# Note: this script has been simplified for educational purposes.

class EDIMessage:
    def __init__(self, message_id):
        self.message_id = message_id
        self.content = ""

    def add_segment(self, segment):
        self.content += segment + "\n"

    def get_message(self):
        return f"ST*{self.message_id}*1\n{self.content}SE*2*1"

class Warehouse:
    def __init__(self):
        self.inventory = {}

    def receive_inbound(self, message):
        lines = message.content.split("\n")
        for line in lines:
            if line.startswith("N1"):
                _, _, sku, quantity, unit = line.split("*")
                self.inventory[sku] = self.inventory.get(sku, 0) + int(quantity)
        print("Received Inbound Shipment:\n", message.content)

    def process_putaway(self, sku):
        message = EDIMessage("944")
        if sku in self.inventory:
            message.add_segment(f"N1*ST*{sku}*{self.inventory[sku]}*units")
            print("Putaway Confirmation:\n", message.get_message())
            return message
        else:
            print("SKU not found in inventory.")

    def process_picking(self, message):
        lines = message.content.split("\n")
        for line in lines:
            if line.startswith("N1"):
                _, _, sku, quantity, unit = line.split("*")
                if self.inventory[sku] >= int(quantity):
                    self.inventory[sku] -= int(quantity)
                else:
                    print(f"Insufficient quantity for SKU {sku}")
        print("Processed Picking Order:\n", message.content)

    def process_outbound(self, picking_message):
        message = EDIMessage("945")
        lines = picking_message.content.split("\n")
        for line in lines:
            if line.startswith("N1"):
                _, _, sku, quantity, unit = line.split("*")
                message.add_segment(f"N1*ST*{sku}*{quantity}*boxes")
        print("Outbound Shipment Confirmation:\n", message.get_message())
        return message

启动模型并创建您的入库订单。

  • 两种不同的 SKU 以纸箱形式收到。

# Initiate the model
warehouse = Warehouse()

# Inbound Process
inbound_message = EDIMessage("940")
inbound_message.add_segment("N1*ST*SKU123*50*boxes")
inbound_message.add_segment("N1*ST*SKU124*40*boxes")
warehouse.receive_inbound(inbound_message)
print("Inventory of {}: {} boxes".format("SKU123",warehouse.inventory["SKU123"]))
print("Inventory of {}: {:,} boxes".format("SKU124",warehouse.inventory["SKU124"]))

输出如下,

N1*ST*SKU123*50*boxes
N1*ST*SKU124*40*boxes

Inventory of SKU123: 50 boxes
Inventory of SKU124: 40 boxes
  • 已传输的两个消息。

  • 收到的物品清单已根据收到的数量进行了更新。

入库确认

# Putaway Process
warehouse.process_putaway("SKU123")
  • 该消息发送“SKU123”的入库确认。
ST*944*1
N1*ST*SKU123*50*units
SE*2*1

拣货订单和出库发货

  • 这两个 SKU 的拣货数量低于其库存水平。
# Picking Process (Picking goods for an order)
picking_message = EDIMessage("940")
picking_message.add_segment("N1*ST*SKU123*10*boxes")
picking_message.add_segment("N1*ST*SKU124*5*boxes")
warehouse.process_picking(picking_message)
print("Inventory of {}: {} boxes".format("SKU123",warehouse.inventory["SKU123"]))
print("Inventory of {}: {:,} boxes".format("SKU124",warehouse.inventory["SKU124"]))

# Outbound Process (Sending out goods)
warehouse.process_outbound()

输出,

N1*ST*SKU123*10*boxes
N1*ST*SKU124*5*boxes

Inventory of SKU123: 40 boxes
Inventory of SKU124: 35 boxes

ST*945*1
N1*ST*SKU123*10*boxes
N1*ST*SKU124*5*boxes
SE*2*1
  • 对“SKU123”和“SKU124”进行的 2 个拣货订单,分别包含 10 和 5 个箱子

  • 库存已更新

  • 出库订单正在处理拣货的数量

我们如何确保传输顺畅?

错误检测与处理

我们引入这个模型并非仅为编码目的。

这个想法是理解如何创建各种检查以处理写入或读取消息时的错误。

EDI 也不免存在数据质量问题,比如

  • 缺失数据、数据格式不正确、无效代码,…

  • 逻辑不一致导致显著的操作中断

因此,实施强大的数据检查和验证对确保电子数据交换的准确性和可靠性至关重要。

接收订单的错误处理示例

def receive_inbound(self, message):
    lines = message.content.split("\n")
    for line in lines:
        if line.startswith("N1"):
            try:
                _, _, sku, quantity, unit = line.split("*")

                # SKU or quantity is missing
                if not sku or not quantity:
                    print("Error: SKU or quantity missing.")
                    return

                # Quantity is an integer
                quantity = int(quantity)

               # Negative or zero quantities
                if quantity <= 0:
                    print("Error: Quantity must be positive.")
                    return

                self.inventory[sku] = self.inventory.get(sku, 0) + quantity
            except ValueError:
                print("Error: Incorrect data format.")
                return

    print("Received Inbound Shipment:\n", message.content)

这段代码是:

  • 检查数量是否缺失或不符合整数格式

  • 验证所有数量是否为正数

  • 如有必要,提出错误

下一步是什么?

使用 Python,你可以支持你的基础设施团队自动化测试,以开发新的 EDI 消息。

EDI 对数据分析的强大作用是什么?

通过连接多样的计算机系统,EDI 支持日常操作,并成为数据分析的真正宝库。

每个 EDI 交易都携带有价值的信息,

  • 时间戳、位置和原因代码提供了对你的货物的可追溯性,并衡量流程的表现

  • 可用于建模物料、财务和信息流的数量、定价和项目信息

生成交易数据以监控和改进供应链网络。

什么是供应链分析? — (作者提供的图片)

这个宝贵的数据来源可以用来

  • 描述过去的事件:描述性分析

  • 分析缺陷和事件:诊断性分析

  • 预测未来事件:预测性分析

  • 设计最佳流程和决策:规范性分析

让我们深入探讨每种分析类型,以了解它如何依赖于良好的 EDI 基础设施。

描述性和诊断性分析

描述性分析是关于理解过去发生了什么。

通过正确设置 EDI 消息,我们可以将历史交易数据映射到以获取过去表现的见解。

通过时间戳跟踪的分销过程示例 — (作者提供的图片)

例如,EDI 消息可以在你的分销链的每个阶段更新状态。

  1. 每个事件都带有时间戳(从订单创建到商店交付)

  2. 实际时间戳可以与预期时间戳进行比较

  3. 然后可以分析延迟以找到根本原因

每个流程的预期时间与实际时间 — (作者提供的图片)

  • 使用与运营团队商定的目标交货时间计算预期时间

  • ERP、WMS、货运代理系统和商店管理系统都使用 EDI 通信时间戳

您可以收集和处理这些时间戳,创建自动化报告,跟踪分销链路上的货物运输。

💡 获取更多详细信息

## 什么是供应链控制塔?

使用 Python 优化您的供应链网络,采用自动化解决方案跟踪您的货物并评估…

towardsdatascience.com

如果我们想要模拟物流链中的事件或故障会怎样?

供应链管理中的数字孪生

这些计算机模型代表各种供应链组件,包括配送中心、运输网络和制造设施。

使用 Python 创建简单的数字孪生 — (作者提供的图片)

EDI 交易可以帮助您提供保持数字孪生更新的实时数据。

使用 Python 创建的简单数字孪生的示例 — (作者提供的图片)

假设您已经建立了一个包括以下内容的简单数字孪生

  • 模拟运输、商店、仓库和工厂运营的模型

  • 沿着链条复制信息和货物流动的连接

我们如何利用这些数据?

您可以将您的 EDI 流程与以下内容连接:

  • 仓库模型用于估算接收到 EDI 消息中订单批次的拣货时间

  • 工厂模型将订单数量与实际生产能力进行比较

这是一个很好的工具,可以使用通过 EDI 通信的真实订单来模拟和分析不同的场景,而不会影响实际运营。

💡 获取更多详细信息

## 什么是供应链数字孪生?

使用 Python 发现数字孪生:建模供应链网络,增强决策能力和优化运营。

towardsdatascience.com ## 什么是供应链分析?

使用数据分析提高运营效率,通过数据驱动的诊断和决策在战略和…

towardsdatascience.com

结论

理解电子数据交换(EDI)在供应链管理中的作用,让我们了解数据传输对现代商业运营的重要性。

这一关键技术为各种计算机系统之间的高效通信提供了基础。

报告的影响是什么?

对可持续性报告的影响:ESG 与绿色洗涤

环境、社会和治理(ESG)报告是公司用来披露其治理结构、社会影响和环境足迹的一种方法。

ESG 支柱展示 — (图像来源:作者)

这一非财务报告已成为公司的战略方面,因为它可能影响消费者的感知和投资的可达性。

电子数据交换如何确保数据一致性并支持审计?

ESG 报告可能会因为缺乏标准化和确保数据准确性的困难而变得具有问题。

如果你的 ESG 报告输入了错误的数据,会发生什么?

审计可能成为任何希望正式报告这一分数的公司的风险

ESG 报告所需的分析能力 — (图像来源:作者)

高级商业智能解决方案可以支持数据处理自动化;EDI 能力可以帮助确保数据的可追溯性。

这可以支持对抗绿色洗涤。

绿色洗涤是通过对产品环境效益做出误导性声明来传达虚假的可持续性形象的做法。

绿色洗涤的五大罪 — (图像来源:作者)

随着公众意识的提高,公司必须更加努力以确保计算的准确性。

这依赖于 EDI 技术支持的交易数据的适当收集、传输和处理。

关于 ESG 报告和绿色洗涤的更多信息,

什么是 ESG 报告?

利用数据分析进行全面有效的环境、社会和治理报告

towardsdatascience.com](/what-is-esg-reporting-d610535eed9c?source=post_page-----92f7215bb699--------------------------------) ## 什么是绿色洗涤?以及如何利用分析来检测它?

探索数据分析如何帮助我们检测和防止绿色洗涤,并推动真正的可持续性。

towardsdatascience.com

参考文献

  • 什么是供应链数字双胞胎?,Samir Saci,数据科学前沿

  • 什么是供应链分析?,Samir Saci,数据科学前沿

什么是 ESG 报告?

原文:towardsdatascience.com/what-is-esg-reporting-d610535eed9c?source=collection_archive---------4-----------------------#2023-08-22

利用数据科学实现公司环境、社会和治理(ESG)报告的全面与有效

Samir SaciTowards Data Science Samir Saci

·

关注 发表在 Towards Data Science · 13 分钟阅读 · 2023 年 8 月 22 日

--

什么是 ESG 报告——(作者提供的图像)

环境、社会和治理(ESG)报告是一种公司披露其治理结构、社会影响和环境足迹的方法。

作为数据科学家,你如何通过分析支持组织提升其 ESG 评分?

随着利益相关者对公司社会责任(CSR)的要求不断增加,ESG 报告已成为公司长期战略中的关键部分。

ESG 支柱展示——(作者提供的图像)

在本文中,我们将深入探讨 ESG 报告的细节,以突出其相关挑战,并探讨数据分析如何提高其准确性

📘 您的供应链分析完整指南:分析备忘单

💌 免费直接发送到您的收件箱的新文章:通讯

Summary
I. Understanding ESG Reporting
**1\. What is ESG Reporting?
2\. ESG Reporting supported with Data**
II. Advanced Analytics for ESG Reporting
**1\. Lack of Standardization
2\. Accuracy and Reliability of ESG Data
3\. Fighting Greenwashing with Data Science**
III. Data Science as a Game Changer
**1\. Sustainable Sourcing
2\. ESG-Friendly Budget Planning
3\. Supply Chain Network Optimization
4\. Circular Economy for Fashion Industry**
IV. Conclusion
Open the window on Business Intelligence and Sustainable Development Goals
**1\. Business Intelligence to Automate the Process
2\. Beyond ESG, Towards Sustainable Development Goals (SDGs)**

利用数据分析自动化 ESG 报告

什么是 ESG 报告?

ESG 报告是一种非财务报告形式,组织向利益相关者传达其环境表现(E)、社会责任(S)和治理结构的实力(G)

三个维度提供了对公司可持续性和伦理影响的深入了解。

报告类别示例 — (图像由作者提供)

例如,一家公司可能会报告

  • 其供应链的碳排放(E)

  • 社区发展倡议(S)

  • 董事会成员的多样性(G)

我们从数据分析的角度来看看这份报告。

你是一家时尚零售公司的数据科学家。

数据支持的 ESG 报告

我们可以考虑一个假设的全球时尚零售商:I&N

I&N是一家快时尚零售商,在亚洲的工厂生产服装、包袋和配饰。

I&N 的供应链网络 — (图像由作者提供)

(位于欧洲的)商店直接补给的本地仓库发货。

I&N 致力于可持续实践(循环经济、可再生能源),并通过透明度建立与利益相关者的信任。

因此,它定期在年度可持续发展报告中披露其ESG 表现

在其最新报告中,I&N披露了几个关键的 ESG 指标。

I&N ESG 指标 — (图像由作者提供)

(E):对于环境部分,I&N 报告

  • 总温室气体排放量(kg CO2eq)

  • 可再生能源的使用百分比(%)

这些指标,需要先进的数据处理,使利益相关者能够理解

  • 销售产品的环境足迹。

  • 向更清洁能源来源过渡的努力。

如何衡量这些环境指标?

产品生命周期评估(LCA)是一种数据驱动的方法,用于评估产品视角下的环境影响。

这个想法是分析每个过程,从原材料提取到产品处置。

生命周期评估 — (图像由作者提供)

对每个过程,我们进行审视

  • 自然资源、原材料和能源的消耗

  • 污染物和 CO2 的排放

  • 产生的废物

💡 欲了解更多关于这些分析解决方案的详情,

## 什么是生命周期评估?LCA

了解生命周期评估如何帮助企业评估产品在其整个生命周期中的环境影响……

[towardsdatascience.com ## 使用 Python 进行供应链可持续性报告

4 个步骤来构建有关分销网络 CO2 排放的 ESG 报告。了解如何测量和减少您的碳排放……

[towardsdatascience.com

社会评分怎么样?

(S):对于社会组件,公司详细说明

  • 社区发展计划 的数量

  • 平均员工满意度评分指示了员工的福祉。

我们公司如何披露平均员工满意度评分?

组织传统上依赖调查来获取这个指标,这通常会产生主观和偏见的结果。

因此,I&N 决定使用 自然语言处理(NLP)和社会情感分析 来分析来自 Glassdoor 或内部沟通渠道的员工评论文本数据。

社交媒体情感分析 — (作者提供的图片)

它也可以用于社交媒体上。

ESG 情感分析 是一种有价值的工具,投资者用来追踪利益相关者对 ESG 问题的态度,并了解这些因素如何影响公司的股票价格。

市场上有 工具 可以对社交媒体和招聘平台进行审计。

他们使用先进的 NLP 技术来获得客户和员工对关键公司话题的看法。

(G):对于治理领域,I&N 披露

  • 独立董事的数量

  • 董事会中的女性代表百分比。

这帮助审计员和投资者评估I&N对公平和负责任治理的承诺。

董事会组成分析是对董事会成员和管理层的多样性和经验的基于数据的评估。

这可以通过分析与被认为是公司战略关键的选定经理相关的数据来完成。

董事会组成分析的虚拟数据示例 — (作者提供的图片)

例如,可以构建可视化图表来分析劳动力多样性,通过种族分布来进行。

种族分布示例 — (作者提供的图片)

如果 I&N 想要促进性别平等,我们可以分析男性和女性管理者的部门分布。

性别分布示例 — (图像来源作者)

这些可视化图表帮助识别潜在的改进领域,并有力支持多样性和包容性,这是良好治理的关键方面。

在下一部分中,我们将看到高级分析如何帮助公司克服 ESG 报告的挑战。

高级分析用于 ESG 报告

ESG 报告可能很复杂,因为报告实践缺乏标准化,而且确保数据准确性存在困难。

你如何支持这一工作?

标准化缺乏

首先是缺乏标准化报告框架,这可能导致不同公司在报告其 ESG 表现时出现不一致

例如,两家公司可能采用完全不同的方法来衡量它们的环境影响

  • 公司 1 是一家塑料玩具制造商

  • 公司 2 在便利店销售新鲜水果

这两家公司报告减少塑料使用

  • 通过对某些物品使用纸箱包装,公司 2 减少了-55%

  • 通过改变玩具的设计,公司 1 减少了-10%

当第一家公司使用塑料作为其产品的原材料时,你能评估其努力和影响吗?

不,我们需要标准化。

💡 数据分析如何支持标准化?

  • 政府实体可以使用按行业划分的公司数据库以及其产品的环境方面 (例如: 世界银行数据库)

  • 自动化数据管道可以提取、处理并部署标准化报告,使用来自不同来源的数据。

我们如何确保数据的可靠性?

ESG 数据的准确性和可靠性

维护质量可能很艰难,因为数据来自多个来源。

商业智能(BI)提供处理和分析来自不同系统的大量数据的能力,以支持 ESG 报告。

  • 来自外部供应商、公共事业账单或运营文件的平面文件

  • 来自工厂管理系统的制造数据

  • 来自ERPWMSTMS 的物流和零售操作数据

生命周期评估所需的分析能力 — (图像来源作者)

在上面的例子中,这种数据架构用于提取、处理和存储数据,以进行生命周期评估

这个想法是估算销售商品的影响

  • 将生产输出数量与能源和资源使用联系起来

  • 估算从生产到运输的 CO2 和污染物排放

  • 包括来自供应商和物流操作的额外非财务指标

终极目标是自动化计算 ESG 指标,从原材料提取到处置的产品生命周期。

💡 额外见解 这也可以支持报告中数据的可追溯性。

例如,我实施了一个系统,使用 文件哈希 证明数据源 (来自货运代理) 在 CO2 排放计算过程中未被修改。

由于可能会进行审计,展示数据来源并证明结果尚未被篡改是很重要的。

对于那些进行欺诈的公司怎么办?

用数据科学对抗绿色洗涤

绿色洗涤是指对产品的环境效益做出误导性声明,以传达虚假的可持续形象。

绿色洗涤的五大罪行 — (作者图片)

组织使用这种不诚实的做法来创造对环境责任的虚假印象。

然而,数据分析可以显著提升通过使用

  • 公开的数据 在可持续发展报告、社交媒体中

  • 高级分析模型, 包括 NLP、预测或统计模型用于欺诈检测

💡 更多关于数据分析的详细信息,

## 什么是绿色洗涤?以及如何使用分析检测它?

探索数据分析如何帮助我们检测和防止绿色洗涤,并促进真正的可持续性。

[towardsdatascience.com

我们可以通过分析实现调和和检测欺诈。

我们能支持公司的转型吗?

数据科学作为游戏规则改变者

除了测量和报告,这些技术还可以帮助你的组织利用系统生成的数据

  • 指示性见解 支持决策:选择供应商、预算分配、供应链网络设计

  • 预测分析 帮助公司预测和减轻未来的 ESG 风险

你听说过线性规划吗?

示例 1: 可持续采购

这是在选择产品或服务供应商时整合社会、伦理和环境绩效因素的过程。

使用数据评估供应商 — (作者图片)

对于每个供应商,I&N 有一套衡量的分数

  • 自然资源的使用(水、棉花)

  • 污染物和 CO2 排放

  • 社会和治理合规

利用先进的分析技术,你可以自动化整个过程

通过三个步骤选择供应商 — (作者提供的图像)

  • 收集供应商数据

    例如:可持续性 KPI(CO2、自然资源、环境足迹)、社会和治理指标

  • 供应商评估 基于 ESG业务指标 例如:固定和变动成本、质量、社会责任

  • 决策 使用线性规划

    例如:决定一组供应商,以最小化利润,同时尊重 ESG 评分的最低水平

这是一场真正的游戏规则改变者,因为它可以帮助采购团队 使其采购策略与公司的 ESG 路线图对齐

💡 关于可持续采购分析的更多细节,

## 可持续采购的数据科学

如何使用数据科学来选择最佳供应商,考虑可持续性和社会指标...

towardsdatascience.com

使用线性规划来帮助决策。

示例 2:ESG 友好的预算规划

线性规划还可以帮助你 指导你的投资,选择支持公司 ESG 路线图的项目。

让我们设想一下国际物流公司的预算分配场景。

一位区域总监收到 17 位仓库经理 的预算申请,这些项目将影响未来三年。

物流公司预算规划的示例 — (作者提供的图像)

对于每个预算申请,经理包括

  • 项目描述(设备采购、翻新等)

  • 未来三年的年度预算

  • 投资回报率 = (成本减少 + 额外收入)— (总成本)

  • 影响业务发展、生产力或 ESG 指标 的附加收益

我们的主管必须根据财务方面(投资回报率)和 ESG 标准来决定将预算分配给哪个项目。

如何在满足 ESG 要求的同时最大化投资回报率?

通过线性规划,我们可以 自动化 选择那些在尊重 CSR、HSE 或可持续性约束的情况下最大化投资回报率的项目。

决策过程 — (作者提供的图像)

  • 参数: 每个项目的布尔值(1:已选择,0:未选择)

  • 约束条件: 业务发展和 ESG 收益

  • 目标函数: 最大化投资回报率

通过设置高层管理规定的 ESG 目标,我们的主管可以确保所选项目将支持公司的长期战略。

💡 关于 ESG 友好型预算规划的更多细节,

## 使用线性规划自动化预算规划

选择那些最大化投资回报的项目,同时遵循管理指南并尊重预算…

[towardsdatascience.com

你需要一个供应链优化应用程序吗?

示例 3:供应链网络优化

提升您的 ESG 评分的一个好方法是推动您的绿色和伦理转型。

可持续供应链优化是一种结合了成本效益与可持续性的激动人心的方法。

可持续供应链优化问题——(图片由作者提供)

您可以,

  1. 每个市场位置的需求(单位/月)

  2. 一组具有不同生产成本环境影响、社会治理评分的潜在制造地点

  3. 每单位的环境足迹限制、社会和治理评分

最可持续(且经济上可行)的组合是什么?

通过先进的分析工具,您可以设计一个工具来测试多个场景

  • 如果我想最小化成本怎么办?

    我能达到我的 ESG 目标吗?

  • 如果我想最小化 CO2 排放怎么办?

    我能保持盈利水平吗?

比较不同场景——(图片由作者提供)

我已经在网上部署的网页应用程序中实现了这样的模型:

  1. 上传您的市场需求数据(单位)每市场

  2. 添加您的制造足迹数据:按位置划分的工厂,包括(成本、CO2 排放、资源使用和社会评分)

  3. 选择目标函数:最小化成本、CO2 排放或资源使用

三种具有不同目标函数的场景——(图片由作者提供)

您可以快速从一个目标切换到另一个目标,以决定最可行的解决方案。

💡 如果您想尝试这个工具,我已分享一个可在线访问的 POC

可持续供应链优化应用程序——(图片由作者提供)

您听说过循环经济吗?重复使用或租赁以代替浪费。

示例 4:循环经济的模拟

循环经济是一种旨在减少废物和最大化资源效率的经济模式。

循环经济的订阅模式 — (作者提供的图像)

一些公司实施了订阅模式,顾客支付定期费用,以在特定时间内访问产品或服务。

一位顾客希望租用一件连衣裙 2 周。

  • 连衣裙可以在商店取货。

  • 该物品使用两周。

  • 顾客归还物品,物品随后被收集。

  • 在收集后,物品会被检查和清洁,然后再送回商店。

案例研究的参数 — (作者提供的图像)

因此,一件制造过一次的连衣裙可以被多个顾客使用。

使用此模型我们可以减少多少 CO2 排放?

我开发了一个基于销售数据的模拟模型,估算了不同租赁周期下的 CO2 节省量。

研究结果 — (作者提供的图像)

结果令人震惊,

  • 短期租赁的减排率为 75%

  • 长期租赁周期会影响网络的效率。

💡 欲了解更多关于本研究的详细信息

## 可持续发展的数据科学 — 模拟循环经济

使用数据科学模拟循环模式对快速时尚的 CO2 排放和水使用的影响…

towardsdatascience.com

这些示例让你了解了数据分析如何帮助你改善 ESG 报告,并实现高层管理设定的目标。

结论

随着 ESG 报告的普及,数据分析在提高其准确性和效率方面的作用预计将不断增长。

未来可能会开发专门针对 ESG 报告的高级解决方案。

如何自动化数据收集和处理?

商业智能自动化过程

商业智能是一种利用软件和服务将数据转化为可操作的智能,支持决策制定的过程。

商业智能的 5 个步骤 — (作者提供的图像)

这些解决方案可以自动化 ESG 报告过程,从数据收集到分析和决策。

💡 欲了解更多信息

什么是商业智能?

探索应用于供应链优化的数据驱动决策工具。

towardsdatascience.com

通过利用这些工具,公司可以改善其 ESG 报告,并获得宝贵的见解以推动其可持续发展战略。

超越 ESG,迈向可持续发展目标(SDGs)

可持续发展目标(SDGs)是联合国制定的17 个目标,旨在应对全球挑战。

这 17 个目标可以分为 5 个类别 — (作者提供的图片)

将这些目标融入我们的操作框架是道德上的必要性,也是推动创新和提高效率的绝佳机会。

面向以人为本的先进分析工具 — (作者提供的图片)

通过数据分析,我们可以支持这些 17 个目标的设计和实施,从而提升你的 ESG 评分。

要深入了解数据分析如何支持这些目标,

## 可持续发展目标是什么? (SDGs)

将全球可持续发展倡议与公司供应链数字化转型通过数据科学相结合

s-saci95.medium.com

关于我

让我们在 LinkedinTwitter 上联系。我是一名供应链工程师,利用数据分析来改善物流运营和降低成本。

如果你对数据分析和供应链感兴趣,可以查看我的网站。

## Samir Saci | 数据科学与生产力

一个专注于数据科学、个人生产力、自动化、运筹学和可持续发展的技术博客

samirsaci.com

💡 关注我在 Medium 上的文章,获取更多有关 🏭 供应链分析、🌳 可持续发展和 🕜 生产力的内容。

参考文献

什么是生成性 AI?全面指南

原文:towardsdatascience.com/what-is-generative-ai-a-comprehensive-guide-for-everyone-8614c0d5860c

了解机器学习在生成性 AI 中的作用。

Mary NewhauserTowards Data Science Mary Newhauser

·发布于 Towards Data Science ·15 分钟阅读·2023 年 10 月 3 日

--

图片由作者提供。

本文最初发表于 GPTech

乍一看,生成性 AI 看起来像纯粹的魔法。但一旦你开始揭开这个迷人技术背后的层层面纱,你会发现它本质上是一个统计过程,既有令人印象深刻的结果,也有关键的局限性。

从最广泛的意义上讲,生成性 AI 是一种人工智能,它基于从现有数据中学习到的模式创建新内容。也许生成性 AI 最明显的例子是预测搜索。谷歌在用户多年来输入的数十亿个搜索查询上训练了一个大型语言模型(LLM),然后尝试预测你自己搜索查询中的下一个词。

但与最近在生成性 AI 方面的进展相比,预测搜索显得有些过时,甚至原始。生成性 AI 现在可以用来编写从新的 《宋飞传》剧集学术文章 的一切,基于文本提示合成图像,甚至 制作歌曲 以著名艺术家的风格。

尽管有很多炒作,但仍然存在令人担忧的原因。由生成性 AI 驱动的聊天机器人可能产生不准确和有毒的回应,政治家和公众人物的深度伪造视频可能被用来传播虚假信息,而各种模型也可能被用来加深现有的人类偏见。

很明显,生成性 AI 将会影响劳动、工业、政府,甚至是人类的定义。为了与生成性 AI 共存,我们需要了解它是如何工作的以及它所带来的风险。本文将解释什么是机器学习模型,讨论判别模型与生成模型的区别,探索生成模型的一些实际应用,并涉及它们的风险和局限性。

机器学习模型

人工智能是一个广泛的术语,描述了一种能够执行模仿人类智能的任务的技术,例如需要推理、问题解决、决策或语言理解的任务。

机器学习是 AI 的一个分支,其中“机器”(算法)从数据中“学习”模式和关联,以执行特定任务。这就是它的工作原理:

  1. 定义任务。 我们需要做的第一件事是定义我们希望模型执行的任务。这可能是将来邮件分类为垃圾邮件或非垃圾邮件,基于销售数据预测未来收入,根据客户行为将客户分组,基于购买历史向客户推荐新产品,或者根据给定的文本提示创建图像。

  2. 选择模型。 影响我们选择哪种类型模型的因素有很多。我们在前一步定义的任务,加上可用数据的性质和数量,以及模型在现实世界中的使用方式(以及使用者)都会影响我们选择的模型类型。

  3. 收集(和清理)数据。 接下来,我们收集希望模型学习的数据。我们通过删除异常值和损坏的数据来清理数据,并将其组织成表格格式。

  4. 可选:拆分数据。 在从数据中学习时,我们通常会留出一部分(通常是 80%)来构建我们的知识,这被称为训练数据。然后我们使用剩下的部分(通常是 20%),这被称为验证数据,来检查我们学习的效果。这个过程帮助我们查看我们对训练数据的理解是否能够适应新信息。

  5. 训练模型。 接下来,我们将空模型投入使用,让它尽可能从训练数据中学习。这被称为训练过程,因为模型正在被训练(即学习、研究和分析数据中的关系)。我们可以通过选择参数来稍微指导模型,并在某些方向上推动它。

  6. 评估模型。 在将模型发布到实际应用之前,我们希望通过查看它在某些指标上的得分,如准确率、精确率、召回率和 F1 分数,来了解它的表现。如果我们有验证集,我们可以要求模型在验证集上执行所选任务,并查看其准确性。

作者提供的图像。

机器学习是一个复杂的、迭代的、不断发展的过程。大多数关注集中在模型训练步骤上,但实际花费的大部分时间在于数据收集和清理步骤。就像石油和天然气等化石燃料通过复杂的管道系统从一个地方运输到另一个地方一样,数据也有自己的管道系统。一旦管道建立并运行,它们需要持续的监控和维护,但达到这一点需要大量的工作。

但是,为了本文的目的,我们将专注于机器学习模型本身。为了有效理解生成式 AI,我们必须了解生成式和判别式机器学习模型之间的区别。

判别模型与生成模型

模型的工作是利用从数据集中学到的关联和模式来预测其他数据点的结果。这些预测以介于 0 和 1 之间的概率形式出现。由于概率是对不确定性的测量,并且在现实世界的情况下总是存在一定程度的不确定性,因此预测的概率永远无法等于确切的 0 或 1。

机器学习模型在生成数据点的预测概率方面的方法各异。在生成式 AI 的背景下,理解判别模型和生成模型生成这些预测概率之间的区别是很重要的。

判别模型

判别模型通过识别之前见过的例子之间的组或类别差异来学习预测数据的概率。

例如,逻辑回归模型可以预测二元结果的概率,例如,基于出勤率、学习时间、以前的考试成绩以及过去学生的通过/未通过状态,预测学生通过课程的概率。

参考下图,其中每个点被可视化为来自去年每个学生的出勤率、学习时间、以前的考试成绩和最终通过/未通过状态。给定每个学生的个体特征和最终结果,模型绘制了一个决策边界

作者提供的图像。

当面对新学生及其数据时,模型使用决策边界来预测他们是否会通过课程,该预测表示为 0(不及格)和 1(及格)之间的概率。数据点距离决策边界越远,模型对其预测的信心越大。

虽然判别模型在分类和回归等任务中可以很简单有效,但它们仅在能够访问足够的标记结果数据时才表现良好(过去学生的及格/不及格状态)。在现实任务中,这可能是一个严重的限制。这正是生成模型发挥作用的地方。

生成模型

生成模型通过仅学习输入数据的基础结构来预测数据的概率。

生成模型在研究和学习训练数据时非常出色,以至于它们不需要标记的结果数据,如上述示例所示。这意味着两件事:

  1. 生成模型可以预测数据的概率(就像判别模型一样,只是使用不同的方法)。

  2. 生成模型可以生成看起来与之前见过的数据(即训练数据)非常相似的新数据。

考虑一下确定一条亚马逊产品评论通常是正面还是负面的任务。在下面的插图中,每个点都被可视化为一个单独的评论,具有自己的风格、语气以及词汇和短语的独特组合。生成模型研究所有这些数据点,捕捉每条评论中的模式、结构和语言变化以及它们之间的关系

图片来自作者。

给定所有评论中的词汇和模式,生成模型计算这些词汇和模式在正面评论与负面评论中出现的概率。这个概率称为联合概率,定义为一组特征在数据中一起出现的概率。例如,模型可能会学到“broken”和“disappointed”这两个词经常一起出现在负面评论中,而“highly recommend”和“very satisfied”这两个词则经常一起出现在正面评论中。

最终,模型将运用它从训练数据中学到的所有知识来确定新未见过的评论被分类为正面或负面的可能性。生成模型与判别模型的不同之处在于,它们不仅能执行分类任务,还能在被提示时生成全新的数据。这意味着我们的亚马逊评论模型不仅能分类现有评论,还能撰写新评论。

在进行生成任务时,模型需要被提示。在这种情况下,已经训练过的评论模型会收到一个文本提示,并被要求猜测接下来哪些词汇出现。

图片来自作者。

尽管在机器学习社区中仍有争议,解释模型生成新文本的最简单方式是说它根据模型训练时的文本和提示中的文本预测下一个词。在下面的例子中,模型预测“smoothies”是最有可能出现在回应中的词。这受到了模型从训练数据中学到的“smoothies”和“shakes”与“blender”相关的事实的影响,以及我们的提示要求模型在回应中提到“smoothies”。

图片来自作者。

鉴于在训练数据中“自行车”很少与“搅拌机”一起出现,并且我们的提示中没有提到“自行车”,模型可以安全地假设“自行车”不会是下一个词。

总结来说,生成式机器学习模型捕捉输入数据中的模式、结构和变化,这使得它们能够计算特征共同出现的联合概率。这使得它们能够预测现有数据属于某个类别(例如,正面或负面评论)的概率,并生成类似于训练数据的新数据。但这种“新数据”究竟是什么样的呢?事实是,机器学习模型生成的数据可以有多种形式,并服务于多种目的。

现实世界中的生成式 AI

自机器学习诞生以来,生成模型就被用于建模和预测数据。然而,近年来领域的进展,如 2014 年变分自编码器(VAE)和生成对抗网络(GAN)模型的出现,将生成技术提升到了新的高度,使模型能够合成完全新颖的图像。同样,2017 年首个生成预训练变换器(GPT)模型的推出标志着语言生成能力的重大飞跃,导致了一系列不断改进的语言模型,能够生成与人类编写的文本难以区分的文本。

尽管像 Meta 和 Google 这样的主要科技公司早已投资于 AI 研究,并且不断尝试通过每个发布的大型语言模型超越彼此,初创公司界也见证了对探索 AI 潜力,特别是生成模型的浓厚兴趣。根据 Dealroom 的数据,生成式 AI 初创公司总共筹集了超过 170 亿美元的资金,Dealroom 维护了一个极佳的 资金可视化图谱

让我们来看看这些公司如何通过生成文本、图像和音频的产品来利用 AI。

生成文本

生成文本是指使用 AI 模型生成连贯且上下文相关的句子。这些模型在大量文本数据上进行训练,能够模仿人类语言模式并生成新的文本。实际应用包括:

  1. AI 聊天机器人: OpenAI 的 ChatGPT 是迄今为止最强大的个人助手聊天机器人。它可以用于多种任务,包括文档摘要、文本风格转移、语言翻译和内容生成。虽然它是一个出色的通用工具,但许多公司进一步优化了 ChatGPT 的底层模型,以创建在完成特定下游任务方面更好的产品。

  2. 内容生成: Jasper AI 提供了一个可定制的生成式 AI 平台,满足企业的特定需求,提供与公司品牌一致的量身定制内容,并支持在各种平台和应用程序中访问,包括将其技术直接集成到企业产品中的选项。

  3. 语言纠正: Grammarly 提供了一系列应用程序,提供跨许多应用和网站的集成写作辅助,特别强调确保无错误写作。他们的服务无缝集成到各种应用中,如 Microsoft Office、Google Docs 和 Gmail,通过其便捷的插件。

图片由作者提供。

生成图像

生成图像涉及通过 AI 模型创建新的、原创的图像,通常通过从现有图像的数据集中学习。这个艺术与技术的迷人交汇点有许多应用,包括:

  1. 艺术图像生成: Adobe Firefly 利用传统 Adobe 产品的能力,包括 Illustrator 和 Photoshop,通过简单的文本提示让用户创建、编辑和操控图像。Stability AI 提供了类似的图像编辑和生成产品 Clipdrop,该产品最近推出了令人着迷的 Uncrop 工具,它利用生成 AI 扩展照片的背景。

  2. 演示和视觉叙事: Tome 使你能够轻松制作引人入胜的现代演示文稿,顺畅地整合来自各种来源的文本和图像,如提示、创意简报,甚至不同的文档格式,如网站。

生成音频

生成声音是指使用 AI 模型生成新的音频元素,包括音乐、语音和音效。这些模型可以从现有的音频数据中学习并生成新的、独特的声音。以下是一些现实世界的应用案例:

  1. 音乐制作: Soundraw 是一个由 AI 驱动的音乐生成器,提供了一个免版税曲目库,让创作者能够为他们的内容项目制作原创歌曲,同时确保对他们的音乐作品拥有完全的所有权和许可控制。

  2. 语音合成: Wellsaid 允许你自动生成高质量的文本语音,并提供一个头像语音库以及创建你自己声音的机会。

图片由作者提供。

生成 AI,通过变分自编码器 (VAE) 和生成对抗网络 (GAN) 等模型显著进步,正在重塑多个领域,投资超过 170 亿美元。现实世界的应用包括文本生成,AI 可以生成类人语言模式,图像创建,提供生成新颖图像的能力,以及音频制作,新声音可以被合成。这些应用标志着生成 AI 在生产风格和质量日益接近人类生成内容的潜力不断扩展。尽管最近 AI 的进展确实令人兴奋,但同样重要的是要认识到其固有的风险和局限性。

生成 AI 的风险和局限性

尽管关于生成 AI 与原子武器一样危险甚至更危险的担忧被夸大和渲染,但这项新技术确实给公众带来了真实的危险,并且具有严重的伦理影响。一些最关键的问题包括数据隐私、模型准确性以及生成有害内容的倾向,和 LLM 及其他生成模型的不道德使用。

数据隐私

关于生成 AI 的主要关注点之一是数据隐私。这些 AI 模型是在大量数据上进行训练的,其中一些可能包括敏感或受版权保护的信息。尽管通常会采取措施在训练模型之前对数据进行匿名化和清理,但无意中泄露数据的潜在风险仍然是一个重大关注点。此外,生成 AI 几乎总是需要一个提示才能开始,而提示中包含的信息可能是敏感的或专有的。这令人担忧,因为一些 AI 工具如 ChatGPT 会将你的提示反馈到基础语言模型中。2023 年 4 月,三星禁止在公司内部使用 ChatGPT,因为发现几名员工不小心泄露了用于测量半导体设备的软件源代码。

[## 彭博社

编辑描述

www.bloomberg.com](https://www.bloomberg.com/news/articles/2023-05-02/samsung-bans-chatgpt-and-other-generative-ai-use-by-staff-after-leak?ref=gptechblog.com&leadSource=uverify+wall&source=post_page-----8614c0d5860c--------------------------------)

准确性与有害内容

关于生成模型实施的另一个关注点是模型的准确性。LLM(大型语言模型)有产生幻觉的倾向,这意味着它们以完全令人信服的方式提供虚假信息。这些幻觉有可能在全球范围内传播虚假信息,并削弱公众对人工智能系统的信任。由于开源模型通常经历的后期模型调整过程较少(如果有的话),它们尤其容易“脱轨”,不仅仅是产生幻觉,还可能生成彻底有害的内容。2023 年 3 月,国家饮食失调协会关闭了其人工操作的电话热线,并用一个聊天机器人替代,但该机器人在上线后给一位独立测试机器人的心理学家提供了有问题的减肥建议。

[## 一款健康聊天机器人因其‘有害’的减肥焦点而下线

人工智能工具 Tessa 由国家饮食失调协会推出,旨在…

www.nytimes.com](https://www.nytimes.com/2023/06/08/us/ai-chatbot-tessa-eating-disorders-association.html?ref=gptechblog.com&source=post_page-----8614c0d5860c--------------------------------)

不道德使用

截至本文发布时,还没有通过任何重要的立法来规范 AI 的创建和应用。因此,恶意行为者在利用这些工具进行恶意行为时似乎拥有完全自由

生成视频技术的滥用很快显现出来,当它被用于通过传播深度伪造色情内容来骚扰和威胁女性时。在 2023 年 3 月,联邦贸易委员会发布了一份声明,提醒大家警惕,因“语音克隆”技术的出现,钓鱼骗局变得更加复杂。语音克隆是一种训练在短音频片段上的 AI,可以通过文本让其说几乎任何内容。

[## 深度伪造色情内容给受害者带来了创伤,但大多数人无能为力

深度伪造色情内容的受害者正在发声,呼吁对施虐者缺乏保护。一项新法案可能会改变这种状况。

www.teenvogue.com](https://www.teenvogue.com/story/deepfake-porn-victims-are-seeking-federal-protections-through-a-new-bill?ref=gptechblog.com&source=post_page-----8614c0d5860c--------------------------------)

总之,尽管生成 AI 已经取得了令人惊叹的进展并充满了巨大潜力,但我们必须意识到其风险和局限性,特别是在目前缺乏立法监管其创建和使用的情况下。这意味着要花时间认真权衡使用生成 AI 的潜在好处与不良后果,考虑伦理问题。以下是一些提示,帮助你更安全、更谨慎、更加道德地使用生成 AI 产品:

  • 阅读(或至少浏览)隐私政策。

  • 不要上传任何私人内容(文本、图片、视频),以免这些内容被反馈到产品的基础模型中。

  • 如果你在商业中使用预训练的生成模型,务必阅读模型的许可证。

  • 验证聊天机器人的响应是否符合主要来源。

  • 研究基础模型的特定偏见和局限性。

结论

在本文中,我们讨论了生成机器学习模型的关键方面,特别是它们区分各种数据类型的能力以及创建与现有数据非常相似的新数据的能力。生成模型的质量在过去十年中显著提高,导致对生成 AI 背后的公司和技术的投资激增,特别是在生成文本、图像和音频方面。

然而,随着这种兴起也带来了诸如数据隐私、模型准确性和创建有害内容等伦理问题。我们必须继续监控这些问题,并在使用生成式 AI 产品时保持个人警惕和意识。

这篇文章最初发布在 GPTech

如果您想保持最新的数据科学趋势、技术和工具,考虑成为 Medium 会员。您将获得对像 Towards Data Science 这样的文章和博客的无限访问,并支持我的写作。 (每个会员我会获得小额佣金)。

[## 通过我的推荐链接加入 Medium - Mary Newhauser

作为 Medium 会员,您的会员费的一部分会分配给您阅读的作者,并且您可以完全访问每个故事……

medium.com](https://medium.com/@mary.newhauser/membership?source=post_page-----8614c0d5860c--------------------------------)

想要联系吗?

  • 📖 在 Medium 上关注我

  • 💌 订阅 以便每次我发布新内容时收到邮件

  • 🖌️ 查看我关于生成式 AI 的新 博客

  • 🔗 查看我的 作品集

  • 👩‍🏫 我还是一名数据科学 教练

我还写过:

## 理解 ChatGPT 插件:优势、风险和未来发展

期待进步,而非完美。

towardsdatascience.com ## 从数据分析师转变为数据科学家的指南 2023

您需要的技能和资源,以便从数据分析师转变为数据科学家职位。

towardsdatascience.com ## 清洁 Pandas 代码的终极参考

清洁文本数据的简洁方法

towardsdatascience.com

参考文献

  1. Parrish, A. (2023 年 2 月 1 日). 这个 AI Seinfeld 直播到底是怎么回事? The Verge.

  2. Williams, A. (2023 年 3 月 23 日). 使用 ChatGPT 撰写的论文展示了 AI 在学术界的机遇和挑战科学日报.

  3. Coscarelli, J. (2023 年 4 月 19 日). 虚假的“Drake”和“The Weeknd”AI 音乐震撼音乐界纽约时报.

  4. IBM. (无日期). 什么是人工智能(AI)?IBM.

  5. IBM. (无日期). 什么是机器学习? IBM.

  6. Ngo, T. (2023 年 2 月 26 日). ChatGPT 并不仅仅是“预测”下一个词LinkedIn.

  7. Kingma, D. P., & Welling, M. (2014). 自编码变分贝叶斯。在国际学习表征会议中。

  8. Goodfellow, I., Pouget-Abadie, J., Mirza, M., Xu, B., Warde-Farley, D., Ozair, S., Courville, A., & Bengio, Y. (2014). GAN(生成对抗网络)日本模糊理论与智能信息学会期刊, 29(5), 177。

  9. Radford, A., Narasimhan, K., Salimans, T., & Sutskever, I. (2018). 通过生成预训练提高语言理解。预印本。

  10. Ullmer, F. & Chiavarini, L. (2023 年 6 月 9 日). 生成性 AI 初创公司Deal Room

  11. Gurman, M. (2023 年 5 月 2 日). 三星禁止员工使用 AI 后发现 ChatGPT 数据泄露彭博社.

  12. McCarthy, L. (2023 年 6 月 8 日). 一款健康聊天机器人因关注体重减轻而下线纽约时报.

  13. Latifi, F. (2023 年 6 月 7 日). 深度伪造色情受害者通过立法寻求联邦保护Teen Vogue.

  14. Puig, A. (2023 年 3 月 20 日). 骗子利用 AI 提升他们的家庭紧急情况骗局FTC 消费者建议。

  15. Evans, K. (2023 年 5 月 10 日). AI 最佳实践:如何安全使用像 ChatGPT 这样的工具信息安全.

什么是绿色洗涤,我们如何利用分析检测它

原文:towardsdatascience.com/what-is-greenwashing-and-how-to-use-analytics-to-detect-it-15b8118031?source=collection_archive---------2-----------------------#2023-08-10

探索数据分析如何帮助我们检测和防止绿色洗涤,以促进真正的可持续发展。

Samir SaciTowards Data Science Samir Saci

·

关注 发表在 Towards Data Science ·9 分钟阅读·2023 年 8 月 10 日

--

使用数据检测绿色洗涤 — (图片由作者提供)

绿色洗涤是指对产品或服务的环境益处做出误导性声明,以传达虚假的可持续性形象。

我们如何利用分析帮助世界对抗绿色洗涤?

这种修饰或掩盖虚假信息的行为已经成为一个普遍的挑战,因为公司们寻求环保意识强的消费者的关注。

绿色洗涤的五大罪恶 — (图片由作者提供)

在这篇文章中,我们将深入探讨绿色洗涤及其表现形式。

我们将通过案例研究展示如何使用数据分析来检测和防止这些不道德的做法。

💌 免费直接发送到你的收件箱的新文章:Newsletter

📘 你的供应链分析完整指南:Analytics Cheat Sheet

Summary
I. Understanding Greenwashing
1\. What is Greenwashing?
2\. Examples of Greenwashing
3\. Greenwashing x Data Analytics
II. Data Analytics for Greenwashing Detection
1\. The difficult task of detection
2\. Natural Language Processing (NLP)
3\. Change Point Analysis
4\. Regression Analysis
5\. Network Analysis
III. Conclusion

理解绿色洗涤

我在进行第一次 supply chain sustainability project.时发现了绿色洗涤。

作为供应链解决方案经理,我的任务是估算客户物流操作的环境足迹。

一家销售一次性塑料产品的公司怎么可能声称自己是碳中和的?

看到一些竞争对手的主张令人惊讶,因为他们生产和销售的产品类似。

这篇文章旨在展示分析工具如何帮助你检测这种虚假声明。

绿色洗涤是什么?

绿色洗涤是“绿色”和“粉饰”的合成词。

组织利用这种不诚实的做法来制造虚假的环保责任印象。

目标是利用客户和投资者对环保产品日益增长的需求。

最常见的绿色洗涤形式包括,

  • 模糊性:使用没有明确定义或证据的未定义术语,如“环保”“全自然”

    例如,一家公司将产品标记为“100%天然”,却没有透露这些天然材料是以不可持续的方式获取的。

  • 无关性:突出显示一种对产品环境影响不重要或无关的环保特性。

    例如,一家公司强调其产品“无 CFC”,而氯氟烃已被禁止了几十年。

  • 隐性权衡:宣传产品的一个环保方面,同时忽视其他重大影响。

    例如,一家纸业公司宣传其使用回收纸,但没有提到生产和物流过程中的能源消耗和碳排放。

绿色洗涤是什么? — (图片来源:作者)

当你看到广告宣传天然来源的回收 T 恤时,请考虑:

  • 获取这些“天然原材料”所使用的能源、电力和水的数量。

  • 回收过程产生的额外二氧化碳排放和废物。

通过生命周期评估 (LCA),你可以使用数据驱动的方法来评估这些影响,通过考虑整个产品生命周期并避免这种陷阱。

你的“100%天然”回收 T 恤的生命周期评估 — (图片来源:作者)

这个想法是估算特定产品或服务的采购、生产和使用的环境影响。

这需要使用商业智能工具从多个来源收集和处理数据。

💡 更多详情,

## 什么是生命周期评估?LCA

了解生命周期评估如何帮助企业评估产品在整个生命周期中的环境影响……

towardsdatascience.com

让我们分析一些实际的例子。

绿色洗白的例子

几个引人注目的案件将绿色洗白问题推到了风口浪尖。

  • 一家大型汽车制造商被发现使用软件在其标榜为“环保”的车辆中作弊排放测试。

  • 一家著名的水公司将其产品宣传为“碳负”而未承认从斐济岛运输瓶装水到全球市场的环境成本。

第二种情况可以通过基本的供应链分析和公开可用的数据轻松揭穿

供应链流动分析 — (图片来源:作者)

如何?

  1. 使用财务报告估算市场销售量

  2. 使用温室气体协议计算每瓶的排放量,从制造工厂到市场

  3. 将结果与公司发布的图表进行比较

💡 有关如何使用分析来估算 CO2 排放的更多细节

## 使用 Python 进行供应链可持续性报告

建立一个关于配送网络 CO2 排放的 ESG 报告的 4 个步骤。学习如何测量和减少你的碳……

towardsdatascience.com

除了报告之外,数据分析如何帮助我们检测这种欺诈行为?

绿色洗白与数据分析

了解绿色洗白的各种形式和影响,对于实施主动措施应对这一问题至关重要。

虽然监管机构和有意识的消费者在这场斗争中发挥了重要作用,但数据分析可以作为额外的推动力来自动化欺诈检测。

使用数据分析检测绿色洗白 — (图片来源:作者)

这个想法是利用……

  • 公开可用的数据:财务和可持续性报告、足迹数据库、社交媒体

  • 高级分析模型,包括 NLP、预测或统计模型以检测欺诈行为

以下部分将探讨如何使用这些工具来促进一个更透明和可持续的企业环境。

数据分析用于检测绿色洗白

检测的艰巨任务

鉴别绿色洗牌是一个复杂的任务,鉴于其表现的复杂性和可用信息的庞大量。

数据分析可以提供强大的工具,用于过滤大型数据集,识别模式和异常,以及提取有价值的见解。

数据分析用于绿色洗牌检测 — (作者提供的图像)

在接下来的章节中,我们将通过潜在欺诈的例子来探讨如何使用这些解决方案。

让我们开始文本分析。

自然语言处理(NLP)

NLP 在绿色洗牌检测中的主要应用是 情感分析

让我们考虑主要石油公司的例子。

他们定期发布可持续性报告和新闻稿,突出他们对环境保护的承诺。

我们手头的数据包括这些在其网站上的 PDF 文档。

报告中的情感分析与二氧化碳排放 — (作者提供的图像)

一个 NLP 情感分析模型可以评估这些陈述背后的情感。

💡 如何检测绿色洗牌?

如果这些陈述传达了过于乐观的情感,而这些情感在实际环境表现指标中没有反映出来,这可能是绿色洗牌的迹象。

例如,上述例子

  • 2020 年二氧化碳总排放量激增:+26k 吨 CO2eq

  • 然而,情感评分却不断增加

实际的 可持续性表现 和报告中出售的叙述之间存在矛盾。

那么,关于可持续性指标呢?我们可以利用它们的趋势。

变点分析

变点分析识别数据序列中统计属性变化的点。

例如,一家主要的汽车制造商报告了二氧化碳排放量的突然减少。

生产输出与排放的相关性潜在异常示例 — (作者提供的图像)

可用数据将包括公司报告的排放量和生产输出的时间序列。

💡 如何检测绿色洗牌? 变点分析可以检测这些减少是否与

  • 合法且持续的可持续性努力

  • 临时情况下这可能暗示绿色洗牌

我使用了一个二氧化碳排放虚拟数据集,并应用了 Python 库 ruptures

变点检测示例 — (作者提供的图像)

它检测到了第 9 年的重大变化,我们应该对此进行调查。

这是一个初步评估,减少可能是由于实际举措的影响。

你可以在可持续性报告中共享的详细举措中验证这一点。

💡 查看代码以获取此视觉效果,

你听说过相关性吗?

回归分析

回归分析可以帮助确定不同变量之间的关系。

例如,一家主要时尚品牌报告了可持续发展支出(欧元)和废料生产水平(吨)。

💡 如何检测绿色洗刷? 回归模型可以识别可持续发展支出增加是否导致废料生产的相应减少。

如果没有,这可能是绿色洗刷的迹象,需进行深入调查

  • 不是一个单变量问题,因为废料可能受到许多其他参数的影响(产品设计、原材料等)

  • 以产品为中心的方法(LCA)更适合追踪支出如何影响整个供应链的环境足迹

我们能否将公司与污染的供应商联系起来?

网络分析

网络分析有助于理解网络中实体之间的关系。

一家电子行业公司可能声称其产品来自可持续和道德的供应商。

💡 如何检测绿色洗刷? 数据应包括公司的供应商网络和第三方对供应商实践的报告。

使用 Python 的 Networkx 进行网络分析 — (图片来源:作者)

使用网络分析,我们可以审查供应商的可持续性关键绩效指标(例如 ESG 评分)及其连接。

如果网络中的节点有可疑的可持续性实践,这可能暗示潜在的绿色洗刷。

💡 了解如何使用 Python 实现网络图的更多细节

## 交通网络分析与图论

利用图论来优化零售公司的公路运输网络

towardsdatascience.com

这让你初步了解如何利用先进分析自动检测绿色洗刷和欺诈,使用公开数据。

结论

绿色洗刷的终结?

随着我们考虑未来的 ESG 法规,绿色洗刷与数据分析之间的联系将显著加深。

报告类别示例 — (图片来源:作者)

这份非财务报告由组织使用,向利益相关者和金融机构传达其环境绩效(E)、社会责任(S)和治理结构的强度(G)

为什么这很重要?

随着客户和投资者对可持续性认识的提高,公司将发现隐瞒模糊或误导性可持续性声明的风险加大。

因此,在一个日益数据驱动的世界里,绿色洗涤将面临重大挑战。

💡 了解更多关于 ESG 报告的详细信息,

## 什么是 ESG 报告?

利用数据分析进行全面且有效的公司环境、社会和治理报告

[towardsdatascience.com

我们能否利用数据实际支持绿色转型?

足迹减少的数据分析

企业可以利用先进的分析技术设计和实施具有实际效果的举措,而不是制造虚假的声明。

例如,可持续供应链优化是一种数据驱动的方法,结合了成本减少足迹减少

可持续供应链优化 — (图像来源:作者)

让我们假设你的公司正在全球范围内生产和销售商品。

工厂和配送中心应该设在哪里?

这是一个考虑了以下因素的优化模型,

  • 每个市场位置的需求(单位/每月)

  • 所有潜在的制造地点及其生产成本、环境足迹(CO2,资源)、ESG 评分

  • 环境足迹每单位的约束,社会和治理评分

最可持续(且经济上可行)的组合是什么?

  • 如果你想专注于盈利,如何最小化成本

    我们能尊重环境目标吗?

  • 如果你想专注于可持续性,如何最小化 CO2 排放

    我们能保持盈利水平吗?

💡 了解更多关于此应用程序的信息,

## 创建可持续供应链优化网页应用

帮助你的组织将可持续采购与供应链优化相结合,以减少成本和环境影响……

[towardsdatascience.com

💡 在 Medium 上关注我,获取更多关于🏭供应链分析、🌳可持续性和🕜生产力的文章。

关于我

让我们在LinkedinTwitter上联系。我是一个利用数据分析改善物流运营和降低成本的供应链工程师。

如果你对数据分析和供应链感兴趣,请查看我的网站。

[## Samir Saci | 数据科学与生产力

一个专注于数据科学、个人生产力、自动化、运筹学和可持续发展的技术博客

samirsaci.com

参考文献

  • 使用 Python 进行供应链可持续性报告,Samir Saci,Towards Data Science

  • 使用图论进行交通网络分析,Samir Saci,Towards Data Science

  • 创建可持续供应链优化的网页应用,Samir Saci,Towards Data Science

什么是智能过程自动化(IPA)?

原文:towardsdatascience.com/what-is-intelligent-process-automation-ipa-547d60df0590

人工智能正在改变许多行业,现在也在自动化工具中改变游戏规则。

Patrick MeyerTowards Data Science Patrick Meyer

·发表于Towards Data Science ·阅读时间 9 分钟·2023 年 2 月 11 日

--

图片来源:克莱顿·卡尔迪纳利Unsplash

介绍

企业不能再忽视竞争对手和客户的数字化转型。这种数字化意味着掌握自己的流程及其优化状态。此外,人工智能是改变公司运营模式及其向客户提供产品和服务方式的新革命。

将不同的自动化技术与业务服务结合起来,再加上 AI 技术,已成为一种迫切的需求。IPA 解决方案的供应商已完全理解这一问题,因为他们在解决方案中整合了越来越多的 AI。为了理解通过 AI 实现自动化的价值,了解每种技术在自动化过程管道中的贡献至关重要。

内容

  1. 一般的智能过程自动化(IPA)

  2. 任务与过程挖掘(TM/PM)

  3. 机器人过程自动化(RPA)

  4. 业务流程管理(BPM)

  5. 智能自动化(IA)

  6. 智能虚拟助手(IVA)

  7. 智能文档处理(IDP)

  8. 一个例子!

  9. 最终…

1. 一般的智能过程自动化(IPA)

Quadrant Knowledge Solutions 将“智能过程自动化(IPA)定义为将机器人过程自动化(RPA)与过程挖掘、人工智能(AI)、智能字符识别(ICR)、光学字符识别(OCR)和高级分析等技术相结合的解决方案和服务。”

IPA 解决方案和服务也被称为超自动化、智能自动化和数字过程自动化(DPA)。

他们利用 RPA、BPM、人工智能、OCR、ICR 以及任务和过程挖掘,通过端到端自动化业务流程来改善业务运营。

IPA 的解决方案和服务通过能够自主学习和利用分析工具收集的上下文信息在正确的时间采取行动,为客户提供价值。

IPA 还提供了定制的数据挖掘、内容处理和决策模型组件,以实现更智能的业务流程。

2. 任务与过程挖掘(TM/PM)

过程挖掘是一种方法,通过分析信息系统(ERP、CRM 等)生成的事件日志,来实现业务流程的发现、监控和优化。

任务挖掘允许执行与过程挖掘相同的操作,但通过记录任务在用户工作站上的执行,特别是借助人工智能(AI)。

这些技术将使公司流程和操作规则的自动发现成为可能。

其优点包括路径的自动化规范化、过程监控以及实施数字双胞胎的帮助。

这些任务挖掘技术可以通过启用用户操作的发现、规范化和监控,作为 RPA 的良好引导。人工智能在这一层面广泛应用于识别用户操作的元素。人工智能驱动的分析技术也被用来预测自动识别的改进工作流机会的时间和成本影响。

这些解决方案通过引用如用户名、文件夹 ID 等恒定标识符来收集数据(事件日志或屏幕截图)。然后分析这些数据,以生成关于用户行为的报告,并帮助生成过程图。

探索的用例:

  • 过程发现,

  • 合规检查,

  • 过程改进,

  • 变更模拟,

  • 监督。

3. 机器人过程自动化(RPA)

机器人过程自动化是一种用于自动化用户重复性活动的技术。

这些技术是非侵入性的,通常通过软件应用程序的用户界面进行交互。

RPA 场景范围从创建一个自动响应电子邮件,到部署数千个机器人,每个机器人都被编程以在一个或多个系统上自动化工作。

适用于 RPA 的过程包括那些涉及大量重复人工处理的任务,如分类电子邮件、下载附件、将文件中的值输入到业务应用程序中等。

适用性:

  • 现有流程,

  • 体积测量与持续时间,

  • 手动输入,

  • 标准与例外,

  • 时间段。

RPA 解决方案通常配备图形工作室,用于记录用户在其工作站上的工作,录制过程的编辑器,以及用于启动和监督机器人的平台。

RPA 解决方案具有额外功能:规则引擎、文档理解(发票、订单等)、IDP 和智能自动化工具,如图像识别、电子邮件分类、语言检测等。

成熟的 RPA 解决方案已经发展成完整的 IPA 平台。

4. 业务流程管理(BPM)

业务流程管理(BPM)提供了业务流程的概述:它们的组织及其相互作用,以尽可能优化和自动化这些流程。

BPM 通常与 BPMN 形式主义以及通过 BAM 监控流程相关联。

BPMN(业务流程模型和符号)是一种用于描述组织价值链和业务活动的业务流程建模方法,以图形化形式呈现。

BPMN 提供了一种所有自动化利益相关者都能理解的符号:业务分析师、设计师和负责实施自动化流程的开发人员。

业务活动监控(BAM)涉及与业务流程相关的数据的实时获取、汇总、分析和展示。

BAM 仪表板显示关键绩效指标,这些指标总结了关键业务活动的健康状况。

BPM 平台包括:

  • BPMN 和/或规则建模能力,

  • 用于管理建模元数据的流程库,

  • 流程执行引擎,

  • 状态和/或规则管理引擎。

一个用于采购请求业务流程的 BPMN 图示,显示采购和会计部门之间的流程

BPM 允许信息传输自动化,并促进采购部门对请求的批准。

一种具有正常流程的业务流程模型和符号的示例(来源:维基百科 - Mikelo Skarabo — CC BY6SA 4.0)

与 RPA 供应商类似,AI 驱动的工具现在也成为 BPM 解决方案的一部分。

5. 智能自动化(IA)

智能自动化(IA),有时也称为认知自动化,是利用机器学习(ML)技术和自然语言处理(NLP)技术来简化和调整组织中的决策过程。

机器学习和复杂算法可以用来分析结构化和非结构化数据。

这使得公司能够开发知识库并从现有数据中进行预测。

算法解释性和可持续性(绿色计算)的概念在基于 AI 的方法中需要考虑,特别是在 AI 涉及关键系统时。

使用案例的示例:

  • 故障预测,

  • 焊接视觉分析,

  • 下一步最佳行动的推荐,

  • 基于文档的维护协助,

  • 自动回复电子邮件,

  • 简历摘要,

  • 应聘者通信,

  • 需求预测,

  • 诊断协助,

  • 欺诈检测,

  • 路径优化。

6. 智能虚拟助手(IVA)

智能虚拟助手(IVA)是直接与用户互动的计算机程序。在这个类别中,有对话助手,它们是设计用于通过自然对话界面(如语音或文本)实时与用户互动的计算机系统。这些解决方案通常被称为聊天机器人。IVA 使用由机器学习和自然语言处理技术支持的 NLP 技术。目前讨论最多的对话助手是来自 OpenAI 的 ChatGPT。

对话助手可以用于执行各种任务,如回答问题、搜索互联网、安排预约、控制连接设备等。

对话助手通常基于不同的技术,如语音识别、语音生成、自然语言理解、神经网络和深度学习。

尤其是,它们可以在不同的渠道上部署:

  • 移动应用程序,

  • 社交网络,

  • 网站,

  • 连接盒,

  • 接待终端,

  • 元宇宙。

对话助手越来越多地用于改善用户体验、自动化重复的支持任务以及为用户提供自助服务解决方案。

到目前为止,有数百种解决方案允许用户配置自己的助手。

在互联网环境中,用户界面已变得相对标准化,方便用户访问。

对话助手的应用场景不仅限于客户服务,还包括人力资源支持、IT 帮助台、销售、市场营销以及供应链/采购等领域……

7. 智能文档处理(IDP)

智能文档处理解决方案是任何从文档中捕获数据、对数据进行分类并提取相关数据以进行进一步处理的产品或软件解决方案。

文档的示例包括:

  • 电子邮件,

  • 商务文档,

  • 合同,

  • 发票,

  • 订单,

  • 简历……

处理基于计算机视觉、光学字符识别和自然语言处理。处理步骤包括对捕获的图像进行预处理(图像校正)、对文档进行分类、提取数据和验证提取的数据。处理结束后,产品或软件解决方案会返回结构化数据,这些数据可以被计算机程序、RPA 脚本、自动化过程等轻松处理。

处理可能需要人工干预来验证或纠正提取的信息。这种处理被称为“人机协作”。

8. 一个示例!

照片由 Alex Kotliarskyi 提供,来源于 Unsplash

Chapati 每天接收数千封电子邮件。公司中有几个人负责分类这些邮件,处理订单,然后回答关于某些先前订单状态或产品的问题。这些员工会处理每封包含订单的电子邮件,打开完成的扫描表单,根据指定产品的列表进行检查,在公司的各种工具中提出请求,然后回应请求者。一些请求需要验证,员工会联系决策者以获得各种确认。

这家公司希望减轻员工的繁琐数据录入工作,以便他们能从事更有价值的活动,如帮助客户。因此,Chapati 公司启动了一个转型项目。由于他并未掌控各个流程的所有阶段,转型经理通过在负责分类和答复的工作站上放置代理,使用自动任务探索。生成的地图,利用任务挖掘(TM),随后被转化为包含活动和关联序列的图形表示(BPM)。由于公司内部应用程序没有 API,实施了 RPA 脚本来模拟员工的输入工作。根据订单产品的特征,系统自动向决策者请求验证(“人机互动”)。

在业务工作流中,使用电子邮件连接器来检索请求,基于 AI 的子程序用于对这些请求进行分类(请求分类)。根据排序结果,提取订单,并使用智能文档处理(IDP)提取扫描文档中的信息。最后,智能虚拟助手(IVA)自动回答客户的剩余问题。

原本的分类员工现在进行客户咨询操作,从而增强了他们对公司内部操作和产品知识的了解。

9. 最后…

已经无法忽视消费者的数字化转型,并由此扩展到企业。对于公司而言,这种转型意味着对流程及其优化的控制。人工智能是当前正在深刻改变运营模式和产品及服务交付方式的革命。各种技术的结合,服务于公司,已经成为一种至关重要的需求。

然而,首先定义公司的目标是重要的:收入、成本和风险。这也需要对公司的流程、结构、优化水平以及在任何优化之前需要做出的修正有透彻的了解。

IPA 的贡献在于提供一个组织和技术框架,以汇集所有自动化技术来服务于业务流程。

结论

在考虑自动化时,重要的是首先了解业务流程,将这些流程分解为活动,然后确定哪些 IPA 组件最合适。

自动化解决方案提供商的格局正在发生变化,它们正逐渐成为 AI 丰富的套件。它们越来越多地融入基于机器学习的方法的模型。因此,不再仅仅以 RPA、BPM 等术语来思考,而是要理解 AI 的贡献以及这些技术带来的偏见。

要深入了解

[## 对话 AI:2023 年的 7 个趋势和预测

我提出了七个关于对话助手市场演变的新趋势和预测(通常称为…)。

pub.towardsai.net](https://pub.towardsai.net/conversational-ai-7-trends-and-predictions-for-2023-9a644becb90b?source=post_page-----547d60df0590--------------------------------) ## 14 个选择聊天机器人解决方案的标准

选择自然语言对话助手解决方案时,首先要考虑的标准是什么?

towardsdatascience.com ## 2020 年全球聊天机器人解决方案市场概况

来自我对对话助手市场的积极观察,我给出了一些统计数据和信息…

towardsdatascience.com [## 面向构建者的对话 AI:4 个复杂度等级

当你想要构建一个对话 AI 解决方案时,重要的是要记住对话通常遵循…

ai.plainenglish.io](https://ai.plainenglish.io/conversational-ai-for-builders-the-4-levels-of-complexity-scale-4eb482a862d9?source=post_page-----547d60df0590--------------------------------)

什么是学习排名:学习排名方法的初学者指南

原文:towardsdatascience.com/what-is-learning-to-rank-a-beginners-guide-to-learning-to-rank-methods-23bbb99ef38c

关于如何处理机器学习中的 LTR 问题的指南

Ransaka RaviharaTowards Data Science Ransaka Ravihara

·发表于 Towards Data Science ·7 分钟阅读·2023 年 1 月 17 日

--

图片来源于 Possessed Photography,来自 Unsplash

介绍

本文将讨论学习排名究竟是什么。在深入了解内部工作之前,让我们快速了解一下理解所需的基本概念。

首先,让我们探究学习排名的核心直觉。在机器学习中,学习排名(LTR)属于监督学习,我们需要历史数据集来训练模型。但当我开始了解学习排名的概念时,我的第一个困惑是如何区分传统机器学习和 LTR。因为如果我们构建分类或回归模型,我们的因变量和自变量都很简单且更有意义。如果我们需要预测给定客户的贷款违约情况,我们必须将特定的特征向量输入到模型学习的函数 f(x) 中。它会返回客户违约的单一值或类别概率。但在学习排名模型中,这完全不同且令人困惑。

让我们举个简单的例子。

用户 A 访问一个网站并输入查询 q。在这种情况下,我们的系统返回了一些文档,换句话说,就是搜索结果,如下所示。

图片作者

如果我们有一个好的排序模型,这些结果的相关性(r)应该是 r(d1) > r(d2) > r(d3)。在幕后,我们的模型应该为每个与该查询相关的文档返回相关性分数。因此,我们的模型应该学习一个函数,该函数以查询和文档作为参数,并为特定的查询-文档对生成相关性分数。然后我们可以进行一些计算,并以这种方式对文档进行排序,使得高度相关的文档获得更高的排名。

逐点排序

让我们讨论一下实现这一点的一种方法。首先,我们需要数据。为了简化,假设一个假设场景,其中我们有两个查询,q1, q2,以及它们各自的文档列表 [d1,d2,d3], [d5,d6,d7]

作者提供的图像

通常,我们知道 d1,d2d3 文档对 q1 是相关的,但对 q2 不相关,反之亦然。因此我们可以按如下方式填充样本。

*示例 1: d1,q1; 标签 :1

示例 2: d2,q1; 标签 :1

示例 3: d3,q1; 标签 :1

示例 4: d4,q2; 标签 :1

示例 5: d5,q2; 标签 :1

示例 6: d6,q2; 标签 :1*

如果你查看上述数据,这个问题现在被简化为一个传统的分类/回归问题,其中输入(查询文档对)与标签之间存在一对一的映射关系。

附加信息

要使用机器学习解决这个问题,你可以对查询数据和文档数据进行特征工程,然后将其输入到模型中,最终得到预测。一些理想且简单的特征工程是获取 john 和 sushi 在查询和文档中出现的次数。

信不信由你,你刚刚学会了一种叫做逐点排序的学习排序方法。

逐点排序是找到一个函数,该函数在给定查询的情况下返回每个文档的相关性。之所以称为逐点排序,是因为每个文档都根据真实目标值独立评分,就像传统的回归和分类任务一样。

让我们讨论一下逐点排序方法的优缺点。一方面,它的优点是简单。但这种简单性也带来了显著的缺陷,例如,

  1. 每个实例被视为一个孤立的点。

  2. 显式的逐点标签是创建训练数据集所必需的。

为了克服这些挑战,我们可以使用对偶排序方法。

对偶排序

在这里,目标是定义一个排序函数,以根据给定的查询对每个文档进行评分。然后将文档按照这些分数的降序排列,表示文档与查询的相对相关性。

在学习过程中,提供多个查询,每个查询都有一对相关文档。使用这些训练数据创建一个排序函数,以便模型可以预测未来查询的相关文档。

让我们以之前的sushi recipe 示例为例。与点对点排序方法不同,我们现在考虑每个查询的两个文档。例如,我们知道d1, d2d3q1相关。在这种情况下,所有可能的查询文档对应如下。

*示例 1: q1, (d1,d2)

示例 2: q1, (d1,d3)

示例 3: q1, (d2,d3)*

其中(di,dj)表示文档ij的顺序。如果我们对文档ij 应该如何排序有明确的标签,我们可以推导出(di,dj)的标签。假设文档j的相关性评分为 3(高度相关),而文档i的相关性评分为 0(较少相关),对于查询q。在我们的最佳排名中,文档i 应该排在文档j 之前。再次,这被简化为传统的分类任务。但不同于点对点排序,这种方法考虑了排名位置。

作者提供的图片

在 LightGBM 的 lambdarank 目标中使用的成对损失函数。使用 LightGBM 的 Python 库,我们可以用几行代码训练这种最先进的 LTR 方法。

由于我们可以将其简化为分类任务,因此可以使用已知的方法论。它还将文档顺序纳入模型中。这也有一些缺点。尽管学习考虑了文档对的顺序,但目标并没有明确设置为对文档进行排序;相反,它试图减少文档对的分类错误。此外,当数据集中包含大量文档和查询对时,训练可能非常昂贵。文档的数量因查询而异,这导致模型对具有大量文档对的查询存在偏差。

列表排序

研究人员引入了一种新颖的列表排序方法,以克服 LTR 中的一些显著缺点。

在这种方法中,我们考虑的是文档的排序列表及其相关性标签,而不是文档对。

为了获得每个查询中文档的相关性标签,我们可以使用人工标注者或某个文档收到的点击次数。

作者提供的图片

在学习阶段,我们必须根据查询和文档对添加特征。如果i 代表查询的索引,j 代表文档的索引,我们可以定义特征向量如下。

作者提供的图片

有了这个,我们可以定义每个文档-查询对的特征以及真实标签。

作者提供的图片

最后,我们可以将训练实例表示为,

作者提供的图片

其中 m 是数据集中查询的数量。最后,创建一个排名函数 f,它为每个特征向量 x_ij 输出一个分数。然后获取一个分数列表 z_i

图片来源:作者

学习的目标是最小化相对于训练数据的总损失。当应用排名时,我们可以使用训练好的函数根据特征向量给新文档分配分数。然后按分数的降序对文档进行排序。

得益于这一学习过程,它可以学习列表中项目之间的关系,例如共现或依赖关系。凭借这一优点,它需要大量标记数据来学习列表中项目之间的关系;因此,训练和优化可能会计算量大。此外,listwise 方法在新领域或标记数据稀缺的细分领域中可能存在问题。

让我们总结一下我们在本文中学到的内容。

LTR 方法的比较 | 图片来源:作者

系列中的下一篇文章: 如何评估学习排序模型

## 如何评估学习排序模型

关于如何评估机器学习中的 LTR 模型的实用指南

towardsdatascience.com

感谢阅读!

参考文献:

什么是部分信息分解及特征如何交互

原文:towardsdatascience.com/what-is-partial-information-decomposition-and-how-features-interact-a713456a1029?source=collection_archive---------3-----------------------#2023-12-08

关于目标变量的信息如何在其多个特征中分布

Rodrigo Silva Towards Data Science Rodrigo Silva

·

关注 发表在 Towards Data Science · 10 分钟阅读 · 2023 年 12 月 8 日 []

--

图片来源:Alina Grubnyak,来自 Unsplash

当目标变量受到多个信息来源的影响时,理解每个来源对整体信息的贡献是至关重要的(虽然这并不简单)。

在这篇文章中,我将从惊讶的基本概念开始,然后解释熵如何由分布在随机变量上的平均惊讶量组成,这为我们定义互信息提供了条件。接下来,我将讨论在信息来源多个的情况下的部分信息分解。

惊讶与熵

也许从信息的角度定义熵最直观的方法是首先谈谈惊讶。惊讶的度量正如我们所期望的那样:不太可能发生的事件更令人惊讶,而更可能发生的事件则不那么令人惊讶。涵盖这些属性的数学定义如下:

从图 1 中的图表可以看出,这一定义与我们讨论的属性非常相关。当某些事件发生的概率很高(p 接近 1)时,惊讶度接近零。另一方面,如果事件发生的概率非常低,则其惊讶度会变得任意大。

图 1:惊讶的图示。作者提供的图像。

那么,熵与惊讶有什么关系呢?熵是随机变量所有值的平均惊讶。因此,如果我们有一个随机变量 X,且 X 的所有可能结果的集合称为 A_X(我们称之为 X 的“字母表”),那么熵 H 定义为:

很好。现在我们将熵与惊讶联系起来,可以理解熵的一个有用解释:

熵是无知的度量。

这怎么可能呢?我将通过一个简单的例子来解释。假设你需要参加一个期末物理考试。在我们目前所发展的语言中,我们可以将考试视为具有某些可能问题字母表的随机变量。现在假设两个场景:

  1. 你为这次考试努力学习,你知道考试中会出现什么样的问题,所以平均来说,你不会对考试感到太惊讶。

  2. 你没有认真学习,也不知道考试中会出现什么类型的问题,所以你在考试中的惊讶度会相当高。

所以,当你的平均惊讶度更大时,正好与信息较少的情况相吻合。

从技术角度来看,更尖峰的分布(例如某些值比其他值更可能发生的分布)具有比更分散的分布更低的熵,而后者中的每个事件发生的概率大致相同。这就是为什么我们说熵最高的分布是均匀分布,在这种分布中,任何值发生的机会都相同。

熵和(互)信息

现在我们已经建立了一个由随机变量描述的系统的平均惊讶度量(即熵),我们可以将熵与信息建立联系。

由于熵是对某个系统的无知的度量,它的缺乏代表着… 信息。从这个意义上说,创建一个叫做互信息的度量是很自然的:它衡量的是当你知道系统的一些信息后,你获得的信息量。

这个定义是:取随机变量 X 的平均惊讶度,然后取随机变量 X 的平均惊讶度,但现在考虑我们知道另一个随机变量 Y 的结果。将前者减去后者,你就知道通过了解 Y,你从系统 X 中移除了多少 无知

回到我们愚蠢的例子:假设你不知道考试中会问哪些问题,这就是 X。现在假设你的一个朋友在你考试前一周做了一个来自同一老师、关于同一科目的测试。他告诉你他的测试涵盖了哪些内容(这恰好是另一个随机变量 Y)。最可能的情况是,你对自己考试的无知减少了,这意味着你的测试 X 和你朋友的测试 Y 共享信息。

图 2 中有一个清晰易懂的维恩图,展示了两个变量 X 和 Y 之间的熵和共享信息的关系。

图 2:互信息方案。图像由作者提供,受到许多其他图像的启发。

但如果我们有多个信息来源呢?

到目前为止,我们只讨论了一个特征 X 和一个目标变量 Y 的情况,但显然这并不具有良好的普遍性。因此,现在设想我们有一个随机变量 Y(比如一个分类模型中的目标变量),我们想知道模型中每个特征 X_1, X_2, …, X_n 提供的信息量。可以说,只需计算 X_1 和 Y 之间的互信息,然后是 X_2 和 Y 之间的互信息,依此类推。然而,在现实世界中,我们的特征可能会相互作用并创建非平凡的关系,如果我们想要一个一致的框架,就必须考虑这些相互作用。

让我们考虑一个有两个输入信号 X_1 和 X_2 的情况,我们想要量化这两个特征和一个目标特征 Y 之间的互信息。也就是说,我们想要计算 I(Y; {X_1, X_2})。部分信息分解框架指出,这些信息可以分为四个非负成分:

  1. Syn(Y; {X_1, X_2}):两个特征的协同作用。这是两个特征共同提供的关于 Y 的信息量。

  2. Rdn(Y; {X_1, X_2}):两个特征的冗余度。这个量表示关于 Y 的信息,这些信息可以通过 X_1 或 X_2 单独解释。

  3. Unq(Y; X_1) 和 Unq(Y; X_2):唯一信息,衡量的是只有 X_1 可以解释的关于 Y 的信息(对于 Unq(Y; X_1))或只有 X_2 可以解释的关于 Y 的信息(对于 Unq(Y; X_2))。

注意,只有Unq(Y; X_1)和Unq(Y; X_2)对应于特征之间没有交互的情景。因此,互信息I(Y; {X_1, X_2})可以分解为其四个组件:

I(Y; {X_1, X_2}) = Syn(Y; {X_1, X_2}) + Rdn(Y; {X_1, X_2}) + Unq(Y; X_1) + Unq(Y; X_2)

像之前一样,我们可以绘制一个漂亮的维恩图来总结这些量的依赖关系。

图 3:部分信息分解的维恩图。图像由作者提供,受[1]的强烈启发。

每个这些术语被称为信息原子。任何非原子信息都可以分解为原子部分,而原子部分不能再分解。

是威廉姆斯和比尔[1]首次提出了这一框架(并提出了一种计算部分信息的方法)。事实证明,计算这些量并不简单,值得专门写一篇文章。部分信息分解有不止一种测量方法,所有这些方法都遵循相同的过程:他们设想一种满足一系列理想特性并与我们期望的某个量称为“信息”的一致的测量方式。所有这些测量方法都有强项和弱项,它们在dit库中得到了很好的实现,并将在接下来的部分中简要介绍并用来给出一些例子。

部分信息分解示例和 dit 库

为了将这些概念结合起来,让我们看一些例子。dit库是进行信息理论概念实验的绝佳工具。它是一个创建自定义概率分布的库,然后对其进行测量。这个库有几个功能,可以在他们的Github或官方文档页面中找到。

对于接下来的所有例子,我们可以考虑两个特征 X_1 和 X_2,都是二进制的,目标变量 Y 是特征的一些布尔操作。所有测量部分信息的形式将基于威廉姆斯和比尔[1],但其他作者提出的形式也在dit中实现。

独特信息

对于这个例子,假设目标变量 Y 如图 4 所示。注意输出总是等于特征 X_1,这使得特征 X_2 完全无关紧要。

图 4:与唯一信息源的 AND 门示意图。

因此,X_1 和 X_2 对 Y 提供的信息完全集中在 X_1 中。在到目前为止我们所开发的形式中,我们可以说关于 Y 的信息对 X_1 是唯一的。

dit库中,我们可以这样创建:

import dit                    # importing dit library
from dit.pid import PID_WB    # importing the PID measure we want to use

# creating a probability distribution of AND gate
dist_unique = dit.Distribution(["000", "010", "101", "111"], [1/4, 1/4, 1/4, 1/4])

print(PID_WB(dist_unique))

"""
Out:
+--------+--------+--------+
| I_min  |  I_r   |   pi   |
+--------+--------+--------+
| {0:1}  | 1.0000 | 0.0000 |
|  {0}   | 1.0000 | 1.0000 |
|  {1}   | 0.0000 | 0.0000 |
| {0}{1} | 0.0000 | 0.0000 |
+--------+--------+--------+
"""

dit库对信息的编码如下:

  • {0:1}: X_1 和 X_2 之间的协同信息

  • {0}: X_1 提供的独特信息

  • {1}: X_2 提供的唯一信息

  • {0}{1}: X_1 和 X_2 提供的冗余信息

从输出中我们可以看到,唯一的部分信息(“pi”列)来自 X_1。

冗余信息

下一个例子展示了冗余信息。在这里,X_1、X_2 和 Y 的值相等,如图 5 所示,因此 X_1 和 X_2 提供的关于 Y 的冗余信息是最大的。

图 5:完全冗余的信息。

使用dit代码如下:

import dit                    # importing dit library
from dit.pid import PID_WB    # importing the PID measure we want to use

# creating a redundant probability distribution
dist_redundant = dit.Distribution(["000", "111"], [1/2, 1/2])
print(PID_WB(d_redundant))

"""
Out: 
+--------+--------+--------+
| I_min  |  I_r   |   pi   |
+--------+--------+--------+
| {0:1}  | 1.0000 | 0.0000 |
|  {0}   | 1.0000 | 0.0000 |
|  {1}   | 1.0000 | 0.0000 |
| {0}{1} | 1.0000 | 1.0000 |
+--------+--------+--------+
""" 

正如我们所见,X_1 和 X_2 提供的关于 Y 的唯一信息是冗余的,换句话说,由它们共同提供。

协同信息

协同信息的经典例子是 XOR 门。XOR 门的图示见图 6。

图 6:具有完全协同信息的 XOR 门

从这种分布中可以看出,只有在知道 X_1 和 X_2 的情况下,我们才能知道目标变量 Y。因为对于每个 X_1 的值,我们都有 Y 的两个值;同样的情况也适用于 X_2。dit中的代码如下:

import dit                    # importing dit library
from dit.pid import PID_WB    # importing the PID measure we want to use

# creating a probability distribution of XOR gate
dist_syn = dit.Distribution(["000", "011", "101", "110"], [1/4]*4)
print(dist_syn)

"""
Out:
+--------+--------+--------+
| I_min  |  I_r   |   pi   |
+--------+--------+--------+
| {0:1}  | 1.0000 | 1.0000 |
|  {0}   | 0.0000 | 0.0000 |
|  {1}   | 0.0000 | 0.0000 |
| {0}{1} | 0.0000 | 0.0000 |
+--------+--------+--------+
""" 

正如预期的那样,X_1 和 X_2 传递的关于 Y 的唯一信息是{0:1},这是协同信息。

最终评论和要点

最终,我们可以看到,当我们仅依赖互信息时,变量之间的互动可能会带来挑战。需要一些工具来测量来自多个源的信息(以及这些信息源之间的互动)。这是部分信息分解(PID)框架的理想场景。

通常,这一领域的测量方法较为复杂,涉及一些形式逻辑:这些内容可以留待另篇详细文章,但现在只需说明,这些工具不仅重要,而且它们的需求自然来源于信息方法。

参考文献

[1] P. L. Williams 和 R. D. Beer, 多变量信息的非负分解arXiv 预印本 arXiv:1004.2515,2010 年

[2] Shujian Yu 等,通过信息理论理解卷积神经网络:初步探索arXiv 预印本 arXiv:1804.06537v5,2020 年

[3] A. J. Gutknecht, M. Wibral 和 A. Makkeh, Bits and pieces: 理解从部分-整体关系和形式逻辑中的信息分解arXiv 预印本 arXiv:2008.09535v2,2022 年

[4] James, R. G., Ellison, C. J. 和 Crutchfield, J. P., dit: 用于离散信息理论的 Python 包,《开源软件期刊》,2018 年

什么是过程挖掘?

原文:towardsdatascience.com/what-is-process-mining-683b5eb6547c?source=collection_archive---------9-----------------------#2023-01-04

Samir SaciTowards Data Science Samir Saci

·

关注 发表在 Towards Data Science ·12 分钟阅读·2023 年 1 月 4 日

--

通过本全面指南,学习如何使用 Python 进行过程挖掘,并解锁业务数据的潜力。

过程挖掘是一种数据分析类型,专注于发现、监控和改进业务流程。

过程挖掘涉及分析来自各种来源的数据,例如过程日志,以了解过程如何执行,识别瓶颈和低效之处,并建议改进方法。

供应链信息系统在过程挖掘中的示例 — (作者提供的图片)

在之前的文章中,我分享了用于监控和可视化物流绩效、建立自动化供应链控制塔或创建智能可视化的 Python 工具示例。

作为数据科学家,你如何利用流程挖掘来优化物流操作?

本文将超越监控,探讨流程挖掘如何帮助你识别瓶颈并提高生产力。

💌 免费订阅直达你的邮箱:通讯

📘 供应链分析的完整指南:分析备忘单

I. What is Process Mining?
1\. Understanding Process Mining
2\. How Process Mining Can Benefit Your Business Operations
II. How to Implement Process Mining with Python
1\. Real-World Examples of Process Mining with Python
2\. Approach 1: Discovery
3\. Approach 2: Conformance
4\. Approach 3: Enhancement
5\. Best Practices for Process Mining with Python
III. Conclusion
1\. You need clean data
2\. Simulate initiatives using a Digital Twin
3\. Focus on sustainability

什么是流程挖掘?

理解流程挖掘

流程挖掘技术可以应用于许多过程,包括制造、供应链管理、医疗保健和客户服务。

我们想要实现什么目标?

流程挖掘可以帮助组织理解其流程如何运作,识别改进领域,并通过分析过程数据做出优化决策。

平均来说,客户团队处理一个订单需要多长时间?

客户服务的流程挖掘示例 — (图片由作者提供)

例如,在这篇文章中,我们探讨了一种用于估算客户服务团队订单处理时间的统计方法。

这对你的组织有什么好处?

流程挖掘如何使你的业务运营受益

流程挖掘有多种不同的方法,包括发现、符合性和改进。

  • 发现涉及使用流程挖掘技术根据流程日志中的数据揭示流程的结构和行为。

  • 符合性涉及将实际过程与期望的过程模型进行比较,以识别偏差和差异。

  • 改进涉及使用流程挖掘基于数据分析建议改进措施。

让我们看看如何使用 Python 实现这一点。

如何使用 Python 实施流程挖掘

使用 Python 的流程挖掘的实际案例

以一个国际服装集团的供应链网络为例。

这家公司销售生产海外工厂的服装、包袋和配件,以补充区域仓库网络

时尚零售公司的供应链网络 — (图片由作者提供)

本文将关注商店的这些区域仓库的交付。

信息系统之间的数据交换 — (图像由作者提供)

每个过程步骤由特定系统(ERP、WMS、TMS)管理,这些系统记录信息和时间戳,我们将用于过程挖掘。

我们如何利用生成的数据来检测瓶颈并提高整体效率?

方法 1:发现

时间戳定义 从订单创建到商店接收,时间戳由不同系统记录。

每个过程的时间戳 — (图像由作者提供)

  • 订单创建时间ERP中由配送计划员创建的时间。

  • 订单接收时间 在仓库管理系统(WMS)(现在准备由仓库团队进行)

  • 拣货时间 包括拣货任务的开始和结束时间,该任务包含订单。

  • 包装时间包装过程结束的时间。

  • 运输时间 当你的订单离开仓库时的时间。

  • 交付时间 当你的卡车送货到商店时的时间。

  • 商店接收时间 是结束交付过程的时间:商店团队在ERP中记录收到的物品的时间。

💡 了解你的流程 系统在你的公司中可能被不同地使用。因此,确保流程已用详细的工作流程进行映射。

提前期定义

由于时间戳本身没有意义,我们通过两个时间戳之间的差异来定义每个过程的提前期。

配送的物流提前期定义 — (图像由作者提供)

他们通常指的是特定团队的责任。

  • 端到端提前期 用于衡量整个物流部门的绩效,也定义为按时全量(OTIF)

  • 订单转移周期IT/基础设施团队负责,确保订单的快速传输

  • 仓库运营团队绩效准备周期来衡量

  • 发货周期是一个灰色地带,因为仓库团队、财务部门(开票)或运输团队(寻找运输卡车)都可以影响它

  • 运输周期完全在运输团队的范围内

  • 接收周期是门店团队的责任

💡 你需要系统专家的支持 你的系统可能没有每个过程的时间戳,但你的基础设施团队总能找到替代解决方案。

例如,当打包过程结束时,没有时间戳显示。

  • 但订单状态正在变化(从打包到准备发货)。

  • 可以开发脚本来在状态变化时创建时间戳。

  • 然后可以将其填充到你用作数据源的数据湖中。

我们该如何处理这些数据?

c) 使用 Python 进行数据处理 使用 Python,你可以连接到不同的系统,从其各自的数据库中提取事务记录。

用 Python 处理数据处理 — (作者提供的图片)

这些系统可能有不同的字段和指标定义。使用订单号将表格合并到一个数据框中,并计算周期时间。

周期时间图例 — (作者提供的图片)

上图显示了周期时间图例(以分钟为单位),提供了订单传输、拣货和包装以及仓库-机场转移的性能波动概览。

有关如何构建物流绩效仪表板的更多信息,请查看这个简短的视频,

方法 2:合规性

a) 交付周期:按时全面交付

最重要的关键绩效指标是从订单创建到交付时间的周期。

了解更多关于 OTIF 的信息 — (作者提供的图片)

分销计划员利用它来管理库存,设定安全库存并计划新产品发布。

在门店接收到 ERP 中创建的订单需要多长时间?

门店经理还会利用它来挑战物流部门在不同的供应绩效评估中。

b) 端到端交付流程

在我们的例子中,我们的交付周期目标是72 小时

交付订单流程示例 — (作者提供的图片)

上面的例子显示了符合目标周期时间的交付。

💡 截止时间定义 订单接收截止时间是 18:00:00。

如果在这个时间之后收到订单,你必须等待 24 小时才能准备好。

它们是延迟交货和干扰的主要原因。

我们现在可以可视化数据。

c) 可视化 定义后,你可以使用你的 Python 脚本将提前时间与这些目标进行比较。

使用 Python Matplotlib 的提前时间目标图 — (作者提供的图像)

在这个可视化中,你可以看到。

  • 对于一些订单,仓库团队需要遵守 5.5 小时(630 分钟)的准备提前时间目标。

  • 订单传输或仓库机场转运永远不会成为问题,因为你远低于最大提前时间。

仅此图表就可以帮助运营团队发现分销过程中的故障并制定行动计划。

方法 3:改进

a) 可视化延迟。 目标是确保你所有的订单都在72 小时内传输、准备和交付。

它从帮助你回答简单问题的可视化开始。

  • 有多少订单已迟交?

  • 哪个过程对你的整体提前时间影响最大?

延迟根本原因甜甜圈图 — (作者提供的图像)

根本原因分析的可视化 — (作者提供的图像)

上面的可视化将帮助你发现迟交货并快速筛选不同的环节,以了解哪一部分影响了你的提前时间。

  1. 开始查看底部图表。

  2. 你发现一个订单的提前时间超过了黄色线。

  3. 筛选上述提前时间以找出导致延迟的部分。

💡 原因代码映射 作为诊断分析的一部分,你可以开始自动创建

迟交货的原因代码将用于上面如甜甜圈图所示的可视化。

如果你的货物延迟且装载提前时间高于目标,你可以添加一个迟交货原因代码:装载。

b) 过程挖掘以减少延迟 现在你知道了根本原因,你可以专注于设计解决方案以避免未来的延迟。

在过去三个月的延迟中是否存在任何模式?

例如,

  1. 你发现许多订单由于长时间的运输提前时间而延迟交付。

  2. 经过进一步分析,你发现根本原因是开票过程

  3. 这个过程取决于交货地点(地区、商店类型(免税店、加盟店等),产品类别,订单类型(交叉对接、补货、收集启动),以及订单创建日期。

延迟开票预测模型 — (作者提供的图像)

你使用数据训练一个模型,预测使用上述特征的开票过程延迟的概率。

  1. 你发现布尔输出(按时开票)与订单创建日期(周一,.. 周日)、以及商店区域(欧洲、中东、亚洲、美洲)之间存在高度相关性。

  2. 绝大多数迟到的发票来自一周的后半段中东地区的商店创建的订单。

  3. 在与中东地区的本地物流团队对齐后,你发现发票处理在周四和周五停滞,因为这些是该地区的周末。

然后你可以要求需求规划师(位于欧洲)调整他们的订单创建流程以适应这些地方特性。

💡 为操作和 IT 团队带来洞察 上面的例子表明,单靠数据无法设计解决方案或解决问题。

使用 Python 进行流程挖掘的最佳实践

它们需要被纳入。

  • 定义时间戳以确保从系统中检索的信息与操作现实相匹配。

  • 确定交付时间定义,以便与贵公司的供应链绩效管理对接。

    (例如:如果商店接收未纳入运输团队的绩效评估中,你需要将其移除)

  • 使用 Python 处理数据,以确保你用于计算的字段是正确的。

  • 创建可视化以确保操作团队能够使用它们获取洞察。

你设计的模型和可视化将提供洞察,支持持续改进举措并提升战略决策。

结论

总体而言,流程挖掘可以成为提高业务流程效率和效果的强大工具,组织越来越多地利用它来推动流程改进工作。

你有经过统一清洗的数据吗?

这需要统一且清洁的数据。

这一基本要求可能是你数字化转型过程中一个重要障碍。

最坏的情况,遗憾的是非常常见,将是一个组织:

  • 多个系统无法相互通信,如多个ERP实例、一个由第三方物流完全控制的每个仓库的 WMS,以及几个未与ERP接口的 TMS。

  • 许多未记录的自定义设置,如由离职开发人员创建的附加字段。

  • 缺乏像数据湖这样的单一来源,无法整合你不同系统的数据库。

在这个阶段,你需要在进行流程挖掘之前,致力于统一和建立一个坚实的数据架构(具有数据治理以维护数据完整性)

诊断后,你需要实施行动计划。

我们能否使用分析来模拟持续改进举措的影响?

使用数字双胞胎模拟举措

数字双胞胎是物理对象或系统的数字复制品。

使用 Python 的供应链数字双胞胎 — (图片来源:作者)

就像你有一个计算机模型来表示供应链中的各种组件和过程,比如仓库、运输网络和生产设施。

你是否想模拟运营提出的举措的影响?

在发现操作故障并找到根本原因后,你可以模拟几种情景,并测试解决方案的弹性。

  • 如果我们使用最后一公里快递配送订单会怎么样?

  • 如果我们增加仓库员工,延迟减少将会是多少?

这个模型可以估算性能改进,计算投资回报,并说服管理层投资额外的资本支出。

更多详情,👇

## 什么是供应链数字双胞胎?

使用 Python 探索数字双胞胎:建模供应链网络,提升决策能力,优化运营。

towardsdatascience.com

除了性能,你的操作对环境的影响如何?

本文聚焦于性能和物流成本。

然而,现在公司被迫减少环境足迹,我希望能打开供应链可持续性的窗口。

你听说过绿色库存管理吗?

专注于可持续性

当我担任解决方案设计师时,我们的零售客户主要关注的是减少运输成本。

Samir,我们需要将每吨的成本降低 25%。

我一直建议减少配送频率,并增加每次发货的数量,以提高卡车的装载率。

这就是绿色库存管理的起点。

这可以被定义为以环保的方式管理库存。

(图片来源:作者)

确实,除了减少二氧化碳排放外,这种方法在成本上也具有优势。

店铺补货系统 — (图片来源:作者)

大多数零售商使用 库存管理系统,这些系统采用基于规则的方法来补充商店,但没有考虑运输路线的效率。

补货频率 是一个重要的参数,可以用来优化分销网络。

我们可以模拟配送频率对二氧化碳排放的影响吗?可以!

为了证明我的观点,在本博客中分享的案例研究中,我模拟了不同配送频率对包装材料使用和二氧化碳排放的影响。

模拟模型 — (图片来源:作者)

对于每种情景,该模型可以提供

  • 准备好的 混合纸箱 的百分比 (%)

  • 部分填充卡车用于配送商店的百分比 (%)

  • 使用的 纸箱材料 总量 (kg)

  • 道路运输的总 CO2 排放(kg CO2eq)

如果您对这种方法有信心或想挑战我的方法论,请查看这篇文章,

## 数据科学与可持续性 - 绿色库存管理

模拟商店配送频率对时尚零售商 CO2 排放的影响

towardsdatascience.com

关于我

LinkedinTwitter上联系我。我是一名供应链工程师,利用数据分析来改善物流操作并降低成本。

如果您对数据分析和供应链感兴趣,请查看我的网站。

[## 萨米尔·萨西 | 数据科学与生产力

一篇技术博客,专注于数据科学、个人生产力、自动化、运筹学和可持续性……

samirsaci.com](https://samirsaci.com/?source=post_page-----683b5eb6547c--------------------------------)

参考文献

什么是合成数据?

原文:towardsdatascience.com/what-is-synthetic-data-e4820ccebfcf

让数据变得有用

伪数据各种类型的实地指南:第一部分

Cassie KozyrkovTowards Data Science Cassie Kozyrkov

·发布于 Towards Data Science ·阅读时长 6 分钟·2023 年 6 月 30 日

--

合成数据,直白地说,就是虚假的数据。也就是说,这些数据实际上并不来自你感兴趣的群体。(群体是数据科学中的一个技术术语,我在这里解释了。)这是一种你打算当作来自你希望的地方/群体的数据来处理的数据。(其实并没有。)

合成数据,直白地说,就是虚假的数据。

人工数据、合成数据、虚假数据模拟数据都是同义词,每个术语的流行程度略有不同,因此它们带有不同年代的诗意内涵。如今,时髦的孩子们更喜欢使用合成数据这个流行词,也许是因为投资者需要被说服相信某种新事物已经被发明,而不是重新发现了什么。这里确实有一些略新的东西,但(在我看来)还不够新,无法使所有旧观念变得不相关。

让我们深入了解!

一些合成数字!所有图片版权归作者所有。

(注意:这篇文章中的链接将带你到同一作者的解释文中。)

无限的可能性

如果你像我一样经历了一个关于高级概率论和测度理论的研究生课程(我的治疗师和我至今仍在处理它),你会极其清楚地意识到有无限的实数。除了其他事情外,无限意味着如果你尝试列举它们,我可以像个混蛋一样 swoop in 发现一个新的,例如通过在你最大数字上加 1,取你两个最接近数字的平均值,或在小数点后最长的一系列数字的后面加一个数字。

这也意味着,如果你给我提供人类历史上所有记录过的数字列表,我仍然可以创造出一个全新的数字。哇!这就是力量。

除了为你下一次关于是否存在真正原创性的争论(呃)提供话题,我想表达什么呢?

合成数字

假设你有一个充满人类身高的数据集。在任意两个测量值之间(比如 173 厘米和 174 厘米,这个区间内会有我的身高),你可以写下无限多的数字。只需不断延长小数位数,超越我们测量工具的合理能力。超越亚原子粒子。超越常识。我仍然可以编造出很多数字,比如:173.4335524095820398502639008342984598739874944444443842397593645873649572850263894458092843956389479592489586232342349832842849687394208287645545352525353353826482384724628732648732799999992323……

生成这些愚蠢数字的规则完全超出了实用和现实的范围,因此当你要求我提供一个可能代表人类身高的数字以添加到你的数据集中时,我会如何处理你的请求?

现实世界数据

一个选择是给你一个来自真实人的实际数据。我环顾四周,发现了我的好友Heather(这是个真实的故事,她说了声你好),并为你的数据集测量她。如果你的关注人群是所有人类,她的身高会成为你数据集中一个合法的数据点,只要(这可是个大问题)我按照你为测量人群所制定的规则进行测量。

嘈杂数据

如果我用笔记本电脑(对不起,我没带卷尺去我们周末的度假地)以最接近 13 英寸的精度来测量 Heather 的身高,而你用的是毫米的米尺来测量身高,那我们会遇到问题。

当我们说数据嘈杂时,我们指的是其中存在非确定性误差,掩盖了真实答案。如果我决定用笔记本电脑来测量 Heather 的身高(或者Smoots),那正是会发生的情况。

从我这里得到的任何测量都会有随机误差,这种误差与其余数据中的误差类型不同。为了应对我们可能打开的麻烦罐子,请务必记录数据来源。(是你还是我收集的?)你可以在之后删除我的条目……只要它们没有混在你的合法数据贡献中。

在收集现实世界的数据时,出错的情况出乎意料地容易。要了解更多,请查看我的数据设计和数据收集系列:

## 数据设计的晦涩艺术

在数字时代挑战一种尴尬的新炼金术

[towardsdatascience.com ## 简单随机抽样:真的简单吗?

如何为你的数据项目创建一个抽样计划

[towardsdatascience.com

手工制作的数据

假设没有人来测量,但你还是想要另一个数据点?(你为什么会想这样做,这有什么优缺点?请参阅我下一个博客帖子!)

那么你是在说你接受合成数据。(如果你允许合成数据进入你的项目,始终记录哪些数据点是合成的以及它们是如何生成的!)

我还可以通过随意编造一个数字来提供一个身高数据点。如果我特别古怪,我甚至可能会抛出一个像-5 + 60sqrt(-1)*这样的复杂数来搅扰你。你说我不能?你应该这么说。如果你让我胡乱编造,你需要限制我的创造力。

没有虚数?好吧,那-100 怎么样?

哦,必须在实际人体身高范围内?那之前的 173.43355240……怎么样?

小数点位数太多因为人类测量仪器不够灵敏?好吧,173.5 厘米怎么样?

我们可以称之为手工制作的数据,因为我,一个人,通过手工制作一个对我有吸引力的例子来得出了它。

但是如果你想要多个新的身高数据点,而你告诉我理智点,并将我的选择四舍五入到最接近的毫米?

好吧,我可能会想出:173.5 厘米、182.4 厘米、175.1 厘米、190.2 厘米、180.1 厘米……

这些都是可信的人体测量数据,但它们偏高。它们可能并不能很好地代表你的目标人群。它们受到我对数据集中理想条目理解的偏见影响。而且对人类身高了解多少呢?可以做得更好。

那么,让我们在第二部分中做得更好,在那里我们将进行一次涵盖以下内容的旅程:

  • 重复数据

  • 重抽样数据

  • 自助抽样数据

  • 增强数据

  • 过度抽样数据

  • 边缘情况数据

  • 模拟数据

  • 单变量数据

  • 双变量数据

  • 多变量数据

  • 多模态数据

或者可以参考我的其他数据分类指南:

## 你能说出多少种数据类型?

连续的、离散的、分类的、序数的……继续吧!

[towardsdatascience.com ## 数据来源全解析

混淆数据、继承数据、耗尽数据以及其他“妖精”

[towardsdatascience.com

感谢阅读!如何来一门课程?

如果你在这里度过了愉快的时光,并且正在寻找一个不无聊的以领导力为导向的课程,旨在让 AI 初学者和专家都感到愉快,这里有个小东西我为你准备的:

课程链接: bit.ly/funaicourse

## 加入 Medium

阅读 Cassie Kozyrkov 的每一篇故事(以及 Medium 上成千上万其他作家的故事)。您的会员费用直接支持…

kozyrkov.medium.com

附注:你曾尝试过在 Medium 上多次点击“鼓掌”按钮看看会发生什么吗? ❤️

喜欢作者吗?与 Cassie Kozyrkov 联系

让我们成为朋友吧!你可以在 TwitterYouTubeSubstackLinkedIn 找到我。想让我在你的活动中演讲?使用 这个表单 与我联系。

所有图片版权归作者所有。

SQL 中 UNION 和 JOIN 的区别是什么?

原文:towardsdatascience.com/what-is-the-difference-between-union-and-join-in-sql-c7cff3975ff4

UNION、EXCEPT 和 INTERSECT 的 5 分钟指南

Mike HulsTowards Data Science Mike Huls

·发表于 Towards Data Science ·7 分钟阅读·2023 年 5 月 1 日

--

我们有大量数据需要处理(图片由 Simon Berger 提供,来源于 Unsplash

在本文中,我们深入探讨了三个经常被忽视的 SQL 操作符:EXCEPTINTERSECTUNION。我们将:

  1. 使用清晰的例子和视觉图像来彻底理解这些概念

  2. 理解操作符的“规则”以真正掌握如何使用它们

  3. 探索一个更复杂的例子

  4. 理解与 JOIN 的区别,并讨论何时使用哪个

在本文结束时,你将掌握一些强大的 SQL 工具,所以让我们开始编程吧!

在我们开始之前...

在一些数据库中,如 SQL Server、PostgreSQL 和 SQLite,我们使用 EXCEPT 操作符。在其他数据库(例如 MySQL 和 Oracle)中,这个操作符被称为 MINUSMINUSEXCEPT 的工作方式完全相同。

TL;DR: *EXCEPT == MINUS*

在本文的剩余部分,我们将使用 SQL Server 的 EXCEPT 示例;如果你使用其他数据库,只需在需要时将其替换为 MINUS

## SQL — 在一个语句中插入、删除和更新:使用 MERGE 同步你的表格

towardsdatascience.com

1. 理解 EXCEPT、INTERSECT 和 UNION

让我们从一个非常简单的例子开始。我们将首先创建一个包含国家的表格:我们有一个 id、一个名称和一个人口。然后我们将插入 10 个国家:

CREATE TABLE countries (
  id INT,
  name VARCHAR(50),
  population INTEGER,
);

INSERT INTO countries (id, name, population) VALUES
    (1, 'Armenia', 2978763),
    (2, 'Belgium', 11730997),
    (3, 'Canada', 37742154),
    (4, 'Denmark', 5792202),
    (5, 'Egypt', 102334404),
    (6, 'Ghana', 31072940),
    (7, 'Hungary', 9660351),
    (8, 'Iraq', 40222493),
    (9, 'Kiribati', 119449),
    (10, 'Liechtenstein', 38128);

现在我们将创建两个查询:

  • 小国家:选择人口少于 100 万的国家

  • c 国家:选择名称中包含字母 'c' 的国家

-- small countries (pop < 1M)
SELECT name FROM countries WHERE population < 1000000 
-->  Kiribati & Liechtenstein

-- c-countries (name contains a c)
SELECT name FROM countries WHERE NAME LIKE '%c%' 
--> Canada and Liechtenstein

接下来我们将展示如何比较和合并这些查询的结果到一个结果集中。

SQL — 了解索引如何在底层工作以加速查询 [## SQL — Understand how indices work under the hood to speed up your queries.

不再等待缓慢的查询完成

SQL — 理解索引如何在底层工作以加速查询

1.1 除外

现在我们可以使用 EXCEPT 选择所有小型国家EXCEPT 这些名称中包含 ‘c’ 的国家:

SELECT name FROM countries WHERE population < 1000000 
EXCEPT
SELECT name FROM countries WHERE NAME LIKE '%c%' 
--> Kiribati

查询 1 的结果 EXCEPT 查询 2 的结果(图示:作者)

1.2 交集

使用 INTERSECT 找出重叠的部分:小型 c 国家:

SELECT name FROM countries WHERE population < 1000000 
INTERSECT
SELECT name FROM countries WHERE NAME LIKE '%c%'
--> Liechtenstein

我们的两个查询之间的交集(图示:作者)

1.3 UNION(和 UNION ALL)

UNION 操作将两个查询的结果合并到一个结果集中:

SELECT name FROM countries WHERE population < 1000000 
UNION
SELECT name FROM countries WHERE NAME LIKE '%c%'
--> Canada, Kiribati, Liechtenstein

SELECT name FROM countries WHERE population < 1000000 
UNION ALL
SELECT name FROM countries WHERE NAME LIKE '%c%'
--> Kiribati, Liechtenstein, Canada, Liechtenstein

在上面的示例代码中,UNION ALL 产生了另一个列支敦士登!这是因为常规的 UNION 去除重复项;UNION ALL 返回两个查询的所有行。

返回两个结果集的输出(图示:作者)

Python 到 SQL — UPSERT 安全、简便且快速 [## Python to SQL — UPSERT Safely, Easily and Fast

使用 Python 实现 lightning-fast 插入和/或更新

Python 到 SQL — UPSERT 安全、简便且快速

2. 什么决定了重叠?规则

SQL 分析查询的结果,并基于返回的列来确定是否有交集。一般来说,有两个规则涉及到我们比较的查询:

  1. 列必须是可比较的(相同数据类型)

  2. 列的数量必须相等

规则 1:可比较的列

以下代码将失败,因为我们不能比较 id(整数)和 name(字符串类型)。

-- FAILS: Conversion failed when converting the varchar value 'Canada' to data type int.
SELECT id FROM countries WHERE population < 1000000 
EXCEPT
SELECT name FROM countries WHERE NAME LIKE '%c%'

规则 2:列的数量相等

以下代码将失败,因为我们从查询 1 选择了两列,而从查询 2 选择了一列:

-- All queries combined using a UNION, INTERSECT or EXCEPT operator must have an equal number of expressions in their target lists.
SELECT id, name FROM countries WHERE population < 1000000 
EXCEPT
SELECT name FROM countries WHERE NAME LIKE '%c%'

SQL — 删除到另一个表 [## SQL — DELETE INTO another table

SQL — 删除到另一个表

遵循规则

当我们遵循这些规则时,我们也可以执行如下查询:匹配所有小型国家的 id 和‘c’国家的 population。虽然这是完全有效的语法,但它将不会返回任何记录。

SELECT id FROM countries WHERE population < 1000000 
INTERSECT
SELECT population FROM countries WHERE NAME LIKE '%c%'
--> returns no rows (id and population match nowhere)

同样,我们可以UNION这些结果。

SELECT id FROM countries WHERE population < 1000000
UNION
SELECT population FROM countries WHERE NAME LIKE '%c%'

将得到:

同时注意,列名不必匹配。如果名称冲突,将使用第一个查询的列名。

## 通过简单升级显著提升数据库插入速度

在 Python 中创建极速数据库连接的 4 个级别

towardsdatascience.com

3. 不同表的EXCEPTINTERSECTUNION

当然,我们不必仅仅比较来自同一个表的数据,我们也可以使用不同的表,只要由SELECT语句产生的数据结构匹配即可。我已经准备了以下示例,参考了这个语句

1. EXCEPT 示例:

在这个示例中,我们比较products表中的记录和sales表中的记录:我们想知道是否有价格低于 100 美分的产品在荷兰以外的地方被销售过:

SELECT id as product_id FROM products WHERE price < 100
EXCEPT
SELECT product_id FROM sales WHERE country = 'Netherlands'
--> Results in product_id 3

2. INTERSECT 示例

接下来,我们将选择在美国有SALES且有退货的任何产品:

SELECT product_id FROM sales WHERE country = 'USA'
INTERSECT
SELECT product_id from returns
--> Results in product_id 2

3. UNION 示例

最后,我们将UNION三个查询的结果:便宜的产品,在荷兰有任何销售的产品,或任何被退货的产品:

SELECT id as product_id FROM products WHERE price < 100
UNION
SELECT product_id FROM sales WHERE country = 'Netherlands'
UNION
SELECT product_id from returns
--> Returns product_id 1, 2, and 3

## 使用 SQLAlchemy 进行 UPSERT 的最简单方法

一个命令既可以INSERT新数据,又可以UPDATE数据库中现有记录

towardsdatascience.com

4. 与连接的区别是什么?

我把JOIN看作是将来自两个或更多表的数据集的结合在一起,使用它们之间的相关列。另一方面,UNIONINTERSECTEXCEPT操作符则将来自两个或更多表的数据结合或比较,然后附加这些数据。

我喜欢把JOIN看作是“水平”操作,“拉链式”地将查询结果结合在一起。UNIONINTERSECTEXCEPT操作符则是“垂直”地,“堆叠”结果集。让我们通过一些图像来演示:

可视化连接

下面是连接两个表的可视化表示:我们从 table1 中取出两列,并用 table2 中的一列通过相关列中的值进行组合(table1.Id <-> table2.SomeFk):

五彩斑斓的连接(作者提供的图像)

从这个角度来看:使用JOIN我们“拉链式”地连接两个表。我们让表比之前更宽:我们水平地添加到表中。

可视化UNION

现在我们来看看一个UNION语句。注意结果彼此之间相当独立。它们没有相关列;我们只是“将结果集堆叠在一起”,垂直扩展表格。我们之所以能这样做,是因为两个查询输出的列数相同,并且所有列的数据类型匹配。

将结果集合并为单个数据堆栈(作者提供的图片)

在这种情况下,我们使用 UNION 操作符将记录堆叠在一起,但INTERSECT也以相同方式工作,只保留重叠部分。同样,EXCEPT则是从“堆栈”中“减去”一些记录。

## 再也不用写 SQL:SQLAlchemy 的 ORM 绝对初学者指南

使用这个 ORM,你可以创建表格、插入、读取、删除和更新数据,而无需编写一行 SQL 代码

towardsdatascience.com

结论

我希望已经澄清了这三种奇妙操作符的工作原理,也希望你在阅读这篇文章时感到愉快。

我希望这篇文章能如我所期望的那样清晰,如果不是,请告诉我我可以做些什么进一步澄清。同时,查看我关于各种编程相关主题的其他文章

编程愉快!

— Mike

P.S: 喜欢我做的事吗? 关注我!

[## 通过我的推荐链接加入 Medium - Mike Huls

阅读 Mike Huls(以及 Medium 上的其他成千上万名作家的每一个故事)。你的会员费用直接支持 Mike…

mikehuls.medium.com

AI 的环境影响是什么?

原文:towardsdatascience.com/what-is-the-environmental-impact-of-ai-b8af55ec169e

新的 AI Index 报告指出了像 ChatGPT 这样的 AI 所需的巨大能量 — 尽管也有积极的一面。

Alan JonesTowards Data Science Alan Jones

·发表于 Towards Data Science ·阅读时长 6 分钟·2023 年 4 月 7 日

--

图片由 Jason Blackeye 提供,来源于 Unsplash

2023¹ 年的AI Index Report中的一个小但重要的部分指出了对 AI 训练所需能耗的日益关注。

剧透警告:这确实是非常多。

目前没有用于追踪 AI 系统碳强度的标准基准,因此报告侧重于 Luccioni 等人,2022² 的一篇近期论文中的研究,该论文记录了包括 ChatGPT 在内的大型语言模型(LLMs)的能源需求。

下表显示了训练四种不同 AI 模型的能源需求以及相关的 CO2 排放。

图片来源:作者,数据来源:Luccioni 等人,2022²

数据包含了若干测量值,但关键点在于我在下方的图表中总结的电力消耗和 CO2 排放。

四种 AI 模型的电力消耗 — 图片来源:作者,数据来源:Luccioni 等人,2022²

各种模型之间存在相当大的差异,正如你所见,OpenAI 的 GPT-3 排名第一,消耗超过 1200 兆瓦时。根据美国能源信息署的数据,这大约是 120 个美国家庭一年所消耗的电量³。这确实看起来是非常大量的能源。

下图展示了 CO2 排放情况,其模式相似。

四种 AI 模型的 CO2 排放 — 图片来源:作者,数据来源:Luccioni 等人,2022²

论文的主要作者 Luccioni 是 Hugging Face Inc.的研究员,该工作的主要关注点是她公司开发的替代 ChatGPT 的模型 BLOOM。其他模型的数据是近似的,基于公开信息(Bloomberg报道 Lucciana 说没有关于 ChatGPT 的确切数据,可能只是“…三只穿着大衣的浣熊。”——这是否意味着 GPT-4 将会是四只浣熊?)。

训练 ChatGPT 的 CO2 排放量相当于约 500 次从纽约到旧金山的航班

人工智能指数报告对其他能源密集型活动及其 CO2 排放进行了比较(见下图)。例如,它发现训练 ChatGPT 产生的 CO2 排放量相当于一名乘客从纽约飞往旧金山约 500 次!或者相当于一个美国人 28 年的总能源消耗!

能源消耗比较:人工智能模型和现实生活中的例子。作者提供的图片,数据来源于人工智能指数报告¹

不足为奇的是,单个航空乘客并未如上图所示产生零排放(实际排放量接近 1 吨)。你可以在下表中更清楚地看到实际数字:

能源消耗比较:人工智能模型和现实生活中的例子。作者提供的图片,数据来源于人工智能指数报告¹

但这并不是全然坏消息。

人工智能也可以减少能源消耗

根据Bloomberg的报道,虽然人工智能模型变得越来越大(并且可能更具能源密集性),但创建这些模型的公司正在致力于提高效率。微软、谷歌和亚马逊——这些托管大部分工作的云公司——都在致力于实现碳负或碳中和运营。这当然是非常可取的。

此外,尽管训练人工智能系统是能源密集型的,但最近的研究表明,人工智能系统也可以用于优化能源消耗。2022 年 DeepMind 发布的一篇论文⁴详细介绍了 2021 年的一个实验,该实验训练了一个名为 BCOOLER 的人工智能,以优化 Google 数据中心的冷却。

BCOOLER 的节能。作者提供的图片,数据来源于人工智能指数报告¹

上图显示了 BCOOLER 实验的节能结果。经过三个月,大约节省了 12.7%的能源。

即使实现了碳中和,利用人工智能提高这些中心的效率也会使其运行成本降低。也许我们应该考虑将人工智能应用于其他能源密集型行业。

我怀疑我们目前是否能确切了解最终对环境的影响。像 ChatGPT 这样的 LLM 不会消失,因此训练它们所需的能源肯定会被消耗。另一方面,人们也不会停止从纽约飞往旧金山、给家里供暖或使用汽车。

但我们应该尝试将这些令人震惊的数据放在相对的视角中。虽然一次 ChatGPT 训练会消耗相当于一个美国人 28 年的能源(这听起来很多),但 330 万美国人——即美国人口——产生的 CO2 是单次 ChatGPT 会话的1000 万倍⁵。

从纽约到旧金山的航班每天大约有 20 班,假设每班服务 150 名乘客,这样每年产生超过 100 万吨的 CO2 排放——超过 2000 个 ChatGPT⁵

对于单一实体,像 ChatGPT 这样的系统显然使用了大量能源(因此——至少目前——也产生了大量的 CO2 排放),但与其他人类活动的能源消耗和 CO2 排放相比,它们真的很重要吗(毕竟,人类的数量远远多于 LLM)?

此外,大型云托管公司旨在实现碳中和,这将减少 CO2 排放至零。因此,虽然能源使用可能仍然很高,但目标是使其环境影响达到中性。

此外,AI 可以用于减少数据中心的能源使用。也许类似的技术可以应用于航空公司和其他能源密集型行业。

然而,关键点是我们所有人都在产生比应有更多的 CO2,因此任何额外的能源使用(如果不是来自可再生能源)都是朝着错误的方向发展。

感谢阅读,希望你觉得这有用。如果你想查看我的更多作品,请访问我的网站

你也可以通过订阅我偶尔发布的免费Substack 通讯来获取更新。

如果你不是 Medium 会员,你可以使用我的推荐链接注册,每月仅需$5 即可阅读任何 Medium 内容。

参考文献

  1. AI Index 2023 Annual Report

Nestor Maslej, Loredana Fattorini, Erik Brynjolfsson, John Etchemendy, Katrina Ligett, Terah Lyons, James Manyika, Helen Ngo, Juan Carlos Niebles, Vanessa Parli, Yoav Shoham, Russell Wald, Jack Clark, 和 Raymond Perrault,“AI Index 2023 Annual Report”,AI Index Steering Committee, Institute for Human-Centered AI, Stanford University, Stanford, CA, 2023 年 4 月。

斯坦福大学的AI Index 2023 Annual Report署名-禁止演绎 4.0 国际许可下发布。

你可以在斯坦福大学的AI Index页面找到完整报告。

2. 估算 BLOOM 的碳足迹,一个 176B 参数的语言模型,Luccioni 等人,2022。

3. 美国能源信息管理局 估计 2021 年,美国住宅电力用户的年平均电力消耗为 10,632 千瓦时(kWh)。

4. 使用强化学习控制商业冷却系统,DeepMind,2022

5. 来自其他来源的 CO2 排放(这些是粗略计算):

3.3 亿美国人每年排放 18 吨 CO2,即 3.3 亿 x 18,5900 万吨 CO2——1000 万个 ChatGPT。

约 20 个航班(每天),从纽约到旧金山,每个航班大约有 150 名乘客,产生 20 x 150,即 3000 吨的 CO2。这相当于 3000 x 365,大约每年 1 百万吨的 CO2——2000 个 ChatGPT。

两个人拥有相同首字母的概率是多少?

原文:towardsdatascience.com/what-is-the-probability-that-two-persons-have-the-same-initials-0ea3bcb9bcf2

学习如何使用模拟、复制和 R 中的for循环来回答许多概率问题

Antoine SoeteweyTowards Data Science Antoine Soetewey

·发表于 Towards Data Science ·14 min 阅读·2023 年 12 月 6 日

--

图片由 Mario Gogh 提供

介绍

上周,我加入了一个团队,参与一个合作项目。这个团队已经建立了几个月,由几位科学家一起工作。为了简便起见,他们习惯用首字母(名字的第一个字母加上姓氏的第一个字母)签署文件、在邮件中提到同事等。

加入项目几天后,当我需要用我的首字母签署第一份文件时,我们意识到团队中另一人和我有完全相同的首字母。

这并不是真的问题,因为我们决定我将倒写我的名字首字母,也就是“SA”而不是“AS”,而另一个人会像往常一样继续签署“AS”。

本来可以到此为止。然而,当团队负责人在一次会议中声称:“你们两个有相同的首字母真是不幸!这种情况发生的几率有多大?!”时,我产生了写一篇关于这个相当平凡的趣事的想法。

我们花了几分钟尝试估计这个概率,最终这些估计大多基于我们的直觉,而不是正式的计算。这引起了我的好奇心。

鉴于我们正在进行的项目需要使用模拟,我决定通过 R 语言中的模拟来回答这个问题。也就是说,像大多数模拟一样,验证这些结果是一个良好的实践。这可以通过概率论来完成。这种比较将有助于评估通过模拟获得结果的真实性。

此外,我认为这将是一个很好的方式来说明在我的帖子中不常出现的方法:for 循环、重复和在 R 中编写函数。

这种情况的可能性有多大?

在回答团队负责人提出的问题之前,有三点需要注意:

  1. 尽管团队负责人对正好有两个人拥有相同首字母的概率很感兴趣,但我们实际上更关心的是至少有两个人拥有相同首字母的概率(因为如果团队中有超过两个人拥有相同首字母,问题也会出现)。

  2. 团队由 8 人组成。

  3. 我们将首字母限制为两个字母(第一个字母是名字的第一个字母,第二个字母是姓氏的第一个字母)。这意味着中间名没有被考虑在内,并且对于复合名只考虑第一个字母。

在这篇文章中,我们将展示如何计算这个概率:

  • 在我们的背景下,即对于一个 8 人团队,以及

  • 为了完整起见,考虑所有从 2 人到 100 人不等的团队。

如引言中所述,我们将首先通过模拟来计算这些概率,然后通过概率论来计算。

对于我们的团队

我们首先创建一个大小为 8 的向量,对应于一个由 8 个人组成的团队的首字母,这些人是从 26 个拉丁字母中随机抽样的:

# number of persons
n_persons <- 8
# create vector of initials
initials <- replicate(
  n = n_persons, # number of replications
  paste0(sample(LETTERS, size = 1), sample(LETTERS, size = 1)) # sample letters
)# display initials
initials
## [1] "UJ" "MN" "XD" "CY" "BB" "ZB" "CU" "HQ"
# are there duplicates?
any(duplicated(initials))
## [1] FALSE

正如我们所看到的,这支模拟的 8 人团队中每个人的首字母都不同,但这并不总是这样。

为了通过模拟估计至少有两个人拥有相同首字母的可能性,我们需要将这个 8 个采样首字母的向量重复大量次(比如 1000 次重复):

# number of replications
reps <- 1000
# create and save replications
dat <- replicate(
  n = reps, # number of replications
  replicate(n_persons, paste0(sample(LETTERS, size = 1), sample(LETTERS, size = 1)))
)# dimensions
dim(dat)
## [1]    8 1000
# display first 4 simulated teams
dat[, 1:4]
##      [,1] [,2] [,3] [,4]
## [1,] "VA" "BU" "LU" "PT"
## [2,] "JG" "SM" "HM" "OL"
## [3,] "BY" "NA" "VJ" "OT"
## [4,] "RT" "CM" "WT" "YT"
## [5,] "PS" "CT" "NB" "QJ"
## [6,] "MG" "KR" "SV" "US"
## [7,] "PL" "SN" "PN" "XW"
## [8,] "NJ" "BR" "DD" "ZC"

结果是一个 8 行 1000 列的矩阵,其中:

  • 每一行对应于一个人的采样首字母,以及

  • 每一列对应于一个模拟的 8 人团队。

为了更好地阅读,我们重新命名:

  • 行名为M1M8,对应于第 1 到第 8 个人,以及

  • 列名为T1T1000,对应于第 1 到第 1000 支团队。

# rename rows
rownames(dat) <- paste0("M", 1:n_persons)
# rename columns
colnames(dat) <- paste0("T", 1:reps)# display first 4 simulated teams
dat[, 1:4]
##    T1   T2   T3   T4  
## M1 "VA" "BU" "LU" "PT"
## M2 "JG" "SM" "HM" "OL"
## M3 "BY" "NA" "VJ" "OT"
## M4 "RT" "CM" "WT" "YT"
## M5 "PS" "CT" "NB" "QJ"
## M6 "MG" "KR" "SV" "US"
## M7 "PL" "SN" "PN" "XW"
## M8 "NJ" "BR" "DD" "ZC"

我们现在需要计算,在模拟的 1000 支团队中,有多少支团队至少有两个人拥有相同的首字母:

# transform to data frame
dat <- as.data.frame(dat)
# save which teams have duplicates
duplicates <- rep(NA, reps) # create empty vector
for (i in 1:reps) { # for loop over i from 1 to 1,000
  duplicates[i] <- any(duplicated(dat[, i])) # save results TRUE/FALSE in duplicates vector
}# count how many teams have duplicates
sum(duplicates)
## [1] 41

在这里,对于数据框dat的每一列(从第一列到第 1000 列),我们检查是否存在重复。这是通过 for 循环在所有列上重复进行的。对于每一列,如果存在重复,结果是TRUE,否则是FALSE。每次迭代的结果保存在duplicates向量中。由于在 R 中TRUE = 1FALSE = 0,我们可以通过求和duplicates向量中的TRUE的数量来计算有多少列(即团队)存在重复。

从上面的输出可以看出,在 1000 个模拟的团队中,有 41 个团队存在重复,即 41 个团队中至少有两个人的首字母相同。

因此,根据模拟结果,我们可以预期在 8 人团队中至少有两个人的首字母相同的概率接近 4.1%。

这是一个很好的起点。不过,请注意,我写了接近 4.1%,因为这个概率在通过模拟计算时会有所变化。

例如,如果我们重复完全相同的过程第二次:

# create and save replications
dat <- replicate(
  n = reps, # number of replications
  replicate(n_persons, paste0(sample(LETTERS, size = 1), sample(LETTERS, size = 1)))
)
# transform to data frame
dat <- as.data.frame(dat)# save which teams have duplicates
duplicates <- rep(NA, reps) # create empty vector
for (i in 1:reps) { # for loop over i from 1 to 1,000
  duplicates[i] <- any(duplicated(dat[, i])) # save results in the duplicates vector (as TRUE/FALSE)
}# count how many teams have duplicates
sum(duplicates)
## [1] 44

我们现在得到一个 4.4%的概率。这不是错误,而是由于在取样首字母时的随机性造成的。

幸运的是,我们可以通过重复计算使这个概率的计算更加稳健。直观地说,其工作原理如下。我们重复相同的计算多次,给出一个可能的概率范围。这使我们能够评估结果的不确定性,并了解由于取不同随机样本的首字母,概率可能会有所变化。

因此,目标是多次计算我们的概率(比如 100 次),并查看其分布。

要多次重复相同的计算,最好编写一个函数,以避免一遍又一遍地复制粘贴相同的代码。因此,我们首先编写一个函数(称为initials),该函数计算一个 n 人团队中至少有两个人的首字母相同的概率:

initials <- function(n_persons, reps = 1000) {
  # simulate data
  dat <- as.data.frame(replicate(
    reps,
    replicate(n_persons, paste0(sample(LETTERS, size = 1), sample(LETTERS, size = 1)))
  ))
 # save which teams have duplicates
  duplicates <- rep(NA, reps)
  for (i in 1:reps) {
    duplicates[i] <- any(duplicated(dat[, i]))
  } # proportion of teams with duplicates
  return(mean(duplicates))
}

R 中的一个函数需要包括:

  • () 内的参数,以及

  • {} 内的计算。

然后,我们可以使用我们的函数计算一个 8 人团队中至少有两个人的首字母相同的概率。我们将其与replicate()函数结合使用,以计算这个概率 100 次。

# compute and save probabilities
probs <- replicate(100, initials(n_persons = 8))
# display probabilities
probs
##   [1] 0.032 0.037 0.040 0.043 0.033 0.042 0.039 0.047 0.045 0.038 0.052 0.042
##  [13] 0.042 0.040 0.023 0.044 0.041 0.039 0.036 0.048 0.041 0.037 0.027 0.030
##  [25] 0.052 0.038 0.043 0.035 0.038 0.045 0.047 0.044 0.030 0.036 0.036 0.048
##  [37] 0.038 0.045 0.044 0.034 0.031 0.043 0.045 0.034 0.049 0.047 0.051 0.036
##  [49] 0.051 0.040 0.043 0.044 0.038 0.049 0.043 0.050 0.035 0.043 0.048 0.038
##  [61] 0.041 0.044 0.039 0.045 0.033 0.057 0.036 0.043 0.041 0.041 0.041 0.041
##  [73] 0.038 0.044 0.031 0.034 0.049 0.041 0.040 0.034 0.032 0.036 0.049 0.047
##  [85] 0.048 0.038 0.038 0.037 0.036 0.037 0.043 0.040 0.026 0.049 0.046 0.044
##  [97] 0.048 0.038 0.026 0.029

最后,我们通过直方图和箱线图(使用{ggplot2}包)可视化这 100 个概率的分布:

# visualize distribution of the computed probabilities
# build and save plots
library(ggplot2)
p1 <- ggplot(mapping = aes(x = probs)) +
  geom_histogram(color = "black", fill = "steelblue", bins = 8) +
  labs(
    x = "Probabilities",
    y = "Frequencies"
  ) +
  scale_x_continuous(labels = scales::percent) # format x-axis in %p2 <- ggplot(mapping = aes(x = probs)) +
  geom_boxplot(color = "black", fill = "steelblue") +
  labs(x = "Probabilities") +
  theme(
    axis.text.y = element_blank(),
    axis.ticks.y = element_blank()
  ) +
  scale_x_continuous(labels = scales::percent) # format x-axis in %# combine plots
library(patchwork)p1 + p2

作者绘图

这两幅图表明,在 8 人团队中,至少有两个人的首字母相同的概率最有可能在 3.5%和 4.5%之间。

作为记录,在这一切思考的源头会议中,我们大多数人认为这种情况的可能性要小得多。事实上,我相信我们曾经想计算的是某个加入团队的人首字母为“AS”的概率。这确实要小得多,因为概率只有 1/26 × 1/26 ≃ 0.15%。

然而,这并没有考虑到以下事实:

  • 新来的员工可以与任何其他人有相同的首字母,并且

  • 这不仅仅是新来的员工可能与其他人有相同的首字母(团队中已有的 2 个人也可能有相同的首字母)。

如果你对这一发现感到困惑,我建议你阅读一下生日悖论。生日悖论表明,在一个相对较小的群体中,两个人共享相同生日的概率会出奇地高。实际上,在一个只有 23 人的小组中,至少有两个人共享相同生日的概率超过 50%,这说明了我们对这种巧合的可能性的直观认知的反常。这个现象是由于群体中可能的生日对的数量众多,类似于团队中首字母对的数量。

针对不同规模的团队

我们现在有兴趣计算这个概率,不仅仅针对 8 人的团队,还针对不同规模的团队。我们可以借助之前定义的函数来实现。

为了说明,让我们计算至少有两个人拥有相同首字母的概率,针对从 2 人到 100 人的团队:

# set lower and upper bounds of number of persons
min_persons <- 2
max_persons <- 100
# create empty vector of probabilities
probs <- rep(NA, length(min_persons:max_persons))# compute and save probabilities for teams of size 2 to 100
for (i in min_persons:max_persons) {
  probs[i] <- initials(n_persons = i)
}# display probabilities
probs
##   [1]    NA 0.001 0.005 0.013 0.012 0.019 0.036 0.040 0.047 0.057 0.074 0.083
##  [13] 0.103 0.128 0.158 0.166 0.178 0.215 0.232 0.260 0.275 0.296 0.300 0.329
##  [25] 0.357 0.392 0.405 0.405 0.439 0.478 0.495 0.536 0.535 0.563 0.578 0.599
##  [37] 0.653 0.656 0.686 0.693 0.715 0.711 0.767 0.760 0.786 0.784 0.814 0.817
##  [49] 0.825 0.826 0.842 0.845 0.867 0.893 0.901 0.920 0.919 0.911 0.917 0.942
##  [61] 0.950 0.951 0.946 0.947 0.969 0.959 0.965 0.964 0.977 0.984 0.977 0.977
##  [73] 0.985 0.978 0.986 0.981 0.989 0.991 0.989 0.988 0.992 0.993 0.994 0.996
##  [85] 0.997 0.995 0.994 0.999 0.999 0.999 1.000 0.999 0.997 1.000 0.999 0.999
##  [97] 0.999 1.000 1.000 0.999

我们将这些概率与团队人数一起存储在数据框中:

# create data frame with saved probabilities and number of persons
dat_plot_sim <- data.frame(
  n_persons = (min_persons - 1):max_persons,
  prob = probs
)
# display first 6 rows
head(dat_plot_sim)
##   n_persons  prob
## 1         1    NA
## 2         2 0.001
## 3         3 0.005
## 4         4 0.013
## 5         5 0.012
## 6         6 0.019

当然,在一个 1 人的团队中(如果我们可以称之为团队的话),两个拥有相同首字母的人是不可能的。

一个不可能发生的事件,其概率等于 0。因此,我们在数据框的第一行中填入这个概率:

# set proba = 1 when n_person = 1
dat_plot_sim[1, 2] <- 0
# display first 6 rows
head(dat_plot_sim)
##   n_persons  prob
## 1         1 0.000
## 2         2 0.001
## 3         3 0.005
## 4         4 0.013
## 5         5 0.012
## 6         6 0.019

最后,我们将这些概率根据团队人数进行可视化:

# visualize probabilities
ggplot(dat_plot_sim) +
  aes(x = n_persons, y = probs) +
  geom_line(linewidth = 1) +
  labs(
    x = "# of persons in the team",
    y = "Probability",
    title = "What is the probability that at least 2 persons have the same initials?"
  ) +
  scale_y_continuous(labels = scales::percent) # format y-axis in %

作者绘制的图

从上面的图表中,我们看到,当团队人数超过 30 人时,至少有两个人拥有相同首字母的概率达到了 50%。

此外,请注意,当团队人数达到约 75 人时,这个概率接近 100%。

验证

为了完整性,我们现在将通过模拟得到的结果与通过概率理论得到的结果进行比较。

我们首先定义一个函数,用于比较上述找到的结果:

# define function
have_same <- function(s, n) {
  sample_space <- s
  probability <- 1
  for (i in 0:(n - 1)) {
    probability <- probability * (sample_space - i) / sample_space
  }
  1 - probability
}

对于我们的团队

# number of possible two-letter initials
n_initials <- 26²
# apply function
have_same(n_initials, n_persons)
## [1] 0.0407218

在 8 人的团队中,至少有两个人拥有相同首字母的概率为 4.07%。这接近于通过模拟得到的概率,并在 3.5% — 4.5%的范围内。

针对不同规模的团队

我们现在计算 1 到 100 人的团队之间的概率:

# compute and save probabilities for teams between 1 and 100 persons
probs <- vector(length = max_persons)
for (i in 1:max_persons) {
  probs[i] <- have_same(n_initials, i)
}
# create data frame with saved probabilities and number of persons
dat_plot_theory <- data.frame(
  n_persons = (min_persons - 1):max_persons,
  prob = probs
)# display first 6 rows
head(dat_plot_theory)
##   n_persons        prob
## 1         1 0.000000000
## 2         2 0.001479290
## 3         3 0.004433493
## 4         4 0.008851688
## 5         5 0.014716471
## 6         6 0.022004071

最后,我们将这些概率根据团队人数进行可视化:

# visualize probabilities
ggplot(dat_plot_theory) +
  aes(x = n_persons, y = probs) +
  geom_line(linewidth = 1) +
  labs(
    x = "# of persons in the team",
    y = "Probability",
    title = "What is the probability that at least 2 persons have the same initials?"
  ) +
  scale_y_continuous(labels = scales::percent) # format y-axis in %

作者绘制的图

为了便于比较,我们在同一图表上绘制了通过模拟和概率理论得到的概率:

# combine the two data frames into one and add the method as variable
dat_plot_sim$Method <- "Simulations"
dat_plot_theory$Method <- "Theory"
dat_plot_all <- rbind(dat_plot_sim, dat_plot_theory)
# visualize probabilities on same plot
ggplot(dat_plot_all) +
  aes(x = n_persons, y = prob, color = Method) +
  geom_line(linewidth = 1) +
  labs(
    x = "# of persons in the team",
    y = "Probability",
    title = "What is the probability that at least 2 persons have the same initials?"
  ) +
  scale_y_continuous(labels = scales::percent) # format y-axis in %

作者绘制的图

上图显示了使用概率理论得到的结果与通过模拟获得的结果相对类似,这表明模拟结果是可靠的。

结论

初始问题是在一次会议上提出的:“在我们由 8 个人组成的团队中,两个人有相同首字母的概率是多少?”

在这篇文章中,我们首先展示了如何通过 R 中的模拟来计算这个概率。其次,我们通过概率理论验证了模拟的真实性。此外,我们还说明了如何使用 for 循环、重复操作和编写函数来在 R 中解决概率问题。

顺便提一下,重要的是要记住在这篇文章中我们假设了以下内容:

  • 所有字母出现的概率相同,这意味着所有的首字母组合的概率是相等的。这在现实中可能并非如此,因为两个名字都以 X 开头的概率不如一个名字以 M 开头另一个名字以 K 开头的概率大。可以通过指定不同的权重来限制这种偏差。

  • 我们将自己限制在了两字母首字母。因此,对于复合的名字或姓氏,只考虑第一个字母。中间名也未被考虑。

最后但同样重要的是,即使你使用完全相同的代码,你可能会得到略微不同的结果。这是由于随机性造成的。要复制本文中所示的结果,请使用 set.seed(6)

感谢阅读。

一如既往,如果你对本文讨论的主题有任何问题或建议,请添加评论,以便其他读者也能从讨论中受益。

  1. 你总是可以使用更多的重复次数,但在我们的案例中,最终结果与更多的重复次数相似,文章的目的是展示开发过程而非最终答案。↩︎

相关文章

最初发布于 https://statsandr.com 于 2023 年 12 月 6 日。

AI 对裁员的真实影响是什么?深入分析

原文:towardsdatascience.com/what-is-the-real-impact-of-ai-on-job-cuts-7197ad1377f9

Ahmed FessiTowards Data Science Ahmed Fessi

·发表于Towards Data Science ·8 分钟阅读·2023 年 11 月 6 日

--

AI 替代人类,未来感,油画风格 — 作者使用 Dall-E 3 生成

自 ChatGPT 发布以来,考虑到生成 AI 的日益普及,许多问题出现了,涉及到 AI 对就业市场的影响。

多家公司宣布裁员,因为他们的团队采用了 AI,从而“需要更少的劳动力”。似乎没有任何行业或职能免受影响。

这些公告涵盖了像英国电信这样的大公司,也有像这家法国公关公司用 AI 替换一半员工这样的小公司。

这显然引发了对工作安全的担忧,因为不同规模、不同领域和不同职能的公司似乎都在大规模地用 AI 替代人类。

这些担忧甚至引起了拜登政府的关注,在拜登总统签署的关于安全、可靠和可信人工智能的行政命令中,声明中提到,“产生一份关于 AI 的 潜在劳动市场影响的报告,并研究和识别加强对 面临劳动冲击的工人,包括 AI 造成的联邦支持的选项”。

因此,作为数据分析师,我希望通过数据和数字评估 AI 对裁员和失业的真实影响。

方法论

数据来源

作为数据来源,我使用了layoffs.fyi,它跟踪初创公司和科技公司的裁员情况。Layoffs.fyi 自 Covid 时期以来一直在跟踪裁员情况。然后,对于每次裁员,我使用了 Layoffs.fyi 中的参考链接以及互联网上的其他来源(新闻稿、Tech Crunch、Bloomberg 等文章)。

layoffs.fyi,筛选视图——关注 2023 年 10 月的裁员——作者的打印屏幕

选择标准

我分析了 2023 年10 月的所有裁员。

参考了 76 次裁员的数据。

通过重复分析发现,有一行是重复的(涉及 Convoy,Logistics)。因此,我们剩下 75 次裁员。

从这些裁员中,我删除了所有与“完全停业”相关的记录,共计 10 条。这可以讨论,但所有这 10 次停业与 AI 无关,而是由于各种原因(市场调整、不可行的商业模式等)导致公司破产。

我们需要分析 65 次裁员。这将是我们考虑的数据集。

分析

(关于限制, 请参见限制部分)

对于 2023 年 10 月:

  • 裁员总数:列出的公司中共有 6,841 名员工被裁员(未考虑缺失的数据点——参见限制)。

  • 平均每家公司裁员数:平均而言,每家公司约有 163 名员工被裁员。

  • 按国家裁员情况:美国的裁员数量最高,总共有 5,395 名员工被裁员,其次是印度的 510 名裁员,加拿大有 271 名裁员,法国报告了 230 名裁员,德国有 215 名裁员。其他国家的裁员较少。

看一下各行业的裁员情况:

2023 年 10 月裁员——按行业分类

金融、零售、消费、医疗保健和加密货币领域面临着最高数量的裁员(不是按员工数量,而是按裁员次数计算)。

AI 的影响

下一步是检查有多少次裁员是与 AI 相关的。在分析了这 65 次裁员的总数据集后,仅有 2 次裁员被报告为由于 AI 采用所导致。

第一个案例:LinkedIn

LinkedIn 决定裁员668 个职位。此次裁员是在今年早些时候宣布的另一轮裁员之后,前者裁员716 个职位。LinkedIn 正在寻求通过 AI 来自动化日常任务、集成新的 AI 驱动工具,同时利用生成 AI 提供新功能,例如LinkedIn 协作文章,这些是 AI 生成的文章,据 LinkedIn 称,这些文章似乎带来了大量流量。此次裁员特别影响了研发部门。

第二个案例:Stack Overflow

Stack Overflow 决定用生成式 AI 替代其大量员工(28%),这表明其战略转向利用人工智能提高效率,寻求盈利,并可能改善其平台上提供的服务质量。值得一提的是,Stack Overflow 起初禁止使用 AI 技术,但后来转向更平衡的立场,理解 AI 产生的真实影响。更简单地说,Stack Overflow 作为知识管理工具的业务受到(如果不是被打乱的话)AI 采用所带来的竞争的直接影响。

分析要点

在 LinkedIn 和 Stack Overflow 的案例中,AI 和自动化显著影响了劳动力结构。LinkedIn 和 Stack Overflow 的这些举措似乎与科技行业的更广泛趋势一致,即 AI 和自动化正在取代传统工作,尤其是在 AI 技术蓬勃发展的背景下。然而,这一趋势并不那么庞大。在这项研究中,它仅影响了 65 次裁员中的 2 次(裁员数量的 3%;受影响员工数量的 ~7%)。

其余裁员的主要原因(65 次中的 63 次)包括实现盈利的努力、重组、财务困难和收购的影响。经济衰退、商业策略的转变和市场动态的变化也促成了这些裁员。此外,一些裁员与特定行业情况有关,例如加密市场在过度炒作后自我修正和“回归现实”的过程。

局限性

  • 缺失的数据点:23 家公司未报告裁员人数。29 家公司未报告裁员占其员工总数的百分比。

  • 数据来源:Layoffs.fyi 无疑是一个优秀的裁员来源和跟踪器,但它可能未列出市场上的所有裁员情况。

  • 新闻稿和文章的透明度:一些裁员可能与 AI 相关,或部分与 AI 相关,但公司可能选择不透明地沟通这一点。

  • 研究时间范围:仅覆盖 1 个月(2023 年 10 月),这可能在采样有效性方面不是一个具有代表性的月份(如果你认为研究应该覆盖更长的时间段,请随时评论)。

考虑到所有这些局限性,我仍然相信它们不会对结果和分析的主要要点产生重大影响。

结语

根据这项分析,AI 对裁员的影响(至少目前)仍然非常有限。它影响了 LinkedIn 和 Stack Overflow 的 2 次裁员中的 65 次。这并未显示市场上出现大规模的运动。

然而,AI 已经存在,并且 AI 将继续存在,准备迎接即将到来的变化是关键。

关于人工智能的一个关键问题是确保每个人,无论其背景或资源如何,都能平等地接触到持续的技术进步并从中受益。这对于确保每个人能够“顺利过渡”并适应这些变化至关重要。

展望未来,人工智能驱动的自动化趋势可能会加剧,从而可能导致更多的裁员。然而,这也为技能提升和以人工智能与数据科学为中心的新角色打开了大门。与人工智能技能相关的职位需求在过去四年中增长了 75%。此外,公司可能需要在利用人工智能提高效率和通过重新培训员工以适应不断变化的角色之间取得平衡。

附录 — 数据集

这是用于本次分析的数据集。

#  |Company            |Laid Off |Date       |%    |AI Impact?|Industry   |Country       
---|-------------------|---------|-----------|-----|----------|-----------|--------------
1  |StepStone          |215      |30/10/2023 |5%   |No        |Recruiting |Germany       
2  |Hubilo             |50       |30/10/2023 |5%   |No        |Other      |United States 
3  |Karat Financial    |         |27/10/2023 |     |No        |Finance    |United States 
4  |Hippo Insurance    |120      |26/10/2023 |20%  |No        |Finance    |United States 
5  |Graphy             |50       |26/10/2023 |20%  |No        |Education  |India         
6  |Salsify            |110      |25/10/2023 |     |No        |Retail     |United States 
7  |F-Secure           |70       |25/10/2023 |     |No        |Security   |Finland       
8  |Virgio             |20       |25/10/2023 |33%  |No        |Retail     |India         
9  |Exabeam            |         |25/10/2023 |20%  |No        |Security   |United States 
10 |SiFive             |130      |24/10/2023 |20%  |No        |Hardware   |United States 
11 |Shipt              |         |24/10/2023 |3%   |No        |Retail     |United States 
12 |Parity Tech        |100      |23/10/2023 |30%  |No        |Crypto     |United Kingdom
13 |Roblox China       |15       |23/10/2023 |     |No        |Consumer   |China         
14 |Nomad Health       |119      |20/10/2023 |17%  |No        |Healthcare |United States 
15 |Tropic             |26       |20/10/2023 |     |No        |Finance    |United States 
16 |Nomad Health       |         |20/10/2023 |25%  |No        |Healthcare |United States 
17 |Bullhorn           |140      |19/10/2023 |9%   |No        |Sales      |United States 
18 |LegalZoom          |100      |19/10/2023 |     |No        |Legal      |United States 
19 |StellarAlgo        |21       |19/10/2023 |28%  |No        |Data       |Canada        
20 |ManoMano           |230      |18/10/2023 |25%  |No        |Retail     |France        
21 |Google             |         |18/10/2023 |     |No        |Consumer   |United States 
22 |WeTransfer         |35       |18/10/2023 |10%  |No        |Other      |Netherlands   
23 |Plume              |24       |18/10/2023 |     |No        |Healthcare |United States 
24 |Expedia            |100      |17/10/2023 |     |No        |Travel     |United States 
25 |Waymo              |         |17/10/2023 |     |No        |Transport  |United States 
26 |LinkedIn           |660      |16/10/2023 |3%   |Yes       |Recruiting |United States 
27 |CityMall           |90       |16/10/2023 |     |No        |Retail     |India         
28 |C2FO               |80       |16/10/2023 |3%   |No        |Finance    |United States 
29 |Kayak/OpenTable    |80       |16/10/2023 |     |No        |Travel     |United States 
30 |Bandcamp           |58       |16/10/2023 |50%  |No        |Other      |United States 
31 |Stack Overflow     |         |16/10/2023 |28%  |Yes       |Recruiting |United States 
32 |PokerStars         |         |15/10/2023 |     |No        |Consumer   |United Kingdom
33 |Adda247            |300      |14/10/2023 |     |No        |Education  |India         
34 |Flexport           |         |13/10/2023 |20%  |No        |Logistics  |United States 
35 |Uno Health         |         |13/10/2023 |     |No        |Healthcare |United States 
36 |Qualcomm           |1258     |12/10/2023 |12%  |No        |Hardware   |United States 
37 |Lending Club       |172      |12/10/2023 |14%  |No        |Finance    |United States 
38 |MariaDB            |84       |12/10/2023 |     |No        |Data       |United States 
39 |Deepgram           |20       |11/10/2023 |20%  |No        |AI         |United States 
40 |Acronis            |         |11/10/2023 |     |No        |Security   |Switzerland   
41 |Stitch Fix         |558      |09/10/2023 |     |No        |Retail     |United States 
42 |Carbon Health      |114      |09/10/2023 |5%   |No        |Healthcare |United States 
43 |Blue Origin        |40       |09/10/2023 |     |No        |Aerospace  |United States 
44 |Product Hunt       |         |09/10/2023 |60%  |No        |Consumer   |United States 
45 |InvestCloud        |80       |06/10/2023 |5%   |No        |Finance    |United States 
46 |Brave              |         |06/10/2023 |9%   |No        |Consumer   |United States 
47 |Yuga Labs          |         |06/10/2023 |     |No        |Crypto     |United States 
48 |Enoivix            |185      |05/10/2023 |     |No        |Energy     |United States 
49 |Bizongo            |50       |05/10/2023 |     |No        |Retail     |India         
50 |SchoolMint         |29       |05/10/2023 |14%  |No        |Education  |United States 
51 |SeekOut            |16       |05/10/2023 |7%   |No        |Recruiting |United States 
52 |Arrival            |         |05/10/2023 |25%  |No        |Transport  |United Kingdom
53 |Ledger             |         |05/10/2023 |12%  |No        |Crypto     |France        
54 |Qualtrics          |780      |04/10/2023 |14%  |No        |Other      |United States 
55 |Hopper             |250      |04/10/2023 |30%  |No        |Travel     |Canada        
56 |Bird               |         |04/10/2023 |     |No        |Transport  |United States 
57 |Block              |         |04/10/2023 |     |No        |Finance    |United States 
58 |Meta               |         |04/10/2023 |     |No        |Consumer   |United States 
59 |Dare               |         |03/10/2023 |     |No        |Energy     |United Kingdom
60 |Sendoso            |         |03/10/2023 |     |No        |Marketing  |United States 
61 |Twitch             |         |03/10/2023 |     |No        |Consumer   |United States 
62 |Chainalysis        |150      |02/10/2023 |15%  |No        |Crypto     |United States 
63 |Synapse            |86       |02/10/2023 |40%  |No        |Finance    |United States 
64 |Chia Network       |26       |02/10/2023 |37%  |No        |Crypto     |United States 
65 |Sono Motors        |         |02/10/2023 |     |No        |Transport  |Germany

随时分享你的想法!你的工作是否受到人工智能的影响?

如果你想要 了解人工智能,请加入我的课程

关于气候的言论:Twitter 数据的 Python 聚类

原文:towardsdatascience.com/what-people-write-about-climate-twitter-data-clustering-in-python-2fbbd2b95906

使用 K-Means、TF-IDF、Word2Vec 和 Sentence-BERT 对 Twitter 数据进行聚类

Dmitrii EliuseevTowards Data Science Dmitrii Eliuseev

·发布于 Towards Data Science ·阅读时间 21 分钟·2023 年 5 月 15 日

--

推文集群可视化,作者提供的图片

人们对气候、疫情、战争或其他紧迫问题的看法和言论是什么?从社会学角度看,这些问题非常有趣;了解人们意见的当前趋势对科学家、记者或政治家也很有意义。但我们如何获得答案呢?过去,收集数百万人的回应可能是一个昂贵的过程,但今天我们可以从社交网络帖子中获得这些答案。现在有许多社交平台;我选择 Twitter 进行分析基于几个原因:

  • Twitter 最初设计用于发布简短的帖子,这可能更容易分析。至少我希望在文字长度有限的情况下,人们尝试以更简洁的方式分享他们的想法。

  • Twitter 是一个大型社交网络;它成立已近 20 年。到本文撰写时,活跃用户约为 4.5 亿,因此很容易获取大量数据进行分析。

  • Twitter 有一个官方 API,其许可证允许我们将数据用于研究目的。

整个分析可能相当复杂,为了使过程更清晰,我们先描述一下需要实施的步骤。

方法论

我们的数据处理管道将包括几个步骤。

  • 收集推文并将其保存到 CSV 文件中。

  • 清理数据。

  • 将文本数据转换为数字形式。我将使用 3 种方法(TF-IDF、Word2Vec 和 Sentence-BERT)来获取文本嵌入,我们将看到哪一种更好。

  • 使用 K-Means 算法对数值数据进行聚类,并分析结果。为了数据可视化,我将使用 t-SNE(t-分布随机邻域嵌入)方法,我们还将为最有趣的聚类构建一个词云。

不再赘述,让我们直接开始吧。

1. 加载数据

从 Twitter 收集数据很简单。Twitter 有一个官方 API 和一个开发者门户;一个免费账户限制为一个项目,这对于这项任务已经足够。免费账户允许我们获取最近 7 天的推文。我在一个月内收集了数据,每周运行一次代码没有问题。可以手动完成,也可以使用 Apache Airflow、Cron、GitHub Actions 或其他工具进行自动化。如果历史数据确实需要,Twitter 还提供了一个特别的学术研究访问程序。

门户中免费注册后,我们可以为我们的项目获取 API“key”和“secret”。为了访问数据,我使用了一个“tweepy”Python 库。该代码允许我们获取所有带有“#climate”标签的推文并将其保存到 CSV 文件中:

import tweepy

api_key = "YjKdgxk..."
api_key_secret = "Qa6ZnPs0vdp4X...."

auth = tweepy.OAuth2AppHandler(api_key, api_key_secret)
api = tweepy.API(auth, wait_on_rate_limit=True)

hashtag = "#climate"

def text_filter(s_data: str) -> str:
    """ Remove extra characters from text """
    return s_data.replace("&amp;", "and").replace(";", " ").replace(",", " ") \
                 .replace('"', " ").replace("\n", " ").replace("  ", " ")

def get_hashtags(tweet) -> str:
    """ Parse retweeted data """
    hash_tags = ""
    if 'hashtags' in tweet.entities:
        hash_tags = ','.join(map(lambda x: x["text"], tweet.entities['hashtags']))
    return hash_tags

def get_csv_header() -> str:
    """ CSV header """
    return "id;created_at;user_name;user_location;user_followers_count;user_friends_count;retweets_count;favorites_count;retweet_orig_id;retweet_orig_user;hash_tags;full_text"

def tweet_to_csv(tweet):
    """ Convert a tweet data to the CSV string """
    if not hasattr(tweet, 'retweeted_status'):
        full_text = text_filter(tweet.full_text)
        hasgtags = get_hashtags(tweet)
        retweet_orig_id = ""
        retweet_orig_user = ""
        favs, retweets = tweet.favorite_count, tweet.retweet_count
    else:
        retweet = tweet.retweeted_status
        retweet_orig_id = retweet.id
        retweet_orig_user = retweet.user.screen_name
        full_text = text_filter(retweet.full_text)
        hasgtags = get_hashtags(retweet)
        favs, retweets = retweet.favorite_count, retweet.retweet_count
    s_out = f"{tweet.id};{tweet.created_at};{tweet.user.screen_name};{addr_filter(tweet.user.location)};{tweet.user.followers_count};{tweet.user.friends_count};{retweets};{favs};{retweet_orig_id};{retweet_orig_user};{hasgtags};{full_text}"
    return s_out

pages = tweepy.Cursor(api.search_tweets, q=hashtag, tweet_mode='extended',
                      result_type="recent",
                      count=100,
                      lang="en").pages(limit)

with open("tweets.csv", "a", encoding="utf-8") as f_log:
    f_log.write(get_csv_header() + "\n")
    for ind, page in enumerate(pages):
        for tweet in page:
            # Get data per tweet
            str_line = tweet_to_csv(tweet)
            # Save to CSV
            f_log.write(str_line + "\n")

如我们所见,我们可以获取每条推文的文本正文、标签和用户 ID,但如果推文被转发,我们需要从原始推文中获取数据。其他字段,如点赞数、转发数、地理坐标等,都是可选的,但对未来的分析也可能有趣。一个“wait_on_rate_limit”参数很重要;它允许库在达到 API 调用的免费限制时自动暂停。

运行此代码后,我收到了大约 50,000 条带有“#climate”标签的推文,都是在最近 7 天内发布的。

2. 文本清理和转换

清理数据是自然语言处理中的一个挑战,尤其是在解析社交网络帖子时。有趣的是,没有“唯一正确”的方法。例如,标签可能包含重要信息,但有时用户只是将相同的标签复制粘贴到他们所有的消息中,因此标签与消息正文的相关性可能会有所不同。Unicode 表情符号也可以被清理,但将其转换为文本可能更好,等等。经过一些实验,我开发了一个转换管道,虽然可能不完美,但对这项任务足够有效。

URLs 和提及的用户名

许多用户只是发布带有 URLs 的推文,通常没有任何评论。保持记录 URL 的事实是很好的,因此我将所有 URLs 转换为虚拟的“#url”标签:

import re

output = re.sub(r"https?://\S+", "#url", s_text)  # Replace links with '#url'

Twitter 用户经常在文本中使用“@”标签提及其他人。用户名与文本上下文无关,而且像“@AngryBeaver2021”这样的名字只会增加数据噪声,因此我将它们全部删除:

output = re.sub(r'@\w+', '', output)  # Remove mentioned user names @... 

标签

转换标签更具挑战性。首先,我使用 NLTK TweetTokenizer 将句子转换为标记:

from nltk.tokenize import TweetTokenizer

s = "This system combines #solar with #wind turbines. #ActOnClimate now. #Capitalism #climate #economics"
tokens = TweetTokenizer().tokenize(s)
print(tokens)
# > ['This', 'system', 'combines', '#solar', 'with', '#wind', 'turbines', '.', '#ActOnClimate', 'now', '.', '#capitalism', '#climate', '#economics']

它有效,但还不够。人们常常在句子中间使用标签,例如“important #news about the climate”。在这种情况下,词语“news”很重要,需要保留。同时,用户常常在每条消息的末尾添加一堆标签,在大多数情况下,这些标签只是复制和粘贴的,与文本本身并不直接相关。因此,我决定只在句子的末尾移除标签:

while len(tokens) > 0 and tokens[-1].startswith("#"):
    tokens = tokens[:-1]
# Convert array of tokens back to the phrase
s = ' '.join(tokens)

这更好,但仍然不够好。人们经常在一个标签中组合几个词,例如上一个例子中的“#ActOnClimate”。我们可以将这个标签拆分为三个词:

tag = "#ActOnClimate"
res = re.findall('[A-Z]+[^A-Z]*', tag)
s = ' '.join(res) if len(res) > 0 else tag[1:]
print(s)
# > Act On Climate

作为这一阶段的最终结果,短语“This system combines #solar with #wind turbines. #ActOnClimate now. #Capitalism #climate #economics”将被转换为“This system combines #solar with #wind turbines. Act On Climate now.”。

移除短推文

许多用户经常发布没有任何文本的图片或视频。在这种情况下,消息体几乎是空的。这些帖子在分析中大多无用,因此我只保留长度超过 32 个字符的句子在数据框中。

词形还原

词形还原是将单词转换为其原始规范形式的过程。

import spacy
nlp = spacy.load('en_core_web_sm')

s = "I saw two mice today!"

print(" ".join([token.lemma_ for token in nlp(s)]))
# > I see two mouse today !

对文本进行词形还原可以减少文本中的单词数量,聚类算法可能会更有效。一个 spaCy 词形还原器 正在分析整个句子;例如,“I saw a mouse”和“cut wood with a saw”这两个短语将为“saw”提供不同的结果。因此,词形还原器应该在清理停用词之前调用。

这些步骤足以清理推文。当然,没有什么是完美的,但对我们的任务来说,这看起来已经足够好了。对于希望自行实验的读者,完整的代码如下:

import re
import pandas as pd
from nltk.tokenize import TweetTokenizer

from nltk.corpus import stopwords
stop = set(stopwords.words("english"))

import spacy
nlp = spacy.load('en_core_web_sm')

def remove_stopwords(text) -> str:
    """ Remove stopwords from text """
    filtered_words = [word for word in text.split() if word.lower() not in stop]
    return " ".join(filtered_words)

def expand_hashtag(tag: str):
    """ Convert #HashTag to separated words.
    '#ActOnClimate' => 'Act On Climate'
    '#climate' => 'climate' """
    res = re.findall('[A-Z]+[^A-Z]*', tag)
    return ' '.join(res) if len(res) > 0 else tag[1:]

def expand_hashtags(s: str):
    """ Convert string with hashtags.
    '#ActOnClimate now' => 'Act On Climate now' """
    res = re.findall(r'#\w+', s) 
    s_out = s
    for tag in re.findall(r'#\w+', s):
        s_out = s_out.replace(tag, expand_hashtag(tag))
    return s_out

def remove_last_hashtags(s: str):
    """ Remove all hashtags at the end of the text except #url """
    # "Change in #mind AP #News #Environment" => "Change in #mind AP"
    tokens = TweetTokenizer().tokenize(s)
    # If the URL was added, keep it
    url = "#url" if "#url" in tokens else None
    # Remove hashtags
    while len(tokens) > 0 and tokens[-1].startswith("#"):
        tokens = tokens[:-1]
    # Restore 'url' if it was added
    if url is not None:
        tokens.append(url)
    return ' '.join(tokens) 

def lemmatize(sentence: str) -> str:
    """ Convert all words in sentence to lemmatized form """
    return " ".join([token.lemma_ for token in nlp(sentence)])

def text_clean(s_text: str) -> str:
    """ Text clean """
    try:
        output = re.sub(r"https?://\S+", "#url", s_text)  # Replace hyperlinks with '#url'
        output = re.sub(r'@\w+', '', output)  # Remove mentioned user names @... 
        output = remove_last_hashtags(output)  # Remove hashtags from the end of a string
        output = expand_hashtags(output)  # Expand hashtags to words
        output = re.sub("[^a-zA-Z]+", " ", output) # Filter
        output = re.sub(r"\s+", " ", output)  # Remove multiple spaces
        output = remove_stopwords(output)  # Remove stopwords
        return output.lower().strip()
    except:
        return ""

def text_len(s_text: str) -> int:
    """ Length of the text """
    return len(s_text)

df = pd.read_csv("tweets.csv", sep=';', dtype={'id': object, 'retweet_orig_id': object, 'full_text': str, 'hash_tags': str}, lineterminator='\n')
df['text_clean'] = df['full_text'].map(text_clean)

df['text_len'] = df['text_clean'].map(text_len)
df = df[df['text_len'] > 32]

display(df)

作为额外收获,使用干净的文本,我们可以轻松绘制词云:

from wordcloud import WordCloud
import matplotlib.pyplot as plt  

def draw_cloud(column: pd.Series, stopwords=None):
    all_words = ' '.join([text for text in column]) 

    wordcloud = WordCloud(width=1600, height=1200, random_state=21, max_font_size=110, collocations=False, stopwords=stopwords).generate(all_words) 
    plt.figure(figsize=(16, 12)) 
    plt.imshow(wordcloud, interpolation="bilinear") 
    plt.axis('off')
    plt.show()

draw_cloud(df['text_clean'])

结果如下:

从清理后的文本中生成的词云,图片由作者提供

这还不是实际的分析,但这张图片已经能提供一些关于人们讨论气候的见解。例如,我们可以看到人们经常发布链接(“URL”是云图中最大的词),以及“energy”、“waste”、“fossil”或“crisis”等词也是相关且重要的。

3. 向量化

文本向量化是将文本数据转换为数值表示的过程。大多数算法,包括 K-Means 聚类,都需要向量而不是纯文本。而且转换本身并不简单。挑战不仅仅是以某种方式为所有单词分配一些随机向量;理想情况下,单词到向量的转换应该保持这些单词在原始语言中的关系。

我将测试三种不同的方法,我们可以看到每种方法的优缺点。

TF-IDF

TF-IDF(词频-逆文档频率)是一个相当古老的算法;早在 1970 年代就提出了一个称为 IDF 的术语加权函数。TF-IDF 的结果基于数字统计,其中 TF(词频)是单词在文档中出现的次数(在我们的例子中是推文中),而 IDF(逆文档频率)显示了相同单词在文本语料库(文档全集)中出现的频率。特定单词的得分越高,该词在特定推文中的重要性就越大。

在处理真实数据集之前,让我们考虑一个简单的例子。两个去除停用词的推文,第一个关于气候,第二个关于猫:

from sklearn.feature_extraction.text import TfidfVectorizer

docs = ["climate change . information about climate important", 
        "my cat cute . love cat"]

tfidf = TfidfVectorizer()
vectorized_docs = tfidf.fit_transform(docs).todense()

print("Shape:", vectorized_docs.shape)
display(pd.DataFrame(vectorized_docs, columns=tfidf.get_feature_names_out()))

结果如下所示:

如我们所见,我们从两个推文中得到了两个向量。向量中的每个数字与特定推文中单词的“重要性”成正比。例如,“climate”一词在第一条推文中出现了两次,因此在第一条推文中它的值很高,而在第二条推文中它的值为零(显然,“cat”一词的输出则相反)。

让我们在之前收集的真实数据集上尝试相同的方法:

docs = df["text_clean"].values

tfidf = TfidfVectorizer()
vectorized_docs = np.asarray(tfidf.fit_transform(docs).todense())

print("Shape:", vectorized_docs.shape)
# > Shape: (19197, 22735)

TfidfVectorizer 完成了任务;它将每条推文转换为一个向量。向量的维度等于语料库中单词的总数,这相当庞大。在我的案例中,19,197 条推文有 22,735 个唯一的标记,最终得到了一个 19,197x22,735 的矩阵!使用这样一个矩阵可能会很具挑战性,即使对于现代计算机也是如此。

我们将在下一步对这些数据进行聚类,但在此之前,让我们测试其他向量化方法。

Word2Vec

Word2Vec 是另一种词向量化方法;有关此方法的第一篇论文是 Tomas Mikolov 于 2013 年在 Google 介绍的。实现中提供了不同的算法(Skip-gram 和 CBOW 模型);一般思想是对大型文本语料库进行模型训练,从而获得准确的词到向量的表示。该模型能够学习不同单词之间的关系,如原始论文中所示:

PCA 投影的国家和首都向量,来源 © arxiv.org/pdf/1310.4546.pdf

可能最著名的使用此模型的例子是“king”、“man”和“queen”之间的关系。那些对细节感兴趣的人可以阅读 这篇很好的文章。

对于我们的任务,我将使用一个预训练向量文件。这个模型是用 Google 新闻数据集训练的;文件包含 300 万词和短语的向量。在使用真实数据集之前,我们先考虑一个玩具示例:

from gensim.models import Word2Vec, KeyedVectors
from gensim.models.doc2vec import Doc2Vec, TaggedDocument

word_vectors = KeyedVectors.load_word2vec_format('GoogleNews-vectors-negative300.bin', binary=True)

print("Shape:", word_vectors["climate"].shape)
display(word_vectors["climate"])

结果如下所示:

正如我们所看到的,单词“climate”被转换成了一个 300 位长度的数组。

使用 Word2Vec,我们可以为每个词获得嵌入,但我们需要整个推文的嵌入。作为最简单的方法,我们可以使用词嵌入的算术运算并获取所有向量的均值:

from nltk import word_tokenize

def word2vec_vectorize(text: str):
    """ Convert text document to the embedding vector """    
    vectors = []
    tokens = word_tokenize(text)
    for token in tokens:
        if token in word_vectors:
            vectors.append(word_vectors[token])

    return np.asarray(vectors).mean(axis=0) if len(vectors) > 0 else np.zeros(word_vectors.vector_size)

这是因为具有相似意义的词被转换成接近的向量,反之亦然。通过这种方法,我们可以将所有的推文转换成嵌入向量:

docs = df["text_clean"].values

vectorized_docs = list(map(word2vec_vectorize, docs))
print("Shape:", vectorized_docs.shape)

# > Shape: (22535, 300)

正如我们所看到的,与 TF-IDF 方法相比,Word2Vec 的输出在内存使用上要高效得多。我们为每条推文有 300 维的向量,输出矩阵的形状是 19,197x300,而不是 19,197x22,735——内存占用差异为 75 倍!

Doc2Vec是另一种模型,相比“简单”平均方法,它在生成文档嵌入方面可能更有效;它特别为文档的向量表示设计的。但在写这篇文章时,我没有找到预训练的 Doc2Vec 模型。读者可以自行尝试。

Sentence-BERT

在前一步中,我们使用 Word2Vec 获得了词嵌入。它有效,但这种方法有一个明显的缺点。Word2Vec 不考虑词的上下文;例如,“bank”这个词在句子“the river bank”和“the bank of England”中会得到相同的嵌入。为了解决这个问题并获得更准确的嵌入,我们可以尝试另一种方法。BERT(Bidirectional Encoder Representations from Transformer)语言模型于2018 年推出。它是在被遮蔽的文本句子上训练的,其中每个词的位置和上下文确实很重要。BERT 最初并不是为了计算嵌入而设计的,但事实证明,从 BERT 层中提取嵌入是一种有效的方法(2019 年和 2020 年的那些 TDS 文章提供了更多细节:12)。

如今,几年后,情况已有所改善,我们不需要手动从 BERT 中提取原始嵌入;像Sentence Transformers这样的特别项目专门为此设计。在处理真实数据集之前,我们先考虑一个玩具示例:

from sentence_transformers import SentenceTransformer

docs = ['the influence of human activity on the warming of the climate system has evolved from theory to established fact', 
        'cats can jump 5 times their own height']

model = SentenceTransformer('all-MiniLM-L6-v2')
vectorized_docs = model.encode(np.asarray(docs))

print("Shape:", vectorized_docs.shape)
# > Shape: (2, 384)

作为输出,我们得到了两个 384 维度的向量用于我们的句子。如我们所见,使用模型很简单,甚至不需要移除停用词;该库会自动处理所有这些。

现在让我们获取推文的嵌入。由于 BERT 词嵌入对词语上下文敏感,并且该库具有自己的清理和标记化,我不会像之前那样使用“text_clean”列。相反,我只会将推文 URL 和标签转换为文本。“partial_clean”方法使用了本文开头“text_clean”函数的部分代码:

def partial_clean(s_text: str) -> str:
    """ Convert tweet to a plain text sentence """
    output = re.sub(r"https?://\S+", "#url", s_text)  # Replace hyperlinks with '#url'
    output = re.sub(r'@\w+', '', output)  # Remove mentioned user names @... 
    output = remove_last_hashtags(output)  # Remove hashtags from the end of a string
    output = expand_hashtags(output)  # Expand hashtags to words
    output = re.sub(r"\s+", " ", output)  # Remove multiple spaces
    return output

docs = df['full_text'].map(partial_clean).values
vectorized_docs = model.encode(np.asarray(docs))
print("Shape:", vectorized_docs.shape)

# > Shape: (19197, 384)

作为句子变换器的输出,我们得到了一个 19,197x384 维度的数组。

附带说明一下,BERT 模型在计算上比 Word2Vec 要“重”得多。计算 19,197 条推文的向量在一个 12 核 CPU 上花费了大约 80 秒,而 Word2Vec 只需 1.8 秒。这在进行这种测试时不是问题,但在云环境中使用可能会更昂贵。

4. 聚类与可视化

最后,我们接近本文的最后部分。在之前的步骤中,我们获得了 3 个“vectorized_docs”数组的版本,这些版本通过使用 3 种方法生成:TF-IDF、Word2Vec 和 Sentence-BERT。让我们将这些嵌入进行分组,并查看可以提取哪些信息。

为此,让我们首先创建几个辅助函数:

from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score

def make_clustered_dataframe(x: np.array, k: int) -> pd.DataFrame:
    """ Create a new dataframe with original docs and assigned clusters """
    ids = df["id"].values
    user_names = df["user_name"].values
    docs = df["text_clean"].values
    tokenized_docs = df["text_clean"].map(text_to_tokens).values

    km = KMeans(n_clusters=k).fit(x)
    s_score = silhouette_score(x, km.labels_)
    print(f"K={k}: Silhouette coefficient {s_score:0.2f}, inertia:{km.inertia_}")

    # Create new DataFrame
    data_len = x.shape[0]
    df_clusters = pd.DataFrame({
        "id": ids[:data_len],
        "user": user_names[:data_len],
        "text": docs[:data_len],
        "tokens": tokenized_docs[:data_len],
        "cluster": km.labels_,
    })
    return df_clusters

def text_to_tokens(text: str) -> List[str]:
    """ Generate tokens from the sentence """
    # "this is text" => ['this', 'is' 'text']
    tokens = word_tokenize(text)  # Get tokens from text
    tokens = [t for t in tokens if len(t) > 1]  # Remove short tokens
    return tokens

# Make clustered dataframe
k = 30
df_clusters = make_clustered_dataframe(vectorized_docs, k)
with pd.option_context('display.max_colwidth', None):
    display(df_clusters)

我正在使用 SciKit-learn KMeans 进行 K-Means 聚类。一个“make_clustered_dataframe”方法创建了一个包含原始推文和一个新“cluster”列的数据框。在使用 K-Means 时,我们还有两个指标可以帮助我们评估结果。惯性可以用来衡量聚类质量。它是通过测量所有聚类点与聚类中心之间的距离来计算的,值越低越好。另一个有用的指标是 轮廓系数;该值的范围为 [-1, 1]。如果值接近 1,则聚类分离良好;如果值接近 0,则距离不显著;如果值为负,则表示聚类重叠。

“make_clustered_dataframe”的输出如下所示:

这确实有效,但仅使用这些信息,很难判断聚类是否足够好。让我们添加另一个辅助方法来显示 最佳聚类,按轮廓系数排序。我使用 SciKit-learn silhouette_samples 方法来计算这个。我还会使用 词云 来可视化每个聚类:

from sklearn.metrics import silhouette_samples

def show_clusters_info(x: np.array, k: int, cdf: pd.DataFrame):
    """ Print clusters info and top clusters """
    labels = cdf["cluster"].values
    sample_silhouette_values = silhouette_samples(x, labels)

    # Get silhouette values per cluster    
    silhouette_values = []
    for i in range(k):
        cluster_values = sample_silhouette_values[labels == i]
        silhouette_values.append((i, 
                                  cluster_values.shape[0], 
                                  cluster_values.mean(), 
                                  cluster_values.min(), 
                                  cluster_values.max()))
    # Sort
    silhouette_values = sorted(silhouette_values, 
                               key=lambda tup: tup[2], 
                               reverse=True)

    # Show clusters, sorted by silhouette values
    for s in silhouette_values:
        print(f"Cluster {s[0]}: Size:{s[1]}, avg:{s[2]:.2f}, min:{s[3]:.2f}, max: {s[4]:.2f}")

    # Show top 7 clusters
    top_clusters = []
    for cl in silhouette_values[:7]:
        df_c = cdf[cdf['cluster'] == cl[0]]

        # Show cluster
        with pd.option_context('display.max_colwidth', None):
            display(df_c[["id", "user", "text", "cluster"]])

        # Show words cloud
        s_all = ""
        for tokens_list in df_c['tokens'].values:
            s_all += ' '.join([text for text in tokens_list]) + " "            
        draw_cloud_from_words(s_all, stopwords=["url"])

        # Show most popular words
        vocab = Counter()
        for token in df_c["tokens"].values:
            vocab.update(token)
        display(vocab.most_common(10))

def draw_cloud_from_words(all_words: str, stopwords=None):
    """ Show the word cloud from the list of words """
    wordcloud = WordCloud(width=1600, height=1200, random_state=21, max_font_size=110, collocations=False, stopwords=stopwords).generate(all_words) 
    plt.figure(figsize=(16, 12)) 
    plt.imshow(wordcloud, interpolation="bilinear") 
    plt.axis('off')
    plt.show()

show_clusters_info(vectorized_docs, k, df_clusters)

在使用 K-Means 方法之前,下一步重要的问题是选择“K”,即最佳簇数。肘部法是一种流行的技术;其思路是构建不同 K 值的惯性值图。图中的“肘部”点(至少理论上)是最佳 K 值。实际上,它很少如预期般工作,尤其是对于结构不佳的数据集,如向量化的推文,但该图可以提供一些见解。让我们制作一个辅助方法来绘制肘部图:

import matplotlib.pyplot as plt  
%matplotlib inline

def graw_elbow_graph(x: np.array, k1: int, k2: int, k3: int):
    k_values, inertia_values = [], []
    for k in range(k1, k2, k3):
        print("Processing:", k)
        km = KMeans(n_clusters=k).fit(x)
        k_values.append(k)
        inertia_values.append(km.inertia_)

    plt.figure(figsize=(12,4))
    plt.plot(k_values, inertia_values, 'o')
    plt.title('Inertia for each K')
    plt.xlabel('K')
    plt.ylabel('Inertia')

graw_elbow_graph(vectorized_docs, 2, 50, 2)

可视化

作为一个额外的点,让我们添加最后一个(我保证这是最后一个:) 辅助方法,将所有簇绘制在 2D 平面上。我想大多数读者还不能在脑海中可视化 300 维的向量 😉 所以我将使用t-SNE(T-分布随机邻域嵌入)降维方法将维度减少到 2,并使用Bokeh绘制结果:

from sklearn.decomposition import PCA
from sklearn.manifold import TSNE

from bokeh.io import show, output_notebook, export_png
from bokeh.plotting import figure, output_file
from bokeh.models import ColumnDataSource, LabelSet, Label, Whisker, FactorRange
from bokeh.transform import factor_cmap, factor_mark, cumsum
from bokeh.palettes import *
from bokeh.layouts import row, column
output_notebook()

def draw_clusters_tsne(docs: List, cdf: pd.DataFrame):
    """ Draw clusters using TSNE """
    cluster_labels = cdf["cluster"].values
    cluster_names = [str(c) for c in cluster_labels]

    tsne = TSNE(n_components=2, verbose=1, perplexity=50, n_iter=300, 
                init='pca', learning_rate='auto')
    tsne_results = tsne.fit_transform(vectorized_docs)

    # Plot output
    x, y = tsne_results[:, 0], tsne_results[:, 1]
    source = ColumnDataSource(dict(x=x, 
                                   y=y, 
                                   labels=cluster_labels,
                                   colors=cluster_names))
    palette = (RdYlBu11 + BrBG11 + Viridis11 + Plasma11 + Cividis11 + RdGy11)[:len(cluster_names)]

    p = figure(width=1600, height=900, title="")
    p.scatter("x", "y",
              source=source, fill_alpha=0.8, size=4,
              legend_group='labels',
              color=factor_cmap('colors', palette, cluster_names)
              )
    show(p)

draw_clusters_tsne(vectorized_docs, df_clusters)

现在我们准备好查看结果了,让我们看看可以得到什么。

结果

我使用了三种不同的(TF-IDF、Word2Vec 和 Sentence-BERT)算法将文本转换为嵌入向量,它们在架构上差异很大。它们是否都能在所有推文中找到有趣的模式?让我们检查一下结果。

TF-IDF

在 TF-IDF 嵌入中寻找簇的主要缺点是数据量大。在我的例子中,矩阵大小为 19,197x22,735,因为文本语料库包含 19,197 条推文和 22,735 个唯一标记。即使对于现代 PC,在如此大的矩阵中寻找簇也并不快。

一般来说,TF-IDF 向量化没有提供特别出色的结果,但 K-Means 仍然能够找到一些有趣的簇。例如,从所有 19,197 条推文中,检测到一个包含 200 条推文的簇,其中人们在发帖关于国际在线论坛:

文本簇词云,图片由作者提供

K-Means 也能够找到一些发布了大量类似帖子用户:

在这种情况下,昵称为“mickel”的用户可能在尝试推广他的在线书籍(顺便说一句,显示消息 ID 对调试很有用;我们可以随时在浏览器中打开原始推文),并且他发布了很多类似的帖子。这些帖子并不完全相似,但算法能够将它们聚类在一起。这种方法在检测用于发布垃圾邮件的账户时可能会很有用。

在 TF-IDF 向量中发现了一些有趣的簇,但大多数其他簇的轮廓值接近零。t-SNE 可视化显示了相同的结果。图中有一些局部群体,但大多数点相互重叠:

t-SNE 对 TF-IDF 生成的向量的可视化,图片由作者提供

我看到一些文章中,作者使用 TF-IDF 嵌入取得了良好的结果,主要是在文本属于不同领域的情况下。例如,关于“政治”、“体育”和“宗教”的帖子可能会形成更多隔离的聚类,并具有较高的轮廓系数值。但在我们的案例中,所有文本都关于气候,因此任务更具挑战性。

Word2Vec

使用 Word2Vec 得到的第一个有趣的结果是——肘部方法能够产生一个相对明显的“肘部”点:

Word2Vec 嵌入的肘部图,图片由作者提供

使用 K=8,t-SNE 可视化得到了这个结果:

t-SNE 对 Word2Vec 生成的向量的可视化,图片由作者提供

大多数聚类仍然重叠,并且轮廓系数值普遍较低。但可以发现一些有趣的模式。

“气候变化”。这个聚类包含了最流行的词汇“气候”、“变化”、“行动”和“全球”:

很多人显然对气候变化感到担忧,所以有这个聚类是显而易见的。

“燃料”。这个聚类包含了诸如“能源”、“碳”、“排放”、“化石”或“太阳能”等流行词汇:

“环境”。这里我们可以看到如“温度”、“海洋”、“海”、“冰”等词汇。

Sentence-BERT

理论上,这些嵌入应该提供最准确的结果;让我们看看实际情况如何。t-SNE 的聚类可视化如下:

t-SNE 对 Sentence-BERT 生成的向量的可视化,图片由作者提供

如我们所见,可以找到许多本地聚类,我将展示其中一些最有趣的聚类。

“冰川融化”。一个包含了最流行词汇“气候”、“冰”、“融化”、“冰川”和“北极”的聚类:

“地球日”。这一天在数据收集时是四月庆祝的,存在一个包含“地球”、“日”、“星球”、“快乐”或“行动”等词汇的消息聚类:

“全球国际论坛”:

这个结果有两个有趣的原因。首先,我们之前见过这个聚类;K-Means 算法在 TF-IDF 嵌入中发现了它。其次,“Word2Vec”模型的词典中没有“thereisa”这个词,因此它被跳过了。BERT 有更好的分词方案,其中未知词被拆分成更小的标记。我们可以很容易地看到它是如何工作的:

model = SentenceTransformer('all-MiniLM-L6-v2')

inputs = model.tokenizer(["thereisa online forum"])
tokens = [e.tokens for e in inputs.encodings]

print(tokens)
# > [['[CLS]', 'there', '##isa', 'online', 'forum', '[SEP]']]

我们可以看到,“online”和“forum”这些词被转换成了单一的标记,但“thereisa”被分解成了两个词“there”和“##isa”。这不仅使 BERT 能处理未知词汇,而且实际上更接近我们作为人类的做法:当我们遇到未知词汇时,我们常常试图“拆分”它们并猜测其含义。

但让我们进一步探讨。另一个明显的组与抗议有关;我们可以看到如“protest”,“change”,“action”,“activism”等词汇:

最后但同样重要的是,另一个受欢迎的气候相关话题是电动交通。我们可以看到像“new”,“electric”,“car”或“emission”等词:

结论

通过文本聚类,我们能够处理来自社交网络的原始和非结构化文本(在我们的案例中是 Twitter,但这种方法也适用于其他平台),并发现数万用户帖子的有趣和独特的模式。这不仅对于像文化人类学或社会学研究这样的纯学术原因重要,也对像检测机器人或发布垃圾信息的用户这样的“实用”案例至关重要。

从自然语言处理的角度来看,社交媒体数据的聚类是一个有趣且富有挑战性的课题。它具有挑战性的原因在于数据清洗和转换的方法多种多样,没有一种方法是完美的。在我们的案例中,BERT 嵌入毫无悬念地提供了比早期的 TF-IDF 和 Word2Vec 模型更好的结果。BERT 不仅能提供良好的结果,而且在处理未知词汇方面也表现得更好,而这可能是 Word2Vec 的一个问题。就我而言,TF-IDF 嵌入并未展示出任何卓越的结果,但这种方法仍然有其优势。TF-IDF 基于纯粹的统计数据,不需要预训练的语言模型。因此,在那些没有可用预训练模型的稀有语言情况下,可以使用 TF-IDF。

本文提供了一种“低级别”的方法,这种方法更适合理解事物的工作原理,我鼓励读者自己做一些实验;文章中的源代码应该足够进行这些实验。同时,那些只想在 10 行代码中获得结果而不想考虑“底层”实现的人,可以尝试像 BERTopic 这样的现成库。

如果你喜欢这个故事,可以随时 订阅 Medium,你将会在我的新文章发布时收到通知,并且可以全面访问其他作者的成千上万篇故事。

感谢阅读。

人工智能在医疗保健中应扮演什么角色?

原文:towardsdatascience.com/what-role-should-ai-play-in-healthcare-7acaf9131278?source=collection_archive---------2-----------------------#2023-11-30

关于机器学习在医疗保健中的应用及美国医疗保健 AI 丑闻

Stephanie KirmerTowards Data Science Stephanie Kirmer

·

关注 发表在 Towards Data Science ·11 分钟阅读·2023 年 11 月 30 日

--

图片来源:国家癌症研究所,来源于 Unsplash

你们中的一些人可能知道我受过社会学培训——准确地说,我在研究生院学习了医学社会学。这意味着我专注于人们和群体如何与疾病、医学、医疗机构以及围绕健康的概念和想法互动。*

当我担任兼职教授时,我曾向进入医疗领域的本科生讲授这些问题,我认为医疗服务提供者对我们社会、经济和种族状况如何与健康互动有深入了解是非常重要的。每个生病的人都不是相同的,认识到这一点是提供高质量护理之前必须做到的。

我解释这些只是为了为今天的话题——机器学习在医疗中的应用——提供一些背景。我之所以等到现在才谈论这个话题,是因为它实在太大了,但最近的一些新闻报道激励我开始讨论。很可能,我会在未来继续谈论这个话题。

关于生命与死亡

我发现很难讨论在医疗领域使用机器学习的原因之一是因为失败的风险极其严重。如果我预测你在线订购的袜子的到达日期错误,最坏的情况就是你可能有一两天的冷脚。如果机器学习模型在医疗环境中出错,风险就会真正上升到生命丧失或生活质量严重下降的程度。

如果机器学习模型在医疗环境中出错,风险就会真正上升到生命丧失或生活质量严重下降的程度。

当然,我们的医疗服务提供者在日常工作中已经意识到了这种风险,并学会了应对它。但总体来说,数据科学家和机器学习模型开发者对这些模型所涉及的结果并不熟悉。在建模时,以分类模型为例,任务的一个重要部分是估计我们称之为假阳性和假阴性的成本——本质上,就是当我们预测某个事件实际上没有发生(FP)或我们预测不会发生任何事件但它实际上发生了(FN)时,可能会出现什么坏事。在其他类型的模型中,我们也会花时间考虑模型预测的结果与期望值或实际情况的差异。共同点是模型总是会有某种程度的不可避免的错误,即使是生成式人工智能也是如此。正如我过去多次提到的,模型输出在某种程度上是基于概率的,这些概率留有一定的错误(不良行为)的空间。

在医疗环境中,假阳性或假阴性等错误的成本意味着什么?如果还不够明显的话,金钱只是模型潜在错误中的一小部分,无论是在医疗领域还是其他行业。与“生命损失”或“失去独立生活能力”相比,金钱损失应当是一个较低的优先级。虽然我们的法律系统尝试为这些问题分配货币价值,以便在法院案件中分配赔偿金,但这真的不是同一回事,尤其是当问题涉及到你自己的生命或生活质量时。

联合健康

最近报道的关于联合医疗如何 使用机器学习的案例,突显了当“金钱”在医疗决策中被赋予比“生命”更高的优先级时,情况变得多么糟糕。这与模型本身没有太大关系,因为你可以教会一个模型更好地优先考虑医疗结果 如果你愿意的话

不幸的是,我们的医疗系统在护理质量和利润这两个竞争的优先级之间摇摆。我坚决拒绝这两者可以和谐共存的观点,因为它们总是处于紧张状态,但美国的系统仍然基于这种可疑的基础。我们在讨论联合医疗所做的事情时,牢记这一点是重要的。

联合医疗(在实际支付护理方面被普遍认为是美国最差的大型健康保险公司)所做的就是:

  • 人员已支付了他们的保险费用,并且做了所有应做的事情以获得保险覆盖;

  • 人员变老和/或生病,需要住院护理来恢复病情或伤害;

  • 联合医疗的模型提供了案件和患者的一般特征,并预测恢复护理可能需要的时间。这一预测所需的护理时间远远短于医生建议的时间;

  • 联合医疗信任模型而非医生,并拒绝支付更长的护理时间,将患者在未康复前赶出了护理设施。

许多医生和医疗系统的学者讨论了健康保险公司如何“无证行医” 当他们对医生关于患者所需护理的专业医学意见提出质疑时,这种行为正是这种情况的体现。当联合医疗的员工(在模型的支持下)改变患者的护理方案时,我们还能怎么称呼这种行为?

但这并不新鲜,实际上,保险公司不需要模型来支持他们对医生的质疑。这在我们的健康保险系统中是常见的,每天都会发生,形式包括事先授权。保险公司会争辩说,他们有其他医生在做最终决定,因此“无证行医”并不适用,但这些医生明显的激励是站在保险公司一边,而非患者。可以确定,这些医生从未推荐比主要医生更昂贵的护理方案。

应用机器学习

那么,为什么 UHC 的行为现在成为新闻?这与机器学习到底有什么关系?UHC 用于确定这些老年患者的急性后护理应该持续多久的模型来自一家名为 naviHealth 的公司,该公司专门处理这些案例。从他们的网站阅读,我了解到,naviHealth 寻找减少老年患者在护理设施中停留时间的方法。他们可能还提供一些关于案例管理的服务,在患者被送回家之前与他们进行咨询。他们在网站上明确表示,他们可以为保险公司提供“显著的成本节约”。

但关键在于,这个模型“nH Predict”声称能够确定患者在护理环境中停留的最佳时间长度, ostensibly 为了最佳的护理效果,而实际上模型的阈值设置使得这些预测与护理效果并不一致,而仅仅是为了成本节约。

换句话说:如果你允许病人留在医院或康复设施,但他们准备提前回家并且真的这样做了,那是很好的。没有人愿意在医院待得过久(你尝过医院的食物吗?)。这是一种你可能通过提供高质量的护理、他们所描述的案例管理以及其他有用服务来实现的成本节约,同时病人也能得到他们所需的护理。但 UHC 所做的却是,通过拒绝支付病人在医院的费用来获得成本节约,因此不论病人是否准备好,他们都会被赶出医院送回家。

UHC 所做的却是,通过拒绝支付病人在医院的费用来获得成本节约,而不是提供这些服务并让病人准备好提前离开医院,因此无论病人是否准备好,他们都会被赶出医院送回家。

模型如何了解健康

我想澄清的是,这不是“人工智能失控”——这是人类做出了不道德的决定,并利用机器学习来推卸责任。如果你想将老年人赶出医院,不考虑他们的生活或健康后果,那么如果你今天是美国的保险公司,你可以这样做。你不需要一个模型来给你许可。但我认为 UHC 意识到,如果他们有一个模型给出这些建议,而人工审核者可以只是走个过场,那么他们就有了掩护,因为人们认为模型具有一定的独立准确性。毕竟,模型肯定不会查看这项护理的价格标签!

但请记住,模型只是一个试图将模式融合成可以复制的数学语言的尝试,它不控制你提供给它的信息,也不控制你教它回答的问题。在创建一个预测住院天数的模型时,你可以这样进行。

  • 收集大量的过去患者档案数据,其中有人受伤或生病,进入医院,接受康复住院护理,并有结果(不论是康复、需要回医院还是去世)。

  • 将这些文件转化为数字数据。把每个患者看作是电子表格中的一行,开始收集诸如患者年龄、初始伤害的严重程度、患者的过去病史数据、是否有其他疾病(糖尿病、心脏病、痴呆等)。这些成为训练数据。最重要的是,你需要包括 A. 康复住院护理的天数和 B. 结果是什么。

  • 现在你需要框定问题。在这种情况下,塑造模型训练的一种方式可能是:“在考虑到所有病例特征的情况下,治疗效果良好的患者有多少天的康复?” 然后你可能会将其与“在考虑到所有病例特征的情况下,治疗效果差的患者有多少天的康复?”进行比较。这只是一个假设性的框定方式,还有许多其他方法可以构建问题并整合训练数据。

最终你会得到每个患者的康复天数估计值,这个估计值适用于良好的结果。可能会得到一个范围,或者基于天数的良好结果的概率,如果你将天数增加到某个点,那么概率也会增加,如果超过某个点,它又会开始变得有风险。

请记住,康复天数并不是与其他一切无关——你可能会有感染、并发症或其他疾病,这意味着长时间住院是必要的,并不是为了愉快的原因(康复),而是为了不幸的原因(额外的疾病)。所以住院时间过长也可能是一个坏事,但原因与住院天数无关。考虑时间顺序,帮助理解因果关系可能存在的地方。

使用模型的结果

所以我们有一个模型,如果我们告诉它有关患者的信息,它就会给出一个估计值,说明如果这个人要有好的结果,康复住院的时间可能需要多久。真正关键的问题是我们如何利用这些信息!

如果我们是全民医疗保险(UHC),我们的目标是节省开支。我们以非常非常低的估算值为准,可能甚至低于模型推荐的良好结果范围,并在此时停止支付医疗费用。这就是这个故事的经过,依据报道来看。

如果我们的目标是病人的结果,那么我们应该退一步思考一下。我们是否认为病人因非医学原因在医院或住院康复中心待了很长时间?我们是否认为医生因不适当的原因将病人送往康复中心?这些原因可能是什么?老实说,我很难想到许多医生在这种情况下会有什么合理的行为。正如我所提到的,谁愿意在病情好转后仍然待在医院?如果确实发生了这种情况,我们应该寻找改变医生行为的方法,但不应以牺牲病人护理质量为代价。也许医院高管们希望病人待得更久,而医生的薪水与病人的住院时间无关。医生的激励是让病人尽快康复。

我在这里想表达的是,如果我们的目标只是让病人康复,我不确定引入这个模型是否有意义。毫无疑问,过长的康复住院时间目前不是对病人健康的最大威胁。

这篇文章讲述了机器学习,这也是大多数读者来这里的原因,但它还涉及了医疗经济学的问题。这些问题对所有美国人来说都很重要,因为医疗系统迟早会影响到我们所有人。我还认为,对于数据科学家来说,思考将模型投入生产环境的真正意义是一个很好的练习,这不仅仅是从召回率和精确度的角度来看,而是从真实人类生活受影响的角度来看。你对你的模型的优化负责。你在构建模型时做出的决策将使该模型对人们和社会的影响是积极的还是消极的,你不能仅仅耸耸肩说“模型做的”。

即使你的模型不会对人们的医疗保健做出决定,它仍然会对人们产生一些影响。(如果没有,那你为什么要构建它?)我鼓励所有从业者在工作中时刻牢记这一点。

*医学社会学关心的这些问题的例子可能包括:

  • 患有慢性疾病的人如何看待自己及其在社会中的位置?

  • 当人们成为医疗服务提供者时,他们的生活和身份有什么不同?

  • 少数群体或弱势群体的长期健康结果是什么?这些结果与多数群体有何不同,为什么会有这种差异?

  • 环境问题如何影响人们的健康,这些问题如何与社会结构/特权互动?

这只是其中的一部分——这个社会学领域涵盖了对人们生活和福祉至关重要的广泛内容。

www.stephaniekirmer.com上查看更多我的作品。

参考文献

国会委员会和监管机构质疑 Cigna 系统,允许其医生拒绝索赔而无需…

这些探查跟随 ProPublica 和 Capitol Forum 的调查,揭示了 Cigna 允许其医生拒绝数百个…

UnitedHealth 被指控使用有缺陷的 AI 拒绝老年患者必要的医疗覆盖 [## 由诉讼声称]

过去受益者的家庭声称,UnitedHealth 的 AI 系统“积极”拒绝了必要的医疗索赔…

naviHealth 官网 [## 首页]

老年中心护理的未来已来

navihealth 官网

当你的 p 值 = 0.052 时,你的决定应该是什么?

原文:towardsdatascience.com/what-should-your-decision-be-when-your-p-value-0-052-1d50f9d4d2c5

选择显著性水平的指南

Jae KimTowards Data Science Jae Kim

·发表于 Towards Data Science ·7 分钟阅读·2023 年 4 月 13 日

--

图片由 Burst 提供,来源于 Unsplash

在假设检验中,“p 值 < α”几乎被普遍作为统计显著性的标准和决策规则,其中α是显著性水平。例如,在测试中

H0: θ = 0; H1: θ ≠ 0,

当θ是代表某种效应的感兴趣参数时,如果 p 值 < α,我们在α显著性水平下拒绝 H0(无效应假设)。通常设置α = 0.05,而 0.10 和 0.01 也被广泛采用。正如众所周知,这些常规值是任意的,并且缺乏科学依据。

当 p 值接近 0.05 时,你应该怎么做?例如,

  • 如果 p 值 = 0.052,你应该维持α = 0.05 并接受 H0 吗?还是应该将α设置为 0.10 并拒绝 H0?

  • 同样地,如果 p 值 = 0.047,你应该维持α = 0.05 并拒绝 H0 吗?还是应该将α设置为 0.01 并接受 H0?

统计教科书对这一点提供的指导很少,而在统计分析和机器学习方法的实际应用中,经常会遇到这种情况。

本文旨在为研究人员提供一些关键点,以在面对这种情况时做出理性的决定。虽然以下讨论适用于任何接近 0.05 的 p 值,但为了说明问题,我们假设 p 值 = 0.052。文中提供了两个实际应用的示例。

1. α值设置的意义

显著性水平α表示 I 型错误(拒绝真实 H0)的概率。设置低值的α意味着你希望以低概率控制 I 型错误。

原则上,显著性水平的选择应考虑Ⅱ型错误的概率(接受虚假的 H0),记作β;统计功效(1-β);样本大小;以及Ⅰ型和Ⅱ型错误的损失,在数据收集之前做出决定。详细信息请见这篇文章

α 和 β 之间的权衡是众所周知的。较高的α值会导致较低的β值;反之亦然。设置较高的α值意味着你希望以较低的概率控制Ⅱ型错误。

只要样本大小固定,两种错误概率不能同时降低。

2. 不应做的事

回到 p 值接近 0.05 的情况,我们首先回答一下不应该做什么。

最不科学的方式是调整α值以符合或证明你预设的决定。即,α值不应根据研究人员是否想要拒绝或接受假设来选择:见Keuzenkamp 和 Magnus (1995, p. 20)

以 p 值 = 0.052 为例。假设研究人员发起研究的目的是拒绝 H0,因此她选择了α = 0.10 并拒绝 H0。相反,如果研究人员的目的是接受 H0,那么她选择α = 0.01 并接受 H0。

上述做法是不科学且武断的,甚至可能是不道德的。这一过程被称为p-hacking数据窥探,这是许多科学领域错误积累的主要原因:请参见美国统计协会的声明

为了在这种情况下做出更科学的统计决策,需要仔细考虑一系列因素,以做出合理的α值选择或调整。

3. 我们应该怎么做?

当 p 值接近 0.05 时,决策者需要考虑三个要点。这些要点应该与 p 值一起或单独权衡,并据此确定或调整最终的α值。

效应大小

首先是估计的θ值是否表明了一个显著的效果。假设 p 值 = 0.052 且效果被发现是显著的,那么研究人员应该拒绝 H0,选择α值为 0.10 或更高。相反,如果效果被发现是微不足道的,那么选择α值为 0.01 或更低,不拒绝 H0 是合适的。

当效应微不足道时,这意味着 H0 极有可能,设置较低的α值来避免 I 型错误是合理的。相反,如果效应强且 H1 极有可能,那么设置较高的α值来避免 II 型错误是合理的。这将减少β值(II 型错误的概率),因为这是α和β之间的权衡结果。

I 型和 II 型错误的相对损失

I 型和 II 型错误带来损失或后果。当损失已知或可估计时,研究人员应将相对损失纳入决策过程。

再假设一次 p-value = 0.052。假设 I 型错误(拒绝真实的 H0)将导致 100 万美元的损失,而 II 型错误(接受虚假的 H0)将带来较小的损失。那么,研究人员应该通过控制 I 型错误的低概率(如 0.01 或更低,即设置α ≤ 0.01)来避免 I 型错误。因此,在这种情况下,在α = 0.01 时,不拒绝 H0 是合理的。

相反,假设 II 型错误比 I 型错误更昂贵。那么,研究人员应该增加α值,以减少β值并避免 II 型错误。这也是基于上述α和β之间的权衡。在这种情况下,设置α ≥ 0.10 并拒绝 H0 是合理的。

先验知识

可能存在关于效应(θ)的先验知识,这些知识可能以

  • 理论,

  • 规范化事实(积累的统计证据),

  • 专家意见及其共识,或

  • 常识或直觉。

假设有一种理论或专家意见强烈建议存在强效应。在这种情况下,当 p-value = 0.052 时,在α = 0.05 时接受 H0 是不合理的。当先验知识强烈支持 H1 时,则应选择较高的α值,以便将β值降低。这是因为,鉴于 H1 极有可能发生,研究人员希望以低概率控制 II 型错误。因此,在这种情况下,设置α ≥ 0.10 并拒绝 H0 是合理的。

相反,如果先验知识强烈支持没有效应的 H0,那么研究人员应该通过设置较低的α值来以较低的概率控制 I 型错误。这是因为,鉴于 H0 极有可能,研究人员应避免 I 型错误。因此,在这种情况下,设置α ≤ 0.01 并接受 H0 是合理的。

4. 示例

本节提供了两个应用实例。

第一个是广为人知的虚假相关性示例,即美国淹死死亡人数与尼古拉斯·凯奇从 1999 到 2009 年出演的电影数量之间的关系。有关更多细节,请参见这篇文章。设 Y 为死亡人数,X 为尼古拉斯·凯奇出演的电影数量。对于回归 Y = β0 + β1 X + u,估计的斜率系数为 5.82,t 统计量为 2.68,(双尾) p 值为 0.025。我们应该在 5%的显著性水平下拒绝 H0: β1 = 0,还是在 1%的显著性水平下接受它?

假设研究者认为这个关系的实质性重要性很小,并且判断 H0: β1 = 0 很可能是真的。她进一步咨询了许多专家,这些专家也支持她的判断。因此,她希望通过选择一个低概率(例如 0.01)来避免 I 类错误。也就是说,在α = 0.01 的情况下,H0: β1 = 0 不能被拒绝,因为 p 值 = 0.025 大于 0.01。

作为第二个例子,我们考虑Selvanathan (2017)的示例 17.10。一位生产经理希望检查在招聘前进行的能力测试分数与员工入职三个月后的表现评分之间的关系。从 20 名工人的随机样本中,计算出的相关系数(ρ)为样本值 r = 0.379。H0:ρ = 0; H1: ρ ≠ 0 的 Z 统计量,服从标准正态分布,给出如下

图片由作者创建

这在 H0 下给出的值为 1.652,p 值 = 0.098。再说一遍,经理应该选择 0.05 还是 0.10 的显著性水平?

假设经理发现 r = 0.379 并非微不足道的相关性,而且广泛认为这是表示中等关联的相关值:例如,请参见这篇文章。基于此,经理决定 H1 很可能成立,并将α设定为较高的值,如 0.10,以降低 II 类错误的概率。因此,在 10%的显著性水平下,H0 被拒绝,支持 H1,因为 p 值 = 0.098 < 0.10。

在这篇文章中,我解释了如何调整显著性水平,特别关注 p 值接近 0.05 的情况。关于这方面的指导文献很少,这篇文章旨在为数据科学家提供在这种情况下需要考虑的几个关键点。有关在更正式和通用环境中选择显著性水平的方法,请参阅这篇文章

上述讨论隐含假设 α = 0.05 作为初始显著性水平。但当 α 的初始值为 0.10 或 0.01 时,同样的逻辑和论点也应适用。

主要结论是,当研究人员选择或调整显著性水平时,他们应考虑包括关键因素在内的理由来证明其选择。

  • 效应量,

  • 类型 I 和 II 错误的相对损失,以及/或者

  • 先验知识。

任意调整显著性水平是不科学的,应予以避免。

什么阻碍了你获得第一个数据科学工作?

原文:towardsdatascience.com/what-stops-you-from-getting-your-first-data-science-job-ccf93e4187d4?source=collection_archive---------8-----------------------#2023-03-23

数据科学面试流程和获得第一个工作机会的步骤

亚历克斯·瓦姆瓦卡里斯迈向数据科学 亚历克斯·瓦姆瓦卡里斯

·

关注 发表在 迈向数据科学 ·12 分钟阅读·2023 年 3 月 23 日

--

图片由 Rod Long 提供,来源于 Unsplash

尽管有很多关于如何成为数据科学家的博客、视频和教程,但许多资源都存在我所称之为“知识的诅咒”。那是什么呢?大多数这些资源都是由那些已经当了很长时间数据科学家的人创建的,因此他们已经忘记了获得第一份数据科学家工作的瓶颈和困难。

我记得当我开始申请伦敦的数据科学职位时(那时我作为数据分析师已有两年多的经验),在几乎所有阶段都遭遇了很多拒绝。我可能提交了数百份申请,才能让只有几个进入下一阶段。即使是那些通过筛选过程的申请,也经历了很多拒绝,才最终获得了第一份 offer。实际上,有时候我决定完全放弃(有时甚至几个月),因为我相信成为数据科学家的梦想无法实现。有时我希望能回到过去,帮助自己导航数据科学面试流程中的复杂性和未知,并挽回一些失去的时间。

鉴于这一点,我想以稍微不同的方式构建这篇文章。我们不会完全忽略技术要求如统计学、编程和机器学习(别担心,我们还是会涵盖这些内容),而是希望创建一个专注于面试过程各个阶段以及如何集中精力以获得你的第一个 offer 的指南。具体来说,文章将按以下结构展开:

  1. 绘制数据科学面试流程图

  2. 用你的简历打开大门

  3. 技术(回家)评估

  4. 与招聘数据科学家的现场面试

  5. 从错误中学习

1. 数据科学面试流程图

Brett Zeck 拍摄,来源于 Unsplash

大多数入门级数据科学职位的面试过程通常包括三到五个阶段。虽然这些阶段会根据你希望成为的数据科学家的类型和你申请的公司有所不同,但基本构成是相同的。

前两个阶段是筛选过程的一部分。这些是你的 简历(CV)与招聘人员的初步电话。此时,你仍在敲打公司的大门。目的是将候选人池缩小到一个较小的群体,这些人将被邀请“进入屋内”。

一旦进入公司,你仍然需要证明自己具备足够的资格。换句话说,你需要展示你拥有合适的态度和技能组合,使他们愿意雇佣你,同时能够对这一选择做出合理的解释。这可以分为以下三个阶段(注意,并非所有阶段都出现在每个面试过程中):

  • 技术(家庭作业)评估: 这一阶段旨在测试你的逻辑思维能力和统计与编程(SQL、R 或 Python)的水平。本质上,他们希望评估你的基础知识是否足够,能够进一步进入公司。

  • 与(招聘)数据科学家的现场面试:这一阶段涉及视频通话(在 Covid 后),高级或首席数据科学家将要求你解决问题并回答基于你在被雇佣后需要完成的日常任务的问题。此时,你已经完全进入了公司。

  • 最终面试: 这一阶段并非总是存在,但在成熟的数据科学团队中,作为最后的关卡,你将与数据科学团队的高级领导(负责人或总监)进行简短的通话。目的是让他们了解你并给出“绿灯”或发现任何红旗。

数据科学面试流程 [作者提供的图像]

现在我们对各个阶段有了更好的理解,让我们深入探讨每一个阶段,以便你更好地理解它们的结构以及如何应对,以获得你的第一份数据科学角色。

2. 用你的简历打开大门

照片由 João FerrãoUnsplash 提供

在创建简历时,仔细考虑你想成为哪种类型的数据科学家。如果你想打造合适的钥匙,首先应考虑你希望它打开哪种类型的门。有两种主要类型的(入门)数据科学家职位(即门):

  • 分析数据科学家: 主要职责是 AB 测试、对广告活动、优惠或产品进行临时分析,并构建简单(主要是探索性)的机器学习模型,例如聚类。

  • 核心数据科学家: 主要职责是构建可以投入生产环境的预测模型(具有最高的准确性)。

如果你想了解更多关于不同类型的数据科学家角色及其日常任务,你还可以查看下面的视频。

虽然典型的钥匙是一个小块形状金属,上面有切口以适配特定锁的钥匙孔,但你的简历将包含 关键词工作经验

不幸的是,即使你打造了正确的“钥匙”,在这个阶段的成功率仍将是整个面试过程中最低的。这主要是由于这个阶段的随机性和匆忙性(你可能听说过,大多数简历在做出决定之前只会被查看 2 到 3 秒)。

尽管申请后没有回应可能会让人感到沮丧,但另一方面,你也获得了所有需要的“弹药”来打造合适的“钥匙”。大多数职位描述通常会列出这些关键词,因此你需要做的是 a) 确定哪些职位适合你,b) 收集常见的关键词和所需的技能,并 c) 确保它们在你的简历中得到清晰的体现。相信这个简单的过程,凭借适当数量的申请,你将进入下一个阶段(这只是由于大数法则的一个简单情况)。

如前所述,筛选过程的第二部分是与招聘人员的电话面试。这通常持续 15 到 20 分钟,招聘人员首先会给你介绍公司的背景和职位情况。之后,招聘人员会询问你的工作经历、通知期、签证要求、薪资预期以及一些关于职位的问题。常见的问题包括:

  • 你能快速介绍一下你的简历/工作经历吗?

  • 你对我们公司这个职位感兴趣的地方是什么?

  • 在寻找新职位时,你期望得到什么?或者换句话说,你看重哪些任务或职责?

  • 你在当前或之前的工作中使用了哪些工具和技术?

尽管这些问题看起来很简单,我建议你练习几次。正如亚伯拉罕·林肯所说:“给我六个小时砍树,我会用前四个小时磨快斧子。”

3. 技术(家庭作业)评估

图片由 Nguyen Dang Hoang Nhu 提供,来源于 Unsplash

技术性家庭作业通常以一系列问题的形式呈现。这些问题通常包括以下内容:

  • 编写一个函数来解决一个简单的问题(比如计算大于 1000 的前 10 个斐波那契数),使用 R 或 Python。

  • 给定一个或多个表(通常不超过两个),你需要用 SQL 编写代码来提取或操作数据。这些问题通常从简单开始,例如计算符合某些条件的行总数,最后的问题则需要使用不同类型的连接和窗口函数。

  • 给定一个图表或小表格,你需要利用统计学来得出正确的结论。最常见的问题涉及偏斜分布、平均值和中心极限定理。

  • 给定一个特定的业务问题,你将被要求写一个简要的提案,说明你会选择哪些 KPI 和分析方法来实现预期结果。

我无法过于强调双重(或三重)检查你的答案和验证代码的重要性。我还建议尽可能将这些检查加入到你的解决方案或代码中。你可以在下面的文章中找到有关 SQL 语句和测试代码的更多信息。

## 如何将你的 SQL 从零提升到数据科学家水平 — 第 2/3 部分

SQL 完全指南:学习数据科学家常用的基础和高级 SQL 查询

[towardsdatascience.com

或者,你可能会被给予一个数据挑战。更具体地说,你将获得一个数据集和一个任务或问题的概述。例如,在我为 Deliveroo 完成的家庭作业中,任务是分析他们的“骑手推荐骑手”项目与其他营销渠道的表现。任务的最后一步涉及向高级非技术利益相关者展示信息摘要,并建议可能的下一步。如果你在这一步需要更多帮助,我推荐阅读下面的指南。

## 如何将家庭作业转化为数据科学职位

如何从数据集中创建一个引人注目的故事的逐步指南

[towardsdatascience.com

4. 与招聘数据科学家的现场面试

照片由 GR Stocks 提供,照片来源于 Unsplash

这将是面试过程中最具挑战性的部分。它不仅是一次现场面试,而且难度也是整个流程中最高的。话虽如此,你可以期待得到公平的评价,因为在视频通话期间,你将获得面试官的全部注意力。

在 COVID-19 之前,大多数技术面试都在公司现场(实际上是在‘公司内部’)进行。然而,如今绝大多数面试都是通过 Zoom 或其他视频会议工具进行的。这些面试由一位或两位数据科学家进行,通常包括以下三个部分:

4.1 行为/态度评估

在这一部分,问题主要是非技术性的,旨在评估你的软技能和个人特点。常见问题包括:

  • 你能描述一个你遇到问题的情况并解释你采取的步骤来解决它吗?

  • 讲述一个你引以为豪的项目及其对业务的影响。

在准备你的回答时(遵循我们朋友亚伯拉罕·林肯的建议),重要的是始终记住这些类型的问题没有正确答案。相反,他们寻找的是理解在任何环境中你都会遇到障碍,而真正重要的是展现出毅力和提供价值的能力。STAR方法是一个很好的框架,讨论具体的情况、任务、行动和结果。

4.2 经验评估

在这一部分,你将被给出一个面试官提出的具体问题,通常基于如果你被录用后需要完成的任务。典型场景包括以下几种:

  • 我们最近启动了一个活动或优惠,并希望评估其表现。描述你会如何从头到尾处理这个问题(与业务相关者沟通,理解目标,获取所需数据,分析和展示结果)。

  • 描述你将如何为特定功能或倡议设计 AB 测试。

  • 如果 AB 测试显示期望的指标在下降,而另一个指标在上升,你会如何决定是否发布或放弃这个功能?

不要害怕向面试官提出澄清问题,并将你的思路阐明给他们。面试官会根据你对模糊描述的理解能力(因为这些描述大多出现在实际环境中)以及你解决问题的方法来评估你。同时,不要犹豫向面试官请求几分钟时间来整理问题后再回答。最后,记住他们在寻找新员工时关注的是为业务提供价值的能力,因此始终以这个北极星为目标来组织你的回答。

4.3 技术技能评估

在这一部分,你将被评估在统计学、AB 测试和机器学习方面的技术技能。示例问题包括:

  • 你将如何向一个 5 岁的小孩描述 p 值和置信区间?

  • 你能解释什么是引导法以及它是如何使用的吗?

  • 你将如何在启动 AB 测试前估计样本大小?

  • 你将如何分析 AB 测试结果中异常值和测试前的不平衡?

如果你需要复习或了解上述问题,可以在下面的链接中找到关于商业环境中 AB 测试的完整指南。

[## 我作为数据科学家运行 AB 测试一年的经验——第 1/2 部分]

像数据科学家一样设置你的 A/B 测试,按照这些简单的步骤操作。

towardsdatascience.com

我还强烈推荐免费书籍《统计学习导论:R 语言应用》(An Introduction to Statistical Learning: With Applications in R)以了解统计学习中的关键主题。书中还涵盖了以下问题:

  • 你能解释一下机器学习中的偏差-方差权衡吗?

  • 你能描述一下什么是过拟合以及在构建预测模型时如何解决它吗?

  • 你能描述一下监督建模和非监督建模之间的区别吗?

  • 你能描述一下什么是交叉验证以及它如何用于模型评估吗?

5. 从错误中学习

Patrick Tomasso拍摄的照片,来自Unsplash

面试过程中最被忽视的部分之一是请求反馈。这是可以理解的,因为大多数情况下,你不会得到答案,或者得到的是自动化(没有用的)回复。

我的建议是把获取反馈看作是一个焦点小组。你需要大约十个好的回复,以确定你需要改进的共同领域,但同样重要的是,找出什么做得好,什么应该保持不变。

另一个我想强调的点是,根据公司面试过程的质量进行自我评估的重要性。是否对不同阶段投入了足够的努力,还是看起来像是匆忙完成的?他们是否根据你预期的标准评估你?他们是否花时间和精力给你反馈?即使今天你没有获得那个职位,你也可以在公司上标记一个星号,以便在未来的申请中指示一个需要避免或值得关注的地方。

最后,不要把拒绝看作是失败。你参加的面试越多,你就会越了解目标职位的要求,同样重要的是,你会越发准备好!就像其他任何事情一样,唯一的提高方式就是通过练习。就像你第一次骑自行车时一样,你不会期望第一次就成功,也不会因为失败而感到尴尬而放弃。

总结

🚀🚀 完成最后一步,我们已经到达了指南的终点。下面,你还可以找到步骤的快速总结:

✅ 确保你对第一个角色的任务和职责有清晰的理解,并使用相关职位描述中的关键词来打造合适的简历(CV)。

✅ 始终以提供业务价值为主要目标来构建你的回答。记住,公司并不单纯寻找统计学或编程的从业者,而是寻找能够从大数据中提供价值的个人。

✅ 练习可能看起来枯燥或重复,但它将对你获得第一个数据科学职位至关重要。

✅ 尽可能地请求反馈,以确定哪些做法有效,哪些需要改进。

保持联系!

如果你喜欢阅读这篇文章并想了解更多内容,不要忘记 订阅,以便直接将我的故事发送到你的收件箱。

在下面的链接中,你还可以找到一个免费的 PDF 指南,介绍如何使用数据科学技术和最佳实践在实际商业场景中完成客户群体分析。

## 数据科学项目检查清单 - 有志数据科学家

我是一名拥有 7 年以上分析经验的数据科学家,目前在英国伦敦的一家游戏公司工作。我的…

www.aspiringdatascientist.net

带什么?——基于协同过滤的物品建议

原文:towardsdatascience.com/what-to-bring-item-suggestions-with-collaborative-filtering-6cd260984330?source=collection_archive---------11-----------------------#2023-10-03

个性化物品建议基于实际数据和真实案例

Malte BleekerTowards Data Science Malte Bleeker

·

关注 发表在 Towards Data Science · 7 min 阅读 · 2023 年 10 月 3 日

--

物品建议(作者提供的图片)

生日聚会、共同旅行或与本地运动俱乐部的夏季聚会——像这些事件很美好,直到你需要自己为准备工作做出贡献。通常,这始于一个非常投入的人,他主动开始并推动事情的进展,但迟早,当已经承诺的项目数量不断增加时,你也不得不问这个问题:我将带什么?

各种类型的活动中常见的物品列表已被大量创建,但总是很难想到一个合适的主意来至少免除你一定的社交义务(通常通过默认的“灵丹妙药”,一瓶酒)。由于我们的网络应用提供了数以万计的此类列表,我们能够通过将其转化为基于已存在列表中的项目来建议有前景的项目,从而应对这一挑战。

我们通过利用数据库中约 10 万份列表与用户当前感兴趣的列表之间的相似性来应对这个挑战。利用这种列表与列表之间的相似性,进而推荐合适的项目,也被称为协同过滤,因为目标是将数据库中可能推荐的海量不同项目过滤成仅几个最合适的(实际上在我们的情况下大约是 10 万种不同的项目)。类似的情况通常可以在如书籍或电影推荐系统中找到,通过利用用户已经观看的内容(在我们的例子中是已添加到列表中的项目)来推荐用户可能错过的电影,这些电影被类似用户观看过(在我们的例子中是已被添加到类似列表中的项目)。

它是如何工作的? — 一个简单的解释

第一步是创建一个表格,行是列表(ID),列是所有项目名称。当我们的所有列表仅包含 20 个唯一单词时,我们只需要 20 列,行数等于列表的数量。每当一个单词出现在列表中时,我们就在相应的列和行中添加值“1”,如果一个单词不在列表中则添加“0”(在文本分析中也称为词袋模型)。我们对要进行建议的列表做相同的操作。

列表-项目矩阵的简单示意图(作者提供的图片)

对于电影或书籍推荐,采用相同的程序,但列会包含数据库中不同的电影或书籍,行会包含不同的用户(ID),值可以指示一本书是否已被阅读,或者它是否以及如何被评分。

可选:相应的 Python 代码(步骤 1)

# Create the list-item matrix
matrix = df.pivot_table(index='id', columns='what', values='value')

# Matrix Dimensions (126.252 x 179.674) 
# Number of unique listIDs:  126252
# Number of unique items ("what"):  179674

这将我们的数据转换为合适的格式,为第二步做好准备——计算数据库中列表与我们希望建议项目的列表之间的相似度。衡量两个行(向量)相似度的最常用方法之一是“余弦距离”或“余弦相似度”。它通过两个行的点积计算,除以两个向量的大小的常规乘积。下面的图形应该使这个计算更易于理解,但这里的重点是对余弦距离的直观理解,对于任何数学上的细节,请参阅这篇文章。请也将下面的代码块视为一个可选但补充的附加部分。

计算两个列表/向量之间的余弦相似度(图像由作者提供)

例如,如果两个列表完全相似,它们的余弦相似度为 1,完全没有共同词的列表相似度为 0,而至少有一些共同词的相似度为 0 < x < 1。余弦相似度值越高,数据库中的列表与我们关注的列表越相似。 有了这一点,我们可以计算我们列表与表中所有其他列表的相似度,为每一行获取一个相似度分数。接下来,我们对这些行进行排序,并提取最相似的行,可以基于预定义的数量(例如最相似的 50 个列表)或相似度阈值(例如 > 0.6)。在我们的案例中,相似度分数的变化很大,取决于关注列表的项目数量及其具体用途,因此我们为了简化操作选择了最相似的 100 个列表(一个经验法则:我们在这里选择的列表越多,我们的建议将越稳定,但也更通用)。我们现在可以创建一个包含原始列表-单词表副本的新表,只包含这 100 个最相似的列表。

可选:对应的 Python 代码(步骤 2)

# Find the index of the listID "TestList" in the matrix
# (the TestList is the list we would like to get suggestions for)
list_index = matrix.index.get_loc(listID)

# Extract the row of the listID "TestList" from the matrix
list_row = matrix.iloc[list_index]

# Calculate the similarity between the listID "TestList" and all other listIDs
similarities = cosine_similarity([list_row], matrix)[0]

# Return the indices of all lists with a similarity greater than 0.6 and store them with the similarities in a list
#similar_list_indices = np.where(similarities > 0.5)[0]

# Return the indices of the 100 most similar lists
similar_list_indices = np.argsort(similarities)[-100:]

# Extract the corresponding similarities
similarity_scores = similarities[similar_list_indices]

# Create a list of tuples with the listID and the similarity
similar_lists = [(listid_dict[i], similarity) for i, similarity in zip(similar_list_indices, similarity_scores)]

# Convert the indices to listIDs
similar_list_ids = [listid_dict[i] for i in similar_list_indices]

# Extract the rows of similar lists from the matrix
recommendation_matrix = matrix[matrix.index.isin(similar_list_ids)]

完成后,接下来是识别这些相似列表中最有前景的条目。首先,我们检查感兴趣列表中已存在的条目,并从表格中删除相应的条目(列)(我们假设在这种情况下用户不希望得到已包含的条目建议)。接下来,最简单的方法是检查这些相似列表中出现频率最高的词,并按降序建议这些词。然而,这样做会对第 99 个最相似列表中的词和最相似列表中的词给予相同的权重。为了解决这个问题,行会乘以之前计算的相似度分数。因此,第 99 个最相似行的值(现在介于 0 和 1 之间)相比最相似行显著较小。基于此,可以计算每列(条目)的加权总和,并建议得分最高的条目。

可选:对应的 Python 代码(步骤 3)

# Find columns with a value of 1 in the 'TestList' row (Items that are already in the list)
columns_to_remove = recommendation_matrix.columns[recommendation_matrix.loc[listID] == 1]

# Drop the identified columns (Do not recommend items already in the list)
recommendation_matrix.drop(columns_to_remove, axis=1, inplace=True)

# Create a dictionary to map listIDs to similarity scores
listid_to_similarity = {listID: similarity for listID, similarity in similar_lists}

# Multiply each row in the recommendation matrix by the corresponding similarity score
recommendation_matrix = recommendation_matrix.apply(lambda row: row * listid_to_similarity.get(row.name, 1), axis=1)

# calculate the sum of each column and sort the values in descending order
recommendations = recommendation_matrix.sum().sort_values(ascending=False)

# Print out the Items with the highest Scores (the most suitable item suggestions)
top_item_recommendations = recommendations.head(10)
print(top_item_recommendations)

就这样了——结合少量数据和简单而强大的计算,如余弦相似度,可以生成合适的个性化建议和推荐。接下来,我将向你展示三次建议模拟的结果,列表中条目还很少(条目和列表大多是从德语翻译过来的……如果有些条目选择对你来说感觉怪异,请见谅)。

三个列表的个性化条目建议模拟(图片作者)

如你所见,几个条目就足以生成反映列表基础主题的个性化建议——一旦处理了特定事件类型的最常见条目,建议会变得更加具体。

一些额外说明:为了防止推荐非常具体的条目名称或可能包含个人信息的条目,我们仅包括在至少 20 个不同列表中出现的条目(列)。我们还排除了包含少于 3 个条目的列表。列表建议功能尚未部署到生产环境中,而只是模拟并在本文描述和测试的 Jupyter Notebook 中测试过。

感谢你对这篇文章的关注,我非常感激所有类型的反馈——祝你一切顺利,保持好奇。

找到异常值后该怎么做

原文:towardsdatascience.com/what-to-do-with-outliers-once-you-find-them-8e4d3d32f228

Bex T.Towards Data Science Bex T.

·发表于Towards Data Science ·阅读时间 5 分钟·2023 年 2 月 15 日

--

图片由Ralf Kunze提供,来源于Pixabay

异常值检测只是故事的一部分。真正的挑战在于弄清楚如何处理这些异常值。很容易就将异常值一笔勾销,但实际情况中有很多细微差别和需要考虑的因素。

盲目删除异常值可能会产生不良后果。虽然发现某种类型的异常值可能暗示数据存在更严重的问题,但检测到另一种类型的异常值可能根本没有问题。因此,重要的是不要做出草率的决定,因为这可能导致数据质量下降或后续机器学习模型的偏差。

今天,我们将从两个角度分析这个问题。首先,我们将根据异常值存在的原因查看适当的行动方案,然后讨论根据数据集中异常值的数量应采取的措施。让我们开始吧!

查看这系列关于异常值检测的早期部分,我们更注重代码方面:

Bex T.

Bex T.

BEXGBoost - 异常值检测

查看列表3 个故事

1. 存在的原因:错误

异常值最常见的原因之一是人为和设备错误。有人搞错了零的个数,按错了键,忘记测量某样东西(或测量了两次),或者故障的仪器产生了不一致的读数;软件故障记录了错误的数据,等等。

作为数据科学家,这些事情超出了你的控制范围,因为它们通常发生在数据收集过程中。第一步适当的行动是尝试修正这些错误的异常值。尝试修正那些错别字或将数字值更改为常识性的替代值(例如,当有人在调查中说自己 200 岁时,你将其更改为 20 岁)。

当无法修正或修正成本过高时,只能过滤掉这些数据,因为你知道它们是不正确的值。

2. 存在原因:抽样错误

统计学家和机器学习工程师使用小样本来对特定目标群体做出结论。然而,在数据收集过程中,不属于该群体的数据点可能会泄漏到收集的样本中。

例如,假设你正在研究你朋友果园中的苹果生长。这个研究定义的总体是果园中的所有苹果树,而样本是 1000 棵随机选择的苹果树。但是,由于它们之间的围栏不太明显,几十棵邻居果园的树木被混入了你的样本中。

虽然邻居的苹果不一定是不正常的,但它们来自不同的群体,可能会扭曲你的整个研究。

当异常值是由于这种抽样错误造成的时,删除它们是唯一的解决办法。

3. 存在原因:自然变异

世界充满了惊喜和不确定性。一些异常值可能突然出现,但仍然是目标群体中固有的自然变异的一部分。

例如,有些人天生拥有特定基因使他们非常高、非常矮、是天才等,或者一些动物能够跳得异常高或寿命远超同类……例子无穷无尽。

如果你抽取了足够大的样本,你肯定会遇到自然分布中的奇异值。它们不一定是问题,但会引入数据的变异性。

虽然删除这些异常值很有诱惑力(因为它们会降低数据的统计显著性),但不能仅仅为了获得更好的指标而这么做。

4. 异常值的数量

处理异常值也会极大地依赖于它们相对于数据集大小的数量。

如果它们只是少数(低于 1%)且你有充足的数据,可以安全地排除它们以保持透明。当然,你必须与收集数据的人或领域实验讨论,以确保它们不是自然变异的一部分。

如果异常值过多,以至于引起怀疑,那么它们的存在可能有某种未知原因。也许它们只是相对于大多数数据点来说是异常值,但实际上是目标人群的关键特征。在这种情况下,你所处理的样本可能并不完全代表其目标人群。

最终的情况是数据中有太多异常值,以至于它们形成了一个新的簇或子群体。在这里,推荐使用相同的方法——分析最初的机器学习或数据科学问题是如何框定的,目标人群和样本是如何选择的,以及为什么会有这么多异常值进入数据集。

如果你不去除异常值,该怎么处理它们?

异常值通常会被删除,以避免它们扭曲特征的均值和标准差,从而最终导致模型性能下降。但在某些情况下,异常值本身也是值得关注的。

异常检测的一些应用包括入侵检测(网络安全)、欺诈检测、故障检测、系统健康监测、传感器网络中的事件检测、生态系统扰动检测、使用机器视觉的图像缺陷检测和医疗诊断。在这些场景中,异常值的性质和存在被广泛研究,以推动业务、隐私和医疗决策。

如果你确实决定去除异常值以提高模型性能、改进视觉效果或统计测试,你应该在方法上保持透明。利益相关者(直接从项目中受益或失去的人)应该被告知这一决定。最好是,你应该提供两个结果:一个包含异常值,另一个不包含。

还有一些非侵入性且轻量级的替代方法。一个流行的方法是百分位修剪,即对超出第一个和第 99 个百分位的极端值进行限制。你可以在 Pandas 或 NumPy 中轻松执行此操作:

import pandas as pd

low = distribution.quantile(0.01)
high = distribution.quantile(0.99)

outlier_free = distribution.clip(low, high)

你也可以用中位数或众数来替代异常值。这可以通过 Pandas 的replace函数或 NumPy 的where函数来完成。

结论

本文的主要目标是强调对异常值采取适当行动的重要性。过去,你可能只是为了更好的指标而盲目删除它们,但现在,你可以根据异常值的类型和数量做出更明智的决定。

查看这系列异常检测的其余文章:

Bex T.

Bex T.

BEXGBoost - 异常检测

查看列表3 stories

感谢阅读!

ibexorigin.medium.com [## 使用我的推荐链接加入 Medium - Bex T.

获取对我所有⚡优质⚡内容和 Medium 上所有内容的独家访问权限,没有限制。通过购买支持我的工作...

ibexorigin.medium.com [## 订阅 Bex T. 的更新

每当 Bex T. 发布文章时,都会向您发送电子邮件。通过注册,如果您还没有 Medium 账户,将为您创建一个...

ibexorigin.medium.com

更多我的文章...

5 个迹象表明你已经成为高级 Pythonista,而自己却没有意识到 ## 5 个迹象表明你已经成为高级 Pythonista,而自己却没有意识到

[towardsdatascience.com [## 5 个优秀的 Julia 特性,Python 开发者只能羡慕

朱莉亚与 Python 辩论的继续

medium.com [## 如何创建高度组织化的 ML 项目,任何人都可以通过 DVC 管道重现

什么是机器学习管道?

pub.towardsai.net

Pandas 2.0 有什么新变化?

原文:towardsdatascience.com/whats-new-in-pandas-2-0-5df366eb0197

关于这次重大发布的五件事

Jeff HaleTowards Data Science Jeff Hale

·发表于 Towards Data Science ·阅读时间 5 分钟·2023 年 4 月 10 日

--

Pandas 2.0 于 2023 年 4 月 3 日正式发布。让我们看看哪些功能比阳光下的柯基还要炙手可热。☀️

来源:pixabay.com

三年前,我写了 Pandas 1.0 有什么新变化。经历了一场大流行和一系列 AI 进展之后,我们迎来了 pandas 2.0。

Pandas 是标准的、脑力友好的 Python 数据处理库。2.0 更新的重点是让 pandas 更快、更节省内存。内存是人们需要离开 pandas 转向 Dask、Ray、SQL 数据库、Spark DataFrames 和其他工具的主要原因。减少内存使用会使 pandas 的使用变得更加轻松。🙂

正如你可能期望的那样,作为一个主要版本,pandas 2.0 有许多显著的变化。让我们深入了解一下!

pyarrow 🐍➡️

如果用一个词来总结这次发布,那就是 pyarrow

Pandas 是使用 NumPy 数据结构进行内存管理构建的。现在,你可以选择使用 pyarrow 作为你的后备内存格式。

使用 pyarrow 意味着你可以加快速度并提高内存使用效率,因为你可以利用 Arrow 的 C++ 实现。有趣的是,pandas 的创始人 Wes McKinney 在 2009 年开源 pandas 后,于 2016 年开始参与 Arrow 的开发。

Arrow 是什么? Sebastian Raschk 解释道,它是“…一种开源且与语言无关的列式数据格式,用于在内存中表示数据。它可以实现进程间的数据零拷贝共享。”

列式数据存储将数据列组装在内存中,从而使得在诸如计算列均值等任务上操作更快。Arrow 数据类型还包含了如空值等有用的概念,如上所述。

使用 pyarrow 的 pandas 比其他 pandas 替代方案更快吗?在一些任务上,Sebastian Raschka 显示 pandas 可能比 polars 更快,polars 是一个相对较新的“Rust 和 Python 的 lightning-fast DataFrame 库”,也使用 Arrow。

然后,polars 库的作者 Ritchie Vink 对 TPCH-10 基准测试 进行了比较测试,这是一个更大、更相关的实际数据测试。请查看以下一些结果和讨论:

来源:twitter.com/RitchieVink/status/1632334005264580608

看起来 pandas 可能还有一段路要走,如果你还没有尝试过,polars 可能值得一试。

如果你觉得需要速度,Numba 是另一个选项。在任何情况下,避免过早优化的普遍建议是合理的。

以下是使用 pyrarrow 后端格式读取 CSV 文件的代码:

pd.read_csv(my_file, dytpe_backend='pyarrow')

如果你想深入了解,Marc Garcia 有一篇不错的文章,介绍了 pandas 内存结构的历史以及 pandas 2.0 中对 pyarrow 的支持(注意,在预发布版本和正式发布之间语法有所更新)。

从一开始就支持可空数据类型

在 pandas 中处理缺失(空)值并不总是那么容易。Pandas 是建立在 NumPy 上的,而 NumPy 对某些数据类型不支持空值。

例如,NumPy 整数数据类型无法支持空值。在整数列中引入空值会导致该列自动转换为浮点数据类型。一分钟列是整数,下一分钟变成浮点数。这至少可以说是不理想的。

Pandas 1.0 为我们提供了可空的数据类型,但使用起来需要一些工作。现在,当你将数据读取到 DataFrame 中时,你可以指定你想要可空的 NumPy 支持的数据类型,如下所示:

pd.read_csv(my_file, dtype_backend="numpy_nullable")

更新:注意,自 2.0 beta 版本以来,这种语法已被更新。

注意,大多数,但不是所有的 read_xxx 函数都支持可空的数据类型。更多信息请见这里

pyarrow 数据类型从一开始就提供了空值支持。

更多 NumPy 数据类型用于索引

现在,你可以为 pandas 索引选择更多的 NumPy 数据类型以减少内存使用。现在你可以选择更低内存的数据类型作为索引。例如,你可以指定索引使用 32 位整数,从而节省之前只能使用 64 位整数时的一半内存。

pd.Index([1, 2, 3], dtype=np.int32)

阅读更多这里

复制-on-写模式

Pandas 变得懒惰了。以一种好的方式。 🙂 大量 DataFrame 和 Series 方法在需要之前不会再创建 pandas 对象的副本。例如,df.head() 不会创建一个包含前五行的新 DataFrame,而只是返回前五行的视图。

这些变化将节省时间和内存。只需使用:

pd.set_option("mode.copy_on_write", True)

你可以通过几种其他方式设置这个行为,因为 pandas 喜欢给你多种方法来完成任务。 ❤️

可安装的额外功能

现在你可以在安装 pandas 时同时安装 pandas 需要的额外 Python 库。例如,运行以下命令将为你提供处理 Google Cloud Platform 和 Parquet 文件格式所需的库。

pip install "pandas[gcp, parquet]==2.0.0"

⚠️ 确保不要忘记引号!

这里是可用的安装选项:

  • all (所有附加功能)

  • performance

  • computation

  • timezone

  • fss

  • aws

  • gcp

  • excel

  • parquet

  • feather

  • hdf5

  • spss

  • postgresql

  • mysql

  • sql-other

  • html

  • xml

  • plot

  • output_formatting

  • clipboard

  • compression

  • test

了解安装的依赖项请访问 这里

Upgrading

要在你的虚拟环境中从 PyPI 安装 pandas 2.0,请使用以下命令进行升级:

pip install -U pandas

现在你已经开始更快、更节省内存的数据处理之旅了! 🎉

Wrap

你已经看到 pandas 2.0 的最大变化了。还有其他变化,比如 read_csv 和类似函数的新日期参数名称。 查看发布帖子了解所有细节

即使有了这些新变化,当你的 pandas DataFrame 没有足够的内存时也会出现问题。针对这种情况,我在 这份指南 中分享了八个帮助你应对的技巧。

如果你是 pandas 新手,可以查看我的入门书籍 Memorable Pandas

希望你觉得这份 pandas 2.0 变化指南对你有帮助。如果有,请分享给其他人,让他们也能找到它! 🚀

我写关于 Python、数据和其他技术话题的文章。如果你对这些感兴趣,跟随我 follow me,这样你就不会错过更新!

来源:pixabay.com

编程愉快!

Pandas 2.1 中的新功能

原文:towardsdatascience.com/whats-new-in-pandas-2-1-d26c0b8314a?source=collection_archive---------2-----------------------#2023-09-07

关于新版本最有趣的功能

Patrick HoeflerTowards Data Science Patrick Hoefler

·

关注 发布于 Towards Data Science ·5 分钟阅读·2023 年 9 月 7 日

--

图片由 Lukas W. 提供,来源于 Unsplash

pandas 2.1 于 2023 年 8 月 30 日发布。让我们来看看这次发布带来了哪些新功能,以及它如何帮助我们改善 pandas 的工作负载。它包含了一系列改进,同时也引入了一些新的弃用功能。

pandas 2.1 在 pandas 2.0 提供的 PyArrow 集成基础上进行了大量构建。我们专注于扩展对预计将成为 pandas 3.0 默认功能的新特性的支持。让我们深入了解这对你意味着什么。我们将详细查看最重要的改进。

我是 pandas 核心团队的一员。我是 Coiled 的开源工程师,在那里我负责 Dask,包括改进 pandas 集成。

避免为字符串列使用 NumPy 对象 dtype

pandas 中一个主要的痛点是低效的字符串表示。这是我们工作了很长时间的一个话题。第一个 PyArrow 支持的字符串 dtype 在 pandas 1.3 中可用。它有潜力将内存使用减少约 70% 并提高性能。我在 我之前的一篇文章 中更深入地探讨了这个话题,其中包括内存比较和性能测量(总结:非常令人印象深刻)。

我们决定引入一个新的配置选项,将所有字符串列存储在 PyArrow 数组中。你不再需要担心转换字符串列,这将直接生效。

你可以通过以下方式启用此选项:

pd.options.future.infer_string = True

这种行为将在 pandas 3.0 中成为默认,这意味着字符串列将始终由 PyArrow 支持。你需要安装 PyArrow 才能使用此选项。

PyArrow 的行为与 NumPy 对象 dtype 不同,这可能会使详细了解变得棘手。我们实现了用于此选项的字符串 dtype,以便与 NumPy 语义兼容。它的行为将与 NumPy 对象列完全相同。我鼓励大家试一试!

改进的 PyArrow 支持

我们在 pandas 2.0 中引入了 PyArrow 支持的 DataFrame。我们的主要目标之一是在过去几个月内改善 pandas 的集成。我们旨在使从 NumPy 支持的 DataFrame 切换尽可能简单。我们关注的一个领域是修复性能瓶颈,因为之前这会导致意外的慢速。

让我们看一个例子:

import pandas as pd
import numpy as np

df = pd.DataFrame(
    {
        "foo": np.random.randint(1, 10, (1_000_000, )),
        "bar": np.random.randint(1, 100, (1_000_000,)),
    }, dtype="int64[pyarrow]"
)
grouped = df.groupby("foo")

我们的 DataFrame 有 100 万行和 10 个组。让我们看一下 pandas 2.0.3 与 pandas 2.1 的性能对比:

# pandas 2.0.3
10.6 ms ± 72.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

# pandas 2.1.0
1.91 ms ± 3.16 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)

在新版本中,这个特定示例的速度快了 5 倍。merge 是另一个常用的函数,现在也会更快。我们希望使用 PyArrow 支持的 DataFrame 的体验会更好。

Copy-on-Write

Copy-on-Write 最初在 pandas 1.5.0 中引入,并预计将在 pandas 3.0 中成为默认行为。Copy-on-Write 在 pandas 2.0.x 上已经提供了良好的体验。我们主要集中在修复已知的错误并提高运行速度。我建议现在在生产中使用此模式。我写了一系列博客文章来解释 什么是 Copy-on-Write 和 它是如何工作的。这些博客文章详细讲解了 Copy-on-Write 的内部工作原理以及你可以期待什么,包括性能和行为。

我们已经看到 Copy-on-Write 可以将实际工作流的性能提高超过 50%。

弃用在 setitem 类操作中的静默上升类型转换

历史上,如果你将不兼容的值设置到列中,pandas 会静默更改其中一个列的数据类型。让我们来看一个例子:

ser = pd.Series([1, 2, 3])

0    1
1    2
2    3
dtype: int64

我们有一个包含整数的 Series,这将导致数据类型为整数。让我们将字母 "a" 设置到第二行:

ser.iloc[1] = "a"

0    1
1    a
2    3
dtype: object

这将把你的 Series 的数据类型更改为 object。Object 是唯一可以同时包含整数和字符串的数据类型。这对很多用户来说是一个重大困扰。Object 列占用大量内存,计算将无法进行,性能下降以及其他许多问题。它还在内部增加了许多特殊处理来适应这些问题。在过去,DataFrame 中的静默数据类型更改曾让我非常烦恼。这个行为现在已被弃用,并将引发 FutureWarning:

FutureWarning: Setting an item of incompatible dtype is deprecated and will raise in a future 
error of pandas. Value 'a' has dtype incompatible with int64, please explicitly cast to a 
compatible dtype first.
  ser.iloc[1] = "a"

像我们的例子这样的操作将在 pandas 3.0 中引发错误。DataFrame 的列数据类型将保持一致。你需要在想要更改数据类型时明确指出,这增加了一些代码,但使得未来的开发者更容易理解。

这一变化影响所有的数据类型,例如,将浮点值设置到整数列中也会引发错误。

升级到新版本

你可以通过以下方式安装新的 pandas 版本:

pip install -U pandas

或:

mamba install -c conda-forge pandas=2.1

这将为你的环境提供新的发布版本。

结论

我们已经查看了一些改进,这些改进将帮助你编写更高效的代码。这包括性能改进、更容易选择 PyArrow 支持的字符串列以及进一步改进 Copy-on-Write。我们还看到了一项弃用,这将使 pandas 在下一个主要版本中更易于预测其行为。

感谢阅读。欢迎随时联系分享你的想法和反馈。

2023 年的分析领域接下来会发生什么?

原文:towardsdatascience.com/whats-next-for-analytics-in-2023-875a5fe94171?source=collection_archive---------20-----------------------#2023-01-06

分析团队会在 2023 年征服分析的最后一公里吗?

João António SousaTowards Data Science João António Sousa

·

关注 发布于 Towards Data Science ·6 min read·2023 年 1 月 6 日

--

我对年末总结和预测总是充满热情。这是一个从日常琐事中抽身,查看全局的绝佳时机。我喜欢阅读同行和行业领袖关于学习和趋势的文章,花时间回顾我的一年,并为下一年做计划。所以我想分享一下我对明年数据分析领域重点关注内容的看法。

图片由 wirestock 提供,来源于 Freepik

对大多数人来说,2022 年并不轻松。由于经济衰退,我们目睹了大量裁员和预算削减。“以少量资源做更多事情”成为了我们大家越来越常用的短语。我预计这将成为 2023 年的座右铭。

因此,我预测将会更加关注效率、商业价值和分析团队的投资回报率最大化。因此,只有那些能够提供以下结果的项目和技术将会受到优先考虑:

  • 帮助团队节省时间和资源,提高效率

  • 帮助团队节省收入和降低成本,最大化数据与分析的投资回报率。以下是我对明年一些重要分析趋势的预测(不按特定顺序)。

预测 #1 —— 专注于证明分析的投资回报率

数据驱动的公司在过去几年中在技术和人员上进行了大量投资。最初,他们的重点是收集、存储、管理、转换和展示数据,以建立强大的核心。

数据质量对于创造有意义的结果至关重要,但仅有数据质量还不足以创造商业价值。如果我们将数据分析之旅视为马拉松,将商业影响视为奖牌,提供能够指导日常和战略决策的可操作性见解是完成比赛的必备条件。因此,这也是领导者将注意力转向最大化投资回报率的原因。

那么你如何达到目标呢?

  • 与业务团队的更紧密合作(例如,共同确定优先级用例,进行每日/每周性能评审以审查和分享见解)

  • 分析中的速度和全面性以真正赋能决策

  • 强调衡量商业价值和持续迭代以实现最佳结果

预测 #2 —— 大多数决策将通过机器学习(ML)得到增强

为了跟上数据和业务的步伐,“用更少做更多”的口号再次浮现。企业需要增强工作流程和自动化琐碎任务,加快洞察速度,打破速度与全面性的权衡,以创造真正的商业价值并最大化数据分析的投资回报率。

使用数据做出的决策可以通过各种方式实现自动化,并且介于主要依赖人工和完全自动化之间。Gartner 预测,到 2025 年,目前使用数据的 95%的决策将至少部分实现自动化。在人工智能时代,拥抱一定程度的决策自动化的组织有可能通过更快速、复杂和细化的决策来获得竞争优势。

在商业智能(BI)中,大多数决策很快将得到增强。我在大多数数据驱动的公司中看到的两个主要使用场景是:

  • 人工参与的诊断分析:使用机器学习测试数据中的每个假设并评估关键业务指标变化的驱动因素。人类可以专注于筛选出最相关的因素并做出决策

  • 针对关键业务指标变化的自动警报,以自然语言通过 Slack/Teams 传递

预测 #3 — 数据与分析角色将进一步专业化

随着职业的逐渐成熟和复杂化,进一步的专业化往往会发生。这是一种自然的演变,分析领域也不会例外。

当前,数据与分析团队的角色主要基于他们在数据分析工作流中负责的阶段进行分段。

  • 数据工程师负责数据管道的建设。

  • 分析工程师负责清理数据。

  • 数据分析师和科学家从数据中提取洞察。

这些核心角色将继续存在,但会进一步细分,专注于特定的业务问题和目标。

  • 分析工程师的角色将继续增长,确保数据建模并向数据分析师和业务用户提供清洁的数据集。这一趋势也释放了数据分析师的工作负担。

  • 数据分析师将更贴近业务,专注于揭示洞察和改善决策,成为值得信赖的顾问,最大化业务影响。

  • 数据产品经理的角色将继续增长,推动数据产品的采用和货币化。

  • 分析翻译员的角色将继续增长,以缩小数据素养差距,并最大化分析用例的价值。

预测 #4 — 数据网格用于数据民主化和可扩展性

数据网格已成为数据讨论中的热词。但是什么促成了这一趋势?对数据架构的民主化和可扩展性的渴望。

许多组织仍在挣扎,因为他们的架构选择是由技术驱动的,而非业务需求。数据网格旨在通过在组织内部联合数据所有权,并专注于效率、创新和透明度来解决这个问题。

这创造了一种分布式、去中心化的数据处理方式,使得分享和创建数据产品变得更快。数据产品由独立的跨职能团队拥有,但遵循中央治理以确保互操作性和一致性。

打破孤岛、提高数据的重用性并推动创新,数据网格和以业务问题为导向的架构将是那些希望更好地利用数据的公司发展的方向。

预测 #5 — 分析团队将“可操作洞察的速度”定义为北极星指标

大多数数据驱动的答案需要几天甚至几周。由于公司现在可以近乎实时地获取数据,决策延迟成为当前分析的瓶颈。随着业务变化速度的加快,这些答案并未以业务的速度出现。这种反应式的方法带来了显著的成本:直接的负面业务影响、削弱的数据文化以及导致员工流失的恶性循环。

改善这一情况已成为许多分析团队的首要任务。顶尖的分析团队已将“可操作洞察的速度”定义为他们的北极星指标,以确保行动性,最大化业务影响,并提升数据文化。

可操作洞察的速度是一个简单的概念:从业务问题到数据驱动的决策或行动的时间。它已经包括了通常需要的多个迭代。这样,分析团队不仅专注于回答问题,而是主动与业务部门合作,推动可操作的洞察。

这推动了诸如增强型业务根本原因分析和由机器学习(ML)驱动的自动警报和洞察信息等创新。这确保了团队利用所有可用的数据,主动以业务的速度提供分析。

预测 #6 — 数据法规将成为关注重点

欧盟 GDPR、加拿大 PIPEDA 和中国 PIPL 等法规促使公司重新思考他们收集和处理数据的方式。我——以及像 Gartner 这样的分析机构——期望在 2023 年看到更多国家出台新的规则和立法。

这意味着需要更多的工作来赢得客户的信任,使他们更愿意分享他们的信息。为此,企业需要更好地结构化、记录和创造更多的透明度,来处理和处理数据。此外,有效的数据治理将变得更加相关。根据合规阶段,这可能意味着需要对现有数据进行一些回顾性工作,包括数据的收集和存储方式以及使用情况。

这也许不是列表中最令人兴奋的预测,但却是在最大化数据价值、遵守安全标准以及防止任何违规和罚款方面至关重要的预测。

结论

对于那些将强烈关注投资回报率(ROI)并且不浪费任何资源或时间的团队来说,他们将会是赢家。我希望看到分析团队与业务部门紧密合作,专注于数据分析、洞察生成,并采取行动以最大化业务价值。我期望数据基础项目在除非它们是关键的或带来显著成本节约的情况下会被降级优先级。

参考资料:

Gartner, 想要成为数据驱动型组织?从 5 项关键数据与分析计划开始

当 AI 走错路时:现实世界中的高-profile 机器学习失误

原文:towardsdatascience.com/when-ai-goes-astray-high-profile-machine-learning-mishaps-in-the-real-world-26bd58692195

一次对引起全球关注的臭名昭著的机器学习失误和失败的巡礼

Kenneth LeungTowards Data Science Kenneth Leung

·发表于 Towards Data Science ·阅读时间 6 分钟·2023 年 8 月 19 日

--

照片由 NEOM 提供,Unsplash

人工智能 (AI) 和机器学习的变革潜力经常成为新闻头条,报告了它在医疗、金融等各个领域的积极影响。

然而,没有任何技术是免疫于失误的。虽然成功的故事描绘了机器学习的奇妙能力,但同样重要的是强调其陷阱,以便理解其影响的全貌。

在本文中,我们探讨了许多高-profile 机器学习失误,以便为未来更有信息化的实施提供借鉴。

目录

特别是,我们将查看以下每个类别中的一个值得注意的案例:

(1) 经典机器学习(2) 计算机视觉(3) 预测(4) 图像生成(5) 自然语言处理(6) 推荐系统

可以在以下 GitHub 仓库 Failed-ML 中找到高-profile 机器学习失误的全面汇编:

[## GitHub — kennethleungty/Failed-ML: 高-profile 现实世界案例汇编

github.com](https://github.com/kennethleungty/Failed-ML?source=post_page-----26bd58692195--------------------------------)

(1) 经典机器学习

标题

亚马逊 AI 招聘系统: 亚马逊的人工智能驱动的自动招聘系统在出现对女性候选人的歧视证据后被取消。

细节

亚马逊开发了一款由人工智能驱动的招聘工具,以从十年的简历中识别顶尖候选人。然而,由于科技行业主要由男性主导,该系统对女性申请者表现出了偏见。

例如,它开始降级包含“女性”一词的简历或来自两所女性专用学院的毕业生的简历,同时偏爱某些术语(例如“执行”),这些术语在男性简历中出现频率更高。

亚马逊尝试纠正这些偏见,但在消除歧视性倾向方面面临挑战。因此,他们在 2017 年初终止了该项目,强调该系统从未用于实际候选人评估。

关键课程

训练数据中的偏见可能会在机器学习模型中延续,并导致人工智能系统中出现意想不到和歧视性的结果,这强调了多样化和具有代表性的数据集的重要性。

报告链接

## 亚马逊据报取消了一个 AI 招聘系统

详细信息

(2) 计算机视觉

标题

谷歌糖尿病视网膜病检测 AI: 该视网膜扫描工具在现实环境中的表现远不如在控制实验中的表现,问题包括由于扫描质量差而拒绝的扫描和因间歇性互联网连接导致的上传图像到云端的延迟。

细节

谷歌健康在泰国的 11 个诊所安装了一套深度学习系统,用于识别糖尿病患者眼部疾病的迹象。在实验室测试中,该系统能够以超过 90%的准确率从眼部扫描中识别糖尿病视网膜病,并在不到 10 分钟内给出结果。

然而,当实际部署时,由于图像质量差,AI 系统常常无法给出结果,拒绝了超过五分之一的图像。

当护士认为被拒绝的扫描没有显示出疾病迹象,或当他们不得不重拍和编辑 AI 系统拒绝的图像时,他们感到非常沮丧。几家诊所的糟糕互联网连接也导致了将图像上传到云端处理的延迟。

关键课程

重要的是将 AI 工具量身定制以适应现实环境的具体条件和限制,包括图像质量和离线可用性等因素。

参考资料

## 谷歌的医疗 AI 在实验室中的准确性非常高,但现实生活却完全不同。

www.technologyreview.com

(3) 预测

标题

Zillow 即时购买(iBuying)算法:由于其机器学习模型对房产估价的价格过高估计,Zillow 在房屋翻转业务中遭受了重大损失。

详细信息

像 Zillow 这样的房地产公司一直在使用 iBuying 商业模式,即直接从卖家那里购买房屋,然后在进行一些小修小补后重新挂牌出售。

Zillow 购买任何房屋的第一个步骤是“Zestimate”——基于一个在数百万次房屋估价上训练的模型的机器学习辅助的未来市场价值估算,并依赖于如房屋状况和邮政编码等数据。

然而,Zillow 的系统误判了未来的房价,导致他们向房主提出了许多高于市场的报价,特别是在 COVID-19 大流行引起的房地产波动期间。

这种误判最终导致了 Zillow 的即时购买操作的关闭,预计损失达到 3.8 亿美元。

关键教训

持续的模型监控、评估和再训练至关重要,以确保捕捉到新事件引起的数据漂移(导致测试数据分布的变化),以便进行最新的预测。

参考

## 为什么 Zillow 无法使算法房价定价成功

www.wired.com

(4) 图像生成

标题

Stable Diffusion(文本到图像模型):Stable Diffusion 在生成的数千张与职位名称和犯罪相关的图像中表现出种族和性别偏见。

详细信息

彭博社对 5000 多张使用 Stable Diffusion 生成的图像进行分析,发现了显著的种族和性别偏见。

使用 Fitzpatrick 皮肤分级标准进行分类,他们发现高薪职位的图像主要展示了肤色较浅的主体,而肤色较深则与“快餐工人”等低薪职业相关联。

同样,性别分析显示,每描绘一名女性的图像几乎会有三张图像描绘男性,大多数高薪职位的代表都是肤色较浅的男性。

Stable Diffusion 从 LAION-5B 获取数据,这是全球最大的公开可用图像-文本数据集,来自各种在线网站,包括暴力、仇恨符号等的描绘。

关键课程

审计用于机器学习的数据至关重要。例如,如果描绘放大刻板印象的图像通过增强训练数据回流到未来的模型中,下一代文本到图像模型可能会变得更加有偏见,形成偏见的滚雪球效应。

参考

www.bloomberg.com/graphics/2023-generative-ai-bias

(5) 自然语言处理

标题

ChatGPT 引用: 一名律师使用流行的聊天机器人 ChatGPT 来补充他的研究发现,但提供了完全虚构的不存在的过去案例。

细节

当一名名为史蒂文·施瓦茨的律师使用 ChatGPT 来协助准备与航空公司过失有关的伤害诉讼的法院文件时,事情很快出了岔子。

他提交的简报中包含了几项所谓相关的法院裁决引用,但航空公司的律师和主审法官都无法找到这些引用的裁决。

从事法律工作三十年的施瓦茨承认使用 ChatGPT 进行法律研究,但对其可能产生虚假内容一无所知。他甚至要求 ChatGPT 验证案件的有效性,而 ChatGPT 错误地确认了这些案件的存在。

关键课程

仅仅依赖像 ChatGPT 这样的生成模型的输出而不进行人工验证,可能导致重大不准确,突显了人类监督(即“人类在环”系统)和与可信来源交叉验证的必要性。

参考

[## 当你的律师使用 ChatGPT 时会发生什么

www.nytimes.com](https://www.nytimes.com/2023/05/27/nyregion/avianca-airline-lawsuit-chatgpt.html?source=post_page-----26bd58692195--------------------------------)

(6) 推荐系统

标题

IBM Watson 在肿瘤学中的应用: IBM 的 Watson 据称为癌症患者提供了大量不安全和不正确的治疗建议。

细节

曾被视为癌症研究的未来,IBM 的 Watson 超级计算机据报导已对癌症治疗提出了不安全的建议。

一个显著的例子是,它建议给一位重度出血的癌症患者用一种可能加重出血的药物。然而,这一建议被指出是理论性的,并未应用于实际患者。

根本问题源于输入 Watson 的数据的性质。IBM 的研究人员一直在输入假设性或“合成”案例,以使系统能够在更广泛的患者场景上进行训练。

然而,这也意味着许多建议主要基于提供数据的少数医生的治疗偏好,而不是从真实患者案例中得出的见解。

关键课程

训练数据的质量和代表性在机器学习中至关重要,尤其是在医疗等关键应用中,以避免偏见和潜在的有害结果。

参考资料

[## IBM 的 Watson 提供了不安全的癌症治疗建议

www.theverge.com

总结

虽然机器学习带来了许多好处,但我们必须记住它并不完美,正如本文中的众多实际错误所示。我们必须从这些错误中学习,以便未来更好地利用 AI 和机器学习。

查看这个 GitHub 仓库,获取完整的机器学习错误汇编。

在你离开之前

欢迎加入我的数据科学探索之旅! 关注我的Medium页面,并访问我的GitHub,以获取更多引人入胜和实用的内容。与此同时,祝你在探索机器学习中的成功与失误时玩得愉快!

## 在本地 CPU 上运行 Llama 2 进行文档问答

清晰解释如何使用 LLama 2、C Transformers、GGML 在 CPU 上运行量化开源 LLM 应用程序……

[towardsdatascience.com ## 微平均、宏平均和加权平均 F1 分数,清晰解释

理解 F1 分数的微平均、宏平均和加权平均背后的概念……

[towardsdatascience.com [## 为你的 Medium 帖子创建可点击的目录

创建动态目录的简单技巧,允许读者轻松滚动导航

medium.com

posted @ 2024-10-12 19:56  绝不原创的飞龙  阅读(184)  评论(0)    收藏  举报