用Python进行机器学习(附代码、学习资源)

简介:

93dfde970ede39196c0ec1615928c61ea51b33ae

使用Python库、流水线功能以及正则化方法对非线性数据进行建模。

在数据科学和分析领域中,对非线性数据进行建模是一项常规任务。但找到一个结果随自变量线性变化的自然过程很不容易。因此,需要有一种简便并且稳健的方法来快速将测量数据集与一组变量进行拟合。我们假定测量数据可能包含了一种复杂的非线性函数关系。这应该是数据科学家或机器学习工程师常用的工具。

我们要考虑以下几个相关的问题:

d47e62d2b349aca45e42305ed6714efbe5ed61d9 怎么确定拟合多项式的顺序?是否需要为多变量回归加上交叉耦合项?有没有简单的方法将这一过程自动化?
d47e62d2b349aca45e42305ed6714efbe5ed61d9 怎样判断模型是否过拟合?
d47e62d2b349aca45e42305ed6714efbe5ed61d9 如何得知模型在面对噪声时够不够稳健?
d47e62d2b349aca45e42305ed6714efbe5ed61d9 模型能不能轻松拓展到更高维度或更大的数据集上?

如何确定拟合多项式的顺序?

“我们能不能画出数据图形直接得到结论?”

数据如果能清楚的可视化表示(即特征维度为1或2)时,方法可行。一旦数据的特征维度等于3或者更多,这事儿就麻烦了。而且如果对结果产生影响的特征存在交叉耦合,这么做就完全是在浪费时间。下面我们画个图来感受一下:

f2026a598763785db3d9d07776f8c7b3741c3b58

很明显,直接画图的方法最多也只能做到上面这种程度。对那些更高维度并且变量相互作用的数据集,如果你试图每次只查看单个输入变量和输出之间的关系,会得出完全错误的结论。而且目前没有什么好办法同时显示两个以上的变量。所以,我们必须采用某种机器学习的技术来拟合多维数据集。

实际上,已经有了不少好的解决方案。

在你看到“...但这些是高维非线性数据集...”这句话发出尖叫之前,线性回归应该是头一个能找到的工具。注意一点:线性回归模型中的“线性”二字指的是系数,而不是特征。特征(即自变量)可以是任意多维度的,甚至可以是指数、对数、正弦这些函数。更厉害的是,可以使用这些变换和线性模型(近似)对令人惊讶的大量自然现象进行建模。

来看看下边这个有三个特征、单输出的数据集。我们再一次使用了前边提到的画图方法,很明显它表现的差强人意。

d45ff5f8afffc8109752dd46f29f60194feaf95f

因此,我们决定学习一个具有高阶多项式项线性模型来拟合数据集。那么问题来了:

d47e62d2b349aca45e42305ed6714efbe5ed61d9 怎样确定什么多项式是有用的?
d47e62d2b349aca45e42305ed6714efbe5ed61d9 如果我们开始将一次项、二次项、三次项...逐个进行组合,什么时候停止比较合适呢?
d47e62d2b349aca45e42305ed6714efbe5ed61d9 我们怎么判定哪些交叉耦合的项是重要的?比如:是只需要_X_1²、_X_2³还是需要有_X_1._X_2以及_X_1².X3这种项?
d47e62d2b349aca45e42305ed6714efbe5ed61d9 最后,我们是不是必须手动将这些多项式转换的方程/函数式写出来并且应用到数据集上?

强大的Python机器学习库来帮忙

幸运的是,有一个很厉害的机器学习库--scikit-learn提供了很多成熟的类/对象来解决上边说的这些问题。

这儿有一个对使用scikit-learn进行线性回归进行概述的资料(原文中说是视频,但打开链接看了一下是这个库的使用文档,故直接翻译为了资料)

http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LinearRegression.html#sklearn.linear_model.LinearRegression

还有一篇很好的文章供大家查看。

