原创声明:未经作者允许,不得转载
免费条件:粉丝数、获赞数、收藏数,三者其一超过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')
根据上述分析,我们把股票根据单价划分为以下几种:
X
≤
20
X\leq20
X≤20、
20
<
X
≤
40
20\lt X \leq40
20<X≤40、
40
<
X
≤
60
40\lt X \leq60
40<X≤60、
60
<
X
≤
80
60\lt X \leq80
60<X≤80、
80
<
X
≤
150
80\lt X \leq150
80<X≤150、
150
<
X
≤
600
150\lt X \leq600
150<X≤600、
600
<
X
600\lt X
600<X。我们利用余弦相似性来计算公司之间的资产配置策略的相似度。我们定义一个向量,大小为7。每一位表示一种股票,每一位的值表示购买该种股票的数量,如:
v
=
[
1
,
2
,
3
,
4
,
5
,
6.7
]
v=[1,2,3,4,5,6.7]
v=[1,2,3,4,5,6.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')