與胸圍的鱸魚體重估算模型:從散點(diǎn)圖到圓柱體近似)
簡(jiǎn)介這份PDF資源圍繞鱸魚體重與身長(zhǎng)、胸圍的數(shù)學(xué)建模展開(kāi)面向參加數(shù)學(xué)建模競(jìng)賽的學(xué)生、數(shù)據(jù)分析初學(xué)者以及需要生物量估算方法的科研人員。資源以垂釣俱樂(lè)部放生獎(jiǎng)勵(lì)為背景解決僅憑軟尺測(cè)量身長(zhǎng)和胸圍來(lái)估算鱸魚體重的問(wèn)題屬于數(shù)學(xué)建模入門到進(jìn)階的典型案例。壓縮包內(nèi)共1個(gè)PDF文件大小約208KB內(nèi)容涵蓋問(wèn)題分析、模型假設(shè)、符號(hào)說(shuō)明、MATLAB散點(diǎn)圖與多項(xiàng)式擬合、相對(duì)誤差檢驗(yàn)以及完整程序代碼讀者可據(jù)此掌握二次函數(shù)擬合、線性回歸和圓柱體近似建模三種思路并得到W1.6247L2-59.3124L709.7392、W92C-1497.5及W0.0327LC2等具體模型。目前已有233人學(xué)習(xí)適合用來(lái)練習(xí)數(shù)據(jù)擬合、誤差分析和論文寫作規(guī)范。1. 一把軟尺估魚重這份鱸魚體重模型到底解決了什么問(wèn)題釣上一條鱸魚手邊只有一把軟尺沒(méi)有秤怎么知道它多重這不是腦筋急轉(zhuǎn)彎而是一個(gè)真實(shí)的建模場(chǎng)景垂釣俱樂(lè)部鼓勵(lì)放生按魚的重量給獎(jiǎng)勵(lì)但現(xiàn)場(chǎng)只有軟尺。于是問(wèn)題變成——用身長(zhǎng)和胸圍兩個(gè)可測(cè)量反推體重。這份《鱸魚體重與身長(zhǎng)、胸圍模型.pdf》給出的就是完整解法從散點(diǎn)圖到多項(xiàng)式擬合從單變量模型到圓柱體近似下的雙變量模型最后落到一組可以直接抄進(jìn) MATLAB 的代碼。它適合正在學(xué)數(shù)學(xué)建模、需要一份「數(shù)據(jù)少但流程全」的擬合案例的人也適合想搞明白最小二乘和量綱分析怎么配合的工程師。8 條魚的數(shù)據(jù)三種模型一條從測(cè)量到估算的完整鏈路。2. 從散點(diǎn)圖到二次擬合身長(zhǎng)單變量模型怎么落地2.1 為什么先看散點(diǎn)圖而不是直接上公式拿到 8 組數(shù)據(jù)第一反應(yīng)不該是套公式而是先看形狀。身長(zhǎng)從 31.8 cm 到 45.1 cm體重從 454 g 到 1389 g跨度不小。如果直接假設(shè)線性關(guān)系很可能把明顯的彎曲趨勢(shì)壓平。常見(jiàn)做法是先用 MATLAB 畫散點(diǎn)圖肉眼判斷趨勢(shì)是直線、拋物線還是指數(shù)。這份資料里身長(zhǎng)與體重的散點(diǎn)圖呈現(xiàn)出輕微上翹的弧度提示二次函數(shù)比一次函數(shù)更合適。這一步不是玄學(xué)而是給后續(xù)擬合定方向——選錯(cuò)函數(shù)形式后面誤差再小也是假的。2.2 用 polyfit 做二次擬合的完整流程MATLAB 的polyfit是最直接的入口。把身長(zhǎng)作為自變量 x體重作為因變量 z擬合階數(shù)設(shè)為 2就能拿到二次項(xiàng)、一次項(xiàng)和常數(shù)項(xiàng)系數(shù)。資料中給出的結(jié)果是% 身長(zhǎng)與體重的二次擬合 x [36.8 31.8 43.8 36.8 32.1 45.1 35.9 32.1]; % 身長(zhǎng) cm z [765 482 1162 737 482 1389 652 454]; % 體重 g v1 polyfit(x, z, 2); % 二次多項(xiàng)式擬合v1 為系數(shù)向量polyfit返回的系數(shù)按降冪排列即v1(1)是二次項(xiàng)系數(shù)v1(2)是一次項(xiàng)系數(shù)v1(3)是常數(shù)項(xiàng)。資料中擬合方程為W 1.6247*L^2 - 59.3124*L 709.7392。這里要注意polyfit本身不做誤差分析它只負(fù)責(zé)最小二乘意義下的系數(shù)求解。系數(shù)拿到后必須自己算相對(duì)誤差否則不知道這個(gè)模型能不能用。2.3 相對(duì)誤差檢驗(yàn)擬合值到底能不能信擬合完不能只看曲線穿過(guò)幾個(gè)點(diǎn)要逐條算相對(duì)誤差。資料中的做法是把 8 條魚的身長(zhǎng)代入擬合方程得到估計(jì)體重再和實(shí)際體重比。表一給出的相對(duì)誤差大多在 5% 以內(nèi)個(gè)別點(diǎn)稍高但整體可接受。這里有個(gè)容易翻車的地方相對(duì)誤差的分母是實(shí)際值不是估計(jì)值。如果寫反了誤差會(huì)被系統(tǒng)性放大或縮小結(jié)論就偏了。常見(jiàn)做法是寫一個(gè)小循環(huán)逐條輸出實(shí)際值、估計(jì)值和相對(duì)誤差百分比方便一眼看出哪個(gè)點(diǎn)偏離最大。% 逐條計(jì)算相對(duì)誤差 L [36.8 31.8 43.8 36.8 32.1 45.1 35.9 32.1]; W_actual [765 482 1162 737 482 1389 652 454]; W_est 1.6247*L.^2 - 59.3124*L 709.7392; rel_err abs(W_est - W_actual) ./ W_actual * 100; disp(table(L, W_actual, W_est, rel_err, ... VariableNames, {身長(zhǎng), 實(shí)際體重, 估計(jì)體重, 相對(duì)誤差百分比}));這段代碼的關(guān)鍵是./而不是/因?yàn)橐獙?duì)每個(gè)元素分別做除法。abs取絕對(duì)值避免正負(fù)誤差相互抵消。輸出成表格后哪個(gè)點(diǎn)誤差大、要不要剔除一目了然。2.4 擬合圖怎么畫才不誤導(dǎo)資料里畫擬合圖的方式是先畫原始散點(diǎn)再在同一個(gè)圖上疊加一條密集采樣的擬合曲線。這里有個(gè)細(xì)節(jié)——擬合曲線的自變量范圍不要超出原始數(shù)據(jù)太多。身長(zhǎng)數(shù)據(jù)在 31.8 到 45.1 之間如果把橫軸拉到 20 到 60曲線兩端會(huì)劇烈彎曲看起來(lái)像是模型能外推很遠(yuǎn)實(shí)際上二次函數(shù)外推風(fēng)險(xiǎn)很大。常見(jiàn)做法是讓擬合曲線的范圍略寬于數(shù)據(jù)范圍即可比如 30 到 50既能看清趨勢(shì)又不至于誤導(dǎo)。% 身長(zhǎng)與體重?cái)M合圖 x1 30:0.1:50; % 密集采樣范圍略寬于原始數(shù)據(jù) z1 1.6247*x1.^2 - 59.3124*x1 709.7392; plot(x, z, *, x1, z1, -); xlabel(身長(zhǎng) (cm)); ylabel(體重 (g)); title(身長(zhǎng)與體重?cái)M合圖); legend(原始數(shù)據(jù), 二次擬合曲線); grid on;x1的步長(zhǎng) 0.1 是為了讓曲線平滑步長(zhǎng)太大曲線會(huì)變成折線。legend和grid on不是裝飾是讓圖能直接放進(jìn)報(bào)告里別人不用猜哪條線是什么。3. 胸圍線性模型與圓柱體近似雙變量模型怎么推3.1 胸圍單變量為什么線性就夠胸圍數(shù)據(jù)從 21.3 cm 到 31.8 cm體重跨度同樣大。資料中胸圍與體重的散點(diǎn)圖看起來(lái)更接近直線所以用一次多項(xiàng)式擬合。polyfit(y, z, 1)返回兩個(gè)系數(shù)對(duì)應(yīng)斜率和截距。擬合結(jié)果是W 92*C - 1497.5。這里斜率 92 的含義是胸圍每增加 1 cm體重平均增加約 92 g。截距為負(fù)說(shuō)明這個(gè)線性關(guān)系只在胸圍大于約 16.3 cm 時(shí)才有物理意義——胸圍太小的時(shí)候公式會(huì)給出負(fù)體重這顯然不合理。所以線性模型有適用范圍不能無(wú)腦外推。% 胸圍與體重的線性擬合 y [24.8 21.3 27.9 24.8 21.6 31.8 22.9 21.6]; % 胸圍 cm z [765 482 1162 737 482 1389 652 454]; % 體重 g v2 polyfit(y, z, 1); % 一次多項(xiàng)式擬合 % v2(1) 為斜率v2(2) 為截距polyfit的第三個(gè)參數(shù)是階數(shù)1 代表一次。返回的v2是長(zhǎng)度為 2 的向量。如果數(shù)據(jù)點(diǎn)明顯不共線一次擬合的誤差會(huì)很大這時(shí)候要回頭看散點(diǎn)圖考慮是否需要換函數(shù)形式。3.2 圓柱體假設(shè)從量綱分析到 W αLC2單獨(dú)看身長(zhǎng)或胸圍都有局限因?yàn)轸~不是只長(zhǎng)一個(gè)方向。資料中的關(guān)鍵假設(shè)是鱸魚體態(tài)近似為與胸圍等周長(zhǎng)、與身長(zhǎng)等高的圓柱體。圓柱體積等于底面積乘高底面積用周長(zhǎng)表示是C2/(4π)所以體積正比于L*C2。質(zhì)量等于密度乘體積于是W α*L*C2其中 α 是待定系數(shù)包含了密度和 π 的常數(shù)部分。這個(gè)推導(dǎo)不是純數(shù)學(xué)游戲它給出了一個(gè)結(jié)構(gòu)化的模型形式——不是隨便湊的二次多項(xiàng)式而是有物理量綱支撐的冪函數(shù)關(guān)系。常見(jiàn)做法是先把L*C2算出來(lái)作為一個(gè)新變量再用最小二乘求 α。3.3 用最小二乘求 α 的代碼實(shí)現(xiàn)資料中的做法很直接把C2和L相乘得到z C2*L然后α W/z最后取 8 條魚的平均值。這本質(zhì)上是最小二乘在過(guò)原點(diǎn)線性模型下的解析解。代碼只有幾行但每一步都有含義。% 圓柱體模型 W alpha * L * C^2 L [36.8 31.8 43.8 36.8 32.1 45.1 35.9 32.1]; % 身長(zhǎng) cm C [24.8 21.3 27.9 24.8 21.6 31.8 22.9 21.6]; % 胸圍 cm W [765 482 1162 737 482 1389 652 454]; % 體重 g V L .* C.^2; % 構(gòu)造自變量 L*C^2 alpha_each W ./ V; % 每條魚單獨(dú)求 alpha alpha mean(alpha_each); % 取平均 fprintf(alpha %.4f\n, alpha);V L .* C.^2用的是點(diǎn)乘和點(diǎn)冪因?yàn)橐獙?duì)每個(gè)元素分別運(yùn)算。alpha_each是每條魚單獨(dú)算出的系數(shù)如果數(shù)據(jù)質(zhì)量好這些值應(yīng)該比較接近如果某個(gè)值明顯偏離說(shuō)明那條魚的數(shù)據(jù)可能有測(cè)量誤差。取平均是最簡(jiǎn)單的融合方式也可以考慮加權(quán)平均但 8 條魚的數(shù)據(jù)量下簡(jiǎn)單平均足夠。3.4 三模型對(duì)比什么時(shí)候用哪個(gè)資料給出了三個(gè)模型身長(zhǎng)二次、胸圍線性、身長(zhǎng)胸圍圓柱體。它們不是互相替代的關(guān)系而是適用場(chǎng)景不同。只有身長(zhǎng)數(shù)據(jù)時(shí)用二次模型只有胸圍數(shù)據(jù)時(shí)用線性模型兩個(gè)都有時(shí)用圓柱體模型。從表三的相對(duì)誤差看圓柱體模型的整體誤差更小因?yàn)樗瑫r(shí)利用了身長(zhǎng)和胸圍的信息。但要注意圓柱體模型假設(shè)魚是均勻圓柱實(shí)際魚體是流線型頭尾細(xì)、中間粗所以這個(gè)模型在魚特別瘦或特別胖時(shí)誤差會(huì)變大。常見(jiàn)做法是把它當(dāng)作一個(gè)基準(zhǔn)如果現(xiàn)場(chǎng)測(cè)量條件允許再根據(jù)魚的實(shí)際體型做微調(diào)。模型自變量函數(shù)形式適用場(chǎng)景主要局限身長(zhǎng)二次LW aL2 bL c只有身長(zhǎng)數(shù)據(jù)外推風(fēng)險(xiǎn)大忽略胸圍胸圍線性CW kC b只有胸圍數(shù)據(jù)小胸圍時(shí)出現(xiàn)負(fù)值圓柱體L, CW αLC2兩個(gè)數(shù)據(jù)都有假設(shè)體型均勻忽略魚體形狀差異4. 避坑與排查8 條魚數(shù)據(jù)建模時(shí)最容易翻車的五個(gè)點(diǎn)4.1 現(xiàn)象polyfit 報(bào)錯(cuò)或結(jié)果明顯不對(duì)原因通常是自變量和因變量長(zhǎng)度不一致或者數(shù)據(jù)里混入了非數(shù)值。排查時(shí)先size(x)和size(z)確認(rèn)兩個(gè)向量長(zhǎng)度相同。如果從 Excel 復(fù)制數(shù)據(jù)常見(jiàn)問(wèn)題是某個(gè)單元格是文本格式MATLAB 讀進(jìn)來(lái)變成 NaN。解決方法是sum(isnan(x))和sum(isnan(z))先定位再清理。4.2 現(xiàn)象擬合曲線穿過(guò)所有點(diǎn)但預(yù)測(cè)新數(shù)據(jù)誤差很大這是過(guò)擬合的典型表現(xiàn)。8 個(gè)點(diǎn)用二次擬合已經(jīng)接近飽和如果強(qiáng)行用三次或四次曲線會(huì)扭曲去穿過(guò)每個(gè)點(diǎn)但新數(shù)據(jù)一來(lái)就崩。判斷方法是看擬合階數(shù)是否接近數(shù)據(jù)點(diǎn)數(shù)量。常見(jiàn)做法是保持階數(shù)遠(yuǎn)小于點(diǎn)數(shù)二次擬合 8 個(gè)點(diǎn)是合理的三次就要謹(jǐn)慎。4.3 現(xiàn)象相對(duì)誤差計(jì)算出現(xiàn) Inf 或 NaN原因通常是實(shí)際體重為零或空值。檢查W_actual里有沒(méi)有 0 或 NaN。如果有要么剔除該點(diǎn)要么改用絕對(duì)誤差。另一個(gè)原因是分母用了估計(jì)值且估計(jì)值為零但這種情況在體重?cái)?shù)據(jù)里少見(jiàn)。解決方法是先f(wàn)ind(W_actual 0)確認(rèn)后處理。4.4 現(xiàn)象圓柱體模型算出的 α 波動(dòng)很大原因可能是某條魚的胸圍或身長(zhǎng)測(cè)量有誤。比如胸圍 31.8 cm 那條魚體重 1389 g單獨(dú)算出的 α 可能和其他魚差很多。排查時(shí)把a(bǔ)lpha_each打印出來(lái)看哪個(gè)值偏離均值超過(guò) 20%。如果確認(rèn)是測(cè)量問(wèn)題可以剔除該點(diǎn)后重新求平均但要在報(bào)告中說(shuō)明。4.5 現(xiàn)象畫出的擬合圖橫軸范圍太大導(dǎo)致曲線變形這是外推的視覺(jué)誤導(dǎo)。二次函數(shù)在數(shù)據(jù)范圍外會(huì)快速上升或下降如果橫軸拉到很遠(yuǎn)曲線看起來(lái)像要飛出去。解決方法是把橫軸范圍限制在數(shù)據(jù)最小值和最大值附近比如身長(zhǎng) 30 到 50胸圍 20 到 35。這樣圖更誠(chéng)實(shí)也更容易看出擬合好壞。5. 從 8 條魚到現(xiàn)場(chǎng)估算一個(gè)可復(fù)用的快速估重技巧把模型落到現(xiàn)場(chǎng)最實(shí)際的問(wèn)題不是公式多漂亮而是怎么在釣點(diǎn)快速算出來(lái)。我的習(xí)慣是提前把三個(gè)模型的系數(shù)存進(jìn)手機(jī)計(jì)算器或者一張小卡片現(xiàn)場(chǎng)量完身長(zhǎng)和胸圍直接代入圓柱體模型W 0.0327 * L * C2。這個(gè)公式只需要乘法和平方心算也能估個(gè)大概。比如身長(zhǎng) 40 cm、胸圍 26 cmC2 676L*C2 27040乘以 0.0327 約等于 884 g。實(shí)際魚可能在 850 到 920 g 之間作為獎(jiǎng)勵(lì)分檔足夠用了。但這里有個(gè)血淚經(jīng)驗(yàn)圓柱體模型對(duì)胸圍特別敏感因?yàn)樾貒瞧椒巾?xiàng)。胸圍量錯(cuò) 1 cm體重估計(jì)可能差 8% 到 10%。所以現(xiàn)場(chǎng)測(cè)量時(shí)軟尺要貼著魚體最粗處繞一圈不要拉太緊也不要太松。如果魚掙扎得厲害量?jī)纱稳∑骄?。身長(zhǎng)的測(cè)量相對(duì)寬容從吻端到尾鰭基部即可差 1 cm 對(duì)結(jié)果影響約 2.5%。如果想進(jìn)一步提高精度可以在放生后記錄實(shí)際體重如果有秤積累更多數(shù)據(jù)后重新擬合 α。8 條魚的數(shù)據(jù)量偏小α 的置信區(qū)間其實(shí)不窄。常見(jiàn)做法是至少積累 20 到 30 條魚的數(shù)據(jù)再按季節(jié)或水域分組看 α 是否穩(wěn)定。如果不同水域的 α 差異明顯說(shuō)明魚體密度或體型有系統(tǒng)性差異這時(shí)候就需要分水域建模而不是用一個(gè)全局系數(shù)。還有一個(gè)容易被忽略的點(diǎn)模型假設(shè)魚體是圓柱但鱸魚實(shí)際是側(cè)扁的胸圍相同的情況下體高和體寬的比例會(huì)影響體積。如果現(xiàn)場(chǎng)能額外量一個(gè)體高可以嘗試把模型修正為W α * L * C * H的形式其中 H 是體高。但這需要更多數(shù)據(jù)來(lái)驗(yàn)證8 條魚不夠。所以這份資料的價(jià)值在于給出一個(gè)完整的、可復(fù)現(xiàn)的基線流程而不是一個(gè)終極公式。從那以后我每次做類似的小樣本擬合都會(huì)先把散點(diǎn)圖、擬合階數(shù)、相對(duì)誤差和適用范圍四件事過(guò)一遍缺一個(gè)都不放心。希望幫到你。本文還有配套的精品資源點(diǎn)擊獲取