https://towardsdatascience.com/simple-and-multiple-linear-regression-in-python-c928425168f9?gi=69160943145f

但本文要介绍的不仅仅是一个简单的线性拟合,请大家接着往下看。(原文有一句提到代码在作者的GitHub,但是发现链接已经404,所以没加)

我们从引入scikit-learn中相关的包开始:

from sklearn.cross_validation#引入函数进行训练集和测试集的划分

import train_test_split

#引入函数自动生成多项式特征

from sklearn.preprocessing import PolynomialFeatures

# 引入线性回归和一个正则化的回归函数

from sklearn.linear_model import LinearRegression

from sklearn.linear_model import LassoCV

from sklearn.pipeline import make_pipeline

下面快速说明一下我们等会儿要用到的一些概念。

训练/测试集划分:表示将已有的单独数据集划分为两个子集。其中一个(训练集)用来建立模型,另外一个(测试集)用来评估模型的准确性和稳定性。这个步骤对任何一个机器学习任务来说都是必不可少的。经过处理,我们没有用所有的数据建立出一个看似异常准确的模型。(因为模型接触到所有的数据,当然会拟合的很好)这个模型通常在新数据(未知)数据上表现很差。

模型在测试集上的准确性比其在训练集上的准确性更有说服力。这儿有一篇关于这个话题延伸的文章,有兴趣的读者可以看看。https://towardsdatascience.com/train-test-split-and-cross-validation-in-python-80b61beca4b6

下面你会看到Google car的先驱Sebastion Thrun对这个概念的说法。

多项式特征自动生成

Scikit-learn提供了一个从一组线性特征中生成多项式特征的方法。你需要做的就是传入线性特征列表,并指定希望生成的多项式项的最大阶数。它还可以让你选择是生成所有交叉耦合项还是只生成主要特征的阶数。这里有一个Python代码进行演示。

http://scikit-learn.org/stable/auto_examples/linear_model/plot_polynomial_interpolation.html#sphx-glr-auto-examples-linear-model-plot-polynomial-interpolation-py

正则化回归

正则化的重要性不言而喻,它是机器学习的一个中心概念。在建立线性模型时,最基本的想法是对模型的系数进行“惩罚”,使它们不会变得太大而过拟合数据(对噪声数据过于敏感)。有两个广泛使用的正则化方法,其中我们要用的被称为LASSO。下边这篇文章对两种正则化方法做了很好的概述。

https://www.analyticsvidhya.com/blog/2016/01/complete-tutorial-ridge-lasso-regression-python/

机器学习流水线

一个机器学习项目几乎不会是单一的建模任务。它最常见的形式包括数据生成、数据清洗、数据转换、模型拟合、交叉验证、模型准确性评估和最终的部署。

列举一些相关的学习资料如下:

d47e62d2b349aca45e42305ed6714efbe5ed61d9 对上述概念总结的一个Quora回答:

https://www.quora.com/What-is-a-pipeline-and-baseline-in-machine-learning-algorithms

d47e62d2b349aca45e42305ed6714efbe5ed61d9 另外一篇关于机器学习流水线的总结:

https://medium.com/@yanhann10/a-brief-view-of-machine-learning-pipeline-in-python-5f50b941fca8

d47e62d2b349aca45e42305ed6714efbe5ed61d9 对piplines在实践中重要性作出阐述:

https://www.oreilly.com/ideas/building-and-deploying-large-scale-machine-learning-pipelines

d47e62d2b349aca45e42305ed6714efbe5ed61d9 Scikit-learn提供了一个流水线功能,可以将多个模型和数据预处理类组合在一起,把原始数据转换为可用模型。

http://scikit-learn.org/stable/tutorial

/statistical_inference/putting_together.html

怎样最终整合并建立一个稳健的模型?

在这里,我们提供了一些代码样例,你可以对它进行修改,应用在你自己的数据集上。

# LASSO回归的参数设置

lasso_eps = 0.0001

