从头开始编码线性回归
使用 python 从零开始实现线性回归
这篇文章是“基础与超越”系列中的线性回归文章的后续,所以如果你刚刚开始机器学习,我建议你先看完那篇文章,然后从这篇教程开始。如果你已经知道什么是线性回归,那么让我们开始吧!
https://medium.com/analytics-vidhya/basics-and-beyond-linear-regression-c12d99a4df35
在本帖中,我们将使用 python 从头开始编写整个线性回归算法,所以今天我们真的要动手了!
我们走吧!
数据
任何机器学习问题的第一步都是获取数据。如果没有可以“学习”的东西,就没有机器“学习”。因此,在本教程中,我们将使用一个非常常见的数据集进行线性回归,即房价预测数据集。数据集可以在 这里找到 。
这是一个包含俄勒冈州波特兰房价的简单数据集。第一栏是房子的大小(平方英尺),第二栏是卧室的数量,第三栏是房子的价格。您可能已经注意到,我们的数据集中有多个要素(即 house_size(以平方英尺为单位)和房间数量),因此我们将查看多元线性回归,标签( y )将是房价,因为这是我们将要预测的价格。
让我们定义加载数据集的函数:
稍后我们将调用上面的函数来加载数据集。该函数返回 x 和 y (注意 x 由数据集的前 2 列组成,而 y 是数据集的最后一列,因为它是价格列,因此为了返回 x 和 y ,我们将分别从函数中返回data[:,:2]
和data[:,-1]
)。
标准化数据
上面的代码不仅加载数据,而且对其进行归一化并绘制数据点。我们一会儿会看一下数据图,但首先让我们理解上面的normalize(data)
行是干什么的。如果您查看 原始数据集 ,您会注意到第二列中的值(即房间数量)比第一列中的值(即房屋大小)小得多。我们的模型不会将这些数据作为房间数量或房屋大小来评估。对于模型来说,它只是数字。这可能会在您的机器学习模型中产生一种不必要的偏向,即偏向数值比其他列(或特征)高的列。它还会造成方差和数学平均值的不平衡。出于这些原因,也为了使工作更容易,建议您缩放或归一化您的要素,使它们都位于相同的范围内(例如[-1 比 1]或[0 比 1])。这使得训练更加容易。因此,出于我们的目的,我们将使用特征归一化,从数学意义上来说,它意味着:
Z = (x — μ) / σ
μ:平均值
σ:标准偏差
在上面的公式中 z 是我们的归一化特征, x 是非归一化特征。如果你对这些数学概念不是很熟悉,也不用担心。快速回顾会让你开始行动。好了,现在我们有了归一化公式,让我们做一个归一化函数:
这段代码正是我们所讨论的。它遍历每一列,并使用这些元素的平均值和标准偏差对该列的所有数据元素进行标准化。
绘制数据
现在,在我们开始编写线性回归模型之前,我们需要问的一件事是为什么?
为什么我们要用线性回归来解决这个问题?这是一个非常有效的问题,在实际跳到任何具体的代码之前,你应该非常清楚你想要使用什么算法,以及对于给定的数据集和你试图解决的问题,那个是否真的是最好的选择。我们可以证明为什么使用线性回归对我们当前的数据集有效的一种方法是绘制它。为此,我们在上面的load_data
中调用了plot_data
函数。现在让我们定义plot_data
函数:
该函数在被调用时会生成以下图形:
房屋面积与房价的关系图(图片来源:作者提供)
你可以看到,通过上面的图可以大致拟合出一条线。这意味着一个线性近似将实际上允许我们做出相当准确的预测,因此我们选择线性回归。
现在我们已经准备好了数据,让我们进入有趣的部分。编码算法!
假设
首先,我们需要定义我们的假设函数是什么样的,因为我们以后会用这个假设来计算成本。我们知道对于线性回归我们的假设是:
hθ(x) = θ0 + θ1x1 + θ2x2 + θ3x3 +……+ θnxn
然而,我们的数据集只有 2 个特征,因此对于我们当前的问题,假设是:
hθ(x) = θ0 + θ1x1 + θ2x2
其中 x1 和 x2 为两个特征(即房屋大小和房间数量)。让我们将它放入一个简单的 python 函数中,该函数返回假设:
矩阵乘法是怎么回事?!不要担心,它仍然给我们相同的假设方程,我们将在这篇文章的后面更深入地研究为什么这在数学上是正确的。
好了,现在我们有了假设函数,下一个重要的是成本函数。
价值函数
为了评估我们模型的质量,我们使用了成本函数。同样,这篇文章是以下内容的“代码版本”:
https://medium.com/analytics-vidhya/basics-and-beyond-linear-regression-c12d99a4df35
因此,如果这里有什么不明白的地方,你可以浏览一下,或者跟着这两篇文章走。好了,成本函数的等式是:
来源:霍尔豪斯
我们成本函数的代码是:
仔细观察,您可能会注意到,到目前为止我们定义的所有 python 函数都与我们之前为线性回归定义的数学方法完全相同。现在我们有了成本,我们必须最小化它,为此我们使用…是的,梯度下降!
梯度下降
在我们的上下文中,梯度下降是一种优化算法,旨在调整参数以最小化成本函数。
梯度下降的主要更新步骤是:
来源:霍尔豪斯
所以我们把代价函数的导数乘以学习率( α) ,再从参数的现值( θ )中减去,得到新的更新参数( θ )。
gradient_descent
函数返回theta
和J_all
。theta
显然是我们的参数向量,其包含假设的 θs 的值,并且J_all
是包含每个时期之后的成本函数的列表。J_all
变量并不完全是必需的,但是它有助于更好地分析模型,你将在后面的文章中看到。
把所有的放在一起
现在剩下要做的就是按照正确的顺序调用我们的函数:
我们首先调用load_data
函数来加载 x 和 y 的值。 x 包含训练示例,而 y 包含标签(在我们的例子中是房价)。
你可能已经注意到,在整个代码中,我们一直在使用矩阵乘法来实现我们想要的表达式。例如,为了获得假设,我们必须将每个参数( θ )与每个特征向量( x )相乘。我们可以使用进行循环,循环每个示例,每次都执行乘法。但是,如果我们有 1000 万个训练示例,这将不是最有效的方法。这里更有效的方法是使用矩阵乘法。如果你对矩阵乘法不是很熟悉,我建议你 复习一遍 ,它相当简单。对于我们的数据集,我们有两个特征(即房屋大小和房间数量),因此我们将有(2+1) 3 个参数。额外的参数 θ0 可以通过考虑假设在图形意义上只是一条线来说明。所以额外的 θ0 说明这条线是符合要求的。
有利假设函数图(来源:图片由作者提供)
好了,我们有 3 个参数和 2 个特征。这意味着我们的 θ 或参数向量(一维矩阵)将具有维度(3,1),但是我们的特征向量将具有维度(46,2){根据我们的数据集}。你可能已经注意到,这两个矩阵相乘在数学上是不可能的。让我们再次看看我们的假设:
hθ(x) = θ0 + θ1x1 + θ2x2
如果你仔细观察,它实际上是非常直观的,如果我们在我们的特征向量(x)的开始添加一个额外的 1 的列{使它具有维度(46,3)}并且如果我们对 x 和θ执行矩阵乘法,我们实际上将得到上面的等式 hθ(x)。如果还是不明显,那就试着在纸上画一个例子。
请记住,当我们实际运行代码来实现这个函数时,我们不会返回类似于 hθ(x) 的表达式,而是返回这个表达式所计算出的数学值。
在上面的代码中,x = np.hstack((np.ones((x.shape[0],1)), x))
行在 x 的开头添加了一列额外的 1,以允许所需的矩阵乘法。
在这之后,我们用零初始化θ向量。你也可以用一些小的随机值初始化它。我们还指定学习速率和我们想要训练的时期数(时期是算法将遍历整个数据集的次数)。
一旦我们定义了所有的超参数,我们调用梯度下降函数,它返回所有成本函数的历史和参数的最终向量theta
。这个theta
向量本质上定义了我们的最终假设。您可能会注意到梯度下降函数返回的theta
向量的形状具有维度(3,1)。还记得我们的假设函数吗?
hθ(x) = θ0 + θ1x1 + θ2x2
我们需要 3 个 θs ,我们的theta
向量的维数是(3,1),因此theta[0]
、theta[1]
和theta[2]
实际上分别是 θ0、θ1 和 θ2 。J_all
变量只不过是所有成本函数的历史。您可以打印J_all
数组来查看成本函数如何在每个梯度下降的时期逐渐降低。
成本与时代数量的关系图(来源:作者提供的图片)
可以通过定义和调用 plot_cost 函数来绘制此图,如下所示:
现在,我们可以使用这些参数来查找标签,即给定房屋大小和房间数量的任何房屋(在俄勒冈州波特兰市)的价格。
试验
现在,您可以调用一个测试函数来测试您的代码,该函数将房子的大小、房间的数量以及由我们的线性回归模型返回的最终theta
向量作为输入,并将给出房子的价格。
完整的代码
就是这样!
信不信由你,这就是线性回归编码的全部内容。恭喜你!现在,您已经完全从头开始成功地编写了一个线性回归模型。能够理解并编码整个算法并不容易,所以你可以为自己的成功感到自豪。线性回归通常是我们开始机器学习的第一个算法,所以如果你理解我们在这里做的事情,我建议你选择另一个数据集(用于线性回归),并尝试自己应用线性回归。快乐编码:)
参考
您可以在此找到完整的代码和数据集,以供参考:
https://github.com/kumudlakara/Medium-codes/tree/main/linear_regression
- https://medium . com/analytics-vid hya/basics-and-beyond-linear-regression-c 12d 99 a4 df 35
- https://www.coursera.org/learn/machine-learning/home/
- 【https://www.holehouse.org 号
从头开始编码逻辑回归
使用 python 从零开始实现逻辑回归。
这篇文章是“基础知识及以后”系列中的逻辑回归文章的后续。因此,如果你是机器学习的新手,那么我建议你先浏览一下这篇文章,但是如果你已经知道什么是逻辑回归,那么让我们开始工作吧!
https://medium.com/analytics-vidhya/basics-and-beyond-logistic-regression-34549d2ee800
在这篇文章中,我们将使用 python 编写一个逻辑回归模型。所以让我们开始吧!
数据
任何机器学习算法的核心都是数据。你的机器学习模型总是需要数据来“学习”。因此,为了我们今天的目的,我们将使用一个非常简单的学生录取结果数据集,可以在这里找到https://github.com/kumudlakara/Medium-codes/blob/main/logistic_regression/student_result_data.txt。
该数据集包含申请者的历史记录。一个记录包括申请人在两次入学考试中的成绩和最终的录取决定(无论该考生是否被录取)。我们今天的目标是建立一个逻辑回归模型,它将能够决定(或者更好地分类)一个申请人是否应该被录取。在我们的数据集中,前两列是两个测试中的标记,第三列是以二进制编码的决策标签( y )(即 y = 1,如果允许,而 y = 0,如果不允许)。我们的目的是预测这个标签 y 。
好了,现在我们知道了数据的样子,让我们定义一个函数来加载数据。
稍后我们将调用上面的函数来加载数据集。该函数返回 x 和 y (注意 x 由数据集的前 2 列组成,而 y 是数据集的最后一列,因为它是结果列,因此为了返回 x 和 y ,我们将从函数中分别返回data[:,:2]
和data[:,-1]
)。
您可能已经注意到了load_data
函数中的另一个函数调用:plot_data(data[:, :2], data[:, -1])
。如果你已经阅读了“从头开始编码线性回归”这篇文章,你可能已经知道这个函数在做什么,你可以直接跳到这篇文章有趣的编码部分,但是如果你还没有,那就留下来,因为我们将要更深入地研究我们数据的分布。
绘制数据
在我们开始编码我们的模型之前,让我们花一点时间来分析我们的数据。这将允许我们理解为什么(如果有的话)逻辑回归是我们给定数据集和相关问题的出路。
为了可视化数据,让我们定义从load_data
调用的plot_data
函数。
该函数在被调用时会生成以下图形:
数据图(来源:图片由作者提供)
只需快速浏览一下上面的图,就可以清楚地看到,我们的数据确实有一个决策边界,在这种情况下,它似乎是一条直线。这里需要特别注意的是,我们的决策边界很简单,因为我们的数据集恰好分布在决策边界近似为一条直线的地方。需要注意的是,逻辑回归可以用来预测比我们当前问题所显示的更复杂的决策边界。使用逻辑回归甚至可以预测椭圆和非几何决策边界。
唷,那是很难接受的。好了,现在我们已经准备好数据,让我们开始编码实际的线性回归模型!
假设
定义模型架构的第一步是定义假设。我们知道线性回归的假设实际上是 sigmoid 函数,所以从数学上讲,我们的假设是:
来源:作者
sigmoid 函数看起来像这样:
sigmoid 函数图(来源:图片由作者提供)
现在让我们定义一个简单的 python 函数,它反映了数学等式:
我们将该函数命名为 sigmoid,而不是 hypothesis 或 h ,当您在程序的后面部分看到该函数在语句中被调用时,例如在h = sigmoid(x@theta)
中,这将变得更加直观。
好了,现在我们有了假设,让我们进入下一步,即成本函数。
价值函数
为了评估我们的模型输出的质量,在我们的例子中是 y =1(承认)或 y =0(拒绝),我们使用了成本函数。
如果你感到有点失落,你可以随时关注“基础和超越:逻辑回归”的帖子,因为这个帖子正是那个帖子的代码版本。
**https://medium.com/analytics-vidhya/basics-and-beyond-logistic-regression-34549d2ee800
好了,为了我们的目的,让我们直接跳到逻辑回归的成本函数方程:
逻辑回归的成本函数(来源:作者)
同样的代码是:
看到我们在每个训练示例中单独使用矩阵乘法而不是实际求和,这可能看起来很荒谬。使用矩阵乘法实际上达到了同样的结果。我们将在稍后的文章中讨论这个问题。
现在我们有了成本函数,接下来呢?我们的目标是总是最小化我们模型的成本,所以如果我们有了成本函数,我们就有可能找到最小化它的方法。有许多方法(有些甚至比我们将要使用的方法更有效)来最小化成本函数,但是因为我们在这里的目的是完全从头开始编码,所以我们将编码梯度下降算法来最小化成本函数,而不是使用“开箱即用”的优化器。那么让我们直接进入梯度下降。
梯度下降
在我们的上下文中,梯度下降是一种优化算法,旨在调整参数以最小化成本函数。
梯度下降的主要更新步骤是:
来源: holehouse
这里我们可以看到这个算法其实和线性回归的算法是一样的。然而,唯一的区别是假设函数 h(x) 的定义,它是逻辑回归情况下的 sigmoid 函数。于是我们把代价函数的导数乘以学习率( α) ,再从参数的现值( θ )中减去,得到新的更新参数( θ )。让我们用 python 再说一遍:
gradient_descent
函数返回theta
和J_all
。theta
显然是我们的参数向量,其包含假设的 θs 的值,而J_all
是包含每个时期之后的成本函数的列表。J_all
变量并不完全是必需的,但它有助于更好地分析模型,你将在后面的文章中看到。
把所有的放在一起
现在我们已经定义了所有的函数,我们需要做的就是以正确的顺序调用它们。
我们首先调用load_data
函数来加载 x 和 y 的值。 x 包含训练样本, y 包含标签(在我们的例子中是录取结果)。
你可能已经注意到,在整个代码中,我们一直在使用矩阵乘法来实现我们想要的表达式。例如,为了得到假设,我们必须将每个参数( θ )与每个特征向量( x )相乘,并将其传递给 sigmoid 函数。我们可以使用 for loops for this,并在每个示例上循环,每次都执行乘法,但是如果我们有 1000 万个训练示例,这将不是最有效的方法。这里更有效的方法是使用矩阵乘法。如果你对矩阵乘法不是很熟悉,我建议你 复习一遍 ,它相当简单。对于我们的数据集,我们有两个特征(即申请人在两次测试中的分数),因此我们将有(2+1) 3 个参数。额外的 θ0 说明我们的决策边界(在我们的例子中是一条近似的线)是必需的。
有利假设函数图(来源:作者图片)
好的,我们有 3 个参数和 2 个特征。这意味着我们的 θ 或参数向量(一维矩阵)将具有维度(3,1),但是我们的特征向量将具有维度(99,2){根据我们的数据集}。你可能已经注意到,这两个矩阵相乘在数学上是不可能的。然而,如果我们在特征向量的开头添加一列额外的 1,我们将得到两个维度为(99,3)和(3,1)的矩阵。这两个矩阵现在在尺寸上是兼容的。
在上面的代码中,x = np.hstack((np.ones((x.shape[0],1)), x))
行在 x 的开头添加了一列额外的 1,以便根据需要进行矩阵乘法。
在这之后,我们用零初始化θ向量。你也可以用一些小的随机值初始化它。我们还指定学习速率和我们想要训练的时期数(时期是算法将遍历整个数据集的次数)。
一旦我们定义了所有的超参数,我们调用梯度下降函数,它返回所有成本函数的历史和参数的最终向量theta
。这个theta
向量本质上定义了我们的最终假设。您可能会注意到梯度下降函数返回的theta
向量的形状具有维度(3,1)。请记住,我们数据集中的每个单独的训练示例也有 3 个字段(2 个原始特征和 1 个后来添加的额外列)。因此,最终的theta
向量的每个元素,即theta[0]
、theta[1]
和theta[2]
实际上分别是 θ0、θ1 和 θ2 ,并且对应于我们的训练示例的每个字段的参数。所以现在我们的最终假设看起来是这样的:
来源:作者
J_all
变量只不过是所有成本函数的历史。您可以打印J_all
数组来查看成本函数如何在每个梯度下降的时期逐渐降低。
成本与时代数量的关系图(来源:作者提供的图片)
该图可以通过定义和调用plot_cost
函数来绘制,如下所示:
现在,我们可以简单地插入我们的参数,并从我们的模型中获得预测。但是等等?!我们的模型没有预测 y =0 或 y =1,事实上我们模型的输出是一个浮点数。这实际上是应该发生的。奇怪的浮点输出实际上是一个例子属于类 y =1 的概率。所以我们现在需要给我们的模型添加最后一个函数。这是预测部分。
预测
让我们定义一个简单的函数来解释我们模型的概率输出,以预测 *y=1(承认)*或 y=0(拒绝)。
上面的代码在概率(我们模型的输出)大于等于 0.5 的情况下,将示例分类为属于 y =1(录取)类(或组),否则输出 y =0(拒绝)。
试验
现在,您可以通过调用一个测试函数来测试您的代码,该函数将申请人在两次测试中的分数大小和由我们的逻辑回归模型返回的最终theta
向量作为输入,并将向我们提供申请人是否应该被录取的最终结果。
完整的代码
就是这样!
嗯,差不多就是这样。您现在可以完全从头开始编写逻辑回归代码。能够理解完整的算法并编码它,不是一件容易的事情,所以,干得好!如果你对我们在这篇文章中提到的例子感到满意,请随意挑选另一个数据集(用于逻辑回归)并尝试一下。
编码快乐!😃**
参考
您可以在此找到完整的代码和数据集,以供参考:
**https://github.com/kumudlakara/Medium-codes
- https://medium . com/analytics-vid hya/basics-and-beyond-logistic-regression-34549 D2 ee 800
- 【https://www.coursera.org/learn/machine-learning/home/ 号
- 【https://www.holehouse.org **
CODIR:训练更小、更快的 NLP 模型
知识提炼的独特方法
亚当·温格在 Unsplash 上的照片
随着 BERT 和 GPT-3 等大型预训练模型的出现,自然语言处理领域发生了革命性的变化。这些模型已经能够从它们接受训练的大量文本中捕获难以置信的大量信息,并使用这些信息来达到最先进的性能,并不断改进各种各样的任务,如分类、摘要和推理。
这些型号性能出色的一个原因是它们的尺寸。BERT-base 有 1.1 亿个参数,BERT-large 有 3.4 亿个参数,GPT-2 有 15 亿个参数,GPT-3 有 1750 亿个参数。随着这些模型规模的增长,预处理它们所需的时间和资源也在增加。为了提高这些模型的成本和资源效率,一系列专注于减小模型大小的研究正在兴起。为此,采用了几种技术:
- 量化专注于减少模型权重的大小(从 32 位数减少到 16 或 8 位数)。
- 修剪识别冗余权重并尝试丢弃它们。
- 知识蒸馏专注于通过尝试将较大的模型(教师)与较小的模型(学生)匹配来创建较小的微调模型。像 DistilBERT 和 MobileBERT 这样的模型扩展了这个概念,使用 BERT 老师创建了更小的预训练模型。
一般来说,知识提炼包括两个部分:
- **原始训练目标:**该目标着重于让学生模型学习正确的标签(在微调期间)或正确的预训练目标
- **提炼目标:**这个目标试图将学生的输出概率(以及可能的隐藏状态)与教师的输出概率相匹配。这是通过选择一个距离度量并最小化学生和老师之间的距离来实现的。
微软动态 365 人工智能研究所的研究人员试图通过不同的视角来解决蒸馏问题。与其尝试最小化老师和学生之间所有例子的距离,为什么不尝试最大化错误例子之间的距离,最小化真实例子之间的距离?这导致他们提出了 CODIR,一种使用对比学习向学生提取教师隐藏状态的技术。CODIR 可应用于预训练和微调阶段。
与传统的知识提炼技术不同,CODIR 有 3 个组成部分:
- **最初的训练目标:**这与常规 KD 相同
- **蒸馏目标:**与常规 KD 不同,该目标使用 KL 散度损失来教导学生预测与教师相似的概率分布。它只适用于学生模型的输出。
- **对比学习目标:**该目标着重于将学生的隐藏状态与教师的隐藏状态拉开距离,以获得负面示例,并将其与正面示例相匹配。
孙等人的 CODIR 训练框架。
将 CODIR 应用于微调阶段非常简单。因为训练样本有标签,所以负样本只是那些与正样本有不同标签的样本。
在预培训阶段,没有标签,因此应用对比学习目标变得更具挑战性。研究人员在 RoBERTa 模型上测试 CODIR,该模型使用掩蔽语言建模作为预训练目标。在这种情况下,反面例子是来自同一篇文章的被掩盖的句子或文本,因此它们在语义上与正面例子相似。这样,对比学习的目标就不会变得太容易解决。
研究人员使用 CODIR 将 Roberta 模型减少到 6 层,并在 GLUE 数据集上验证其有效性。该模型实现了与原始 BERT 模型几乎相同的精度,而推理时间只有原来的一半。
这里有一个链接到论文,如果你想了解更多关于 CODIR 的内容,一个链接到代码,你可以提炼出你自己的模型,点击这里可以看到更多我们的出版物和其他工作。
参考文献
- 维克多桑,弗拉达利首次亮相,朱利安肖蒙德,和托马斯沃尔夫。2019.蒸馏伯特,伯特的蒸馏版:更小、更快、更便宜、更轻。 arXiv 预印本 arXiv:1910.01108。
- 孙志清、俞鸿坤、宋、刘、和周丹妮。2020. Mobilebert:一个紧凑的任务无关的 bert,用于资源有限的设备。arXiv 预印本 arXiv:2004.02984。
- 孙思齐,何哲,俞成,,方,王硕航,。“用于语言模型压缩的中间表示的对比提取” arXiv 预印本 arXiv:2009.14167 (2020)。
按镜头类型的咖啡流量分析
咖啡数据科学
更多关于分层浓缩咖啡的分析
在之前的中,我研究了流量参数与一杯好的浓缩咖啡的关系。我没有发现任何新的东西,但后来我对镜头类型进行了细分,我开始看到一些有趣的变量。我的数据中的一个混淆变量在多种类型的分层拍摄中,它们在流动上有差异。
浓缩咖啡系列:
- 普通浓缩咖啡
- 断奏被篡改
- Sudo-Staccato
- 双双
绩效指标
我使用两个指标来评估技术之间的差异:最终得分和咖啡萃取。
最终得分 是评分卡上 7 个指标(辛辣、浓郁、糖浆、甜味、酸味、苦味和余味)的平均值。当然,这些分数是主观的,但它们符合我的口味,帮助我提高了我的拍摄水平。分数有一些变化。我的目标是保持每个指标的一致性,但有时粒度很难确定。
使用折射仪测量总溶解固体量(TDS),该数字与咖啡的输出重量和输入重量相结合,用于确定提取到杯中的咖啡的百分比。
流量指标
我编了一些我认为可能对心流感兴趣的指标。我把预输注(PI)和输注分开。我没有看压力脉动,而是平稳的流动。
对于预注入,我将其减半,因为通常 PI 开始缓慢,然后加速。对于输液,我看着向上和向下的趋势,如下图所示,至于我的杠杆机器,我在整个拍摄过程中积极调整流量。
此外,我还查看了喝 1 克咖啡以及 2、3、4、5、6、7 和 8 克咖啡的时间。
覆盖过滤器的时间(TCF)和 T10(达到 10 毫升的时间)这两个变量我已经使用了将近一年,以帮助在更高水平上跟踪流量的差异。它们和一杯好的浓缩咖啡有很好的相关性。
数据分析
在我之前的作品中,我解释了我从流量日志中获得的变量。这项工作中使用的主要指标是相关性。
相关性是衡量两个变量彼此相似程度的指标。高度相关并不意味着一个变量会引起另一个变量,而是当情况发生变化时,两个变量的涨跌幅度相同。相关性可以是正的(趋势相同)或负的(趋势相反)。0 表示没有相关性。
这是按镜头类型的第一个细分:
似乎很清楚,对于常规拍摄,有一些与第一个输出权重块的时间百分比相关的流度量。
让我们把这些图表分成更小的部分。
****
π/TCF 对于普通投篮和两双来说是一个很好的指标,但对于其他人来说可能就没那么好了。压力脉动泵的数量似乎也无关紧要。对于常规拍摄,预灌注的斜率似乎影响较大。
如果我们关注不同重量的时间和达到这些重量的击球时间的百分比,一些有趣的趋势出现了。就味道而言,击球速度越快,双倍击球的味道就越好,但这并不适用于 sudo-staccato。而 EY 也有类似的趋势。
然而,达到一定重量所需的时间百分比与常规注射的高提取率高度相关。这意味着花费在预输注(PI)中的时间比例越高越好,因为前 8 至 10g 通常是在这些注射的预输注期间。
我从这些故障中得出的最好结论是,情况仍不明朗。似乎这些不同类型的分层快照从根本上彼此不同,因此修改每个分层快照的参数可能具有挑战性。
我原以为更多的数据会揭示出简单的模式或者一些新的东西,但是浓缩咖啡面临的挑战是多重的、相互关联的变量问题。我怀疑,如果找到一种简单明了的方法,全力以赴从多方面改进浓缩咖啡,那会令人失望。
如果你愿意,可以在 Twitter 和 YouTube 上关注我,我会在那里发布不同机器上的浓缩咖啡视频和浓缩咖啡相关的东西。你也可以在 LinkedIn 上找到我。也可以关注我中。
我的进一步阅读:
通过颗粒分布比较咖啡研磨机
咖啡数据科学
最近发生了两件事:我买了一个利基零,我开发了一个基于图像的颗粒分布测量方法。当我清理我的韩国研磨机准备退休或搬迁时,我想我可以很容易地在几个研磨设置的研磨机之间进行比较,看看它们的性能如何。
所有图片由作者提供
我有四台研磨机,按购买顺序排列如下:
我一开始买了一个 Hario 研磨机,因为我很便宜,我没有意识到它不是一个好的浓缩咖啡研磨机。然后我买了一辆 Rok,5 年来它一直是我的支柱。我买了一辆旅行车。为了磨时间和方便,我决定买个小生。
所有的毛刺除了壁龛的。我不是为了好玩才拿出全新的刀片。顺序:韩国、Lume、Hario
研磨机比较中的大多数颗粒分布是单一研磨设置。我做了一些研磨设置,以了解研磨机如何在多种情况下工作。我尝试使用类似的点击量,通常,我知道什么是太精细,什么是太粗糙,什么是刚刚好。
单个研磨机数据
这里是每个研磨机的分布。
Hario 是最难操作的,因为它磨起来很慢,很难拨入。
我爱韩国。我已经用了好几年了,通常是在零位。它很好地控制了地面设置的变化。
我为旅行买了 Lume,但是它没有我想要的那么快。这是非常敏感的设置,但我已经得到了很好的咖啡。
利基是可怕的,真的允许细微的增量变化。
比较 3 个设置
我不认为这些设置是等价的,但我认为比较精细、中等和粗糙设置会很有趣。
Lume 在最精细的设置下有一个更多细屑的奇怪缺口,但这可能只是比其他研磨机更精细一点。
对我来说很奇怪的是,Hario 的设置 6 与 Niche 的设置 10 如此接近
这个粗的确实能看出 Lume 是怎么起飞的,但是发行还是有很多细的。我不确定这是否令人惊讶,因为它们都是锥形毛刺。
最终,我的目标是使用这种方法来更好地了解小生境,并且,私下里,我正试图在多种研磨设置中给出平面和锥形毛刺之间的量化比较。这也有助于鉴定研磨机,也许我们最终可以查看多个研磨机,以了解它们应该如何相互排序。
如果你愿意,可以在 Twitter 和 YouTube 上关注我,我会在那里发布不同机器上的浓缩咖啡视频和浓缩咖啡相关的东西。你也可以在 LinkedIn 上找到我。也可以关注我中。
我的进一步阅读:
咖啡渣遇水膨胀
咖啡数据科学
使用研磨分布了解水如何影响咖啡
以前,我研究过咖啡渣遇水膨胀的想法。我利用冰球缩小的体积得出了这个结论。然而,我有机会通过使用咖啡渣和研磨分布来近距离观察。我还观察了一次拍摄前后的研磨分布,由于拔牙的缘故,的研磨面缩小了。
作者的所有图片
我首先在一些数据中注意到了干燥的影响。我测量了一堆地上的两个样本的分布。更具体地说,我从一个干的用过的咖啡球的顶部和底部取样。一天后,我取了另一个样本,我注意到两个分布都发生了变化。
这是咖啡渣吸收了水分的有力证据,但我想要更多的控制,因为我测量了两个不同的样本。
所以我取了一个样本,测量了它的分布。然后我让它干 12 个小时(过夜);我的房子很干燥。新的测量是对同一个样本进行的,在分布上有一个明确的变化。
我从一开始就测量了几次这个样本的分布,有一个明确的颗粒收缩的趋势。
这种分布上的变化是一个很好的证据,表明咖啡在提取过程中吸收了水分,随着水分从咖啡渣中变干,咖啡渣开始膨胀,这表明咖啡渣在收缩。
这些数据还表明,一旦开始拍摄,咖啡磨粒之间的潜在间隙将会缩小,因此冰球内任何粒子移动的主要时间将是在拍摄的最开始。
如果你愿意,可以在推特和 YouTube上关注我,我会在那里发布不同机器上的浓缩咖啡照片和浓缩咖啡相关的视频。你也可以在 LinkedIn 上找到我。也可以在中关注我,在订阅。
我的进一步阅读:
“我思故我在”——用另类的思维框架对数据和决策进行建模
思想和理论
如何理解数据(或缺少数据)—当数据表现良好或表现不佳时
“我思故我在”
“我思故我在”
勒内·笛卡尔
思考或解决任何事情都需要某种框架,我们会有意识或无意识地遵循这种框架。他们有完整的分析领域,要么理解和构建一个人如何思考/决定(阅读:决策分析),要么理解其他人在某种情况下如何思考,比如说,零售购物(阅读:预测分析)。
在学术环境中,现在有了一个博士项目,我在这个过程中收集了一些经验教训——当内在化时,这些经验教训有助于一个人有效地思考或决定。我已经吸收了这么多,称它们为任何类型的框架都是过分的,但这些是简单的基本概念,我相信每个人,尤其是处理数据的人,应该偶尔阅读和反思。随着时间的推移,我意识到我对这些想得越多,它们就变得越自然,看起来就越正确。
毕加索的公牛
在某些时候,你可能会看到一个视频或图表,展示了毕加索创作的极简主义的公牛肖像。在这里,供参考。
毕加索,《公牛》,每日艺术杂志
外界对它有很多解释,但我个人最喜欢的是一个简单的解释。随后的每一幅画,公牛的一部分都被拿走了,但剩下的仍然是可以被认出的公牛,而且看起来很优雅。史蒂夫·乔布斯一直在思考寻找简单而优雅的方法来解决问题,引用毕加索自己的话
“……最抽象的东西也许是现实的顶峰”
每次我处理一个问题,几乎所有的问题都是数据驱动的,在我写完代码,推断出结果,写完手稿之后,我会花大量的时间去“毕加索”它。我删除了任何一行,任何一个推论,任何一个概念的提及,或者任何一个外行读者不需要知道的参考,我只保留了帮助读者从零到一(从 Theil 偷)的基本框架。这适用于文字、代码、数字、图表和几乎任何其他可以制作的东西。
这种“毕加索式”创作的想法不仅仅适用于提出解决方案或创作作品。它代表了一种思想流派,在这种思想流派中,以保留支点的方式处理问题,但否定任何无关紧要的东西是最重要的。无视干扰,专注于有用的东西是一门艺术。
费曼的技术
也许真的是英雄所见略同,因为理查德·费曼也相信简单明了。这种技术的抽象解释通常可以在互联网上找到,可以总结如下:
- 学点东西。
- 教一个孩子。
- 如果孩子理解它,你对它的理解是坚定的。如果没有,重复。
当我用毕加索的技巧来思考一个问题,或者展示结果时,当我必须学习时,我会试着“费曼”它。可以毫不夸张地说,这种技术是毕加索学派的“学习”版本。
当涉及到学习任何新东西时,无论是像贝叶斯定理这样简单的东西,还是像理解神经网络或变压器如何工作这样复杂的东西,这种技术都是可以信赖的。
互联网上无数的文献都信誓旦旦地用这种方法来教和学,我会让他们来说服你。这篇中型文章是一篇很好的入门读物。
好的内脏
我经常了解到,当思考或解决问题时,所谓的“直觉”或直觉是一种很好的启发。当解决一个问题或做一项任务时,它通常会引导你找到一个很好的起点,它是一个很好的指标,表明一项任务是否在你目前的知识范围内,当它暗示有什么事情出错时,它会非常出色。它太好了,甚至连蜘蛛侠都相信它(阅读:蜘蛛侠感觉)。
我不知道,也不想去探究我们的“蜘蛛侠感觉”背后的科学,但我知道,对我和我周围几乎所有的人来说,这些经历是常见的:
- “这道数学题似乎有很简单的解法。似乎很可疑”
- “我已经通读了问题陈述,并且知道我将需要通宵来解决它”
- “我觉得简单的线性回归可以很好地解决这个问题”
称之为经验,称之为智慧。如果这是你感觉到的第一件事,而不仅仅是理性的结论,那么你可以知道你的直觉已经给出了它的结论。所以很多时候,我不相信最初的感觉,与它斗争,花了无数个小时寻求其他解决方案,直到我后悔和退缩。也就是说,就像这个宇宙中的任何知识一样,仅凭直觉无法帮助你涉过重重险阻——你需要将直觉与合理的解释结合起来。
引用莫法特和加蒂丝的《夏洛克》,
“直觉是不可忽视的。它们代表的数据处理速度太快,意识无法理解”
黑天鹅悖论
“排除所有其他因素,剩下的必然是真相.”
夏洛克也这样说过。但是通常,即使有堆积如山的数据或信息,有些事情还是没有意义。可能是数据不适合这个问题。这可能是因为我们不知道如何使用数据来解决问题——也许我们的建模是错误的。
在这种情况下,寻找黑天鹅通常是有帮助的。让我解释一下。
简而言之,如果你想了解天鹅(出于某种原因)并观察它们。如果你见过的所有天鹅都是白色的,那么当你写这种鸟或者报告你的结果时,这就不是一个令人惊讶的描述了。事实上,这将是一个决定性的特征。如果你看到一只黑色的鸟漂浮在水面上,你会毫不犹豫地认为它是一只天鹅。但是如果有一天,你观察到一只黑天鹅呢?你对天鹅的理解受到了影响。你开始思考你是否还了解他们。现在,如果这只黑天鹅的行为完全不同呢?如果他们发出嘘声而不是喇叭呢?夸张点说,如果是食人族消灭了其他天鹅呢?
这种情况被称为“黑天鹅”情况的一个例子,在这种情况下,一个突然的、意想不到的和罕见的事件使你的知识和理解,甚至可能是你正在处理的世界变得不正常。黑天鹅也很常见。毫不夸张地说,如果你观察到一群人在同一时间出现了一种似乎正在迅速传播的疾病的相同症状,你可以认为他们形成了疫情的开端。货币的非货币化是另一个例子——这是一个罕见的事件,你很少预料到/准备好它,但它却发生了——往往会带来严重的后果。
Marvin Rozendal 在 Unsplash 上的照片
但是你为什么需要知道这些呢?你其实不知道。能够预测黑天鹅并不常见,也不经常需要。但是知道像黑天鹅事件这样的事情可能存在,能够在它们发生时识别它们,并能够预先列举它们,可以帮助形成应急措施或在它们发生时更快地减轻它们。我相信,如果你正在管理一家餐厅,而这家餐厅现在因为疫情而不得不应对外卖订单,而不是内部订单,这将会有所帮助。
当数据没有意义,但你看到一个模式,寻找一只黑天鹅。
生活几乎无时无刻不包含积极的思考。无论是管理财务,还是建立神经网络来解决概率问题。没有一种真正的方式来思考和解决这些问题,有一些形式领域可以帮助你基于深刻的理性思考和数理逻辑做出有效的决定。但是,当你找房子的时候,或者当你弄清楚为什么你的杂货价格在一个街区上涨,而在另一个街区却没有上涨的时候,你真的会画出一棵决策树吗?你多久会尝试用一种可量化的方式来了解你是否以正确的方式解决了一项任务,或者你是否很好地展示了一条信息?
这些是我们每天快速做出的决定,很少受到框架和工具的干扰,通常只需要一点点理性的思考。正是这一点点,我试图用我“接受”的这些想法做出更好的决定。
aditya Narayan an是布法罗大学的博士生。他擅长将逻辑应用于概率图,有 计算机科学 背景。阅读新闻并加以评论是他的本能。
他有另一个自我,无聊时喜欢创作各种数字内容,但更喜欢纸和笔。他为多个大型体育实体创建了数字内容,如 LaLiga Santander、Roland-Garros 和 NBA 篮球学校。
腹侧颞叶皮层时空功能磁共振成像的认知计算模型
解码和理解人类大脑
玻璃大脑可视化(图片由作者提供)
材料
在这一系列文章中,我们将回顾以下文章
- 人脑认知计算模型导论(上)
- 发现神经影像分析(第二部分)
- 人脑的功能连接和相似性分析(下)
- 人脑分布区域的无监督表示学习(四)
- 基于机器学习和深度学习的时空 fMRI 解码(五)
所有相关资料都放在我的 Github 页面上。别忘了去看看。如果你是一个纸质爱好者,你可以阅读这一系列文章的纸质版,也可以在我的回购中找到。
在进入技术面之前,先了解
- 计算神经科学
- 无监督学习和机器学习的基础
- 简单的神经网络(MLPs,CNN,…)
会很有帮助的。但是,不用担心。这些将是高水平的、实践的、代码优先的文章。那么,我们开始吧。
在本文中,我们将简要讨论人脑腹侧颞叶皮层的多体素模式分析(MVPA)。多体素模式分析和识别目前被用来研究包含在神经活动的分布式模式中的信息,以推断大脑区域和网络的功能作用。
从机器学习的角度来看,这是一个直接监督的分类问题。这里,输入通常是来自神经科学实验的 fMRI 数据。输出是感兴趣类别的概率分布。在我们的例子中,我们将尝试解码人类主体看到的视觉刺激类别(人脸、猫、椅子、鞋子……)。
MVPA 被认为是一个监督分类问题,其中分类器试图捕捉功能磁共振成像活动的空间模式和实验条件之间的关系。
在我们的例子中,fMRI 数据将是由空间和时间成分组成的 4D 时间序列数据。
目录
- 在第一部分,我们将在计算认知神经科学的背景下讨论人类腹侧颞叶皮层分布区域的视觉解码。然后,我们将理解为什么我们需要构造时空解码算法来执行认知任务。(第一部分)
- 在第二部分中,我们通过功能磁共振成像(fMRI)方法研究了人脑中物体视觉通路的功能结构,以解码人类受试者所看到的视觉刺激。我们进行了最先进的解释性回波平面,感兴趣区域(RoI),统计图,解剖和玻璃脑预分析,以从人脸和物体表征的研究中发现块设计的 4-D 时间序列 fMRI 数据集,即 Haxby 数据集。(第二部分)
- 在第三部分中,为了理解腹侧颞掩蔽的 fMRI 样本中的测地线关系,我们进行了基于相关性、精确度和偏相关的功能连接性分析,以及基于余弦、闵可夫斯基和欧几里得距离的相似性分析。(第三部分)
- 在第四部分中,流形学习和维数约减方法在每个受试者的腹侧时间掩模上执行,以提取时空掩模的潜在表示,这将有助于 fMRI 的进一步解码。(第四部分)
- 在第五部分中,开发了从感知器到 FREMs 的端到端机器学习算法,以根据腹侧颞叶皮层中的分布和重叠区域对刺激进行分类。通过利用不同视觉表示流之间的交互作用,我们进一步构建了认知神经网络,准确地说是 MLPs、2D 和 3D CNNs。(第五部分)
文章链接
- 发表文章
https://cankocagil.medium.com/discovery-neuroimaging-analysis-part-ii-b2cdbdc6e6c3
2.在路上(即将到来…)
- 第五部分的占位符
进一步阅读
- 【https://www.hindawi.com/journals/cmmm/2012/961257/
我在机器学习和神经科学方面的研究中使用了以下参考文献列表。我强烈建议复制粘贴参考资料,并简要回顾一下。
参考
[1]巴、基罗斯和辛顿。图层归一化,2016。
[2] L. Buitinck,G. Louppe,M. Blondel,F. Pedregosa,A. Mueller,O. Grisel,V. Niculae,P. Prettenhofer,A. Gramfort,J. Grobler,R. Layton,J. VanderPlas,a .乔利,B. Holt,10 和 G. Varoquaux。机器学习软件的 API 设计:scikit-learn 项目的经验。在 ECML PKDD 研讨会:数据挖掘和机器学习的语言,第 108–122 页,2013。
[3]褚,田,王,张,任,魏,夏,沈。双胞胎:重新审视《视觉变形金刚》中空间注意力的设计,2021。
[4] K .克拉默、o .德克、j .凯舍特、s .沙莱夫-施瓦兹和 y .辛格。在线被动攻击算法。2006.
[5] K. J .弗里斯顿。统计参数映射。1994.
[6]格罗斯、罗查-米兰达和本德。猕猴下颞皮质神经元的视觉特性。神经生理学杂志,35(1):96–111,1972。
[7] S. J .汉森、t .松坂和 J. V .哈克斯比。用于物体识别的腹侧颞叶组合编码。
[8]哈克斯比、戈比尼、富里、伊沙伊、斯豪滕和彼得里尼。《视觉物体识别》,2018。
[9]赫克曼、哈伊纳尔、贾巴尔、吕克特和哈默斯。结合标记传播和决策融合的自动解剖脑 mri 分割。神经影像,33(1):115–126,2006。
10d .亨德里克斯和 k .金佩尔。高斯误差线性单位(gelus),2020。
[11]黄少华,邵文伟,王明林,张德庆.人脑活动视觉信息的功能解码:简要综述。国际自动化和计算杂志,第 1-15 页,2021。
[12] R. Koster、M. J. Chadwick、Y. Chen、D. Berron、A. Banino、E. Duzel、D. Hassabis 和 D. Kumaran。海马系统内的大循环复发支持跨发作的信息整合。神经元,99(6):1342–1354,2018。
[13]马奥尔。勾股定理:4000 年的历史。普林斯顿大学出版社,2019。
[14] K. A. Norman、S. M. Polyn、G. J. Detre 和 J. V. Haxby 超越读心术:功能磁共振成像数据的多体素模式分析。认知科学趋势,10(9):424–430,2006。
[15]奥图尔、江、阿卜迪和哈克斯比。腹侧颞叶皮层中物体和面孔的部分分布表征。认知神经科学杂志,17(4):580–590,2005。
[16] F .佩德雷戈萨、g .瓦洛夸、a .格拉姆福特、v .米歇尔、b .蒂里翁、o .格里塞尔、m .布隆德尔、p .普雷登霍弗、r .魏斯、v .杜伯格、j .范德普拉斯、a .帕索斯、d .库尔纳波、m .布鲁彻、m .佩罗特和 e .杜切斯内。sci kit-learn:Python 中的机器学习。机器学习研究杂志,12:2825–2830,2011。
17 r . a .波尔德拉克。功能磁共振成像的感兴趣区域分析。社会认知和情感神经科学,2(1):67–70,2007。
[18] M. Poustchi-Amin、S. A. Mirowitz、J. J. Brown、R. C. McKinstry 和 T. Li。回波平面成像的原理和应用:普通放射科医师回顾。放射学,21(3):767–779,2001。
[19] R. P. Reddy,A. R. Mathulla 和 J. Rajeswaran。心理健康专家的观点采择和情绪传染的初步研究:移情的玻璃脑观点。印度心理医学杂志,0253717620973380,2021 页。
[20]史密斯、米勒、萨利米-科尔希迪、韦伯斯特、贝克曼、尼科尔斯、拉姆齐和伍尔利奇。功能磁共振成像的网络建模方法。神经影像,54(2):875–891,2011。
21 田中先生。下颞叶皮层和物体视觉。神经科学年度评论,19(1):109–139,1996。
[22] M. S .特雷德。Mvpa-light:一个多维数据的分类和回归工具箱。神经科学前沿,14:289,2020。
[23] M. P .范登赫维尔和 H. E .波尔。探索大脑网络:静息态功能磁共振成像功能连接综述。欧洲神经精神药理学,20(8):519–534,2010。
[24] G. Varoquaux,A. Gramfort,J. B. Poline 和 B. Thirion。大脑协方差选择:使用群体先验的更好的个体功能连接模型。arXiv 预印本 arXiv:1008.5071,2010。
[25] Y. Wang,J. Kang,P. B. Kemmer 和 Y. Guo。一种利用偏相关估计大规模脑网络功能连接的有效可靠的统计方法。神经科学前沿,10:123,2016。
26s . Wold、K. Esbensen 和 P. Geladi。主成分分析。化学计量学和智能实验室系统,2(1–3):37–52,1987。
27s . Wold、K. Esbensen 和 P. Geladi。主成分分析。化学计量学和智能实验室系统,2(1–3):37–52,1987。
认知风险管理
行业笔记
自然语言处理技术的商业应用
由 亚历山大约翰·托马斯李嘉图马克西姆【阿拉德】 ,以及 阿坎克沙乔希**
作者图片
介绍
机器学习(ML)应用已经变得无处不在。每天都有关于自动驾驶汽车、在线客户支持、虚拟个人助理等人工智能的消息。然而,如何将现有的商业实践与所有这些惊人的创新联系起来,可能并不明显。一个经常被忽视的领域是自然语言处理(NLP)和深度学习的应用,以帮助快速有效地处理大量的业务文档,从而在大海捞针。
允许有机应用 ML 的领域之一是金融机构和保险公司的风险管理。关于如何应用 ML 来改进风险管理,组织面临许多问题。以下是其中的几个例子:
如何识别可以从使用人工智能中受益的有影响力的用例?
如何弥合主题专家的直觉期望和技术能力之间的差距?
如何将 ML 集成到现有的企业信息系统中?
如何在生产环境中控制 ML 模型的行为?
本文旨在分享 IBM 数据科学和人工智能精英(DSE)以及 IBM 专家实验室团队的经验,这些经验基于风险控制领域的多个客户项目。IBM DSE 已经构建了各种加速器,可以帮助组织快速采用 ML。在这里,我们将浏览风险管理领域的用例,介绍认知风险控制加速器,并讨论机器学习如何在这一领域转变企业业务实践。
风险管理草图
2020 年,多家金融机构遭受了单个机构超过数亿美元的罚款。罚款的原因是国家风险控制不足。
这引发了对金融公司的呼吁,要求它们确保必须处理的大量风险控制措施的高质量。这包括明确识别风险、实施风险控制以防止风险发展,以及最终建立测试程序。
对于非专业人士来说,风险控制有点令人费解。这是怎么回事?一个简单的定义是,风险控制是为了监控公司业务运营的风险。例如,安全风险可能是入侵者猜测密码,并因此获得对某人账户的访问权。一种可能的风险控制可能被设计为建立一种策略,该策略要求通过组织的系统强制执行长且重要的密码。作为萨班斯-奥克斯利法案(SOX)的结果,上市公司需要有效管理此类风险的方法,作为建立风险控制和评估这些控制质量的一部分。
对于风险经理来说,一个重要的因素是控制措施是否定义良好。对此的评估可以通过回答以下问题来完成:谁来监控风险,应该为风险识别或预防做些什么,在组织的生命周期中应该多久执行一次控制程序,等等。这些问题都要回答。现在我们需要认识到,在一个企业中,这种控制的数量从几千到几十万,并且很难手工对控制主体进行评估。这就是当代人工智能技术能够提供帮助的地方。
当然,这种类型的挑战只是一个例子,试图在一篇文章中涵盖风险管理的广阔领域是不切实际的,因此我们将重点关注从业者在日常实践中面临的一些具体挑战,这些挑战已经使用认知风险控制加速器实现了。
可用的公共风险控制数据库不多,因此加速器中的解决方案基于在https://nvd.nist.gov/800-53提供的针对安全控制的 NIST 特别出版物 800–53。这个安全控制数据库很小,但它允许我们展示可以扩展到大量和不同风险控制领域的方法。
使用文本分析和深度学习进行风险控制
一个关键的用例类别是使现有的风险控制合理化:挑战是现有的风险控制是如何发展的可能有许多历史方面。例如,一些风险控制可以通过复制其他现有控制进行最小的修改来构建。再比如有些风险控制可能是把多个风险控制整合成一个而形成的。这种方法的常见后果是重复的控制和不再与业务相关的控制的存在。最困难的挑战之一是评估现有风险控制的总体质量状态。因此,从商业的角度来看,第一个目标是建立质量评估:自动评估控制描述的质量,通过只关注那些真正重要的评审和改进,节省了大量阅读描述的时间。一个很好的问题是人工智能在这里是如何出现的。基于 NLP 的 ML 模型在常见的语言相关任务中变得非常有效,特别是在诸如回答问题的挑战中。这里可以引用的一种模型是基于 Transformer 架构的(有关更多详细信息,请参见位于https://medium . com/inside-machine-learning/what-is-a-Transformer-d 07 DD 1 fbec 04的一篇关于 Transformer 架构的文章)。
在风险管理草图中,回答有关风险控制描述的问题的能力是评估控制描述质量的关键。从鸟瞰图来看,未回答问题的数量是控制描述质量的一个很好的指标。最好的消息是,借助变形金刚等当代人工智能模型的能力和额外的实用规则,这种提出正确问题的技术成为一种有效的机制,可以在人工智能的协助下,由一个小团队控制大量的控制描述。
控制质量评估(图片由作者提供)
通常,在文档中寻找重复被认为是一项简单的任务,而 Levenshtein 距离可以帮助找到用相似措辞表达的条目。然而,如果我们想要找到语义相似的描述,这就变成了一个更具挑战性的任务。这是当代人工智能可以发挥作用的另一个领域——使用大型神经网络(例如,自动编码器、语言模型等)构建的嵌入。)可以捕捉语义相似度。从实际结果的角度来看,我们的经验是,发现重复和重叠可能导致控制量减少 30%。
重叠分析(作者图片)
此外,通过 ML 技术(如聚类)来分析信息的内部结构已经成为一种常见的做法。这使业务人员能够更好地了解更大范围内的控制内容,并查看现有的风险和控制分类是否与内容保持一致,或者两者中可能缺少什么。
聚类示例(作者图片)
以前的用例侧重于对现有控件的分析。另一个用例侧重于帮助风险经理创建新的风险控制。使用语义相似性为给定风险推荐控制措施可以显著减少人工工作量,并为构建控制措施提供灵活的模板。机器学习可以帮助分析风险描述,并找出正确的控制措施来解决每个风险。
在大型组织中,团队通常致力于其他团队可能使用的解决方案和最佳实践。在整个组织中采用最佳实践需要大量的培训。在这种情况下,机器学习非常有用。例如,可以将控制分类为预防性或检测性。在此使用案例中,我们使用受监督的机器学习,通过使用特定团队的现有标记集,将控制分类扩展到整个控制集,即使用机器学习完成知识转移,而不是耗时的人员培训。
IBM DSE 风险控制加速器中的认知技术允许我们构建风险控制,为用自然语言表达的风险推荐控制,识别控制中的重叠,并分析控制的质量。
accelerator 提供了一个认知控制分析应用程序,该应用程序集成了开发的模型并将其应用于非结构化风险控制内容。
使用 IBM Cloud Pak for Data 实现认知风险控制
从逻辑上讲,认知风险控制加速器包含几个组件:
- 第一个是所谓的认知助手,它是一个应用 ML 模型来促进内容处理的应用程序,例如,通过识别风险控制优先级、类别和评估控制描述的质量。作为产品化的一部分,认知助手成为企业信息系统的一部分。
认知助手(图片由作者提供)
- 第二个组成部分是内容分析:当数据通过机器学习模型丰富时,Watson Discovery 内容挖掘可用于在丰富的内容中寻找见解
使用 Watson Discovery 进行内容分析(图片由作者提供)
- 还有一个组件是一套支持数据科学模型的 Jupyter 笔记本
沃森工作室的 Jupyter 笔记本(图片由作者提供)
让我们看看使用 IBM Cloud Pak 实现数据的基于加速器的实现。
在此之前,让我们简要回顾一下 IBM 平台和方法。IBM 对人工智能之旅有一个描述性的方法,叫做人工智能阶梯。在他的人工智能阶梯:揭开人工智能挑战的神秘面纱中,罗布·托马斯(SVP,IBM 云&认知软件)证实,要将数据转化为洞察力,您的组织应该遵循下列阶段:
收集—能够轻松访问数据,包括虚拟化数据
组织—对数据进行编目、构建数据字典以及确保访问数据的规则和策略的方法
分析——这包括交付 ML 模型,使用认知工具和人工智能技术使用数据科学来识别洞察力。这自然需要构建、部署和管理您的机器学习模型
注入——从许多角度来看,这是一个关键阶段。这是指以一种允许业务信任结果的方式操作人工智能模型的能力,即在生产模式下在企业系统中使用你的机器学习模型,同时能够确保这些模型的持续性能及其可解释性。
Cloud Pak for Data 是 IBM 的多云数据和人工智能平台,提供信息架构并提供所有概述的功能。下图捕捉了在 AI 阶梯环境中开发实现的细节。
阶段(图片由作者提供)
它记录了基于 DSE 加速器的认知风险控制项目的实施阶段:
- 实施风险控制项目的前两个阶段是获取和编目数据集,例如,在加速器中,我们使用 NIST 控制数据集。这里的控件表示为自由文本描述。
- 下一个阶段是在 Watson Studio 中丰富所获得的非结构化数据:聚类被用作理解内容内部结构的一种方式。风险控制叙述可能很长,可能会讨论多个主题,因此可能需要某种机制来跟踪描述过程中不断变化的主题。在我们的聚类实践中,我们使用了基于嵌入的 K-means 和潜在的 Dirichlet 分配(LDA)。它确实需要数据科学家和主题专家的仔细协调,因为数学可能不会与 SME 的期望理想地一致。更广泛的丰富在这里也是可能的——一个很好的例子是对描述的质量进行分类。
主题建模(图片由作者提供)
- 当浓缩完成后,我们需要理解产生的数据集。这就把我们带到了探索阶段。实际上,挑战在于数量;内容审查是最耗时的过程之一,因为它需要仔细阅读大量文本。我们如何探索海量的非结构化信息?Watson Discovery 内容挖掘工具使这成为可能,并大大减少了工作量。
- 在内容被 SME 审查之后,它形成了构建监督机器学习模型的基础。IBM 平台提供了部署模型、监控漂移和获得复杂模型所做决策的可解释性的方法。所有这些都包含在机器学习的可操作化中,并由 IBM Cloud Pak For Data 提供支持。
结论
本文介绍了机器学习在当代商业中日益增长的应用领域之一——认知风险控制。访问我们的加速器目录,了解更多关于认知控制加速器的信息。如果您有兴趣了解更多关于认知风险控制和人工智能技术的信息,请随时联系 IBM 数据科学和人工智能精英团队。此外,如果您发现您的用例与所展示的相似,或者如果您的业务和技术挑战可以通过提到的方法或工具解决,请联系 IBM。
承认
作者(IBM DSE 和专家实验室)对他们的同事持续协作和开发认知控制的业务和技术方法表示感谢:斯蒂芬·米尔斯(IBM Promontory 董事总经理)、迈尔斯·拉维兹(IBM Promontory 高级负责人)、罗德尼·赖德奥特(IBM 全球业务服务部交付主管)、维奈·拉奥·檀丁(数据科学家)、艾西瓦娅·斯里尼瓦桑(IBM DSE 数据科学家)和拉克什思·达塞纳哈里·林加茹(IBM DSE 数据科学家)。
Cogram.ai:数据科学和机器学习的编码助手
马库斯·温克勒在 Unsplash 上的照片
在 jupyter 笔记本上运行的用于数据科学和机器学习的 Codex 支持的自动完成功能
自从 GPT-3 的发布和传播以来,像 Github copilot 这样的编码助手,由 OpenAi 的 codex API 提供支持,已经在机器学习社区的雷达上出现了很长一段时间。最近,我偶然发现了这个叫做 Cogram 的工具,它似乎是自动完成的一种进化,专门用于数据科学和机器学习,直接在 Jupyter 笔记本上运行。
在本文中,我将向您展示这个工具是如何工作的,并分享我迄今为止使用它的一点点经验,在 Jupyter 笔记本上生成机器学习代码。
Cogram 入门
首先,要设置 Cogram,你必须去他们的网站,在那里你注册一个免费账户并获得一个 API 令牌。之后,你所要做的就是安装 Cogram,包括:
pip install -U jupyter-cogram
将其作为 jupyter 笔记本扩展:
jupyter nbextension enable jupyter-cogram/main
最后,用以下代码设置您的 API 令牌:
python -m jupyter_cogram --token YOUR_API_TOKEN
现在你已经设置好了,你可以开始在你的 jupyter 笔记本上直接完成。
对于最新的可用版本,默认情况下启用 Cogram。用户可以通过该图标在菜单中打开和关闭共格图,
作者图片
还可以定制 Cogram,选择 Cogram 显示多少建议,以及 Cogram 有多有创意。
有两种方法可以使用 Cogram:你可以使用自动建议模式,每当你停止输入时,Cogram 都会提出建议,
来自 Cogram 的自动建议示例;图片由 cogram.ai 提供(获得许可)
或者当你去一个新的行。您也可以使用手动完成选项,由 Tab 键触发。
通过 Tab 键触发的 cogram.ai(获得许可)手动完成选项
用 Tab 键触发的手动完成选项;图片由 cogram.ai 提供(获得许可)
用户可以通过 Cogram 菜单中的自动建议复选框在这些选项之间切换。
Jupyter 笔记本上的自动完成功能
我用 Cogram 生成了一组补全来测试它的可用性,下面是我最喜欢的一些:
写这个的时候:
# plot sin(x) from 0 to pi
它生成了这个:
# plot sin(x) from 0 to pi
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, np.pi, 100)
y = np.sin(x)
plt.plot(x, y)
plt.show()
作者图片
令我高兴的是,我尝试的第一个例子实际上生成了无需任何编辑或调试就能运行的代码!现在,另一个简单的例子,来自这个:
# plot a histogram of points from a poisson distribution
它生成了这个:
# plot a histogram of points from a poisson distribution
import numpy as np
import matplotlib.pyplot as plt
x = np.random.poisson(5, 1000)
plt.hist(x)
plt.show()
作者图片
再次,它运行没有问题!到目前为止非常酷。让我们更进一步,创建一个假数据集来拟合一个简单的线性回归模型:
# create a fake dataset and run a simple linear regression model
输出:
# create a fake dataset and run a simple linear regression model
import numpy as np
import matplotlib.pyplot as plt
x = np.random.randn(100)
y = 2 * x + np.random.randn(100)
plt.scatter(x, y)
plt.show()
作者图片
好了,差不多了。代码实际上运行了,并且在我试图实现的上下文中是有意义的,但是模型没有为实际的线性回归生成代码。让我们看看是否可以通过在我们的初始评论中添加更多的描述来改变这一点:
# write a linear regression model with sklearn
输出:
# write a linear regression model with sklearn
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
x = np.random.randn(100)
y = 2 * x + np.random.randn(100)
model = LinearRegression()
model.fit(x.reshape(-1, 1), y.reshape(-1, 1))
plt.scatter(x, y)
plt.plot(x, model.predict(x.reshape(-1, 1)))
plt.show()
作者图片
酷毙了。它实际上创造了一切,包括进口!从数据帧中绘图怎么样?
我写道:
# load a csv file and plot the numerical data using the date column as the x axis
输出:
# load data.csv and plot the "data" column with the "date" column as index
import pandas as pd
import matplotlib.pyplot as plt
data = pd.read_csv("data.csv", index_col="date", parse_dates=True)
data.plot()
plt.show()
作者图片
它没有专门绘制“数据”列,但是它将“日期”列设置为索引,这真的很酷。
现在,让我们尝试一个稍微高级一点的例子,让我们使用 NumPy 包从头开始编写一个简单的感知器:
# write a perceptron from scratch in numpy
输出:
# write a perceptron from scratch in numpy
import numpy as np
class Perceptron(object):
"""Perceptron classifier.
Parameters
------------
eta : float
Learning rate (between 0.0 and 1.0)
n_iter : int
Passes over the training dataset.
Attributes
-----------
w_ : 1d-array
Weights after fitting.
errors_ : list
Number of misclassifications in every epoch.
"""
def __init__(self, eta=0.01, n_iter=10):
self.eta = eta
self.n_iter = n_iter
def fit(self, X, y):
"""Fit training data.
Parameters
----------
X : {array-like}, shape = [n_samples, n_features]
Training vectors, where n_samples is the number of samples and
n_features is the number of features.
y : array-like, shape = [n_samples]
Target values.
Returns
-------
self : object
"""
self.w_ = np.zeros(1 + X.shape[1])
self.errors_ = []
for _ in range(self.n_iter):
errors = 0
for xi, target in zip(X, y):
update = self.eta * (target - self.predict(xi))
self.w_[1:] += update * xi
self.w_[0] += update
errors += int(update != 0.0)
self.errors_.append(errors)
return self
def predict(self, X):
"""Return class label after unit step"""
return np.where(X >= 0.0, 1, -1)
X = np.array([[0, 0, 1], [1, 1, 1], [1, 0, 1], [0, 1, 1]])
y = np.array([0, 1, 1, 0])
model = Perceptron(eta=0.1, n_iter=10)
model.fit(X,y)---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
TypeError: only size-1 arrays can be converted to Python scalars
The above exception was the direct cause of the following exception:
ValueError Traceback (most recent call last)
<ipython-input-31-38e27395dd1c> in <module>
60 y = np.array([0, 1, 1, 0])
61 model = Perceptron(eta=0.1, n_iter=10)
---> 62 model.fit(X,y)
<ipython-input-31-38e27395dd1c> in fit(self, X, y)
48 update = self.eta * (target - self.predict(xi))
49 self.w_[1:] += update * xi
---> 50 self.w_[0] += update
51 errors += int(update != 0.0)
52 self.errors_.append(errors)
ValueError: setting an array element with a sequence.
现在,这里有很多要解开的,虽然代码有一些错误,并不是开箱即用的,但它确实编写了非常引人注目的代码,经过一些编辑后就可以运行了。
我注意到的最酷的事情之一是,该模型还为函数编写注释,考虑到编写文档所呈现的上下文复杂性,这很有趣。除此之外, Cogram 也是上下文感知的(就像 VSCode 中的 Github copilot),所以如果你写了一个函数、变量或者类,它就能记住它。
关于数据科学和机器学习编码助手的总结性思考
我想指出的一点是,自从围绕软件 2.0 的讨论开始以来(可能甚至在那之前),加上像 GPT-3 这样极其强大的语言模型的发展,现在已经演变成了法典引擎,这种编写软件的风格变得越来越普遍,并且有一个很好的理由,我们最终关心的是为问题编写解决方案,而不是自己编写每一行代码来解决问题 x
这并不意味着我们应该相信语言模型并疯狂地使用自动完成功能,但对我来说很明显,在跨平台、跨编程语言的代码编写环境中,可能会出现一种智能的、经过深思熟虑的人机共生关系,并且思考如何将它集成到自己的工作流中可能是有意义的。
如果你喜欢这篇文章,加入媒体,关注,订阅我的简讯。还有,在 Twitter 、 LinkedIn 和 Instagram 上和我联系!谢谢,下次再见!😃
声明:这篇文章没有得到赞助,我也没有因为写这篇文章得到任何报酬
R 队列分析可视化
Adrien Delforge 在 Unsplash 上拍摄的照片
让 ggplot2 以优雅的方式可视化您的群组分析
如果你是 B2C(企业对消费者)行业的数据从业者,或者只是一个分析过一些消费者数据的数据极客,那么你很有可能必须熟悉群组分析。
群组分析是一种分析方法,其中我们首先将属于数据集的个体分组到具有特定时间跨度的不同群组中,在该时间跨度内,同一群组中的个体共享相同的特定经历。然后进行适当的分析,将这些组群作为分析单位。
在其他使用案例中,群组分析允许我们在执行特定指标时,观察用户保留率随时间的变化。这是通过比较不同年龄组的表现来实现的。
在本文中,我将分享如何创建群组分析可视化。为此,我们将使用 R 及其流行的 ggplot2 包。将显示两种群组分析可视化:线图和热图。
数据
使用的数据是在这个 Github 存储库中可用的relay-food
数据。该数据包含某个食品零售商的订单详细信息。在整篇文章中,我们只对每月一次的用户购买群体的可视化感兴趣。因此,我们将只考虑如下两列数据:
OrderDate
:订单发生的日期UserId
:用户 ID
形象化
线形图
和往常一样,首先要做的是导入必要的库。
# import libraries
library(dplyr) #handy data manipulation
library(ggplot2) #our today's super star
library(stringr) #to manipulate string date
library(ggthemes) #many nice themes
library(mdthemes) #handy text in plot formatting
library(gghighlight) #will abuse it a bit to show nice label
接下来加载数据。
#load the data
df = read.csv("relay-foods.csv")#inspect first 5 rows of the data
df %>% select(OrderDate, UserId) %>% head(5)
显然,OrderDate
栏的日期格式还不标准。因此我们需要调整它。
# adjust date formatting of OrderDate column
df$OrderDate = format(as.Date(df$OrderDate, '%m/%d/%Y'), '%Y/%m/%d')
df$OrderDate = gsub('00','20',df$OrderDate)
接下来,由于我们想要查看月度群组,我们需要从OrderDate
列派生出OrderMonth
列。
# create OrderMonth column from OrderDate (to make monthly cohort)
df$OrderMonth = str_sub(df$OrderDate,end = 7)
群组分析需要数据集中每个用户的群组信息,因此我们建立一个群组。
# create reference data frame of cohort group (month level)
cohort_group_df = df %>% group_by(UserId) %>%
summarize(CohortGroup = min(OrderDate))cohort_group_df$CohortGroup = str_sub(cohort_group_df$CohortGroup, end = 7) # join with the initial df
df = inner_join(df, cohort_group_df, by = 'UserId')
接下来,我们创建一个参考数据框架,其中包含每个群组的总用户数,以及每月购买的用户数。
# create reference data frame of total users for each cohort group
base_cohort_df = df %>% group_by(CohortGroup) %>%
summarise(
TotalUsers = n_distinct(UserId)
)# create purchase activity data frame
activity_cohort_df = df %>% group_by(CohortGroup, OrderMonth) %>%
summarise(
BuyingUsers = n_distinct(UserId)
)# join activity_cohort_df and base_cohort_df
user_cohort_df = inner_join(activity_cohort_df, base_cohort_df,
by = 'CohortGroup')
数据检查点。到目前为止我们得到了什么?
user_cohort_df %>% head(5)
注意OrderMonth
列仍然是上面的字符串格式。对于绘图,我们希望它是整数格式,成为 x 轴。
# transform OrderMonth to integer
user_cohort_df = user_cohort_df %>% group_by(CohortGroup) %>% mutate(MonthNumber = 1:n())
最后,我们将只绘制数据的子集,以避免过度绘制。
# subsetting the data
plot_user_cohort_df = inner_join(base_cohort_df[seq(1,11,2),c(“CohortGroup”)], user_cohort_df, by = “CohortGroup”)
在要画的情节中,我想在线条的末端有漂亮的图例。为此,我使用 gghighlight 包。我知道这有点不太好,所以如果你们知道更合适的方法,请在下面评论。
# dummy column for in-place legend
plot_user_cohort_df$dummy_col = 1
好了,我们完成了线图的数据准备工作。下面是数据的最终形式。
plot_user_cohort_df %>% head(5)
所以,我们准备有我们的第一个情节!
# plotting line plot
ggplot(plot_user_cohort_df) +
geom_line(aes(x = MonthNumber,
y = BuyingUsers/TotalUsers,
col = CohortGroup)) +
gghighlight(dummy_col == 1) +
scale_x_continuous(breaks = seq(from = 1, to = 15, by = 2)) +
scale_y_continuous(labels = scales::percent_format()) +
mdthemes::md_theme_solarized() +
labs(
title = "**Monthly User Purchasing Cohort**",
caption = "*Data: Relay Food order details (Source: github.com/ethen8181)*",
x = "K-th Month",
y = "Retention",
col = "Cohort Group"
)
图 1 —线形图中的队列分析
从图中可以得出结论,接力食品往往会遇到用户保留率降低的问题,因为年轻群体的保留率(2009-11 年)低于年长群体的保留率(2009-01 年)。
热图
根据我的经验,有些人更喜欢看到热图这类的图表来可视化这些群体。所以我们也画一个吧。
我们将继续上述工作,而不是从头开始。特别是我们将从user_cohort_df
开始。
# create base dataframe for heat map visualization
cohort_heatmap_df = user_cohort_df %>% select(CohortGroup, MonthNumber, BuyingUsers) %>%
spread(MonthNumber, BuyingUsers)# inspect data
cohort_heatmap_df %>% head(5)
我们还创建了数据的百分比版本。
# the percentage version of the dataframe
cohort_heatmap_df_pct = data.frame(
cohort_heatmap_df$CohortGroup,
cohort_heatmap_df[,2:ncol(cohort_heatmap_df)] / cohort_heatmap_df[["1"]]
)# assign the same column names
colnames(cohort_heatmap_df_pct) = colnames(cohort_heatmap_df)
接下来,我们融合两个数据帧以取悦 ggplot2。
# melt the dataframes for plotting
plot_data_abs = gather(cohort_heatmap_df, "MonthNumber", "BuyingUsers", 2:ncol(cohort_heatmap_df))
plot_data_pct = gather(cohort_heatmap_df_pct, "MonthNumber", "Retention", 2:ncol(cohort_heatmap_df_pct))
我们为热图准备标签。
# prepare label names containing absolute number of buyers for the first month and retention percentages for the rest months
label_names = c(plot_data_abs$BuyingUsers[1:(ncol(cohort_heatmap_df)-1)],plot_data_pct$Retention[(ncol(cohort_heatmap_df_pct)):(nrow(plot_data_pct))])
最后,我们把所有的东西放在一个数据框架中,准备绘图。
# beautify percentage labels
beauty_print <- function(n) {
case_when( n <= 1 ~ sprintf("%1.0f %%", n*100),
n > 1 ~ as.character(n),
TRUE ~ " ") # for NA values, skip the label
}# create dataframe ready for plotting
plot_data = data.frame(
CohortGroup = plot_data_pct$CohortGroup,
MonthNumber = plot_data_pct$MonthNumber,
Retention = plot_data_pct$Retention,
Label = beauty_print(label_names)
)
plot_data$MonthNumber = as.numeric(plot_data$MonthNumber)
热图可视化数据框架的最终形式如下。
plot_data %>% head(5)
击鼓!生成热图的代码如下。
# plotting heatmap
ggplot(plot_data) +
geom_raster(aes(x = MonthNumber,
y = reorder(CohortGroup, desc(CohortGroup)),
fill = Retention)) +
scale_fill_continuous(guide = FALSE, type = "gradient",
low = "deepskyblue", high = "darkblue") +
scale_x_continuous(breaks = seq(from = 1, to = 15, by = 1),
expand = c(0,0)) +
geom_text(aes(x = MonthNumber,
y = reorder(CohortGroup, desc(CohortGroup)),
label = Label), col = "white") +
mdthemes::md_theme_gray() +
labs(
title = "**Monthly User Purchasing Cohort**",
caption = "*Data: Relay Food order details (Source: github.com/ethen8181)*",
x = "K-th Month",
y = "Cohort Group"
)
图 2—热图中的群组分析
请注意,热图的第一列显示了在相应月份进行购买的用户的绝对数量。因此,这种队列可视化的热图版本比其折线图版本更加丰富,因为它提供了关于队列组绝对大小的更多背景信息。
在你走之前
在本文中,我们通过一步一步的 R 代码教程,以线图和热图的形式生成队列分析的优雅可视化。对于更喜欢跟踪 Github 代码的读者来说,本文的完整代码可以在我的 Github 库这里找到。
最后,感谢阅读,大家在 LinkedIn 上和我连线吧!👋
使用 Python 进行队列分析
每个电子商务数据分析师都必须掌握的数据聚类技能
介绍
如果你是一名为电子商务公司工作的数据分析师,你的工作任务之一很可能是从客户数据中发现洞察力,以提高客户保留率。
然而,客户数据是海量的,每个客户的行为都不同。2020 年 3 月获得的客户 A 表现出与 2020 年 5 月获得的客户 B 不同的行为。因此,有必要将客户分成不同的群,然后调查每个群随时间推移的行为。这叫做队列分析。
群组分析是一种数据分析技术,用于了解特定客户群体在一段时间内的行为。
在这篇文章中,我不会详细介绍群组分析的理论。如果你不知道群组分析是怎么回事,我强烈建议你先看看这篇博客。
这篇文章更多的是向您展示如何将客户分成不同的群组,并观察每个群组在一段时间内的保留率。
让我们开始吧!
导入数据和 python 库
你可以在这里下载数据。
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as snsdf = pd.read_csv('sales_2018-01-01_2019-12-31.csv')
df
VS 代码 2
将首次顾客与回头客分开
first_time = df.loc[df['customer_type'] == 'First-time',]final = df.loc[df['customer_id'].isin(first_time['customer_id'].values)]
简单地选择df.loc[df['customer_type']]
是不明智的。我来解释一下原因。在该数据中,customer_type
栏下的First_time
是指新客户,而Returning
是指回头客。因此,如果我在 2019 年 12 月 31 日首次购买,数据将显示我在 2019 年 12 月 31 日是新客户,但在我的第二、第三……时间是回头客。群组分析着眼于新客户及其后续购买行为。因此,如果我们简单地使用df.loc[df['customer_type']=='First-time',]
,我们将忽略新客户的后续购买,这不是分析群体行为的正确方法。
因此,我在这里所做的是,首先创建一个所有首次客户的列表,并将其存储为first_time
。然后从原始客户数据框架df
中只选择那些 id 属于first_time
客户组的客户。通过这样做,我们可以确保我们获得的数据只包含首次购买的客户以及他们随后的购买行为。
现在,让我们删除customer_type
列,因为它已经没有必要了。另外,将day
列转换成正确的日期时间格式
final = final.drop(columns = ['customer_type'])
final['day']= pd.to_datetime(final['day'], dayfirst=True)
先按客户 ID,再按日期对数据进行排序
final = final.sort_values(['customer_id','day'])final.reset_index(inplace = True, drop = True)
定义一些函数
def purchase_rate(customer_id):
purchase_rate = [1]
counter = 1
for i in range(1,len(customer_id)):
if customer_id[i] != customer_id[i-1]:
purchase_rate.append(1)
counter = 1
else:
counter += 1
purchase_rate.append(counter) return purchase_ratedef join_date(date, purchase_rate): join_date = list(range(len(date))) for i in range(len(purchase_rate)):
if purchase_rate[i] == 1:
join_date[i] = date[i]
else:
join_date[i] = join_date[i-1] return join_date def age_by_month(purchase_rate, month, year, join_month, join_year): age_by_month = list(range(len(year))) for i in range(len(purchase_rate)): if purchase_rate[i] == 1: age_by_month[i] = 0 else: if year[i] == join_year[i]: age_by_month[i] = month[i] - join_month[i] else: age_by_month[i] = month[i] - join_month[i] + 12*(year[i]-join_year[i]) return age_by_month
purchase_rate
功能将确定每位顾客的第二次、第三次、第四次购买。
join_date
功能允许我们识别客户加入的日期。
age_by_month
函数给出了客户从当前购买到第一次购买有多少个月。
现在输入已经准备好了。让我们创建群组。
创建群组
final['month'] =pd.to_datetime(final['day']).dt.monthfinal['Purchase Rate'] = purchase_rate(final['customer_id'])final['Join Date'] = join_date(final['day'], final['Purchase Rate'])final['Join Date'] = pd.to_datetime(final['Join Date'], dayfirst=True)final['cohort'] = pd.to_datetime(final['Join Date']).dt.strftime('%Y-%m')final['year'] = pd.to_datetime(final['day']).dt.yearfinal['Join Date Month'] = pd.to_datetime(final['Join Date']).dt.monthfinal['Join Date Year'] = pd.to_datetime(final['Join Date']).dt.year
final['Age by month'] = age_by_month(final['Purchase Rate'], final['month'],final['year'],final['Join Date Month'],final['Join Date Year'])
cohorts = final.groupby(['cohort','Age by month']).nunique()
cohorts = cohorts.customer_id.to_frame().reset_index() # convert series to framecohorts = pd.pivot_table(cohorts, values = 'customer_id',index = 'cohort', columns= 'Age by month')
cohorts.replace(np.nan, '',regex=True)
如何解读此表 以 cohort 2018–01 为例。2018 年 1 月,新增客户 462 家。在这 462 名顾客中,有 121 名顾客在 2018 年 2 月回来购买,125 名在 2018 年 3 月购买,以此类推。
转换成群组百分比
for i in range(len(cohorts)-1):
cohorts[i+1] = cohorts[i+1]/cohorts[0]cohorts[0] = cohorts[0]/cohorts[0]
(英)可视化(= visualization)
cohorts_t = cohorts.transpose()cohorts_t[cohorts_t.columns].plot(figsize=(10,5))sns.set(style='whitegrid')plt.figure(figsize=(20, 15))plt.title('Cohorts: User Retention')sns.set(font_scale = 0.5) # font sizesns.heatmap(cohorts, mask=cohorts.isnull(),cmap="Blues",annot=True, fmt='.01%')plt.show()
就是这样。希望你们喜欢这篇文章,并从中有所收获。如果你有任何问题,请在下面的评论区写下来。谢谢你的阅读。祝你今天愉快,新年快乐🎉🎉🎉
Colab Pro 与 Free-AI 计算性能
GPU 加速值不值得每月 10 美元的费用?
动机 : 当我考虑是否要为 Colab Pro 支付 10 美元的升级费用时,我主要关心的是“GPU 加速是否值得每月付费?”可悲的是,我无法找到一个好的来源来回答这个问题,所以我写了这个故事来帮助像我这样的人。😉
我应该升级到 Colab Pro 吗?如果你用谷歌搜索这个问题,你会发现很多很棒的文章。例如:
- GPU、RAM、高级训练时间对比 byDario rade CII:https://towardsdatascience . com/colab-pro-is-it-worth-the-money-32a 1744 f 42 A8
- Colab Pro 主要功能:https://colab.research.google.com/signup
- Reddit 讨论:https://www . Reddit . com/r/machine learning/comments/f0wm0l/n _ colab _ pro _ more _ ram _ longer _ run _ time _ faster _ GPU/
为了给正在进行的讨论带来一些新的东西,我将利用这篇文章在 Google Colab 的背景下更深入地探究他们在人工智能计算性能方面的差异。
背景
要比较不同 Colab 层的 AI 计算性能,只看硬件规格是不够的。最好的方法可能是在专业版和免费版上运行实际的、固定的 AI 模型,并查看它们完成固定训练工作的运行时间。
比较工具
为了进行比较,我们使用 AI 基准,这是来自 Github 的开源工具。这个工具是由苏黎世联邦理工学院的一组研究人员开发的,它通过运行下面的代码来工作。当我们执行代码时,工具会收集 19 个不同机器学习模型在特定数据集上的训练和推理时间。
得分
除了时间,该基准还根据预定义的分数来评估训练、推理和整体人工智能性能。尽管该工具没有明确解释得分公式,但我查看了它的源代码,并总结了下面的公式。
计算训练分数。作者图片
虽然它是训练分数的公式,但推理分数的计算方法类似,然后将它们的总和用作总的 AI 分数。我假设您可能希望在以下内容中更多地关注培训性能方面,因为 Colab 更多地用作研究工具,而不是部署。
比较
基准测试在以下时间进行:
- 仅带 CPU 的 Colab 免费(实验链接)
- Colab 免费与 T4 ( 实验链接
- 仅带 CPU 的 colab pro(实验链接)
- Colab pro 与 P100 ( 实验环节)
- Colab pro 带 V100 ( 实验环节)
Colab 在免费版本中支持 K80,但有一段时间没有看到它,所以不包括在内。至于 P100 和 V100,是由 Colab Pro 随机给出的。通常,P100 会有更大的机会。
作者图片
注: 为便于观察,图表中并未包含所有信息。这些模型由不同的数据集训练,因此跨模型比较运行时间不会有很大帮助。
训练分数排名
- 带 V100 的 colab pro—16289 分
- P100 的 colab pro—11428 分
- 与 T4 的免费可乐— 7155 分
- 仅带 CPU 的 Colab 免费 —187 分
- 仅带 CPU 的 colab pro**—175 分**
观察
我创建了这个谷歌表单来包含更多的细节。从那里,您可以观察到以下情况:
- 平均而言,配备 V100 和 P100 的 Colab Pro 分别比配备 T4 的 Colab Free 快 146%和 63%。(资料来源:“比较”表,表 E6-G8)
- 即使来自 Colab Pro 的 GPU 通常更快,但仍然存在一些异常值;例如,Pixel-RNN 和 LSTM 在 V100 上的训练速度比 T4 慢 9%-24%。(资料来源:“比较”表,表 C18-C19)
- 当只使用 CPU 时,Pro 和 Free 的性能相似。(来源:“培训”表,B 栏和 D 栏)
结论
如果你把训练时间长当成研究时的痛点,我强烈推荐你升级到 Colab Pro。例如,我发现自己每个月花在 Colab 上的时间超过 20 个小时,将近 50%的时间花在模型训练上。所以,Colab Pro 每个月给我节省了 20*0.5=10 多个小时。然而,如果我不是一个 Colab 的重度用户,或者有一个不同的地方来加速模型训练,用这 10 美元给自己买一个夏威夷广场似乎是一个更好的主意。
**同样,本文只关注 AI 计算性能。**在做出决定之前,您应该明确考虑其他方面,如 RAM、运行时等等。
免费的 4 个 V100 GPUs
如果你在寻找更多免费的 GPU 资源,我想介绍一下 AIbro ,一个无服务器的模型训练工具,我和我的朋友们目前正在开发。它可以帮助你用一行代码在 AWS 上训练 AI 模型。为了收集更多早期用户的反馈,我们现在为您提供免费的p 3.8x large(4x V100)版本。更多细节,你可能想看看我以前的故事:
**
AIpaca Inc .图片作者**
ColabCode:从 Google Colab 部署机器学习模型
启动 VS 代码服务器、Jupyter 实验室或 FastAPI
照片由 Niclas Illg 在 Unsplash 上拍摄
Google colab 是 Python 和数据科学爱好者最方便的在线 IDE。它于 2017 年向公众发布,最初是谷歌研究团队用于合作不同人工智能项目的内部项目。从那以后,由于其易于使用的界面,Jupyter 笔记本的相似性,以及 GPU 的支持,它获得了很大的人气。
大多数流行的机器学习库,如 numpy,pandas,seaborn,matplotlib,sklearn,TensorFlow,都预装在这个云环境中,因此您不需要任何显式的先决条件。您也可以安装您选择的任何 python 包来运行您的代码。在本文中,我将向您解释一种使用 FastAPI 和 ngrok 将您的机器学习模型部署为 API 的简单方法。
什么是 FastAPI?
它是一个用 Python 构建 API 的高性能 web 框架。传统上,大多数开发人员使用 flask 作为构建 API 的首选,但由于一些限制,但不限于数据验证、身份验证、异步等,FastAPI 获得了很大的流行。FastAPI 通过 pydantic 模型提供自动文档生成功能、身份验证和数据验证。要详细了解这两个框架之间的显著差异,您可以在这里查看我关于分析 Vidya 的文章:
https://www.analyticsvidhya.com/blog/2020/11/fastapi-the-right-replacement-for-flask/
FastAPI 有助于设置生产就绪的服务器,但是如果您想在将它部署到实际的云平台(如 Heroku)之前与您的团队共享,该怎么办呢?ngrok 通过隧道将您的本地主机暴露给互联网来解救您。现在,任何人都可以通过提供的链接访问您的 API 端点,但是如果所有这些都只能在 Google Colab 上完成呢?解决这个问题的方法是 ColabCode!
什么是 ColabCode?
它是一个 Python 包,允许您直接从您的 Colab 笔记本上启动代码服务器,而无需在您的系统上进行任何本地设置。它可以用来启动 VS 代码环境、Jupyter 实验室服务器,或者将 FastAPI 服务器隧道连接到 web,所有这些都在 colab 笔记本中。这对于那些在云上训练他们的模型,并且现在想要以 API 的形式与世界分享他们的发现的爱好者来说是一个很好的加分点。我们将讨论 ColabCode 的所有功能,直到本文结束。
为 ColabCode 准备 FastAPI 代码
我将在本文中使用的问题陈述是一个决策树分类器,用于在两种音乐流派之间进行分类:Hip-Hop 或 Rock。我已经清理了数据集,它在我的 GitHub 库上。现在我已经有了数据集,我简单地把它导入笔记本并训练了一个决策树模型,没有任何预处理或 ed a 的东西,因为本文更多的是关于部署。所以这个模型可能会返回一些错误的结果!
模型创建代码
- 现在,如果您知道 FastAPI 架构,我们将需要一个数据类作为输入。这个数据类允许 FastAPI 验证要发送给模型的输入,如果给出了任何错误的输入,它只是引发错误,而不会将错误提供给模型。
- 创建数据类非常简单,只需要接受参数和数据类型。为了进一步定制,您还可以添加一个定制示例来快速测试结果。这个类的代码是:
数据类别代码
3.现在,我们需要创建一个服务所有请求的端点。FastAPI 中的端点创建与 flask 非常相似,只需要端点函数接受数据类进行验证。
FastAPI 代码
如果你想探索一些很酷的项目,请查看我的 GitHub 档案:
https://github.com/kaustubhgupta
可乐码
我们的 FastAPI 已经准备好了,现在唯一需要的就是通过 colab 环境运行它。首先,导入这个包并初始化服务器:
from colabcode import ColabCodeserver = ColabCode(port=10000, code=False)
端口号可以由您选择,代码参数应该为 false。现在,服务器已经准备好接收 FastAPI 对象,在 ngrok 的帮助下,本地主机通过一个唯一的 URL 被隧道化并暴露给公众。
server.run_app(app=app)
就这样!你将得到一个 ngrok URL,你可以与你的社区、团队或任何人分享。一旦你终止了单元格进程,链接就会失效,如果你不这样做,Google Colab 会在一段时间后终止它。此过程的 GIF 示例如下所示:
作者 GIF
在这里,单击链接后,我导航到 FastAPI 自动生成的端点/文档,在这里,我们可以测试结果。如果你想运行并尝试这个东西,这里有完整的笔记本代码。打开笔记本运行所有单元格。
作者代码
其他功能
ColabCode 并不局限于在 Colab 上运行 FastAPI 代码还可以提供 VS 代码服务器和 Jupyter 实验室服务器!它可以帮助用户对基于云的服务有一个熟悉的环境。资源非常有限的用户也可以从这些服务中受益。它变得非常类似于新引入的 GitHub Codespaces,它在 web 上提供 VS 代码环境。要通过 ColabCodes 运行 VS 代码服务器,请执行以下操作:
from colabcode import ColabCode
ColabCode()
您将被提示一个 ngrok URL,加载完成后,您将在 web 浏览器上运行 VS 代码,如下所示:
作者图片
类似地,如果您想打开一个 Jupyter 实验室服务器,将 lab 参数作为 true 传递,将 code 作为 false。
from colabcode import ColabCode
ColabCode(code=False, lab=True)
您将获得一个 URL 和一个令牌,用于对服务器进行身份验证。输入令牌并点击 login,会出现类似如下的屏幕:
作者图片
结论
在本文中,我解释了 ColabCode 提供了什么,并简单介绍了 FastAPI。目前,该软件包的创建者 Abhishek Thakur 发布了 v0.2.0。如果您想投稿,请查看这个包的 GitHub 库。
说到这里,这篇文章就结束了,我希望你能有新的想法,我会通过其他文章加入你的反馈。
我的领英:
https://www.linkedin.com/in/kaustubh-gupta/
我的其他热门文章:
数据科学家和数据工程师之间的协作变得简单
如何在您的数据科学家和数据工程师之间创造协同效应
DayTwo 拥有世界上最大的微生物数据库,拥有超过 85K 个独特的基因组序列。分析高达数百 TB 的海量数据需要可靠而坚实的工程基础设施,能够由多名数据科学家同时进行持续探索和分析。
数据科学家需求清单
在我们开展的每个研究项目的核心,都有数据分析部分,我们的数据科学家需要分析和探索海量数据,以寻找有价值的商业见解。这种探索应该仔细设计,因为不理解基础设施的限制可能会导致失望和浪费时间。
因此,在每次实验之前,我们都会查看一份简短的清单,以展示我们可能会遇到的一些依赖和障碍:
- 我们的输入和输出数据的实际大小是多少
- 根据上面的大小,需要多少内存?
- 我们应该在 jupyter 笔记本还是 VS-Code 上运行它?
- 我们应该投资并行吗?
值得注意的是,并不是所有的实验都需要分析大量的数据。但是为了这篇文章,我们假设情况就是这样。
数据工程师前来救援
在我们看来,数据工程师是我们数据科学家工作的重要组成部分。在一个没有我们的数据工程师支持的研究项目中工作看起来会有很大的不同,而且不是一种好的方式。它从收集和查询数据的可靠基础设施开始,继续到特征选择和模型训练,当适当的工具和脚本可用时,项目的任何方面都可以被简化和更好地结构化。
托德·夸肯布什在 Unsplash 上的照片
回到我们分析数十 TB 数据的使用案例,我们通过定义一个用于发送和接收数据的共享通道来利用我们的数据工程团队的能力。
更简单的说,我们定义了两个核心组件: (1) 我们应该计算的计算量。 (2) 应该使用的相关数据子集。
通过这种方式,每个复杂且未记录的分析任务都变得结构化且易于跟踪,这使我们的研究人员能够专注于寻找见解,并将它们从科学家通常遇到的大多数工程麻烦中清除。
作者图片
收场白
数据工程师早已成为每家科技公司必不可少的一部分。在 DayTwo,除了他们“组织公司数据库的琐碎角色之外,我们还利用他们在构建工具和基础架构方面的渊博知识来简化我们的数据科学团队工作流。将我们的数据工程师整合到我们的数据科学流程中,使我们能够扩展我们的研究和数据分析能力,此外还有一个显而易见的好处,即让更多人了解当前最热门的话题之一——m lops。
如果你想了解更多关于我们正在开发的最新最棒的产品,请随时联系我。
协作友好的 SQL 查询
数据工程和数据科学
提高 SQL 查询质量和更好协作的一些技巧
作者照片。
一个数据管道卡住了,需要有人注意。或者需要使用新表重构查询,因为其中一个使用的表已经过时或不可用。或者我们需要向非常旧的数据管道的 SQL 逻辑中添加更多内容。
在所有这些情况下,几分钟后我们会有一种感觉。我们要么感谢以前的代码作者,要么被困在数百行 SQL 查询中。我敢打赌,大多数人(如果不是全部的话)都希望自己的工作得到赏识。然而,许多数据工程师和数据科学家不知道如何以协作友好的方式设计 SQL 查询。
本文将为您提供一些基本的技巧,帮助您开发专业的、协作友好的 SQL 查询和数据管道。
避免选择*
不要误解我,我经常使用 SELECT *,但只是在临时的特别查询中使用,以调查表或进行快速数据检查。很少在非临时的管道或查询中使用 SELECT *。
不使用 SELECT *很重要的原因是,当您希望以后更新或重构您的管道或查询时。更新查询(例如,用另一个表替换一个表)的第一件事是了解查询/管道中使用了哪些列。让我们考虑一个例子。
假设我们正在维护一个表,用于根据一些度量标准来识别我们的高级员工。出于某种原因,我们不能再使用performance_review
表了(例如,因为一些隐私问题)。我们的任务是用其他可访问的表替换performance_review
表。
WITH current_senior_employees AS (
SELECT *
FROM employee
WHERE age>=45
AND is_current = true
AND years_in_company >= 6
),
performance_last_5years AS (
SELECT *
FROM performance_review
WHERE year BETWEEN 2016 AND 2020
)
SELECT
ARBITRARY(a.first_name),
ARBITRARY(a.last_name),
ARBITRARY(a.email),
SUM(b.num_of_managed_employees) AS total_num_managed_employees,
SUM(b.num_of_managed_projects) AS total_num_of_managed_projects,
SUM(b.revenue_generated_by_managed_projects) AS total_revenue
FROM current_senior_employees AS a
LEFT JOIN avg_performance_last_5years AS b
ON a.id = b.employee_id
GROUP BY b.employee_id
如您所见,由于 SELECT *的误用,我们无法轻松识别维护该表需要哪些表中的哪些列。我们需要更深入地研究代码,找出num_of_managed_employees
、num_of_managed_projects
、revenue_generated_by_managed_projects
和employee_id
是我们应该在其他表中找到的列。当然,与实际工作中的常规查询相比,我的示例非常小,并且不难发现使用了哪些列。但是在实际项目中,一个查询可能包含数百行和数十个连接的表。在这些情况下,如果程序员首先使用 SELECT *读取所有内容,然后从一堆加载的列中选择列,那么深入代码找出哪些列来自哪些表是非常困难的。
在我的例子中,编写这个查询的更好的方法是:
WITH current_senior_employees AS (
SELECT
id,
first_name,
last_name,
email
FROM employee
WHERE age>=45
AND is_current = true
AND years_in_company >= 6
),
performance_last_5years AS (
SELECT
employee_id,
num_of_managed_employees,
num_of_managed_projects,
revenue_generated_by_managed_projects
FROM performance_review
WHERE year BETWEEN 2016 AND 2020
)
SELECT
ARBITRARY(a.first_name),
ARBITRARY(a.last_name),
ARBITRARY(a.email),
SUM(b.num_of_managed_employees) AS total_num_managed_employees,
SUM(b.num_of_managed_projects) AS total_num_of_managed_projects,
SUM(b.revenue_generated_by_managed_projects) AS total_revenue
FROM current_senior_employees AS a
LEFT JOIN avg_performance_last_5years AS b
ON a.id = b.employee_id
GROUP BY b.employee_id
使用别名
一个不好的做法是在连接多个表时避免使用别名。看下面的例子。
WITH current_senior_employees AS (
...
),
performance_last_5years AS (
...
)
SELECT
ARBITRARY(first_name),
ARBITRARY(last_name),
ARBITRARY(email),
SUM(num_of_managed_employees) AS total_num_managed_employees,
SUM(num_of_managed_projects) AS total_num_of_managed_projects,
SUM(revenue_generated_by_managed_projects) AS total_revenue
FROM current_senior_employees
LEFT JOIN avg_performance_last_5years
ON id = employee_id
GROUP BY employee_id
这是与上一节相同的例子。唯一的区别是我在这里没有使用别名(例如,a
和b
)。在这个例子中,很难判断出email
列来自哪个表。仅仅因为列名是唯一的,就不应该停止使用别名(尤其是在连接多个表时)。
现在想象一下,如果我除了不使用别名之外还使用 SELECT *的话。
WITH current_senior_employees AS (
SELECT *
FROM employee
WHERE age>=45
AND is_current = true
AND years_in_company >= 6
),
performance_last_5years AS (
SELECT *
FROM performance_review
WHERE year BETWEEN 2016 AND 2020
)
SELECT
ARBITRARY(first_name),
ARBITRARY(last_name),
ARBITRARY(email),
SUM(num_of_managed_employees) AS total_num_managed_employees,
SUM(num_of_managed_projects) AS total_num_of_managed_projects,
SUM(revenue_generated_by_managed_projects) AS total_revenue
FROM current_senior_employees
LEFT JOIN avg_performance_last_5years
ON id = employee_id
GROUP BY employee_id
即使对于简单的查询,使用 SELECT *并避免使用别名也会导致很大的混乱。
请记住,使用别名可以使您的查询更易读、更容易理解。
没有无意义的别名
停止使用无意义的别名,如 a、b、c 等等。不使用别名之后的下一件坏事就是使用无意义的别名。在数据工程师和科学家中,当他们连接表时,使用像 a 和 b 这样的简单别名是很常见的。我不反对将 a 和 b 用于临时的特别查询,但是我不会将它们用于长期查询或管道。当你和别人分享一个查询或者很久以后再回到你的查询,用没有意义的别名是不容易理解的。同样,对于像上一个例子一样的超短查询,不难发现 a 和 b 指的是什么,但是当查询变长时,它会占用我们太多的短期记忆来理解查询并在必要时修复它。例如,在我的查询中,我可以使用:
WITH current_senior_employees AS (
SELECT
id,
first_name,
last_name,
email
FROM employee
WHERE age>=45
AND is_current = true
AND years_in_company >= 6
),
performance_last_5years AS (
SELECT
employee_id,
num_of_managed_employees,
num_of_managed_projects,
revenue_generated_by_managed_projects
FROM performance_review
WHERE year BETWEEN 2016 AND 2020
)
SELECT
ARBITRARY(employee.first_name),
ARBITRARY(employee.last_name),
ARBITRARY(employee.email),
SUM(perform.num_of_managed_employees)
AS total_num_managed_employees,
SUM(perform.num_of_managed_projects)
AS total_num_of_managed_projects,
SUM(perform.revenue_generated_by_managed_projects)
AS total_revenue
FROM current_senior_employees AS employee
LEFT JOIN avg_performance_last_5years AS perform
ON employee.id = perform.employee_id
GROUP BY perform.employee_id
cte 很友好
不要害怕使用 cte。我见过数据工程师和科学家使用复杂的嵌套子查询来避免使用 cte(没有明显的原因!).让我向您展示如果我使用子查询而不是 cte,我的示例查询是如何变得复杂的。
SELECT
ARBITRARY(employee.first_name),
ARBITRARY(employee.last_name),
ARBITRARY(employee.email),
SUM(perform.num_of_managed_employees)
AS total_num_managed_employees,
SUM(perform.num_of_managed_projects)
AS total_num_of_managed_projects,
SUM(perform.revenue_generated_by_managed_projects)
AS total_revenue
FROM (
SELECT
id,
first_name,
last_name,
email
FROM employee
WHERE age>=45
AND is_current = true
AND years_in_company >= 6
) AS employee
LEFT JOIN(
SELECT
employee_id,
num_of_managed_employees,
num_of_managed_projects,
revenue_generated_by_managed_projects
FROM performance_review
WHERE year BETWEEN 2016 AND 2020
) AS perform
ON employee.id = perform.employee_id
GROUP BY perform.employee_id
想象一下,如果我们有几十个连接的表(有时是嵌套的),这会有多复杂。请记住,使用 cte 有多种好处:
- cte 对人类的短记忆是友好的(更有条理)。
- 您可以在一个查询中多次使用 CTE,使您的查询更有条理(与子查询相反)。
使用 JINJA2 的基本查询
Jinja2 非常受数据工程师和科学家的欢迎,用于开发数据管道。它使他们能够通过Template()
函数进行动态查询和压缩大型 ETL 查询。这里我只关注 Jinja2 数百个模板应用中的一个。我的重点是向您展示 Jinja2 模板如何帮助您编写更清晰的 SQL 查询。
如果管道中有多个查询使用相同的 CTE 或子查询,请考虑使用定义一个基本查询,并通过 Jinja2 在查询中替换它。下面是一个伪查询的例子。
WITH cte1 AS (
SELECT ...
FROM table3
JOIN (
**SELECT
...
FROM table1
JOIN table2
ON table1.col1 = table2.col2
WHERE ...
AND ...**
) AS table_x
ON ...
WHERE ...),
cte2 AS (
SELECT ...
FROM table4
JOIN (
**SELECT
...
FROM table1
JOIN table2
ON table1.col1 = table2.col2
WHERE ...
AND ...**
) AS table_x
ON ...
WHERE ...),
)
SELECT
...
FROM cte1
JOIN cte2
ON ...
WHERE ...
如果仔细观察,您会注意到粗体子查询在cte1
和cte2
中重复出现。使用 Jinja2 模板(例如,在 Python 中),您可以为重复查询定义一个基本查询,并在主查询中替换它。您可能会认为我们可以定义一个 CTE,而不是在这个例子中使用 Jinja2 模板。你完全正确!如果管道中只有一个带有这种子查询的查询,使用 CTE 是更好的解决方案。但是,如果您的管道中有多个单独的查询(例如,用于不同的任务)使用同一个子查询,那么您可以使用 Jinja2 模板在它们之间共享同一个查询。
如果你不知道如何使用 Jinja2 模板,这里有一个 Python 中的例子。
from jinja2 import Templatebase_query = """
SELECT
...
FROM table1
JOIN table2
ON table1.col1 = table2.col2
WHERE ...
AND ...
"""main_query = Template("""
WITH cte1 AS (
SELECT ...
FROM table3
JOIN ({{subquery}}) AS table_x
ON ...
WHERE ...),
cte2 AS (
SELECT ...
FROM table4
JOIN ({{subquery}}) AS table_x
ON ...
WHERE ...),
)
SELECT
...
FROM cte1
JOIN cte2
ON ...
WHERE ...
""").render(subquery=base_query)
一些最终(但重要!!!)小贴士
最后,我想给你一些重要的一般性建议,告诉你如何设计你的查询或管道,以实现更好的协作。
由于大多数关系数据库系统的查询优化特性,您编写的查询在执行之前就得到优化。因此,在许多情况下,您可能会编写一个低效的查询(例如,将所有列加载到一个 CTE 中,然后选择列)。但是,优化器会找到一个最佳的查询计划来执行,并且机器性能仍然很好。但是,请记住,仅仅因为优化器帮助您获得了更好的性能,并不意味着您可以按照自己喜欢的方式编写查询。我们必须体谅现在和将来与我们合作维护代码的人。
最后,如果您认为有些事情在查询开发阶段可能会花费您的时间,但它会为阅读它的人节省时间,那么您必须这样做。例如,找到并使用一个合适的别名而不是随机的“a”或“b”可能会花费你一点时间,但是它会为后来阅读它的人(甚至是你自己)节省很多时间。
简化的协同过滤:推荐系统背后的基础科学
入门
简介
在做出消费者决策时,我们似乎经常在有意识地选择我们使用的服务和我们偏好的产品。然而,竞争我们业务的公司不断以微妙的方式影响我们的决策。公司经常推荐特定的产品,以增加我们选择他们而不是竞争对手的可能性,我们接触到的产品选项组合越来越符合我们的个人偏好。这是基于这样一种理论,即某人更有可能购买和享受符合其偏好的产品。推荐系统允许公司提高用户参与度,增加销售额,并不断调整产品以适应用户的偏好[1]。实际上,我们看到的歌曲或产品的推荐列表可能看起来很简单。然而,一个复杂、直观的工程过程在幕后产生这个列表。
推荐系统利用从用户行为产生的数据来推断用户偏好。在 Spotify,用户数据可以是歌曲选择,而亚马逊经常根据用户观看的产品、购买的产品和对产品的评论进行推荐。如何实现推荐系统的细节由用例决定,但是已经有了生成推荐的通用技术。最显著和最强大的技术是协同过滤,我们现在将进一步探讨它。
协同过滤
协同过滤使用大量关于用户交互的数据来生成一组推荐。协同过滤背后的想法是,对某些项目有相似评价的用户现在和将来都会喜欢同样的东西[2]。例如,假设用户 A 和用户 B 都喜欢项目 X 和 y。基于该信息,我们可以假设用户 A 和 B 具有相似的偏好。因此,如果用户 B 喜欢项目 Z,我们可以向用户 a 推荐项目 Z。这种从用户之间的相似性中寻找推荐的过程就是这种技术被称为“协作”过滤的原因。
驱动协同过滤系统的交互数据可以经由显式提示从用户处获得,或者从用户行为中隐式提取。在显式数据的情况下,用户提供关于他们喜欢某个项目的程度的清楚和直接的数据。这通常是用户被明确提示提供的“喜欢”或等级(见下图)[5]。也可以隐含地收集用户偏好数据。这需要根据跟踪的行为间接推断用户是否更喜欢某个项目。这些行为可以包括用户浏览了哪些页面,他们点击了哪里,他们花了多少时间看一些东西,等等[3]。例如,如果用户长时间查看某个项目,这通常意味着他们喜欢该项目或对其感兴趣。
亚马逊要求顾客评论的例子(截图直接来自 Amazon.com)
一旦收集了交互数据,接下来的问题就是如何将这些数据转化为推荐?最流行的方法之一是称为矩阵分解的强大的线性代数技术。矩阵分解为应用协同过滤提供了具体的数学基础,因为它允许我们将交互数据转换成确定用户是否会喜欢某个项目的模型。
矩阵分解
为了理解矩阵分解,我们必须了解矩阵乘法是如何工作的。矩阵是一组按行和列排列的数字,形成一个数组。当两个矩阵相乘时,结果矩阵的行数与第一个矩阵相同,列数与第二个矩阵相同。对于结果矩阵中的每个元素,我们在第一个矩阵中取相应的行,在第二个矩阵中取相应的列。然后,我们将所选行和列的相应元素相乘,并将结果相加。下图显示了该过程如何工作的示例。结果矩阵中的值 75 在第一行,所以我们选择第一个矩阵的第一行。值 75 也在第一列中,所以我们选择第二个矩阵的第一列。然后将行和列中的相应值相乘,并将结果相加,得到值 75。
矩阵乘法的一个例子(图片由作者提供)
乘法就是可以通过因式分解的过程来倒推。例如,3 和 4 相乘得到数字 12。然后,数字 12 可以分解为因子 3 和 4,因为它们相乘得到 12。同样的事情也可以用矩阵来做。对于大多数矩阵,存在两个矩阵因子,它们相乘得到同一个矩阵,或者是一个非常接近的矩阵。在上图中,第三个矩阵可以分解为前两个矩阵。这是因为将这两个矩阵相乘会得到第三个矩阵。为给定矩阵寻找两个因子的过程称为矩阵分解。
在推荐系统中,用户交互存储在一个大矩阵中。考虑电影推荐系统的情况。在矩阵的一个轴上,我们可以有不同的用户,而在另一个轴上是不同的电影。矩阵中的每个值对应于用户对该电影的喜爱程度(隐式或显式,取决于收集的数据)。然后,我们可以得到这个矩阵,并应用矩阵分解。结果因子将是表示用户偏好的矩阵和表示电影的矩阵。让我们看一个例子来获得更多关于这是如何工作的直觉。
协作过滤示例
此图像用于以下协作过滤示例。蓝色数字是未收集的数据。它们表示通过执行矩阵分解做出的预测(图片由作者提供)。
考虑上图中有三个用户和三部电影的情况。黑色轮廓的矩阵代表交互数据。绿色和红色的数字是通过观察用户动作收集的,而蓝色的数字是通过执行矩阵分解生成的。如果值为 1,则用户喜欢相应的电影,如果值为 0,则用户不喜欢。
交互矩阵已经被分解为用户和项目的嵌入矩阵。两个新矩阵中的数字使得两个矩阵相乘得到相互作用矩阵。例如,为了得到交互矩阵左上角的值,我们对用户矩阵中第一行和项目嵌入矩阵中第一列的相应元素的乘积求和。这个值是 11 + 00 = 1,与左上交互值相匹配。注意,以前未知的蓝色值现在可以通过应用相同的过程得到。例如,可以使用用户矩阵的第二行和项目矩阵的第二列来计算用户 User 2 喜欢蝙蝠侠的程度的值。
检查交互值将表明我们的协同过滤应用已经成功了!请注意,用户 1 和 2 有相似的偏好,因为他们都喜欢超人,不喜欢《冰雪奇缘》。因此,因为用户 1 喜欢蝙蝠侠,所以用户 2 也可能喜欢蝙蝠侠,这由该点中蓝色生成的值 1 所证实。相反,请注意,用户 3 的偏好与用户 1 和 2 非常不同。因此,由于这两个用户都喜欢蝙蝠侠,用户 3 可能不喜欢蝙蝠侠,这一点由我们在该点生成的蓝色值 0 所证实。这个简单的例子演示了矩阵分解如何确定用户是否喜欢某个项目。通过推荐用户最可能喜欢的项目,这些信息可以转化为推荐。实际上,数据集会更大,计算会更复杂。虽然本例中的值是手工设计的,但生产级推荐系统的计算将使用内置机器学习功能的库自动处理[4]。
我们还没有解决的一件事是,这些推荐是如何在没有定义任何电影信息的情况下做出的。在我们的例子中,我们知道蝙蝠侠和超人都是动作片,而《冰雪奇缘》是一部更面向家庭的电影。然而,我们从来没有定义过电影的类型,但是无论如何,检查用户行为仍然会导致似乎考虑电影类型的预测。潜在特征使得在没有关于项目的定义信息的情况下推荐项目的能力成为可能。潜在特征是我们没有明确定义的项目特征或用户偏好。然而,在寻找一组能够解释我们的相互作用数据的嵌入矩阵值时,矩阵分解中使用的计算无意中发现了一组相关特征。这是因为潜在特征首先影响了用户交互。这些特征可以是从流派信息到价格的任何东西。没有办法明确知道哪些特性会生效,但是我们通常可以根据我们推荐的项目类型进行假设[5]。潜在特征提供了协作过滤的真正力量,因为它们给大量数据带来了秩序。这最终为用户提供了可能是准确的推荐。
冷启动问题
关于协同过滤的最后一件事是它最大的缺点,冷启动问题。你可能已经注意到,在我们之前的例子中,我们能够确定用户 2 和 3 有多喜欢蝙蝠侠,因为我们知道用户 1 有多喜欢它。然而,如果我们不知道用户 1 对这部电影的想法,我们如何为其他 2 个用户做出预测呢?当然,我们可以意识到蝙蝠侠是一部动作片,类似于超人。这意味着用户 2 可能会喜欢,而用户 3 不会。然而,这违背了在协同过滤中使用潜在特征的目的。这种难以预测没有交互数据的项目的问题被称为冷启动问题。
当协作过滤系统最初被创建时,由于缺乏关于用户偏好的信息,它通常是无效的。这阻碍了这种类型的推荐系统的性能,并且可能导致它在用户基数小或者项目太多的情况下无效。通常,这可以通过存储关于每部电影的一些相关的显式特征信息(例如,流派、评级等)来解决。)并将其与用户过去的偏好进行匹配。由于冷启动问题,这种混合方法在现实世界中经常发生。
入门指南
现在我们已经回顾了基础知识,您可以开始探索一些工具并创建您自己的推荐系统。许多编程语言都可以用来创建推荐系统,但最常用的是 Python。Python 有很棒的工具,比如 pandas 和 NumPy,它们可以让你将交互数据转换成一种便于计算的形式。TensorFlow 和 PyTorch 等工具具有内置功能,可以处理协作过滤所需的强大计算。
推荐系统在现代商业中已经变得非常普遍。它们允许公司通过根据用户的偏好定制产品来实践先进的微营销策略。推荐系统的力量只会继续增长,因为它们从我们的行为中学到了更多关于我们个人偏好的东西。有了这些工具和我们在这里讨论的概念,你将有一个很好的开始来创建你自己的推荐系统,并在你自己的企业中利用技术的力量。
注意:本文主要介绍了协同过滤的基础知识,并提供了一个简单的例子来说明它是如何工作的。您可以期待未来的一些更高级的文章,介绍构建功能性推荐系统的技术步骤!
参考
[1] C. Underwood,“商业中推荐系统的使用案例——当前应用和方法”,Emerj ,2020 年 3 月 4 日。【在线】。可用:https://emerj . com/ai-sector-overviews/use-cases-recommendation-systems/。【访问时间:2020 年 10 月 10 日】。
[2] V .鞍马,《协同过滤简单介绍》,内置,04-Sep-2019。【在线】。可用:https://builtin . com/data-science/collaborative-filtering-recommender-system。【访问时间:2020 年 10 月 10 日】。
[3] S .罗,《推荐系统导论:协同过滤》,中,2019 年 2 月 6 日。【在线】。可用:https://towards data science . com/intro-to-recommender-system-collaborative-filtering-64a 238194 a26。【访问时间:2020 年 10 月 10 日】。
[4]“协同过滤|推荐系统|谷歌开发者”,谷歌。【在线】。可用:https://developers . Google . com/machine-learning/recommendation/collaborative/basics。【访问时间:2020 年 10 月 10 日】。
[5] P. Pandey,《现实世界中的推荐系统》,中,2019 年 5 月 25 日。【在线】。可用:https://towardsdatascience . com/recommendation-systems-in-the-real-world-51e 3948772 f 3。【访问时间:2020 年 10 月 10 日】。
使用 fast.ai 的协同过滤
了解推荐系统
想知道网飞是如何为用户推荐合适的内容的吗?这一深度探讨集中在推荐系统和嵌入[潜在因素]上,以从用户-项目交互中获得意义。如果你以前没有使用过推荐系统,这个博客对你来说是一个完美的开始。本文描述的模型使用 fast.ai 库,并假设您对 python 编程语言以及 PyTorch 有基本的了解。让我们开始吧。
在 Unsplash 上由 Sayan Ghosh 拍摄的照片
数据分析
首先,让我们熟悉一下“电影镜头”数据集。要将数据输入 jupyter 笔记本,只需运行下面的单元格。fast.ai 函数会帮你完成剩下的工作。
注意:该数据集使用 100,000 个电影排名的子集。
样本收视率数据
收视率数据正是我们所需要的。用户栏、电影 id、相应的评级和时间戳。为什么要建立模型?因为评价是不完整的,并且推荐者试图为用户以前没有看过的电影填充缺失的评价。
了解潜在因素
对于那些不熟悉推荐系统的人来说,这是重要的一步。潜在因素基本上是为数据集中的每个用户和电影随机初始化的参数。如果您在这一点上没有得到它,也不要太担心,但请尝试并了解这些潜在因素在协同过滤中的作用(下面的解释)。
假设我们知道用户喜欢一部电影所属类别(流派)的程度。现在假设我们也知道关于每部电影的相同信息[即电影与这一类别的紧密程度]。现在,为了填补缺失的评级,只需将这两个潜在因素相乘。答案是你对那部电影的预测评分。信息太多?让我们看一个小例子来理解这个概念。
尝试运行下面这段代码的代码块:
这里假设潜在因子的范围在-1 和 1 之间,正数表示强匹配,负数表示弱匹配。这个例子中的类别是“科幻小说”、“动作片”和“老电影”。也就是说,电影《原力觉醒》有它的潜在因素:1 为 0.98,表示它“有多科幻”,潜在因素:2 为 0.9,表示它“有多动作”,潜在因素:3 为-0.9,表示它“有多老”。
科幻电影预测
言情电影预测
我们在这里做了什么?我们基本上是将两个潜在向量/因子相乘,然后将它们的结果相加。如果你想用数据科学术语,你可以称之为“点积”。很简单,对吧?对于数据集中的每个用户和电影都会发生这种情况,这就是该模型的基本原理。从上面的例子中,你可以清楚地看到我对科幻/动作电影感兴趣,所以《原力觉醒》[2015]的评分高于《一个明星诞生》[1937]。
重要提示:正如这里提到的,评级预测基本上是潜在因素的点积。一旦计算了点积,该模型就试图通过调整潜在因子来最小化损失(使用随机梯度下降,本文将不讨论其细节,但模型实现将简要解释其功能)。
就这样—让我们从实际的代码开始:)
创建数据加载器
为了使这成为一个有趣的练习,让我们将电影片名引入到我们的数据集中,并将它们与收视率数据合并。表“u.item”由映射到标题的电影 ID 组成,所以让我们把它们拖进来。
为了更好的直觉,标题被合并
Dataloaders 对象通常将第一列作为用户,第二列作为项目,评级作为第三列。由于我们的项目是电影,我们将其重命名为“标题”,批量大小为 64。
协同过滤的 PyTorch 表示
潜在因素需要以某种方式表示出来,以便我们对模型有所了解。pyTorch 表示它们的方式是使用矩阵。这是使用“torch.randn”函数完成的。工作原理是——py torch 根据用户和电影的总数随机创建用户和电影潜在因素。然后用点积来得出评级。我们已经确立了这一点。但是要做这个点积,就要在我们的电影潜在因子矩阵中查找电影的索引,在用户矩阵中查找用户索引。这不是深度学习模型知道的。这就需要嵌入【一个很简单的话题】。
在我们继续之前,请随意查看 pyTorch 如何在没有嵌入的情况下创建以下潜在因素:
嵌入
尽管“嵌入”这个术语听起来很奇怪,但其基本概念却很简单。这也是直接索引条目的行话。为了定义嵌入,让我们创建一个类和一个函数来定义潜在因素(嵌入)以及这些因素的点积,以达到预测的评级。
很简单,对吧?第一块使用嵌入创建用户和电影潜在因素,而第二块将两者相乘(点积)。
这里要理解的关键是模型接受一个形状张量(batch_size x 2)作为输入。这里第一列代表用户 id,第二列代表电影 id。嵌入层用于表示用户和电影潜在因素的矩阵。再次,自己探索一下数据。例如,分别看一下 x 和 y。
模范学习者
嵌入完成后,我们只剩下运行模型了。
历元&损失— I
结果相当不错。我们可以通过使用 sigmoid_range 来进一步改进它,以确保我们的预测评级在 0 到 5 之间。
现在让我们尝试运行模型
时期&损失-II(具有乙状结肠范围)
差别不大。我们肯定能做得比这更好。我们可以尝试的一件重要或显而易见的事情是考虑偏见。如果我们可以为每个用户添加一个数字,并对每部电影都这样做,我们将考虑用户和电影的偏见。所以让我们来试试这个。
时代&损失— III(有偏差)
不太好。我们的结果变得更糟了。我们可以尝试的最后一件事肯定会改善我们的模型结果。让我们介绍一下我们数据科学家称之为加权衰减或 L2 正则化。该参数将基本上控制我们添加到损耗中的平方和,并减少过拟合。
纪元&损失—四(与 L2)
好多了。我们的成绩终于提高了。现在,让我们从这些建议中获得一些视觉效果和见解。
解释嵌入和偏见
该模型为我们提供了建议,但看到它识别出了哪些因素是非常有趣的。让我们试着看看偏见。下面的代码给了我们偏差最小的电影。
偏见最低的电影
这是什么意思?这基本上是在告诉我们,这些电影可能与某些用户的潜在因素非常匹配,但最终仍然不被用户喜欢。我们可以只按平均评级对电影进行分类,但这种使用偏见的观点更有趣,因为它不仅告诉我们一部电影是否是人们不太喜欢的那种,而且告诉我们这样一个事实,即它完全属于他们喜欢的类别,但他们并不总是喜欢它。
我很赞同这个模式。这些是一些糟糕的电影(其中一些是闻所未闻的,至少对我来说是这样——比如《歌舞女郎》, Bio-Dome 的互联网评分低于 5 分)
从这个意义上说,这是获得最具偏见的电影的代码。
偏见最高的电影
这也是我不得不同意的一点。这是一个疯狂的电影列表。我个人已经看了全部 10 部电影,所以电影中的偏见已经被很好地考虑进去了。
用于可视化电影的 PCA
解释嵌入并不那么直接,因为维数通常很高。但是我们可以使用主成分分析来提取最重要的信息,并观察电影是如何分散在较低的维度中的。
潜在空间中的电影 PCA 情节
这个情节挺有意义的。如果你注意到,我们有一些科幻电影,如《帝国反击战》、《绝地归来》、《星际迷航》、《印第安纳琼斯》等。左边是一些新黑色电影,如《教父》和《法戈》。这是几个例子,说明相似的电影在潜在空间中表现得有多相似。
这篇博客到此结束。要查看完整代码和其他机器学习算法的笔记本,请关注我的【github。
从 Twitter 收集数据:使用 Tweepy 的逐步实现
本文是使用 tweepy 从 Twitter 收集数据的全面概述
布雷特·乔丹在 Unsplash 上的照片
介绍
获取数据是任何数据科学/机器学习项目生命周期的第二步,就在框定你想要解决的问题之后,这将使这一步成为其余阶段的支柱。此外,社交媒体是收集数据的好地方,尤其是用于竞争对手分析、话题研究、情感分析等。本文旨在逐步实现如何获取凭证,并在一个简单的用例上实现。
Twitter,一个相关的数据收集场所
Twitter 拥有 3.13 亿活跃用户( Statista,2017 ),这意味着这种数据收集方法可以减少基于研究人员地理位置和研究资源的研究参与障碍。它还可以最大限度地利用资源,包括时间、精力和便利
Tweepy 的实现示例
在执行任何类型的分析之前,要执行的第一个操作是获取您的 Twitter 认证凭证,如下所述。
获取认证凭证
- 注册开发者账户
这里的是进入下一页的链接。
(图片由作者提供)
2。获取您的认证凭证
在此页面上,创建一个项目并回答所有问题。然后,您将获得包含所有凭证的以下页面。确保你不会与任何人分享这些信息。
(图片由作者提供)
实施要求
- 安装 tweepy 模块
pip install tweepy # install the tweepy module
- 导入所需的模块
import tweepy # tweepy module to interact with Twitter
import pandas as pd # Pandas library to create dataframes
from tweepy import OAuthHandler # Used for authentication
from tweepy import Cursor # Used to perform pagination
Python 实现
- 实现实用函数来获取 tweets:
在这个例子中有三个主要的函数。(1)认证功能。(2)为了与 Twitter API 交互的客户端功能。(3)最后一个功能,收集推文并创建一个数据框,其中包含关于给定 Twitter 帐户的一些特定信息。收集的信息如下:推文的创建日期
推文的作者推文的作者
与推特账户上的名字相对应的网名
该推文获得的点赞数
推文转发数
"""
Twitter Authentification Credentials
Please update with your own credentials
"""
cons_key = ''
cons_secret = ''
acc_token = ''
acc_secret = ''# (1). Athentication Function
def get_twitter_auth():
"""
[@return](http://twitter.com/return):
- the authentification to Twitter
"""
try:
consumer_key = cons_key
consumer_secret = cons_secret
access_token = acc_token
access_secret = acc_secret
except KeyError:
sys.stderr.write("Twitter Environment Variable not Set\n")
sys.exit(1)
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_secret)
return auth# (2). Client function to access the authentication API
def get_twitter_client():
"""
[@return](http://twitter.com/return):
- the client to access the authentification API
"""
auth = get_twitter_auth()
client = tweepy.API(auth, wait_on_rate_limit=True)
return client # (3). Function creating final dataframe
def get_tweets_from_user(twitter_user_name, page_limit=16, count_tweet=200):
"""
[@params](http://twitter.com/params):
- twitter_user_name: the twitter username of a user (company, etc.)
- page_limit: the total number of pages (max=16)
- count_tweet: maximum number to be retrieved from a page
[@return](http://twitter.com/return)
- all the tweets from the user twitter_user_name
"""
client = get_twitter_client()
all_tweets = []
for page in Cursor(client.user_timeline,
screen_name=twitter_user_name,
count=count_tweet).pages(page_limit):
for tweet in page:
parsed_tweet = {}
parsed_tweet['date'] = tweet.created_at
parsed_tweet['author'] = tweet.user.name
parsed_tweet['twitter_name'] = tweet.user.screen_name
parsed_tweet['text'] = tweet.text
parsed_tweet['number_of_likes'] = tweet.favorite_count
parsed_tweet['number_of_retweets'] = tweet.retweet_count
all_tweets.append(parsed_tweet)
# Create dataframe
df = pd.DataFrame(all_tweets)
# Revome duplicates if there are any
df = df.drop_duplicates( "text" , keep='first')
return df
所有的功能最终都实现了,现在我们可以继续收集数据了。比方说,我们想收集谷歌人工智能的推文。创建数据框的函数将 Twitter 用户名/屏幕名称作为强制参数,在本例中,它是 GoogleAI ,没有@符号。
图片来自作者定制的 GoogleAI Twitter 账户
googleAI = get_tweets_from_user("GoogleAI")print("Data Shape: {}".format(googleAI.shape))
打印 指令显示 数据形状:(1743,6) 含义我们有 1743 条来自 Google AI 的推文,下面的 。head(10) 给出了数据帧中的前 10 条推文
googleAI.head(10)
googleAI.head 的结果(10)
tweepy 的优点和缺点
优点
- 写得很好的文档,有一个非常活跃的社区
- 提供关于给定推文的许多特征(例如,关于推文的地理位置的信息,等等。)
缺点
- 将用户限制在时间线中的最后 3200 条推文。
文章结尾
在本文中,您了解了如何获得 Twitter 开发人员证书,以及如何使用 tweepy 从 Twitter 获取数据。此外,您已经了解了该工具的局限性和优点。
如需进一步阅读,请随时查阅以下链接:
额外资源
再见🏃🏾