分析工具:Python
涉及库:pandas sklearn keras
背景和挖掘目标
企业做假账偷税漏税的行为普遍存在,汽车行业通过“多开发票”、“做双份报表”、“减少支出”等方式进行偷漏税。随着企业偷漏税现在泛滥,也影响国家经济基础。通过数据挖掘能自动识别企业偷漏税行为,提高稽查效率减少经济损失。
汽车销售行业在税收上存在少开发票金额、少记收入,上牌、按揭、保险不入账,不及时确认保修索赔款等情况,导致政府损失大量税收。汽车销售企业的部分经营指标数据能在一定程度上评估企业的偷漏税倾向。样本数据提供了汽车销售行业纳税人的各种属性和是否偷漏税标识,提取纳税人经营特征可以建立偷漏税行为识别模型。
分析方法和过程
在建立偷漏税识别模型前需要先整理流程(如下图),主要包含以下步骤:
- 从后台业务系统抽取企业经营指标静态数据,保证建模样本数据稳定性。
- 对样本数据进行探索性分析,查看指标分布情况。
- 对样本数据进行预处理,包括数据集清洗、缺失值处理和数据规则化。
- 选取特征建立样本集和测试集。
- 构建识别模型对样本数据进行模型训练,并对模型进行评价。
-
使用多种模型并挑选最优模型进行自动识别。
数据抽取
由于已经有现成的数据集可供使用,故这里省略从后台系统抽取数据集的过程。先用pandas库读取Excel文件的原始数据,具体代码如下:
import pandas as pd
data = pd.read_excel('data.xls', index_col=u'纳税人编号') # 读取数据文件,指定索引为纳税人编号
data.head() # 查看前五条数据
数据探索分析
样本数据包含15个特征属性,分别为14个输入特征和1个输出特征,有纳税人基本信息和经营指标数据。数据探索性分析能及早发现样本数据是否存在较大差异和对数据的整体情况有基本的认识。具体代码如下:
fig, axes = plt.subplots(1, 2) # 创建画布
fig.set_size_inches(12, 4) # 设置画布大小
ax0, ax1 = axes.flat
data[u'销售类型'].value_counts().plot(kind='barh', ax=ax0, title=u'销售类型分布情况') # 分类汇总后绘制水平柱状图
data[u'销售模式'].value_counts().plot(kind='barh', ax=ax1, title=u'销售模式分布情况')
data.describe().T # 对数值变量进行统计描述
-
分类变量分布情况
从数据的分布情况上看,销售类型主要集中在国产轿车和进口轿车,销售模式主要集中在4S店和一级代理商。
-
数值变量统计描述
统计结果显示各个数据指标均无缺失值,个别指标数据如(整体税负控制数、办牌率、单台办牌手续费收入等)最小值为零。
数据预处理
考虑建模的需要前面样本数据中类别型特征需要进行转换成数值型特征,故对销售类型和销售模式进行重编码处理,输出特征进行二值化处理。由于数据中并无缺失值,则不需要进行缺失值处理。
# 数据预处理
data[u'输出'] = data[u'输出'].map({u'正常': 0, u'异常': 1})
data[u'销售类型'] = data[u'销售类型'].map({u'国产轿车': 1, u'进口轿车': 2, u'大客车': 3,
u'卡车及轻卡': 4, u'微型面包车': 5, u'商用货车': 6,
u'工程车': 7, u'其它': 8})
data[u'销售模式'] = data[u'销售模式'].map({u'4S店': 1, u'一级代理商': 2, u'二级及二级以下代理商': 3,
u'多品牌经营店': 4, u'其它': 5})
构建偷漏税行为识别模型
在得到预处理后的样本数据,需要对数据集进行划分训练集和测试集,随机选取20%的数据作为测试集,其余80%的数据作为训练集。模拟方面使用分类预测模型来实现偷漏税自动识别,比较常用的分类模型又LM神经网络和CART决策树,两种模型都有其优点,故采用两种模型进行训练并从中选择最优的分类模型。
1. 数据划分
使用scikit-learn交叉验证随机将数据集划分据为训练集和测试集,具体代码如下:
from sklearn.cross_validation import train_test_split
p = 0.2 # 设置训练数据比例
data = data.as_matrix() # 将数据转化为矩阵
train_x, test_x, train_y, test_y = train_test_split(data[:, :14], data[:, 14], test_size=p) # 设置20%的数据为测试集,其余的为训练集
分类模型的性能根据模型正确和错误预测的检验记录计数进行评估,这些计数存放在混淆矩阵的表格中。下表描述二元分类问题的混淆矩阵。表中每个表项f表示实际类标号为i但被预测为类j的记录数。
2. LM神经网络
使用Keras库可以来构建神经网络模型,设定LM神经网络的输入节点数为14,输出节点数为1,隐藏层节点数为10,使用Adam方法求解。在隐藏层使用Relu(x) = max(x, 0) 做为激活函数。训练集建模的混淆矩阵如下图,算出分类准确率为(57+34) / (57+34+2+6) = 91.9%。构建LM神经网络模型的代码如下:
# 构建LM神经网络模型
from keras.models import Sequential # 导入神经网络初始函数
from keras.layers.core import Dense, Activation # 导入神经网络网络层函数及激活函数
net_file = 'net.model'
net = Sequential() # 建立神经网络
net.add(Dense(10, input_shape=(14,))) # 添加输入层(14节点)到隐藏层(10节点)的连接
net.add(Activation('relu')) # 隐藏层使用relu激活函数
net.add(Dense(1, input_shape=(10,))) # 添加隐藏层(10节点)到输出层(1节点)的连接
net.add(Activation('sigmoid')) # 输出层使用sigmoid激活函数
net.compile(loss='binary_crossentropy', optimizer='adam', class_mode='binary') # 编译模型,使用adam方法求解
net.fit(train_x, train_y, nb_epoch=1000, batch_size=10) # 训练模型循环一千次
net.save_weights(net_file) # 保存模型
predict_result = net.predict_classes(train_x).reshape(len(train_x)) # 预测结果
from cm_plot import cm_plot # 导入混淆矩阵可视化函数
cm_plot(train_y, predict_result).show() # 显示混淆矩阵可视化图
3. CART决策树
使用scikit-learn库构建CART决策树模型,并训练模型后得到混淆矩阵如下图,分类的准确率为 (55+39) / (55+39+1+4) = 94.9%,构建决策树模型的代码如下:
# 构建CART决策树模型
from sklearn.tree import DecisionTreeClassifier # 导入决策树模型
from sklearn.externals import joblib
tree_file = 'tree.pkl' # 模型输出路径
tree = DecisionTreeClassifier(criterion='entropy', max_depth=3) # 建立决策树模型
tree.fit(train_x, train_y) # 训练模型
joblib.dump(tree, tree_file) # 保存模型
cm_plot(train_y, tree.predict(train_x)).show() # 显示混淆矩阵可视化图
模型评价
对于训练集,LM神经网络模型和CART决策树的分类准确率都比较好,分别为91.9%和94.9%。为了进一步评估模型分类的效果,需要使用测试集对两个模型进行评价,采用ROC线评价方法进行评估,优秀的分类器所对应的ROC曲线应该经历靠近左上角。分别画出LM神经网络和CART决策树在测试集下的ROC曲线,如下图所示。LM神经网络和CART决策树对测试集数据的测试代码如下:
# 绘制LM神经网络模型的ROC曲线
from sklearn.metrics import roc_curve # 导入ROC曲线函数
predict_result = net.predict(test_x).reshape(len(test_x)) # 预测结果
fpr, tpr, thresholds = roc_curve(test_y, predict_result, pos_label=1)
plt.plot(fpr, tpr, linewidth=2, label='ROC of LM') # 绘制ROC曲线
plt.xlabel('False Positive Rate') # 坐标轴标签
plt.ylabel('True POstive Rate')
plt.xlim(0, 1.05) # 设定边界范围
plt.ylim(0, 1.05)
plt.legend(loc=4) # 设定图例位置
plt.show() # 显示绘图结果
# 绘制决策树模型的ROC曲线
fpr, tpr, thresholds = roc_curve(test_y, tree.predict_proba(test_x)[:,1], pos_label=1)
plt.plot(fpr, tpr, linewidth=2, label='ROC of CHAR') # 绘制ROC曲线
plt.xlabel('False Positve Rate') # 坐标轴标签
plt.ylabel('True Postive Rate')
plt.xlim(0, 1.05) # 设定边界范围
plt.ylim(0, 1.05)
plt.legend(loc=4) # 设定图例位置
plt.show() # 显示绘图结果
对比两个模型的ROC曲线可以发现LM神经网络的ROC曲线比CART决策树的ROC曲线更加靠近左上角,LM神经网络的ROC曲线下的面积更大,说明LM神经网络模型的分类性能更好,能用来识别偷漏税行为。
参考资料:
《数据挖掘导论》
《数据挖掘概念与技术》
《Python数据分析与数据挖掘实战》