数学公式太晦涩,蓝冠教你不如用代码写出来:这是程序员学数学的独特方式_蓝冠测速

行业解决方案



数学公式太晦涩,蓝冠教你不如用代码写出来:这是程序员学数学的独特方式


时间:2020/03/13 15:53


简洁的代码不仅能运行程序,还能用来学数学。

∑、∏、∈……如果你学习过数学,你一定知道这些符号的含义,而如果我们能用最喜欢的编程语言来理解它们,也许还能带来更加透彻的领悟。近日,MindbuilderAI & nurio 创始人、机器学习专家 Ian Rowan 介绍了自己借助代码来理解数学计算过程的经验。

对于想要在机器学习和数据科学领域创出一番事业或做出一些研究成果的人来说,终有一天会在鼓捣 Python 软件库的基础上更进一步,跟随自己的好奇心进入背后的数学领域。这通常会将你引向那些描述了各种原理的数量庞大的公开论文集。你对核心数学机制的理解越深入,你就越可能灵光闪现,成为一种新方法的创造者。在读第一篇论文时,可能一开始一切都还很容易理解,但当你遇到下面这种公式时,你可能就会开始疑惑了:

对于学习过多年的数学或研究过机器学习的数学层面的人来说,这样的等式可以通过精心的处理而解析为语言描述和代码。但对其他很多人来说,这看起来可能就像天书。事实上,这看起来就像是古代的数学领袖选择了看起来最有意思的符号来描述相当直观的方法。这就导致了一个结果:等式和变量看起来比实际表达的含义还要复杂得多。

我发现代码不仅能用来写程序,而且还是用于解释复杂问题的全球通用语言。当我学习数据科学背后的数学时,我总是发现理解数学的最佳方式是写出描述这些等式的代码段。最终,我理解了这些符号,现在读它们就像读一篇普通论文一样。我希望通过这篇文章分享一些示例,让大家知道用代码描述数学竟会如此简单!

求和与求积

在迭代数学方法中,求和符号是最有用且最常用的符号。尽管求和符号设计复杂,但实现方法却非常简单,而且也极其有用。

x = [1, 2, 3, 4, 5, 6]result = 0for i in range(6):

result += x[i]Output of print(result) -> 21

如前所示,这个符号表达的其实就是一个循环。求和符号上面的数字是这个循环的范围,下面的数字是起始位置。下面的变量集会变成索引变量,每次循环的结果都被加起来,得到一个总和值。下面的符号则更少见一些:

这个符号通常被称为乘积算子(Product Operator)。这个符号与求和符号的工作方式相似,只不过每次循环的结果不是相加,而是相乘。

x = [1, 2, 3, 4, 5, 1]

result = 1

for i in range(6): result *= x[i]Output of print(result) -> 120

阶乘

阶乘的符号是 !,大多数计算器都有这个功能。对很多人来说,这个符号表达的含义可能很明显和直白,但还是值得用代码来理解其原理。

5! 可以表示成:

result = 1for i in range(1,6):

result *= iOutput of print(result) -> 120

条件括号

条件括号的作用是基于一组条件来切换所要执行的等式。对于程序员来说,这其实就是简单的 if 语句。上面的条件等式可表示为:

i = 3y = [-2, 3, 4, 1]result = 0if i in y:

result = sum(y)elif i > 0: result = 1else:

result = 0print(result) -> 6

可以看到,等式右侧括号中每一行都对应一个条件以及该条件下所要执行的路径。我还在每个条件中增加了额外的「属于」符号,以便提供更多见解。如前所示,我们检查了 i 值是否在 y 列表中。如果在,则返回数组的和。如果不在,我们则根据具体的值返回 0 和 1。

逐点乘法和笛卡尔矩阵乘法

最后,我想快速介绍几个任何数据科学家都可以用自己最喜欢的语言库轻松完成的运算——矩阵乘法。理解矩阵乘法的最简单方式是逐点运算。这可以简单地写成:

注意,首要要求是每个矩阵都必须形状一样(即 # rows= & #Columns=)。其代码如下:

y = [[2,1],[4,3]]z = [[1,2],[3,4]]x = [[0,0],[0,0]]

for i in range(len(y)): for j in range(len(y[0])): x[i][j] = y[i][j] * z[i][j]print(x) -> [[2, 2], [12, 12]]

最后,我们来看一种典型的矩阵乘法过程,这在机器学习领域非常常用。用复杂的术语来说,这个运算的目的是求取每个主要行与每个次要列的点积。主要来说是下面的要求:假设 [#rows, #columns] 矩阵 i x j 要求 #columns(i) == #rows(j) 最终积的形状为 [#rows(i), #columns(j)]

这看起来很令人困惑,我最好的建议是搜索一下这些要求的可视化图片。

这个等式的代码如下(使用了 numpy dot 方法):

y = [[1,2],[3,4]]z = [[2], [1]]# x has shape [2, 1]x = [[0], [0]]for i in range(len(y)) for j in range(len(z): x[i][j] = np.dot(y[i], z[:, j])print(x) -> [[4],[10]]

本文仅给出了少量示例,但理解这些简单代码能让任何程序员都能踏足乍看之下难以深入的数学世界。当然,这些方法都可以合并简化,实现更高的效率,而且通常很多软件库中都有现成的方法可用。用简单代码写出这些数学符号的意义在于通过写出这些等式的真正计算过程来理解它们的含义。