lasso_nalpha=20

lasso_iter=5000

# 多项式特征项的最大、最小阶数

degree_min = 2

degree_max = 8

# 训练集、测试集划分

X_train, X_test, y_train, y_test =

train_test_split(df['X'], df['y'],test_size=test_set_fraction)

# 建立一个流水线模型

for degree in range(degree_min,degree_max+1):

model=make_pipeline(PolynomialFeatures(degree, interaction_only=False),LassoCV(eps=lasso_eps,

n_alphas=lasso_nalpha,max_iter=lasso_iter,

normalize=True,cv=5))

model.fit(X_train,y_train)

test_pred = np.array(model.predict(X_test))

RMSE=np.sqrt(np.sum(np.square(test_pred-y_test)))

test_score = model.score(X_test,y_test)

不过这些冷冰冰的代码是给机器看的,我们还准备了有详细注释的版本。

为了进一步提炼它,下面是更精简的流程图:

e47924a161fa5e9b30fb956ce30f9706b648b602

为了进一步提炼它,下面是更精简的流程图:

2cc8ba47e96d7b0bdb808d26999a40fd1aa2f705

让我们来讨论讨论结果

对于所有的模型,我们给出了测试误差、训练误差(均方根)还有R²系数作为模型准确性的度量。然后把它们画出来:

cf83cfa05e5df5f1393ce75412f63a0c6678a937

这些图回答了最早提出的两个问题。

可以看出,我们需要四阶和五阶的多项式项来进行拟合。线性、二次甚至三次模型对这个数据来说都不够复杂。

同时,我们也没必要使阶数超过5,这会使得模型过于复杂。

967e3df85764ad9b1a7541648fa1497103ac03a1

等等!问题来了:在这条曲线中,我们熟悉的表现出偏差和方差之间权衡(即过拟合与欠拟合)的形状在哪?为什么测试误差没有随着模型复杂度的增加急剧升高?

答案在于,使用LASSO回归之后,我们基本消除了复杂模型中的高阶项。对于更细节的东西,比如这个结果到底是怎么出现的,可以参考这篇文章。

https://dataorigami.net/blogs/napkin-folding/79033923-least-squares-regression-with-l1-penalty

实际上,这正是LASSO回归和L1正则的关键优势之一,它不是仅仅将模型中的部分系数减小,而是将它们直接变为零。这相当于提供了“自动特征选择”的功能。即便你一开始使用了很复杂的模型来拟合数据,经过这种处理后,也可以让那些不重要的特征自动被忽略。

为了进行对比,我们这次不做正则化处理,并且使用一个简单的线性模型来拟合数据。下边是得出的结果。这次可以看到那条熟悉的偏差/方差权衡曲线了(补充:表示训练误差及测试误差随着模型复杂度增长的变化,体现过拟合及欠拟合)

499c2d91c5941e433b6e449fd7c7bbc5f233447c

噪声数据会发生什么?

(这里作者有提到自己的代码,同样因为GitHub地址失效没有加进来)

数据中的噪声会让模型很难变得准确,甚至还会产生过拟合。因为模型会试图解释噪声,而不是发掘真正的模式。基本上,简单的线性回归模型在这种情况下都会失败,而正则化模型仍然表现良好。不过即便这样,在模型足够复杂时,过拟合现象也会现出端倪。

下面是总结:

54375db828ef5f847db151004ec8c72d811c4237

结语

简而言之,本文讨论了一个拟合多变量回归模型的方法,它适用于高度非线性、具有耦合项并且含有噪声的数据集。我们知道了如何利用Python的机器学习库来生成多项式特征、对数据进行正则化处理,防止模型中的系数变得过大、画图来评估模型的准确性及稳定性等。

对于更高级的具有非多项式特征的模型,你可以看看sklearn中关于核回归或支持向量机的内容。还有这篇文章有对高斯核回归的介绍。


