草庐IT

2023美赛C题:预测Wordle结果-思路详解及参考代码

lichensun 2023-06-29 原文

一、题目解析

总体来看与去年的C题比较相似,唯一一道有数据(不需要自己额外找)的题目,选题人估计也最多。

本质是数据分析题目,需要建立预测模型、分类模型、特征挖掘等。相对来说出思路比较简单,想出彩比较难。所以在分析建模时一定要多维度思考,不然连页数都凑不够。

题目要求:

《纽约时报》已经要求你对此文件中的结果进行分析,以回答几个问题。

•1.报告的结果的数量每天都在变化。开发一个模型来解释这种变化,并使用您的模型为2023年3月1日报告的结果数量创建一个预测区间。单词的任何属性是否会影响在困难模式下玩家的分数的百分比?如果是,如何处理?如果不是,为什么不呢?

这一问要求对数据表中的数据进行分析和解释说明,总结变化规律,并选择合适的预测模型对未来数据进行预测。这里题目指出预测结果应该是一个区间,这说明传统的回归拟合预测不能满足题目要求,需要进行改进或者直接使用基于统计学的区间预测方法。

同时我们还需要分析单词的属性,给出的单词量虽然并不大,但直接对单词进行属性分析需要较深的NLP知识,不好切入。不妨我们可以从结果入手,求出每个单词选择困难模式的玩家平均解题次数作为特征变量进行聚类分析,得到少、适中、多三个或更多的类别,然后可以生成词云图观察对应类别中的词分布特点。分布特点可以人为构造,如统计各个字母出现频次,aeiou元音字母占比(aeiou存在少的往往生僻),重复字母个数(按照题目困难模式下拥有重复的字母会好猜)。分析聚类是否在以上特点中存在显著的分布趋势,即可得到结论。

如果有影响,就在出题中减少这类单词。无影响,说明情况即可。

•2.对于未来日期的给定未来解决方案词,开发一个模型,允许您预测报告结果的分布。换句话说,来预测未来一个日期的(1、2、3、4、5、6、X)的相关百分比。你的模型和预测有哪些不确定性?举一个你在2023年3月1日预测eerie这个词的具体例子。你对你的模型的预测有多有信心?

结合问题一的结论开发预测模型,直接将已知数据其输入预测模型进行训练,调整优化参数后得到预测模型,将新词已知条件输入,输出(1、2、3、4、5、6、X)的值,最后将结果进行归一化处理。(按照3问,该题不需要考虑难易程度)

测量模型的不确定性可以采用蒙特卡罗Dropout法(MC Dropout)和深度集成法。

3.开发和总结一个模型,按难度分类解决方案词。识别与每个分类关联的给定单词的属性。使用你的模型,怪诞这个词有多难?讨论你的分类模型的准确性。

结合问题一的结论开发预测模型,根据eerie词的特点去给该题的难易程度打分,显而易见,该词并不是一个常见的词汇,难度系数较高。生僻词可以作为一个评价维度,然后用问题一的分布特点作为其他评价指标,用综合评价法求出得分作为词的标签。其他已知词的难以标签则由聚类结果(对应平均分)决定。接着将其输入预测模型进行训练,输出(1、2、3、4、5、6、X)的值,最后将结果进行归一化处理。

测量模型的不确定性可以采用蒙特卡罗Dropout法(MC Dropout)和深度集成法,预测信心可以用训练集的准确率、AUC值来验证,也可以添加噪声来验证模型鲁棒性。

•4.列出并描述了这个数据集的其他一些有趣的特性。最后,在一封给《纽约时报》拼图编辑的一到两页的信中总结你的结果。

数据分析+可视化+总结结果

二、具体步骤及代码

问题一:

首先进行数据分析与可视化,观察规律

我们发现在记录的日期最开始的时候,报告的数量上升迅速,在2月分左右到达峰值,在较小幅度的震荡波动之后缓慢下降,逐渐稳定下来,维持在一个稳定的数据区间内波动。这说明在游戏推出时,人们由于新鲜感和宣传、传播等大量的涌入游戏网页进行猜谜,然而随着时间的推动,人们失去了新鲜感,逐渐退出,游戏的热度也随之下降。只有一些忠实的玩家会持续进行游戏。

