CDA数据分析师 出品

作者:曹鑫

双十一到今年已经是13个年头,每年大家都在满心期待看着屏幕上的数字跳动,年年打破记录。而 2019 年的天猫双11的销售额却被一位微博网友提前7个月用数据拟合的方法预测出来了。他的预测值是2675.37或者2689.00亿元,而实际成交额是2684亿元。只差了5亿元,误差率只有千分之一。

但如果你用同样的方法去做预测2020年的时候,发现,预测是3282亿,实际却到了 4982亿。原来2020改了规则,实际上统计的是11月1到11日的销量,理论上已经不能和历史数据合并预测,但咱们就为了图个乐,主要是为了练习一下 Python 的多项式回归和可视化绘图。

把预测先发出来:今年双十一的销量是 9029.688 亿元!坐等双十一,各位看官回来打我的脸。

NO.01、统计历年双十一销量数据
从网上搜集来历年淘宝天猫双十一销售额数据,单位为亿元,利用 Pandas 整理成 Dataframe,又添加了一列’年份int’,留作后续的计算使用。

import pandas as pd

数据为网络收集,历年淘宝天猫双十一销售额数据,单位为亿元,仅做示范

double11_sales = {‘2009年’: [0.50],
‘2010年’:[9.36],
‘2011年’:[34],
‘2012年’:[191],
‘2013年’:[350],
‘2014年’:[571],
‘2015年’:[912],
‘2016年’:[1207],
‘2017年’:[1682],
‘2018年’:[2135],
‘2019年’:[2684],
‘2020年’:[4982],
}

df = pd.DataFrame(double11_sales).T.reset_index()
df.rename(columns={‘index’:‘年份’,0:‘销量’},inplace=True)
df[‘年份int’] = [[i] for i in list(range(1,len(df[‘年份’])+1))]
df
.dataframe tbody tr th {
vertical-align: top;
}

.dataframe thead th {
text-align: right;
}

NO.02、绘制散点图
利用 plotly 工具包,将年份对应销售量的散点图绘制出来,可以明显看到2020年的数据立马飙升。

散点图

import plotly as py
import plotly.graph_objs as go
import numpy as np

year = df[:][‘年份’]
sales = df[‘销量’]

trace = go.Scatter(
x=year,
y=sales,
mode=‘markers’
)
data = [trace]

layout = go.Layout(title=‘2009年-2020年天猫淘宝双十一历年销量’)

fig = go.Figure(data=data, layout=layout)

fig.show()

var gd = document.getElementById(‘2b361fe9-adc3-4cbe-810c-f76371d70c59’);
var x = new MutationObserver(function (mutations, observer) {{
var display = window.getComputedStyle(gd).display;
if (!display || display === ‘none’) {{
console.log([gd, ‘removed!’]);
Plotly.purge(gd);
observer.disconnect();
}}
}});

// Listen for the removal of the full notebook cells
var notebookContainer = gd.closest(’#notebook-container’);
if (notebookContainer) {{
x.observe(notebookContainer, {childList: true});
}}

// Listen for the clearing of the current output cell
var outputEl = gd.closest(’.output’);
if (outputEl) {{
x.observe(outputEl, {childList: true});
}}
})
};
});

NO.03、引入 Scikit-Learn 库搭建模型
一元多次线性回归

我们先来回顾一下2009-2019年的数据多么美妙。先只选取2009-2019年的数据:

df_2009_2019 = df[:-1]
df_2009_2019
.dataframe tbody tr th {
vertical-align: top;
}

.dataframe thead th {
text-align: right;
}

通过以下代码生成二次项数据:

from sklearn.preprocessing import PolynomialFeatures
poly_reg = PolynomialFeatures(degree=2)
X_ = poly_reg.fit_transform(list(df_2009_2019[‘年份int’]))
1.第一行代码引入用于增加一个多次项内容的模块 PolynomialFeatures

2.第二行代码设置最高次项为二次项,为生成二次项数据(x平方)做准备

3.第三行代码将原有的X转换为一个新的二维数组X_,该二维数据包含新生成的二次项数据(x平方)和原有的一次项数据(x)

X_ 的内容为下方代码所示的一个二维数组,其中第一列数据为常数项(其实就是X的0次方),没有特殊含义,对分析结果不会产生影响;第二列数据为原有的一次项数据(x);第三列数据为新生成的二次项数据(x的平方)。

