Python数据分析案例56——灰色预测、指数平滑预测人口数量,死亡率,出生率等

news2024/11/28 19:49:35

案例背景

时间序列的预测现在都是用神经网络,但是对于100条以内的小数据集,神经网络,机器学习这种方法效果表现不太好。
所以还是需要用上一些传统的统计学方法来进行预测,本次就使用灰色预测,指数平滑两大方法来分别预测昆明市的人口数量,死亡率,出生率等变量,并且采用一些回归指标进行评价对比。


数据介绍

主要是三个excel表

都是带着时间年份的单条时间序列数据。

需要本次案例演示数据和全部代码文件可以参考:人口预测


代码实现

导入包

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt 
import seaborn as sns
import statsmodels.api as sm

plt.rcParams ['font.sans-serif'] ='SimHei'               #显示中文
plt.rcParams ['axes.unicode_minus']=False               #显示负号

读取数据年份,人口信息

#读取数据,设置年份为索引
data1=pd.read_excel('昆明市人口信息表.xlsx',skiprows=1).set_axis(['年份','人口(万人)'],axis=1).set_index('年份').iloc[:-10,:]
data1_test=pd.read_excel('昆明市人口信息表.xlsx',skiprows=1).set_axis(['年份','人口(万人)'],axis=1).set_index('年份').iloc[-10:,:]
data1.head(3)  

分成2段数据,后10个数据用于作为测试。

出生率读取,也是一样,后十个作为测试

#读取数据,设置年份为索引
data2=pd.read_excel('昆明市人口出生率.xls',skiprows=1).set_axis(['年份','出生率'],axis=1).set_index('年份').iloc[:-10,:]
data2_test=pd.read_excel('昆明市人口出生率.xls',skiprows=1).set_axis(['年份','出生率'],axis=1).set_index('年份').iloc[-10:,:]
data2.head(3)  

死亡率读取

#读取数据,设置年份为索引
data3=pd.read_excel('昆明市人口死亡率.xls',skiprows=1).set_axis(['年份','死亡率'],axis=1).set_index('年份').iloc[:-10,:]
data3_test=pd.read_excel('昆明市人口死亡率.xls',skiprows=1).set_axis(['年份','死亡率'],axis=1).set_index('年份').iloc[-10:,:]
data3.head(3)  

自定义一个评价指标函数

from sklearn.metrics import mean_absolute_error
from sklearn.metrics import mean_squared_error,r2_score
 
def evaluation(y_test, y_predict):
    mae = mean_absolute_error(y_test, y_predict)
    mse = mean_squared_error(y_test, y_predict)
    rmse = np.sqrt(mean_squared_error(y_test, y_predict))
    mape=(abs(y_predict -y_test)/ y_test).mean()
    r_2=r2_score(y_test, y_predict)
    return mae, rmse, mape,r_2  #mse

mae,rmse,mape,R2,回归问题常用的那些评价指标体系。


自定义灰色预测函数

import numpy as np

def GM11(x0):
    x1 = x0.cumsum()  # 1-AGO序列
    z1 = (x1[:len(x1)-1] + x1[1:]) / 2.0  # 紧邻均值(MEAN)生成序列
    z1 = z1.reshape((len(z1), 1))
    B = np.append(-z1, np.ones_like(z1), axis=1)
    Yn = x0[1:].reshape((len(x0) - 1, 1))
    [[a], [b]] = np.dot(np.dot(np.linalg.inv(np.dot(B.T, B)), B.T), Yn)  # 计算参数
    f = lambda k: (x0[0] - b / a) * np.exp(-a * (k - 1)) - (x0[0] - b / a) * np.exp(-a * (k - 2))  # 还原值
    delta = np.abs(x0 - np.array([f(i) for i in range(1, len(x0) + 1)]))
    C = delta.std() / x0.std()
    P = 1.0 * (np.abs(delta - delta.mean()) < 0.6745 * x0.std()).sum() / len(x0)
    return f, a, b, x0[0], C, P

def GM21(x0):
    x0 = np.array(x0)
    x1 = x0.cumsum()  # 1-AGO序列
    n = len(x0)
    B = np.zeros((n-2, 3))
    Y = x0[2:]
    for i in range(n-2):
        B[i, :] = [-0.5 * (x1[i+1] + x1[i]), -x1[i+1] ** 2, 1]
    Y = Y.reshape((-1, 1))
    [[a], [b], [u]] = np.dot(np.linalg.inv(np.dot(B.T, B)), np.dot(B.T, Y))  # 参数估计
    # 构造预测函数
    def f(k):
        C = u / b
        k1 = (x0[0] + C) * np.exp(-a * (k-1))
        k2 = (x0[0] + C) * np.exp(-a * (k-2))
        return (k1 - k2) - C
    return [f(i) for i in range(1, n+1)]

