2020全國大學生數學建模C題中小微企業的信貸決策隨機森林代碼


  2020全國大學生數學建模C題中小微企業的信貸決策(含隨機森林代碼)

  某銀行對確定要放貸企業的貸款額度為10~100萬元;年利率為4%~15%;貸款期限為1年。附件1~3 分別給出了123家有信貸記錄企業的相關數據、302家無信貸記錄企業的相關數據和貸款利率與客戶流失率關系的2019年統計數據。我們團隊需根據實際和附件中的數據信息,通過建立數學模型研究對中小微企業的信貸策略,主要幫助銀行解決下列問題:

  (1) 對附件1中123家企業的信貸風險進行量化分析,給出該銀行在年度信貸總額固定時對這些企業的信貸策略。

  (2) 在問題1的基礎上,對附件2中302家企業的信貸風險進行量化分析,並給出該銀行在年度信貸總額為1億元時對這些企業的信貸策略。

  (3) 企業的生產經營和經濟效益可能會受到一些突發因素影響,而且突發因素往往對不同行業的企業會有不同的影響。綜合考慮附件2中各企業的信貸風險和可能的突發因素對各企業的影響,給出該銀行在年度信貸總額為1億元時的信貸調整策略。

一、問題的分析

       綜合考慮附件2中各企業的信貸風險和新冠疫情對各企業的影響,我們首先對企業名稱做文本分析,根據詞頻統計結果,選取了勞務、工程建築業、文化等九個行業類別。其次,我們通過國家數據網,收集了2020年第二季度各行業GDP與上一年的同期增長率,對在突發事件下的風險值進行了修正和歸一化處理,建立並求解信貸策略的非線性規划模型,最終給出了該銀行在年度信貸總額為1億元時的信貸策略,其中銀行所獲最大利潤為232.3474萬元。此問題綜合考慮附件2中各企業的信貸風險和新冠疫情這一突發因素對各行業企業GDP的影響,首先對企業名稱進行文本分析,在統計出附件中出現頻率較高的企業類別之后,結合2020年第二季度企業GDP與上一年的同期增長率得出一個修正后的風險值 ,將其標准化后再代入信貸策略規划模型,從而給出該銀行在年度信貸總額為1億元時的信貸調整策略。

二、問題假設

  1、假設信貸風險率 與所選指標 有關;

  2、在這段時間內不考慮經濟波動;

  3、假設數據來源於隨機樣本;

  4、假設有 個 , 因素影響 的取值;

  5、因變量Y是分類變量,一般為二分類變量,我們研究的目的是在X事件發生時Y取值的條件概率。

三、隨機森林

       隨機森林是一種集成機器學習方法,它利用隨機重采樣技術和節點隨機分裂技術構建多棵決策樹,通過投票得到最終分類結果。隨機森林具有分析復雜相互作用分類特征的能力,對於噪聲數據和存在缺失值的數據具有較強魯棒性,其學習速度較快,且不容易出現過擬合。


       隨機森林機器學習模型選取自助法(bootstrap)進行數據集的提取,即對於每棵樹而言,隨機且有放回地從規模為n的訓練集中的抽取n個進行訓練;RF模型在抽樣的基礎上構造出Bagging算法,這種方法將訓練集分成m個,然后在每個新訓練集上構建一個模型,各自不相干,最后預測結果為這m個模型結果的整合(如圖所示)。

 

  我們選擇包含眾多機器學習模型的Sklearn第三方模塊實現隨機森林模型的構建與訓練。模型構建過程如下圖

 

 

  在機器學習模型中,當模型復雜度不足時,機器學習程度不足,會出現欠擬合現象;當復雜度逐漸提高到最佳模型復雜度時,將會達到最高准確度;當復雜度仍在提高,將會出現過擬合現象。因此,我們通過不斷調節模型中的參數來提高訓練准確度,使其盡可能地接近泛化誤差最低點。隨機森林模型主要的參數有n_estimators(子樹的數量)和max_depth(樹的最大生長深度),我們通過超參數搜索,最終確定使用n_estimators=30,max_depth=16的參數設置來預測“信譽評級”,n_estimators=30,max_depth=11來預測“是否違約”,最終訓練達到了45%與85%左右的測試集與驗證集准確率。

 

python代碼(所使用的數據、及調用的文件均來自賽題)

sort.py文件(數據的預處理)處理后的文件用spss擬合

 1 import pandas as pd
 2 from pandas import DataFrame
 3 
 4 #篩選無效發票
 5 def ticket():
 6     data = pd.read_excel('C:/Users/yzj/Desktop/信貸風險值.xlsx', sheet_name="Sheet3")# 讀取文件附件2:302家無信貸記錄企業的相關數據
 7     data = data[~data['發票狀態'].isin(['有效發票'])]   #刪除作廢發票
 8 
 9 DataFrame(data).to_excel('C:/Users/yzj/Desktop/信貸風險值.xlsx', index=False, header=True)