X_
array([[ 1., 1., 1.],
[ 1., 2., 4.],
[ 1., 3., 9.],
[ 1., 4., 16.],
[ 1., 5., 25.],
[ 1., 6., 36.],
[ 1., 7., 49.],
[ 1., 8., 64.],
[ 1., 9., 81.],
[ 1., 10., 100.],
[ 1., 11., 121.]])
from sklearn.linear_model import LinearRegression
regr = LinearRegression()
regr.fit(X_,list(df_2009_2019[‘销量’]))
LinearRegression()
1.第一行代码从 Scikit-Learn 库引入线性回归的相关模块 LinearRegression;

2.第二行代码构造一个初始的线性回归模型并命名为 regr;

3.第三行代码用fit() 函数完成模型搭建,此时的regr就是一个搭建好的线性回归模型。

NO.04、模型预测
接下来就可以利用搭建好的模型 regr 来预测数据。加上自变量是12,那么使用 predict() 函数就能预测对应的因变量有,代码如下:

XX_ = poly_reg.fit_transform([[12]])
XX_
array([[ 1., 12., 144.]])
y = regr.predict(XX_)
y
array([3282.23478788])
这里我们就得到了如果按照这个趋势2009-2019的趋势预测2020的结果,就是3282,但实际却是4982亿,原因就是上文提到的合并计算了,金额一下子变大了,绘制成图,就是下面这样:

散点图

import plotly as py
import plotly.graph_objs as go
import numpy as np

year = list(df[‘年份’])
sales = df[‘销量’]

trace1 = go.Scatter(
x=year,
y=sales,
mode=‘markers’,
name=“实际销量” # 第一个图例名称
)

XX_ = poly_reg.fit_transform(list(df[‘年份int’])+[[13]])
regr = LinearRegression()
regr.fit(X_,list(df_2009_2019[‘销量’]))
trace2 = go.Scatter(
x=list(df[‘年份’]),
y=regr.predict(XX_),
mode=‘lines’,
name=“拟合数据”, # 第2个图例名称
)

data = [trace1,trace2]

layout = go.Layout(title=‘天猫淘宝双十一历年销量’,
xaxis_title=‘年份’,
yaxis_title=‘销量’)

fig = go.Figure(data=data, layout=layout)

fig.show()

var gd = document.getElementById(‘e8ae9262-7d14-4b38-b661-fb79f13ff6a7’);
var x = new MutationObserver(function (mutations, observer) {{
var display = window.getComputedStyle(gd).display;
if (!display || display === ‘none’) {{
console.log([gd, ‘removed!’]);
Plotly.purge(gd);
observer.disconnect();
}}
}});

// Listen for the removal of the full notebook cells
var notebookContainer = gd.closest(’#notebook-container’);
if (notebookContainer) {{
x.observe(notebookContainer, {childList: true});
}}

// Listen for the clearing of the current output cell
var outputEl = gd.closest(’.output’);
if (outputEl) {{
x.observe(outputEl, {childList: true});
}}
})
};
});

NO.05、预测2021年的销量
既然数据发生了巨大的偏离,咱们也别深究了,就大力出奇迹。同样的方法,把2020年的真实数据纳入进来,二话不说拟合一样,看看会得到什么结果:

from sklearn.preprocessing import PolynomialFeatures
poly_reg = PolynomialFeatures(degree=5)
X_ = poly_reg.fit_transform(list(df[‘年份int’]))

预测2020年

regr = LinearRegression()
regr.fit(X_,list(df[‘销量’]))
LinearRegression()
XXX_ = poly_reg.fit_transform(list(df[‘年份int’])+[[13]])

散点图

import plotly as py
import plotly.graph_objs as go
import numpy as np

year = list(df[‘年份’])
sales = df[‘销量’]

trace1 = go.Scatter(
x=year+[‘2021年’,‘2022年’,‘2023年’],
y=sales,
mode=‘markers’,
name=“实际销量” # 第一个图例名称
)

trace2 = go.Scatter(
x=year+[‘2021年’,‘2022年’,‘2023年’],
y=regr.predict(XXX_),
mode=‘lines’,
name=“预测销量” # 第一个图例名称
)

trace3 = go.Scatter(
x=[‘2021年’],
y=[regr.predict(XXX_)[-1]],
mode=‘markers’,
name=“2021年预测销量” # 第一个图例名称
)

data = [trace1,trace2,trace3]