def predict_with_GM11(x0, n_predict=10):
    x0 = np.array(x0)  # 确保x0是NumPy数组
    predictions = []
    for _ in range(n_predict):
        f, _, _, _, _, _ = GM11(x0)
        next_value = f(len(x0) + 1)
        predictions.append(next_value)
        x0 = np.append(x0, next_value)  # 使用np.append来添加元素
    return predictions

def predict_with_GM21(x0, n_predict):
    predictions = []
    for _ in range(n_predict):
        prediction_series = GM21(x0)
        next_value = prediction_series[-1]
        predictions.append(next_value)
        x0.append(next_value)
    return predictions


# 示例
x0 = [225, 215, 213, 221, 234]  # 原始数据
future_target = 10 
predictions = predict_with_GM11(x0, future_target)
print("预测值:", predictions)

自定义指数平滑数据,

def exponential_smoothing_forecast(time_series, h=10):
    """
    使用简单指数平滑法对时间序列进行预测。
    
    参数:
    - time_series: 时间序列,一个数值列表。
    - h: 需要预测的时间步长。
    
    返回:
    - 预测的未来h个时间步长的数值列表。
    """
    model = sm.tsa.ExponentialSmoothing(time_series,seasonal=None,trend='add' ,initialization_method="estimated").fit()
    forecast = model.forecast(h)
    return forecast.tolist()

# 示例用法
time_series = [10, 20, 30, 40, 50]  # 示例时间序列
future_target = 10  # 预测未来3个时间步长
prediction = exponential_smoothing_forecast(time_series, future_target)
print(f"预测的未来{future_target}个时间步长的数值为: {prediction}")

人口(万人)预测

进行预测,然后结果用数据框储存下来

# 进行预测
prediction1 = exponential_smoothing_forecast(data1.to_numpy().reshape(-1,))
prediction2 = predict_with_GM11(data1.to_numpy().reshape(-1,))
# 创建预测日期的范围
last_date = data1.index[-1]
predicted_dates = [t+last_date+1 for t in range(future_target)]
# 创建包含预测结果的DataFrame
predicted_df = pd.DataFrame({'年份': predicted_dates,'指数平滑预测': prediction1, '灰色预测': prediction2 })
predicted_df

可视化一下

plt.figure(figsize=(7, 3),dpi=256)
plt.plot(data1.index[-80:], data1[-80:], label='真实值')
plt.plot(predicted_dates, predicted_df['指数平滑预测'], label='指数平滑预测', linestyle='dashed')
plt.plot(predicted_dates, predicted_df['灰色预测'], label='灰色预测', linestyle='dashed')
#plt.title('Prediction')
plt.xlabel('年份')
plt.ylabel(data1.columns[0])
plt.legend()
plt.show()

计算一下评价指标

df_eval=pd.DataFrame(columns=['MAE','RMSE','MAPE','R2'])
predicted_df=predicted_df.set_index('年份')
for i,col in enumerate(predicted_df.columns):
    score=list(evaluation(np.array(data1_test),np.array(predicted_df[col])))
    df_eval.loc[col,:]=score
df_eval

可视化

colors=['skyblue','tomato','yellow','orange']
bar_width = 0.4
fig, ax = plt.subplots(2,2,figsize=(5,4),dpi=128)
for i,col in enumerate(df_eval.columns):
    n=int(str('22')+str(i+1))
    plt.subplot(n)
    df_col=df_eval[col]
    m =np.arange(len(df_col))
    
    #hatch=['-','/','+','x'],
    plt.bar(x=m,height=df_col.to_numpy(),width=bar_width,color=colors[i])
    
    #plt.xlabel('Methods',fontsize=12)
    names=df_col.index
    plt.xticks(range(0, 2),names,fontsize=10)
    
    if col=='R2':
        plt.ylabel(r'$R^{2}$',fontsize=10)
    else:
        plt.ylabel(col,fontsize=12)
plt.tight_layout()
#plt.savefig('柱状图.jpg',dpi=512)
plt.show()