10 
11 #讀取金額信息
12 def money():
13 df=pd.read_excel("C:/Users/yzj/Desktop/第二題數據/進項有效發票.xlsx")  # 讀取每一個公司信息
14 print(df.groupby('企業代號')[['金額','稅額','價稅合計']].sum())
15 d=df.groupby('企業代號')[['金額','稅額','價稅合計']].sum()
16 d.to_csv("C:/Users/yzj/Desktop/第二題數據/進項金額稅額.csv",encoding='utf-8-sig',index=False, header=True)
17 
18 #統計日期
19 def data():
20 df=pd.read_excel("C:/Users/yzj/Desktop/第二題數據/進項有效發票.xlsx" )  # 讀取每一個公司信息
21 d=df.groupby('企業代號')[['開票日期']].nunique()
22 print(df.groupby('企業代號')[['開票日期']].nunique())
23 #d.to_csv("C:/Users/yzj/Desktop/第二題數據/銷項日期.csv",encoding='utf-8-sig',index=False, header=True)
24 d.to_csv("C:/Users/yzj/Desktop/第二題數據/進項日期.csv",encoding='utf-8-sig',index=False, header=True)
25 
26 def obj():
27     df=pd.read_excel("C:/Users/yzj/Desktop/第二題數據/銷項有效發票.xlsx" )  # 讀取每一個公司信息
28 #df=pd.read_excel("C:/Users/yzj/Desktop/第二題數據/進項有效發票.xlsx" )  # 讀取每一個公司信息
29 d=df.groupby('企業代號')[['購方單位代號']].nunique()
30 print(df.groupby('企業代號')[['購方單位代號']].nunique())
31 d.to_csv("C:/Users/yzj/Desktop/第二題數據/銷項供應商.csv",encoding='utf-8-sig',index=False, header=True)
32 
33 #統計發票狀態數量
34 def ticket_state():
35     df=pd.read_excel("C:/Users/yzj/Desktop/第二題數據/進項有效發票.xlsx" )  # 讀取每一個公司信息
36 d=df.groupby('企業代號')['發票狀態'].value_counts()
37 print(df.groupby('企業代號')['發票狀態'].value_counts())
38 
39 #統計發票總數
40 def ticket_count():
41 pd.set_option('display.max_rows', 500)
42 pd.set_option('display.max_columns', 100)
43 pd.set_option('display.width', 1000)
44     df=pd.read_excel("C:/Users/yzj/Desktop/第二題數據/銷項有效發票.xlsx")  # 讀取每一個公司信息
45 #df=pd.read_excel("C:/Users/yzj/Desktop/第二題數據/進項有效發票.xlsx")  # 讀取每一個公司信息
46 d=df.groupby('企業代號')['發票狀態'].value_counts()
47 print(df.groupby('企業代號')['發票狀態'].value_counts())
48 d.to_csv("C:/Users/yzj/Desktop/第二題數據/銷項有效發票總數.csv",encoding='utf-8-sig',index=False, header=True)

RF.py文件(隨機森林代碼)選取某些參數最為評定標准,預測信譽值

 1 #隨機森林 預測信譽值ABCD違約行為
 2 import pandas as pd
 3 from sklearn.externalsimport joblib
 4 from sklearn.feature_extractionimport DictVectorizer
 5 from sklearn.model_selectionimport train_test_split
 6 from sklearn.ensembleimport RandomForestClassifier
 7 from sklearn.model_selectionimport GridSearchCV
 8 
 9 def forest():
