【练习笔记(第一次)】2020年数学建模国赛C题:数据处理、源代码

前言

本来因为ACM竞赛培训的原因没有参加数学建模的培训和系列赛事,开学被同学拉过来凑数,就这样阴差阳错的参加了一次数学建模国赛。由于没有系统的学习数学建模,还是第一次接触数学建模正式赛事,所以论文写的比较水。主要用到的方法都是烂大街的没有新意的方法,都是我在平时做数据练习时的一些偏机器学习的模型。前期想着队长能有什么模型想出来,结果队长啥也没想出来只好自己上,导致正式开始动笔建模时已经比较晚。其实论文还有很多可以改进的地方,比如没有查阅足够的文献资料,综合前人的结果,其实前人已经做出一些信用风险评估模型,其次集成学习比较仓促,没有分配分类器权重系数,时间够的话还应该可以做一下信用迁移矩阵,将题目中的时间用到。但最终还是写出了一个可行但并非最优解,也算完成论文。
最近好多童鞋在问我要论文,这里统一回复一下,当时做的实在太烂了,没有留下相关资源
2020年国赛明令提出不能使用topsis等算法,我使用了,其实做的很烂

题目

在这里插入图片描述

摘要

在这里插入图片描述

说明

详细论文、程序源码和数据

请见代码仓库,过一阵子放

数据预处理

据说这个部分让很多队伍头痛,其实也不是很难,不用很多时间。主要是根据发票信息对每个公司进行统计,我们算出了一些指标,以便以后使用,由于时间原因,没有处理发票中的时间信息。如果时间足够的话,其实还可以算一下信用迁移矩阵。详细程序见下。

综合评价系统

我们用的是Topsis+熵权法,其实综合评价系统有很多种,应该针对不同的数据区别使用,但笔者没系统学过建模,也是现学现用。读者可以尝试使用其他评价系统,或者尝试一些现有信用风险模型,谷歌学术搜一搜就可。

分类系统

使用kmeans分类,我也只知道这个,太菜了╯﹏╰。论文里分了九类,是根据聚类效果评价算法得出来的最佳聚类簇个数,其实3个也就够了的。

程序

1.问题1

数据读取

#导入相关库
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.stats import zscore
from sklearn.decomposition import PCA
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
#读取数据
data = pd.read_excel('a0.xlsx')
data2 =pd.read_excel('a0.xlsx',sheet_name=1)
data3 =pd.read_excel('a0.xlsx',sheet_name=2)
#将企业代号前的E去掉,使其成为数值型变量,便于排序
data['企业代号']=data['企业代号'].apply(lambda x:int(x[1:]))
data2['企业代号']=data2['企业代号'].apply(lambda x:int(x[1:]))
data3['企业代号']=data3['企业代号'].apply(lambda x:int(x[1:]))

数据概览

data
企业代号 企业名称 信誉评级 是否违约
0 1 ***电器销售有限公司 A
1 2 ***技术有限责任公司 A
2 3 ***电子(中国)有限公司***分公司 C
3 4 ***发展有限责任公司 C
4 5 ***供应链管理有限公司 B
... ... ... ... ...
118 119 ***药房 D
119 120 ***陈列广告有限公司 D
120 121 ***药业连锁有限公司***药店 D
121 122 ***商贸有限责任公司 D
122 123 ***创科技有限责任公司 D

123 rows × 4 columns

data2
企业代号 发票号码 开票日期 销方单位代号 金额 税额 价税合计 发票状态
0 1 3390939 2017-07-18 A00297 -943.40 -56.60 -1000.00 有效发票
1 1 3390940 2017-07-18 A00297 -4780.24 -286.81 -5067.05 有效发票
2 1 3390941 2017-07-18 A00297 943.40 56.60 1000.00 有效发票
3 1 3390942 2017-07-18 A00297 4780.24 286.81 5067.05 有效发票
4 1 9902669 2017-08-07 A05061 326.21 9.79 336.00 有效发票
... ... ... ... ... ... ... ... ...
210942 122 54706234 2019-04-17 A08967 223.30 6.70 230.00 有效发票
210943 122 55721344 2020-01-10 A09184 264.15 15.85 280.00 有效发票
210944 123 38493295 2017-12-15 A03624 264.15 15.85 280.00 有效发票
210945 123 95472001 2018-12-29 A03626 264.15 15.85 280.00 有效发票
210946 123 54469883 2019-12-18 A03626 264.15 15.85 280.00 有效发票