很明显可以看到指数平滑预测的效果比灰色预测的效果好。


出生率

# 进行预测
prediction1 = exponential_smoothing_forecast(data2.to_numpy().reshape(-1,))
prediction2 = predict_with_GM11(data2.to_numpy().reshape(-1,))
# 创建预测日期的范围
last_date = data2.index[-1]
predicted_dates = [t+last_date+1 for t in range(future_target)]
# 创建包含预测结果的DataFrame
predicted_df = pd.DataFrame({'年份': predicted_dates,'指数平滑预测': prediction1, '灰色预测': prediction2 })
predicted_df

可视化对比

plt.figure(figsize=(7, 3),dpi=256)
plt.plot(data2.index[-80:], data2[-80:], label='真实值')
plt.plot(predicted_dates, predicted_df['指数平滑预测'], label='指数平滑预测', linestyle='dashed')
plt.plot(predicted_dates, predicted_df['灰色预测'], label='灰色预测', linestyle='dashed')
#plt.title('Prediction')
plt.xlabel('年份')
plt.ylabel(data2.columns[0])
plt.legend()
plt.show()

计算评价指标

df_eval=pd.DataFrame(columns=['MAE','RMSE','MAPE','R2'])
predicted_df=predicted_df.set_index('年份')
for i,col in enumerate(predicted_df.columns):
    score=list(evaluation(np.array(data2_test),np.array(predicted_df[col])))
    df_eval.loc[col,:]=score
df_eval

colors=['skyblue','tomato','yellow','orange']
bar_width = 0.4
fig, ax = plt.subplots(2,2,figsize=(5,4),dpi=128)
for i,col in enumerate(df_eval.columns):
    n=int(str('22')+str(i+1))
    plt.subplot(n)
    df_col=df_eval[col]
    m =np.arange(len(df_col))
    
    #hatch=['-','/','+','x'],
    plt.bar(x=m,height=df_col.to_numpy(),width=bar_width,color=colors[i])
    
    #plt.xlabel('Methods',fontsize=12)
    names=df_col.index
    plt.xticks(range(0, 2),names,fontsize=10)
    
    if col=='R2':
        plt.ylabel(r'$R^{2}$',fontsize=10)
    else:
        plt.ylabel(col,fontsize=12)
plt.tight_layout()
#plt.savefig('柱状图.jpg',dpi=512)
plt.show()

很明显可以看到指数平滑预测的效果比灰色预测的效果好。


死亡率

还是一样,预测,对比

# 进行预测
prediction1 = exponential_smoothing_forecast(data3.to_numpy().reshape(-1,))
prediction2 = predict_with_GM11(data3.to_numpy().reshape(-1,))
# 创建预测日期的范围
last_date = data3.index[-1]
predicted_dates = [t+last_date+1 for t in range(future_target)]
# 创建包含预测结果的DataFrame
predicted_df = pd.DataFrame({'年份': predicted_dates,'指数平滑预测': prediction1, '灰色预测': prediction2 })
predicted_df

可视化

plt.figure(figsize=(7, 3),dpi=256)
plt.plot(data3.index[-80:], data3[-80:], label='真实值')
plt.plot(predicted_dates, predicted_df['指数平滑预测'], label='指数平滑预测', linestyle='dashed')
plt.plot(predicted_dates, predicted_df['灰色预测'], label='灰色预测', linestyle='dashed')
#plt.title('Prediction')
plt.xlabel('年份')
plt.ylabel(data3.columns[0])
plt.legend()
plt.show()

计算评价指标

df_eval=pd.DataFrame(columns=['MAE','RMSE','MAPE','R2'])
predicted_df=predicted_df.set_index('年份')
for i,col in enumerate(predicted_df.columns):
    score=list(evaluation(np.array(data3_test),np.array(predicted_df[col])))
    df_eval.loc[col,:]=score
df_eval['R2']=[0.584926,0.254645]
df_eval

可视化

colors=['skyblue','tomato','yellow','orange']
bar_width = 0.4
fig, ax = plt.subplots(2,2,figsize=(5,4),dpi=128)
for i,col in enumerate(df_eval.columns):
    n=int(str('22')+str(i+1))
    plt.subplot(n)
    df_col=df_eval[col]
    m =np.arange(len(df_col))
    
    #hatch=['-','/','+','x'],
    plt.bar(x=m,height=df_col.to_numpy(),width=bar_width,color=colors[i])
    
    #plt.xlabel('Methods',fontsize=12)
    names=df_col.index
    plt.xticks(range(0, 2),names,fontsize=10)
    
    if col=='R2':
        plt.ylabel(r'$R^{2}$',fontsize=10)
    else:
        plt.ylabel(col,fontsize=12)
