Python数据分析与应用----财政收入预测分析、实训(企业所得税预测)

Python数据分析与应用----财政收入预测分析、实训(企业所得税预测)

本案例按照1994年我国财政体制改革后至2013年的数据进行分析并预测未来两年财政收入变化情况。主要按照财政收入分析预测模型流程进行~

在这里插入图片描述


目录:

财政收入预测分析
        一、对原始数据进行探索性分析,了解原始特征之间的相关性
        二、利用Lasso特征选择模型进行特征提取
        三、建立单个特征的灰色预测模型以及支持向量回归预测模型
        四、使用支持向量回归预测2014-2015的财政收入

     实训(企业所得税预测)


一、对原始数据进行探索性分析,了解原始特征之间的相关性

特征名说明
x1社会从业人数
x2在岗职工工资总额
x3社会消费品零售总额
x4城镇居民人均可支配收入
x5城镇居民人均消费性支出
x6年末总人口
x7全社会固定资产投资额
x8地区生产总值
x9第一产业产值
x10税收
x11居民消费价格指数
x12第三产业与第二产业产值比
x13居民消费水平
y财政收入

相关性分析是指对两个或多个具备相关型的特征元素进行分析,从而衡量两个特征因素的相关密切程度。在统计学中,常用到Pearson相关系数来进行相关性分析。Pearson相关系数可用来度量两个特征间的相互关系(线性相关强弱),是最简单的一种相关系数,常用r或ρ来表示,取值范围在[-1,1].
在这里插入图片描述
当 r=1 时,表示x与y完全正相关;
当 0<r<1时,表示x与y呈现正相关;
当 r=0 时,表示x与y不相关;
当 -1<r<0时,表示x与y呈现负相关;
当 r=-1 时,表示x与y完全负相关;
|r| 越接近于 1 ,表示x与y的差距越小,相关性越大。

Pearson相关系数的一个关键特性就是,他不会随着特征的位置会是大小变化而变化。

DataFrame.corr(method='pearson', min_periods=1)
 参数说明:

        method:可选值为{‘pearson’, ‘kendall’, ‘spearman’}

              pearson:Pearson相关系数来衡量两个数据集合是否在一条线上面,即针对线性数据的相关系数计算,针对非线性数据便会有误差。

              kendall:用于反映分类变量相关性的指标,即针对无序序列的相关系数,非正太分布的数据

              spearman:非线性的,非正太分析的数据的相关系数

        min_periods:样本最少的数据量
import pandas as pd
import numpy as np

# 读取数据
data = pd.read_csv('data/data.csv',encoding='gbk')
print(data.shape)
//(20, 14)

#计算各特征之间的pearson相关系数
p_data = data.corr(method='pearson')
print('各特征之间的pearson相关系数的形状为:\n',p_data.shape)
//各特征之间的pearson相关系数的形状为:
// (14, 14)

#保留两位小数
p_data = np.round(p_data,2)
print('各特征之间的pearson相关系数为:\n',p_data)

在这里插入图片描述
从表中不难看出,除了x11(居民消费价格指数)外,其余特征均与y(财政收入呈现高度的正相关关系);同时,各特征之间存在着严重的多重共线性,甚至是完全的共线性。综上,可以利用相关性高的特征作为财政收入预测的关键特征进行分析。

返回顶部


二、利用Lasso特征选择模型进行特征提取

数据探索性分析时引入的特征太多,要直接利用其建模,需要进一步的筛选特征,在这里我们采用最近广泛使用的Lasso特征选择方法进一步筛选特征。

