从我们出生那一刻起,我们就在不断学习。随着成长,我们会学会走路、模仿周围人的言行、理解和运用词汇,并且逐渐分辨事物的好坏。比如,当我们第一次接触火源时,会因为感到灼热而退缩,从而明白与火源保持距离的重要性。
现在思考一下计算机的工作方式。计算机能在一秒内处理数百万条指令,执行人类指定的任务,但却无法自主做出决策。这时,机器学习就能发挥重要作用。如果赋予计算机类似人类的思维能力,将会发生什么?我们可以用计算机能理解的方式为它下达任务,还可以建立一些模型来帮助它在未来做出行动。
人类通过经验积累知识,计算机则根据指令执行任务。然而,我们也可以直接向计算机提供经验,让它通过学习为行动做准备。我们目前是通过结构化的方式定义经验。因此,我们将计算机从数据(经验)中学习的过程称为机器学习。
以购买香蕉为例。你的母亲让你去买一些香蕉,同时告诉她鲜黄色的香蕉很好吃。你到了水果店,按母亲的建议挑选香蕉。你买了20根香蕉,但回家后发现有些香蕉的味道并不好。实际上,有5根是坏的。你逐一拿起香蕉,开始作出假设:20根香蕉中有12根是大香蕉,8根是小香蕉。这8根小香蕉都非常好吃,但大香蕉的情况不同,在12根大香蕉中,有5根的味道不如预期。
你已经掌握了挑选香蕉的知识。第二天,当你再次来到市场时,注意到水果店在打折出售一些香蕉,这些香蕉与前一天的有所不同,它们的皮带有一些绿色。根据之前的经历,你将每根香蕉分为好与坏,发现大的绿色香蕉味道很好,但小的绿色香蕉的味道却不太好。这样,你就学到了新的规则。
你开始把自己看作是香蕉专家。有一天,你需要去另一个城市参加表亲的婚礼。在那里,你惊讶地发现所有香蕉都很小,但味道却非常好。在这里,你了解到这个地区的香蕉是畅销品。
你现在确实已经成为专家了。但如果你的姐姐很久没回家,她喜欢石榴而不喜欢香蕉,你该怎么办?为了找到美味的石榴,你又需要重新开始学习。
这项任务可以由机器学习来引导计算机完成。可以通过数据点的形式向计算机提供知识。数据点的属性称为特征(Feature),这些特征包括香蕉的大小(小、中、大)、颜色、产地等。输出(Output)就是味道(好或坏)。将这些数据输入到机器学习程序中,计算机就可以学会如何区分香蕉的好坏。
机器学习算法是一种根据经验提供决策能力的智能算法。
Python在数据科学家和机器学习工程师中非常受欢迎。首先,它免费且易于学习,不需要为琐碎的任务浪费太多精力;其次,它是一种面向对象的语言,这也让它获得了大型开发者的支持;最后,它拥有庞大的开源库支持。Python拥有大量的开源库,可以帮助快速实现数据科学和机器学习解决方案,而无需从头编写每个算法。像Pandas、scikit-learn、SciPy、NumPy、Keras这样的库对于快速实现机器学习算法非常有用。
首先,通过一个实例来了解如何使用编程语言解决现实问题。
假设你要举办一场聚会,为每位到场的人分配一个1至100之间的唯一号码。聚会结束后,你宣布了一个消息:“我们将从1至200之间随机抽取一个数字,如果有两个人的号码之和与这个数字相等,我们会奖励这两个人。”
假设你已经给x个人分配了号码。如何确定是否应该奖励其中两个人?
你可以尝试使用Python来解决这个问题。首先,从列表中获取输入数据:
python
number_list = [43, 23, 1, 67, 54, 2, 34, 56, 23, 65, 12, 9, 87, 4, 33]
接下来,选择一个随机数并将其存储在一个变量中:
python
sum_selector = int(input())
为了处理这个问题,需要先对数据进行排序。在Python列表中排序非常简单,可以使用sort()
函数:
python
number_list.sort()
排序后的数字被赋值给变量。现在使用两个指针:一个指向列表开头(前指针),另一个指向列表结尾(后指针)。检查这两个指针所指的元素之和。如果和小于目标值(意味着当前总和小于所需的总和),前指针向前移动一步并再次检查;如果和大于目标值(意味着当前总和大于所需的总和),后指针向后移动一步并再次检查。如果当前总和等于目标值,说明找到了两个数的和等于目标值,需要给予奖励;如果两个指针相遇且仍未达到所需的总和,则说明不存在这样的两个数。
以下是完整的解决方案:
```python def isprizegiven(numberlist, sumselector): i = 0 j = len(number_list) - 1
if i >= j:
return False
while i <= j:
current_sum = number_list[i] + number_list[j]
if current_sum == sum_selector:
return True
elif current_sum > sum_selector:
j -= 1
else:
i += 1
return False
numberlist = [43, 23, 1, 67, 54, 2, 34, 56, 23, 65, 12, 9, 87, 4, 33] sumselector = int(input())
if isprizegiven(numberlist, sumselector): print("No Escape. Give Prize to Everyone") else: print("You Saved Yourself!!") ```
即使现在不能理解这段代码,也不要担心。接下来我们将对这段代码进行解析,并介绍编程语言的基本原理。
机器学习不仅仅是简单的算法,它还能应用于各种领域,从而产生创新性的结果。机器学习是一个从定义数据开始,最终获得具有一定准确率模型的过程。
机器学习的过程始于定义一个业务问题。我们需要明确机器学习的需求,判断是否真的需要高级预测算法来解决问题。
问题定义非常重要,因为它提供了更正式的思考解决方案的方向。它主要解决两个问题:
A. 问题是什么?
这个问题涵盖了问题的定义,并使其更加具体。假设我们要识别图像中是否有人。
现在定义这个任务,将其分解为任务(T)、经验(E)和性能指标(P): - 任务(T):根据图像中是否有人对图像进行分类。 - 经验(E):带有是否有人标签的图像。 - 性能指标(P):错误率。在所有分类的图像中,错误预测的百分比是多少。错误率越低,准确率越高。
B. 为什么需要解决这个问题?
这个问题更侧重于商业方面,包括解决问题的动机和好处。
如果你是一名研究人员,希望通过解决某个问题来发表论文,使其成为他人解决问题的参考标准,这可能是你的动机之一。
关于这个问题,还需要确定其他需求。例如,在没有安全措施的情况下,夜间在银行的自动取款机上是否有人类活动(假设要解决的问题与自动取款机的安全有关)。
还需要定义可以使用此解决方案的场景。这是一个通用的解决方案,还是为特定任务(如ATM传感器中的检测人员)设计的?解决方案的有效期是什么时候(是终生有效还是在特定时间内有效)?
在定义问题之后,开始进行数据收集。有许多不同的方式来搜集数据。例如,如果你想将回复与评分关联起来,可以从抓取网站开始。为了分析Twitter数据并与情感关联,可以使用Twitter提供的API来收集标签数据或与某个公司相关联的数据。市场调查人员可以通过创建不同的调查问卷并在网站上发布来收集数据。对于拥有大量用户的公司,如亚马逊、Facebook,其数据量非常庞大,根据不同的问题,还需要收集数据和标签。假设要建立一个新闻分类器,将新闻分为体育新闻、市场新闻和政治新闻。因此,每条新闻都需要一个与之相关的标签,这些数据可以用来构建机器学习分类器。
正确数据是解决机器学习问题的关键。即使是基础算法,高质量的数据也能产生满意的结果。
在收集数据后,需要专注于数据准备。需要将收集的数据转换成机器学习算法可以使用的格式。算法不是魔术表演,数据必须以正确的方式输入到机器学习算法中才能获得结果。根据不同的算法库,算法可以适应不同类型的输入格式。
数据准备从数据选择开始,并不是收集到的所有数据都对问题的解决有帮助。例如,如果你正在分析服务器日志,每个用户活动后都会生成许多与系统相关的信息。如果正在预测的是营销活动的市场反应,那么这个日志可能不起作用。因此,基于要解决的问题,应从后续操作中删除无关数据。
在高层次上识别数据后,需要对数据进行转换或预处理,使其更好地适用于机器学习算法。以下是数据预处理的一些过程:
这个过程也称为特征处理(Feature Processing),它包括特征选择、预处理以及将其转换为对机器学习算法有益的格式。
机器学习算法的目的是对未知的新数据进行预测。我们使用训练数据来建立模型。在训练数据上,算法将逐步减少训练误差。但是,不能将训练数据的准确率视为普遍适用的准确率,因为算法可能会记住实例并进行相应分类。因此,为了评估生成的模型,需要将数据分为训练数据和测试数据。使用训练数据进行算法训练,使用测试数据来计算生成模型的最终准确率。测试数据不参与算法训练。
通常将60%到80%的数据作为训练数据,其余部分作为测试数据。因此,在测试数据中获得最佳结果的模型可以作为目标模型。
我们从一组机器学习算法开始,并将训练数据的特征应用于算法中。算法选择取决于问题的定义。例如,从电子邮件中收集数据并将邮件分为垃圾邮件或非垃圾邮件,这时需要的算法是在输入变量后输出相应结果(垃圾邮件或非垃圾邮件),这类算法称为分类(Classification)算法(如决策树、朴素贝叶斯、神经网络等)。如果要预测任意连续变量(如预测即将到来的季度销售额),则使用回归(Regression)算法(如线性回归、核回归等)。如果处理的问题没有任何输入或反馈,则可以使用聚类(Clustering)算法,根据它们的特性进行分组。每种类别中都有大量的算法,我们将在后续章节中给出示例。
在选择算法后,开始训练模型。训练模型是在训练数据集上进行的,大多数算法的权重/参数在训练开始时都是随机分配的,并在每次迭代中进行改进。算法训练过程中,在训练数据集上多次运行以产生结果。例如,在线性回归的情况下,算法在开始时随机放置分离线,并在每次迭代中不断改进自身(即移动分离线)。
在选择正确的算法后,在测试数据集上评估算法的性能。测试数据集不会参与算法训练,因此测试数据不会影响算法的决策。
在选择正确的算法后,可以尝试对其进行改进以获得更好的性能。每个算法都有不同的参数设置方式,可以对其进行配置以更改算法性能,这称为参数调整(Parameter Tuning)。例如,可以改变算法学习的速率(学习率)来提高算法性能,这些参数称为超参数(Hyper Parameter)。对于机器学习来说,参数调整更像是一门艺术。
完成以上所有步骤后,就可以获得在训练集上训练生成并在测试集上完成评估的模型。现在可以使用这个模型来预测新数据的值。对于生产环境,可以将模型部署到服务器并通过API接口使用模型的预测功能。当然,这个模型并不是一成不变的,每当获得新数据时,都需要重复上述步骤,以改进模型的性能。
因此,在机器学习中,从问题开始,最终以一个处理问题的预测算法结束。
通过以下实例,我们可以尝试了解机器学习算法是如何处理问题的。
假设你需要购买一栋房子。现在开始查看市场上正在出售的房屋,并根据你的预算进行筛选。你对将要购买的房子有多个要求,首先是房子的面积。
在图1.2所示的情境中,你先考察了一栋600平方英尺(约56平方米)的房子,价格是220,000英镑(约1,942,578元)。这个房子的确很不错,但是它并不满足你的要求——你将和家人一起居住,而这栋房子面积太小,无法让每个人都住得舒适。因此,你继续研究并找到一栋1700平方英尺(约158平方米)的房子,价格是730,000英镑(约6,445,827元)。这个房子满足你的要求,但价格超出了你的预算——你的预算比小面积房子的价格高一些,但不像大面积房子的价格那么高。但是,只有当你与房主或代理人见面并提交详细材料后,才能得到房子的实际价格。然而,你不想与每一个房主或代理人见面。
在二维平面上分析你所考察的两个属性,如图1.3所示。
现在,你在城市里闲逛,找到一栋面积在这两栋房子之间的房子。
这栋新房子的面积大约有1250平方英尺(约116平方米),但你还不知道价格。因此,你想预测房子的价格,看它是否符合预算和要求。
将新房子的信息放在同一个二维平面上,试着预测这个房子的价格,如图1.4所示。
为了预测房屋的价格,将设置一条符合已知结果(即房屋价格和房屋面积)的直线,这里得到了如图1.5所示的一条直线。
经过这条直线,可以预测出1250平方英尺(约116平方米)的房子的价格是475,000英镑(约4,194,202.5元)。因此,我们得到了一条根据房子面积来预测房子价格的直线,这种技术称为线性回归(Linear Regression)。可以将这种技术理解为在现有数据点上寻找最佳直线。
例如,计算3个点到直线距离之和的最小值。首先,随机选择一条线,直线上方有A、B、C共3个点,如图1.6所示。
然后,计算每个点到直线的距离,如图1.7所示。
可以得到总距离是a+b+c。现在,移动直线的位置(向下移动)并再次计算点到直线的距离,如图1.8所示。
改变了直线的位置,但总距离a+b+c增加了。显然,这不是我们想要的结果。让我们将直线向另一个方向(向上移动)移动,如图1.9所示。
这条直线(见图1.9)比第一条直线(见图1.7)更符合要求。现在移动这条直线,并试着重复同样的步骤。最终通过这种方式确定直线的位置,如图1.10所示。
对于给定的3个点(A、B、C)来说,图1.10所示的直线是最符合条件的。在这里取3个点到直线的非负距离,找到这条线的方法称为梯度下降法。
有时在所有数据点上拟合一条直线并没有多大意义。现在考虑图1.11所示的点集。
如果尝试使用线性回归技术来拟合一条直线,它看起来如图1.12所示。
很明显,这条线不适合用来预测。相反,可以用图1.13所示的曲线来对数据建模。
这就是所谓的多项式回归(Polynomial Regression)——因为其参数是多项式。
再来看另一个例子,例如有一个售鞋网站,其中包含来自不同公司的各种鞋子,可以通过其网上商店订购鞋子。鞋子成功交付后,公司将发送电子邮件获取顾客的反馈。顾客在回复区留言,其中有些回复是正面的,有些回复则是负面的。
该公司每天销售数千双鞋,需要跟踪每一个回复并采取相应的行动。如果顾客回复说鞋子质量不佳,则需向生产商询问产品质量问题;如果鞋子反响很好,则最好将它们放在网站的首页。
为了处理这个问题,首先需要从一组顾客回复开始,将每个回复分为负面回复或正面回复,下面给出部分示例。
正面回复
A1:质量不错!我很喜欢这双鞋子。
A2:非常好的产品。
A3:给我爸爸买的,他很喜欢。
负面回复
B1:材质不好,不合适。
B2:很不喜欢这个产品,包装也很不好。
B3:千万不要买这个产品。
分析示例中的正面回复和负面回复,会发现,如果回复中包含“喜欢”这个词,那么它更有可能是一个正面回复。因此,创建这条规则并检查整个数据集,会发现60%的正面回复中包含“喜欢”这个词;另一方面,只有10%的负面回复中包含“喜欢”这个词。
同样,其他词语所占的比例如表1.1所示。
因此,对于未来可能收到的回复,可以根据其所包含的词的复合概率,判断该回复是正面回复还是负面回复,这就是朴素贝叶斯分类器(Naïve Bayes Classifier)。
再列举一个向不同的人推荐杂志的例子。假设已经记录了用户的年龄、性别、地位以及他们阅读的杂志类型,表1.2所列为记录的数据。
现在,通过对这些数据进行观察,可以发现小于15岁的人喜欢阅读儿童杂志。根据这一点,制作一个决策节点,如图1.14所示。每个圆节点表示决策节点,图的边缘(箭头)则表示相应的决策,每个矩形节点表示通过图分支后采取的决策。
因此,可以说每个年龄小于或等于15岁的人有概率阅读儿童杂志。现在,处理年龄大于15岁的读者的分支。
接下来,观察到的另一个特征是男性,他们喜欢阅读政治杂志。为此创建相反的决策节点和分支,如图1.15所示。
接着,需要看一下年龄在15岁以上的女性的选择。还有一个信息可以利用——地区。因此,可以说,来自美国的女性喜欢阅读体育杂志,而其他地区的女性则喜欢商业杂志。在这里形成的节点如图1.16所示。
正确地对每个数据点进行分类,这个过程中形成了决策树。可以有多种创建决策树的方法。根据现有数据,这些方法可以做出正确的预测。
图1.17所示的这棵树对数据进行了准确的分类。
再来举另一个例子,有人每年申请贷款,银行根据他们的收入和贷款金额来决定是否批准贷款,目的是向那些在规定时间内偿还债务且没有违约的人提供贷款。
如果一个人月收入是20,000美元,他申请了100,000美元的贷款,银行根据他的收入来源可以同意贷款;如果一个人月收入是3,000美元,他申请了600,000美元的贷款,银行可能会早早拒绝他。
因此,银行基于过往违约者的记录创建了一个数据集,如图1.18所示。红点表示银行拒绝的贷款申请,绿点表示银行同意的贷款申请。横坐标是贷款金额,纵坐标是月收入。
现在,一个月收入10,000美元的人想要贷款300,000美元,银行是否会同意?可以使用一条直线来分割数据,如图1.19所示。
根据这条直线,可以预测银行将同意月收入20,000美元的人申请300,000美元的贷款申请。
现在,已经有了一条合适的直线来分割现有数据点。我们使用的算法(梯度下降法)与在线性回归过程中使用的算法相同。在这里,目标变量是类别,而不是在线性回归情况下连续的预测值,这种技术称为逻辑回归(Logistic Regression)。
现在,银行来了一个新经理,他要检查所有的记录,他认为银行同意或拒绝贷款申请的标准是荒谬的,一些像10,000美元或20,000美元的贷款申请并没有风险,银行可以同意这些贷款申请。因此,他改变了规则和数据,如图1.20所示。
显然,仅用一条直线并不能将红点和绿点分开。既然如此,那就使用两条直线吧?如图1.21所示。
与一条直线相比,使用两条直线可以将红点和绿点分开。这种技术被称为神经网络(Neural Network)。神经网络基于大脑中神经元的概念提出。大脑中的神经元收集信息并将其传递给其他神经元。简单来说,就是基于先前神经元的输入,下一个神经元接收要求并决定输入,它还将信息传递给其他神经元。最后,通过处理不同的神经元,大脑做出决策。
这个概念可以用下面的模型(见图1.22)来理解。在这个模型中,两个神经元通过使用不同的假设建立模型,并将它们的发现发送给另一个神经元。根据收集到的信息,输入神经元做出决策。
在处理数据时,对于一条分割数据点的直线,可能有不同的选择。如图1.23所示的两个例子。
与直线1相比,直线2的边距更大,其在分割数据方面似乎更好,如图1.24所示。
现在我们要寻找最佳分割路径,而梯度下降并不能解决这个问题,需要线性优化才能完成。这种技术被称为最大间隔分类器或支持向量机(Support Vector Machine,SVM)。
在现实世界中,数据并不能完全分割开。它可能会像图1.25所示的那样。
因此,不能通过一条直线把红点和绿点分开。但是,如果通过一个平面来区分红点和绿点,就可以用一个分类器对它们进行分类。创建一个新的维度并用这个平面来分割红点和绿点,如图1.26所示。
现在使用一个新的维度将红点和绿点分开。这种技术被称为核函数(Kernel Trick)。
真实的数据非常复杂,并且有很多维度。带有支持向量机分类器的核函数可以用来处理这些复杂的问题。
现在来看另一个问题。如图1.27所示,有一家杂货店A2A。他们提供电话送货服务,每当接到电话时,他们就会将地址发送给配送员,配送员会前往送货地点并交付商品。他们设法将办公室设在城市的中心,以便为越来越多的人提供及时的服务。
这里的点代表A2A的服务需求。现在他们意识到,用一个配送中心处理所有的需求并不明智。因此,他们决定在城市中开设4个配送中心,按照不同区域来接受需求和服务。
因此,为了处理这个问题,首先可以随机添加4个配送中心并分配配送需求,如图1.28所示。
显然,这不是配送中心的最佳分配位置。接下来,将每个点移动到分类点的中心。然后,将所有点分类到最近的配送中心,并将配送中心的位置移动到之前的分类中心。经过多次迭代,将得到图1.29所示的分配位置。
因此,每个点的分配都是基于点到中心的距离。这种技术称为K-均值聚类(K-Means Clustering)。
也可以使用另一种方法进行聚类。将所有的点视为独立的簇,而不是首先将它们分组到簇中再进行重新分配。然后,将两个最近的点分组,形成一个簇。不断这样做,直到出现较大的间隔或形成最小数量的簇。这种技术称为层次聚类(Hierarchical Clustering)。
本文摘自《Python机器学习》
《Python机器学习》通过解释数学原理和展示编程示例对机器学习进行了系统、全面的解析。本书共分为12章,内容涵盖机器学习和Python语言的基础知识、特征工程的概念与操作技术、数据可视化技术的实现、监督学习及无监督学习算法、文本分析、神经网络和深度学习、推荐系统的构建方法以及预测处理时间序列的方法等。阅读本书可以加深读者对机器学习的理解,从而达到理论与实践相结合、学以致用的目的。