原文:
towardsdatascience.com/heres-what-i-learned-about-information-theory-through-wordle-c835319cc87f
Wordle 是由《纽约时报》开发的一款令人上瘾的在线每日单词谜题游戏。
规则很简单。玩家有六次机会猜测一个五字母单词。Wordle 通过用绿色、灰色和黄色突出显示你猜测的单词中的字母来对你每次猜测提供反馈。
绿色表示你对给定字母和位置的猜测是正确的。黄色表示字母存在于单词中,但位置放错了。灰色表示字母在单词中不存在。
一个完美的猜测将导致所有五个字母都变成绿色。一个糟糕的猜测可能会导致所有字母都是灰色。如果猜测部分正确,你可能会看到黄色和灰色的混合,这表明一些字母存在但位置放错了。
我相信许多读者之前都玩过 Wordle,但如果你还没有尝试过,可以这里试试。
Wordle 网站截图 网站
由于其有趣的反馈循环有助于缩小可能的单词列表,Wordle 是信息论概念如何增强决策的一个完美例子。我玩游戏是为了娱乐,但内心那个书呆子想要深入了解猜测背后的“为什么”。什么使得一些猜测比其他猜测更好?反馈如何引导我找到正确的单词?
在这篇文章中,我们将探讨信息论如何回答上述问题,以及它如何应用于提高你寻找正确单词的策略。文章需要你具备概率的基本理解。
让我们开始吧。
信息论
信息论量化了系统中的不确定性以及我们如何有效地减少这种不确定性。其核心概念之一是熵(或香农熵),它衡量了一组可能结果中的不确定性量。给定概率分布 P(x),熵的方程为 -
香农熵公式。图由作者提供
熵告诉我们我们对随机变量结果的确定性有多高。熵越低,我们对结果就越确定。熵越低,我们拥有的信息就越多。当 p=0.5 时,熵达到最高。0.5 的概率表示最大的不确定性,因此信息最少。在 p=0 和 p=1 时,我们具有最低的熵,最高的确定性,以及最高的信息。熵和信息成反比。
熵曲线。图片由作者提供
“信息”如何在 Wordle 游戏中发挥作用?
假设英语词典中有 2000 个五字母单词。所有单词都有可能成为每日单词。换句话说,P(x) = 1/2000。你的第一次猜测时的熵会是多少?
熵计算。图片由作者提供
使用上述公式计算的熵将等于log(2000) = 10.97 比特。这意味着在你开始第一次猜测时,你大约有 11 比特的不确定性。
假设原始单词是“PLANT”。你在第一次尝试中猜测了“ROGUE”。屏幕将显示灰色、灰色、灰色、灰色和灰色方块。恐慌模式!不!
在收到反馈后,你成功消除了字母 R、O、G、U 和 E。通过这样做,假设你将可能的单词列表减少到 100!你的第二次猜测之前的熵会是多少?使用相同的公式,熵将等于log(100) = 6.67 比特。
熵从 10.97 比特下降到 6.67 比特!这是信息增益。“ROGUE”用五个灰字给出,但给我们带来了 4.5 比特的信息。信息增益越高,猜测在减少可能的单词池方面的作用就越大。
因此,我们需要猜测一个高熵单词。如果你在第二次猜测之前猜测了一个单词,将可能的单词列表缩小到 10,你将得到log(10) = 3.32 比特的熵。这将导致 7.65 比特的信息增益!
游戏
WORDSRATED声称英语词典中有 12987 个五字母单词。Wordle 使用这些五字母单词的子集(2315 个单词)进行游戏。在这篇文章中,我将使用 2315 个五字母单词的词典。
策略是建议我们猜测的前十个建议。游戏中每个步骤的最高建议将基于上一节中讨论的熵计算生成。熵较高的单词有更高的可能是答案。
代码
以下 Python 函数根据提供的猜测和实际单词(目标)获取反馈。该函数输出游戏在猜测后显示的颜色列表。
from collections import Counter
# Function to calculate feedback for a guess against the target word
def get_feedback(guess, target):
feedback = ['gray'] * 5
target_counter = Counter(target)
# First pass to mark greens
for i in range(5):
if guess[i] == target[i]:
feedback[i] = 'green'
target_counter[guess[i]] -= 1
# Second pass to mark yellows
for i in range(5):
if feedback[i] == 'gray' and guess[i] in target_counter and target_counter[guess[i]] > 0:
feedback[i] = 'yellow'
target_counter[guess[i]] -= 1
return feedback
以下函数将根据给定的单词列表计算特定猜测的熵。首先,它将获取列表中每个单词的反馈。存储每种类型的反馈模式(GYBGG、GYGBY 等)的频率。猜测的熵是通过反馈模式频率的概率分布来计算的。
import math
# Function to compute entropy for a list of words given the current guess
def compute_entropy(words, guess):
feedback_counts = Counter()
for word in words:
feedback = tuple(get_feedback(guess, word))
feedback_counts[feedback] += 1
total_words = len(words)
entropy = 0.0
for feedback in feedback_counts.values():
p = feedback / total_words
entropy -= p * math.log2(p)
return entropy
以下辅助函数从单词列表中过滤可能的单词,并根据最高熵建议前 10 个单词。
# Function to filter words based on feedback
def filter_words(words, guess, feedback):
def match_feedback(word):
return get_feedback(guess, word) == feedback
return [word for word in words if match_feedback(word)]
# Function to suggest top 10 guesses based on entropy
def suggest_words(words):
entropy_list = [(word, compute_entropy(words, word)) for word in words]
entropy_list.sort(key=lambda x: x[1], reverse=True)
print("nTop 10 suggestions based on entropy:")
for i, (word, entropy) in enumerate(entropy_list[:10]):
print(f"{i+1}. {word} (Entropy: {entropy:.4f})")
我编写了一个可以在 Python 环境中运行的 Python 脚本,用于交互式地玩游戏。该代码随机选择一个单词作为目标,要求您猜测一个单词,并在每次猜测之前输出顶级建议以提供帮助。
import random
# Simulate a game of Wordle using information theory for guessing
def play_wordle(words):
target = random.choice(words)
remaining_words = words
guesses = 0
print(f"Target word has been chosen (hidden for simulation).")
# Start by showing suggestions before the first guess
suggest_words(remaining_words)
while guesses < 6:
# Get the player's guess
guess = input(f"nEnter your no. {guesses + 1} guess: ").strip().lower()
if guess not in remaining_words:
print("Invalid guess. Please enter a valid 5-letter word from the suggestions.")
continue
guesses += 1
# Fetch the feedback
feedback = get_feedback(guess, target)
print(f"Feedback for '{guess}': {feedback}")
if feedback == ['green'] * 5:
print(f"Success! Found the word '{guess}' in {guesses} guesses.")
return
# Filter the words based on feedback
remaining_words = filter_words(remaining_words, guess, feedback)
if not remaining_words:
return
print(f"{len(remaining_words)} possible words remaining")
# Suggest top 10 guesses based on entropy
suggest_words(remaining_words)
print(f"Failed to guess the word. The correct word was: {target}")
if __name__ == '__main__':
words = load_word_list()
play_wordle(words)
模拟
我进行了一些模拟。以下图像展示了使用 Python 实现的 Wordle 游戏的示例。
猜出 “exert” 需要 3 次猜测。图由作者提供
猜出 “Guide” 需要 3 次猜测。图由作者提供
Wordle 辅助工具
我创建了一个 Wordle 辅助工具,在您实时玩 Wordle 游戏时可以帮助您。它会在每次猜测后提供前十个单词的建议。您必须向程序提供您的猜测和收到的反馈。辅助工具将生成一个包含前 10 个建议的列表。
以下代码片段包含了 Wordle 辅助工具的代码。
# Function to suggest top 10 words based on entropy and return all possible words
def wordle_assistant(words, guess, feedback):
# Filter the remaining words based on feedback
remaining_words = filter_words(words, guess, feedback)
# Compute entropy for each remaining word
entropy_list = [(word, compute_entropy(remaining_words, word)) for word in remaining_words]
entropy_list.sort(key=lambda x: x[1], reverse=True)
# Get the top 10 suggestions
top_suggestions = entropy_list[:10]
print("nTop 10 suggestions based on entropy:")
for i, (word, entropy) in enumerate(top_suggestions):
print(f"{i + 1}. {word} (Entropy: {entropy:.4f})")
return [word for word, _ in top_suggestions], remaining_words
if __name__ == "__main__":
# Example word list (replace with a larger dictionary for real use)
remaining_words = words
for guess_number in range(1, 7):
print(f"n--- Guess {guess_number} ---")
# Input the user's guess
guess = input("Enter your guess: ").strip().lower()
if guess not in remaining_words:
print("Invalid guess. Make sure the word is valid and in the list of remaining suggestions.")
continue
# Input feedback for the guess
feedback_input = input("Enter feedback (e.g., 'xygxx'): ").strip().lower()
feedback = ['green' if c == 'g' else 'yellow' if c == 'y' else 'gray' for c in feedback_input]
# Process and update suggestions
top_suggestions, remaining_words = wordle_assistant(remaining_words, guess, feedback)
if len(remaining_words) == 1:
print(f"nCongratulations! The target word is: {remaining_words[0]}")
break
elif not remaining_words:
print("nNo words remaining. Something went wrong with the feedback.")
break
else:
print(f"n{len(remaining_words)} words remain in the list.")
以下图示说明了我是如何使用熵来猜测正确单词的。
使用 Wordle 辅助工具进行的实时 Wordle 模拟
对不起,我破坏了游戏的乐趣。
尽管如此,该模拟从纽约时报官方为 Wordle 定义的 2315 个单词的词典中生成建议。在约 12000 个五字母长单词的词典上执行此类模拟可能是一项有趣的练习。
本文使用的代码已上传至此 – github.com/sm823zw/wordle-simulation
希望您觉得我的文章有趣!
感谢您阅读我的文章!
425

被折叠的 条评论
为什么被折叠?