Lasso回归方法
概念:
Lasso回归方法属于正则化方法的一种,是压缩估计通过构造一个惩罚函数得到一个较为精炼的模型。使用它压缩一些系数,同时设定一些系数为0,保留了子集收缩的有点,是一种处理具有复共线性数据的有偏估计。(有偏估计(biased estimate)是指由样本值求得的估计值与待估参数的真值之间有系统误差,其期望值不是待估参数的真值。
基本原理:
Lasso以缩小特征集(降阶)为思想,是一种收缩估计方法。Lasso方法可以将特征系数进行压缩并使得某些回归系数变为0,进而达到特征选择的目的,可以应用于模型改进与选择—通过选择惩罚函数,借用Lasso思想和方法实现特征选择;模型选择本质上是寻求模型系数表达的过程,可以通过优化一个“损失”+“惩罚”的函数问题来完成。
在这里插入图片描述
适用场景:
当原始数据中存在多重共线性时,Lasso回归是个不错的选择。在机器学习中,面对众多的数据,首先想到的就是降维,从某个意义上说,Lasso模型进行特征选择也是一种有效的降维方式。一般来说,Lasso对数据类型没有太大的要求,可以接受任何数据类型,并且一般不需对特征进行标准化。

优点与缺点:
Lasso回归方法可以弥补最小二乘估计法和逐步回归局部最优估计的不足,能很好地选择特征,有效的解决特征之间存在的多重共线性问题。
缺点是当存在一组高度相关的特征三,Lasso回归方法会选择其中一个,而忽视其他所有的特征,可能会导致结果的不稳定。
语法:

Lasso(alpha=1.0, fit_intercept=True, normalize=False, precompute=False, 
     copy_X=True, max_iter=1000, tol=0.0001, warm_start=False, 
     positive=False, random_state=None, selection=‘cyclic’)

• alphas: 指定λ\lambdaλ值,默认为1。
• fit_intercept:bool类型,是否需要拟合截距项,默认为True。
• normalize: bool类型,建模时是否对数据集做标准化处理,默认为False。
• precompute: bool类型,是否在建模前计算Gram矩阵提升运算速度,默认为False。
•copy_X: bool类型,是否复制自变量X的数值,默认为True。
• max_iter: 指定模型的最大迭代次数。
•tol: 指定模型收敛的阈值,默认为0.0001。
•warm_start: bool类型,是否将前一次训练结果用作后一次的训练,默认为False。
•positive: bool类型,是否将回归系数强制为正数,默认为False。
• random_state: 指定随机生成器的种子。
•selection: 指定每次迭代选择的回归系数,如果为’random’,表示每次迭代中将随机更新回归系数;如果为’cyclic’,则每次迭代时回归系数的更新都基于上一次运算。

import pandas as pd
import numpy as np
from sklearn.linear_model import Lasso

# 读取数据
data = pd.read_csv('data/data.csv')

# 使用lasso回归方法进行关键特征的选取
lasso = Lasso(1000,random_state=1234)
lasso.fit(data.iloc[:,0:13],data['y'])  这里主要是选取与财政收入相关的特征

print('相关系数为:',np.round(lasso.coef_,5))
//相关系数为: 
[-1.8000e-04 -0.0000e+00  1.2414e-01 -1.0310e-02  6.5400e-02  1.2000e-04
  3.1741e-01  3.4900e-02 -0.0000e+00  0.0000e+00  0.0000e+00  0.0000e+00
 -4.0300e-02]
 
# 计算相关系数非0的个数
print('相关系数非零的个数为:',np.sum(lasso.coef_!=0))
//相关系数非零的个数为: 8

# 返回一个相关系数是否为0的布尔数组
mask = lasso.coef_!=0
print('相关系数是否为0:',mask)
//相关系数是否为0: 
[ True False  True  True  True  True  True  True False False False False
  True]

mask = np.append(mask,True)
new_reg_data = data.iloc[:,mask]

#new_reg_data.to_csv('tmp/new_reg_data.csv')
print('输出的数据维度为:',new_reg_data.shape)
//输出的数据维度为: (20, 9)

在这里插入图片描述

np.round(lasso.coef_,5) #返回参数向量,保留5位小数

这里要注意的是下面代码:

mask = np.append(mask,True)
new_reg_data = data.iloc[:,mask]

在一开始没有加上一行时会报错,原因是你的得到的mask返回值是除了财政收入(y)的,共计13个,而原始数据data共有14列,会导致列数不对应,所以这里要用append方法加一个,true或false,两个值会影响得出的数据中是否包含有y列,由于后续操作需要其保留y列,此处应为True。当然是用False也并不错。只是后续操作时要将y列数据提取并添加至表格中,注意看后面代码注释部分。
在这里插入图片描述

返回顶部


三、建立单个特征的灰色预测模型

基于灰色预测对小样本数据集的优良性能,首先对单个特征建立灰色预测模型,得到各特征2014-2015年的预测值。然后对2013年以前的训练数据建立支持向量回归预测模型,将建立好的模型与灰色预测模型结合,对2014和2015年的财政收入进行预测。

灰色预测法:
概念:
灰色预测法是一种对含有不确定性因素的系统进行预测的方法。在建立灰色预测模型之前,需要对原始时间序列进行处理,经过处理的时间序列称为生成列。灰色系统常用的处理数据方式有累加和累减两种。

基本原理:
在这里插入图片描述

检验参照:
在这里插入图片描述

适用场景:
灰色预测法的通用性比较强,一般时间序列场合都可以使用,尤其那些规律性差且不清楚数据产生机理的情况。

优点与缺点:
优点是预测精度高,模型可检验,参数估计方法简单,对小数据集有较好的效果 缺点是对原始数据序列的光滑度要求很高

import pandas as pd 
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 #返回灰色预测函数、a、b、首项、方差比、小残差概率

# 读取数据
data = pd.read_csv('data/data.csv',encoding='gbk')
new_reg_data = pd.read_csv('tmp/new_reg_data1.csv')

# 自定义提取特征后数据的索引
new_reg_data.index = range(1994,2014)
# print(new_reg_data.index)
new_reg_data.loc[2014] = None
new_reg_data.loc[2015] = None

l = ['x1','x3','x4','x5','x6','x7','x8','x13']
for i in l:
    f = GM11(new_reg_data.loc[range(1994,2014),i].as_matrix())[0]
    new_reg_data.loc[2014,i] = f(len(new_reg_data)-1)
    new_reg_data.loc[2015,i] = f(len(new_reg_data))
    new_reg_data[i] = new_reg_data[i].round(2) # 保留2位小数
   
//以下几行可以不用,因为之前在Lasso回归时,我们使用mask添加了TRUE,保留了y列   
//y = list(data['y'].values) # 提取财政收入列,合并至新数据框内
//y.extend([np.nan,np.nan])
//new_reg_data['y '] = y
new_reg_data.to_excel('tmp/new_reg_data_GM11.xls')
print('预测结果为:\n',new_reg_data.loc[2014:2015,:])
//预测结果为:
       Unnamed: 0          x1       x3        x4        x5          x6  \
2014         NaN  8142148.24  7042.31  43611.84  35046.63  8505522.58   
2015         NaN  8460489.28  8166.92  47792.22  38384.22  8627139.31   

           x7        x8       x13   y  
2014  4600.40  18686.28  44506.47 NaN  
2015  5214.78  21474.47  49945.88 NaN  

这里使用灰色预测算法采用遍历并对各个特征进行2014和2015年的预测:

首先添加行数并设定索引为年份

# 自定义提取特征后数据的索引
new_reg_data.index = range(1994,2014)
# print(new_reg_data.index)
new_reg_data.loc[2014] = None
new_reg_data.loc[2015] = None

其次,当i=l[i],进入对应列从1994-2013遍历,然后根据1994-2013年的数据预测出2014和2015年的值并将其保存至数据表中。

l = ['x1','x3','x4','x5','x6','x7','x8','x13']
for i in l:
    f = GM11(new_reg_data.loc[range(1994,2014),i].as_matrix())[0]
    print('i:',i)
    print(new_reg_data.loc[range(1994,2014),i])
    new_reg_data.loc[2014,i] = f(len(new_reg_data)-1)
    print(new_reg_data.loc[2014,i])
    new_reg_data.loc[2015,i] = f(len(new_reg_data))
    print(new_reg_data.loc[2015,i])
    new_reg_data[i] = new_reg_data[i].round(2) # 保留2位小数
    print("*"*50)

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

返回顶部


四、支持向量回归预测模型及其使用—预测2014-2015的财政收入

SVR算法:
基本原理:
在这里插入图片描述
在这里插入图片描述
方法及主要参数:
在这里插入图片描述
优点与缺点:
相比于其他方法,支持向量回归的优点是不仅支持适用于线性模型,对于数据和特征之间的非线性关系也能很好抓住;不需要担心多重共线性问题,可以避免局部极小化问题,提高泛化性能,解决高维问题;虽然不会再过程中排出异常点,但是会使得由异常点引起的偏差更小。
缺点是计算复杂程度高,面临大量数据时,计算耗时长。

import pandas as pd
import numpy as np
from sklearn.svm import LinearSVR
import matplotlib.pyplot as plt
from sklearn.metrics import explained_variance_score,mean_absolute_error,mean_squared_error,median_absolute_error,r2_score

data = pd.read_excel('tmp/new_reg_data_GM11.xls',index_col=0) //读取文件是设定第一列为索引,否则默认为0开始,后面会报错找不到索引
feature = ['x1','x3','x4','x5','x6','x7','x8','x13']
print(data.index)


# 取2014年之前的数据建模
data_train = data.loc[range(1994,2014)].copy()
data_std = data_train.std() # 取标准差
data_mean = data_train.mean() # 取平均值
data_train = (data_train - data_mean)/data_std # 数据标准化
print(data_train.columns)
//Index(['Unnamed: 0.1', 'x1', 'x3', 'x4', 'x5', 'x6', 'x7', 'x8', 'x13', 'y '], dtype='object')

x_train = data_train[feature].as_matrix() # 特征数据
y_train = data_train['y'].as_matrix() # 标签数据

linearsvr = LinearSVR().fit(x_train,y_train)

x = ((data[feature]-data_mean[feature])/data_std[feature]).as_matrix() #预测,并还原结果

data[u'y_pred'] = linearsvr.predict(x)*data_std['y'] + data_mean['y']

#SVR预测后保存的结果
#data.to_excel('tmp/new_reg_data_GM11_revenue.xls')
print('真实值与预测值分别为:\n',data[['y','y_pred']])

print('预测图为:',data[['y','y_pred']].plot(subplots = True,
      style=['b-o','r-*']))

首先选取数据并对其标准差标准化,这里使用了copy(),copy()方法会创建一个新的数组对象,而不是建立一个对原数组的索引。简单地说,就是原数组和新数组没有任何关系,任何对新数组的改变都不会影响到原数组,这样一来保证了原始数据的完整性,可以多次操作。
值得一提的是,这里是按照书上的代码,在现行的版本中.as_matrix()已经不用了,改成.values就可以。还有就是使用pycharm运行时正常,但使用jupyter打开运行时,在读取data_train[‘y’]这里会出现keyError。本人的解决方法是在同一个文件中执行,数据就用上面的:
在这里插入图片描述

# 取2014年之前的数据建模
data_train = data.loc[range(1994,2014)].copy()
data_std = data_train.std() # 取标准差
data_mean = data_train.mean() # 取平均值
data_train = (data_train - data_mean)/data_std # 数据标准化
print(data_train.columns)
//Index(['Unnamed: 0.1', 'x1', 'x3', 'x4', 'x5', 'x6', 'x7', 'x8', 'x13', 'y '], dtype='object')

x_train = data_train[feature].as_matrix() # 特征数据
y_train = data_train['y'].as_matrix() # 标签数据

接着构建LinearSVR线性支持向量回归模型,将灰色预测法预测的数据代入进行预测,得到2014和2015年的财政收入的预测值。

linearsvr = LinearSVR().fit(x_train,y_train)
//标准差标准化灰色预测值
x = ((data[feature]-data_mean[feature])/data_std[feature]).as_matrix() #预测,并还原结果
data[u'y_pred'] = linearsvr.predict(x) * data_std['y']  +  data_mean['y'] 

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

ConvergenceWarning说明我们设置的迭代次数不够,参数未收敛,通过设置合理的max_iter属性,可以使模型收敛.
在这里插入图片描述

返回顶部


实训(企业所得税预测)

通过上面的学习,我们了解了一般财政收入的预测流程,接下来按照上述流程,实现对某企业2016和2017年的企业所得税预测。
在这里插入图片描述

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# 求解Pearson相关系数
data = pd.read_csv('data/income_tax.csv')
print('相关系数矩阵为:\n',np.round(data.corr(method='pearson'),2))

在这里插入图片描述

# 使用Lasso回归选取特征
from sklearn.linear_model import Lasso

# 构建Lasso训练数据
lasso = Lasso(1000,random_state=123).fit(data.iloc[:,1:11],data['y'])
print('相关系数为:\n',np.round(lasso.coef_,5)) # 保留5位小数
//相关系数为:
// [ 6.38000000e-03 -3.89000000e-03  5.48000000e-03  4.39088192e+03
//  1.23900000e-02 -5.45124664e+03 -4.00000000e-05 -1.60000000e-02
//  3.75000000e-03  7.60000000e-04]

# 计算相关系数大于0的个数
print('相关系数大于0的有:',np.sum(lasso.coef_>0))
//相关系数大于0的有: 6

mask = lasso.coef_>0
print('lasso.coef_是否大于0:\n',mask)
mask=np.insert(mask,0,[False]) #第一列为年份,在读入新表格的时候要排除
print(mask)
mask = np.append(mask,True) 
print(mask)

new_reg_data = data.iloc[:,mask]
#new_reg_data.to_csv('tmp/new_reg_data1.csv')
print(new_reg_data)

在这里插入图片描述

mask = lasso.coef_>0
print('lasso.coef_是否大于0:\n',mask)
mask=np.insert(mask,0,[False]) //第一列为年份,False表示在读入新表格的时候要排除,但是此处必须得写
print(mask)
mask = np.append(mask,True) //保留y列
print(mask)

在这里插入图片描述
在这里插入图片描述

以上代码与前面案例有所不同,这里经过Lasso回归后的数据仅有正负之分,我们利用为正数的特征进行操作。并且在选择特征提取时,要注意添加第一列为False。如果我们直接按照之前的做,会发现报错:new_reg_data = data.iloc[:,mask] 当下的数目与原数据数目不匹配!。之前不用加是因为得到的Lasso回归系数为0列+y列=表格总列数,而现在得到的Lasso回归系数大于0列+y列!=表格总列数(少了第一列年份的布尔值)

# 引入自编的灰色预测函数
def GM11(x0): #自定义灰色预测函数
  import numpy as np
  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 #返回灰色预测函数、a、b、首项、方差比、小残差概率

# 设置索引为年份
new_reg_data.index = range(2004,2016)
print(new_reg_data)    
# 添加20162017行
new_reg_data.loc[2016] = None
new_reg_data.loc[2017] = None
print(new_reg_data)    

# 设定遍历对象为列名
l = ['x1', 'x3', 'x4', 'x5', 'x9', 'x10']
# 遍历特征使用灰色预测法预测20162017
for i in l:
    f = GM11(new_reg_data.loc[range(2004,2016),i].values)[0]
    new_reg_data.loc[2016,i] = f(len(new_reg_data)-1)
    new_reg_data.loc[2017,i] = f(len(new_reg_data))
    new_reg_data[i] = new_reg_data[i].round(2)
    
print(new_reg_data)    
#new_reg_data.to_excel('tmp/new_reg_data_GM11_1.xls')

在这里插入图片描述

# 构建支持向量回归预测模型
from sklearn.svm import LinearSVR

feature = ['x1', 'x3', 'x4', 'x5', 'x9', 'x10']

// 提取2015年之前的数据建模
data_train = new_reg_data.loc[range(2004,2016)].copy()
data_mean = data_train.mean()
data_std = data_train.std()
// 数据标准差标准化
data_train = (data_train - data_mean)/data_std

x_train = data_train[feature].values //特征数据
y_train = data_train['y'].values     //y标签数据

// 调用LinearSVR函数
linearsvr = LinearSVR() 
linearsvr.fit(x_train,y_train)

x = ((new_reg_data[feature]-data_mean[feature])/data_std[feature]).values
//print(len(x))
//print(len(new_reg_data))
new_reg_data[u'y_pred'] = linearsvr.predict(x)*data_std['y'] + data_mean['y']

//SVR预测后保存的结果
new_reg_data.to_excel('tmp/new_reg_data_GM11_revenue_1.xls')
print('真实值与预测值分别为:\n',new_reg_data[['y','y_pred']])
print('预测图为:',new_reg_data[['y','y_pred']].plot(subplots = True,
      style=['b-o','r-*']))

在这里插入图片描述

返回顶部


本文相关源码下载:https://download.csdn.net/download/qq_45797116/74467274

评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

骑着蜗牛ひ追导弹'

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值