layout = go.Layout(title=‘天猫淘宝双十一历年销量’,
xaxis_title=‘年份’,
yaxis_title=‘销量’)

fig = go.Figure(data=data, layout=layout)

fig.show()

var gd = document.getElementById(‘3151a044-f334-4544-8e20-b4908350e140’);
var x = new MutationObserver(function (mutations, observer) {{
var display = window.getComputedStyle(gd).display;
if (!display || display === ‘none’) {{
console.log([gd, ‘removed!’]);
Plotly.purge(gd);
observer.disconnect();
}}
}});

// Listen for the removal of the full notebook cells
var notebookContainer = gd.closest(’#notebook-container’);
if (notebookContainer) {{
x.observe(notebookContainer, {childList: true});
}}

// Listen for the clearing of the current output cell
var outputEl = gd.closest(’.output’);
if (outputEl) {{
x.observe(outputEl, {childList: true});
}}
})
};
});

NO.06、多项式预测的次数到底如何选择
在选择模型中的次数方面,可以通过设置程序,循环计算各个次数下预测误差,然后再根据结果反选参数。

df_new = df.copy()
df_new[‘年份int’] = df[‘年份int’].apply(lambda x: x[0])
df_new
.dataframe tbody tr th {
vertical-align: top;
}

.dataframe thead th {
text-align: right;
}

多项式回归预测次数选择

计算 m 次多项式回归预测结果的 MSE 评价指标并绘图

from sklearn.pipeline import make_pipeline
from sklearn.metrics import mean_squared_error

train_df = df_new[:int(len(df)*0.95)]
test_df = df_new[int(len(df)*0.5):]

定义训练和测试使用的自变量和因变量

train_x = train_df[‘年份int’].values
train_y = train_df[‘销量’].values

print(train_x)

test_x = test_df[‘年份int’].values
test_y = test_df[‘销量’].values

train_x = train_x.reshape(len(train_x),1)
test_x = test_x.reshape(len(test_x),1)
train_y = train_y.reshape(len(train_y),1)

mse = [] # 用于存储各最高次多项式 MSE 值
m = 1 # 初始 m 值
m_max = 10 # 设定最高次数
while m <= m_max:
model = make_pipeline(PolynomialFeatures(m, include_bias=False), LinearRegression())
model.fit(train_x, train_y) # 训练模型
pre_y = model.predict(test_x) # 测试模型
mse.append(mean_squared_error(test_y, pre_y.flatten())) # 计算 MSE
m = m + 1

print("MSE 计算结果: ", mse)

绘图

plt.plot([i for i in range(1, m_max + 1)], mse, ‘r’)
plt.scatter([i for i in range(1, m_max + 1)], mse)

绘制图名称等

plt.title(“MSE of m degree of polynomial regression”)
plt.xlabel(“m”)
plt.ylabel(“MSE”)
MSE 计算结果: [1088092.9621201046, 481951.27857828484, 478840.8575107471, 477235.9140442428, 484657.87153138855, 509758.1526412842, 344204.1969956556, 429874.9229308078, 8281846.231771571, 146298201.8473966]
Text(0, 0.5, ‘MSE’)

从误差结果可以看到,次数取2到8误差基本稳定,没有明显的减少了,但其实你试试就知道,次数选择3的时候,预测的销量是6213亿元,次数选择5的时候,预测的销量是9029亿元,对于销售量来说,这个范围已经够大的了。我也就斗胆猜到9029亿元,我的胆量也就预测到这里了,破万亿就太夸张了,欢迎胆子大的同学留下你们的预测结果,让我们11月11日,拭目以待吧。

NO.07、总结最后
希望这篇文章带着对 Python 的多项式回归和 Plotly可视化绘图还不熟悉的同学一起练习一下。

本文出品:CDA数据分析师