10 # 加載數據
11 firm= pd.read_excel("C:/Users/yzj/Desktop/國賽/C/問題一總表1.xlsx")
12 # 構造特征值和目標值
13 feature = firm[["進項發票有效率", "銷項發票有效率","總銷方數","總售方數",”進項年平均價稅總額”,”銷項年平均價稅總額”]]
14     target = firm["信譽評級"]
15 #target = titan["是否違約"]
16     # 特征預處理
17 # 查看有沒有缺失值
18 print(pd.isnull(feature).any())
19 # 划分數據集
20 x_train, x_test, y_train, y_test = train_test_split(feature, target, test_size=0.25)
21 print("訓練集:", x_train.shape, y_train.shape)
22 print("測試集:", x_test.shape, y_test.shape)
23 # 建立模型
24 rf = RandomForestClassifier()
25 # 超參數搜索
26 param = {"n_estimators":range(20,100,10), "max_depth":range(1,50,5)}
27 model = GridSearchCV(rf, param_grid=param, cv=10)
28 # 訓練
29 model.fit(x_train, y_train)
30 print("測試集准確率:", model.score(x_test, y_test))
31 print("驗證集准確率:", model.best_score_)
32 print("最好模型參數:", model.best_params_)
33 print("最好模型模型:", model.best_estimator_)
34 #保存模型
35 joblib.dump(model, 'C:/Users/yzj/Desktop/第二題數據/model_level_change.pkl')
36 #joblib.dump(model, 'C:/Users/yzj/Desktop/第二題數據/model_obey_change.pkl')
37 def test():
38 #引入測試數據
39 df = pd.read_excel("C:/Users/yzj/Desktop/第二題數據/問題二總表1.xlsx")
40 #數據預處理
41 X = df.drop(['是否違約'], axis=1)
42 #導入模型
43 clf = joblib.load("C:/Users/yzj/Desktop/第二題數據/model_level_change.pkl")
44 namelist = []
45 #得到預測目標值
46 tolist = clf.predict(X)
47 for iin tolist:
48 namelist.append(i)
49 #對目標值列進行賦值
50 df['信譽評級'] = namelist
51 df.to_csv("C:/Users/yzj/Desktop/第二題數據/model_level_change.csv", encoding='utf-8')
52 print(tolist)

Statistics.py文件(一個詞雲圖的代碼)為了論文更直觀、好看做的一個

 1 import pandas as pd
 2 # 導入擴展庫
 3 import re # 正則表達式庫
 4 import collections # 詞頻統計庫
 5 import wordcloud# 詞雲展示庫
 6 from PIL import Image # 圖像處理庫
 7 import matplotlib.pyplotas plt# 圖像展示庫
 8 import numpyas np
 9 import jieba
10 import jieba
11 import re
12 import collections
13 from wordcloudimport WordCloud, STOPWORDS, ImageColorGenerator
14 from PIL import Image
15 import matplotlib.pyplotas plt
16 from pandas import DataFrame
17 
18 corpus = pd.read_excel('C:/Users/yzj/Desktop/國賽/C/附件2:302家無信貸記錄企業的相關數據.xlsx') # 得到DataFrame
19 corpus = np.array(corpus)  # 轉換為ndarray [[1], [2], [3]]
20 #print(corpus)
21 corpus = corpus.reshape(1, len(corpus)).tolist()  # 轉換成 List [[1, 2, 3]]
22 corpus = corpus[0]  # 取第一個元素得到最終結果 [1, 2, 3]
23 print(corpus)
24 object_list = []
25 for iin range(len(corpus)):
26     text = corpus[i]
27 for chin text:
28 if ch<='9'and ch>='0':
29             text = text.replace(ch, " ")
30 if ch<='Z'andch>='A':
31             text = text.replace(ch, " ")
32 
33 #remove_words = ['','公司','有限','有限公司','經營','個體','個體經營','有限責任',
34     #                '責任','*','經營部','營部','設備','管理','技術','咨詢','建築工程','建設工程']  # 自定義去除詞庫
35 remove_words = ['', '公司', '有限', '經營', '個體',
36 '責任', '*', '經營部', '營部', '建築工程', '建設工程']  # 自定義去除詞庫
37 
38 #得到所有單詞
39 words = jieba.cut(text,cut_all=True)
40 space_wordlist = ""
41 
42 for word in words:
43 if word not in remove_words:
44 object_list.append(word)
45 space_wordlist = word+space_wordlist
46 
47 #統計詞頻
48 word_counts = collections.Counter(object_list) # 對分詞做詞頻統計
49 word_counts_top15 = word_counts.most_common(15) # 獲取前10最高頻的詞
50 print (word_counts_top15) # 輸出檢查
51 
52 # 詞頻展示
53 #mask = np.array(Image.open('C:/Users/yzj/Desktop/wordcloud.jpg')) # 定義詞頻背景
54 wc = wordcloud.WordCloud(
55 font_path='C:/Windows/Fonts/simhei.ttf', # 設置字體格式
56 #mask=mask, # 設置背景圖
57 #max_words=88, # 最多顯示詞數
58 #max_font_size=100, # 字體最大值
59 background_color= 'white',
60 margin=2
61 )
62 
63 wc.generate_from_frequencies(word_counts) # 從字典生成詞雲
64 plt.imshow(wc) # 顯示詞雲
65 plt.axis('off') # 關閉坐標軸
66 plt.savefig('C:/Users/yzj/Desktop/test5.png')
67 plt.show() # 顯示圖像

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM