一文读懂为什么要选择 Python做机器学习
2018-08-18
随着机器学习的兴起,Python逐步成为了「最受欢迎」的语言。它简单易用、逻辑明确并拥有海量的扩展包,因此其不仅成为机器学习与数据科学的首选语言,同时在网页、数据爬取可科学研究等方面成为不二选择。此外,很多入门级的机器学习开发者都是跟随大流选择 Python,但到底为什么要选择 Python 就是本文的核心内容。
本教程的目的是让你相信两件事:首先,Python 是一种非常棒的编程语言;其次,如果你是一名科学家,Python 很可能值得你去学习。本教程并非想要说明 Python 是一种万能的语言;相反,作者明确讨论了在几种情况下,Python 并不是一种明智的选择。本教程的目的只是提供对 Python 一些核心特征的评论,并阐述作为一种通用的科学计算语言,它比其他常用的替代方案(最著名的是 R 和 Matlab)更有优势。
本教程的其余部分假定你已经有了一些编程经验,如果你非常精通其他以数据为中心的语言(如 R 或 Matlab),理解本教程就会非常容易。本教程不能算作一份关于 Python 的介绍,且文章重点在于为什么应该学习 Python 而不是怎样写 Python 代码(尽管其他地方有大量的优秀教程)。
概述
Python 是一种广泛使用、易于学习、高级、通用的动态编程语言。这很令人满意,所以接下来分开讨论一些特征。
Python(相对来说)易于学习
编程很难,因此从绝对意义上来说,除非你已经拥有编程经验,否则编程语言难以学习。但是,相对而言,Python 的高级属性(见下一节)、语法可读性和语义直白性使得它比其他语言更容易学习。例如,这是一个简单 Python 函数的定义(故意未注释),它将一串英语单词转换为(crummy)Pig Latin:
def pig_latin(text):
''' Takes in a sequence of words and converts it to (imperfect) pig latin. '''
word_list = text.split(' ')
output_list = []
for word in word_list:
word = word.lower()
if word.isalpha():
first_char = word[0]
if first_char in 'aeiou':
word = word + 'ay'
else:
word = word[1:] + first_char + 'yay'
output_list.append(word)
pygged = ' '.join(output_list)
return pygged
以上函数事实上无法生成完全有效的 Pig Latin(假设存在「有效 Pig Latin」),但这没有关系。有些情况下它是可行的:
test1 = pig_latin("let us see if this works")
print(test1)
抛开 Pig Latin 不说,这里的重点只是,出于几个原因,代码是很容易阅读的。首先,代码是在高级抽象中编写的(下面将详细介绍),因此每行代码都会映射到一个相当直观的操作。这些操作可以是「取这个单词的第一个字符」,而不是映射到一个没那么直观的低级操作,例如「为一个字符预留一个字节的内存,稍后我会传入一个字符」。其次,控制结构(如,for—loops,if—then 条件等)使用诸如「in」,「and」和「not」的简单单词,其语义相对接近其自然英语含义。第三,Python 对缩进的严格控制强加了一种使代码可读的规范,同时防止了某些常见的错误。第四,Python 社区非常强调遵循样式规定和编写「Python 式的」代码,这意味着相比使用其他语言的程序员而言,Python 程序员更倾向于使用一致的命名规定、行的长度、编程习惯和其他许多类似特征,它们共同使别人的代码更易阅读(尽管这可以说是社区的一个特征而不是语言本身)。
Python 是一种高级语言
与其他许多语言相比,Python 是一种相对「高级」的语言:它不需要(并且在许多情况下,不允许)用户担心太多底层细节,而这是其他许多语言需要去处理的。例如,假设我们想创建一个名为「my_box_of_things」的变量当作我们所用东西的容器。我们事先不知道我们想在盒子中保留多少对象,同时我们希望在添加或删除对象时,对象数量可以自动增减。所以这个盒子需要占据一个可变的空间:在某个时间点,它可能包含 8 个对象(或「元素」),而在另一个时间点,它可能包含 257 个对象。在像 C 这样的底层语言中,这个简单的要求就已经给我们的程序带来了一些复杂性,因为我们需要提前声明盒子需要占据多少空间,然后每次我们想要增加盒子需要的空间时,我么需要明确创建一个占据更多空间的全新的盒子,然后将所有东西拷贝到其中。
相比之下,在 Python 中,尽管在底层这些过程或多或少会发生(效率较低),但我们在使用高级语言编写时并不需要担心这一部分。从我们的角度来看,我们可以创建自己的盒子并根据喜好添加或删除对象:
# Create a box (really, a 'list') with 5 things# Create
my_box_of_things = ['Davenport', 'kettle drum', 'swallow-tail coat', 'table cloth', 'patent leather shoes']
print(my_box_of_things)
['Davenport', 'kettle drum', 'swallow-tail coat', 'table cloth', 'patent leather shoes']
# Add a few more things
my_box_of_things += ['bathing suit', 'bowling ball', 'clarinet', 'ring']
# Maybe add one last thing
my_box_of_things.append('radio that only needs a fuse')
# Let's see what we have...
print(my_box_of_things)
更一般来说,Python(以及根据定义的其他所有高级语言)倾向于隐藏需要在底层语言中明确表达的各种死记硬背的声明。这使得我们可以编写非常紧凑、清晰的代码(尽管它通常以降低性能为代价,因为内部不再可访问,因此优化变得更加困难)。
例如,考虑从文件中读取纯文本这样看似简单的行为。对于与文件系统直接接触而伤痕累累的开发者来说,从概念上看似乎只需要两个简单的操作就可以完成:首先打开一个文件,然后从其中读取。实际过程远不止这些,并且比 Python 更底层的语言通常强制(或至少是鼓励)我们去承认这一点。例如,这是在 Java 中从文件中读取内容的规范(尽管肯定不是最简洁的)方法:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class ReadFile {
public static void main(String[] args) throws IOException{
String fileContents = readEntireFile("./foo.txt");
}
private static String readEntireFile(String filename) throws IOException {
FileReader in = new FileReader(filename);
StringBuilder contents = new StringBuilder();
char[] buffer = new char[4096];
int read = 0;
do {
contents.append(buffer, 0, read);
read = in.read(buffer);
} while (read >= 0);
return contents.toString();
}
}
你可以看到我们不得不做一些令人苦恼的事,例如导入文件读取器、为文件中的内容创建一个缓存,以块的形式读取文件块并将它们分配到缓存中等等。相比之下,在 Python 中,读取文件中的全部内容只需要如下代码:
# Read the contents of "hello_world.txt"
text = open("hello_world.txt").read()
当然,这种简洁性并不是 Python 独有的;还有其他许多高级语言同样隐藏了简单请求所暗含的大部分令人讨厌的内部过程(如,Ruby,R,Haskell 等)。但是,相对来说比较少有其他语言能与接下来探讨的 Python 特征相媲美。
Python 是一种通用语言
根据设计,Python 是一种通用的语言。也就是说,它旨在允许程序员在任何领域编写几乎所有类型的应用,而不是专注于一类特定的问题。在这方面,Python 可以与(相对)特定领域的语言进行对比,如 R 或 PHP。这些语言原则上可用于很多情形,但仍针对特定用例进行了明确优化(在这两个示例中,分别用于统计和网络后端开发)。
Python 通常被亲切地成为「所有事物的第二个最好的语言」,它很好地捕捉到了这样的情绪,尽管在很多情况下 Python 并不是用于特定问题的最佳语言,但它通常具有足够的灵活性和良好的支持性,使得人们仍然可以相对有效地解决问题。事实上,Python 可以有效地应用于许多不同的应用中,这使得学习 Python 成为一件相当有价值的事。因为作为一个软件开发人员,能够使用单一语言实现所有事情,而不是必须根据所执行的项目在不同语言和环境间进行切换,是一件非常棒的事。