1.4 第一个用 Python 实现的数据化运营分析实例——销售预测
1.4.1 案例概述
本节通过一个简单的案例,来介绍如何使用Python进行数据化运营分析。
案例场景:每个销售型公司都有一定的促销费用,促销费用可以带来销售量的显著提升;当给出一定的促销费用时,预计会带来多大的商品销售量?
在“附件-chapter1”中data.txt存储了建模所需的原始数据,get_started_example.py是案例完整代码。以下是原始数据概况:
来源:生成的模拟数据,非真实数据。
用途:用来做第一个销售预测案例。
维度数量:1。
记录数:100。
字段变量:第一列是促销费用,第二列是商品销售量。
数据类型:全部是浮点数值型。
是否有缺失值:否。
1.4.2 案例过程
下面逐步解析整个分析和实践过程。
第一步 导入库。
本案例中,我们会使用四个库:
Re:正则表达式,程序中通过该库来实现字符串分割。
Numpy:数组操作和处理库,程序中用来做格式转换和预处理。
Sklearn:算法模型库,程序中使用了线性回归方法linear_model。
Matplotlib:图形展示库,用来在建模前做多个字段关系分析。
代码如下:
import re import numpy from sklearn import linear_model from matplotlib import pyplot as plt
相关知识点:Python导入库
Python导入库有两种方式:
导入直接导入库,方法是import[库名],例如import numpy;对于某些名称比较长的库,我们会使用as方法为其取个别名以方便后续使用,例如import numpy as np。
导入库中的指定函数,方法是from[库名]import[函数名],例如from sklearn import linear_model;这种情况下也可以使用as为其取个别名方便后续使用,例如from matplotlib import pyplot as plt。
第二步 导入数据。
本案例中的数据存于txt格式文件中,我们使用Python默认的读取文件的方法。代码如下:
fn = open('data.txt','r') all_data = fn.readlines() fn.close()
第一段代码fn=open('data.txt','r')的作用是打开名为“data.txt”的文件,文件模式是只读,并创建一个名为fn的文件对象,后续所有关于该文件的操作都通过fn执行。由于程序文件和数据文件处于同一个目录下,因此无须指定路径;也可以通过相对路径和绝对路径来设置完整路径。
指定相对路径:'../data/data.txt',含义是“data.txt”位于当前Python工作目录的父级目录中的data文件夹中。
指定绝对路径:'d:/python_data/data/data.txt',该方式中的绝对路径需要注意使用正斜杠/,而不是Windows默认的反斜杠\;如果一定要使用反斜杠,那么需要写成'd:\\python_data\\data\\data.txt',用转义字符表示。
在Python中反斜杠作为转义字符存在,使用\\的意思是这是一个反斜杠符号。表1-1列出了Python常用的转义字符。
表1-1 常用转义字符列表
第二段代码all_data=fn.readlines()的意思是从fn中读取所有的行记录,并保存到一个名为all_data的列表中。我们可以通过all_data[0]来查看该列表的第一个数据,Python中的数据索引都是从0开始,第0个索引值对应第一个值。
In[3]: all_data[0] Out[3]: '28192.0\t68980.0\n'
通过查看第一个数据,我们了解了数据的基本情况,这是一个由数字、水平制表符和回车符组成的字符串,两个数字之间使用\t水平制表符分割,每个字符串以\n回车符结尾。该信息会为后续做数据预处理提供思路。
第三段代码fn.close()的意思是关闭文件对象的占用。当文件读写完成后,需要及时关闭资源占用。
不仅是文件对象,包括数据库游标、数据库连接等资源,在使用完成后都需要及时关闭,这样能减少对资源的无效占用。同时,这还能防止当其他功能模块对该对象进行重命名、删除、移动等操作时,不会由于文件对象的占用而报错。
第三步 数据预处理。
在本阶段,主要实现对读取的列表数据进行清洗转换,以满足数据分析展示和数据建模的需要。代码如下:
x = [] y = [] for single_data in all_data: tmp_data = re.split('\t|\n',single_data) x.append(float(tmp_data[0])) y.append(float(tmp_data[1])) x = numpy.array(x).reshape([100,1]) y = numpy.array(y).reshape([100,1])
代码x=[]和y=[]的意思是创建两个空列表,目的是用来存放自变量和因变量数据。
代码for single_data in all_data的意思是通过一个for循环每次从列表all_data中读取一条数据,并赋值给single_data。
代码tmp_data=re.split('\t|\n',single_data)的意思是,分别使用\t和\n作为分割符,对single_data进行数据分割,分割结果赋值为tmp_data。
代码x.append(float(tmp_data[0]))和y.append(float(tmp_data[1]))的意思是将tmp_data的第一个值追加到列表x中,将tmp_data的第二个值追加到列表y中。在追加之前,我们先将每个数据通过float方法设为浮点型(数值型)。
代码x=numpy.array(x).reshape([100,1])和y=numpy.array(y).reshape([100,1])的意思是将x和y由列表类型转换为数组类型,同时数组的形状是100行1列。
第四步 数据分析。
到现在止我们已经拥有了格式化的数据,但这两列数据集到底应该使用哪种模型还未可知。因此先通过散点图来观察一下。代码如下:
plt.scatter(x,y) plt.show()
代码plt.scatter(x,y)的意思是用一个散点图来展示x和y,plt.show()的作用是展示图形。代码执行后会弹出如图1-9所示的散点图。
图1-9 散点图
通过散点图发现,x和y的关系呈现明显的线性关系:当x增大时,y增大;当x减小时,y减小。初步判断可以选择线性回归进行模型拟合。
第五步 数据建模。
建模阶段我们使用Sklearn中的线性回归模块实现,代码如下:
model = linear_model.LinearRegression() model.fit(x, y)
代码model=linear_model.LinearRegression()的作用是创建一个模型对象,后续所有的模型操作都基于该对象产生。
代码model.fit(x,y)的作用是将x和y分别作为自变量和因变量输入模型进行训练。
第六步 模型评估。
模型已经创建完成,本阶段进行模型拟合的校验和评估,代码如下:
model_coef = model.coef_ model_intercept = model.intercept_ r2 = model.score(x,y)
代码model_coef=model.coef_的作用是获取模型的自变量的系数并赋值为model_coef;代码model_intercept=model.intercept_的作用是获取模型的截距并赋值为model_intercept;代码r2=model.score(x,y)获取模型的决定系数R的平方。
通过上述步骤我们可以获得线性回归方程y=model_coef*x+model_inter-cept,即y=2.09463661*x+13175.36904199。该回归方程的决定系数R的平方是0.78764146847589545,整体拟合效果不错。
第七步 销售预测。
我们已经拥有了一个可以预测的模型,现在我们给定促销费用(x)为84610,销售预测代码如下:
new_x = 84610 pre_y = model.predict(new_x) print (pre_y)
代码new_x=84610的作用是创建促销费用常量,用来做预测时输入。代码pre_y=model.predict(new_x)的作用是对促销费用常量new_x输入模型进行预测,将预测结果赋值为pre_y。代码print(pre_y)的作用是打印输出销售预测值。
代码执行后,会输出[[190402.57234225]],这就是预测的销售量。为了符合实际销量必须是整数的特点,后续可以对该数据做四舍五入,使round(pre_y)获得预测的整数销量。
相关知识点:如何执行Python代码?
对稍微有些经验的程序员或Python工程师来讲这当然不是什么问题,但对第一次接触Python的读者来讲,这也许是一个需要补充的必要知识点。
对于Python代码,既可以只执行特定代码行/段,也可以执行整个代码文件。
场景1:执行特定代码行/段。
这种方式通常是以调试的方式逐行/模块运行代码,大多应用在单功能、模块的开发、调试和测试上。执行方式如下:
1)在Python命令行中执行:打开系统终端命令行窗口,输入python进入Python命令行界面,然后逐行或模块输入上述Python代码即可。
2)在IPython命令行中执行:在打开系统命令行窗口,输入ipython进入ipython命令行界面,然后逐行或模块输入上述Python代码即可。
3)在PyCharm中执行:PyCharm是本书推荐使用的Python IDE,笔者推荐使用这种方式进行代码功能开发和测试。打开PyCharm程序,第一次需要新建一个项目用来存储和管理所有即将开发的Python资源,Location(位置)指向本书的“附件”根目录,然后点击Create(创建)。如图1-10所示。
创建完成后的PyCharm界面如图1-11所示,除了顶部菜单栏外,下面的内容区分为4个部分,从①到④依次是项目/结构区、代码区、调试区、智能提示区。
项目/结构区:项目方式展示本项目所有文件、外部连接库,结构方式展示当前文件下所有的函数、变量等详细信息。
图1-10 在PyCharm中新建Python项目
图1-11 PyCharm项目界面概览
代码区:展示所有程序代码、注释的区域。
调试区:分为TODO、Console、Terminal三个模块,分别用于提供注释的TODO列表、调试和终端功能。
智能提示区:给出代码中可能存在的格式、引用、语法等方面的错误或警告信息。
在代码区,用鼠标选中要调试的程序,直接输入组合键ALT+Shift+E,然后在调试区可以看到该代码执行的状态。图1-12所示是程序调试执行结果。
图1-12 程序调试执行结果
场景2:执行整个代码文件。
这种方式通常将Python文件作为整体的运行代码,一般在单个功能或模块开发完成之后,在整体或多功能模块的测试、集成或程序间调用时使用。
1)在系统终端命令行中调用Python命令执行:打开系统命令行窗口,输入python+[python文件名称].py。图1-13为运行本章案例的Python程序文件,执行结果将先显示一个图形文件,关闭图形之后会继续运行显示预测结果。
图1-13 通过系统终端命令行中调用Python命令执行
2)在IPython命令行中执行:打开系统命令行窗口,输入ipython进入ipython命令行界面,然后在交互命令窗口输入run+[python文件名称].py,如图1-14所示。
3)在PyCharm中执行:在PyCharm中新建项目后,双击左侧项目/结构区要执行的Python文件,右侧会显示对应的Python文件的代码内容。输入组合快捷键Alt+Shift+F10或通过顶部菜单栏“Run→Run”,在弹出的窗口中选择要执行的Python文件。如图1-15所示,程序文件执行后,会在底部调试窗口显示执行结果。
图1-14 在IPython中执行Python文件
图1-15 在PyCharm中执行Python文件
在PyCharm中已经集成了IPython命令行和系统终端窗口功能,点击“Python Console”后的调试界面,默认调用的是IPython库;点击“Terminal”后的调试界面正是系统终端的命令行界面。读者可直接在此直接操作上述命令,实际上,这也是笔者着重推荐使用PyCharm作为IDE的主要原因之一,在一个工具里面可以直接实现不同的调试场景:
安装第三方库时使用pip命令或需要从终端调用命令时,可直接点击“Terminal”操作;
想要使用IPython的友好开发交互和提示功能,可直接在“Python Console”中完成;
想要完整查看Python项目资源并进行管理,尤其是代码审查等方面,PyCharm可以完美胜任。
1.4.3 案例小结
本案例看似篇幅很长,其实代码本身只有40多行,却实现了导入库、获取数据、数据预处理、数据展示分析、数据建模、模型评估和销售预测7个关键步骤,麻雀虽小五脏俱全。
案例场景虽然简单,但完整地演示了如何从输入数据到输出结果的整个过程,其中,我们用到了以下基础知识:
Python文件的读取;
Python基本操作:列表操作(新建、追加)、for循环、变量赋值、字符串分割、数值转换;
Numpy数组操作:列表转数组、重新设置数组形状;
使用Matplotlib进行散点图展示;
使用Sklearn进行线性回归的训练和预测;
用print输出指定数据。
这是本书的第一个完整案例的目的是引导读者快速进入使用Python进行数据化运营的场景中来,因此笔者并不希望让读者陷入复杂的逻辑和太多知识当中,以下内容仅做拓展思考之用:
通过散点图初步判断线性回归是比较好的拟合模型,此时应思考,是否有其他回归方法会得到更好的效果,例如广义线性回归、SVR(SVM中的回归)、CART(分类回归树)等?
通过图形法观察数据模型只适合用于二维数据,如果数据输入的维度超过2个呢?
本案例中的数据量比较小,如果数据量比较大,假如有1000万条,如何进行数据归约?
除了案例中的评估指标外,还有哪些指标可以做效果评估?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论