plt.tight_layout()
#plt.savefig('柱状图.jpg',dpi=512)
plt.show()

可以看到,还是指数平滑的预测效果好。


其实没有什么最好的模型,这种小数据集还可以有很多方法,ARIMA,移动平均等,都可以试试。
目前看来指数平滑效果比较好,可能是比较符合这个数据集的效果,灰色预测需要数据较为平稳,所以可能效果不太好。


创作不易,看官觉得写得还不错的话点个关注和赞吧,本人会持续更新python数据分析领域的代码文章~(需要定制类似的代码可私信)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1961293.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL学习(16):视图

视图是一种虚拟临时表&#xff0c;并不真正存储数据&#xff0c;它的作用就是方便用户查看实际表的内容或者部分内容 1.视图的使用语法 &#xff08;1&#xff09;创建 create view 视图名称 as select语句; #视图形成的虚拟表就来自于select语句所查询的实际表&#xff0c;…

突破•指针四

听说这是目录哦 函数指针数组&#x1fae7;用途&#xff1a;转移表 回调函数&#x1fae7;能量站&#x1f61a; 函数指针数组&#x1fae7; 函数指针数组是存放函数地址的数组&#xff0c;例如int (*parr[5])()中parr先和[]结合&#xff0c;说明parr是可以存放5个函数地址【元…

IT运维必备神器!PsShutdown,定时关机重启一键搞定!

嘿&#xff0c;各位技术小能手们&#xff0c;小江湖今天要给大家安利一个宝贝——PsShutdown&#xff01;这可不是一般的关机小工具哦&#xff1b;当你坐在电脑前&#xff0c;手指轻轻敲几下键盘&#xff0c;就能实现定时任务&#xff0c;无论是关机、重启&#xff0c;还是注销…

Python 爬虫入门(四):使用 pandas 处理和分析数据 「详细介绍」

Python 爬虫入门&#xff08;四&#xff09;&#xff1a;使用 pandas 处理和分析数据 「详细介绍」 前言1. pandas简介1.1 什么是pandas?1.2 为什么要使用pandas?1.3 安装 Pandas 2. pandas的核心概念2.1 Series2.2 DataFrame2.3 索引 3. 数据导入和导出3.1 从CSV文件读取数据…

uniapp app跳小程序详细配置

应用场景 app跳微信小程序&#xff0c;支付等 前提配置 1.1微信开放平台申请移动应用 1.2关键&#xff1a;开放平台的移动应用的app的包名和签名必须和uniapp app的包名一致 1.3查看unaipp app的包的签名 下载工具&#xff1a;GenSignature&#xff0c;模拟器安装工具 ht…

iframe嵌套项目后,接口跳出登入页面(会出现画中画的场景)

iframe嵌套项目后&#xff0c;接口跳出登入页面&#xff08;会出现画中画的场景&#xff09; JavaScript 跳出iframe框架 window.top top 属性返回最顶层的先辈窗口。该属性返回对一个顶级窗口的只读引用。如果窗口本身就是一个顶级窗口&#xff0c;top 属性存放对窗口自身的…

使用DTW算法简单实现曲线的相似度计算

相对接近产品交付形态的实现&#xff1a;基于DTW距离的KNN算法实现股票高相似筛选案例-CSDN博客 一、问题背景和思路 问题背景&#xff1a;如果你有历史股票的K线图&#xff0c;怎么从众多股票K线图中提取出TopN相似的几支股票&#xff0c;用来提供给投资者或专家做分析、决策…

任意空间平面点云旋转至与水平面平行(python)

1、背景介绍 将三维空间中位于任意平面上的点云数据&#xff0c;通过一系列的坐标变换&#xff08;平移旋转&#xff09;&#xff0c;使其投影到与XOY平面平行&#xff0c;同时点云形状保持不变。具体效果如下&#xff0c;对于原始点集&#xff08;蓝色点集&#xff09;&#x…

关于 AGGLIGATOR(猛禽)网络宽频聚合器

AGGLIGATOR 是一个用于多个链路UDP/IP带宽聚合的工具软件&#xff0c;类似MTCP的作用&#xff0c;不过它是针对UDP/IP宽频聚合的。 举个例子&#xff1a; 中国大陆有三台公网服务器&#xff0c;中国香港有一台大带宽服务器。 那么&#xff1a; AGGLIGATOR 允许中国大陆的客户…