210947 rows × 8 columns

data3
企业代号 发票号码 开票日期 购方单位代号 金额 税额 价税合计 发票状态
0 1 11459356 2017-08-04 B03711 9401.71 1598.29 11000.0 有效发票
1 1 5076239 2017-08-09 B00844 8170.94 1389.06 9560.0 有效发票
2 1 5076240 2017-08-09 B00844 8170.94 1389.06 9560.0 有效发票
3 1 5076241 2017-08-09 B00844 4085.47 694.53 4780.0 有效发票
4 1 5076242 2017-08-09 B00844 4085.47 694.53 4780.0 有效发票
... ... ... ... ... ... ... ... ...
162479 123 8887701 2019-12-17 B10944 4827.67 144.83 4972.5 有效发票
162480 123 8887702 2019-12-17 B10944 7412.62 222.38 7635.0 有效发票
162481 123 34173085 2019-12-17 B13093 1917.47 57.53 1975.0 有效发票
162482 123 8887703 2019-12-25 B13093 7252.42 217.58 7470.0 有效发票
162483 123 8887704 2019-12-25 B13093 6660.19 199.81 6860.0 有效发票

162484 rows × 8 columns

数据预处理

#计算有效发票、负数发票和作废发票数量
def cnt(a,b,df):
    tot=0
    for i in range(a,b):
        if df.iloc[i,6]<0 and df.iloc[i,7] == '有效发票':
            tot+=1 
    if(len(df.iloc[a:b,:]['发票状态'].value_counts())==1):
        return  df.iloc[a:b,:]['发票状态'].value_counts()['有效发票'],0,tot
    return df.iloc[a:b,:]['发票状态'].value_counts()['有效发票'],df.iloc[a:b,:]['发票状态'].value_counts()['作废发票'],tot
#计算有效金额,有效税额,作废额
def cnt2(a,b,df):
    zf=0
    yxj=0
    yxs=0
    for i in range(a,b):
        if df.iloc[i,7] == '作废发票':
            zf+=df.iloc[i,6]
        else:
            yxj+=df.iloc[i,4]
            yxs+=df.iloc[i,5]
    return yxj,yxs,zf
#对进项发票进行统计
checkin=pd.DataFrame(data2['企业代号'].value_counts())
checkin.columns=['进项发票数量']
checkin.sort_index(inplace=True)

last=0
temp1=[]
temp2=[]
temp3=[]
temp4=[]
temp5=[]
temp6=[]
temp7=[]

for i in range(len(checkin)):
    a,b,c=cnt(last,last+int(checkin.iloc[i,0]),data2)
    d,e,f=cnt2(last,last+int(checkin.iloc[i,0]),data2)
    last=last+int(checkin.iloc[i,0])
    temp1.append(a)
    temp2.append(b)
    temp3.append(c)
    temp4.append(d)
    temp5.append(e)
    temp6.append(f)
    temp7.append(d+e)

checkin['进项有效发票']=temp1
checkin['进项作废发票']=temp2
checkin['进项负数发票']=temp3
checkin['进项有效金额']=temp4
checkin['进项有效税额']=temp5
checkin['进项无效额']=temp6
checkin['进项有效价税']=temp7
#对销项发票进行统计
checkout=pd.DataFrame(data3['企业代号'].value_counts())
checkout.columns=['销项发票数量']
checkout.sort_index(inplace=True)