然而,困难模式的相对数量变化波动并不大,我们可以认为,热衷于挑战困难模式的玩家属于一类比较固定的玩家群体。

建立解释变化的模型可以采用简单的拟合多项式模型来解释,也可以利用时间序列的模型来拟合,如移动平均、指数平滑等。

由于前述分析可以看出,数据的变化和时间有着紧密的关系,所以我们可以依赖时间建立预测模型。

由于我们序列的性质比较单一,(无明显季节等特征),可以直接采用holt线性预测方法。

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


df=pd.read_excel('Problem_C_Data_Wordle.xlsx',skiprows=1)
data=df[['Date','Number of  reported results']]

def secondaryExponentialSmoothingMethod(list, n_average, alpha,
                                        day):  # 参数list为你要传入的时间序列,n_average表示数列两端取多少个数(要取奇数),alpha为平滑系数,day为向后预测的天数
    # 准备好解二元一次方程组的方法
    def fangChengZu(a1, b1, a2, b2, c1, c2):
        a = np.array([[a1, b1], [a2, b2]])
        b = np.array([c1, c2])
        x, y = np.linalg.solve(a, b)
        return x, y

    # 取数列两端各n_average个值加以平均
    list_left = list[0:n_average]  # data中前n_average个值构成的list
    list_right = list[n_average + 1:len(list)]  # data中后n_average个值构成的list
    list_left_average = np.mean(list_left)  # list_left包含元素的均值
    list_right_average = np.mean(list_right)
    x1 = (n_average + 1) / 2
    x2 = (len(list) - x1) + 1
    # print(list_left_average,list_right_average)

    # 代入线性趋势方程,解出a1,b1
    a1, b1 = fangChengZu(1, x1, 1, x2, list_left_average, list_right_average)
 # print(a1,b1)

    # 代入公式(12),解出S11,S12
    S11, S12 = fangChengZu(2, -1, a1, b1, -b1, (alpha / (1 - alpha)))
    # print(S11,S12)

    a_tao = 0  # 初始化
    b_tao = 0
    for i in range(len(list)):
        S1 = alpha * list[i] + (1 - alpha) * S11
        S2 = alpha * S1 + (1 - alpha) * S12
        S11 = S1
        S12 = S2
        a_tao = 2 * S1 - S2
        b_tao = (alpha / (1 - alpha)) / (S1 - S2)
    H = a_tao + b_tao * day  # 预测值
    return H


if __name__ == '__main__':
    data =data['Number of  reported results']  # 时间序列
    prediction_day1 = secondaryExponentialSmoothingMethod(data, 3, 0.5, 1) #预测下一天
    prediction_day2 = secondaryExponentialSmoothingMethod(data, 3, 0.5, 53)#预测3.2号
    print(prediction_day2)

plt.figure(figsize=(25, 7))
plt.plot(data,color='b', label='Original')
plt.plot(414,prediction_day2,color='c', label='Predict',marker='+')
plt.show()

或者采用简单参数的arima算法。

接下来为了判断词的特性,我们先先求出平均解题次数(因为X的不确定性,我们忽略该项),直接用SPSS进行k-means聚类分析。

分类结果

不同类对应词特征

一二问完整版已出,放在评论区,如失效请私信

