原創聲明:未經作者允許,不得轉載
免費條件:粉絲數、獲贊數、收藏數,三者其一超過500 |
題目來源:2020年_51數學建模_B題 (暫時只更到問題1)
該題是個組合優化問題。老規矩,先上一張問題1的結果圖。
1. 問題1解析
附件1給出了各公司購買的股票信息:持股總市值和持股總量。由兩個數據我們可以計算出每種股票的單價。問題1要求10家公司之間的資產配置策略的相似性,這個相似性就是公司購買了哪種哪種股票,每種股票購買了多少。公司購買了多少某種股票,這就是附件1中的持股總量。那麼,公司購買了哪種哪種股票,這該怎麼判斷呢?
我們的思路是根據股票的單價,把所有股票劃分爲不同類型。在劃分前,我們先利用箱圖看下所有股票的單價分佈情況,如圖2所示。
下面是圖2的實現代碼。
# -*- coding: utf-8 -*-
import pandas as pd
import matplotlib.pyplot as plt
from collections import Counter
import numpy as np
from scipy.spatial.distance import pdist
import seaborn as sns
file_path = r'G:\數學建模\題目及原數據\五一數學建模\2020\2020_51MCM_B題\附件1.xlsx'
data = pd.read_excel(file_path)
data['股價'] = data['持股總市值(萬元)'] / data['持股總量(萬股)']
dic = dict()
for company_name in Counter(data['公司名稱']).keys():
lst = data[data['公司名稱'] == company_name]['股價'].tolist()
dic[company_name[-1]] = lst
df = pd.DataFrame(dic)
plt.subplot(121)
df.boxplot()
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.grid(linestyle="--", alpha=0.3)
plt.title('各公司購買股票類型分析')
plt.ylabel('股價(單位:元)')
stock_name_lst = []
for stock_name in Counter(data['股票名稱']).keys():
stock_name_lst.append(data[data['股票名稱'] == stock_name]['股價'].mean())
plt.subplot(122)
plt.boxplot(stock_name_lst)
plt.grid(linestyle="--", alpha=0.3)
plt.ylabel('股價(單位:元)')
plt.title('股票單價分佈')
# plt.show()
plt.savefig(r'C:\Users\Desktop\tt.png')
根據上述分析,我們把股票根據單價劃分爲以下幾種:、、、、、、。我們利用餘弦相似性來計算公司之間的資產配置策略的相似度。我們定義一個向量,大小爲7。每一位表示一種股票,每一位的值表示購買該種股票的數量,如:,他表示第一種股票購買的數量爲1,第二種股票購買的數量爲2,依次類推。最後,我們用熱力圖來呈現結果,如圖1所示。
該部分的實現代碼如下。
# -*- coding: utf-8 -*-
import pandas as pd
import matplotlib.pyplot as plt
from collections import Counter
import numpy as np
from scipy.spatial.distance import pdist
import seaborn as sns
file_path = r'G:\數學建模\題目及原數據\五一數學建模\2020\2020_51MCM_B題\附件1.xlsx'
data = pd.read_excel(file_path)
data['股價'] = data['持股總市值(萬元)'] / data['持股總量(萬股)']
price_lst = [20, 40, 60, 80, 150, 600]
asset_allocation_dic = dict()
for company_name in Counter(data['公司名稱']).keys():
info_lst = [0] * 7 # 資產配置信息
df_tmp = data[data['公司名稱'] == company_name]
for i in range(len(info_lst)):
if i == 0:
info_lst[i] = df_tmp[df_tmp['股價'] <= 20]['持股總量(萬股)'].sum()
elif i == 1:
info_lst[i] = df_tmp[(df_tmp['股價'] > price_lst[i - 1]) & (df_tmp['股價'] <= price_lst[i])]['持股總量(萬股)'].sum()
elif i == 6:
info_lst[i] = df_tmp[df_tmp['股價'] > 600]['持股總量(萬股)'].sum()
asset_allocation_dic[company_name] = info_lst
# 計算相似性
similarity_arr = np.zeros((10, 10))
company_name_lst = list(Counter(data['公司名稱']).keys())
print(company_name_lst)
for i in range(10):
for j in range(10):
v1 = asset_allocation_dic[company_name_lst[i]]
v2 = asset_allocation_dic[company_name_lst[j]]
similarity_arr[i][j] = 1 - pdist(np.vstack([v1, v2]), 'cosine')
# 畫圖
plt.figure()
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
ax = sns.heatmap(similarity_arr, cmap='Reds')
plt.title('10家基金公司之間資產配置策略的相似性', size=16)
plt.xlabel('公司名稱')
plt.ylabel('公司名稱')
# plt.show()
plt.savefig(r'C:\Users\10102\Desktop\tt.png')