03_迭代建模

3 迭代建模

套用喬治的話,“所有的模型都是錯(cuò)誤的,但是有些模型比其他模型更加錯(cuò)誤。“在這一章中,我們將展示我們?nèi)绾螠p少模型的錯(cuò)誤。

作為一個(gè)例子,我們將回顧上一章中的自行車模型,考慮其優(yōu)缺點(diǎn),并逐步改進(jìn)。我們也將拭目以待,使用模型了解系統(tǒng)行為并進(jìn)行評(píng)估的方法,旨在使它的設(shè)計(jì)完成更好地工作。

3.1迭代建模

到目前為止,我們的模型都很簡(jiǎn)單,不過它是基于不切實(shí)際的假設(shè)。在繼續(xù)之前,請(qǐng)花點(diǎn)時(shí)間回顧一下上一章的模型。它基于什么假設(shè)?列出這個(gè)模型可能不現(xiàn)實(shí)的方式;也就是說,模型和現(xiàn)實(shí)世界之間有什么區(qū)別?

以下是我列表上的一些差異:

1.在模型中,學(xué)生在任何一分鐘內(nèi)到達(dá)的可能性相等。在現(xiàn)實(shí)中,這種可能性取決于一天中的特定時(shí)間、一周中的哪一天等等。

2.該模型沒有考慮從一個(gè)自行車站到另一個(gè)自行車站的旅行時(shí)間。

3.模型不檢查是否有自行車,因此自行車的數(shù)量有可能為負(fù)數(shù)(正如您在一些模擬中注意到的)。

其中一些建模決策比其他決策更好。例如,如果我們?cè)诙虝r(shí)間內(nèi)(比如一個(gè)小時(shí))模擬系統(tǒng),第一個(gè)假設(shè)可能是合理的。

第二個(gè)假設(shè)不太現(xiàn)實(shí),但它可能不會(huì)對(duì)結(jié)果產(chǎn)生太大影響,這取決于我們使用模型的目的。

另一方面,第三個(gè)假設(shè)似乎有問題,而且相對(duì)容易修正。在第3.4節(jié)中,我們將會(huì)講到。

這個(gè)過程,從一個(gè)簡(jiǎn)單的模型開始,識(shí)別出最重要的問題,并逐步改進(jìn),稱為迭代建模。

對(duì)于任何現(xiàn)實(shí)/物理系統(tǒng),都有許多可能的模型,基于不同的假設(shè)和簡(jiǎn)化。開發(fā)一個(gè)對(duì)預(yù)期目的來說足夠好的模型通常需要多次迭代,但并會(huì)產(chǎn)生不比必要的復(fù)雜。

3.2多個(gè)狀態(tài)對(duì)象

在繼續(xù)之前,我想對(duì)上一章的代碼做一些修改。首先,我將概括我們編寫的函數(shù),以便它們將狀態(tài)對(duì)象作為參數(shù)。然后,我將通過添加文檔使代碼更具可讀性。

以下是上一章bike_to_wellesley的功能之一:

def bike_to_wellesley():
    bikeshare.olin -= 1
    bikeshare.wellesley += 1

調(diào)用此函數(shù)時(shí),它將修改bikeshare。只要只有一個(gè)狀態(tài)對(duì)象,那就好了,但是如果世界上有不止一個(gè)自行車共享系統(tǒng)呢?或者如果我們想運(yùn)行多個(gè)模擬呢?

如果將狀態(tài)對(duì)象作為參數(shù),則此函數(shù)將更加靈活。下面是這樣的:

def bike_to_wellesley(state):
    state.olin -= 1
    state.wellesley += 1

參數(shù)的名稱是state而不是bikeshare作為提示,state的值可以是任何state對(duì)象,而不僅僅是bikeshare。

這個(gè)版本的bike-to-wellesley需要一個(gè)State對(duì)象作為參數(shù),因此,我們必須提供一個(gè):

bike_to_wellesley(bikeshare)

同樣,我們提供的實(shí)際參數(shù)(argumenet)被分配給形式參數(shù)(parameter),因此,此函數(shù)調(diào)用的效果和如下一樣:

state = bikeshare

state.olin -= 1

state.wellesley += 1

現(xiàn)在,我們可以創(chuàng)建任意多個(gè)狀態(tài)對(duì)象:

