【2024美赛】C题 Problem C: Momentum in Tennis网球运动中的势头 网球问题一python代码

news2024/11/24 3:00:24

相关链接

(1)问题分析

(2)26页论文

1 题目

http://t.csdnimg.cn/BzhFu

2 问题一数学模型

采用隐马尔可夫模型(Markov Model),这是一种描述随机过程的数学模型,它满足马尔可夫性质,即未来状态的概率只依赖于当前状态,与过去的状态无关。马尔可夫模型可以分为马尔可夫链和隐马尔可夫模型两种常见形式。模型建立过程如下,

  1. 建立状态: 在网球比赛中,每个时间点的状态可以用元组来表示:(状态可以是盘分0-0、1-0、2-0等,可以以是局分1-6、2-6等,可以是小比分15-0、30-0、40-0等,以及其他特征)。其中,球员表示当前发球的球员;比分状态表示局分和盘分的组合;发球方表示该时间点的发球方是哪个球员。

  2. 状态转移矩阵: 通过观察比赛数据,可以建立状态转移矩阵来描述状态之间的转移概率。对于相邻的时间点,可以统计从一个状态转移到另一个状态的次数,然后将这些计数转换为概率。举例来说,对于当前状态 (player1, score_status, server),下一个状态 (next_player1, next_score_status, server) 的转移概率可以表示为 transition_matrix[(player1, score_status, server)][(next_player1, next_score_status, server)]。本模型以比分出现的次频次作为状态转移概率,只考了盘分和局分,没有考虑小分,即15-0,30-0,40-0这样的小分。

  3. 发球方优势模型: 代码中使用了一个函数 serving_advantage 来模拟发球方的优势。该函数返回了一个假设的发球方赢得比赛的概率。

  4. 胜率计算: 根据状态转移矩阵和发球方优势模型,可以计算每个时间点球员的胜率。对于每个状态乘以发球优势比例 ,可以用以下公式计算其胜率:

问题一代码实现

  1. 读取了网球比赛数据,并根据比赛的局分和盘分创建了一个表示比赛积分状态的新列。

  2. 定义了一个函数 serving_advantage 用来计算发球方赢得比赛的概率,假设发球方赢得比赛的概率为60%,接发方赢得比赛的概率为40%。

  3. 构建了一个状态转移矩阵,根据比赛中每个时间点的状态计算了从当前状态到下一个状态的转移概率。

  4. 根据状态转移矩阵计算了每个时间点上两位球员的胜率,并将结果可视化为比赛进程图,显示了每位球员在比赛中的预测胜率。

因此,该模型以状态转移矩阵为基础,通过定义的发球优势和转移概率,可以预测每个时间点上两位球员在比赛中的胜率,并将预测结果可视化为比赛进程图。




import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# 读取数据
data = pd.read_csv("data/Wimbledon_featured_matches.csv")

# 添加一列表示比赛积分状态(包括局分和盘分)
data['score_status'] = data['p1_games'].astype(str) + '-' + data['p2_games'].astype(str) + ' ' + data['p1_sets'].astype(str) + '-' + data['p2_sets'].astype(str)

# 只分析第一场比赛
match_1 = data.iloc[0]['match_id']
df = data[data['match_id']==match_1]
player1 = data.iloc[0]['player1']
player2 = data.iloc[0]['player2']
print(player1,player2)
df

在这里插入图片描述

# 定义函数计算发球方赢得比赛的概率
def serving_advantage(server):
    if server == 1:
        return 0.6  # 假设发球方赢得比赛的概率为60%
    else:
        return 0.4  # 假设接发方赢得比赛的概率为40%

# 构建状态转移矩阵
def build_transition_matrix(df):
    transition_matrix = {}
    for i in range(len(df) - 1):
        row = df.iloc[i]
        next_row = df.iloc[i + 1]
        current_state = (row['player1'],row['score_status'],row['server'])
        next_state = (next_row['player1'], next_row['score_status'],row['server'])
        if current_state not in transition_matrix:
            transition_matrix[current_state] = {}
        if next_state not in transition_matrix[current_state]:
            transition_matrix[current_state][next_state] = 0
        transition_matrix[current_state][next_state] += 1
    # 将计数转换为概率
    for current_state, next_states in transition_matrix.items():
        total_transitions = sum(next_states.values())
        for next_state in next_states:
            transition_matrix[current_state][next_state] /= total_transitions
    return transition_matrix