不靠谱的预测:今年双十一的销量是 6213 亿元相关推荐

  1. 京东双十一累计下单超2044亿元背后,低线市场增量强劲

    11月12日,京东方面公布了2019年11月1日零时起至11月11日23时59分59秒的最新战报.数据显示,"11.11京东全球好物节"累计下单金额超2044亿元. 京东双十一下单 ...

  2. Geoffrey Hinton获得时间检验奖;AI预测世界杯荷兰夺冠;Galactica不靠谱,ChatGPT又如何……...

    这一周,AI业界又有哪些新鲜事? AI人物 Geoffrey Hinton:Forward-Forward新型神经网络更接近大脑运作 近日,深度学习之父.图灵奖得主 Geoffrey Hinton 在 ...

  3. 为什么诸多顶级期刊论文中的观点也不靠谱?

    12月10日,东北大学的某位教授来京出差,顺便看望了咱.聊天时,咱问道"您平常看什么期刊的文献?"他答曰"常看<Nature>和<Science> ...

  4. 如何判断一家公司靠不靠谱?

    经常有读者问我如何判断一家创业公司是否靠谱,我给改了改,其实不仅仅是创业公司具备「坑」的特征,还有很多活了很多年的公司也是「坑」. 为了节约大家的时间,我先总结一下本文的观点: 坑无处不在,不仅仅是创 ...

  5. 回测好,为什么实盘不靠谱?

    用IT技术玩金融系列文章,将介绍如何使用IT技术,处理金融大数据.在互联网混迹多年,已经熟练掌握一些IT技术.单纯地在互联网做开发,总觉得使劲的方式不对.要想靠技术养活自己,就要把技术变现.通过&qu ...

  6. 如何判断一家公司靠不靠谱

    经常有读者问我如何判断一家创业公司是否靠谱,我给改了改,其实不仅仅是创业公司具备「坑」的特征,还有很多活了很多年的公司也是「坑」. 为了节约大家的时间,我先总结一下本文的观点: 坑无处不在,不仅仅是创 ...

  7. 斥资建造全景分割养猪场,AI 养猪,到底靠不靠谱?

    目录 1.背景 2.方法 3.实验 4.探讨 前几天分享一个AI案例:5行Python代码实现图像分割,近日就读到一篇德国基尔大学和哥廷根大学研究的论文:应用在养猪场的全景分割系统,就让我们一起品品. ...

  8. AIOps做根因定位靠不靠谱?

    昨晚跟浙江移动晓征总畅谈很久,从狭义AIOps做根因分析引出,聊了AIOps的作用,跟SRE的关系,实践的总结,有很多共鸣,也碰撞出很多有意思的观点. 结合晓征总整理的,和我记录的,形成一篇文章,算是 ...

  9. 用什么心态对待水平糟糕的程序员[不靠谱的程序员、思路紊乱的程序员]?

    这些年遇到了很多糟糕的程序员,其实真正是写程序料的人,普通IT公司大概只占1/3左右吧,其实有2/3的人都太适合当程序员,还不如早点儿改行该干啥就干啥了,其中有1/10的人往往是相对比较糟糕的. 01 ...

最新文章

  1. USB获取图像实时处理
  2. Nginx虚拟机主机根据不同的域名使用不同的root路径
  3. VCenter电源报警
  4. [笑]每个人都有脑袋脱线的时候……
  5. TCP与UDP的选择--结合QQ来说明
  6. java爬虫代码示例_那些让你代码思维和能力有较大的提升Java源码
  7. 使用WPF动态资源在Gtk3 C#中进行本地化
  8. 快速计算--斐波那契数列
  9. 力扣-692 前k个高频单词
  10. 《未来行业前景必看》大数据未来的发展趋势!
  11. 九宫格按键输入(java)
  12. 用Java写一个简易五子棋游戏
  13. 论文解读-Intriguing properties of neural networks(ICLR2014)
  14. aspose获取文件纸张方向以及设置纸张方向
  15. pyTorch中tensor运算
  16. 【音视频开发】基础知识:视频简介
  17. /etc/xinetd.d 的使用
  18. 花前挥手别伊人,月下纵马扬轻尘,红尘游历,荡剑江湖。四方辗转,看千山飞鸟逐;万里飘蓬,叹海角天涯路。夜风萧瑟雨凄楚,相思情入梦,孤影独对窗前烛,离别意难书。何时平尽心中愿,从此相守不离疏,岁岁年年情深
  19. OpenCV 录制视频
  20. 前端案例 ——注册页面(html+css实现)

热门文章

  1. win7防火墙入站规则 出站规则 什么意思
  2. LD3320语音识别模块分析
  3. docker启动jenkins部署springboot到tomcat(集成:企业微信和邮件通知)
  4. bzip2: Data integrity error when decompressing--apt-get update
  5. 《算法之美》 第三章:数据结构
  6. WMS LICENSE PLATE NUMBERS LPN CONTEXT
  7. Python 实现哥德巴赫猜想
  8. word中自带插入公式,实现换行和对齐
  9. python画三维(3D)图
  10. 【Pandas 基础知识 数据修改总结】