bikeshare1 = State(olin=10, wellesley=2)
bikeshare2 = State(olin=2, wellesley=10) 

并獨(dú)立更新:

bike_to_wellesley(bikeshare1)
bike_to_wellesley(bikeshare2) 

bikeshare1中的更改不會(huì)影響bikeshare2,反之亦然。所以我們可以模擬不同的自行車共享系統(tǒng),或者對(duì)同一系統(tǒng)運(yùn)行多個(gè)模擬。

3.3 文檔

到目前為止,代碼的另一個(gè)問題是它不包含文檔。文檔是我們添加到程序中以幫助其他程序員閱讀和理解它的文本。它在運(yùn)行時(shí)對(duì)程序沒有影響。

文檔有兩種形式,文檔字符串(docstrings)注釋(comments)。文檔字符串是一個(gè)三引號(hào)的字符串,出現(xiàn)在函數(shù)的開頭,如下所示:

def run_simulation(state, p1, p2, num_steps):
    """Simulate the given number of time steps.
    state: State object
    p1: probability of an Olin->Wellesley customer arrival
    p2: probability of a Wellesley->Olin customer arrival
    num_steps: number of time steps
    """
    results = TimeSeries()
    for i in range(num_steps):
        step(state, p1, p2)
        results[i] = state.olin
    plot(results, label=?Olin?)

文檔字符串遵循傳統(tǒng)格式:

1.第一行是一個(gè)單獨(dú)的句子,描述函數(shù)的作用。

2.下面幾行解釋了每個(gè)參數(shù)是什么。

函數(shù)的文檔字符串應(yīng)該包含一些使用者需要知道的信息,從而使用該函數(shù);它不應(yīng)該包含函數(shù)如何工作的詳細(xì)信息,而那是注釋的目的。

注釋是以哈希符號(hào)#開頭的一行文本。它通常出現(xiàn)在一個(gè)函數(shù)中,用來解釋一些對(duì)于閱讀程序的人來說并不明顯的東西。

例如,這里有一個(gè)帶有文檔字符串和注釋的bike-to-olin版本。

def bike_to_olin(state):
        """
        Move one bike from Wellesley to Olin.
        state: State object
        """
        # We decrease one state variable and increase the
        # other, so the total number of bikes is unchanged.
    state.wellesley -= 1
    state.olin += 1

在這一點(diǎn)上,我們有比代碼更多的文檔,這對(duì)于短函數(shù)來說并不罕見。

3.4 負(fù)數(shù)量的自行車

到目前為止,我們所做的改進(jìn)提高了代碼的質(zhì)量,但是我們還沒有做任何事情來提高模型的質(zhì)量。我們現(xiàn)在就開始吧。

目前,模擬不檢查客戶到達(dá)時(shí)是否有自行車,因此一個(gè)地點(diǎn)的自行車數(shù)量可能為負(fù)數(shù)。這不太現(xiàn)實(shí)。下面是一個(gè)更新版本的bike_to_olin解決了這個(gè)問題:

def bike_to_olin(state):
    if state.wellesley == 0:
        return
    state.wellesley -= 1
    state.olin += 1

第一行檢查韋爾斯利的自行車數(shù)量是否為零。如果是這樣,它將使用return語句,這將導(dǎo)致函數(shù)立即結(jié)束,而不運(yùn)行其余語句。因此,如果在韋爾斯利沒有自行車,我們“返回”bike_to_olin,而不改變狀態(tài)。

我們可以用同樣的方法將其更新為bike_to_wellesley。

3.5 比較運(yùn)算符

上一節(jié)中bike_to_olin的版本使用等號(hào)運(yùn)算符==,它比較兩個(gè)值,如果相等則返回True,否則返回False。

很容易混淆等號(hào)運(yùn)算符和賦值運(yùn)算符=,后者為變量賦值。例如,下面的語句創(chuàng)建一個(gè)變量x,如果它不存在,并給它賦值5。

x = 5

另一方面,下面的語句檢查x是否為5并返回True或False。它不會(huì)創(chuàng)建x或更改其值。

x == 5

可以在if語句中使用equals運(yùn)算符,如下所示:

if x == 5:
    print('yes, x is 5')

如果您犯了一個(gè)錯(cuò)誤,并在If語句中使用了=,如下所示:

if x = 5:
    print('yes, x is 5')

這是一個(gè)語法錯(cuò)誤,這意味著程序的結(jié)構(gòu)是無效的。Python將顯示一條錯(cuò)誤消息,程序?qū)o法運(yùn)行。 等號(hào)運(yùn)算符是比較運(yùn)算符之一。比較運(yùn)算符包括:

Operation Symbol
Less than <
Greater than >
Less than or equal <=
Greater than or equal >=
Equal ==
Not equal !=

3.6 指標(biāo)

回到自行車共享系統(tǒng),現(xiàn)在我們有能力模擬系統(tǒng)的行為。由于客戶的到達(dá)是隨機(jī)的,所以每次進(jìn)行模擬時(shí),系統(tǒng)的狀態(tài)都是不同的。像這樣的模型被稱為隨機(jī)模型;每次運(yùn)行時(shí)都做同樣的事情的模型是確定性的。

假設(shè)我們想用我們的模型來預(yù)測(cè)自行車共享系統(tǒng)的工作情況,或者設(shè)計(jì)一個(gè)更好的系統(tǒng)。首先,我們必須決定“多好”和“更好”是什么意思。

從客戶的角度來看,我們可能想知道找到一輛可用自行車的可能性。從系統(tǒng)所有者的角度來看,我們可能希望盡量減少客戶在想要自行車時(shí)沒有得到自行車的數(shù)量,或者最大限度地增加使用中的自行車數(shù)量。像這些統(tǒng)計(jì)數(shù)據(jù)量化系統(tǒng)工作的好壞稱為度量(metrics)

舉個(gè)簡(jiǎn)單的例子,讓我們來衡量一下不滿意的顧客的數(shù)量。以下是bike_to_olin的一個(gè)版本,它可以記錄到達(dá)沒有自行車的車站的客戶數(shù)量:

def bike_to_olin(state):
    if state.wellesley == 0:
        state.wellesley_empty += 1
        return
    state.wellesley -= 1
    state.olin += 1

如果客戶到達(dá)Wellesley車站,發(fā)現(xiàn)沒有可用的自行車,bike_to_olin會(huì)更新Wellesley_empty,并計(jì)算不滿意的客戶數(shù)量。

只有在創(chuàng)建State對(duì)象時(shí)初始化wellesley_empty,此函數(shù)才有效,如下所示:

bikeshare = State(olin=10, wellesley=2,
                  olin_empty=0, wellesley_empty=0)

假設(shè)我們以同樣的方式更新move_to_wellesley,我們可以這樣運(yùn)行模擬(見第3.3節(jié)):

run_simulation(bikeshare, 0.4, 0.2, 60)

然后我們可以檢查指標(biāo):

print(bikeshare.olin_empty, bikeshare.wellesley_empty)

因?yàn)槟M是隨機(jī)的,每次運(yùn)行的結(jié)果都是不同的。

在你繼續(xù)之前,你可能想讀一下本章的筆記本chap03.ipynb,并練習(xí)一下。有關(guān)下載和運(yùn)行代碼的說明,請(qǐng)參閱0.4節(jié)。

本書的中文翻譯由南開大學(xué)醫(yī)學(xué)院智能醫(yī)學(xué)工程專業(yè)2018級(jí)、2019級(jí)的師生完成,方便后續(xù)學(xué)生學(xué)習(xí)《Python仿真建模》課程。翻譯人員(排名不分前后):薛淏源、金鈺、張?chǎng)埇擃?、趙子雨、李翀、慕振墺、許靖云、李文碩、尹瀛寰、沈紀(jì)辰、迪力木拉、樊旭波、商嘉文、趙旭、連煦、楊永新、樊一諾、劉志鑫、彭子豪、馬碧婷、吳曉玲、常智星、陳俊帆、高勝寒、韓志恒、劉天翔、張藝瀟、劉暢。

整理校訂由劉暢完成,如果您發(fā)現(xiàn)有翻譯不當(dāng)或者錯(cuò)誤,請(qǐng)郵件聯(lián)系changliu@nankai.edu.cn。

本書中文版不用于商業(yè)用途,供大家自由使用。

未經(jīng)允許,請(qǐng)勿轉(zhuǎn)載。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容