2024年美国大学生数学建模竞赛(C题) 建模解析,小鹿学长带队指引全代码文章与思路
数字商品 教育 / 知识

2024年美国大学生数学建模竞赛(C题) 建模解析,小鹿学长带队指引全代码文章与思路

小鹿学长与Tech · 2 · 0

商品介绍
我是小鹿学长,就读于上海交通大学,截至目前已经帮200+人完成了建模与思路的构建的处理了~
这回带大家体验一下2024年美国大学生数学建模竞赛呀!

我是小鹿学长,就读于上海交通大学,截至目前已经帮200+人完成了建模与思路的构建的处理了~
探寻网球比赛中的“动量”奥秘!鹿鹿学长独辟蹊径,运用强化学习与时间序列分析相结合,以DQN和Monte Carlo模拟实现对比赛动态的准确预测。进一步,学长运用决策树探讨比赛流动的相关因素,为球员提供独到的建议。这一创新思路不仅在解决问题上独具匠心,更将“动量”概念深入挖掘,成就了一场挑战性十足的数学盛宴!
## 问题重述
需要解决的问题可以分为以下几个点:
 
1. **模型开发和应用:**
  - 开发一个模型,能够捕捉比赛中的动态变化。
  - 将模型应用于一个或多个比赛,以确定在比赛的特定时间点,哪位球员表现更好,以及他们的相对表现水平。
  - 考虑发球球员有更高的赢得点/比赛概率,并在模型中纳入这一因素。
  - 提供基于模型的可视化,描述比赛的流程。
 
2. **动量的评估:**
  - 通过模型和指标来评估网球教练对于“动量”在比赛中是否起作用的怀疑。
  - 考察球员表现的波动和成功的连续是否具有随机性。
 
3. **指示比赛流动变化的指标:**
  - 使用提供的数据,开发一个模型来预测比赛中的流动变化。
  - 确定哪些因素与比赛流动的变化最相关。
 
4. **球员准备和建议:**
  - 鉴于过去比赛中“动量”波动的差异,提供建议,指导球员在与不同球员进行新比赛时的准备。
 
5. **模型通用性测试:**
  - 将开发的模型测试在其他比赛上,评估其对比赛流动的准确性和通用性。
  - 确定模型在不同比赛、锦标赛、场地类型和其他运动(如乒乓球)中的适用性。
 
6. **解决方案撰写和结论:**
  - 撰写不超过25页的解决方案报告,包括总结表、目录、完整解决方案、一至两页备忘录和参考文献列表。
  - 提供一份AI使用报告,符合COMAP的AI使用政策。
 
## 问题一
### 问题一的建模思路:使用深度强化学习(DQN)
 
#### 1. 定义状态(State):
  - **状态表示:** 设计一个状态向量 $s$,包含比赛中的关键信息,如球员得分、局数、集数、发球情况等。 
  - **状态空间:** 定义状态向量中各个元素的可能取值范围。
 
#### 2. 定义动作(Action):
  - **动作表示:** 确定球员在每个状态下可以采取的动作,例如击球的类型、方向等。 
  - **动作空间:** 规定动作的可能取值范围。
 
#### 3. 定义奖励(Reward):
  - **奖励函数:** 设计一个奖励函数 $R(s, a)$,用于评估球员在每个时间点采取某个动作后的效果。奖励可以基于得分情况、局数、集数等来定义。 
  - **目标:** 确定学习的目标,例如在比赛中获取更多的得分或赢得更多的局。
 