transition_matrix = build_transition_matrix(df)
transition_matrix

在这里插入图片描述

# 根据状态转移矩阵计算每个时间点的比赛胜率
def calculate_win_prob(transition_matrix):
    win_prob = {}
    for state in transition_matrix:
        # 运动员的胜率计算
        if state not in win_prob.keys():
            win_prob[state] = 0  # 初始化胜率为0
        for next_state, prob in transition_matrix[state].items():
            win_prob[state] = prob * serving_advantage(state[2])
    return win_prob

win_prob = calculate_win_prob(transition_matrix)
win_prob

在这里插入图片描述

# 可视化比赛进程
def visualize_match_flow(win_prob, df):
    x = np.arange(len(df))
    y_p1 = [win_prob[(df.iloc[i]['player1'], df.iloc[i]['score_status'],df.iloc[i]['server'])] for i in range(len(df))]
    print(y_p1[-10:])
    y_p2 = [1 - win_prob[(df.iloc[i]['player1'], df.iloc[i]['score_status'],df.iloc[i]['server'])] for i in range(len(df))]  # 第二个运动员的预测概率
    print(y_p2[-10:])
    plt.figure(figsize=(10, 5))
    plt.plot(x, y_p1, color='red', label=player1)
    plt.plot(x, y_p2, color='blue', label=player2)
    plt.xlabel('Point Number')
    plt.ylabel('Win Probability')
    plt.title('Match Flow')
    plt.legend()
    plt.show()

visualize_match_flow(win_prob, df)


![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/3b23b31d15654ab58593c0bcc6bf68fe.png)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1431823.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Powershell Install 一键部署Prometheus

前言 Prometheus是一个开源的系统监控和报警系统,现在已经加入到CNCF基金会,成为继k8s之后第二个在CNCF托管的项目,在kubernetes容器管理系统中,通常会搭配prometheus进行监控,同时也支持多种exporter采集数据,还支持pushgateway进行数据上报,Prometheus性能足够支撑上…

redis 6.x集群搭建

redis6集群搭建 安装文件下载 redis-6.2.6.tar.gz 编译 tar -zxvf redis-6.2.6.tar.gz cd redis-6.2.6/ make MALLOClibc make install PREFIX/opt/soft/redis复制可执行文件 cp /opt/soft/redis/redis-cli /usr/bin/redis-cli cp /opt/soft/redis/redis-server /usr/bi…

ffmpeg操作实战001:视频+音频文件融合

一、功能需求 把视频文件video.mp4 和音频文件audio.wav融合在一起,输出视频文件output.mp4 二、操作指令 ffmpeg -i video.mp4 -i audio.wav -c:v copy -map 0:v:0 -map 1:a:0 output.mp4 三、参数说明 ffmpeg: 这是用于执行FFmpeg命令行工具的命令。-i video…

数据结构(C语言)代码实现(六)——单链表的实现

