想象一下,您有一個線性方程組和不等式系統(tǒng)。這樣的系統(tǒng)通常有許多可能的解決方案。線性規(guī)劃是一組數(shù)學(xué)和計算工具,可讓您找到該系統(tǒng)的特定解,該解對應(yīng)于某些其他線性函數(shù)的最大值或最小值。
創(chuàng)新互聯(lián)公司專注于七星網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗。 熱誠為您提供七星營銷型網(wǎng)站建設(shè),七星網(wǎng)站制作、七星網(wǎng)頁設(shè)計、七星網(wǎng)站官網(wǎng)定制、小程序設(shè)計服務(wù),打造七星網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供七星網(wǎng)站排名全網(wǎng)營銷落地服務(wù)。
混合整數(shù)線性規(guī)劃是 線性規(guī)劃 的擴展。它處理至少一個變量采用離散整數(shù)而不是連續(xù)值的問題。盡管乍一看混合整數(shù)問題與連續(xù)變量問題相似,但它們在靈活性和精度方面具有顯著優(yōu)勢。
整數(shù)變量對于正確表示自然用整數(shù)表示的數(shù)量很重要,例如生產(chǎn)的飛機數(shù)量或服務(wù)的客戶數(shù)量。
一種特別重要的整數(shù)變量是 二進制變量 。它只能取 零 或 一 的值,在做出是或否的決定時很有用,例如是否應(yīng)該建造工廠或者是否應(yīng)該打開或關(guān)閉機器。您還可以使用它們來模擬邏輯約束。
線性規(guī)劃是一種基本的優(yōu)化技術(shù),已在科學(xué)和數(shù)學(xué)密集型領(lǐng)域使用了數(shù)十年。它精確、相對快速,適用于一系列實際應(yīng)用。
混合整數(shù)線性規(guī)劃允許您克服線性規(guī)劃的許多限制。您可以使用分段線性函數(shù)近似非線性函數(shù)、使用半連續(xù)變量、模型邏輯約束等。它是一種計算密集型工具,但計算機硬件和軟件的進步使其每天都更加適用。
通常,當人們試圖制定和解決優(yōu)化問題時,第一個問題是他們是否可以應(yīng)用線性規(guī)劃或混合整數(shù)線性規(guī)劃。
以下文章說明了線性規(guī)劃和混合整數(shù)線性規(guī)劃的一些用例:
隨著計算機能力的增強、算法的改進以及更多用戶友好的軟件解決方案的出現(xiàn),線性規(guī)劃,尤其是混合整數(shù)線性規(guī)劃的重要性隨著時間的推移而增加。
解決線性規(guī)劃問題的基本方法稱為,它有多種變體。另一種流行的方法是。
混合整數(shù)線性規(guī)劃問題可以通過更復(fù)雜且計算量更大的方法來解決,例如,它在幕后使用線性規(guī)劃。這種方法的一些變體是,它涉及使用 切割平面 ,以及。
有幾種適用于線性規(guī)劃和混合整數(shù)線性規(guī)劃的合適且眾所周知的 Python 工具。其中一些是開源的,而另一些是專有的。您是否需要免費或付費工具取決于問題的規(guī)模和復(fù)雜性,以及對速度和靈活性的需求。
值得一提的是,幾乎所有廣泛使用的線性規(guī)劃和混合整數(shù)線性規(guī)劃庫都是以 Fortran 或 C 或 C++ 原生和編寫的。這是因為線性規(guī)劃需要對(通常很大)矩陣進行計算密集型工作。此類庫稱為求解器。Python 工具只是求解器的包裝器。
Python 適合圍繞本機庫構(gòu)建包裝器,因為它可以很好地與 C/C++ 配合使用。對于本教程,您不需要任何 C/C++(或 Fortran),但如果您想了解有關(guān)此酷功能的更多信息,請查看以下資源:
基本上,當您定義和求解模型時,您使用 Python 函數(shù)或方法調(diào)用低級庫,該庫執(zhí)行實際優(yōu)化工作并將解決方案返回給您的 Python 對象。
幾個免費的 Python 庫專門用于與線性或混合整數(shù)線性規(guī)劃求解器交互:
在本教程中,您將使用SciPy和PuLP來定義和解決線性規(guī)劃問題。
在本節(jié)中,您將看到線性規(guī)劃問題的兩個示例:
您將在下一節(jié)中使用 Python 來解決這兩個問題。
考慮以下線性規(guī)劃問題:
你需要找到X和?使得紅色,藍色和黃色的不平等,以及不平等X 0和? 0,是滿意的。同時,您的解決方案必須對應(yīng)于z的最大可能值。
您需要找到的自變量(在本例中為 x 和 y )稱為 決策變量 。要最大化或最小化的決策變量的函數(shù)(在本例中為 z) 稱為 目標函數(shù) 、 成本函數(shù) 或僅稱為 目標 。您需要滿足的 不等式 稱為 不等式約束 。您還可以在稱為 等式約束 的約束中使用方程。
這是您如何可視化問題的方法:
紅線代表的功能2 X + Y = 20,和它上面的紅色區(qū)域示出了紅色不等式不滿足。同樣,藍線是函數(shù) 4 x + 5 y = 10,藍色區(qū)域被禁止,因為它違反了藍色不等式。黃線是 x + 2 y = 2,其下方的黃色區(qū)域是黃色不等式無效的地方。
如果您忽略紅色、藍色和黃色區(qū)域,則僅保留灰色區(qū)域。灰色區(qū)域的每個點都滿足所有約束,是問題的潛在解決方案。該區(qū)域稱為 可行域 ,其點為 可行解 。在這種情況下,有無數(shù)可行的解決方案。
您想最大化z。對應(yīng)于最大z的可行解是 最優(yōu)解 。如果您嘗試最小化目標函數(shù),那么最佳解決方案將對應(yīng)于其可行的最小值。
請注意,z是線性的。你可以把它想象成一個三維空間中的平面。這就是為什么最優(yōu)解必須在可行區(qū)域的 頂點 或角上的原因。在這種情況下,最佳解決方案是紅線和藍線相交的點,稍后您將看到。
有時,可行區(qū)域的整個邊緣,甚至整個區(qū)域,都可以對應(yīng)相同的z值。在這種情況下,您有許多最佳解決方案。
您現(xiàn)在已準備好使用綠色顯示的附加等式約束來擴展問題:
方程式 x + 5 y = 15,以綠色書寫,是新的。這是一個等式約束。您可以通過向上一張圖像添加相應(yīng)的綠線來將其可視化:
現(xiàn)在的解決方案必須滿足綠色等式,因此可行區(qū)域不再是整個灰色區(qū)域。它是綠線從與藍線的交點到與紅線的交點穿過灰色區(qū)域的部分。后一點是解決方案。
如果插入x的所有值都必須是整數(shù)的要求,那么就會得到一個混合整數(shù)線性規(guī)劃問題,可行解的集合又會發(fā)生變化:
您不再有綠線,只有沿線的x值為整數(shù)的點??尚薪馐腔疑尘吧系木G點,此時最優(yōu)解離紅線最近。
這三個例子說明了 可行的線性規(guī)劃問題 ,因為它們具有有界可行區(qū)域和有限解。
如果沒有解,線性規(guī)劃問題是 不可行的 。當沒有解決方案可以同時滿足所有約束時,通常會發(fā)生這種情況。
例如,考慮如果添加約束x + y 1會發(fā)生什么。那么至少有一個決策變量(x或y)必須是負數(shù)。這與給定的約束x 0 和y 0相沖突。這樣的系統(tǒng)沒有可行的解決方案,因此稱為不可行的。
另一個示例是添加與綠線平行的第二個等式約束。這兩行沒有共同點,因此不會有滿足這兩個約束的解決方案。
一個線性規(guī)劃問題是 無界的 ,如果它的可行區(qū)域是無界,將溶液不是有限。這意味著您的變量中至少有一個不受約束,可以達到正無窮大或負無窮大,從而使目標也無限大。
例如,假設(shè)您采用上面的初始問題并刪除紅色和黃色約束。從問題中刪除約束稱為 放松 問題。在這種情況下,x和y不會在正側(cè)有界。您可以將它們增加到正無窮大,從而產(chǎn)生無限大的z值。
在前面的部分中,您研究了一個與任何實際應(yīng)用程序無關(guān)的抽象線性規(guī)劃問題。在本小節(jié)中,您將找到與制造業(yè)資源分配相關(guān)的更具體和實用的優(yōu)化問題。
假設(shè)一家工廠生產(chǎn)四種不同的產(chǎn)品,第一種產(chǎn)品的日產(chǎn)量為x ?,第二種產(chǎn)品的產(chǎn)量為x 2,依此類推。目標是確定每種產(chǎn)品的利潤最大化日產(chǎn)量,同時牢記以下條件:
數(shù)學(xué)模型可以這樣定義:
目標函數(shù)(利潤)在條件 1 中定義。人力約束遵循條件 2。對原材料 A 和 B 的約束可以從條件 3 和條件 4 中通過對每種產(chǎn)品的原材料需求求和得出。
最后,產(chǎn)品數(shù)量不能為負,因此所有決策變量必須大于或等于零。
與前面的示例不同,您無法方便地將其可視化,因為它有四個決策變量。但是,無論問題的維度如何,原理都是相同的。
在本教程中,您將使用兩個Python 包來解決上述線性規(guī)劃問題:
SciPy 設(shè)置起來很簡單。安裝后,您將擁有開始所需的一切。它的子包 scipy.optimize 可用于線性和非線性優(yōu)化。
PuLP 允許您選擇求解器并以更自然的方式表述問題。PuLP 使用的默認求解器是COIN-OR Branch and Cut Solver (CBC)。它連接到用于線性松弛的COIN-OR 線性規(guī)劃求解器 (CLP)和用于切割生成的COIN-OR 切割生成器庫 (CGL)。
另一個偉大的開源求解器是GNU 線性規(guī)劃工具包 (GLPK)。一些著名且非常強大的商業(yè)和專有解決方案是Gurobi、CPLEX和XPRESS。
除了在定義問題時提供靈活性和運行各種求解器的能力外,PuLP 使用起來不如 Pyomo 或 CVXOPT 等替代方案復(fù)雜,后者需要更多的時間和精力來掌握。
要學(xué)習(xí)本教程,您需要安裝 SciPy 和 PuLP。下面的示例使用 SciPy 1.4.1 版和 PuLP 2.1 版。
您可以使用pip以下方法安裝兩者:
您可能需要運行pulptest或sudo pulptest啟用 PuLP 的默認求解器,尤其是在您使用 Linux 或 Mac 時:
或者,您可以下載、安裝和使用 GLPK。它是免費和開源的,適用于 Windows、MacOS 和 Linux。在本教程的后面部分,您將看到如何將 GLPK(除了 CBC)與 PuLP 一起使用。
在 Windows 上,您可以下載檔案并運行安裝文件。
在 MacOS 上,您可以使用 Homebrew:
在 Debian 和 Ubuntu 上,使用apt來安裝glpk和glpk-utils:
在Fedora,使用dnf具有g(shù)lpk-utils:
您可能還會發(fā)現(xiàn)conda對安裝 GLPK 很有用:
安裝完成后,可以查看GLPK的版本:
有關(guān)詳細信息,請參閱 GLPK 關(guān)于使用Windows 可執(zhí)行文件和Linux 軟件包進行安裝的教程。
在本節(jié)中,您將學(xué)習(xí)如何使用 SciPy優(yōu)化和求根庫進行線性規(guī)劃。
要使用 SciPy 定義和解決優(yōu)化問題,您需要導(dǎo)入scipy.optimize.linprog():
現(xiàn)在您已經(jīng)linprog()導(dǎo)入,您可以開始優(yōu)化。
讓我們首先解決上面的線性規(guī)劃問題:
linprog()僅解決最小化(而非最大化)問題,并且不允許具有大于或等于符號 ( ) 的不等式約束。要解決這些問題,您需要在開始優(yōu)化之前修改您的問題:
引入這些更改后,您將獲得一個新系統(tǒng):
該系統(tǒng)與原始系統(tǒng)等效,并且將具有相同的解決方案。應(yīng)用這些更改的唯一原因是克服 SciPy 與問題表述相關(guān)的局限性。
下一步是定義輸入值:
您將上述系統(tǒng)中的值放入適當?shù)牧斜怼⒃M或NumPy 數(shù)組中:
注意:請注意行和列的順序!
約束左側(cè)和右側(cè)的行順序必須相同。每一行代表一個約束。
來自目標函數(shù)和約束左側(cè)的系數(shù)的順序必須匹配。每列對應(yīng)一個決策變量。
下一步是以與系數(shù)相同的順序定義每個變量的界限。在這種情況下,它們都在零和正無窮大之間:
此語句是多余的,因為linprog()默認情況下采用這些邊界(零到正無窮大)。
注:相反的float("inf"),你可以使用math.inf,numpy.inf或scipy.inf。
最后,是時候優(yōu)化和解決您感興趣的問題了。你可以這樣做linprog():
參數(shù)c是指來自目標函數(shù)的系數(shù)。A_ub和b_ub分別與不等式約束左邊和右邊的系數(shù)有關(guān)。同樣,A_eq并b_eq參考等式約束。您可以使用bounds提供決策變量的下限和上限。
您可以使用該參數(shù)method來定義要使用的線性規(guī)劃方法。有以下三種選擇:
linprog() 返回具有以下屬性的數(shù)據(jù)結(jié)構(gòu):
您可以分別訪問這些值:
這就是您獲得優(yōu)化結(jié)果的方式。您還可以以圖形方式顯示它們:
如前所述,線性規(guī)劃問題的最優(yōu)解位于可行區(qū)域的頂點。在這種情況下,可行區(qū)域只是藍線和紅線之間的綠線部分。最優(yōu)解是代表綠線和紅線交點的綠色方塊。
如果要排除相等(綠色)約束,只需刪除參數(shù)A_eq并b_eq從linprog()調(diào)用中刪除:
解決方案與前一種情況不同。你可以在圖表上看到:
在這個例子中,最優(yōu)解是紅色和藍色約束相交的可行(灰色)區(qū)域的紫色頂點。其他頂點,如黃色頂點,具有更高的目標函數(shù)值。
您可以使用 SciPy 來解決前面部分所述的資源分配問題:
和前面的例子一樣,你需要從上面的問題中提取必要的向量和矩陣,將它們作為參數(shù)傳遞給.linprog(),然后得到結(jié)果:
結(jié)果告訴您最大利潤是1900并且對應(yīng)于x ? = 5 和x ? = 45。在給定條件下生產(chǎn)第二和第四個產(chǎn)品是沒有利潤的。您可以在這里得出幾個有趣的結(jié)論:
opt.statusis0和opt.successis True,說明優(yōu)化問題成功求解,最優(yōu)可行解。
SciPy 的線性規(guī)劃功能主要用于較小的問題。對于更大和更復(fù)雜的問題,您可能會發(fā)現(xiàn)其他庫更適合,原因如下:
幸運的是,Python 生態(tài)系統(tǒng)為線性編程提供了幾種替代解決方案,這些解決方案對于更大的問題非常有用。其中之一是 PuLP,您將在下一節(jié)中看到它的實際應(yīng)用。
PuLP 具有比 SciPy 更方便的線性編程 API。您不必在數(shù)學(xué)上修改您的問題或使用向量和矩陣。一切都更干凈,更不容易出錯。
像往常一樣,您首先導(dǎo)入您需要的內(nèi)容:
現(xiàn)在您已經(jīng)導(dǎo)入了 PuLP,您可以解決您的問題。
您現(xiàn)在將使用 PuLP 解決此系統(tǒng):
第一步是初始化一個實例LpProblem來表示你的模型:
您可以使用該sense參數(shù)來選擇是執(zhí)行最小化(LpMinimize或1,這是默認值)還是最大化(LpMaximize或-1)。這個選擇會影響你的問題的結(jié)果。
一旦有了模型,就可以將決策變量定義為LpVariable類的實例:
您需要提供下限,lowBound=0因為默認值為負無窮大。該參數(shù)upBound定義了上限,但您可以在此處省略它,因為它默認為正無窮大。
可選參數(shù)cat定義決策變量的類別。如果您使用的是連續(xù)變量,則可以使用默認值"Continuous"。
您可以使用變量x和y創(chuàng)建表示線性表達式和約束的其他 PuLP 對象:
當您將決策變量與標量相乘或構(gòu)建多個決策變量的線性組合時,您會得到一個pulp.LpAffineExpression代表線性表達式的實例。
注意:您可以增加或減少變量或表達式,你可以乘他們常數(shù),因為紙漿類實現(xiàn)一些Python的特殊方法,即模擬數(shù)字類型一樣__add__(),__sub__()和__mul__()。這些方法用于像定制運營商的行為+,-和*。
類似地,您可以將線性表達式、變量和標量與運算符 ==、=以獲取表示模型線性約束的紙漿.LpConstraint實例。
注:也有可能與豐富的比較方法來構(gòu)建的約束.__eq__(),.__le__()以及.__ge__()定義了運營商的行為==,=。
考慮到這一點,下一步是創(chuàng)建約束和目標函數(shù)并將它們分配給您的模型。您不需要創(chuàng)建列表或矩陣。只需編寫 Python 表達式并使用+=運算符將它們附加到模型中:
在上面的代碼中,您定義了包含約束及其名稱的元組。LpProblem允許您通過將約束指定為元組來向模型添加約束。第一個元素是一個LpConstraint實例。第二個元素是該約束的可讀名稱。
設(shè)置目標函數(shù)非常相似:
或者,您可以使用更短的符號:
現(xiàn)在您已經(jīng)添加了目標函數(shù)并定義了模型。
注意:您可以使用運算符將 約束或目標附加到模型中,+=因為它的類LpProblem實現(xiàn)了特殊方法.__iadd__(),該方法用于指定 的行為+=。
對于較大的問題,lpSum()與列表或其他序列一起使用通常比重復(fù)+運算符更方便。例如,您可以使用以下語句將目標函數(shù)添加到模型中:
它產(chǎn)生與前一條語句相同的結(jié)果。
您現(xiàn)在可以看到此模型的完整定義:
模型的字符串表示包含所有相關(guān)數(shù)據(jù):變量、約束、目標及其名稱。
注意:字符串表示是通過定義特殊方法構(gòu)建的.__repr__()。有關(guān) 的更多詳細信息.__repr__(),請查看Pythonic OOP 字符串轉(zhuǎn)換:__repr__vs__str__ .
最后,您已準備好解決問題。你可以通過調(diào)用.solve()你的模型對象來做到這一點。如果要使用默認求解器 (CBC),則不需要傳遞任何參數(shù):
.solve()調(diào)用底層求解器,修改model對象,并返回解決方案的整數(shù)狀態(tài),1如果找到了最優(yōu)解。有關(guān)其余狀態(tài)代碼,請參閱LpStatus[]。
你可以得到優(yōu)化結(jié)果作為 的屬性model。該函數(shù)value()和相應(yīng)的方法.value()返回屬性的實際值:
model.objective持有目標函數(shù)model.constraints的值,包含松弛變量的值,以及對象x和y具有決策變量的最優(yōu)值。model.variables()返回一個包含決策變量的列表:
如您所見,此列表包含使用 的構(gòu)造函數(shù)創(chuàng)建的確切對象LpVariable。
結(jié)果與您使用 SciPy 獲得的結(jié)果大致相同。
注意:注意這個方法.solve()——它會改變對象的狀態(tài),x并且y!
您可以通過調(diào)用查看使用了哪個求解器.solver:
輸出通知您求解器是 CBC。您沒有指定求解器,因此 PuLP 調(diào)用了默認求解器。
如果要運行不同的求解器,則可以將其指定為 的參數(shù).solve()。例如,如果您想使用 GLPK 并且已經(jīng)安裝了它,那么您可以solver=GLPK(msg=False)在最后一行使用。請記住,您還需要導(dǎo)入它:
現(xiàn)在你已經(jīng)導(dǎo)入了 GLPK,你可以在里面使用它.solve():
該msg參數(shù)用于顯示來自求解器的信息。msg=False禁用顯示此信息。如果要包含信息,則只需省略msg或設(shè)置msg=True。
您的模型已定義并求解,因此您可以按照與前一種情況相同的方式檢查結(jié)果:
使用 GLPK 得到的結(jié)果與使用 SciPy 和 CBC 得到的結(jié)果幾乎相同。
一起來看看這次用的是哪個求解器:
正如您在上面用突出顯示的語句定義的那樣model.solve(solver=GLPK(msg=False)),求解器是 GLPK。
您還可以使用 PuLP 來解決混合整數(shù)線性規(guī)劃問題。要定義整數(shù)或二進制變量,只需傳遞cat="Integer"或cat="Binary"到LpVariable。其他一切都保持不變:
在本例中,您有一個整數(shù)變量并獲得與之前不同的結(jié)果:
Nowx是一個整數(shù),如模型中所指定。(從技術(shù)上講,它保存一個小數(shù)點后為零的浮點值。)這一事實改變了整個解決方案。讓我們在圖表上展示這一點:
如您所見,最佳解決方案是灰色背景上最右邊的綠點。這是兩者的最大價值的可行的解決方案x和y,給它的最大目標函數(shù)值。
GLPK 也能夠解決此類問題。
現(xiàn)在你可以使用 PuLP 來解決上面的資源分配問題:
定義和解決問題的方法與前面的示例相同:
在這種情況下,您使用字典 x來存儲所有決策變量。這種方法很方便,因為字典可以將決策變量的名稱或索引存儲為鍵,將相應(yīng)的LpVariable對象存儲為值。列表或元組的LpVariable實例可以是有用的。
上面的代碼產(chǎn)生以下結(jié)果:
如您所見,該解決方案與使用 SciPy 獲得的解決方案一致。最有利可圖的解決方案是每天生產(chǎn)5.0第一件產(chǎn)品和45.0第三件產(chǎn)品。
讓我們把這個問題變得更復(fù)雜和有趣。假設(shè)由于機器問題,工廠無法同時生產(chǎn)第一種和第三種產(chǎn)品。在這種情況下,最有利可圖的解決方案是什么?
現(xiàn)在您有另一個邏輯約束:如果x ? 為正數(shù),則x ? 必須為零,反之亦然。這是二元決策變量非常有用的地方。您將使用兩個二元決策變量y ? 和y ?,它們將表示是否生成了第一個或第三個產(chǎn)品:
除了突出顯示的行之外,代碼與前面的示例非常相似。以下是差異:
這是解決方案:
事實證明,最佳方法是排除第一種產(chǎn)品而只生產(chǎn)第三種產(chǎn)品。
就像有許多資源可以幫助您學(xué)習(xí)線性規(guī)劃和混合整數(shù)線性規(guī)劃一樣,還有許多具有 Python 包裝器的求解器可用。這是部分列表:
其中一些庫,如 Gurobi,包括他們自己的 Python 包裝器。其他人使用外部包裝器。例如,您看到可以使用 PuLP 訪問 CBC 和 GLPK。
您現(xiàn)在知道什么是線性規(guī)劃以及如何使用 Python 解決線性規(guī)劃問題。您還了解到 Python 線性編程庫只是本機求解器的包裝器。當求解器完成其工作時,包裝器返回解決方案狀態(tài)、決策變量值、松弛變量、目標函數(shù)等。
一、遺傳算法介紹
遺傳算法是通過模擬大自然中生物進化的歷程,來解決問題的。大自然中一個種群經(jīng)歷過若干代的自然選擇后,剩下的種群必定是適應(yīng)環(huán)境的。把一個問題所有的解看做一個種群,經(jīng)歷過若干次的自然選擇以后,剩下的解中是有問題的最優(yōu)解的。當然,只能說有最優(yōu)解的概率很大。這里,我們用遺傳算法求一個函數(shù)的最大值。
f(x) = 10 * sin( 5x ) + 7 * cos( 4x ), 0 = x = 10
1、將自變量x進行編碼
取基因片段的長度為10, 則10位二進制位可以表示的范圍是0到1023。基因與自變量轉(zhuǎn)變的公式是x = b2d(individual) * 10 / 1023。構(gòu)造初始的種群pop。每個個體的基因初始值是[0, 1, 0, 1, 0, 1, 0, 1, 0, 1]
2、計算目標函數(shù)值
根據(jù)自變量與基因的轉(zhuǎn)化關(guān)系式,求出每個個體的基因?qū)?yīng)的自變量,然后將自變量代入函數(shù)f(x),求出每個個體的目標函數(shù)值。
3、適應(yīng)度函數(shù)
適應(yīng)度函數(shù)是用來評估個體適應(yīng)環(huán)境的能力,是進行自然選擇的依據(jù)。本題的適應(yīng)度函數(shù)直接將目標函數(shù)值中的負值變成0. 因為我們求的是最大值,所以要使目標函數(shù)值是負數(shù)的個體不適應(yīng)環(huán)境,使其繁殖后代的能力為0.適應(yīng)度函數(shù)的作用將在自然選擇中體現(xiàn)。
4、自然選擇
自然選擇的思想不再贅述,操作使用輪盤賭算法。其具體步驟:
假設(shè)種群中共5個個體,適應(yīng)度函數(shù)計算出來的個體適應(yīng)性列表是fitvalue = [1 ,3, 0, 2, 4] ,totalvalue = 10 , 如果將fitvalue畫到圓盤上,值的大小表示在圓盤上的面積。在轉(zhuǎn)動輪盤的過程中,單個模塊的面積越大則被選中的概率越大。選擇的方法是將fitvalue轉(zhuǎn)化為[1 , 4 ,4 , 6 ,10], fitvalue / totalvalue = [0.1 , 0.4 , 0.4 , 0.6 , 1.0] . 然后產(chǎn)生5個0-1之間的隨機數(shù),將隨機數(shù)從小到大排序,假如是[0.05 , 0.2 , 0.7 , 0.8 ,0.9],則將0號個體、1號個體、4號個體、4號個體、4號個體拷貝到新種群中。自然選擇的結(jié)果使種群更符合條件了。
5、繁殖
假設(shè)個體a、b的基因是
a = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]
b = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]
這兩個個體發(fā)生基因交換的概率pc = 0.6.如果要發(fā)生基因交換,則產(chǎn)生一個隨機數(shù)point表示基因交換的位置,假設(shè)point = 4,則:
a = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]
b = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1]
交換后為:
a = [1, 0, 0, 0, 1, 0, 1, 1, 1, 1]
b = [0, 0, 0, 1, 0, 1, 1, 1, 0, 0]
6、突變
遍歷每一個個體,基因的每一位發(fā)生突變(0變?yōu)?,1變?yōu)?)的概率為0.001.突變可以增加解空間
二、代碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
def b2d(b): #將二進制轉(zhuǎn)化為十進制 x∈[0,10] t = 0 for j in range(len(b)): t += b[j] * (math.pow(2, j)) t = t * 10 / 1023 return tpopsize = 50 #種群的大小#用遺傳算法求函數(shù)最大值:#f(x)=10*sin(5x)+7*cos(4x) x∈[0,10]chromlength = 10 #基因片段的長度pc = 0.6 #兩個個體交叉的概率pm = 0.001; #基因突變的概率results = [[]]bestindividual = []bestfit = 0fitvalue = []tempop = [[]]pop = [[0, 1, 0, 1, 0, 1, 0, 1, 0, 1] for i in range(popsize)]for i in range(100): #繁殖100代 objvalue = calobjvalue(pop) #計算目標函數(shù)值 fitvalue = calfitvalue(objvalue); #計算個體的適應(yīng)值 [bestindividual, bestfit] = best(pop, fitvalue) #選出最好的個體和最好的函數(shù)值 results.append([bestfit,b2d(bestindividual)]) #每次繁殖,將最好的結(jié)果記錄下來 selection(pop, fitvalue) #自然選擇,淘汰掉一部分適應(yīng)性低的個體 crossover(pop, pc) #交叉繁殖 mutation(pop, pc) #基因突變 results.sort() print(results[-1]) #打印函數(shù)最大值和對應(yīng)的
來自CODE的代碼片
GA.py
1
2
3
4
5
6
7
8
9
def best(pop, fitvalue): #找出適應(yīng)函數(shù)值中最大值,和對應(yīng)的個體 px = len(pop) bestindividual = [] bestfit = fitvalue[0] for i in range(1,px): if(fitvalue[i] bestfit): bestfit = fitvalue[i] bestindividual = pop[i] return [bestindividual, bestfit]
來自CODE的代碼片
best.py
1
2
3
4
5
6
7
8
9
10
11
def calfitvalue(objvalue):#轉(zhuǎn)化為適應(yīng)值,目標函數(shù)值越大越好,負值淘汰。 fitvalue = [] temp = 0.0 Cmin = 0; for i in range(len(objvalue)): if(objvalue[i] + Cmin 0): temp = Cmin + objvalue[i] else: temp = 0.0 fitvalue.append(temp) return fitvalue
來自CODE的代碼片
calfitvalue.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import mathdef decodechrom(pop): #將種群的二進制基因轉(zhuǎn)化為十進制(0,1023) temp = []; for i in range(len(pop)): t = 0; for j in range(10): t += pop[i][j] * (math.pow(2, j)) temp.append(t) return tempdef calobjvalue(pop): #計算目標函數(shù)值 temp1 = []; objvalue = []; temp1 = decodechrom(pop) for i in range(len(temp1)): x = temp1[i] * 10 / 1023 #(0,1023)轉(zhuǎn)化為 (0,10) objvalue.append(10 * math.sin(5 * x) + 7 * math.cos(4 * x)) return objvalue #目標函數(shù)值objvalue[m] 與個體基因 pop[m] 對應(yīng)
來自CODE的代碼片
calobjvalue.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import randomdef crossover(pop, pc): #個體間交叉,實現(xiàn)基因交換 poplen = len(pop) for i in range(poplen - 1): if(random.random() pc): cpoint = random.randint(0,len(pop[0])) temp1 = [] temp2 = [] temp1.extend(pop[i][0 : cpoint]) temp1.extend(pop[i+1][cpoint : len(pop[i])]) temp2.extend(pop[i+1][0 : cpoint]) temp2.extend(pop[i][cpoint : len(pop[i])]) pop[i] = temp1 pop[i+1] = temp2
來自CODE的代碼片
crossover.py
1
2
3
4
5
6
7
8
9
10
11
12
13
import randomdef mutation(pop, pm): #基因突變 px = len(pop) py = len(pop[0]) for i in range(px): if(random.random() pm): mpoint = random.randint(0,py-1) if(pop[i][mpoint] == 1): pop[i][mpoint] = 0 else: pop[i][mpoint] = 1
來自CODE的代碼片
mutation.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import randomdef sum(fitvalue): total = 0 for i in range(len(fitvalue)): total += fitvalue[i] return totaldef cumsum(fitvalue): for i in range(len(fitvalue)): t = 0; j = 0; while(j = i): t += fitvalue[j] j = j + 1 fitvalue[i] = t;def selection(pop, fitvalue): #自然選擇(輪盤賭算法) newfitvalue = [] totalfit = sum(fitvalue) for i in range(len(fitvalue)): newfitvalue.append(fitvalue[i] / totalfit) cumsum(newfitvalue) ms = []; poplen = len(pop) for i in range(poplen): ms.append(random.random()) #random float list ms ms.sort() fitin = 0 newin = 0 newpop = pop while newin poplen: if(ms[newin] newfitvalue[fitin]): newpop[newin] = pop[fitin] newin = newin + 1 else: fitin = fitin + 1 pop = newpop
Python是工具 數(shù)據(jù)挖掘是研究方向 數(shù)據(jù)挖掘有很多經(jīng)典算法,這些算法有的有現(xiàn)成Python包,你可以用Python調(diào)用這些包處理自己的數(shù)據(jù)實現(xiàn)數(shù)據(jù)挖掘。
Python通常是直接從數(shù)據(jù)庫取出已有信息,進行一些統(tǒng)計、可視化、文字結(jié)論等。數(shù)據(jù)挖掘一般是指從大量的數(shù)據(jù)中通過算法搜索隱藏于其中信息的過程。
數(shù)據(jù)挖掘只能告訴你,A和B可能存在相關(guān)關(guān)系,但是它無法告訴你A和B存在什么相關(guān)關(guān)系。機器學(xué)習(xí)是從假設(shè)空間H中尋找假設(shè)函數(shù)g近似目標函數(shù)f。數(shù)據(jù)挖掘是從大量的數(shù)據(jù)中尋找數(shù)據(jù)相互之間的特性。主要挖掘方法有:分類、估計、預(yù)測、相關(guān)性分組或關(guān)聯(lián)規(guī)則、聚類、復(fù)雜數(shù)據(jù)類型挖掘(Text, Web ,圖形圖像,視頻,音頻等)等技術(shù)。
想要了解更多有關(guān)數(shù)據(jù)挖掘的信息,可以了解一下CDA數(shù)據(jù)分析師的課程。CDA數(shù)據(jù)分析師證書的含金量是很高的,課程內(nèi)容兼顧培養(yǎng)解決數(shù)據(jù)挖掘流程問題的橫向能力以及解決數(shù)據(jù)挖掘算法問題的縱向能力。幫助學(xué)員掌握真正過硬的解決業(yè)務(wù)問題的數(shù)據(jù)挖掘能力。點擊預(yù)約免費試聽課。
這篇的內(nèi)容是一系列針對在Python中從零開始運用機器學(xué)習(xí)能力工作流的輔導(dǎo)第一部分,覆蓋了從小組開始的算法編程和其他相關(guān)工具。最終會成為一套手工制成的機器語言工作包。這次的內(nèi)容會首先從數(shù)據(jù)準備開始。
—— 來自Matthew Mayo, KDnuggets
似乎大家對機器學(xué)習(xí)能力的認知總是簡單到把一系列論據(jù)傳送到越來越多的數(shù)據(jù)庫和應(yīng)用程序界面中,接著就期待能有一些神奇的結(jié)果出現(xiàn)??赡苣銓υ谶@些數(shù)據(jù)庫里究竟發(fā)生了什么有自己很好的理解—— 從數(shù)據(jù)準備到建模到結(jié)果演示呈現(xiàn)等等,但不得不說你依然需要依賴于這些紛繁的工具去完成自己的工作。
這其實很正常。我們用被準確檢驗證明過能運行的工具來完成一些日常的任務(wù)是無可厚非的。重新發(fā)明使用那些不能有效滾動的輪子不是最好的辦法。這樣會有很多局限,也會浪費很多的不必要的時間。無論你是使用開放源代碼還是被授權(quán)的工具來完成你工作,這些代碼工具已經(jīng)被很多人反復(fù)試用升級以確保當你上手使用的時候能夠以最好的質(zhì)量完成你的工作。
然而,有些苦活累活你自己做也是有價值的,即便是作為一種教育性的努力。我不是要推薦你們從零開始通過自己深度學(xué)習(xí)練習(xí)寫出一個程序框架,至少不能一直這樣,但哪怕只有一次通過不斷的試驗和失敗,從頭開始寫出和自己的算實現(xiàn)它們的支持工具也是非常好的。我可能說的不對,但我認為如今在學(xué)習(xí)機器學(xué)習(xí)能力、數(shù)據(jù)科學(xué)、人工智能等方面的大多數(shù)人都沒有在這么做。
所以讓我們從頭開始,來學(xué)習(xí)在Python里建立一些機器學(xué)習(xí)能力的相關(guān)知識。
“From Scratch” 究竟是什么意思?
首先,我先申明:當我提到“From Scratch”,我的意思是盡可能少的借助外界的幫助。當然這也是相對的,但是為了達成我們的目標,我會劃定界限,當我們在寫自己的矩陣模型、數(shù)據(jù)框或者構(gòu)建自己的數(shù)據(jù)庫時,我們會分別使用Python中的numpy、panda和matplotlib庫。在某些情況下,我們甚至不會使用這些庫的全部功能。我們稍后會討論,讓我們先暫時放一放它們的名字以便大家更好的理解。在Python自帶的庫中自帶的功能原則上都是可以使用的,但除此之外,我們就要自己來寫了。
我們需要從一個點入手,那就讓我們從一些簡單的數(shù)據(jù)準備任務(wù)開始吧。開始的時候我們會慢一點,但當我們對(要學(xué)習(xí)的東西)有了一點感覺以后,我們會逐漸加快速度。除了數(shù)據(jù)準備,我們還需要數(shù)據(jù)轉(zhuǎn)換、結(jié)果演示和呈現(xiàn)工具——更不必說機器學(xué)習(xí)能力算法了——來達成我們我們即將要完成的目標。
我們的想法是手動拼接任何我們需要的重大功能,以便完成我們的機器學(xué)習(xí)能力任務(wù)。當序列展開的時候,我們可以添加新的工具和算法,同時我們也能重新思考我們以前的假設(shè)(是否正確),使整個過程盡可能重復(fù)迭代,就像它會漸近一樣。慢慢的,我們會集中精力在我們的目標上,制定策略來完成目標,把它們運用到Python里,再檢驗它們是否能夠運行。
最終的結(jié)果,就想我們現(xiàn)在預(yù)期的一樣,會是有序排列在我們自己的簡易的機器學(xué)習(xí)數(shù)據(jù)庫中的一系列簡單的Python模型。對于初學(xué)者,我相信這是理解機器學(xué)習(xí)過程、工作流和算法如何運行的非常寶貴的經(jīng)驗。
工作流(workflow)究竟是什么意思?
工作流對不同的人意味著不同的意思,但是我們這里說的工作流指的是機器學(xué)習(xí)項目中的一部分。我們有很多過程框架來幫助我們追蹤我的工作進程,但現(xiàn)在讓我們簡化到一下的這些:
獲取數(shù)據(jù)
處理/準備數(shù)據(jù)
建立模型
解釋呈現(xiàn)結(jié)果
在我們真正做的時候我們可以拓展,但是這是我們現(xiàn)在自己設(shè)計的簡單的機器學(xué)習(xí)的過程框架。同時,“輸送管(小箭頭)”暗含了把工作流中各功能聚集在一起的能力,所以讓我們把這些記住然后繼續(xù)向前。
獲得數(shù)據(jù)
在我們建立自己的模型之前,我們需要一些數(shù)據(jù),還需要確認這些數(shù)據(jù)與我們合理的期望相符合。為了檢測的目的(而不是訓(xùn)練或測試,但只是測試我們自己的設(shè)備),我們會使用虹膜數(shù)據(jù)集,你可以從這里下載。盡管我們可以在網(wǎng)上找到很多版本的數(shù)據(jù)集,但我建議我們都使用相同的原始數(shù)據(jù),以確保我們的準備工作正常運行。
讓我們來看一看:
既然我們已經(jīng)知道了這個簡單的數(shù)據(jù)集和它對應(yīng)的文件,我們先來想一想我們需要做什么使原始數(shù)據(jù)演變成我們想要的結(jié)果:
數(shù)據(jù)需要儲存成CSV格式的文件
實例大部分由有數(shù)字屬性的值組成
組別是經(jīng)過分組的內(nèi)容
到目前為止,以上沒有一種是對所有的數(shù)據(jù)集都適用的,但是也沒有任何一個是只能適用于某一種數(shù)據(jù)集的。這使得我們能夠有機會編寫我們可以以后重復(fù)使用的代碼。好的編程練習(xí)會讓我們集中于重復(fù)利用性和模塊性。
一些簡單的探索性數(shù)據(jù)分析被羅列如下:
(上圖為具體數(shù)值,下圖為圖像化數(shù)據(jù))
準備數(shù)據(jù)
雖然數(shù)據(jù)準備在我們現(xiàn)在這個特定的情境中需要的很少,但是有時還是會需要。尤其是我們需要確認我們解釋了標題行,去除了任何pandas呈現(xiàn)出來的參數(shù),并且把我們的每一次組的值從名字型的轉(zhuǎn)化成數(shù)值型的。因為在我們使用模型時已經(jīng)沒有名字性數(shù)值了,所以到此為止至少就沒有更復(fù)雜的轉(zhuǎn)化了。
最終,我們也需要一個對我們自己的算法的更好的數(shù)據(jù)呈現(xiàn),所以我們在繼續(xù)向前進行之前會確保我們最終呈現(xiàn)的是一個矩陣——或者numpy nadarry。我們的數(shù)據(jù)準備工作流接下來會做一下的表格:
同時,我們需要主要我們沒有理由相信所有有趣的數(shù)據(jù)都會被儲存在被逗號分開的文件里。我們可能希望能夠從一個SQL數(shù)據(jù)庫里或者直接從網(wǎng)上獲取數(shù)據(jù),從這兩個地方找到的數(shù)據(jù)我們以后還能返回去回看。
首先,讓我們寫一個簡單的函數(shù),把一個CSV文件上傳到DataFrame。當然,這在內(nèi)網(wǎng)做很容易,但是再往前想一步我們可能想再加一些額外的步驟到我們自己的數(shù)據(jù)集里以便我們以后上載函數(shù)。
這個編碼是相當直接的。一行一行的讀數(shù)據(jù)文件就完成了一些額外的預(yù)先加工,比如忽略了那些內(nèi)容非數(shù)據(jù)的行(我們認為在數(shù)據(jù)文件中評價是由井號鍵開始的,盡管這很荒謬。)我們可以詳細說明這個數(shù)據(jù)集文件是否包括標題,我們也可以接受csv和tsv文件,csv文件是默認的設(shè)置。
有一些錯誤檢查存在,但它還并不是很健全,所以我們或許可以晚一點再回來說這個話題。此外,逐條讀文件再逐條決定要對這些行做什么,比直接用內(nèi)置功能把處理干凈的一致的cs一文件直接讀到DataFrame中要慢,但權(quán)衡之后我們發(fā)現(xiàn)允許更多的靈活性,在這一階段是值得的(但讀大的文件可能會發(fā)花費很久的時間)。不要忘了,如果一部分內(nèi)置操作不是最好的方法,我們可以晚一些再做調(diào)整。
在我們嘗試運行自己的編碼之前,我們需要來寫一個函數(shù),把名字類數(shù)值轉(zhuǎn)化成數(shù)字類數(shù)值。為了推廣函數(shù),我們需要使它能夠用于數(shù)據(jù)集中的任何屬性的數(shù)值,不僅僅是運用于不同的類別。我們還應(yīng)該跟蹤屬性名稱最終是否成為了整數(shù)。有了之前把csv或ts me的數(shù)據(jù)文件上傳pandas的DataFrame的步驟經(jīng)驗,這個函數(shù)應(yīng)該同時接受一個pandas DataFrames以及被轉(zhuǎn)化為數(shù)字的屬性名稱。
我們還要注意,我們回避了關(guān)于使用單熱編碼的話題,這涉及到分類的非分類屬性,但我認為我們以后還會回到這個話題。
上述的函數(shù)又是一個簡單的,但是能幫助我們完成目標函數(shù)。我們可以用很多不同的方式來完成這個任務(wù),包括使用pandas內(nèi)置的功能,但是讓你從一些會讓你有些累的苦差事開始做就是這個函數(shù)的意義。
現(xiàn)在我們可以從文件中加載一個數(shù)據(jù)集,然后把分類屬性值轉(zhuǎn)換成數(shù)字屬性值(我們也可以保留這些映像在字典中供以后使用)。就像之前提到的,我們希望我們的數(shù)據(jù)集最終是以numpy ndarry的形式存在,這樣我們可以在自己的算法中很簡單的使用。同樣的,這是一個簡單的任務(wù),但寫一個函數(shù)會讓我們在以后需要的時候還可以以此為準。
即使以前任何的功能都沒有過度的殺傷力,但這個功能有可能有。但請忍耐我,我們遵守非常全面的編程準則--如果過于謹慎的話。在我們繼續(xù)往下講的過程中會有很好的機會讓我們對已有的功能做改變或添加。這些變化如果能在一個地方實施并且記錄在案,從長遠來看非常有意義。
測試數(shù)據(jù)準備的工作流
我們的工作流迄今為止可能仍然是構(gòu)建板塊的形式,但讓我們給自己的編碼一個測試。
我們的代碼正在按我們希望的方式工作,讓我們做一些簡單的房屋清理工作。一旦開始滾動,我們將為我們的編碼提供一個更全面的組織結(jié)構(gòu),但是現(xiàn)在我們需要把所有這些功能加到一個單獨的文件中,并保存成為dataset.py的格式。這會讓我們以后的使用更方便,下次我們會學(xué)到。
未來計劃
之后我們會學(xué)習(xí)簡單的分類算法,k最近鄰算法。我們會學(xué)習(xí)如何在簡單的工作流中構(gòu)建分類和聚類模型。毫無疑問,這需要編寫一些限額外的工具來幫助我們完成項目,并且我確定我們還將對已經(jīng)做完的部分進行修改。
練習(xí)機器學(xué)習(xí)就是理解機器學(xué)習(xí)的最好方法。運用我們的工作流中需要的算法和支持工具最終會被證明是有用的。
python的內(nèi)置函數(shù)(68個)
Python考核31個內(nèi)置函數(shù),
python內(nèi)置了很多內(nèi)置函數(shù)、類方法屬性及各種模塊。當我們想要當我們想要了解某種類型有哪些屬性方法以及每種方法該怎么使用時,我們可以使用dir()函數(shù)和help()函數(shù)在python idle交互式模式下獲得我們想要的信息。
? dir()函數(shù)獲得對象中可用屬性的列表
Python中的關(guān)鍵詞有哪些?
dir(__builtins__):查看python內(nèi)置函數(shù)
help(‘keywords‘):查看python關(guān)鍵詞
如微分積分方程的求解程序、訪問互聯(lián)網(wǎng)、獲取日期和時間、機器學(xué)習(xí)算法等。這些程序往往被收入程序庫中,構(gòu)成程序庫。
只有經(jīng)過嚴格檢驗的程序才能放在程序庫里。檢驗,就是對程序作充分的測試。通常進行的有正確性測試、精度測試、速度測試、邊界條件和出錯狀態(tài)的測試。經(jīng)過檢驗的程序不但能保證計算結(jié)果的正確性,而且對錯誤調(diào)用也能作出反應(yīng)。程序庫中的程序都是規(guī)范化的。所謂規(guī)范化有三重含義:①同一庫里所有程序的格式是統(tǒng)一的;② 對這些程序的調(diào)用方法是相同的;③ 每個程序所需參數(shù)的數(shù)目、順序和類型都是嚴格規(guī)定好的。
Python的庫包含標準庫和第三方庫
標準庫:程序語言自身擁有的庫,可以直接使用。help('modules')
第三方庫:第三方者使用該語言提供的程序庫。
標準庫: turtle 庫(必選)、 random 庫(必選)、 time 庫(可選)。
? turtle 庫:圖形繪制庫
原理如同控制一只海龜,以不同的方向和速度進行位移而得到其運動軌跡。
使用模塊的幫助時,需要先將模塊導(dǎo)入。
例如:在IDLE中輸入import turtle
dir(turtle)
help(turtle.**)
1.畫布
畫布就是turtle為我們展開用于繪圖區(qū)域, 我們可以設(shè)置它的大小和初始位置。
setup()方法用于初始化畫布窗口大小和位置,參數(shù)包括畫布窗口寬、畫布窗口高、窗口在屏幕的水平起始位置和窗口在屏幕的垂直起始位置。
參數(shù):width, height: 輸入寬和高為整數(shù)時,表示 像素 ;為小數(shù)時,表示占據(jù)電腦屏幕的比例。(startx,starty):這一坐標表示
矩形窗口左上角頂點的位置,如果為空,則窗口位于屏幕中心:
例如:setup(640,480,300,300)表示在桌面屏幕(300,300)位置開始創(chuàng)建640×480大小的畫布窗體。
2、畫筆
? color() 用于設(shè)置或返回畫筆顏色和填充顏色。
例如:color(‘red’)將顏色設(shè)為紅色,也可用fillcolor()方法設(shè)置或返回填充顏色,或用pencolor()方法設(shè)置或返回筆觸顏色。
基于以下三個原因,我們選擇Python作為實現(xiàn)機器學(xué)習(xí)算法的編程語言:(一) Python的語法清晰;(二) 易于操作純文本文件;(三) 使用廣泛,存在大量的開發(fā)文檔。 可執(zhí)行偽代碼 Python具有清晰的語法結(jié)構(gòu),大家也把它稱作可執(zhí)行偽代碼(executable pseudo-code)。默認安裝的Python開發(fā)環(huán)境已經(jīng)附帶了很多高級數(shù)據(jù)類型,如列表、元組、字典、集合、隊列等,無需進一步編程就可以使用這些數(shù)據(jù)類型的操作。使用這些數(shù)據(jù)類型使得實現(xiàn)抽象的數(shù)學(xué)概念非常簡單。此外,讀者還可以使用自己熟悉的編程風格,如面向?qū)ο缶幊?、面向過程編程、或者函數(shù)式編程。不熟悉Python的讀者可以參閱附錄A,該附錄詳細介紹了Python語言、Python使用的數(shù)據(jù)類型以及安裝指南。 Python語言處理和操作文本文件非常簡單,非常易于處理非數(shù)值型數(shù)據(jù)。Python語言提供了豐富的正則表達式函數(shù)以及很多訪問Web頁面的函數(shù)庫,使得從HTML中提取數(shù)據(jù)變得非常簡單直觀。 Python比較流行 Python語言使用廣泛,代碼范例也很多,便于讀者快速學(xué)習(xí)和掌握。此外,在開發(fā)實際應(yīng)用程序時,也可以利用豐富的模塊庫縮短開發(fā)周期。 在科學(xué)和金融領(lǐng)域,Python語言得到了廣泛應(yīng)用。SciPy和NumPy等許多科學(xué)函數(shù)庫都實現(xiàn)了向量和矩陣操作,這些函數(shù)庫增加了代碼的可讀性,學(xué)過線性代數(shù)的人都可以看懂代碼的實際功能。另外,科學(xué)函數(shù)庫SciPy和NumPy使用底層語言(C和Fortran)編寫,提高了相關(guān)應(yīng)用程序的計算性能。本書將大量使用Python的NumPy。 Python的科學(xué)工具可以與繪圖工具Matplotlib協(xié)同工作。Matplotlib可以繪制二D、三D圖形,也可以處理科學(xué)研究中經(jīng)常使用到的圖形,所以本書也將大量使用Matplotlib。 Python開發(fā)環(huán)境還提供了交互式shell環(huán)境,允許用戶開發(fā)程序時查看和檢測程序內(nèi)容。 Python開發(fā)環(huán)境將來還會集成Pylab模塊,它將NumPy、SciPy和Matplotlib合并為一個開發(fā)環(huán)境。在本書寫作時,Pylab還沒有并入Python環(huán)境,但是不遠的將來我們肯定可以在Python開發(fā)環(huán)境找到它。 Python語言的特色 諸如MATLAB和Mathematica等高級程序語言也允許用戶執(zhí)行矩陣操作,MATLAB甚至還有許多內(nèi)嵌的特征可以輕松地構(gòu)造機器學(xué)習(xí)應(yīng)用,而且MATLAB的運算速度也很快。然而MATLAB的不足之處是軟件費用太高,單個軟件授權(quán)就要花費數(shù)千美元。雖然也有適合MATLAB的第三方插件,但是沒有一個有影響力的大型開源項目。 Java和C等強類型程序設(shè)計語言也有矩陣數(shù)學(xué)庫,然而對于這些程序設(shè)計語言來說,最大的問題是即使完成簡單的操作也要編寫大量的代碼。程序員首先需要定義變量的類型,對于Java來說,每次封裝屬性時還需要實現(xiàn)getter和setter方法。另外還要記著實現(xiàn)子類,即使并不想使用子類,也必須實現(xiàn)子類方法。為了完成一個簡單的工作,我們必須花費大量時間編寫了很多無用冗長的代碼。Python語言則與Java和C完全不同,它清晰簡練,而且易于理解,即使不是編程人員也能夠理解程序的含義,而Java和C對于非編程人員則像天書一樣難于理解。 所有人在小學(xué)二年級已經(jīng)學(xué)會了寫作,然而大多數(shù)人必須從事其他更重要的工作。 ——鮑比·奈特 也許某一天,我們可以在這句話中將“寫作”替代為“編寫代碼”,雖然有些人對于編寫代碼很感興趣,但是對于大多數(shù)人來說,編程僅是完成其他任務(wù)的工具而已。Python語言是高級編程語言,我們可以花費更多的時間處理數(shù)據(jù)的內(nèi)在含義,而無須花費太多精力解決計算機如何得到數(shù)據(jù)結(jié)果。Python語言使得我們很容易表達自己的目的。 Python語言的缺點 Python語言唯一的不足是性能問題。Python程序運行的效率不如Java或者C代碼高,但是我們可以使用Python調(diào)用C編譯的代碼。這樣,我們就可以同時利用C和Python的優(yōu)點,逐步地開發(fā)機器學(xué)習(xí)應(yīng)用程序。我們可以首先使用Python編寫實驗程序,如果進一步想要在產(chǎn)品中實現(xiàn)機器學(xué)習(xí),轉(zhuǎn)換成C代碼也不困難。如果程序是按照模塊化原則組織的,我們可以先構(gòu)造可運行的Python程序,然后再逐步使用C代碼替換核心代碼以改進程序的性能。C++ Boost庫就適合完成這個任務(wù),其他類似于Cython和PyPy的工具也可以編寫強類型的Python代碼,改進一般Python程序的性能。 如果程序的算法或者思想有缺陷,則無論程序的性能如何,都無法得到正確的結(jié)果。如果解決問題的思想存在問題,那么單純通過提高程序的運行效率,擴展用戶規(guī)模都無法解決這個核心問題。從這個角度來看,Python快速實現(xiàn)系統(tǒng)的優(yōu)勢就更加明顯了,我們可以快速地檢驗算法或者思想是否正確,如果需要,再進一步優(yōu)化代碼
網(wǎng)頁名稱:python機器目標函數(shù)的簡單介紹
網(wǎng)頁路徑:http://chinadenli.net/article10/hegddo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供ChatGPT、網(wǎng)站導(dǎo)航、企業(yè)建站、服務(wù)器托管、App設(shè)計、動態(tài)網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)