先来吐槽一下:双十一过后,我估计参加不了任何超过十块的饭局!
言归正传,今天确实是被双十一销售额刷屏了
突然·,我在微博、朋友圈等地方看到,这样一种声音,从 2009-2019,淘宝天猫的双十一销售总额严格符合三次函数,于是乎,就有人怀疑淘宝天猫的双十一数据造假;且不论真假,怀着强烈的好奇心,我自己动手实现了下这个过程。
动手:实现三次拟合
主要用到 numpy 实现拟合,并用 matplotlib + seaborn 实现可视化
(代码注释比较清楚,如有疑问可留言)
# -*- coding: utf-8 -*-
# create_time: 2019/11/12 12:22
# file_name: main.py
# 月小水长(ID: inspurer)
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
# 设置中文字体和负号正常显示
plt.rcParams['font.sans-serif'] = ['SimHei'] # 指定默认字体
plt.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题
sns.set_context("paper") # 背景
sns.set_style('whitegrid') # 主题
sns.set(font='SimHei') # 解决Seaborn中文显示问题,这一句必须放在前两句后面
years = np.array([year for year in range(2009,2020)])
sales = np.array([0.5,9.36,52,191,352,571,912,1207,1682.69,2135,2684])
plt.barh(y=years,width=sales)
for i in range(len(years)):
plt.text(sales[i],years[i],str(sales[i])+"亿元")
plt.title("2009-2019淘宝双十一销售额 made by 微信公众号:月小水长")
plt.figure()
def fit(x,y,deg,x_to_predict):
'''
:param x: 输入 x
:param y: 输入 y
:param deg: 拟合多项式的最高次数
:return: 拟合后的 y 值
'''
function = np.polyfit(x, y, deg)
poly = np.poly1d(function)
fit_y = poly(x)
predict_y = poly(x_to_predict)
return fit_y,predict_y
def get_accuray(y1,y2):
'''
:param y1: 实际值
:param y2: 预测值
:return: 均方误差 MSE,以及 R2
'''
y_n = np.mean(y1)
SSR = np.sum((y2 - y_n) ** 2)
SST = np.sum((y1 - y_n) ** 2)
R2 = SSR/SST
R2 = (float(R2))
# 计算均方误差
MSE = 0
m = len(y1)
for fxi, yi in zip(y1, y2):
MSE += (fxi - yi) ** 2
MSE /= m
MSE = round(MSE, 2)
return MSE,R2
x_to_predict = np.array([2020,2021,2022])
# 三次拟合
fit_sales,predict_sales = fit(x=years,y=sales,deg=3,x_to_predict=x_to_predict)
MSE,R2 = get_accuray(sales,fit_sales)
plt.scatter(years,sales,label='实际销售额')
plt.plot(years,fit_sales,label='拟合销售额')
plt.scatter(x_to_predict,predict_sales,label='预测销售额')
# 显示图例
plt.legend()
plt.title('三次曲线拟合淘宝双十一销售额 made by 微信公众号:月小水长')
plt.xlabel("年份")
plt.ylabel("销售额(单位/亿)")
plt.text(2009,3000,"拟合度 {}".format(R2))
plt.show()
# create_time: 2019/11/12 12:22
# file_name: main.py
# 月小水长(ID: inspurer)
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
# 设置中文字体和负号正常显示
plt.rcParams['font.sans-serif'] = ['SimHei'] # 指定默认字体
plt.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题
sns.set_context("paper") # 背景
sns.set_style('whitegrid') # 主题
sns.set(font='SimHei') # 解决Seaborn中文显示问题,这一句必须放在前两句后面
years = np.array([year for year in range(2009,2020)])
sales = np.array([0.5,9.36,52,191,352,571,912,1207,1682.69,2135,2684])
plt.barh(y=years,width=sales)
for i in range(len(years)):
plt.text(sales[i],years[i],str(sales[i])+"亿元")
plt.title("2009-2019淘宝双十一销售额 made by 微信公众号:月小水长")
plt.figure()
def fit(x,y,deg,x_to_predict):
'''
:param x: 输入 x
:param y: 输入 y
:param deg: 拟合多项式的最高次数
:return: 拟合后的 y 值
'''
function = np.polyfit(x, y, deg)
poly = np.poly1d(function)
fit_y = poly(x)
predict_y = poly(x_to_predict)
return fit_y,predict_y
def get_accuray(y1,y2):
'''
:param y1: 实际值
:param y2: 预测值
:return: 均方误差 MSE,以及 R2
'''
y_n = np.mean(y1)
SSR = np.sum((y2 - y_n) ** 2)
SST = np.sum((y1 - y_n) ** 2)
R2 = SSR/SST
R2 = (float(R2))
# 计算均方误差
MSE = 0
m = len(y1)
for fxi, yi in zip(y1, y2):
MSE += (fxi - yi) ** 2
MSE /= m
MSE = round(MSE, 2)
return MSE,R2
x_to_predict = np.array([2020,2021,2022])
# 三次拟合
fit_sales,predict_sales = fit(x=years,y=sales,deg=3,x_to_predict=x_to_predict)
MSE,R2 = get_accuray(sales,fit_sales)
plt.scatter(years,sales,label='实际销售额')
plt.plot(years,fit_sales,label='拟合销售额')
plt.scatter(x_to_predict,predict_sales,label='预测销售额')
# 显示图例
plt.legend()
plt.title('三次曲线拟合淘宝双十一销售额 made by 微信公众号:月小水长')
plt.xlabel("年份")
plt.ylabel("销售额(单位/亿)")
plt.text(2009,3000,"拟合度 {}".format(R2))
plt.show()
其拟合结果可视化如下:
直观来看,利用三次函数去拟合销售额,曲线与真实值重合度非常之高,经计算达到了 0.999…,这得有多巧合,难怪网上有人怀疑数据的真实性。这个数据真假不是本文的重点,我们是来学技术的,就不在文章中讨论了。
作者同时预测了接下来 2020、2021、2022 三年的淘宝天猫销售额,分别是
3294.23
、
3968.51
、
4708.68
亿元。
— 完 —
感谢大家置顶一下公众号,不要错过公众号每月的打卡活动!
另外,新关注我们公众号的朋友,可以在公众号后台聊天框回复【1024】,可以免费获取2T的编程视频,算法、人工智能、Python、Java、Linux、Go、C语言、软考、英语等等资源 。
推荐阅读:
长按加入10W+朋友的IT圈
觉得内容还不错的话,给我点个“在看”呗