目录 参考、格式 头文件LinkList.h 一、将函数的小括号写成中括号 二、读取权限冲突 三、L->Last指针没有移动 四、函数指针的使用 头文件完整代码 测试函数(主函数)test.cpp 测试结果 参考、格式 数据结构课本2.3节(严蔚敏版&a…

虚幻UE5Matehuman定制自己的虚拟人,从相机拍照到UE5制作全流程

开启自己的元宇宙,照片扫描真实的人类,生成虚拟形象,保姆级教程,欢迎大家指正。 需要的软件: 制作流程: 一.拍照。 围绕自己拍照,大概20多张图就差不多了,把脑门漏出来,无需拍后脑勺。 拍照方式 例如,拍照时尽量不要在脸上体现出明显的光源方向。

如何在Shopee平台上进行测款选品

在如今竞争激烈的电商市场,选择合适的产品成为卖家们提高销售业绩的重要一环。在Shopee平台上进行测款选品,可以帮助卖家找到符合市场需求的产品,提高销售业绩。本文将介绍一些策略和步骤,帮助卖家在Shopee平台上进行测款选品。 …

PCL安装以及CGAL构建三维凸包

基础理论专栏目录 - 知乎 (zhihu.com) 凸包问题——概述 - 知乎 (zhihu.com) 1、安装PCL 安装pcl,我的是window10,vs2019。我安装的是1.13 win10系统下 VS2019点云库PCL1.12.0的安装与配置_windows 10使用pcl-CSDN博客 照着上述博客进行配置,再结合这个设置环境变…

LeAPI 后端接口开发 - 发布、下线接口

一、上线接口(仅管理员) 1. 校验请求参数 2. 判断(测试)接口是否可以调用 引入调用接口的客户端(自己写的 SDK)注入客户端实例调用接口 3. 修改数据库中接口的状态 /*** 上线(发布&#xff…

070:vue中provide、inject的使用方法(图文示例)

第070个 查看专栏目录: VUE 本文章目录 示例背景示例效果图示例源代码父组件代码子组件代码孙组件代码 基本使用步骤 示例背景 本教程是介绍如何在vue中使用provide和inject。在 Vue 中,provide 和 inject 是用于实现祖先组件向后代组件传递数据的一种方式。 在这个…

Linux一些实用操作

学习笔记,记录以下课程中关于Linux的一些实用操作。黑马程序员新版Linux零基础快速入门到精通,全涵盖linux系统知识、常用软件环境部署、Shell脚本、云平台实践、大数据集群项目实战等_哔哩哔哩_bilibili 目录 1 各类小技巧(快捷键&#xff…

计算机速成课Crash Course - 28. 计算机网络

今天继续计算机速成课Crash Course的系列讲解。 更多技术文章,全网首发公众号 “摸鱼IT” 锁定 -上午11点 - ,感谢大家关注、转发、点赞! 计算机速成课Crash Course - 28. 计算机网络 (qq.com) 28. 计算机网络 互联网太棒啦,键…

java05 数组

一 概念介绍 指的是一种容器,可以同来存储同种数据类型的多个值。 但是数组容器在存储数据的时候,需要结合隐式转换考虑。 比如: 定义了一个int类型的数组。那么boolean。double类型的数据是不能存到这个数组中的, 但是byte类…

Linux文本三剑客-sed

一、sed介绍: sed(Stream Editor)是一种流编辑器,用于对文本进行处理和转换。它可以从输入流中读取文本,并根据指定的规则进行编辑和替换。sed通常用于在命令行中进行文本处理,可以实现搜索、替换、删除、…

Python对日期的一些操作

1. 把这种日期 Mon Jan 29 11:10:49 0800 2024 转换成 ‘2024/2/1 10:50:38’ 这里定义一个func 传入英文日期,返回标准日期格式 def time_formater(input_time_str): input_format %a %b %d %H:%M:%S %z %Y output_format %Y-%m-%d %H:%M:%S return dat…

springboot154基于Spring Boot智能无人仓库管理

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的 适用于计算机类毕业设计,课程设计参考与学习用途。仅供学习参考, 不得用于商业或者非法用途,否则,一切后果请用户自负。 看运行截图看 第五章 第四章 获取资料方式 **项…

【Win10下实现开机Jar启动的CICD自动化流程】

目录 在Win10下实现开机Jar启动的CICD自动化流程,可以按照以下步骤进行操作:在Win10下实现开机Jar启动的CICD自动化流程,可以按照以下步骤进行操作: 安装Java环境:确保你的计算机上已经安装Java环境,可以通过命令行运行java -version来验证Java环境是否已安装。 编写启动…

操作符重点

简介 移位操作符 <<:左移操作符 移动的是二进制的数&#xff0c;即存储在计算机内部的数的补码 移动之后再右边补零 >>:右移操作符 同左移操作符 移动之后补的数分两种情况: (1).逻辑右移:移动后左边补1 (2).算术右移:移动后左边补原符号位 位操作符: (1).&a…

嵌入式基础知识-逻辑覆盖测试用例设计

1 基础示例 1.1 例题一 有如下程序&#xff0c;设计分别满足语句覆盖和分支覆盖的最有效力的测试用例。 int x 0; int y 0;if (x > 0 && y > 0) {y y/x; }if (x > 1 || y > 1) {y y 1; }x x y;分析&#xff1a; 语句覆盖只需要所有的语句都被执…

【JavaEE spring】SpringBoot 统一功能处理

SpringBoot 统一功能处理 1. 拦截器1.1 拦截器快速⼊⻔1.2 拦截器详解1.2.1 拦截路径1.2.2 拦截器执⾏流程 1.3 登录校验1.3.1 定义拦截器1.3.2 注册配置拦截器 2. 统⼀数据返回格式2.1 快速⼊⻔2.2 存在问题2.3 案例代码修改2.4 优点 3. 统⼀异常处理 1. 拦截器 后端程序根据…

浅谈——开源软件的影响力

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 ✨特色专栏&#xff1a…