财政因素影响分析及预测模型
数据探索
这里我们要研究的是财政的影响因素,所以首先对可能影响财政收入的十三个因素(x1-x13)和最后的财政收入(y)进行数据探索,找出每个属性的均值,最大最小值,方差这些的:
import numpy as np
import pandas as pd
inputfile = 'data1.csv' #输入的数据文件
data = pd.read_csv(inputfile) #读取数据
r = [data.min(), data.max(), data.mean(), data.std()] #依次计算最小值、最大值、均值、标准差
此时r是一个list,中包含四个Series,r为(4,14)的,data.min()为(14,1)
将这个list变为DataFrame类型,r变为(4,14)的DataFrame,所以要转置
r = pd.DataFrame(r, index = ['Min', 'Max', 'Mean', 'STD']).T #计算相关系数矩阵
a = np.round(r, 2) #保留两位小数
print(a)
得到a:
相关性分析
我们要分析x1-x13与y是否有线性关系,所以要做自相关性分析,表示出每一个x对y的相关性系数,需要得出自相关矩阵:
import numpy as np
import pandas as pd
inputfile = 'data1.csv' #输入的数据文件
data = pd.read_csv(inputfile) #读取数据
corr_matrix = np.round(data.corr(method = 'pearson'), 2) #计算相关系数矩阵,保留两位小数
print(corr_matrix)
很显然,x11对财政收入的线性关系不显著,而且成负相关
相关系数是变量之间相关程度的指标。样本相关系数用r表示,总体相关系数用ρ表示,相关系数的取值一般介于-1~1之间。相关系数不是等距度量值,而只是一个顺序数据。计算相关系数一般需大样本。
相关系数 又称皮(尔生)氏积矩相关系数,说明两个现象之间相关关系密切程度的统计分析指标。
相关系数用希腊字母γ表示,γ值的范围在-1和+1之间。
γ>0为正相关,γ<0为负相关。γ=0表示不相关;
γ的绝对值越大,相关程度越高。
两个现象之间的相关程度,一般划分为四级:
如两者呈正相关,r呈正值,r=1时为完全正相关;如两者呈负相关则r呈负值,而r=-1时为完全负相关。完全正相关或负相关时,所有图点都在直线回归线上;点子的分布在直线回归线上下越离散,r的绝对值越小。当例数相等时,相关系数的绝对值越接近1,相关越密切;越接近于0,相关越不密切。当r=0时,说明X和Y两个变量之间无直线关系。通常|r|大于0.75时,认为两个变量有很强的线性相关性。
模型构建
变量选择模型
我们可以看出影响y的x共有13个,,其中有一些对y的贡献率很小,或者没有和其他变量重复了,存在共线性现象:如居民消费水平和城镇居民人均消费支出存在明显的共线性
这里用Adaptive-Lasso变量选择模型
import pandas as pd
import numpy as np
inputfile = '../data/data1.csv' #输入的数据文件
data = pd.read_csv(inputfile) #读取数据
#导入AdaptiveLasso算法,要在较新的Scikit-Learn才有。
from sklearn import linear_model
model = linear_model.Lasso(alpha = 1)
model.fit(data.iloc[:,0:13],data['y'])
co = model.coef_ #各个特征的系数
coo = np.round(co,4)#都保留四位小数
print(coo)
-0.0002
-0.3155
0.4329
-0.0316
0.0758
0.0004
0.2413
-0.037
-2.5545
0.4414
5.6928
-0
-0.0399
不知道为啥,跟书上有点不一样
按书上的意思是说,算出来的系数为0的话,该属性应该就是要被剔除的,这里就跳过这个步骤,认为已经筛选出来6个影响因素了,接下来用这六个因素去预测财政收入
财政收入预测模型
这里财政收入预测模型采用灰色预测与神经网络的组合模型
先用灰色预测模型算出2014,2015的各项影响因素的值,再用预测出的影响因素的值代入到神经网络中,预测财政收入y_pre
首先贴出GM11.py的代码:
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、首项、方差比、小残差概率
这里我们先用灰色预测模型算2014,2015的x1,x2,x3,x4,x5,x7:
import numpy as np
import pandas as pd
from GM11 import GM11 #引入自己编写的灰色预测函数
inputfile = 'data1.csv' #输入的数据文件
outputfile = 'data1_GM11.xls' #灰色预测后保存的路径
modelfile = 'net.model' #模型保存路径
data = pd.read_csv(inputfile) #读取数据
data.index = range(1994, 2014)#将索引值更换为1994到2013
data.loc[2014] = None
data.loc[2015] = None
在原来的data下面添加2014和2015的行:
l = ['x1', 'x2', 'x3', 'x4', 'x5', 'x7']
for i in l:
f = GM11(data[i][:20].values)[0]
print(f(21))
data[i][2014] = f(len(data)-1) #2014年预测结果
data[i][2015] = f(len(data)) #2015年预测结果
data[i] = data[i].round(2) #保留两位小数
data[l+['y']].to_excel(outputfile) #结果输出
这里我先开始一直报错,说GM11里面的linalg出现了奇异矩阵的情况:
后来我发现 f = GM11(data[i][:20].values)[0] 我写成了 f = GM11(data[i][1994:2014].values)[0]这样导致GM11的参数为空了,i是索引值,后面一个‘[]’里面应该填行数,而不是索引了!!!
注意:
这里
f = GM11(data[i][:20].values)[0]
print(f(21))
这里得出来的f是一个函数<function GM11.GM11..(k)>,f(21)表示函数自变量是21时候的值,所以这里打印f是打印不出来的,你得打印f(x)才有值
这样算出来了六个影响因素的预测值:
接下来,我们再用神经网络:
import pandas as pd
import numpy as np
inputfile = 'data1_GM11.xls' #灰色预测后保存的路径
outputfile = 'revenue.xls' #神经网络预测后保存的结果
modelfile = '1-net.model' #模型保存路径
data = pd.read_excel(inputfile,index_col = 0) #读取数据
feature = ['x1', 'x2', 'x3', 'x4', 'x5', 'x7'] #特征所在列
得到data:
data = pd.read_excel(inputfile,index_col = 0) #读取数据
注意读取数据,如果不加index_col = 0会怎么样,报错:
KeyError: “None of [Int64Index([1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,\n 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013],\n dtype=‘int64’)] are in the [index]”
那么年份也成了一个属性值,一个影响因素,我们想去掉前面的0:21,以1994:2015为索引,参考
从数据中分离出训练数据
data_train = data.loc[np.arange(1994,2014)].copy() #取2014年前的数据建模
标准化
#对训练数据标准化
data_mean = data_train.mean()
data_std = data_train.std()
data_train = (data_train - data_mean)/data_std #数据标准化
将训练数据分为x_train,y_train,进行训练,但是训练的数据得是numpy.ndarray型的,而data是dataFrame型,所以用values变换
x_train = data_train[feature].values #特征数据
y_train = data_train['y'].values #标签数据
训练神经网络:
from keras.models import Sequential
from keras.layers.core import Dense, Activation
model = Sequential() #建立模型
model.add(Dense(input_dim = 6,output_dim = 12))
model.add(Activation('relu')) #用relu函数作为激活函数,能够大幅提供准确度
model.add(Dense(input_dim = 12,output_dim = 1))
model.compile(loss='mean_squared_error', optimizer='adam') #编译模型
model.fit(x_train, y_train, nb_epoch = 10000, batch_size = 16) #训练模型,学习一万次
model.save_weights(modelfile) #保存模型参数
进行10000次学习,最后的loss很小,保存训练好的模型
这里保存的是模型的参数weights,即只保存了模型的weights到这个model文件中
这里把上面的构建模型以及训练步骤全部注释掉,模拟我们下次直接拿测试数据进去测试的过程,我们后面运行的代码中,不想再有训练这个过程,因为很费时间,既然存储了参数,那么我们后面的预测,就直接load_weights下来参数使用就好了:
from keras.models import Sequential
from keras.layers.core import Dense, Activation
#model = Sequential() #建立模型
#model.add(Dense(input_dim = 6,output_dim = 12))
#model.add(Activation('relu')) #用relu函数作为激活函数,能够大幅提供准确度
#model.add(Dense(input_dim = 12,output_dim = 1))
#model.compile(loss='mean_squared_error', optimizer='adam') #编译模型
#model.fit(x_train, y_train, nb_epoch = 10000, batch_size = 16) #训练模型,学习一万次
#model.save_weights(modelfile) #保存模型参数
model.load_weights(modelfile)
但是我们发现报错了!!!!:
NameError: name ‘model’ is not defined
这是因为我们的文件中只存储了神经网络的weights参数,并没有将模型存储下来,他不知道这是一个多少层,输入输出多少,激励函数是什么的神经网络,所以这样是没有意义的,我们要告诉他这个神经网络的构造,再把训练好的weights参数加载进去,这样才可以正常工作:
def build_model():
model = Sequential()
model.add(Dense(input_dim = 6,output_dim = 12))
model.add(Activation("relu"))
model.add(Dense(input_dim = 12,output_dim = 1))
model.compile(loss='mean_squared_error', optimizer='adam')
return model
model = build_model()
model.load_weights(modelfile)
我们构造了一个函数,告诉这个模型的具体结构,然后把训练好的参数载入进去使用:
#预测,并还原结果。
x = ((data[feature] - data_mean[feature])/data_std[feature]).values
data[u'y_pred'] = model.predict(x) * data_std['y'] + data_mean['y']
#data.to_excel(outputfile)
data:
画出原始数据和预测对比图
import matplotlib.pyplot as plt #画出预测结果图
p = data[['y','y_pred']].plot(subplots = True, style=['b-o','r-*'])
plt.show()
若画在一起:
import matplotlib.pyplot as plt #画出预测结果图
p = data[['y','y_pred']].plot(style=['b-o','r-*'])
plt.show()
完整代码:
import pandas as pd
import numpy as np
inputfile = 'data1_GM11.xls' #灰色预测后保存的路径
outputfile = 'revenue.xls' #神经网络预测后保存的结果
modelfile = '1-net.model' #模型保存路径
data = pd.read_excel(inputfile,index_col = 0) #读取数据
feature = ['x1', 'x2', 'x3', 'x4', 'x5', 'x7'] #特征所在列
data_train = data.loc[np.arange(1994,2014)].copy() #取2014年前的数据建模
#对训练数据标准化
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 #标签数据
from keras.models import Sequential
from keras.layers.core import Dense, Activation
model = Sequential() #建立模型
model.add(Dense(input_dim = 6,output_dim = 12))
model.add(Activation('relu')) #用relu函数作为激活函数,能够大幅提供准确度
model.add(Dense(input_dim = 12,output_dim = 1))
model.compile(loss='mean_squared_error', optimizer='adam') #编译模型
model.fit(x_train, y_train, nb_epoch = 10000, batch_size = 16) #训练模型,学习一万次
model.save_weights(modelfile) #保存模型参数
#def build_model():
# model = Sequential()
#
# model.add(Dense(input_dim = 6,output_dim = 12))
# model.add(Activation("relu"))
# model.add(Dense(input_dim = 12,output_dim = 1))
# model.compile(loss='mean_squared_error', optimizer='adam')
# return model
#model = build_model()
#model.load_weights(modelfile)
#预测,并还原结果。
x = ((data[feature] - data_mean[feature])/data_std[feature]).values
data[u'y_pred'] = model.predict(x) * data_std['y'] + data_mean['y']
#data.to_excel(outputfile)
import matplotlib.pyplot as plt #画出预测结果图
p = data[['y','y_pred']].plot(style=['b-o','r-*'])
plt.show()
有了财政收入预测模型之后,对于增值税预测模型、营业税预测模型、企业所得税预测模型、个人所得税预测模型、政府性基金收入预测模型,都是一样的
- 先用Adaptive-Lasso变量选择算法算出得出影响因素具体是哪几个x
- 再用灰色预测模型算出这几个影响因素x的2014,2015的值
- 用神经网络算2014,2015的预测值y_pre
增值税预测模型
1.Adaptive-Lasso变量选择算法略,因为用现在python算出系数表与书上不一样,可能是算法变了
2.灰色预测模型:
import numpy as np
import pandas as pd
from GM11 import GM11 #引入自己编写的灰色预测函数
inputfile = '../data/data2.csv' #输入的数据文件
outputfile = '../tmp/data2_GM11.xls' #灰色预测后保存的路径
data = pd.read_csv(inputfile) #读取数据
data.index = range(1999, 2014)
data.loc[2014] = None
data.loc[2015] = None
l = ['x1', 'x3', 'x5']
for i in l:
f = GM11(data[i][np.arange(1999, 2014)].as_matrix())[0]
data[i][2014] = f(len(data)-1) #2014年预测结果
data[i][2015] = f(len(data)) #2015年预测结果
data[i] = data[i].round(6) #保留六位小数
data[l+['y']].to_excel(outputfile) #结果输出
3.神经网络:
import pandas as pd
inputfile = '../tmp/data2_GM11.xls' #灰色预测后保存的路径
outputfile = '../data/VAT.xls' #神经网络预测后保存的结果
modelfile = '../tmp/2-net.model' #模型保存路径
data = pd.read_excel(inputfile,index_col = 0) #读取数据
feature = ['x1', 'x3', 'x5'] #特征所在列
data_train = data.loc[range(1999,2014)].copy() #取2014年前的数据建模
data_mean = data_train.mean()
data_std = data_train.std()
data_train = (data_train - data_mean)/data_std #数据标准化
x_train = data_train[feature].as_matrix() #特征数据
y_train = data_train['y'].as_matrix() #标签数据
from keras.models import Sequential
from keras.layers.core import Dense, Activation
model = Sequential() #建立模型
model.add(Dense(input_dim = 3,output_dim = 6))
model.add(Activation('relu')) #用relu函数作为激活函数,能够大幅提供准确度
model.add(Dense(input_dim = 6,output_dim = 1))
model.compile(loss='mean_squared_error', optimizer='adam') #编译模型
model.fit(x_train, y_train, nb_epoch = 10000, batch_size = 16) #训练模型,学习一万次
model.save_weights(modelfile) #保存模型参数
#预测,并还原结果。
x = ((data[feature] - data_mean[feature])/data_std[feature]).as_matrix()
data[u'y_pred'] = model.predict(x) * data_std['y'] + data_mean['y']
data[u'y_pred'] = data[u'y_pred'].round(2)
data.to_excel(outputfile)
import matplotlib.pyplot as plt #画出预测结果图
p = data[['y','y_pred']].plot(subplots = True, style=['b-o','r-*'])
plt.show()
营业税预测模型
企业所得税预测模型
个人所得税预测模型
政府性基金收入预测模型
同上