有关2023美赛C题:预测Wordle结果-思路详解及参考代码的更多相关文章

  1. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  2. ruby-on-rails - Rails 源代码 : initialize hash in a weird way? - 2

    在rails源中:https://github.com/rails/rails/blob/master/activesupport/lib/active_support/lazy_load_hooks.rb可以看到以下内容@load_hooks=Hash.new{|h,k|h[k]=[]}在IRB中,它只是初始化一个空哈希。和做有什么区别@load_hooks=Hash.new 最佳答案 查看rubydocumentationforHashnew→new_hashclicktotogglesourcenew(obj)→new_has

  3. ruby-on-rails - 浏览 Ruby 源代码 - 2

    我的主要目标是能够完全理解我正在使用的库/gem。我尝试在Github上从头到尾阅读源代码,但这真的很难。我认为更有趣、更温和的踏脚石就是在使用时阅读每个库/gem方法的源代码。例如,我想知道RubyonRails中的redirect_to方法是如何工作的:如何查找redirect_to方法的源代码?我知道在pry中我可以执行类似show-methodmethod的操作,但我如何才能对Rails框架中的方法执行此操作?您对我如何更好地理解Gem及其API有什么建议吗?仅仅阅读源代码似乎真的很难,尤其是对于框架。谢谢! 最佳答案 Ru

  4. ruby - 模块嵌套代码风格偏好 - 2

    我的假设是moduleAmoduleBendend和moduleA::Bend是一样的。我能够从thisblog找到解决方案,thisSOthread和andthisSOthread.为什么以及什么时候应该更喜欢紧凑语法A::B而不是另一个,因为它显然有一个缺点?我有一种直觉,它可能与性能有关,因为在更多命名空间中查找常量需要更多计算。但是我无法通过对普通类进行基准测试来验证这一点。 最佳答案 这两种写作方法经常被混淆。首先要说的是,据我所知,没有可衡量的性能差异。(在下面的书面示例中不断查找)最明显的区别,可能也是最著名的,是你的

  5. ruby - 寻找通过阅读代码确定编程语言的ruby gem? - 2

    几个月前,我读了一篇关于ruby​​gem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:

  6. ruby - Net::HTTP 获取源代码和状态 - 2

    我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur

  7. 报告回顾丨模型进化狂飙,DetectGPT能否识别最新模型生成结果? - 2

    导读语言模型给我们的生产生活带来了极大便利,但同时不少人也利用他们从事作弊工作。如何规避这些难辨真伪的文字所产生的负面影响也成为一大难题。在3月9日智源Live第33期活动「DetectGPT:判断文本是否为机器生成的工具」中,主讲人Eric为我们讲解了DetectGPT工作背后的思路——一种基于概率曲率检测的用于检测模型生成文本的工具,它可以帮助我们更好地分辨文章的来源和可信度,对保护信息真实、防止欺诈等方面具有重要意义。本次报告主要围绕其功能,实现和效果等展开。(文末点击“阅读原文”,查看活动回放。)Ericmitchell斯坦福大学计算机系四年级博士生,由ChelseaFinn和Chri

  8. 程序员如何提高代码能力? - 2

    前言作为一名程序员,自己的本质工作就是做程序开发,那么程序开发的时候最直接的体现就是代码,检验一个程序员技术水平的一个核心环节就是开发时候的代码能力。众所周知,程序开发的水平提升是一个循序渐进的过程,每一位程序员都是从“菜鸟”变成“大神”的,所以程序员在程序开发过程中的代码能力也是根据平时开发中的业务实践来积累和提升的。提高代码能力核心要素程序员要想提高自身代码能力,尤其是新晋程序员的代码能力有很大的提升空间的时候,需要针对性的去提高自己的代码能力。提高代码能力其实有几个比较关键的点,只要把握住这些方面,就能很好的、快速的提高自己的一部分代码能力。1、多去阅读开源项目,如有机会可以亲自参与开源

  9. 华为OD机试用Python实现 -【明明的随机数】 2023Q1A - 2

    华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o

  10. 7个大一C语言必学的程序 / C语言经典代码大全 - 2

    嗨~大家好,这里是可莉!今天给大家带来的是7个C语言的经典基础代码~那一起往下看下去把【程序一】打印100到200之间的素数#includeintmain(){ inti; for(i=100;i 【程序二】输出乘法口诀表#includeintmain(){inti;for(i=1;i 【程序三】判断1000年---2000年之间的闰年#includeintmain(){intyear;for(year=1000;year 【程序四】给定两个整形变量的值,将两个值的内容进行交换。这里提供两种方法来进行交换,第一种为创建临时变量来进行交换,第二种是不创建临时变量而直接进行交换。1.创建临时变量来

随机推荐