last=0
temp1=[]
temp2=[]
temp3=[]
temp4=[]
temp5=[]
temp6=[]
temp7=[]

for i in range(len(checkout)):
    a,b,c=cnt(last,last+int(checkout.iloc[i,0]),data3)
    d,e,f=cnt2(last,last+int(checkout.iloc[i,0]),data3)
    last=last+int(checkout.iloc[i,0])
    temp1.append(a)
    temp2.append(b)
    temp3.append(c)
    temp4.append(d)
    temp5.append(e)
    temp6.append(f)
    temp7.append(d+e)
    
checkout['销项有效发票']=temp1
checkout['销项作废发票']=temp2
checkout['销项负数发票']=temp3
checkout['销项有效金额']=temp4
checkout['销项有效税额']=temp5
checkout['销项无效额']=temp6
checkout['销项有效价税']=temp7
#保存中间结果
checkin.to_excel('value_counts_in.xls')
checkout.to_excel('value_counts_out.xls')
#合并进项和销项发票收据数据,为进行下一步计算做准备
checks=pd.concat([checkin,checkout],axis=1)
#对发票进行汇总统计
temp1=data['信誉评级']
temp2=data['是否违约']

temp1.index=range(1,124)
temp2.index=range(1,124)
checks=pd.concat([temp1,temp2,checks],axis=1)
checks['收入']=checks['销项有效价税']-checks['进项有效价税']

temp1=[]
temp2=[]
temp3=[]
temp4=[]
temp5=[]
last1=last2=0
a=b=0
for i in range(len(checks)):
    next1=last1+checks.iloc[i,2]
    next2=last2+checks.iloc[i,10]
    temp3=data2.iloc[last1:next1,3].value_counts()
    temp4=data3.iloc[last2:next2,3].value_counts()
    if(len(temp3)<=3):
        temp1.append(1)
        temp2.append(1)
        temp5.append(1)
    else:
        a=sum(temp3[:3])/sum(temp3)
        b=sum(temp4[:3])/sum(temp4)
        temp1.append(a)
        temp2.append(b)
        temp5.append(np.sqrt((a*a+b*b)/2))
    last1=next1
    last2=next2
    
checks['进稳定度指标']=temp1
checks['销稳定度指标']=temp2
checks['供求稳定度指标']=temp5

temp1=[]
temp2=[]
for i in range(len(checks)):
    sum1=sum2=sum3=0
    sum1=checks.iloc[i,2]+checks.iloc[i,10]
    sum2=checks.iloc[i,4]+checks.iloc[i,12]
    sum3=checks.iloc[i,5]+checks.iloc[i,13]
    temp1.append(sum2/sum1)
    temp2.append(sum3/sum1)
    
checks['作废发票率']=temp1
checks['负数发票率']=temp2
#保存中间结果
checks.to_excel('checks_1.xls')

第一问子问题一求解

