《深度学习基础与概念》task2/3
第四章 单层网络:回归
给定D维输入变量x,回归的目标是预测一个或多个连续的目标变量t
(总览)思维导图
4.1
最简单的回归模型是输入变量的线性组合:
这种形式的模型有时也被称为线性回归(linear regression)。
线性回归的最小二乘法,是高斯噪声假设下的概率最优解,能用矩阵运算高效求解;遇到大数据用在线学习逐样本更新,遇到过拟合用正则化压缩参数,几何上看就是高维空间的投影~
当然,除此之外还有其他的优化方法:
(1)梯度下降家族: 批量梯度下降(BGD) 随机梯度下降(SGD) 小批量梯度下降(MBGD)
(2)带正则化的优化: 岭回归(Ridge Regression) Lasso 回归
(3)其他小众但有用的方法: 弹性网(Elastic Net) 坐标下降法
4.2
“决策理论” 在回归问题里的逻辑:
推断:用数据学到预测分布 p(t∣x)(知道 “可能的结果及概率” ) --> 决策:根据损失函数,选一个预测值 f(x) ,让 “期望损失最小”
这里先简单的介绍一下平方损失、绝对损失和0-1损失。
平方损失的分解:误差 =“模型 - 条件期望”² + 条件方差
由此可知,平方损失下,最优解是条件期望。
绝对损失和0-1损失
为了给大家更好的体验依据推断进而决策的过程,这里构建了一个“21点”交互页面。
选择不同损失函数,页面会基于剩余牌堆的概率分布自动计算期望损失,即时给出 “继续摸牌” 或 “停止摸牌” 的最优决策,让你直观感受概率推断与损失函数如何共同驱动决策逻辑。
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>21点决策助手</title><script src="https://cdn.tailwindcss.com"></script><link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet"><script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.8/dist/chart.umd.min.js"></script><script>tailwind.config = {theme: {extend: {colors: {primary: '#165DFF',secondary: '#FF7D00',neutral: '#F5F7FA',dark: '#1D2129',success: '#00B42A',danger: '#F53F3F',warning: '#FF7D00',},fontFamily: {inter: ['Inter', 'system-ui', 'sans-serif'],},}}}</script><style type="text/tailwindcss">@layer utilities {.content-auto {content-visibility: auto;}.card-shadow {box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);}.btn-hover {@apply transition-all duration-300 hover:shadow-lg hover:-translate-y-0.5;}.card-flip {perspective: 1000px;transform-style: preserve-3d;}.card-front, .card-back {backface-visibility: hidden;transition: transform 0.6s cubic-bezier(0.4, 0, 0.2, 1);}.card-back {transform: rotateY(180deg);}.card-flipped .card-front {transform: rotateY(180deg);}.card-flipped .card-back {transform: rotateY(0deg);}.progress-gradient {background: linear-gradient(to right, #FF7D00, #165DFF);}}</style>
</head>
<body class="font-inter bg-gray-50 min-h-screen"><div class="container mx-auto px-4 py-8 max-w-6xl"><!-- 头部区域 --><header class="text-center mb-10"><h1 class="text-[clamp(1.8rem,5vw,2.5rem)] font-bold text-dark mb-3"><i class="fa fa-calculator text-primary mr-2"></i>21点决策助手</h1><p class="text-gray-600 max-w-2xl mx-auto">基于概率模型和损失函数的智能决策系统,助你在21点游戏中做出最优选择</p></header><div class="grid grid-cols-1 lg:grid-cols-12 gap-6"><!-- 左侧栏 --><div class="lg:col-span-3 space-y-6"><!-- 已出现牌的情况 --><div class="bg-white rounded-xl p-5 card-shadow"><h3 class="text-lg font-semibold mb-4 flex items-center"><i class="fa fa-history text-primary mr-2"></i>已出现的牌</h3><div id="playedCards" class="grid grid-cols-4 gap-2 mb-3 max-h-48 overflow-y-auto"><!-- 动态生成已出牌 --></div><div class="text-xs text-gray-500"><span id="remainingCardsCount">剩余牌: 52</span></div></div><!-- 选择损失函数 --><div class="bg-white rounded-xl p-5 card-shadow"><h3 class="text-lg font-semibold mb-4 flex items-center"><i class="fa fa-sliders text-primary mr-2"></i>损失函数设置</h3><div class="space-y-3"><div class="flex items-start"><div class="flex items-center h-5"><input id="squareLoss" name="loss_type" type="radio" value="square" checked class="w-4 h-4 text-primary focus:ring-primary border-gray-300"></div><div class="ml-3 text-sm"><label for="squareLoss" class="font-medium text-gray-700">平方损失</label><p class="text-gray-500">追求精准接近21点</p></div></div><div class="flex items-start"><div class="flex items-center h-5"><input id="absoluteLoss" name="loss_type" type="radio" value="absolute" class="w-4 h-4 text-primary focus:ring-primary border-gray-300"></div><div class="ml-3 text-sm"><label for="absoluteLoss" class="font-medium text-gray-700">绝对损失</label><p class="text-gray-500">平衡爆牌风险和收益</p></div></div><div class="flex items-start"><div class="flex items-center h-5"><input id="zeroOneLoss" name="loss_type" type="radio" value="0-1" class="w-4 h-4 text-primary focus:ring-primary border-gray-300"></div><div class="ml-3 text-sm"><label for="zeroOneLoss" class="font-medium text-gray-700">0-1损失</label><p class="text-gray-500">极端规避爆牌</p></div></div></div><button id="recalculateBtn" class="w-full mt-4 bg-primary hover:bg-primary/90 text-white py-2 px-4 rounded-lg font-medium flex items-center justify-center btn-hover"><i class="fa fa-refresh mr-2"></i>重新计算</button></div></div><!-- 中间栏 --><div class="lg:col-span-6 space-y-6"><!-- 决策结果 --><div class="bg-white rounded-xl p-5 card-shadow"><div id="decisionContainer" class="bg-neutral rounded-lg p-4 mb-3"><div id="decisionText" class="text-lg font-medium text-center">请开始游戏或调整损失函数</div><!-- 决策进度条 --><div id="decisionProgressContainer" class="mt-4 hidden"><div class="flex justify-between text-xs mb-1"><span class="text-secondary">继续摸牌</span><span class="text-primary">停止摸牌</span></div><div class="h-6 bg-gray-200 rounded-full overflow-hidden"><div id="decisionProgressBar" class="h-full progress-gradient relative"><div id="decisionPointer" class="absolute top-0 h-full w-0.5 bg-white"></div></div></div><div class="flex justify-between text-xs mt-1"><span id="drawProbability">0%</span><span id="standProbability">0%</span></div></div></div></div><!-- 对手的情况 --><div class="bg-white rounded-xl p-5 card-shadow"><h3 class="text-lg font-semibold mb-4 flex items-center"><i class="fa fa-user-o text-secondary mr-2"></i>对手的手牌</h3><div class="flex flex-wrap gap-2 mb-3"><div id="dealerCards" class="flex flex-wrap gap-2"><!-- 对手的牌将在这里动态生成 --></div></div><div id="dealerStatus" class="text-sm font-medium">对手点数: ??? </div></div><!-- 自己的手牌 --><div class="bg-white rounded-xl p-5 card-shadow"><h3 class="text-lg font-semibold mb-4 flex items-center"><i class="fa fa-user text-primary mr-2"></i>你的手牌</h3><div class="flex flex-wrap gap-2 mb-5 min-h-[100px]"><div id="playerCards" class="flex flex-wrap gap-2"><!-- 玩家的牌将在这里动态生成 --></div></div><div class="flex justify-between items-center mb-4"><div><div class="text-sm text-gray-500">当前点数</div><div id="playerTotal" class="text-2xl font-bold">0</div></div><div><div class="text-sm text-gray-500">爆牌概率</div><div id="bustChance" class="text-2xl font-bold">0%</div></div></div><div class="flex gap-3" id="actionButtons"><button id="hitBtn" class="flex-1 bg-secondary hover:bg-secondary/90 text-white py-3 px-4 rounded-lg font-medium flex items-center justify-center btn-hover"><i class="fa fa-plus-circle mr-2"></i>继续摸牌</button><button id="standBtn" class="flex-1 bg-primary hover:bg-primary/90 text-white py-3 px-4 rounded-lg font-medium flex items-center justify-center btn-hover"><i class="fa fa-hand-paper-o mr-2"></i>停止摸牌</button><button id="restartBtn" class="bg-dark hover:bg-dark/90 text-white py-3 px-4 rounded-lg font-medium flex items-center justify-center btn-hover"><i class="fa fa-refresh mr-2"></i>重新开始</button></div><div id="gameResult" class="mt-4 hidden"><div class="rounded-lg p-4 text-center font-medium text-lg"></div></div></div></div><!-- 右侧栏 --><div class="lg:col-span-3 space-y-6"><!-- 游戏规则卡片 --><div class="bg-white rounded-xl p-5 card-shadow"><h3 class="text-lg font-semibold mb-4 flex items-center"><i class="fa fa-book text-primary mr-2"></i>游戏规则</h3><ul class="space-y-2 text-sm text-gray-700"><li class="flex items-start"><i class="fa fa-check-circle text-green-500 mt-1 mr-2"></i><span>目标:在尽可能的摸牌的同时,确保手牌总和不超过21点</span></li><li class="flex items-start"><i class="fa fa-check-circle text-green-500 mt-1 mr-2"></i><span>每张牌的点数:A(1), 2-10(面值), J/Q/K(0.5) 去掉了大小王</span></li><li class="flex items-start"><i class="fa fa-check-circle text-green-500 mt-1 mr-2"></i><span>爆牌:选手手牌总和超过21点(不管对手是否超出21点,都判为游戏失败)</span></li><li class="flex items-start"><i class="fa fa-check-circle text-green-500 mt-1 mr-2"></i><span>决策:根据当前手牌和剩余牌堆,决定是否继续摸牌</span></li></ul></div><!-- 损失函数解释卡片 --><div class="bg-white rounded-xl p-5 card-shadow"><h3 class="text-lg font-semibold mb-4 flex items-center"><i class="fa fa-area-chart text-primary mr-2"></i>损失函数</h3><div class="space-y-4 text-sm"><div><h4 class="font-medium mb-1">平方损失</h4><p class="text-gray-700">L(t,f) = (t−f)²</p><p class="text-gray-500 text-xs mt-1">追求精准接近21点,容易爆牌</p></div><div><h4 class="font-medium mb-1">绝对损失</h4><p class="text-gray-700">L(t,f) = |t−f|</p><p class="text-gray-500 text-xs mt-1">平衡爆牌风险和接近21点的收益</p></div><div><h4 class="font-medium mb-1">0-1损失</h4><p class="text-gray-700">L(t,f) = 0 (≤21) 或 1 (>21)</p><p class="text-gray-500 text-xs mt-1">只要有爆牌风险就倾向停止</p></div></div></div></div></div></div><script>// 扑克牌数据const suits = ['hearts', 'diamonds', 'clubs', 'spades'];const ranks = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K'];const cardValues = {'A': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9, '10': 10, 'J': 0.5, 'Q': 0.5, 'K': 0.5};// 游戏状态let gameState = {deck: [],playerCards: [],dealerCards: [],playerTotal: 0,dealerTotal: 0,gameOver: false,initialPlayedCards: [] // 存储初始随机已出现的牌};// DOM 元素const playerCardsEl = document.getElementById('playerCards');const dealerCardsEl = document.getElementById('dealerCards');const playerTotalEl = document.getElementById('playerTotal');const dealerStatusEl = document.getElementById('dealerStatus');const hitBtn = document.getElementById('hitBtn');const standBtn = document.getElementById('standBtn');const restartBtn = document.getElementById('restartBtn');const gameResultEl = document.getElementById('gameResult');const decisionTextEl = document.getElementById('decisionText');const lossComparisonEl = document.getElementById('lossComparison');const expectedLossValueEl = document.getElementById('expectedLossValue');const stopLossValueEl = document.getElementById('stopLossValue');const winRateContainerEl = document.getElementById('winRateContainer');const playedCardsEl = document.getElementById('playedCards');const remainingCardsCountEl = document.getElementById('remainingCardsCount');const bustChanceEl = document.getElementById('bustChance');const recalculateBtn = document.getElementById('recalculateBtn');const decisionProgressContainerEl = document.getElementById('decisionProgressContainer');const decisionProgressBarEl = document.getElementById('decisionProgressBar');const decisionPointerEl = document.getElementById('decisionPointer');const drawProbabilityEl = document.getElementById('drawProbability');const standProbabilityEl = document.getElementById('standProbability');// 初始化游戏function initGame() {// 创建一副新牌gameState.deck = [];suits.forEach(suit => {ranks.forEach(rank => {gameState.deck.push({ rank, suit, value: cardValues[rank] });});});// 随机移除10-20张牌作为已出现的牌const numInitialCards = Math.floor(Math.random() * 10) + 13; // 13-22张gameState.initialPlayedCards = [];for (let i = 0; i < numInitialCards; i++) {if (gameState.deck.length === 0) break;const randomIndex = Math.floor(Math.random() * gameState.deck.length);const card = gameState.deck.splice(randomIndex, 1)[0];gameState.initialPlayedCards.push(card);}// 清空玩家和对手的牌gameState.playerCards = [];gameState.dealerCards = [];gameState.playerTotal = 0;gameState.dealerTotal = 0;gameState.gameOver = false;// 重置UIplayerCardsEl.innerHTML = '';dealerCardsEl.innerHTML = '';playerTotalEl.textContent = '0';dealerStatusEl.textContent = '对手点数: ???';gameResultEl.classList.add('hidden');gameResultEl.querySelector('div').textContent = '';hitBtn.disabled = false;standBtn.disabled = false;playedCardsEl.innerHTML = '';// 显示初始已出现的牌updatePlayedCards();// 对手随机1张牌const dealerCardCount = 1; for (let i = 0; i < dealerCardCount; i++) {const card = gameState.deck.pop();gameState.dealerCards.push(card);// 第一张牌显示,其余隐藏renderCard(dealerCardsEl, card, i === 0);}// 玩家初始1张牌hitPlayer();// 更新决策updateDecision();}// 洗牌function shuffleDeck() {for (let i = gameState.deck.length - 1; i > 0; i--) {const j = Math.floor(Math.random() * (i + 1));[gameState.deck[i], gameState.deck[j]] = [gameState.deck[j], gameState.deck[i]];}}// 玩家摸牌function hitPlayer() {if (gameState.gameOver) return;const card = gameState.deck.pop();gameState.playerCards.push(card);renderCard(playerCardsEl, card, true);updatePlayerTotal();// 更新已出牌显示updatePlayedCards();// 检查是否爆牌if (gameState.playerTotal > 21) {if (gameState.dealerTotal<22){endGame('你爆牌了,输了!');}else{endGame('都爆牌了,平局!');}} else {// 更新决策updateDecision();}}// 对手摸牌(AI逻辑)function dealerPlay() {if (gameState.gameOver) return;// 显示对手的隐藏牌dealerCardsEl.innerHTML = '';gameState.dealerCards.forEach((card, index) => {renderCard(dealerCardsEl, card, true);});// 计算对手点数updateDealerTotal();dealerStatusEl.textContent = `对手点数: ${gameState.dealerTotal}`;// 对手AI逻辑:小于17点继续摸牌while (gameState.dealerTotal < 17) {const card = gameState.deck.pop();gameState.dealerCards.push(card);renderCard(dealerCardsEl, card, true);// 更新已出牌显示updatePlayedCards();updateDealerTotal();dealerStatusEl.textContent = `对手点数: ${gameState.dealerTotal}`;// 检查对手是否爆牌if (gameState.dealerTotal > 21 ) {if (gameState.playerTotal<22){endGame('对手爆牌了,你赢了!');}else{endGame('都爆牌了,平局!');}return;}// 添加延迟,让摸牌过程更自然awaitSleep(500);}// 比较点数compareHands();}// 比较手牌function compareHands() {if (gameState.playerTotal > gameState.dealerTotal) {endGame('你赢了!');} else if (gameState.playerTotal < gameState.dealerTotal) {endGame('你输了!');} else {endGame('平局!');}}// 结束游戏function endGame(message) {gameState.gameOver = true;hitBtn.disabled = true;standBtn.disabled = true;gameResultEl.classList.remove('hidden');gameResultEl.querySelector('div').textContent = message;gameResultEl.querySelector('div').className = 'rounded-lg p-4 text-center font-medium text-lg';if (message.includes('赢')) {gameResultEl.querySelector('div').classList.add('bg-success/10', 'text-success');} else if (message.includes('输')) {gameResultEl.querySelector('div').classList.add('bg-danger/10', 'text-danger');} else {gameResultEl.querySelector('div').classList.add('bg-neutral', 'text-gray-700');}decisionTextEl.textContent = "游戏结束(下滑查看对局结果)";}// 渲染卡牌function renderCard(container, card, faceUp) {const cardElement = document.createElement('div');cardElement.className = 'card-flip w-16 h-24 rounded-lg flex items-center justify-center shadow-md';let suitClass = '';let suitSymbol = '';switch(card.suit) {case 'hearts':suitClass = 'text-red-600';suitSymbol = '♥';break;case 'diamonds':suitClass = 'text-red-600';suitSymbol = '♦';break;case 'clubs':suitClass = 'text-gray-800';suitSymbol = '♣';break;case 'spades':suitClass = 'text-gray-800';suitSymbol = '♠';break;}const cardFront = `<div class="card-front flex flex-col items-center justify-center w-full h-full bg-white rounded-lg border border-gray-200 p-1 ${faceUp ? '' : 'hidden'}"><div class="self-start text-xs ${suitClass}">${card.rank} ${suitSymbol}</div><div class="text-2xl ${suitClass}">${suitSymbol}</div><div class="self-end text-xs ${suitClass} rotate-180">${card.rank} ${suitSymbol}</div></div>`;const cardBack = `<div class="card-back w-full h-full bg-primary/10 flex items-center justify-center rounded-lg border border-gray-200 ${faceUp ? 'hidden' : ''}"><i class="fa fa-diamond text-primary text-2xl"></i></div>`;cardElement.innerHTML = cardFront + cardBack;container.appendChild(cardElement);// 添加翻牌动画if (!faceUp) {setTimeout(() => {cardElement.classList.add('card-flipped');cardElement.querySelector('.card-front').classList.remove('hidden');cardElement.querySelector('.card-back').classList.add('hidden');}, 500);}}// 更新玩家点数function updatePlayerTotal() {let total = 0;let aces = 0;gameState.playerCards.forEach(card => {total += card.value;if (card.rank === 'A') aces++;});gameState.playerTotal = total;playerTotalEl.textContent = total;// 更新爆牌概率updateBustChance();}// 更新对手点数function updateDealerTotal() {let total = 0;let aces = 0;gameState.dealerCards.forEach(card => {total += card.value;if (card.rank === 'A') aces++;});gameState.dealerTotal = total;}// 更新已出牌显示function updatePlayedCards() {playedCardsEl.innerHTML = '';// 合并初始已出现的牌和当前游戏中已出现的牌const allPlayedCards = [...gameState.initialPlayedCards, ...gameState.playerCards];// 只显示已翻开的牌allPlayedCards.forEach(card => {const cardElement = document.createElement('div');cardElement.className = 'w-8 h-12 rounded border border-gray-200 bg-white flex items-center justify-center text-xs';let suitClass = '';let suitSymbol = '';switch(card.suit) {case 'hearts':suitClass = 'text-red-600';suitSymbol = '♥';break;case 'diamonds':suitClass = 'text-red-600';suitSymbol = '♦';break;case 'clubs':suitClass = 'text-gray-800';suitSymbol = '♣';break;case 'spades':suitClass = 'text-gray-800';suitSymbol = '♠';break;}cardElement.innerHTML = `<div class="${suitClass}">${card.rank}${suitSymbol}</div>`;playedCardsEl.appendChild(cardElement);});// 更新剩余牌数量remainingCardsCountEl.textContent = `剩余牌: ${gameState.deck.length}`;}// 更新爆牌概率function updateBustChance() {if (gameState.playerTotal >= 21) {bustChanceEl.textContent = gameState.playerTotal > 21 ? '100%' : '0%';return;}// 计算爆牌概率const cardsLeft = gameState.deck.length;let bustCards = 0;gameState.deck.forEach(card => {if (gameState.playerTotal + card.value > 21) {bustCards++;}});const bustChance = (bustCards / cardsLeft) * 100;bustChanceEl.textContent = `${bustChance.toFixed(1)}%`;}// 更新决策建议function updateDecision() {const lossType = document.querySelector('input[name="loss_type"]:checked').value;const currentSum = gameState.playerTotal;// 计算期望损失const { drawLoss, stopLoss, decision, drawProbability, standProbability } = calculateExpectedLoss(currentSum, lossType);// 更新决策文本decisionTextEl.textContent = decision;decisionTextEl.style.color = 'red';}// 计算期望损失function calculateExpectedLoss(currentSum, lossType) {// 计算剩余牌的概率分布const cardCounts = {};gameState.deck.forEach(card => {cardCounts[card.value] = (cardCounts[card.value] || 0) + 1;});const totalRemaining = gameState.deck.length;const cardProbabilities = {};Object.keys(cardCounts).forEach(value => {cardProbabilities[value] = cardCounts[value] / totalRemaining;});// 计算摸牌期望损失let drawLoss = 0;let winCount = 0;Object.keys(cardProbabilities).forEach(value => {const cardValue = parseInt(value);const newSum = currentSum + cardValue;let loss;if (lossType === 'square') {loss = newSum <= 21 ? Math.pow(21 - newSum, 2) : Math.pow(newSum - 21, 2);} else if (lossType === 'absolute') {loss = newSum <= 21 ? Math.abs(21 - newSum) : (newSum - 21);} else if (lossType === '0-1') {loss = newSum <= 21 ? 0 : 1;}// 计算可能的胜率(简化模型)if (newSum <= 21) {// 假设对手总和小于等于21的概率为0.5// 如果我们的点数大于对手,我们赢winCount += cardProbabilities[value] * 0.5;}drawLoss += loss * cardProbabilities[value];});// 计算停止损失let stopLoss;if (lossType === 'square') {stopLoss = Math.pow(21 - currentSum, 2);} else if (lossType === 'absolute') {stopLoss = Math.abs(21 - currentSum);} else if (lossType === '0-1') {stopLoss = currentSum <= 21 ? 0 : 1;}// 计算胜率const drawProbability = winCount;const standProbability = currentSum <= 21 ? 0.5 : 0; // 简化模型// 做出决策const decision = drawLoss < stopLoss ? '建议继续摸牌' : '建议停止摸牌';return { drawLoss, stopLoss, decision, drawProbability, standProbability };}// 计算胜率function calculateWinRate(currentSum, isDraw) {if (!isDraw) {// 停止摸牌:胜率取决于当前总和与对手可能总和的比较// 简化模型:计算对手爆牌的概率const dealerBustChance = calculateDealerBustChance();return dealerBustChance;}// 继续摸牌:计算摸一张牌后不爆且最终获胜的概率const cardsLeft = gameState.deck.length;let safeCards = 0;let winProbability = 0;gameState.deck.forEach(card => {if (currentSum + card.value <= 21) {safeCards++;// 计算摸这张牌后的胜率const newSum = currentSum + card.value;const dealerBustChance = calculateDealerBustChance(newSum);winProbability += dealerBustChance / cardsLeft;}});return winProbability;}// 计算对手爆牌的概率(简化模型)function calculateDealerBustChance(playerSum = 0) {return 0.5;}// 辅助函数:等待function awaitSleep(ms) {return new Promise(resolve => setTimeout(resolve, ms));}// 事件监听hitBtn.addEventListener('click', hitPlayer);standBtn.addEventListener('click', dealerPlay);restartBtn.addEventListener('click', initGame);recalculateBtn.addEventListener('click', updateDecision);// 初始化游戏initGame();</script>
</body>
</html>
在交互的过程中发现0-1损失相较于其他两个更加保守,而平方损失和绝对损失理论上,平方损失会更加激进博取更大的点数和。
(此局)停止摸牌后的结果
当然,也会在继续摸牌后,手头的牌爆了。。。同时,也会存在停止摸牌后,和对手的手牌相同或者反而比我们的大,导致输掉比赛 ┭┮﹏┭┮
借此交互场景来看:
平方损失下,最优解对应 “条件期望”—— 就像预估摸牌后最接近 21 的理想均值,追求长期误差平方和最小;一旦换损失函数,比如怕爆牌时用 0-1 损失,最优解会变成 “条件中位数”(规避极端值)甚至 “条件众数”(选最常出现的安全牌面)。
本质上,概率分布是 “量化不确定性的语言”(比如算出摸每张牌的概率),损失函数是 “把模糊概率翻译成行动的规则”(不同损失对应不同风险偏好)。模型先通过数据算出 “各种结果的可能性”(算概率),再用损失函数把可能性转化成 “当下该摸还是该停” 的明确指令(做决策),这就搭起了从 “知概率” 到 “行决策” 的桥梁,让抽象的概率模型真正能指导实际选择。