前言
本文是本人研读《深入浅出数据分析》一书后,使用不同工具对书中案例的分析,一是为了加强自己对案例的理解,二是希望能将各种主流工具学以致用,三是将个人的学习思考进行总结量化;
本文所使用的案例数据均从《深入浅出数据分析》的官网中下载,根据自己的学习需求对数据进行了一些处理,不代表官方,官方下载地址如下:examples / Head First Data Analysis · GitLab (oreilly.com)
背景描述:
某客户公司想提高产品利润,需要你计算出该如何组合产品数量来实现利润最大化;
思考引导:
你需要哪些数据才能解决这些问题?
个人思考:
我需要以下数据来进行分析
(1)产品利润数据:了解每种产品的毛利,才能计算总利润;
(2)生产条件限制:了解生产时间和原材料的约束,确定生产阈值;
(3)产品历史销量数据:了解两种产品的历史销量,确定销量阈值;
(4)行业销量数据:了解整个行业的产品销量,确定生产上下限;
现有信息:
原料:橡胶供应量50000,够生产500只橡皮鸭或400条橡皮鱼;
时间:时间仅够用来生产400只橡皮鸭或300条橡皮鱼;
利润:橡皮鸭5美元/只,橡皮鱼4美元/条;
数据:只有行业的历史销量数据,没有公司的历史销量数据,原始数据结构如下:
Month列的值为1-12月份的英文首字母,意味着1-12月会有重复字母出现,如March和May的首字母都是M;
解决思路:
此时,若不考虑历史销量数据和行业销量数据就进行生产组合求解,得出的产品组合只能是理想状态下的最优解,因为现实情况中,生产的产品不一定能够全部销售出去,要根据历史销量进行生产调整。但我们不妨看看理想情况下需要怎么样的产品组合才能使利润最大化。我们可以根据已知信息,建立目标函数:
如果全拿来生产一种产品则另一种产品就无法生产,可知这两种产品是相互约束的一元关系,可以使用x,y表示这两种产品的数量;
假设生产x只橡皮鸭,y条橡皮鱼,获得利润为z,根据客户信息可知,x, y的取值在不同条件约束下分别为:
在原料上:0≤x≤500, 0≤y≤400;
在时间上:0≤x≤400, 0≤y≤300;
在利润上:z=5x+4y;
在时间上的约束取值要小于原料上的约束取值,所以将x, y的约束取值缩小为0≤x≤400, 0≤y≤300;
为了使得z最大化,求解x, y;
详细步骤:
1.设计excel表格结构,将时间约束、橡胶约束、利润呈现在表格中,注意使用单元格引用,实现表格自动化;
2.使用Excel工具中的"规划求解"在可行域中进行最优化求解,只需要将x,y,z单元格、约束条件传入求解器中,就能得到求解出的x,y,z;
(1)使用"规划求解"前需要在Excel的加载项中将其加载到菜单栏中,在 Excel 文件 - >选项→加载项 - > 管理(Excel 加载项) - > 转到,勾选 “规划求解加载项”,然后确定,加载出的“规划求解“就会出现在 数据标签的功能区下了;
(2)在规划求解器中传入相关单元格后,点击确认,自动求解出x,y,z的值,最优解显示 x=400,y=80,z=2320;
后续优化
正如前文解决思路所说,不考虑历史销量的生产组合时理想状态下的求解方案。现在,让我们看看真实的历史销量数据,将历史销量数据作为约束条件考虑进来后求解,为此,我们需要对历史数据进行分析。
分析思路:
绘制历史销量趋势,看一下数据变化趋势,对趋势进行分析,并对下一个月的销量进行预测,将预测销量作为约束条件放到规划求解器中重新求解。
工具选择:
Excel
使用Excel绘制折线图,不会对源数据表中的月份列的重复值进行合并,简单方便快速,就是有点丑,调格式有点费时间。
Tableau
使用Tableau绘制折线图,需要先对源数据表进行处理,将Month列的值处理成不重复的日期格式,因为原始数据中的月份有重复值,Tableau会将重复值进行合并,得不到完整的日期序列,经过Excel处理后的日期如下所示,可以使用下列两种日期格式,Excel还支持更多日期格式的显示,可以看个人喜好进行调整。
Tableau绘图的最大优点是简单,默认配色十分好看,而且还能使用分析功能在进行下一月份/年度的销量预测,下图显示了产品的历史销量趋势和下月销量预测,预测显示,下个月橡皮鸭销量不会超过200,橡皮鱼销量不会超过150;
Python
使用Pyhton绘制折线图,和Tableau一样需要先对源数据表进行处理,理由同上,为了方便显示,最终的日期格式为"Jan-07",最终制图效果如下:
粗糙版跑图效果看起来比Excel还差,如果需要优化显示,需要对图像中各种元素进行参数的调整,调参过程也有点费时,不嫌麻烦的朋友也可以上网找一些优秀图像代码,本文所用python代码详见附录;
工具总结:
在可视化图表上,最简单且最好看的是Tableau,推荐用于制图;
在数据处理和简单趋势分析上,可以使用大众通用工具Excel;
在批量数据处理和批量出图上,可以使用Python代码解放双手;
具体工具使用看个人喜好和实际数据情况;
图像分析:
由上图可以明显看出
1.总销量在每年的10月份开始快速上升,而在每年12月份过后,总销量开始迅速下降;
2.橡皮鸭和橡皮鱼的销量总体上呈现负相关,一年之中的大部分时间里,橡皮鸭卖得多,橡皮鱼就卖得少,单也有极个别月会出现两者销量共同上升的情况,虚线区域表示橡皮鱼和橡皮鸭销量共同上升的时间段;
3.从销售曲线上来看,明年1月份的销量会是橡皮鸭领先,但是销量不会超过200,如果保守一点参考过去两年的一月份数据,则橡皮鸭不会超过150,橡皮鱼不会超过50;
规划求解:
根据Tableau预测和人为的保守预测,有以下两种方案可以作为约束条件:
(1)Tableau预测:下个月橡皮鸭销量不会超过200,橡皮鱼销量不会超过150;
(2)保守预测:下个月橡皮鸭销量不会超过150,橡皮鱼销量不会超过50;
将这两个方案分别代入到规划求解器中求解目标函数的最优解,分别得到如下结果:
于是我们惊人地发现最优解居然就是两个方案的约束条件;
全文总结
通过上面这个例子,我们其实也可以直接利用历史销量数据对下月份的销量进行预测,用销量指导生产,但如果这样计算的话,我们又犯了一开始的错误,要是生产的橡胶不足以支撑销量怎么办?要是时间不够怎么办?因此在考虑生产销量问题的时候还是需要把两者结合起来组成约束条件,才能实现利润最大化;
附录
python源代码
import pandas as pd import matplotlib.pyplot as plt plt.rcParams['font.sans-serif']='SimHei'#设置中文字体格式 plt.rcParams['axes.unicode_minus']=False#设置横杠显示 plt.grid(axis='y')#显示水平方向的网格 #plt.grid(True,color='r',linestype='--',linewidth=0.5,alpha=0.5)#设置网格线的宽度,风格,颜色,透明度 #读取数据表 data=pd.read_csv('F:/hfda/historical_sales_data1.csv') #取出x,y变量 Month=data['Date'] Fish=data['Fish'] Ducks=data['Ducks'] Total=data['Total'] #折线图 plt.plot(Month,Fish,label='Fish',color="pink") plt.plot(Month,Ducks,label='Ducks',color="orange") plt.plot(Month,Total,label='Total',color="red") plt.legend() plt.title('历史销量情况2007-2009') #设置标题 plt.xticks(rotation='vertical')#设置x轴标签文字为竖直排列 plt.xlabel('月份') #设置x轴标题 plt.ylabel('销量') #设置y轴标题 plt.ylim(0,400) #设置y轴范围 plt.show() #显示图像