原文发布时间为:2018-06-4本文作者:Tirthajyoti Sarkar本文来自云栖社区合作伙伴“ 数据派THU”,了解相关信息可以关注“ 数据派THU”。

相关文章
|
3天前
|
SQL 人工智能 自然语言处理
Python 潮流周刊#52:Python 处理 Excel 的资源
探索Python精彩:文章涵盖正则、代码恢复、PEP新规范、轻量级打包、在线开发、动态生成GitHub README、自定义linting、代码转图片等。项目资源包括Excel处理、虚拟环境管理、Tensor谜题、依赖注入框架、Web应用转换、AI自动化测试、语法高亮、BI模型查询及Python监控库。在当前环境下,持续学习提升竞争力,Python Weekly提供丰富的学习资源,助力技术精进和职业发展。
|
12天前
|
C语言 Python
​python学习之变量类型​
​python学习之变量类型​
|
1天前
|
Python 缓存 开发者
Python中的装饰器:优雅而强大的代码增强工具
在Python编程中,装饰器是一种强大的工具,它允许开发者在不改变原有代码结构的情况下,增加额外的功能。本文将深入探讨Python中装饰器的概念、用法和实际应用,展示其在代码优化和增强方面的威力。
|
1天前
|
Python 设计模式 缓存
Python中的装饰器:提升代码可读性与可维护性
在Python编程中,装饰器是一种强大的工具,它可以提高代码的可读性和可维护性。本文将深入探讨装饰器的概念、用法以及实际应用场景,帮助读者更好地理解和利用Python中的装饰器。
|
1天前
|
Python 缓存
Python 中的装饰器:提升代码可读性与灵活性
Python 中的装饰器是一种强大的工具,它可以提高代码的可读性和灵活性。本文将深入探讨装饰器的概念、用法以及如何在实际项目中应用装饰器来简化代码、增加功能,以及解决常见的编程问题。
|
1天前
|
Python
通过f-string编写简洁高效的Python格式化输出代码
Python 3.6中引入的f-string是Python中最常用的特征之一,它可以让我们编写更干净、更高效和更易于维护的代码,我们今天就由浅入深来详细介绍使用它的一些技巧。
11 4
|
2天前
|
算法 程序员 开发工具
GitHub上新!14个Python项目详细教程(附完整代码)
Python作为程序员的宠儿,越来越得到人们的关注,使用Python进行应用程序开发的也越来越多。 今天给小伙伴们分享的这份项目教程完整代码已上传至GitHub,你可以选择跟着这份教程一段一段的手敲出来这几个项目,也可以直接从GitHub上copy下来。
|
2天前
|
机器学习/深度学习 人工智能 运维
【机器学习】Adaboost: 强化弱学习器的自适应提升方法
在机器学习领域,集成学习是一种通过结合多个弱模型以构建更强大预测模型的技术。Adaptive Boosting,简称Adaboost,是集成学习中的一种经典算法,由Yoav Freund和Robert Schapire于1996年提出。Adaboost通过迭代方式,自适应地调整数据样本的权重,使得每个后续的弱学习器更加关注前序学习器表现不佳的样本,以此逐步提高整体预测性能。本文将深入探讨Adaboost的工作原理、算法流程、关键特性、优势及应用场景,并简要介绍其实现步骤。
10 1
|
3天前
|
并行计算 算法 编译器
如何优化Python代码以提高执行效率
如何优化Python代码以提高执行效率
10 1
|
5天前
|
Shell 开发工具 git
[oeasy]python019_ 如何在github仓库中进入目录_找到程序代码_找到代码
本文档介绍了如何在终端环境下使用Git克隆仓库后,通过`cd`、`pwd`和`ls`命令导航并找到下载的文件。首先,使用`ls`查看当前目录,然后通过`cd`逐层进入目标文件夹,最后到达包含游戏文件game.py的位置。文章还提到了如果`git clone`失败,可以直接进行下一节实验。
12 0