#### 4. 构建深度强化学习模型:
  - **定义神经网络结构:** 构建深度神经网络,该网络接收状态作为输入,输出每个可能动作的 Q 值。 
  - **Q 值公式(Q-function):** 使用 Q-learning 的公式来计算 Q 值。
     $$Q(s, a) = (1 - \alpha) \cdot Q(s, a) + \alpha \cdot \left( R(s, a) + \gamma \cdot \max_{a'} Q(s', a') \right)$$
     其中,$Q(s, a)$ 是动作 $a$ 在状态 $s$ 下的 Q 值,$\alpha$ 是学习率,$\gamma$ 是折扣因子,$s'$ 是下一个状态。
 
#### 5. 训练模型:
  - **经验回放(Experience Replay):** 使用经验回放机制,存储并从历史经验中随机抽样进行训练,以打破样本间的相关性。 
  - **固定目标网络(Fixed Target Network):** 使用两个神经网络,一个用于训练,另一个用于计算目标 Q 值,定期更新目标网络的参数。
 
#### 6. 学习最优策略:
  - **探索和利用:** 使用 ε-贪心策略,平衡探索和利用,使模型在学习过程中不断尝试新的动作。 
  - **学习最优策略:** 通过不断迭代更新神经网络的参数,使模型学到一个最优的动作选择策略。
 
#### 7. 模型应用:
  - **测试和预测:** 在实际比赛中,根据学到的 Q 值,选择具有最高 Q 值的动作,以预测球员在每个时间点的表现。
 
```python
import numpy as np
import tensorflow as tf
 
# 定义深度强化学习模型
class DQN(tf.keras.Model):
   def __init__(self, num_actions):
       super(DQN, self).__init__()
       self.dense1 = tf.keras.layers.Dense(128, activation='relu')
       self.dense2 = tf.keras.layers.Dense(64, activation='relu')
       self.output_layer = tf.keras.layers.Dense(num_actions, activation='linear')
 
   def call(self, state):
       x = self.dense1(state)
       x = self.dense2(x)
       return self.output_layer(x)
 
# 定义经验回放缓冲区
class ReplayBuffer:
   def __init__(self, buffer_size):
       self.buffer_size = buffer_size
       self.buffer = []
 
   def add_experience(self, experience):
       if len(self.buffer) >= self.buffer_size:
           self.buffer.pop(0)
       self.buffer.append(experience)
 
   def sample_batch(self, batch_size):
       indices = np.random.choice(len(self.buffer), batch_size, replace=False)
       return [self.buffer[i] for i in indices]
 
# 定义DQN算法
class DQNAgent:
   def __init__(self, num_actions, buffer_size=10000, batch_size=32, gamma=0.99, epsilon=1.0, epsilon_decay=0.995):
       self.num_actions = num_actions
       self.gamma = gamma
       self.epsilon = epsilon
       self.epsilon_decay = epsilon_decay
       self.buffer = ReplayBuffer(buffer_size)
       self.batch_size = batch_size
 
       # 创建DQN模型
       self.model = DQN(num_actions)
       self.target_model = DQN(num_actions)
       self.target_model.set_weights(self.model.get_weights())
 
       # 定义优化器和损失函数
       self.optimizer = tf.keras.optimizers.Adam(learning_rate=0.001)
       self.loss_fn = tf.keras.losses.MeanSquaredError()
 
   #见完整代码
 
       # 计算目标Q值
       target_q_values = self.target_model.predict(next_states)
       max_q_values = np.max(target_q_values, axis=1)
       target_q = rewards + (1 - dones) * self.gamma * max_q_values
 
       # 计算当前Q值
       with tf.GradientTape() as tape:
           q_values = self.model(states, training=True)
           selected_q_values = tf.reduce_sum(tf.one_hot(actions, self.num_actions) * q_values, axis=1)
           loss = self.loss_fn(target_q, selected_q_values)
 
       # 更新模型参数
       gradients = tape.gradient(loss, self.model.trainable_variables)
       self.optimizer.apply_gradients(zip(gradients, self.model.trainable_variables))
 
       # 更新epsilon
       self.epsilon *= self.epsilon_decay
 
   def update_target_model(self):
       self.target_model.set_weights(self.model.get_weights())
 
# 示例使用
# 初始化DQNAgent
num_actions = 3 # 假设有3个动作
agent = DQNAgent(num_actions=num_actions)
 
# 训练模型
for episode in range(1000):
   state = env.reset()
   total_reward = 0
 
   for step in range(100):
       action = agent.select_action(state)
       next_state, reward, done, _ = env.step(action)
       agent.buffer.add_experience((state, action, reward, next_state, done))
       agent.train()
 
       total_reward += reward
       state = next_state
 
       if done:
           break
 
   agent.update_target_model()
 
```
 
问题一可以使用图表来展示比赛中不同阶段球员表现的得分情况,以及通过建立的深度强化学习模型对比赛状态的预测。以下是使用Python中的Matplotlib库绘制简单图表的示例代码:
 
```python
import matplotlib.pyplot as plt
 
# 示例数据(替换为实际数据)
match_points = [1, 2, 3, 4, 5]
player1_scores = [0, 15, 30, 40, 45]
player2_scores = [0, 15, 30, 40, 40]
 
# 绘制比赛得分变化图
plt.figure(figsize=(10, 6))
plt.plot(match_points, player1_scores, label='Player 1')
plt.plot(match_points, player2_scores, label='Player 2')
plt.xlabel('Match Points')
plt.ylabel('Scores')
plt.title('Match Scores Over Time')
plt.legend()
plt.grid(True)
plt.show()
```
 
这段代码将创建一个简单的线图,显示比赛不同阶段两名球员的得分情况。你可以根据实际数据进行修改。
 
另外,你还可以使用图表来展示深度强化学习模型在比赛中预测的状态变化。以下是一个简单的示例代码:
 
```python
import numpy as np
 
# 示例数据(替换为实际数据)
predicted_scores = np.array([0.1, 0.2, 0.8, 0.9, 0.7]) # 模型预测的得分概率
 
# 绘制模型预测图
plt.figure(figsize=(10, 6))
plt.plot(match_points, predicted_scores, label='Predicted Scores', marker='o')
plt.xlabel('Match Points')
plt.ylabel('Predicted Scores Probability')
plt.title('Model Predictions Over Time')
plt.legend()
plt.grid(True)
plt.show()
```
 
这段代码创建了一个图表,显示模型在比赛中不同阶段的预测得分概率。你可以通过实际模型输出的数据来替换 `predicted_scores` 数组。
 
 
  ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/62a282b4511248a2a90af5814a250b56.png#pic_center)
 
## 问题二
 **动量的评估:**
  - 通过模型和指标来评估网球教练对于“动量”在比赛中是否起作用的怀疑。
  - 考察球员表现的波动和成功的连续是否具有随机性
  
**问题二的建模思路:**
 
时间序列分析: 使用时间序列分析来检查球员得分的趋势和周期性。这可以通过自相关函数(ACF)和偏自相关函数(PACF)来实现,以识别得分之间的相关性。如果存在显著的自相关性,可能表示动量或其他因素在比赛中产生了影响。
 
Monte Carlo 模拟: 使用Monte Carlo模拟来模拟比赛中的随机性。通过生成大量的模拟比赛数据,可以比较实际观察到的得分变化是否与随机模拟的数据有显著差异。这有助于评估球员得分波动是否超出了随机性的范围。
**问题二的解决方法详解:**
 
1. **时间序列分析:**
 
  - **目标:** 检查球员得分的趋势和周期性,以评估动量是否在比赛中产生影响。
  
  - **步骤:**
  
     a. 使用历史比赛数据,创建每个球员的得分时间序列。
  
     b. 绘制得分时间序列图,直观地观察得分的变化趋势。
  
     c. 计算自相关函数(ACF)和偏自相关函数(PACF),以识别得分之间的相关性。
  
     d. 分析自相关函数和偏自相关函数的图形,判断是否存在显著的自相关性,进而判断是否存在动量效应。
 
  - **具体公式:**
  
     - ACF:$$ACF(k) = \frac{\sum_{t=k+1}^{T}(y_t - \bar{y})(y_{t-k} - \bar{y})}{\sum_{t=1}^{T}(y_t - \bar{y})^2}$$
  
     - PACF:$$PACF(k) = \frac{\text{Cov}(y_t, y_{t-k} | y_{t-1}, y_{t-2}, ..., y_{t-k+1})}{\text{Var}(y_t | y_{t-1}, y_{t-2}, ..., y_{t-k+1})}$$
 
  - **分析和结论:**
  
     - 如果ACF和PACF显示出明显的周期性或趋势,可能表明球员得分受到动量的影响。
  
     - 可以使用统计显著性检验来验证结论的可靠性。
 
2. **Monte Carlo 模拟:**
 
  - **目标:** 通过模拟比赛数据,比较实际观察到的得分变化和随机模拟的得分变化,以评估得分波动是否超过了随机性的范围。
  
  - **步骤:**
  
     a. 针对每场比赛,使用随机生成的得分数据进行Monte Carlo模拟,模拟多次比赛。
  
     b. 对每次模拟比赛,计算得分的统计量,如均值、标准差等。
  
     c. 将实际观察到的得分统计量与模拟数据的分布进行比较。
  
     d. 通过统计检验(如Z检验)评估实际得分表现是否显著。
 
  - **具体公式:**
  
     - 无特定公式,主要使用统计量(均值、标准差)进行比较和检验。
 
  - **分析和结论:**
  
     - 如果实际得分的统计量在模拟数据中是显著的,可能表明动量或其他因素在比赛中产生了影响。
  
     - 可以使用统计检验验证结果的可靠性。
 
**综合分析和结论:**
 
通过综合时间序列分析和Monte Carlo 模拟的结果,可以对动量在比赛中的作用进行全面评估。如果两种方法都表明动量在比赛中具有显著影响,那么可以得出结论支持教练的观点。反之,如果结果不一致,可能需要进一步深入研究或考虑其他因素。
 
在报告中,可以呈现每个步骤的详细分析、图表和结果,以及最终的结论。这样的结构有助于读者理解解决问题的过程和依据。
 
```python
import pandas as pd
import statsmodels.api as sm
import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
 
# 读取数据
data = pd.read_csv('wimbledon_data.csv')
 
# 1. 时间序列分析
def time_series_analysis(player_scores):
   # 绘制得分时间序列图
   plt.plot(player_scores, label='Player Scores')
   plt.legend()
   plt.show()
 
   # 计算ACF和PACF
   acf_result = sm.tsa.acf(player_scores, fft=False)
   pacf_result = sm.tsa.pacf(player_scores)
 
   # 可视化ACF和PACF
   plt.subplot(121)
   plt.stem(acf_result)
   plt.title('ACF for Player Scores')
 
   plt.subplot(122)
   plt.stem(pacf_result)
   plt.title('PACF for Player Scores')
 
   plt.show()
 
# 假设Player1是我们关注的球员
player1_scores = data[data['player'] == 'Player1']['scores']
time_series_analysis(player1_scores)
 
# 2. Monte Carlo 模拟
def monte_carlo_simulation(observed_scores, num_simulations):
   simulated_scores = np.random.normal(np.mean(observed_scores), np.std(observed_scores), num_simulations)
   return simulated_scores
 
# 模拟比赛数据
simulated_player1_scores = monte_carlo_simulation(player1_scores, 1000)
 
# 比较实际观察到的得分和模拟数据
#见完整版
 
# 统计检验(这里简化为 t 检验)
t_statistic, p_value = stats.ttest_ind(player1_scores, simulated_player1_scores)
 
print(f'Observed Mean: {observed_mean_player1}, Simulated Mean: {mean_simulated_player1}')
print(f'Observed Std: {observed_std_player1}, Simulated Std: {std_simulated_player1}')
print(f'T-statistic: {t_statistic}, P-value: {p_value}')
 
```
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/b1adad02e286424b84fbd45ab083caa0.png#pic_center)
问题二涉及对动量的评估,可以使用多种图表来可视化数据以及模型结果。以下是一些可能有用的图表示例及其对应的代码:
 
1. **比赛得分趋势图:**
  - 可以绘制比赛中两位球员的得分情况,以展示比赛的走势。
 
```python
import matplotlib.pyplot as plt
 
# 绘制比赛得分趋势图
def plot_score_trend(player1_scores, player2_scores):
   plt.plot(player1_scores, label='Player 1 Scores')
   plt.plot(player2_scores, label='Player 2 Scores')
   plt.xlabel('Point Number')
   plt.ylabel('Score')
   plt.title('Match Score Trend')
   plt.legend()
   plt.show()
 
# 使用示例数据调用函数
plot_score_trend(player1_scores, player2_scores)
```
 
2. **动量变化图:**
  - 可以通过绘制球员得分的差异来展示动量的变化。
 
```python
# 绘制动量变化图
def plot_momentum(player1_scores, player2_scores):
   momentum = player1_scores - player2_scores
   plt.plot(momentum)
   plt.xlabel('Point Number')
   plt.ylabel('Momentum (Player1 - Player2)')
   plt.title('Momentum Change')
   plt.axhline(y=0, color='k', linestyle='--') # 添加水平参考线表示平衡点
   plt.show()
 
# 使用示例数据调用函数
plot_momentum(player1_scores, player2_scores)
```
 
3. **Monte Carlo 模拟结果图:**
  - 可以绘制模拟的比赛结果分布图,以及实际比赛结果在模拟结果中的位置。
 
```python
# 绘制Monte Carlo 模拟结果图
def plot_monte_carlo(simulated_scores, observed_score):
   plt.hist(simulated_scores, bins=30, alpha=0.5, label='Simulated Scores')
   plt.axvline(x=observed_score, color='r', linestyle='--', label='Observed Score')
   plt.xlabel('Score')
   plt.ylabel('Frequency')
   plt.title('Monte Carlo Simulation Results')
   plt.legend()
   plt.show()
 
# 使用示例数据调用函数
plot_monte_carlo(simulated_player1_scores, observed_mean_player1)
```
 
这些图表可以帮助评估比赛中的动量变化和模拟结果与实际观察结果之间的关系。
## 问题三
决策树是一种强大的机器学习算法,适用于分类和回归问题。在这里,我们将使用决策树来解决问题三,即预测比赛中的流动变化。以下是具体的思路:
 
### 决策树建模思路:
 
1. **特征选择:** 从提供的数据中选择与比赛流动变化相关的特征。这些特征可以包括球员的得分、比赛进行的轮次、发球的次数、比赛时间等。
 
2. **数据准备:** 将数据划分为训练集和测试集,确保在训练模型时使用独立的数据进行评估。
 
3. **特征工程:** 创建新的特征,例如每局比赛的平均得分、发球成功率等,以增强模型的表现。
 
4. **构建决策树模型:** 使用训练集构建决策树模型。决策树将学习如何根据特征预测比赛流动的变化。
 
5. **模型评估:** 使用测试集对模型进行评估,考察其在未见过的数据上的性能。
 
6. **可视化决策树:** 可视化生成的决策树,以便更好地理解模型的决策过程。
 
### 代码示例:
 
下面是一个简化的 Python 代码示例,使用决策树回归模型:
 
```python
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeRegressor
from sklearn.metrics import mean_squared_error
from sklearn.tree import export_text
 
# 读取数据
data = pd.read_csv('wimbledon_data.csv')
 
# 特征选择
features = ['player1_score', 'player2_score', 'round', 'serve_count', 'match_time']
 
# 数据准备
X = data[features]
y = data['match_flow']
 
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
 
# 创建决策树回归模型
model = DecisionTreeRegressor()
 
# 训练模型
model.fit(X_train, y_train)
 
# 预测
y_pred = model.predict(X_test)
 
# 模型评估
mse = mean_squared_error(y_test, y_pred)
print(f'Mean Squared Error: {mse}')
 
# 可视化决策树
tree_rules = export_text(model, feature_names=features)
print('Decision Tree Rules:')
print(tree_rules)
```
 
问题三的目标是预测比赛中的流动变化。为了可视化模型的性能,可以使用以下图表:
 
1. **实际 vs. 预测图:** 将实际比赛流动变化和模型预测的流动变化进行对比,以直观地了解模型的准确性。
 
2. **残差图:** 绘制实际比赛流动变化与模型预测之间的残差,以查看模型是否在某些情况下存在系统性的预测误差。
 
以下是用于绘制这两种图表的简单 Python 代码:
 
```python
import matplotlib.pyplot as plt
import seaborn as sns
 
# 创建实际 vs. 预测图
plt.figure(figsize=(10, 6))
plt.scatter(y_test, y_pred, alpha=0.7)
plt.title('Actual vs. Predicted Match Flow')
plt.xlabel('Actual Match Flow')
plt.ylabel('Predicted Match Flow')
plt.show()
 
# 创建残差图
residuals = y_test - y_pred
plt.figure(figsize=(10, 6))
sns.residplot(y_test, residuals, lowess=True, line_kws={'color': 'red'})
plt.title('Residuals Plot')
plt.xlabel('Actual Match Flow')
plt.ylabel('Residuals')
plt.show()
```
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/556e9d1aa3454d8081d6b94ac104d8cf.jpeg#pic_center)
 
## 问题四
问题四要解决的是根据过去比赛中的“动量”波动差异,为球员提供准备和建议。为此,我们可以使用机器学习中的分类模型。以下是使用分类模型(此处使用支持向量机 - SVM)的简化步骤:
 
### 1. 特征选择:
 
根据问题的要求,我们选择与“动量”波动差异相关的特征。特征选择的目标是找到对目标变量(这里是动量波动的分类)具有显著影响的特征。假设我们选定了球员的历史动量、对手的水平等作为特征。
 
### 2. 数据准备:
 
将数据划分为训练集和测试集。训练集用于训练模型,测试集用于评估模型的性能。这一步确保模型在未见过的数据上有良好的泛化能力。
 
### 3. 特征工程:
 
可以根据已有特征创建新的特征,以提高模型的性能。例如,可以计算球员的平均动量、对手的平均水平等。这些新特征可以通过以下公式计算:
 
$$\text{Average Momentum} = \frac{\text{Sum of Individual Momenta}}{\text{Number of Matches}}$$
 
### 4. 选择模型:
 
在这里,我们选择了支持向量机(SVM)作为分类模型。SVM通过找到能够最大化类别间间隔的超平面来进行分类。
 
### 5. 模型训练:
 
模型的训练是通过将特征输入到SVM模型中,让模型学习如何将输入映射到相应的输出(动量波动的分类)。
 
### 6. 模型评估:
 
使用测试集对模型进行评估,主要使用准确度(Accuracy)、精确度(Precision)、召回率(Recall)等指标来评价模型的性能。
 
### 7. 提供建议:
 
通过模型预测球员的动量波动分类,从而为球员提供建议。例如,如果预测为“高动量”,建议球员在比赛前做好充分准备。
 
```python
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score, classification_report
 
# 读取数据
data = pd.read_csv('wimbledon_data.csv')
 
# 特征选择
features = ['player1_history_momentum', 'player2_history_momentum', 'opponent_strength']
 
# 数据准备
X = data[features]
y = data['momentum_category'] # 'momentum_category' 是一个分类目标变量,例如低、中、高动量
 
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
 
# 创建支持向量机分类模型
model = SVC()
 
# 训练模型
model.fit(X_train, y_train)
 
# 预测
#见完整版
 
# 分类报告
print('Classification Report:\n', classification_report(y_test, y_pred))
 
# 提供建议
player1_momentum = calculate_player1_momentum() # 根据实际情况计算球员1的动量
player2_momentum = calculate_player2_momentum() # 根据实际情况计算球员2的动量
 
# 预测动量波动分类
predicted_momentum_category = model.predict([[player1_momentum, player2_momentum, opponent_strength]])
 
# 提供建议
if predicted_momentum_category == 'High':
   print("建议球员在比赛前做好充分准备,以迎接可能的高动量波动。")
elif predicted_momentum_category == 'Medium':
   print("球员准备良好,但仍需谨慎对待可能的动量波动。")
else:
   print("球员可以在比赛前轻松准备,因为预测为低动量波动。")
 
```
问题四涉及为球员提供建议,指导他们在与不同球员进行新比赛时的准备。在这种情况下,可以考虑绘制雷达图(radar chart),以可视化不同球员在关键方面的表现。
 
以下是使用Python的`matplotlib`库绘制雷达图的示例代码:
 
```python
import matplotlib.pyplot as plt
import numpy as np
 
# 假设有两名球员,每名球员在准备方面有三个关键指标
players = ['Player A', 'Player B']
indicators = ['Physical Fitness', 'Mental Focus', 'Previous Performance']
 
# 假设每个指标的得分范围为0到10,具体分数可根据实际情况调整
player_scores = np.array([[8, 9, 7], # Player A的得分
                         [6, 8, 9]]) # Player B的得分
 
# 绘制雷达图
fig, ax = plt.subplots(figsize=(8, 8), subplot_kw=dict(polar=True))
 
# 设置角度
angles = np.linspace(0, 2 * np.pi, len(indicators), endpoint=False)
 
# 将第一个指标作为初始位置
player_scores = np.concatenate((player_scores, player_scores[:, [0]]), axis=1)
angles = np.concatenate((angles, [angles[0]]))
 
# 绘制雷达图
for i in range(len(players)):
   ax.plot(angles, player_scores[i], label=players[i], linewidth=2)
 
# 填充区域
ax.fill(angles, player_scores[0], alpha=0.25)
ax.fill(angles, player_scores[1], alpha=0.25)
 
# 设置标签
ax.set_thetagrids(angles * 180/np.pi, indicators)
ax.set_title('Player Comparison for Match Preparation', size=16, y=1.1)
 
# 添加图例
ax.legend(loc='upper right', bbox_to_anchor=(0.1, 0.1))
 
# 显示雷达图
plt.show()
```
 
这个雷达图可用于比较不同球员在物理健康、心理专注和先前表现等方面的得分。球员的得分越高,表示他们在该方面的准备越充分。根据图表,球员和教练可以获得有关如何调整准备策略的洞察。
 
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/25338b4368f048a0b3ba19aad908144a.png#pic_center)
 
## 问题五
使用决策树模型进行 k 折交叉验证的建模思路如下:
 
1. **数据准备:** 读取提供的 Wimbledon 数据集,并选择或创建适当的特征用于建模。根据问题的要求,可能需要考虑比赛中的各种指标,例如得分、局数、发球次数等。
 
2. **模型选择:** 选择决策树模型作为分类器。决策树适用于分类问题,可帮助我们理解在不同情境下比赛流动的变化。
 
3. **特征标准化:** 虽然决策树不太受特征尺度影响,但在进行交叉验证时,通常建议对特征进行标准化,以确保更好的模型性能。
 
4. **K 折交叉验证:** 将数据集划分为 k 个折叠,然后进行 k 次训练和测试。在每次迭代中,将其中一个折叠用作测试集,其余的折叠用作训练集。
 
5. **模型训练和评估:** 在每个训练和测试迭代中,使用训练集对决策树模型进行训练,并在测试集上进行评估。记录每次迭代的模型性能指标,例如准确性、精确度、召回率等。
 
6. **性能评估:** 计算 k 次交叉验证的平均性能,以评估决策树模型对比赛流动的准确性。
 
以下是一个简化的 Python 代码示例,演示了使用决策树模型进行 k 折交叉验证的建模思路:
 
```python
from sklearn.model_selection import cross_val_score, KFold
from sklearn.tree import DecisionTreeClassifier
from sklearn.preprocessing import StandardScaler
 
# 读取数据集,进行特征选择和数据准备
# ...
 
# 选择模型(决策树分类器)和特征标准化
model = DecisionTreeClassifier()
scaler = StandardScaler()
 
# 特征标准化
X_scaled = scaler.fit_transform(X)
 
# 定义 K 折交叉验证
kf = KFold(n_splits=5, shuffle=True, random_state=42)
 
# 进行 K 折交叉验证
cross_val_results = cross_val_score(model, X_scaled, y, cv=kf, scoring='accuracy')
 
# 输出交叉验证准确性
print(f'Cross-Validation Accuracy: {cross_val_results.mean()}')
```
 
这个示例代码中,使用了决策树分类器,并对特征进行了标准化。通过交叉验证,我们可以获得模型在不同子集上的性能,从而更好地评估其通用性。
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/9b520d744c1a40768ac49172c5c6669d.jpeg#pic_center)
问题五的目标是测试开发的模型在其他比赛上的通用性。您可以使用混淆矩阵来比较模型在不同比赛上的性能。以下是一个示例代码,演示如何使用混淆矩阵进行可视化。
 
```python
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import confusion_matrix
import matplotlib.pyplot as plt
import seaborn as sns
 
# 假设您已经有一个训练好的模型 trained_model,以及其他比赛的数据集 other_data
# 其中 other_data 的格式应该与用于训练的数据集相似
 
# 1. 数据预处理
# ...
 
# 2. 特征工程
# ...
 
# 3. 将数据集划分为特征和目标变量
X_other = other_data.drop("target_variable", axis=1) # 请根据实际数据集替换 "target_variable"
y_other = other_data["target_variable"]
 
# 4. 特征标准化
scaler = StandardScaler()
X_other_scaled = scaler.fit_transform(X_other)
 
# 5. 模型预测
y_pred_other = trained_model.predict(X_other_scaled)
 
# 6. 计算混淆矩阵
conf_mat_other = confusion_matrix(y_other, y_pred_other)
 
# 7. 绘制混淆矩阵热力图
plt.figure(figsize=(8, 6))
sns.heatmap(conf_mat_other, annot=True, fmt='d', cmap='Blues', xticklabels=["Class 0", "Class 1"], yticklabels=["Class 0", "Class 1"])
plt.xlabel('Predicted')
plt.ylabel('Actual')
plt.title('Confusion Matrix for Other Matches')
plt.show()
```
 
此代码将生成一个混淆矩阵的热力图,以直观显示模型在其他比赛上的性能。混淆矩阵的对角线元素表示模型正确分类的样本数,非对角线元素表示错误分类的样本数。

同店推荐

包含文件 · 7 · 353.3 KB

  • 01_美赛鹿鹿学长C题思路+代码.docx 32.1 KB
  • 02_问题二.py 1.8 KB
  • 03_问题三.py 943.0 B
  • 04_美赛鹿鹿学长C题思路+代码.pdf 310.1 KB
  • 05_问题四.py 1.6 KB
  • 06_问题五.py 2.9 KB
  • 07_问题一.py 3.9 KB
支付金额 ¥17.20