Python 机器学习 预测新数据(用Python分析英国人的肥胖现象)
Python 机器学习 预测新数据(用Python分析英国人的肥胖现象)Python和Excel的对比在使用Pandas分析这些数据之前,我们先来思考一个无法回避的问题:既然已经可以在EXCEL中分析处理这些数据了,还需要使用Python多此一举吗?数据来源数据来自Data.gov.uk,我们选择2014年度的XLS格式的数据,下载下来,用表格软件打开(本文用的是OpenOffice,一款开源的办公处理软件——译者注)。如下图所示定位到sheet7.2,找到我们需要的数据:
Python部落(python.freelycode.com)组织翻译,禁止转载,欢迎转发。
下面这篇文章出自Shantnu Tiwari ,在发现并使用Python之前,他是一个在C/C 里摸爬滚打多年的程序猿。
现在他在这里分享他的挚爱(Python)。
昨天我在体育场看到一条标语:“儿童正在走向肥胖”。在这个标语下面立着一个展板,说是在未来五年,全英国儿童平均要和拖拉机一样肥胖。我觉得这个说法有一丢丢的不靠谱,因此我决定研究一下……
数据来源
数据来自Data.gov.uk,我们选择2014年度的XLS格式的数据,下载下来,用表格软件打开(本文用的是OpenOffice,一款开源的办公处理软件——译者注)。
如下图所示定位到sheet7.2,找到我们需要的数据:
在使用Pandas分析这些数据之前,我们先来思考一个无法回避的问题:既然已经可以在EXCEL中分析处理这些数据了,还需要使用Python多此一举吗?
Python和Excel的对比
我们应该使用Python还是Excel?
对于一些刚接触数据分析的人来说,经常会有这样的疑问。虽然在编程社区里面Python非常流行,但是在日常办公中Excel更普及。大部分管理层、销售人员、市场营销等都在使用Excel——再正常不过了。如果你能熟练掌握Excel的话,它是一个很实用的工具。即使你不是专业人员,Excel也能让你成为数据分析专家。
所以说使用Python还是Excel,这是一个问题,一个不太好回答的问题。但是说到底,其实我们没有必要非A即B的做选择题,鱼与熊掌,我们可以兼得——Python和Excel结合起来做数据分析。
Excel可以满足数据查阅、基本的数据分析和简单的图表制作,但是不适合进行数据的整理分析(除非你愿意跳入VBA的坑)。可以想象一下,如果你有一个500MB左右的数据文件,这个数据文件里夹杂着残缺的数据,混乱的格式,那么你需要花费大量时间去手动整理这些数据。如果你的数据是在一堆CSV格式的文件里,情况也好不到哪里去。
Pandas是Python中用来处理数据的一个库,利用它来整理上面提到的凌乱的数据简直就是小菜一碟。作为Numpy中地位较高的库,Pandas可以轻松处理高难度的数据分析,还能把处理的结果保存到Excel文件中,方便我们继续跟一些不懂编程的人分享交流。
代码
现在我们可以编写代码了——这些代码可以在https://github.com/shantnu/python-obesity的repo项目里找到。
创建一个新的Python脚本,命名为obesity.py,导入Pandas和matplotlib,以便于后面绘制图表。
确保你已经安装了这两个依赖的库:pip install pandas matplotlib
接下来,读取Excel文件:
看,就是这么任性,一行代码读取了整个Excel文件。
输出读取的数据:
运行这个脚本,输出结果如下:
很眼熟吧?这就是我们之前看到的sheet(工作表)。不要忘了,我们的目标时sheet7.2。在sheet7.2里我们可以看到,前4行和后14行包含的都是没有用的信息:对我们来说有用,对代码来说没有用。现在只需要提取第5到第18行数据。
数据整理
在读取sheet里面的数据之前,我们首先要确保sheet里面多余的信息已经被剔除。
再次运行。
这样就实现了读取sheet,并且忽略了前4行和后四行(因为这几行内容不是我们需要的数据)。然后输出了读取到的sheet里面的内容(这里只截图了输出的一部分结果)。
第一行表示列的表头。Pandas在处理数据时非常智能,它可以正确的提取出大部分表头——除了第一列Unnamed:0。为什么会这样呢?答案很简单。看看Excel文件,文件本身就没有year列的表头。
另一个问题是在原始文件中存在一个空行,在输出时显示的是NaN(Not a Number)。
因此现在我们要做两件事:
1.重命名第一列year的表头;
2.剔除所有的空行。
这里告诉Pandas利用內建函数rename把Unnamed:0重命名为year。
inplace = True 该参数修改已经存在的对象。如果没有这个参数,Pandas会创建并返回一个新的对象。
接下来剔除空行NaN:
还有一件事要做,做了这件事以后,我们接下来的处理就会方便很多。如果认真观察data_age标签,我们可以发现,第1列值是数字(0 1 2 3……)。这些数字是索引,Pandas沿用Excel中默认的作为索引。然而,我们想要把year列作为索引,这样在绘制图标的时候就简便了,因为索引通常作为X轴。
把year设置为索引。
现在输出整理后的数据:
运行脚本:
比之前好多了。你可以看到现在索引是year列了,而且所有的NaN都没有了。
图表
现在我们依据提取到的数据绘制图表。
呃,出了个小问题:原始数据里面包含total,从上图中也可以看出,total那条线占据了大半个图,我们需要剔除它。
参数axis = 1 可能不太好理解,不过它的作用就是去除total那一列(具体用法可以参考Stack Overflow上的解释)
现在重新绘制一下图表。
比刚才好多了。在下图中可以看到每个年龄段的具体情况。你能看出哪个年龄段的人群更肥胖吗?
回到我们一开始提出的问题:儿童正在走向肥胖吗?
我们只提取出一小部分数据:年龄在16岁以下的儿童和年龄在35到44之间的成年人。
谁在越发的肥胖呢?
那么,我们从图上看到了什么呢?
儿童的肥胖情况在2008年以后有所下降,但是他们的父母肥胖情况却在爆发式地增长:这意味着父母更应该担心他们自己的体重。
但是将来会如何呢?
然并卵,这张图没有告诉我们将来儿童肥胖情况的走势。有很多办法可以根据图中的曲线来预测将来的趋势,但是在我们着手处理之前,我必须友情提示一下下:这些肥胖数据没有精确统计依据。也就是说,我们无法找到一个公式来预测将来这些数据的走势。一切都是基于预测——脑子里有了这个概念,我们看看怎样推导出我们想要的图表。
首先,Scipy确实提供了一个用于预测的函数,但是它只对单调递增的数据有用(然而我们的数据是上下波动的)。
我们可以试试 Curve Fitting:
Curve Fitting尝试通过图表上的点来拟合曲线。生成的图像可能准确,也可能不准确,这取决于数据的准确性。
Polynomial Interpolation(多项式插值)一旦有了公式,你可以利用Polynomial Interpolation在图表中插入任何值。
我们将利用这两个函数推测出英国儿童未来肥胖发展趋势:
这里,我们提取出年龄小于16岁的儿童的数据。之前图表X轴为日期,为了简化处理,我们用数字0—10作为X轴。
输出:
还有一事儿:曲线拟合时使用不同的多项式复杂度。简单来说,就是复杂度越高,绘出的曲线越精确,不过也有可能导致图表废掉。如果复杂度设置的太高的话,Scipy会发出警告。不用担心复杂度的设置,看一些例子就明白了。
我们把复杂度设置为3,然后利用Numpy的polyfit函数进行拟合,最后利用poly1d函数调用这个拟合后的对象。下面代码将用到返回的poly_interp。
i的值从0到10,poly_interp循环作用于这些值。这是我们使用曲线拟合算法时推导的函数。
在继续敲代码之前,我们先看看不同的复杂度都有什么区别。
我们用原始数据和处理过的数据,看看哪一个更接近我们理想的结果。
蓝色的曲线是原始数据绘制的,标记为Orig;红色曲线是生成的数据绘制的,标记为Fitted。
复杂度设置为3.
这样的曲线拟合度不高,我们试试复杂度设为5:
拟合度好多了,试试把复杂度设置为7:
现在这两根曲线基本上能够贴合到一起去,那么我们为什么不把复杂度设置的更高呢?
因为复杂度设置的越高,曲线拟合度就越高,那么对曲线趋势的预测就越不准确。如果我们依据上面的曲线来做出预测,那么得到的结果也是不靠谱的。经过不同的尝试,我发现3到4的复杂度能最大程度的还原数据本身,并且能更准确地预测未来的走势,所以下面我们选择3到4的复杂度。
我们重新运行poly_interp函数,这一次把参数设置为0—15,也就是预测未来五年的走势。
代码和之前的一样,拟合复杂度分别设置为3和4,绿色的曲线是预测趋势线,标记为Prediction。
复杂度为3:
这里,肥胖趋势向下。复杂度为4呢?
这里,预测的曲线扶摇直上,这是要上天的节奏,也就是说五年后孩子们真的会像拖拉机一样肥胖!
上面两条预测曲线,哪一个正确呢?这取决于你是在为政府工作还是在为反对党工作了。
上面两个走势线确实是一种趋势,不是bug。在一些政治辩论中,你一定听说过这样的情况,面对同样的数据争论双方得到的却是完全相反的结论。现在你明白怎样通过调整一个小参数来得出截然相反的结论了吧。
这也就是为什么对于从别人那里得到的数据和图表,我们要格外留意分辨真假,尤其是当他们不愿意分享原始数据的时候。有的时候,不妨把预测留给算命先生去。
大功告成!
在Python For Engineers 上面获得免费的电子书:Python: From Apprentice to Master,还可以学习更多关于数据处理的知识。
英文原文:https://realpython.com/blog/python/analyzing-obesity-in-england-with-python/