2020 全国大学生数学建模竞赛C题思路+代码# i( z5 K! F; V- f# ?
题目链接:https://cloud.189.cn/t/ri2uUb7BRVJr0 f7 W% N: T3 B1 J1 b
0 k' a; r) I. b) q! [: A0 c( y
: O* g$ R, R3 v/ x5 f
前言- a5 l* s u+ z, @. ?
: w% A. h- p! R( j
: j, i5 L6 M) n# n+ U
6 w+ z. a+ V' V
* \+ j/ X9 A) F. d& v
又是一年数据挖掘题型,第一次接触这种题型还是在去年的mathorcup上,这种题的难度就在于指标的建立和数据的处理上。后面会出一份关于数据挖掘题型,我的相关经验,常用的工具和代码。; I2 x2 X. k% F) G
6 F d# y: @$ y* Q* U7 Q0 q% t1 x5 L- o: [5 G$ u
下面的一,二问实际都在解决& M( W3 f9 m1 d
- ]2 T" @% H4 v$ F: h+ O6 `- z/ D. N. i4 p4 H& L
贷不贷款?+ L( N4 S' _, T' @" E6 K
贷款金额多少?0 ?" [* c- z! Z4 d! B5 O
数据清洗4 K7 F4 J2 `1 E
这道题的附件数据没有出现缺省或者异常数据,因此对于数据的预处理,更多的是根据问题的需求来做的。 3 V$ [1 Z; o' ^, r& G4 _( g$ e& i( N3 P
, I3 _/ g9 O* o! C$ k将是否违约,违约设置为1,不违约设置为0 & k* j v9 u% Y& @0 x0 _% L l8 C/ T: i/ D: ~, T
8 s7 ~8 i% E$ c. A' ?
信誉等级ABCD分别对应4,3,2,1 & f1 R2 \3 X, Z! @" P$ D 5 ~/ a w9 {4 u* ^8 h8 |- U8 ]7 H& Q2 A0 J& @* c
发票状态,有效发票为a,作废发票为b 0 q% D5 H, F2 s5 \5 ^5 z e/ S; S1 n5 h& f7 e9 z) {
( y3 e/ W& ?8 g8 l1 |0 }
我将销项和进项所有数据,以公司代码为区别,提取到了不同的sheet当中,对于该公司有效发票数,作废发票数,负数发票数,方便对数据观察。 ! L$ d" m( R# s9 | . M$ g: ^& A, F7 X. J / J# X; C0 C! t# B# 遍历所有sheet数据. L# P$ h6 ]& y6 m7 O; Z9 r7 V' Z* l
for xsn in sn.sheet_names[1:]: n# L" m* `; A3 C3 }5 c
# 读取文件 " M) {- o; l+ j datas = pd.read_excel(file_pos, sheet_name=xsn)- ?! o. w0 `- N5 v
datas['date']=pd.to_datetime(datas['date'],format='%Y/%m/%d')5 ]4 i# c/ Z: y+ z9 v# \
datas.set_index('date', drop=True) 5 g+ l; f' u6 N0 _' _* C. e9 r # 找到全部公司名称代号 + P$ a4 ?! j2 t% s. c0 C r code_list = list(set(list((datas['code'])))) ( I, H# M1 W0 E$ s( Z' v) f for name in code_list: 9 l$ s0 y& D; l$ s& g& b: d tmp_datas = datas[datas['code'] == name] ^* G5 l1 C: F: m) ?
tmp_datas.index = range(len(tmp_datas)) & E: E8 r& t9 M: k8 `8 \ # 转换日期未object类型 / V/ r0 F# {! N5 M6 l tmp_datas['date'] = [x.strftime('%Y/%m/%d') for x in tmp_datas['date']]( d0 ]6 G, I7 S9 l
count1 = tmp_datas['tax_status'].value_counts()* {+ Z3 U5 @9 I" j4 C
tmp_datas['a_count'] = list(count1)[0]! H; G9 S+ A5 G8 _3 W
if(len(count1) > 1): & E2 |8 R' w, y+ M" G& k8 L% y7 c tmp_datas['b_count'] = list(count1)[1]; Y0 S3 p5 F" u6 q- Q: y
tmp2 = tmp_datas[tmp_datas['cost'] < 0] o9 V/ K6 b) v! z, L
tmp_datas['neg_value_tax'] = len(tmp2)/ ~8 Y7 x8 a$ s1 f( ~! m
if xsn == sn.sheet_names[1]:% N! l5 R! J# p. s
tmp_datas.to_excel(writer1,sheet_name=name,index=False)1 P# M( l" Z" [3 n
else:2 x9 p4 t% w+ [3 [) B7 f
tmp_datas.to_excel(writer2,sheet_name=name,index=False)4 [! \( ~5 \" q0 U6 Q% X
负数发票:在之前购买的物品,并开具了相关正向发票,后来退货所以开具了值为负数的发票,抵消前面正数发票的值。 # g' p8 H7 a$ k# Y5 H, j) d2 ^ 8 s, a" G' P9 M g3 e2 N; v, h7 j# u$ C; s5 M9 [' y4 i% `
提取到信息: / {' V! g0 B/ m) E3 N" I" u' ^9 O0 ~7 f! {( V: N0 p7 B5 ]& t
9 l; k3 s) X. m, M, i8 u2 b5 y# Z' Z. A, q
贷款年利率' d+ s* V3 Q; B9 R
绘制出年利率与客户流失率图,可以分析出两者应该是有关系的。利用SPSS拟合出不同信誉等级,年利率与客户流失率的关系式。0 U5 b- [% k) V8 {% r
- d8 N$ `& m& i' F! ^! r3 m T- ] i
$ T, x0 E% H! V信誉等级 R平方 关系式, g9 w, M) ]7 g" V9 w
A 0.9977 y = 37.97x^3-258.57x^2+640.944*x -1.1218 V5 [* @) B# J$ F
B 0.9982 y = 33.995x^3-225.051x^2+552.829*x-1.017 3 _/ `( r" h7 F( l% [2 M( L2 iC 0.9982 y = 32.157x^3-207.386x^2+504.717*x-0.973 I2 n" [* t& V. F# x( M" o! i银行获利=贷款金额x贷款年利率x(1-利率对于信誉评级客户流失率)! _2 X! x: F% f) j h
: K( h( {1 X4 v8 k
5 F. J' s a9 [! Q
在贷款金额确认,贷款年利率范围在0.4~1.5的情况下,利用上面拟合的关系式,我们能够暴力跑出最优年利率。 ]/ Z9 }$ { ~ 3 } X+ S1 X8 \2 Q0 I7 ?0 ^8 u5 H , {1 u7 J7 c, ?0 Rdouble turnover_rate(double x, char ch) {+ a2 T+ g! |4 g- |. I! ^3 b
double y = 0, result = 0; 9 [; U B4 A! r/ Z) U7 ?( ]2 ] switch (ch) {4 L3 s, K, y# J1 I! {, @
case 'A': , J$ n" D. m4 R y = 37.969520 * pow(x, 3) - 258.570452 * pow(x, 2) + 640.944427 * x - 1.121484; " l: j" d3 f! `% k/ L) B result = x * (1 - y / 100.0); : U. M; w% j7 v& r1 P6 p3 E% ~ break;. p. @( p& W) ^7 p. ~
case 'B': 6 j6 M$ C' M# J/ [, c! D. i y = 33.994698 * pow(x, 3) - 225.050538 * pow(x, 2) + 552.829151 * x - 1.016503; 2 h) s& _0 d' }* h2 Y result = x * (1 - y / 100.0); $ L. Q, K! `0 [2 u9 | break;' V. [9 y: \ _6 L
case 'C': 4 d2 g( u+ J9 G y = 32.156864 * pow(x, 3) - 207.385880 * pow(x, 2) + 504.716993 * x - 0.973497; ' }5 f4 I6 E6 i$ D0 x! x. a result = x * (1 - y / 100.0);5 k+ @" E" B6 Z+ w! ^
break; 0 Z" @8 F! U" |; V default:# ?9 ?2 J. z8 [( L; H6 V. j o# W
cout << "输出有误!" << ch << endl; # x! a; d6 L* J0 F$ d @, j } 0 Z* C! m* Q0 A k* V% S 4 `/ L, {% b% a. x return result;; B/ ~; ^: E% e2 e [
} D& Q4 i+ C" S4 {* B" Y/ e& I( ^6 w; w; Z E' D
; {, y0 ^4 D, k" U6 e+ i: d) y; D
/ m. c% i% U8 N% ]* r问题二 " {' Y- _. n# b, Y6 t利用代码,重新计算出各指标数据 9 G9 b$ j( b* `/ I$ ?代入Logistics违约率预测模型,预测出各公司的违约率- l' N, V ~: e! b* z* ]9 }' Y2 i" b
根据标准普尔评级建立,主标尺,对不同违约率进行A~D等级划分,信誉等级D不予贷款/ L+ ]2 B! `$ p V2 { Q- f
将违约率代入,之前得到的公式,得到具体贷款金额& G/ K. e% I) X' @% {
最优年利率沿用上一问 # g; C5 c) f& Z+ H1 x# 信用等级 9 d5 G: a6 x* ^+ _cs = [] 0 N! f: Q" h; I. I. `5 P" T7 q# 最优年利率,客户流失率,利率值+ W% d; g) d. T" @" C! T3 k$ a: V
tax = [] " [/ R2 H3 C# J# O$ |for i in m: 3 D0 O, L% ]$ ~! k! t if i <= 0.0069264: - R3 L ]1 l% z9 k) Q( D cs.append('A')" n& V) ^! e' \9 e
tax.append([0.083,0.503173,0.0412366]) ! |; v. a. o8 b9 v J elif i > 0.0069264 and i <= 0.22619:4 A Z8 W2 J* X: c/ L8 r# [
cs.append('B') 1 r7 f* t8 N/ ^9 J! _ tax.append([0.097,0.505215,0.0479942])* f9 s |% g; q# e
elif i > 0.22619 and i <= 0.509915: / |2 `8 @+ w+ |9 ?8 }( E cs.append('C'); {# V v$ Q, M! b
tax.append([0.1069,0.506501,0.052755]) 5 G( Z, ^. T. Y7 S elif i > 0.509915: ! t. ]/ X- Q r cs.append('D') $ Y1 H) }$ x) _# w tax.append([0.15,0,0])# B, t' q3 i" d- w! `2 e
else: ' D6 n) l7 u2 `' ~8 g1 B print('违规')( \2 G5 V+ s: u: Y& t
. p' ^+ M2 U! E* a" w
parr = [] " W4 q5 `. d! x- t) Zfor arr in list(a): $ ^! W" u; e' y* e, o parr.append(list(arr)[0]) 4 |+ T1 U1 V9 x# X0 A7 d* Nsum_val = sum(parr) " F- ?, ?2 C1 R6 j' s) x9 |amount = [] % X* {3 n( \ T3 D& yfor ival in parr: 8 v7 M7 M5 S- P( f) j8 G3 i tmp = ival / sum_val * 100000000 0 ~: k( t9 l! T2 v2 ^1 ^, _ if ival < 1 - 0.509915: ' p% K5 B. a( T: _# L amount.append(0)1 d$ f- x* R7 p* M# `
else:$ E( z2 J0 U* P- c: Z, W& g
amount.append(tmp)5 \8 U# l: y+ J
( m2 U, X ^- I ?: D2 b
+ r) z& T, y, u, g / f7 i0 N* a6 `; m+ o( A) ~: w . Z7 j. h2 k; O可以看到,贷款金额也都在10w~100w之内。 6 f+ Y8 m* J5 `8 D) l& a6 W4 U+ \7 z
5 W. I3 P" b' v+ |/ o* K问题三* W5 F+ H5 }5 T& j; _: |
这一问,我们做得有些匆忙了,有其他想法的可以按照自己的想法做做,这里只拿我们的做参照。9 e4 u. o0 y! K9 Q) e" l7 `