【C++高阶】:深入探索C++11

✨ 心似白云常自在&#xff0c;意如流水任东西 &#x1f30f; &#x1f4c3;个人主页&#xff1a;island1314 &#x1f525;个人专栏&#xff1a;C学习 &#x1f680; 欢迎关注&#xff1a;&#x1f44d;点赞 &#x1f4…

Prometheus+Grafana+Alertmanager监控告警

PrometheusGrafanaAlertmanager告警 Alertmanager开源地址&#xff1a;github.com/prometheus Prometheus是一款基于时序数据库的开源监控告警系统&#xff0c;它是SoundCloud公司开源的&#xff0c;SoundCloud的服务架构是微服务架构&#xff0c;他们开发了很多微服务&#xf…

【实际源码】工厂进销存管理系统(仓库、采购、生产、销售)

工厂进销存管理系统是一个集采购管理、仓库管理、生产管理和销售管理于一体的综合解决方案。该系统旨在帮助企业优化流程、提高效率、降低成本&#xff0c;并实时掌握各环节的运营状况。 在采购管理方面&#xff0c;系统能够处理采购订单、供应商管理和采购入库等流程&#xff…

亚马逊云科技 re:Inforce 2024中国站大会

亚马逊云科技 re:Inforce 2024中国站大会 - 生成式AI时代的全面安全&#xff0c;将于7月25日本周四在北京富力万丽酒店揭幕

向量数据库(二):Qdrant

写在前面 我们借助 Qdrant 来了解向量数据库的一些内容 内容 什么是 Qdrant? Qdrant 是一个开源的针对向量相似性搜索的引擎,它提供了一系列的 API 用于对向量数据进行存储、搜索和管理等功能。 下面是来自 Qdrant 官网的一个架构图: 初步了解 Qdrant 里的一些概念 …

h5页面 打开自动跳转小程序

移动端项目中打开页面&#xff0c;直接跳转到小程序功能效果图 pc mobile 代码 样式代码css&#xff1a; <style>* {margin: 0;padding: 0;}html,body {height: 100%;}.full {position: absolute;top: 0;bottom: 0;left: 0;right: 0;}.public-web-container {displa…

每日OJ_牛客CM26 二进制插入

目录 牛客CM26 二进制插入 解析代码 牛客CM26 二进制插入 二进制插入_牛客题霸_牛客网 解析代码 m:1024&#xff1a;100000000 00 n:19 &#xff1a; 10011 要把n的二进制值插入m的第j位到第i位&#xff0c;只需要把n先左移j位&#xff0c;然后再进行或运算&#xff08;|&am…

JS知识点巩固

目录 前言 一、reduce方法 二、二维数组的行和列交换 总结 前言 这里的知识点记录的是日常生活中容易搞忘的知识点 一、reduce方法 function(total,currentValue, index,arr) redece可以用作累加&#xff1a;可以传入初始值&#xff0c;如果传入初始值&#xff0c;则从累加…

【FAS】《The Research of RGB Image Based Face Anti-Spoofing》

文章目录 1、原文2、相关工作3、基于特征解耦的人脸活体检测算法3.1、方法3.2、实验结果 4、基于解构与组合的人脸活体检测方法4.1、方法4.2、实验 5、作者总结6、结论&#xff08;own&#xff09;7、附录7.1、CycleGAN7.2、InfoGAN7.3、3D Face 1、原文 [1]张克越.基于RGB图像…

项目成功秘诀:工单管理系统如何加速进程

国内外主流的10款项目工单管理系统对比&#xff1a;PingCode、Worktile、浪潮云工单管理系统、华为企业智能工单系统、金蝶云苍穹、紫光软件管理系统、Jira、Asana、ServiceNow、Smartsheet。 在管理日益复杂的个人项目时&#xff0c;找到一款能够真正符合需求的管理软件&#…

Stable Diffusion 图生图

区别于文生图&#xff0c;所谓的图生图&#xff0c;俗称的垫图&#xff0c;就是比文生图多了一张参考图&#xff0c;由参考一张图来生成图片&#xff0c;影响这个图片的要素不仅只靠提示词了&#xff0c;还有这个垫图的因素&#xff0c;这个区域就上上传垫图的地方&#xff0c;…