pa0=checks[checks['信誉评级']!='D']
pa0
信誉评级 是否违约 进项发票数量 进项有效发票 进项作废发票 进项负数发票 进项有效金额 进项有效税额 进项无效额 进项有效价税 ... 销项有效金额 销项有效税额 销项无效额 销项有效价税 收入 进稳定度指标 销稳定度指标 供求稳定度指标 作废发票率 负数发票率
1 A 3441 3249 192 71 5.744706e+09 8.932358e+08 2.547518e+08 6.637942e+09 ... 4.065843e+09 6.327901e+08 1.001785e+08 4.698633e+09 -1.939309e+09 0.515838 0.236252 0.401188 0.036014 0.025885
2 A 32156 31435 721 156 1.557623e+08 6.725653e+06 9.248509e+06 1.624880e+08 ... 5.908417e+08 3.545392e+07 6.841255e+07 6.262956e+08 4.638077e+08 0.268597 0.084520 0.199108 0.039297 0.011457
3 C 4561 4367 194 26 5.202698e+07 2.152374e+06 3.341486e+06 5.417935e+07 ... 5.701780e+08 9.089228e+07 2.166951e+07 6.610703e+08 6.068909e+08 0.168823 0.568936 0.419636 0.020221 0.154781
4 C 558 521 37 4 2.198771e+08 3.470711e+07 1.258232e+08 2.545842e+08 ... 1.839970e+09 3.065709e+08 1.990901e+08 2.146541e+09 1.891956e+09 0.261649 0.710892 0.535643 0.081391 0.004661
5 B 2169 2084 85 16 1.977850e+08 2.954699e+07 4.718235e+06 2.273320e+08 ... 2.026323e+08 3.065841e+07 9.497473e+06 2.332907e+08 5.958721e+06 0.393269 0.591509 0.502267 0.043357 0.008052
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
98 B 51 50 1 1 1.993190e+05 9.963970e+03 2.060000e+02 2.092830e+05 ... 1.403242e+06 4.186923e+04 3.697712e+05 1.445111e+06 1.235828e+06 0.392157 0.732026 0.587218 0.102941 0.034314
104 C 1 1 0 0 2.641500e+02 1.585000e+01 0.000000e+00 2.800000e+02 ... 2.626505e+05 7.879490e+03 2.000000e+04 2.705300e+05 2.702500e+05 1.000000 1.000000 1.000000 0.090909 0.045455
105 C 6 6 0 0 7.436920e+03 1.043080e+03 0.000000e+00 8.480000e+03 ... 9.248194e+05 2.774452e+04 1.039500e+04 9.525639e+05 9.440839e+05 0.833333 0.196721 0.605452 0.007812 0.031250
106 B 36 35 1 0 5.033527e+04 2.125830e+03 9.000000e+03 5.246110e+04 ... 5.860489e+05 1.762900e+04 5.552000e+04 6.036779e+05 5.512168e+05 0.361111 0.156863 0.278395 0.084656 0.021164
110 C 3 3 0 0 9.633900e+02 7.661000e+01 0.000000e+00 1.040000e+03 ... 1.969199e+05 5.907650e+03 7.257769e+04 2.028275e+05 2.017875e+05 1.000000 1.000000 1.000000 0.244186 0.000000

99 rows × 24 columns

pa0.iloc[:,0].value_counts()
B    38
C    34
A    27
Name: 信誉评级, dtype: int64
#替换指标值、删除多余项
pa1=pa0
pa1=pa1.replace('是',0)
pa1=pa1.replace('否',1)
pa1=pa1.replace('A',100)
pa1=pa1.replace('B',80)
pa1=pa1.replace('C',52.45)

pa1.drop(pa1.columns[range(2,18)],axis=1,inplace=True)
pa1.drop(pa1.columns[range(3,5)],axis=1,inplace=True)
pa1
信誉评级 是否违约 收入 供求稳定度指标 作废发票率 负数发票率
1 100.00 1 -1.939309e+09 0.401188 0.036014 0.025885
2 100.00 1 4.638077e+08 0.199108 0.039297 0.011457
3 52.45 1 6.068909e+08 0.419636 0.020221 0.154781
4 52.45 1 1.891956e+09 0.535643 0.081391 0.004661
5 80.00 1 5.958721e+06 0.502267 0.043357 0.008052
... ... ... ... ... ... ...
98 80.00 1 1.235828e+06 0.587218 0.102941 0.034314
104 52.45 1 2.702500e+05 1.000000 0.090909 0.045455
105 52.45 1 9.440839e+05 0.605452 0.007812 0.031250
106 80.00 1 5.512168e+05 0.278395 0.084656 0.021164
110 52.45 1 2.017875e+05 1.000000 0.244186 0.000000

99 rows × 6 columns

#成本型指标转换,数据归一化
pa1['作废发票率']=(max(pa1['作废发票率'])-pa1['作废发票率'])/(max(pa1['作废发票率'])-min(pa1['作废发票率']))
pa1['负数发票率']=(max
评论 27
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值