狠狠操夜夜甜|人妻在线中文字幕亚洲无码不卡av|一区二区欧美亚洲|日躁夜躁狠狠躁2001|亚洲,超碰,欧美|18AV成人电影|午夜成人免费在线|婷婷激情网深爱五月|色欲综合成人在线|在线美女搞黄大片

中企動力 > 頭條 > python中平方

網(wǎng)站性能檢測評分

注:本網(wǎng)站頁面html檢測工具掃描網(wǎng)站中存在的基本問題,僅供參考。

python中平方

一文介紹機器學(xué)習中基本的數(shù)學(xué)符號 公司視頻課程

img

孔尋云

關(guān)注

在機器學(xué)習中,你永遠都繞不過數(shù)學(xué)符號。

通常,只要有一個代數(shù)項或一個方程符號看不懂,你就完全看不懂整個過程是怎么回事了。這種境況非常令人沮喪,尤其是對于那些正在成長中的機器學(xué)習初學(xué)者來說更是如此。

如果你能了解一些基本的數(shù)學(xué)符號以及相關(guān)的小技巧,那你就在看懂機器學(xué)習方法的論文或書籍描述上前進了一大步。

在本教程中,你將學(xué)到機器學(xué)習技術(shù)描述中遇到的基本數(shù)學(xué)符號。

在學(xué)完整個教程后,你會知道:

算術(shù)符號,包括若干種乘法、指數(shù)、平方根以及對數(shù)數(shù)列和集合符號,包括索引、求和以及集合關(guān)系5 種當你看不明白數(shù)學(xué)符號的時候可以采用的應(yīng)急方法

讓我們開始學(xué)習吧!

機器學(xué)習中的基本數(shù)學(xué)符號

教程概覽

本教程分為 7 個部分,分別是:

1. 看不懂數(shù)學(xué)符號的沮喪

2. 算術(shù)符號

3. 希臘字母

4. 數(shù)列符號

5. 集合符號

6. 其他符號

7. 更多幫助資源

看不懂數(shù)學(xué)符號的沮喪

你在閱讀機器學(xué)習算法的相關(guān)內(nèi)容時會遇到一些數(shù)學(xué)符號。舉例來說,這些符號可能會被用來:

描述一個算法描述數(shù)據(jù)的預(yù)處理描述結(jié)果描述測試工具描述含義

你可能在論文、教科書、博文以及其他地方看到這些描述。相關(guān)代數(shù)項常常會給出完整定義,但你還是會看到不少陌生的數(shù)學(xué)符號。我曾多次深受其苦,簡直太令人感到挫敗了!

在本教程中,你會復(fù)習到一些幫助你看懂機器學(xué)習方法描述的基本數(shù)學(xué)符號。

算術(shù)符號

在本節(jié)中,我們將重溫一些基礎(chǔ)算數(shù)中你不太熟悉的符號,以及畢業(yè)之后一些可能遺忘的概念。

簡單算術(shù)

算術(shù)的基本符號你已很熟悉。例如:

加法:1 + 1 = 2減法:2 – 1 = 1乘法:2 x 2 = 4除法:2 / 2 = 1

大多數(shù)的數(shù)學(xué)運算都有一個對應(yīng)的逆運算,進行相反的運算過程;比如,減法是加法的逆運算,而除法是乘法的逆運算。

代數(shù)

我們常希望用更抽象的方式來描述運算過程,以將其與具體的數(shù)據(jù)或運算區(qū)分開來。因此代數(shù)的運用隨處可見:也就是用大寫和/或小寫字母來代表一個項,或者一個數(shù)學(xué)符號體系中的概念。用希臘字母來代替英文字母也是很常見的用法。數(shù)學(xué)中的每一個領(lǐng)域都可能有一些保留字母,這些字母都會代表一個特定的東西。盡管如此,代數(shù)中的項總應(yīng)在描述中被定義一下,如果作者沒有去定義,那是他的問題,不是你的錯。

乘法符號

乘法是一個常見的符號,有幾種記法。一般是用一個小小的「ⅹ」或者星號「*」來代表乘法:

c = a x bc = a * b

你有時也會看到用一個點來代表乘法,比如:

c = a . b

這個式子其實和下式是一樣的意思:

c = a x b

或者你可能會看到運算符被省略,先前被定義的代數(shù)項之間沒有符號也沒有空格,比如:

c = ab

這還是一樣的意思。

指數(shù)和平方根

指數(shù)就是一個數(shù)字的冪次。這個符號寫作正常大小的原數(shù)(底數(shù))以及一個上標數(shù)(指數(shù)),例如:

2^3

這個表達式的計算結(jié)果就是 3 個 2 連乘,或者說是 2 的立方:

2 x 2 x 2 = 8

求一個數(shù)的冪,就默認是求它的平方。

2^2 = 2 x 2 = 4

平方運算的效果可以用開方來逆轉(zhuǎn)。開方在數(shù)學(xué)中是在被開方的數(shù)字上面加一個開方符號,這里簡單起見,直接用「sqrt()」函數(shù)來表示了。

sqrt(4) = 2

式中,我們知道了指數(shù)的結(jié)果 4,以及指數(shù)的次數(shù) 2,我們想算出指數(shù)的底數(shù)。事實上,開方運算可以是任意次指數(shù)的逆運算,只是開方符號默認次數(shù)為 2,相當于在開方符號的前面有一個下標的 2。我們當然可以試著寫出立方的逆運算,也就是開立方符號:

2^3 = 83 sqrt(8) = 2

對數(shù)和 e

當我們求 10 的整數(shù)次冪的時候,我們常稱之為數(shù)量級。

10^2 = 10 x 10 or 100

對這個運算求逆的另一方法是求這個運算結(jié)果(100)以 10 為底數(shù)的對數(shù);用符號來表達的話就寫作 log10()。

log10(100) = 2

這里,我們已知指數(shù)的結(jié)果和底數(shù),而要求指數(shù)的次數(shù)。這讓我們在數(shù)量級上輕松地縮放。除此之外,由于計算機中使用二進制數(shù)學(xué),求以 2 為底數(shù)的對數(shù)也是常用的運算。例如:

2^6 = 64log2(64) = 6

還有一個非常常見的對數(shù)是以自然底數(shù) e 為底數(shù)的。符號 e 是一個專有符號,代表一個特殊的數(shù)字或者說一個稱為歐拉數(shù)的常數(shù)。歐拉數(shù)是一個無限不循環(huán)小數(shù),可以追溯到無窮的精度。

e = 2.71828...

求 e 的冪被稱為自然指數(shù)函數(shù):

e^2 = 7.38905...

求自然對數(shù)的運算就是這個運算的逆運算,記作 ln():

ln(7.38905...) = 2

忽略更多數(shù)學(xué)細節(jié),自然指數(shù)和自然對數(shù)在數(shù)學(xué)中非常有用,因為它們能用來抽象地描述某一系統(tǒng)的持續(xù)增長,比如說復(fù)利這樣的指數(shù)級增長體系。

希臘字母

希臘字母在數(shù)學(xué)中用來代表變量、常數(shù)、函數(shù)以及其他的概念。比如說,在統(tǒng)計學(xué)中我們用小寫的希臘字母 mu 來代表平均值,而小寫的希臘字母 sigma 表示標準差。在線性回歸中,我們用小寫字母 beta 來代表系數(shù),諸如此類。學(xué)會所有希臘字母的大小寫以及怎么念會帶來極大的幫助。

希臘字母表。

維基百科詞條「數(shù)學(xué)、科學(xué)及工程中的希臘字母」是個非常有用的使用指南(https://en.wikipedia.org/wiki/Greek_letters_used_in_mathematics,_science,_and_engineering),因為上面列出來了在數(shù)學(xué)和科學(xué)不同領(lǐng)域內(nèi)每一個希臘字母的常見用法。

數(shù)列符號

機器學(xué)習中的符號常用來描述數(shù)列運算。一個數(shù)列可以是一列數(shù)據(jù),或者代數(shù)項。

索引

讀懂數(shù)列符號的關(guān)鍵是要弄明白數(shù)列中的索引符號。一般來說符號中會明確數(shù)列的起點和終點,比如從 1 到 n,這里的 n 是數(shù)列的長度。在數(shù)列中的項都會用一個諸如 i、j、k 的下標來作為索引,就像數(shù)組的符號一樣。比如說,a_i 就是數(shù)列 a 中的第 i 個元素。如果數(shù)列是二維的,那就需要用到 2 個索引;比如:b_{i,j} 就是數(shù)列 b 的第 i 行, 第 j 列的元素。

數(shù)列運算

我們也可以對一個數(shù)列進行數(shù)學(xué)運算。有兩類運算時常被用到,所以有專門的簡寫運算符來表示它們:累加和累乘。

數(shù)列累加

對一個數(shù)列的累加用大寫的希臘符號 sigma 來表示,而累加的內(nèi)容則用變量名來表示,同時在 sigma 符號的下面明確開始的索引(如 i=1),在 sigma 符號的上面明確結(jié)束的索引(如 n)。

Sigma i = 1, n a_i

這就是數(shù)列 a 的第一個元素到第 n 個元素的累加。

數(shù)列累乘

數(shù)列的累乘是用大寫的希臘字母 pi 來表示的。而對累乘范圍的描述方式與數(shù)列累加類似,開始的索引寫在符號下面,結(jié)束的索引在符號上面。

Pi i = 1, n a_i

這就是數(shù)列 a 的第一個元素到第 n 個元素的累乘。

集合符號

一個集合就是一組互不相同的元素的整體。在定義機器學(xué)習中的一些代數(shù)項的時候我們可能會遇到集合符號。

數(shù)字集合

你最常見的集合是數(shù)字集合,比如說有的代數(shù)項會定義在整數(shù)集或?qū)崝?shù)集內(nèi)。這些常見的數(shù)字集合包括:

所以自然數(shù)的集合: N所有整數(shù)的集合: Z所有實數(shù)的集合: R

當然還有很多其他的數(shù)字集合,你可以參考維基百科中的「特殊集合」詞條。我們在定義代數(shù)項的時候常指的是實值或者實數(shù),而不是浮點數(shù)。浮點數(shù)在計算機運算中實際上是離散的數(shù)字。

集合關(guān)系

在定義代數(shù)項的時候常會看到集合關(guān)系符號,集合關(guān)系符號看起來就像是一個大寫的「E」一樣。

1 a E R

這表示定義 a 屬于 R 集,或者說 a 屬于實數(shù)集。同樣,也有許多集合運算符;常見的兩個集合運算符包括:

并集, 就是把兩個集合的元素都包含進來:A U B交集,就是只包括同時出現(xiàn)在兩個集合中的元素:A ^

更多相關(guān)內(nèi)容可以參考維基百科中的「集合」詞條:https://en.wikipedia.org/wiki/Set_(mathematics)。

其他符號

本節(jié)中我會列出一些較常見的其他符號。一種常見的情況是我們會先抽象地定義一個方法,然后用單獨的符號來重新定義一個具體的實現(xiàn)。比如,如果我們在估計一個變量 x,可以在 x 上加一些符號來代表這些估計,比如:

x-bar(x 上方有一橫)x-prime(x 右上角有一小撇)x-hat(x 上方有一折線)

同一個符號在諸如數(shù)學(xué)的子領(lǐng)域或不同對象的語境下可能含義不同。比如說,|x|就是個很容易令人不解的符號,在不同的情況下可以指:

|x|: x 的絕對值.|x|: 向量 x 的長度.|x|: 集合 x 的勢.

本教程只提及了基礎(chǔ)的數(shù)學(xué)符號。有很多數(shù)學(xué)的子學(xué)科與機器學(xué)習更相關(guān),需要更詳細地復(fù)習一下。包括:

線性代數(shù)統(tǒng)計學(xué)概率論微積分

可能還有一些多變量分析和信息論的內(nèi)容。

5 個在數(shù)學(xué)符號方面尋求幫助的小建議

本部分將列示一些當你被機器學(xué)習中的數(shù)學(xué)符號折磨時可以用到的小建議。

考慮一下作者

你在閱讀的論文或者書籍總有一個作者。這個作者可能犯錯,可能有疏忽,也可能是因為他們自己也不明白自己在寫什么,才讓你如此迷惑。從符號的限制中逃離片刻,然后想想作者的目的。他們到底想把什么講清楚?也許你甚至可以用電子郵件、Twitter、Facebook、領(lǐng)英等方式來聯(lián)系作者讓他幫你解釋清楚。你放心,大多數(shù)學(xué)者都希望其他人能夠理解并好好利用他們的研究成果。

上維基百科查一查

維基百科上有符號列表,可以幫助你縮小符號含義的可能范圍。我建議你從這兩個詞條開始:

「數(shù)學(xué)符號表」(https://en.wikipedia.org/wiki/List_of_mathematical_symbols)「數(shù)學(xué)、科學(xué)和工程中的希臘字母」(https://en.wikipedia.org/wiki/Greek_letters_used_in_mathematics,_science,_and_engineering)

用代碼簡述出來

數(shù)學(xué)運算不過就是對數(shù)據(jù)進行函數(shù)處理。把你讀到的任何東西都用變量、for-循環(huán)等寫成偽代碼展示出來。這個過程中你可能打算使用某個腳本語言來處理自己隨意寫出來的數(shù)組,或者甚至一張 Excel 表格的數(shù)據(jù)。

當你閱讀并理解了文章中的技術(shù)改進,那你隨之寫出來的核心代碼才會取得更好的結(jié)果,最終經(jīng)過不斷的改進,你就會寫出一個小小的原型機,可以自己玩耍了!我一度不相信這個方法行得通,直到看到一個學(xué)者僅用幾行 MATLAB 代碼和隨意編寫的數(shù)據(jù)就寫出了一篇非常復(fù)雜的論文的核心代碼。這令我大吃一驚,因為我以前一直堅信機器學(xué)習的系統(tǒng)必須完整地編寫出來并且使用真實數(shù)據(jù)才能運行,所以要學(xué)習任何一篇文章只有找到原始的代碼和數(shù)據(jù)這一條路可走。但是我真的錯了。不過話說回來,那個學(xué)者真的是個天才。

現(xiàn)在我一直都在用這種方法學(xué)習機器學(xué)習,不過我是用 Python 寫出新學(xué)到的技巧的核心代碼。

換條路試試

有一個我在搞懂新技術(shù)時常用的小技巧,即找到所有引用了包含該技術(shù)的論文的其他論文,看看其他人如何演繹、解釋這個新技術(shù)時常能夠解除我在讀原始描述產(chǎn)生的誤解。不過這個辦法不總是有效,反而會更加迷惑,引入了更多令人誤解的方法和新符號。但是總體來說,這個辦法還是有效的。

在網(wǎng)上向大神請教

說實話,有很多線上論壇里的人們很愿意向別人解釋數(shù)學(xué)。你可以在屏幕上截張困擾你的符號圖,寫清楚出處和鏈接,然后連同你的困惑一起發(fā)布在問答網(wǎng)站上。推薦以下兩個入門網(wǎng)站:

https://math.stackexchange/https://stats.stackexchange/

你都有哪些弄明白數(shù)學(xué)符號的小技巧呢?不妨在評論區(qū)留言。

推薦閱讀

如果你想進一步深入了解,這一部分會告訴你更多相關(guān)資源。

Section 0.1. Reading Mathematics, Vector Calculus, Linear Algebra, and Differential Forms, 2009:http://math.cornell.edu/~hubbard/readingmath.pdfThe Language and Grammar of Mathematics, Timothy Gowers:http://assets.press.princeton.edu/chapters/gowers/gowers_I_2.pdfUnderstanding Mathematics, a guide, Peter Alfeld:https://math.stackexchange/

總結(jié)

在本教程中,你了解了在閱讀機器學(xué)習相關(guān)技術(shù)時可能會遇到的基礎(chǔ)數(shù)學(xué)符號。具體來說,你學(xué)到了:

算數(shù)符號,包括各種乘法、指數(shù)、平方根以及對數(shù)。數(shù)列和集合符號,包括索引、累加以及集合關(guān)系。5 個當你在理解數(shù)學(xué)符號遇到困難時可以幫到你的小技巧。

跟著Sutton經(jīng)典教材學(xué)強化學(xué)習中的蒙特卡羅方法 推廣視頻課程

img

清秋節(jié)

關(guān)注

大數(shù)據(jù)文摘出品

作者:Ray Zhang

編譯:halcyon、龍牧雪

用動態(tài)規(guī)劃去解決強化學(xué)習的相關(guān)問題基本夠了,但還是有很多限制。比如,你知道現(xiàn)實世界問題的狀態(tài)轉(zhuǎn)移概率嗎?你能從任意狀態(tài)隨機開始嗎?你的MDP是有限的嗎?

好消息是,蒙特卡羅方法能解決以上問題!蒙特卡羅是一種估計復(fù)雜的概率分布的經(jīng)典方法。本文部分內(nèi)容取自Sutton的經(jīng)典教材《強化學(xué)習》,并提供了額外的解釋和例子。

初探蒙特卡羅

蒙特卡羅模擬以摩納哥的著名賭場命名,因為機會和隨機結(jié)果是建模技術(shù)的核心,它們與輪盤賭,骰子和老虎機等游戲非常相似。

相比于動態(tài)規(guī)劃,蒙特卡羅方法以一種全新的方式看待問題,它提出了這個問題:我需要從環(huán)境中拿走多少樣本去鑒別好的策略和壞的策略?

這一次,我們將再引入回報的概念,它是長期的預(yù)期收益:

有時,如果環(huán)節(jié)不收斂,那么我們使用折扣因子:

我們將這些回報Gt和可能的At聯(lián)系起來試圖推導(dǎo)出:

根據(jù)大數(shù)定律,當N逼近∞時,我們能夠得到準確的期望。我們記i次模擬下標為i。

現(xiàn)在,如果這是一個馬爾科夫決策過程(MDP)(99%的強化學(xué)習問題都是),那么我們知道它展現(xiàn)出了強馬爾科夫性質(zhì),也即:

有了這些,我們可以很容易推導(dǎo)得到這樣一個事實,即期望中的

是完全無關(guān)的,從現(xiàn)在開始,我們將使Gs指示從某個狀態(tài)開始的回報(移動那個狀態(tài)到t=0)。

解決值函數(shù)的一種經(jīng)典方式是對第一次s的發(fā)生的回報進行采樣,也叫首次訪問蒙特卡羅預(yù)測。那么一個找到最優(yōu)V的一個有效的算法如下:

pi=init_pi()returns=defaultdict(list)for i in range(NUM_ITER):episode=generate_episode(pi)#(1) G=np.zeros(|S|) prev_reward=0 for (state,reward) in reversed(episode): reward+=GAMMA*prev_reward #breaking up replaces s eventually, #so we get first-visit reward. G[s]=reward prev_reward=reward for state in STATES: returns[state].append(state) V={state:np.mean(ret) for state, ret in returns.items()}

另一種方法是每次訪問蒙特卡羅預(yù)測,也就是你在每個環(huán)節(jié)中每一次發(fā)生s的回報都進行采樣。在兩種情況下,估計均成平方收斂于期望。

在蒙特卡羅方法的背景下,策略迭代的核心問題是,正如我們之前說過的,如何確保探索和開采?

一種補救大狀態(tài)空間探索的方法是,明確我們從一個特定的狀態(tài)開始并采取特定的行動,對所有可能性采用輪循方式對它們的回報采樣。這假定我們可以從任何狀態(tài)出發(fā),在每一環(huán)節(jié)的開始采取所有可能的行動,這在很多情況下不是一個合理的假設(shè)。然而對于像21點紙牌游戲這樣的問題,這是完全合理的,這意味著我們可以很容易地解決我們的問題。

在以下代碼中,我們只需要對我們之前的代碼(1)做一個快速的補?。?/p>

# Before(Start at some arbitrary s_0,a_0)episode=generate_episode(pi)# After(Start at some specifics s,a)episode=generate_episode(pi,s,a)# loop through s, a at every iteration.

在線策略ε-貪婪策略

如果我們不能假設(shè)我們可以從任何狀態(tài)開始并采取任意行動那怎么辦呢?好吧,那么,只要我們不要太貪婪或者探索所有的狀態(tài)無窮次,我們?nèi)匀豢梢员WC收斂,對嗎?

以上是在線策略方法的主要屬性之一,在線策略方法試圖去改善當前運行試驗的策略,與此同時,離線策略方法試圖改善一種不同于正在運行試驗的策略的策略。

說到這里,我們要規(guī)則化“不要太貪婪”。一種簡答的方法是使用我們之前學(xué)過的k臂老虎機-ε-貪婪方法?;仡櫼幌?,我們以ε的概率從一個給定狀態(tài)下所有行動的均勻分布中挑選,以1-ε的概率我們選argmaxtq(s,a)行動。

現(xiàn)在我們問:對于蒙特卡羅方法,這是否收斂到最優(yōu)π*?答案是它會收斂,但不是收斂到那個策略。

我們從q和一個ε-貪婪策略π(s)開始:

再一次,我們得到這個結(jié)論ε-貪婪策略,跟其他貪婪策略一樣,對于Vπ執(zhí)行單調(diào)的改進。如果我們回退到所有的時間步,那么我們得到:

這就是我們想要的收斂性。

然而,我們需要去發(fā)現(xiàn)這個策略實際上收斂到什么。顯然,即使最優(yōu)策略是確定性的,我們的策略也被迫是隨機的,不能保證收斂到π*。然而,我們可以修訂我們的問題:

假定不是我們的策略保持以概率ε的隨機性一致選擇行動,而是環(huán)境不管我們的策略的規(guī)定隨機選擇一個行動,那么,我們能夠確保一個最優(yōu)解。證明的大綱在(1)中顯示,如果等式成立,那么我們π=π,因此我們有Vπ=Vπ于環(huán)境,這個等式在隨機性下是最優(yōu)的。

離線策略:重要性采樣

讓我們介紹一些新的術(shù)語!

π是我們的目標策略。我們正努力優(yōu)化它的預(yù)期回報。b是我們的行為策略。我們使b產(chǎn)π以后會用到的數(shù)據(jù)。π(a|s)>0b(a|s)>0 a∈A。這是收斂的概念。

離線策略方法通常有2個或者多個智能體,其中一個智能體產(chǎn)生另一個智能體需要的數(shù)據(jù),我們分別叫它們行為策略和目標策略。離線策略方法比在線策略方法更異想天開,就像神經(jīng)網(wǎng)絡(luò)之于線性模型更異想天開。離線策略方法往往更強大,其代價是產(chǎn)生更高的方差模型和較慢的收斂性。

現(xiàn)在,讓我們討論重要性采樣。

重要性采樣回答了這個問題:“給定Eπ[G],Eπ[G]是什么?”換句話說,你怎樣使用從b的采樣中獲得的信息去決定π的期望結(jié)果。

一種你能想到的直觀方法就是:“如果b選擇a很多,π選a很多,那么b的行為對于決π的行為是很重要的!”,相反:“如果b選擇a很多,π不曾選擇a,那么b在a上的行為π在a上的行為沒有什么重要性”,很有道理,對吧?

所以這差不多就知道重要性采樣的比率是什么概念了。給定一個軌跡

,在給定策略π的條件下,這條準確的軌跡發(fā)生的概率為:

π和b之間的比率是:

普通的重要性采樣

現(xiàn)在,有很多方法可以利用

給我們一個Eπ[G]的很好的估計。最基礎(chǔ)的方法是利用普通的重要性采樣。假定我們采樣了N個環(huán)節(jié):

定義S的第一次到達時間為:

我們想要估計Vπ(s),那么我們可以使用經(jīng)驗均值去通過首次訪問方法估計值函數(shù):

當然,這可以很容易地推廣到每次訪問方法,但是我想用最簡單的形式來表達我的意思。這說明我們需要不同的方式來衡量每一環(huán)節(jié)的收益,因為對于π更容易發(fā)生的軌跡相比那些永遠不會發(fā)生的需要賦予更多的權(quán)重。

這種重要性采樣的方法是一種無偏估計量,但它存在極大的方差問題。假定第k個環(huán)節(jié)的重要性比率

是1000,這個數(shù)很大,但是確實可能發(fā)生。這是不是意味著獎勵也要1000倍甚至更多呢?如果我們只有一個環(huán)節(jié),我們的估計是準確的。從長遠來看,因為我們有一個乘法關(guān)系,導(dǎo)致比率可能會爆炸式增長或者消失。這對于估計來說,有點令人擔憂。

加權(quán)重要性采樣

為了減小方差,一種簡單直觀的方法就是減少估計的大小,通過除以重要比率的大小的總和(有點像柔性最大激活函數(shù)):

這叫做加權(quán)重要性采樣,它是一種有偏估計(偏差漸進趨于0),但是減小了方差。在此之前,我們能夠得到一個普通估計量的病態(tài)無界方差,但是這里的每個元素的最大權(quán)值都是1,通過此限制了方差有界。Sutton建議,在實踐中,總是使用加權(quán)重要性采樣比較好。

增值實現(xiàn)

與許多其它采樣技術(shù)一樣,我們可以逐步實現(xiàn)它。假設(shè)我們使用上一節(jié)的加權(quán)重要性采樣方法,那么我們可以得到一些如下形式的采樣算法:

其中Wk可以是我們的權(quán)重。

我們想基于Nn來構(gòu)造Nn+1,這是可行的。記Cn為

,我們會以如下方式持續(xù)更新這個計算和:

Cn的更新規(guī)則非常明顯:

。

現(xiàn)在Vn是我們的值函數(shù),但是一個非常相似的類比也可以應(yīng)用到我們的行為Qn。

當我們更新值函數(shù)的時候,我們也能更新我們的策略π,我們能夠用雖舊但是很好用argmaxtq(s,a)來更新π。

折扣意識重要性采樣

到目前為止,我們已經(jīng)計算了回報,并采樣了回報得到了我們的估計。然而我們忽視了G的內(nèi)部結(jié)構(gòu)。它真的只是折扣獎勵的求和,我們未能將它納入到比率中ρ。折扣意識重要性采樣將γ建模為終止的概率。環(huán)節(jié)的概率在一些時間步t終止,因此必須是一個幾何分布geo(γ):

全部回報可以認為是對隨機變量Rt求期望:

可以構(gòu)造一個任意的裂項求和如下:

以此類推,我們可以看到,令k從x處開始,那么我們有γx

將上式代入G得到:

這將導(dǎo)致Rt項中的等效系數(shù)1,γ,γ2等。這就意味著,我們現(xiàn)在能夠分解Gt,并且在重要性采樣比率中使用折扣。

現(xiàn)在,回憶我們之前得到的:

如果我們擴展G,我們會有:

注意我們是怎樣在所有的回報中使用相同的比率的。一些回報,Gt.t+1,被整個軌跡的重要性比率相乘,這在模型假設(shè):γ是終止概率下是不正確的。直觀上,我們想要給Gt.t+1Pt.t+1,這很容易:

啊,好多了!這樣,每個部分回報都有他們正確的比率,這極大解決了無界方差問題。

單個獎勵重要性采樣

另一種緩解p和它的方差問題的方式,我們可以將G分解為各個獎勵,然后做一些分析,讓我們研究一下Pt.T-1Gt.T:

對于每一項,我們有Pt.T-1γkRt+k+1。擴展p,我們發(fā)現(xiàn):

在沒有常數(shù)γk的情況下求期望:

記住E(AB)=E(A)E(B)當且僅當它們是獨立的。顯然根據(jù)馬爾科夫性質(zhì),任意π(Ai|Si)和b(Ai|Si)都是獨立于Rt+k+1,(如果i≥t+k+1),且

(b也一樣)。由此我們能夠?qū)⑺鼈兎蛛x出來,從而得到:

這個式子看起來也許非常丑,但是我們發(fā)現(xiàn):

所以我們可以完全忽略后半部分,從而得到:

這是什么意思呢?我們完全可以用期望來表示最初的和:

這又一次將減少我們估計量的偏差。

Python中的在線策略模型

因為蒙特卡羅方法通常都是相似的結(jié)構(gòu)。我在Python中創(chuàng)建了一個離散蒙特卡羅類,可以用來插入和運行。

代碼下載:

https://github/OneRaynyDay/MonteCarloEngine

"""General purpose Monte Carlo model for training on-policy methods."""from copy import deepcopyimport numpy as npclass FiniteMCModel:def __init__(self, state_space, action_space, gamma=1.0, epsilon=0.1): """MCModel takes in state_space and action_space (finite) Arguments --------- state_space: int OR list[observation], where observation is any hashable type from env's obs. action_space: int OR list[action], where action is any hashable type from env's actions. gamma: float, discounting factor. epsilon: float, epsilon-greedy parameter. If the parameter is an int, then we generate a list, and otherwise we generate a dictionary. >>> m = FiniteMCModel(2,3,epsilon=0) >>> m.Q [[0, 0, 0], [0, 0, 0]] >>> m.Q[0][1] = 1 >>> m.Q [[0, 1, 0], [0, 0, 0]] >>> m.pi(1, 0) 1 >>> m.pi(1, 1) 0 >>> d = m.generate_returns([(0,0,0), (0,1,1), (1,0,1)]) >>> assert(d == {(1, 0): 1, (0, 1): 2, (0, 0): 2}) >>> m.choose_action(m.pi, 1) 0 """ self.gamma = gamma self.epsilon = epsilon self.Q = None if isinstance(action_space, int): self.action_space = np.arange(action_space) actions = [0]*action_space # Action representation self._act_rep = "list" else: self.action_space = action_space actions = {k:0 for k in action_space} self._act_rep = "dict" if isinstance(state_space, int): self.state_space = np.arange(state_space) self.Q = [deepcopy(actions) for _ in range(state_space)] else: self.state_space = state_space self.Q = {k:deepcopy(actions) for k in state_space} # Frequency of state/action. self.Ql = deepcopy(self.Q) def pi(self, action, state): """pi(a,s,A,V) := pi(a|s) We take the argmax_a of Q(s,a). q[s] = [q(s,0), q(s,1), ...] """ if self._act_rep == "list": if action == np.argmax(self.Q[state]): return 1 return 0 elif self._act_rep == "dict": if action == max(self.Q[state], key=self.Q[state].get): return 1 return 0 def b(self, action, state): """b(a,s,A) := b(a|s) Sometimes you can only use a subset of the action space given the state. Randomly selects an action from a uniform distribution. """ return self.epsilon/len(self.action_space) + (1-self.epsilon) * self.pi(action, state) def generate_returns(self, ep): """Backup on returns per time period in an epoch Arguments --------- ep: [(observation, action, reward)], an episode trajectory in chronological order. """ G = {} # return on state ...

如何利用自然語言處理構(gòu)建基于內(nèi)容的電影推薦系統(tǒng) 推廣視頻課程

img

假象

關(guān)注

本文來自阿里云云棲社區(qū),未經(jīng)許可禁止轉(zhuǎn)載。

更多資訊,盡在云棲科技快訊~

來科技快訊看新聞鴨~

快點關(guān)注我認識我愛上我啊~~~

摘要: 本文教你如何構(gòu)建屬于你自己的推薦系統(tǒng),不容錯過。

“empty brown theater chairs” by Tyler Callahan on Unsplash

你是否有過這樣的疑惑:為什么Netflix,Amazon,Google總能推薦到你比較感興趣的產(chǎn)品?我們有時會對互聯(lián)網(wǎng)上的產(chǎn)品進行評分,以此體現(xiàn)我們對產(chǎn)品的偏好,同時,推薦系統(tǒng)會利用我們分享的數(shù)據(jù),生成推薦結(jié)果。主流的推薦系統(tǒng)算法大致分為兩類:基于用戶歷史數(shù)據(jù)的協(xié)同過濾算法和基于內(nèi)容數(shù)據(jù)的過濾算法。兩者的區(qū)別其實從名稱上便可看出,但接下來我們將以電影推薦為例進一步闡述二者之間的不同。

協(xié)同過濾(Collaborative filters)

協(xié)同過濾依賴用戶的歷史評分數(shù)據(jù),為用戶推薦自己未曾看過,而與自己相似的用戶已經(jīng)觀看過的電影。為了確定兩個用戶之間是否相似,協(xié)同過濾會結(jié)合用戶所看過的電影以及他們對電影的評分。

Collaborative-based filter.

協(xié)同過濾算法的準確性依賴于用戶對產(chǎn)品的歷史評分,但并非所有的用戶都會持續(xù)不斷的對產(chǎn)品進行評價,有一些用戶甚至未曾評價過任何產(chǎn)品。協(xié)同過濾算法的另一個特點是能提供多樣化的建議,根據(jù)應(yīng)用場景的不同,對推薦系統(tǒng)的評價也不盡相同。舉個例子,假設(shè)用戶A非常喜歡反烏托邦電影和黑色喜劇,用戶B也喜歡反烏托邦電影,但從來沒有看過黑色喜劇。協(xié)同過濾算法將根據(jù)用戶A和用戶B對反烏托邦電影的喜愛,為用戶B推薦黑色喜劇。這個推薦結(jié)果將會產(chǎn)生兩種影響:用戶B也非常喜歡黑色喜劇,則推薦成功;如若用戶B喜歡輕喜劇,那么推薦是不成功的。

基于內(nèi)容的過濾(Content-based filters)

Content-based filter.

基于內(nèi)容的推薦不再涉及其他用戶,只根據(jù)我們自身的喜愛,簡單的選擇內(nèi)容相似的項目進行推薦。

相比協(xié)同過濾算法,基于內(nèi)容的推薦減少了推薦的多樣性,但用戶是否對項目進行了評分便不再影響推薦結(jié)果。還是前一個例子,也許用戶B潛意識里也喜歡黑色喜劇,但除非他自己決定主動嘗試,否則他永遠也不會知道自己的這個喜好,因為基于內(nèi)容的推薦只會繼續(xù)推薦反烏托邦或同種類型的電影。以電影為例,在計算相似度的時候,除了考慮片名,還可以考慮導(dǎo)演,主要演員等因素。

到目前為止,我已多次提及到相似度(similarity)這個詞,但是它究竟是什么呢?相似度是我們在計算用戶之間或者項目之間的相似性時可以使用的度量標準之一。它雖然不可量化,但卻是可以通過計算得到。在構(gòu)建基于內(nèi)容的推薦系統(tǒng)之前,我將簡明地對相似度的概念做一個講解。

余弦相似度(Cosine similarity)

向量可以是二維,三維甚至n維的。讓我們以二維向量為例回顧一下點積(dot product)。兩個向量之間的點積等于其中一個向量在另一個向量上的投影。因此,兩個相同向量(即相同分量)之間的點積等于該向量模的平方,而如果這兩個向量垂直,則點積為零。通常,對于n維向量,點積的計算公式如下所示。

Dot product.

點積在計算相似度時非常重要,因為它與相似度直接相關(guān)。兩個向量u和v之間相似度是由它們之間的點積和它們自身的模的比值定義的。

Similarity.

透過相似度的定義我們可以看出,如果兩個向量相同,相似度為1,如果兩個向量是正交的,相似度為0。換句話說,相似度是一個在0和1之間有界的數(shù),它反應(yīng)了這兩個向量的相似程度。

下面進入實戰(zhàn)階段。

1. 數(shù)據(jù)收集

實驗數(shù)據(jù)來自IMDB數(shù)據(jù)集,本次只選取了前250個高評分電影。數(shù)據(jù)集列表有250行(250部電影),38列。在構(gòu)建模型的時候,我們只考慮了電影導(dǎo)演、主要演員、電影類型和電影情節(jié)這幾類特征。

部分數(shù)據(jù)如下圖所示:

我們將每一部包含上述特征的電影作為一列,以便能更好的進行向量化。我們還會使用到自然語言處理,將文字轉(zhuǎn)換為向量能幫助我們更好的計算余弦相似度。

接下來,我們將對數(shù)據(jù)進行清洗。

2. 數(shù)據(jù)清洗(Data cleaning)

nltk(natural language toolkit)是一套基于python的自然語言處理工具集,它能夠幫助我們從文本中提取關(guān)鍵字,甚至可以為每個字打分。我們將使用Rake功能從Plot列中提取出關(guān)鍵字,相較于使用完整的句子對電影情節(jié)進行描述,我更青睞于使用一些與電影情節(jié)最相關(guān)的詞語。為此,我在Plot列中,對每行都使用了Rake功能,將獲取到的關(guān)鍵詞獨立作為新的一列,命名Key_words。

除了Plot列,還需要對其余列的數(shù)據(jù)進行清洗。同時,為了避免重復(fù),需要對所有的內(nèi)容進行小寫轉(zhuǎn)換,并且將所有的名和姓合并到一個單詞中。試想:如果電影A的導(dǎo)演是Danny Boyle,而電影B的主要演員是Danny DeVito,那么電影A和B會因為Danny而擁有較高的相似度,但這并不是我們想要的。

在進行了所有的清理和合并之后,我將索引重新分配到movie title列,下圖是為向量化準備的Dataframe。

3. 建模(Modeling)

為了充分利用NLP挖掘電影之間的相似性,我們需要將文字轉(zhuǎn)為詞向量。我更傾向于使用CountVecorizer而非TfIdfVecorizer,因為我只需要一個簡單的頻率計數(shù)器來統(tǒng)計bag_of_words列中的每個單詞。Tf-Idf認為字詞的重要性隨著它在文件中出現(xiàn)的次數(shù)成正比增加,但同時會隨著它在語料庫中出現(xiàn)的頻率成反比下降。這不適用于我們今天所講的應(yīng)用場景,畢竟每個單詞對于相似度的衡量都非常重要。一旦我們得到了包含每個單詞計數(shù)的矩陣,便可應(yīng)用cosine_similarity函數(shù)對相似度進行計算。

相似度矩陣如下圖所示:

Similarity matrix.

對角線上的值都為1,因為每部電影在和自己比較時是完全相似的。同時,這是一個對稱矩陣,因為電影A和B與電影B與A之間的相似度是相同的。

接下來,我們將電影標題作為輸入,返回前10個類似的電影作為推薦結(jié)果。此外,我們還給電影標題加上了數(shù)字索引,以匹配相似矩陣到實際電影標題的索引。實際上,函數(shù)一旦接收到輸入,就會檢測出與所輸入的電影相對應(yīng)的行中最大的10個數(shù)字,獲取相應(yīng)的索引并將其與電影標題系列匹配,以返回推薦的電影列表。當函數(shù)選取10個最高的相似度值時,丟棄了單位值,這樣就不會返回與輸入相同的電影標題。

4. 推薦系統(tǒng)測試(Testing the recommender)

由于我們只是用了包含250部電影的數(shù)據(jù)集,所構(gòu)建的推薦系統(tǒng)性能有限。在測試的時候,輸入了我喜愛的電影“Fargo”,下圖為推薦的前10部電影。

Movies recommended because I like Fargo.

我對推薦結(jié)果是滿意的,從導(dǎo)演和情節(jié)上可以看出它們與我喜愛的電影有一些相似之處。上面列表中有我已經(jīng)看過的電影,我喜歡它們就像我喜歡“Fargo”一樣,接下來我會去看列表中我還沒有看過的那幾部電影。

機器學(xué)習大牛最常用的5個回歸損失函數(shù),你知道幾個? 企業(yè)視頻課程

img

雷雷

關(guān)注

大數(shù)據(jù)文摘出品

編譯:Apricock、睡不著的iris、JonyKai、錢天培

“損失函數(shù)”是機器學(xué)習優(yōu)化中至關(guān)重要的一部分。L1、L2損失函數(shù)相信大多數(shù)人都早已不陌生。那你了解Huber損失、Log-Cosh損失、以及常用于計算預(yù)測區(qū)間的分位數(shù)損失么?這些可都是機器學(xué)習大牛最常用的回歸損失函數(shù)哦!

機器學(xué)習中所有的算法都需要最大化或最小化一個函數(shù),這個函數(shù)被稱為“目標函數(shù)”。其中,我們一般把最小化的一類函數(shù),稱為“損失函數(shù)”。它能根據(jù)預(yù)測結(jié)果,衡量出模型預(yù)測能力的好壞。

在實際應(yīng)用中,選取損失函數(shù)會受到諸多因素的制約,比如是否有異常值、機器學(xué)習算法的選擇、梯度下降的時間復(fù)雜度、求導(dǎo)的難易程度以及預(yù)測值的置信度等等。因此,不存在一種損失函數(shù)適用于處理所有類型的數(shù)據(jù)。這篇文章就講介紹不同種類的損失函數(shù)以及它們的作用。

損失函數(shù)大致可分為兩類:分類問題的損失函數(shù)和回歸問題的損失函數(shù)。在這篇文章中,我將著重介紹回歸損失。

本文出現(xiàn)的代碼和圖表我們都妥妥保存在這兒了:

https://nbviewer.jupyter.org/github/groverpr/Machine-Learning/blob/master/notebooks/05_Loss_Functions.ipynb

分類、回歸問題損失函數(shù)對比

均方誤差

均方誤差(MSE)是最常用的回歸損失函數(shù),計算方法是求預(yù)測值與真實值之間距離的平方和,公式如圖。

下圖是MSE函數(shù)的圖像,其中目標值是100,預(yù)測值的范圍從-10000到10000,Y軸代表的MSE取值范圍是從0到正無窮,并且在預(yù)測值為100處達到最小。

MSE損失(Y軸)-預(yù)測值(X軸)

平均絕對值誤差(也稱L1損失)

平均絕對誤差(MAE)是另一種用于回歸模型的損失函數(shù)。MAE是目標值和預(yù)測值之差的絕對值之和。其只衡量了預(yù)測值誤差的平均模長,而不考慮方向,取值范圍也是從0到正無窮(如果考慮方向,則是殘差/誤差的總和——平均偏差(MBE))。

MAE損失(Y軸)-預(yù)測值(X軸)

MSE(L2損失)與MAE(L1損失)的比較

簡單來說,MSE計算簡便,但MAE對異常點有更好的魯棒性。下面就來介紹導(dǎo)致二者差異的原因。

訓(xùn)練一個機器學(xué)習模型時,我們的目標就是找到損失函數(shù)達到極小值的點。當預(yù)測值等于真實值時,這兩種函數(shù)都能達到最小。

下面是這兩種損失函數(shù)的python代碼。你可以自己編寫函數(shù),也可以使用sklearn內(nèi)置的函數(shù)。

# true: Array of true target variable# pred: Array of predictionsdef mse(true, pred):return np.sum((true - pred)**2)def mae(true, pred):return np.sum(np.abs(true - pred))# also available in sklearnfrom sklearn.metrics import mean_squared_errorfrom sklearn.metrics import mean_absolute_error

下面讓我們觀察MAE和RMSE(即MSE的平方根,同MAE在同一量級中)在兩個例子中的計算結(jié)果。第一個例子中,預(yù)測值和真實值很接近,而且誤差的方差也較小。第二個例子中,因為存在一個異常點,而導(dǎo)致誤差非常大。

左圖:誤差比較接近 右圖:有一個誤差遠大于其他誤差

從圖中可以知道什么?應(yīng)當如何選擇損失函數(shù)?

MSE對誤差取了平方(令e=真實值-預(yù)測值),因此若e>1,則MSE會進一步增大誤差。如果數(shù)據(jù)中存在異常點,那么e值就會很大,而e則會遠大于|e|。

因此,相對于使用MAE計算損失,使用MSE的模型會賦予異常點更大的權(quán)重。在第二個例子中,用RMSE計算損失的模型會以犧牲了其他樣本的誤差為代價,朝著減小異常點誤差的方向更新。然而這就會降低模型的整體性能。

如果訓(xùn)練數(shù)據(jù)被異常點所污染,那么MAE損失就更好用(比如,在訓(xùn)練數(shù)據(jù)中存在大量錯誤的反例和正例標記,但是在測試集中沒有這個問題)。

直觀上可以這樣理解:如果我們最小化MSE來對所有的樣本點只給出一個預(yù)測值,那么這個值一定是所有目標值的平均值。但如果是最小化MAE,那么這個值,則會是所有樣本點目標值的中位數(shù)。眾所周知,對異常值而言,中位數(shù)比均值更加魯棒,因此MAE對于異常值也比MSE更穩(wěn)定。

然而MAE存在一個嚴重的問題(特別是對于神經(jīng)網(wǎng)絡(luò)):更新的梯度始終相同,也就是說,即使對于很小的損失值,梯度也很大。這樣不利于模型的學(xué)習。為了解決這個缺陷,我們可以使用變化的學(xué)習率,在損失接近最小值時降低學(xué)習率。

而MSE在這種情況下的表現(xiàn)就很好,即便使用固定的學(xué)習率也可以有效收斂。MSE損失的梯度隨損失增大而增大,而損失趨于0時則會減小。這使得在訓(xùn)練結(jié)束時,使用MSE模型的結(jié)果會更精確。

根據(jù)不同情況選擇損失函數(shù)

如果異常點代表在商業(yè)中很重要的異常情況,并且需要被檢測出來,則應(yīng)選用MSE損失函數(shù)。相反,如果只把異常值當作受損數(shù)據(jù),則應(yīng)選用MAE損失函數(shù)。

推薦大家讀一下這篇文章,文中比較了分別使用L1、L2損失的回歸模型在有無異常值時的表現(xiàn)。

文章網(wǎng)址:

http://rishy.github.io/ml/2015/07/28/l1-vs-l2-loss/

這里L1損失和L2損失只是MAE和MSE的別稱。

總而言之,處理異常點時,L1損失函數(shù)更穩(wěn)定,但它的導(dǎo)數(shù)不連續(xù),因此求解效率較低。L2損失函數(shù)對異常點更敏感,但通過令其導(dǎo)數(shù)為0,可以得到更穩(wěn)定的封閉解。

二者兼有的問題是:在某些情況下,上述兩種損失函數(shù)都不能滿足需求。例如,若數(shù)據(jù)中90%的樣本對應(yīng)的目標值為150,剩下10%在0到30之間。那么使用MAE作為損失函數(shù)的模型可能會忽視10%的異常點,而對所有樣本的預(yù)測值都為150。

這是因為模型會按中位數(shù)來預(yù)測。而使用MSE的模型則會給出很多介于0到30的預(yù)測值,因為模型會向異常點偏移。上述兩種結(jié)果在許多商業(yè)場景中都是不可取的。

這些情況下應(yīng)該怎么辦呢?最簡單的辦法是對目標變量進行變換。而另一種辦法則是換一個損失函數(shù),這就引出了下面要講的第三種損失函數(shù),即Huber損失函數(shù)。

Huber損失,平滑的平均絕對誤差

Huber損失對數(shù)據(jù)中的異常點沒有平方誤差損失那么敏感。它在0也可微分。本質(zhì)上,Huber損失是絕對誤差,只是在誤差很小時,就變?yōu)槠椒秸`差。誤差降到多小時變?yōu)槎握`差由超參數(shù)δ(delta)來控制。當Huber損失在[0-δ,0+δ]之間時,等價為MSE,而在[-∞,δ]和[δ,+∞]時為MAE。

Huber損失(Y軸)與預(yù)測值(X軸)圖示。真值取0

這里超參數(shù)delta的選擇非常重要,因為這決定了你對與異常點的定義。當殘差大于delta,應(yīng)當采用L1(對較大的異常值不那么敏感)來最小化,而殘差小于超參數(shù),則用L2來最小化。

為何要使用Huber損失?

使用MAE訓(xùn)練神經(jīng)網(wǎng)絡(luò)最大的一個問題就是不變的大梯度,這可能導(dǎo)致在使用梯度下降快要結(jié)束時,錯過了最小點。而對于MSE,梯度會隨著損失的減小而減小,使結(jié)果更加精確。

在這種情況下,Huber損失就非常有用。它會由于梯度的減小而落在最小值附近。比起MSE,它對異常點更加魯棒。因此,Huber損失結(jié)合了MSE和MAE的優(yōu)點。但是,Huber損失的問題是我們可能需要不斷調(diào)整超參數(shù)delta。

Log-Cosh損失

Log-cosh是另一種應(yīng)用于回歸問題中的,且比L2更平滑的的損失函數(shù)。它的計算方式是預(yù)測誤差的雙曲余弦的對數(shù)。

Log-cosh損失(Y軸)與預(yù)測值(X軸)圖示。真值取0

優(yōu)點:對于較小的x,log(cosh(x))近似等于(x^2)/2,對于較大的x,近似等于abs(x)-log(2)。這意味著‘logcosh’基本類似于均方誤差,但不易受到異常點的影響。它具有Huber損失所有的優(yōu)點,但不同于Huber損失的是,Log-cosh二階處處可微。

為什么需要二階導(dǎo)數(shù)?許多機器學(xué)習模型如XGBoost,就是采用牛頓法來尋找最優(yōu)點。而牛頓法就需要求解二階導(dǎo)數(shù)(Hessian)。因此對于諸如XGBoost這類機器學(xué)習框架,損失函數(shù)的二階可微是很有必要的。

XgBoost中使用的目標函數(shù)。注意對一階和二階導(dǎo)數(shù)的依賴性

但Log-cosh損失也并非完美,其仍存在某些問題。比如誤差很大的話,一階梯度和Hessian會變成定值,這就導(dǎo)致XGBoost出現(xiàn)缺少分裂點的情況。

Huber和Log-cosh損失函數(shù)的Python代碼:

# huber lossdef huber(true, pred, delta):loss = np.where(np.abs(true-pred) < delta , 0.5*((true-pred)**2), delta*np.abs(true - pred) - 0.5*(delta**2))return np.sum(loss)# logcosh lossdef logcosh(true, pred): loss = np.log(np.cosh(pred - true))return np.sum(loss)

分位數(shù)損失

在大多數(shù)現(xiàn)實世界預(yù)測問題中,我們通常希望了解預(yù)測中的不確定性。清楚預(yù)測的范圍而非僅是估計點,對許多商業(yè)問題的決策很有幫助。

當我們更關(guān)注區(qū)間預(yù)測而不僅是點預(yù)測時,分位數(shù)損失函數(shù)就很有用。使用最小二乘回歸進行區(qū)間預(yù)測,基于的假設(shè)是殘差(y-y_hat)是獨立變量,且方差保持不變。

一旦違背了這條假設(shè),那么線性回歸模型就不成立。但是我們也不能因此就認為使用非線性函數(shù)或基于樹的模型更好,而放棄將線性回歸模型作為基線方法。這時,分位數(shù)損失和分位數(shù)回歸就派上用場了,因為即便對于具有變化方差或非正態(tài)分布的殘差,基于分位數(shù)損失的回歸也能給出合理的預(yù)測區(qū)間。

下面讓我們看一個實際的例子,以便更好地理解基于分位數(shù)損失的回歸是如何對異方差數(shù)據(jù)起作用的。

分位數(shù)回歸與最小二乘回歸

左:b/wX1和Y為線性關(guān)系。具有恒定的殘差方差。右:b/wX2和Y為線性關(guān)系,但Y的方差隨著X2增加。(異方差)

橙線表示兩種情況下OLS的估值

分位數(shù)回歸。虛線表示基于0.05和0.95分位數(shù)損失函數(shù)的回歸

附上圖中所示分位數(shù)回歸的代碼:

https://github/groverpr/Machine-Learning/blob/master/notebooks/09_Quantile_Regression.ipynb

理解分位數(shù)損失函數(shù)

如何選取合適的分位值取決于我們對正誤差和反誤差的重視程度。損失函數(shù)通過分位值(γ)對高估和低估給予不同的懲罰。例如,當分位數(shù)損失函數(shù)γ=0.25時,對高估的懲罰更大,使得預(yù)測值略低于中值。

γ是所需的分位數(shù),其值介于0和1之間。

分位數(shù)損失(Y軸)與預(yù)測值(X軸)圖示。Y的真值為0

這個損失函數(shù)也可以在神經(jīng)網(wǎng)絡(luò)或基于樹的模型中計算預(yù)測區(qū)間。以下是用Sklearn實現(xiàn)梯度提升樹回歸模型的示例。

使用分位數(shù)損失(梯度提升回歸器)預(yù)測區(qū)間

上圖表明:在sklearn庫的梯度提升回歸中使用分位數(shù)損失可以得到90%的預(yù)測區(qū)間。其中上限為γ=0.95,下限為γ=0.05。

對比研究

為了證明上述所有損失函數(shù)的特點,讓我們來一起看一個對比研究。首先,我們建立了一個從sinc(x)函數(shù)中采樣得到的數(shù)據(jù)集,并引入了兩項人為噪聲:高斯噪聲分量εN(0,σ2)和脈沖噪聲分量ξBern(p)。

加入脈沖噪聲是為了說明模型的魯棒效果。以下是使用不同損失函數(shù)擬合GBM回歸器的結(jié)果。

連續(xù)損失函數(shù):(A)MSE損失函數(shù);(B)MAE損失函數(shù);(C)Huber損失函數(shù);(D)分位數(shù)損失函數(shù)。將一個平滑的GBM擬合成有噪聲的sinc(x)數(shù)據(jù)的示例:(E)原始sinc(x)函數(shù);(F)具有MSE和MAE損失的平滑GBM;(G)具有Huber損失的平滑GBM,且δ={4,2,1};(H)具有分位數(shù)損失的平滑的GBM,且α={0.5,0.1,0.9}。

仿真對比的一些觀察結(jié)果:

MAE損失模型的預(yù)測結(jié)果受脈沖噪聲的影響較小,而MSE損失函數(shù)的預(yù)測結(jié)果受此影響略有偏移。Huber損失模型預(yù)測結(jié)果對所選超參數(shù)不敏感。分位數(shù)損失模型在合適的置信水平下能給出很好的估計。

最后,讓我們將所有損失函數(shù)都放進一張圖,我們就得到了下面這張漂亮的圖片!它們的區(qū)別是不是一目了然了呢~

一個完整的機器學(xué)習項目在Python中的演練(二) 公司視頻課程

img

布鞋

關(guān)注

譯者 | 磐石

出品 | 磐創(chuàng)AI技術(shù)團隊

【磐創(chuàng)AI導(dǎo)讀】:本文主要介紹了本系列的第三項特征工程與特征選擇。歡迎大家關(guān)注我們的公眾號:磐創(chuàng)AI。

大家往往會選擇一本數(shù)據(jù)科學(xué)相關(guān)書籍或者完成一門在線課程來學(xué)習和掌握機器學(xué)習。但是,實際情況往往是,學(xué)完之后反而并不清楚這些技術(shù)怎樣才能被用在實際的項目流程中。就像你的腦海中已經(jīng)有了一塊塊”拼圖“(機器學(xué)習技術(shù)),你卻不知道如何講他們拼起來應(yīng)用在實際的項目中。如果你也遇見過同樣的問題,那么這篇文章應(yīng)該是你想要的。本系列文章將介紹一個針對真實世界實際數(shù)據(jù)集的完整機器學(xué)習解決方案,讓您了解所有部分如何結(jié)合在一起。

本系列文章按照一般機器學(xué)習工作流程逐步進行:

1. 數(shù)據(jù)清洗與格式處理

2. 探索性數(shù)據(jù)分析

3. 特征工程和特征選取

4. 機器學(xué)習模型性能指標評估

5. 微調(diào)最佳模型(超參數(shù))

6. 在測試集上評估最佳模型

7. 解釋模型結(jié)果

8. 總結(jié)分析

通過完成所有流程,我們將看到每個步驟之間是怎么聯(lián)系起來的,以及如何在Python中專門實現(xiàn)每個部分。該項目可在GitHub上可以找到,附實現(xiàn)過程。第二篇文章將詳細介紹第三個步驟,其余的內(nèi)容將在后面的文章中介紹。

特征工程和特征選擇

特征工程和特征選擇雖然是完成機器學(xué)習項目中很小的一個環(huán)節(jié),但它模型最終的表現(xiàn)至關(guān)重要。在特征工程與特征選擇階段做的工作都會準時在模型的表現(xiàn)上得以體現(xiàn)。首先,讓我們來了解一下這兩項任務(wù)是什么:

特征工程:特征工程是一項獲取原始數(shù)據(jù)并提取或創(chuàng)建新特征的過程。也就是說可能需要對變量進行轉(zhuǎn)換。例如通過取自然對數(shù)、取平方根或者對分類變量進行獨熱(one-hot)編碼的方式以便它們可以在模型中更好的得以利用。通常來說,特征工程就是通過對原始數(shù)據(jù)的一些操作構(gòu)建額外有效特征的過程。(詳細介紹可參考:https://machinelearningmastery/discover-feature-engineering-how-to-engineer-features-and-how-to-get-good-at-it/)特征選擇:特征選擇是一項選擇數(shù)據(jù)中與任務(wù)最相關(guān)的特征的過程。在特征選擇的過程中,我們通過刪除無效或重復(fù)的數(shù)據(jù)特征以幫助模型更好地學(xué)習和總結(jié)數(shù)據(jù)特征并創(chuàng)建更具可解釋性的模型。通常來說,特征選擇更多的是對特征做減法,只留下那些相對重要的特征。(詳細介紹可參考:https://machinelearningmastery/an-introduction-to-feature-selection/)

因為機器學(xué)習模型只能從我們提供的數(shù)據(jù)中學(xué)習特征,所以確保數(shù)據(jù)包含我們?nèi)蝿?wù)的所有相關(guān)信息至關(guān)重要。如果我們沒有給模型提供正確的數(shù)據(jù),那么機器學(xué)習模型將不會達到我們所期望的表現(xiàn)。

在本項目中,我們將按照以下步驟完成特征工程:

獨熱(one-hot)編碼分類變量(borough和 property use type)對數(shù)值變量做自然對數(shù)轉(zhuǎn)換并作為新特征添加到原始數(shù)據(jù)中

獨熱(one-hot)編碼對于在模型訓(xùn)練中包含分類變量是必要的。例如:機器學(xué)習算法無法理解“辦公室”這種建筑類型,因此如果建筑物是辦公室,則必須對其進行將其記錄為1,否則將其記錄為0。

添加轉(zhuǎn)換的特征可以使我們的模型學(xué)習到數(shù)據(jù)中的非線性關(guān)系。取平方根、取自然對數(shù)或各種各樣的數(shù)值轉(zhuǎn)換是數(shù)據(jù)科學(xué)中特征轉(zhuǎn)換的常見做法,并通過領(lǐng)域知識或在多次實踐中發(fā)現(xiàn)最有效的方法。這里我們將對所有數(shù)值特征取自然對數(shù)并添加到原始數(shù)據(jù)中。

下面的代碼實現(xiàn)了數(shù)值特征選擇并對這些特征進行了取對數(shù)操作,選擇兩個分類變量并對這些特征進行獨熱(one-hot)編碼、然后將兩列特征連接在一起。這一系列操作可以通過pandas庫很快捷的實現(xiàn)。

完成上述操作之后,我們有110列(features)、總共超過11,000個對象(buildings)。但是,這些特征并非所有都能夠?qū)︻A(yù)測能源之星得分(ENERGY STAR Score)有用,所以接下來我們將通過特征選擇去除一些變量。

特征選擇

在上面做特征工程的過程之后得到的數(shù)據(jù)中的110列特征,許多都是多余或重復(fù)的,因為它們彼此高度相關(guān)。

例如,下圖是Site EUI與Weather Norm EUI相關(guān)系數(shù)為0.997的情況。

那些相互之間有很強關(guān)聯(lián)性的特征被稱為共線(collinear)https://en.wikipedia.org/wiki/Multicollinearity,而且消除這些“特征對”中的一個變量通??梢允箼C器學(xué)習模型更魯棒并且具有更強的可解釋性。(需要注意的一點是,現(xiàn)在是在討論特征與其他特征的相關(guān)性,而不是與目標的相關(guān)性。)

有許多方法可以計算特征之間的共線性(collinearity),其中最常見的是方差膨脹因子(VIF)。在本項目中,我們將使用相關(guān)系數(shù)來識別和刪除共線特征。如果它們之間的相關(guān)系數(shù)大于0.6,我們將放棄一對特征中的一個。

也許你會認為這個值(0.6)是隨便定義的,其實并不是,而是通過多次嘗試不同的閾值比較后得到的。使用0.6這個值可以產(chǎn)生了最好的模型。機器學(xué)習是一個經(jīng)驗性領(lǐng)域,通常是通過試驗發(fā)現(xiàn)性能最好參數(shù)組合。選擇特征后,我們剩下64列特征和1列目標特征(能源之星得分)。

建立基線

我們現(xiàn)在已經(jīng)完成了數(shù)據(jù)清洗,探索性數(shù)據(jù)分析和特征工程,開始建立模型之前還需要做最后一步:建立一個初步的基線(baseline)。這實際上是設(shè)置一項可以用來核對我們最終模型的實際表現(xiàn)的預(yù)估表現(xiàn)。我們可以通過拿最終模型表現(xiàn)與預(yù)估模型表現(xiàn)做比較反過來評測此次項目的整體思路。如果機器學(xué)習模型的最終表現(xiàn)沒有超越我們的預(yù)估表現(xiàn),那么我們可能不得不得出如下結(jié)論:

使用機器學(xué)習的方法無法解決此問題。或者我們可能需要嘗試其它不同的方法。

對于回歸問題,一個合理的基線是通過預(yù)估測試集中所有示例的運行結(jié)果為訓(xùn)練集中目標結(jié)果的中值。這種方式建立的基線為對比模型表現(xiàn)結(jié)果設(shè)定了一個相對較低的門檻。

我們將使用的度量標準是平均絕對誤差(mae)--計算出預(yù)測的平均絕對誤差。其實存在很多種回歸問題的度量指標,但我喜歡Andrew Ng的建議去選擇一個指標然后一直在以后模型評估中使用它。平均絕對誤差(mae)是一個不錯的選擇,它不僅容易計算并且可解釋性強。

在計算基線之前,我們需要將我們的數(shù)據(jù)分成一個訓(xùn)練集和一個測試集:

1. 訓(xùn)練集的作用就是通過給模型提供有標簽的數(shù)據(jù)來訓(xùn)練模型能力,換句話說就是訓(xùn)練集既能“提供問題”又能“提供答案”。旨在讓模型學(xué)習特征與目標之間的映射。

2. 測試集的作用是用來評估訓(xùn)練好模型。評估過程中不允許模型查看測試集的標簽,只能使用特征進行預(yù)測。我們可以通過對比測試集的預(yù)測值與標簽真實值來評估模型的表現(xiàn)。換句話說就是測試集只“提供問題”給模型不“提供答案”。

我們將使用70%的數(shù)據(jù)進行訓(xùn)練,30%用于測試:

計算基線并得出預(yù)估表現(xiàn)值(mae):

通過計算得出預(yù)估模型表現(xiàn)為66,在測試集中的誤差約為25左右(分值:1-100)。這是一個很容易達到的性能。

結(jié)論

在前兩篇的分析中,我們走過了一個完整機器學(xué)習項目的前三個步驟。在明確定義問題之后,我們:

1. 清洗并格式化了原始數(shù)據(jù)

2. 執(zhí)行探索性數(shù)據(jù)分析以了解數(shù)據(jù)集

3. 轉(zhuǎn)換出了一系列我們將用于模型的特征

4. 建立了可以判斷整個機器學(xué)習算法的基線。

接下來將展示如何使用Scikit-Learn評估機器學(xué)習模型,選擇最佳模型和微調(diào)超參數(shù)來優(yōu)化模型。

酷叮貓少兒編程講堂——Python 尋找aabb完全平方數(shù) 營銷視頻課程

img

凌鞅

關(guān)注

某個數(shù)如果是另一個整數(shù)的完全平方,那么我們就稱這個數(shù)為完全平方數(shù),也叫做平方數(shù)。比如:0,1,4,9,16,25,36等。 我們的任務(wù)是找到形如aabb的這樣的完全平方數(shù) (即前兩位相等,后兩位也相等)。

[分析]

算法一: 用0~9之間的數(shù)字組合出aabb這樣的數(shù)字,再對其進行開方,平方運算,從而驗證aabb是否為完全平方數(shù)。

算法二:我們對1~100之內(nèi)的數(shù)進行平方運算得到10000以內(nèi)的完全平方數(shù),再對其進行拆解,找到形如aabb的數(shù)

運行結(jié)果如下圖:

代碼如下:

# 算法一for a in range(1,10):for b in range(0,10): aabb = a*1100 + b*11 # 不一定是平方數(shù),但里面有平方數(shù) c = int(aabb**0.5 + 0.5) # 驗證。對aabb進行開方運算,并進行四舍五入取整 if c**2==aabb: print("完全平方數(shù){}, 開方后得到 {}".format(aabb, c)) print("{1} x {1} = {0}".format(aabb,c) )

第二種算法請大家自行設(shè)計,相信你一定可以想到辦法.

入門|數(shù)據(jù)科學(xué)初學(xué)者必知的NumPy基礎(chǔ)知識 營銷視頻課程

img

凝旋

關(guān)注

本文介紹了一些 NumPy 基礎(chǔ)知識,適合數(shù)據(jù)科學(xué)初學(xué)者學(xué)習掌握。

NumPy(Numerical Python)是 Python 中的一個線性代數(shù)庫。對每一個數(shù)據(jù)科學(xué)或機器學(xué)習 Python 包而言,這都是一個非常重要的庫,SciPy(Scientific Python)、Mat-plotlib(plotting library)、Scikit-learn 等都在一定程度上依賴 NumPy。

對數(shù)組執(zhí)行數(shù)學(xué)運算和邏輯運算時,NumPy 是非常有用的。在用 Python 對 n 維數(shù)組和矩陣進行運算時,NumPy 提供了大量有用特征。

這篇教程介紹了數(shù)據(jù)科學(xué)初學(xué)者需要了解的 NumPy 基礎(chǔ)知識,包括如何創(chuàng)建 NumPy 數(shù)組、如何使用 NumPy 中的廣播機制、如何獲取值以及如何操作數(shù)組。更重要的是,大家可以通過本文了解到 NumPy 在 Python 列表中的優(yōu)勢:更簡潔、更快速地讀寫項、更方便、更高效。

本教程將使用 Jupyter notebook 作為編輯器。

讓我們開始吧!

安裝 NumPy

如果你已經(jīng)裝有 Anaconda,那么你可以使用以下命令通過終端或命令提示符安裝 NumPy:

conda install numpy

如果你沒有 Anaconda,那么你可以使用以下命令從終端上安裝 NumPy:

pip install numpy

安裝好 NumPy 后,你就可以啟動 Jupyter notebook 開始學(xué)習了。接下來從 NumPy 數(shù)組開始。

NumPy 數(shù)組

NumPy 數(shù)組是包含相同類型值的網(wǎng)格。NumPy 數(shù)組有兩種形式:向量和矩陣。嚴格地講,向量是一維數(shù)組,矩陣是多維數(shù)組。在某些情況下,矩陣只有一行或一列。

首先將 NumPy 導(dǎo)入 Jupyter notebook:

import numpy as np

從 Python 列表中創(chuàng)建 NumPy 數(shù)組

我們先創(chuàng)建一個 Python 列表:

my_list = [1, 2, 3, 4, 5]

通過這個列表,我們可以簡單地創(chuàng)建一個名為 my_numpy_list 的 NumPy 數(shù)組,顯示結(jié)果:

my_numpy_list = np.array(my_list)my_numpy_list #This line show the result of the array generated

剛才我們將一個 Python 列表轉(zhuǎn)換成一維數(shù)組。要想得到二維數(shù)組,我們要創(chuàng)建一個元素為列表的列表,如下所示:

second_list = [[1,2,3], [5,4,1], [3,6,7]]new_2d_arr = np.array(second_list)new_2d_arr #This line show the result of the array generated

我們已經(jīng)成功創(chuàng)建了一個有 3 行 3 列的二維數(shù)組。

使用 arange() 內(nèi)置函數(shù)創(chuàng)建 NumPy 數(shù)組

與 Python 的 range() 內(nèi)置函數(shù)相似,我們可以用 arange() 創(chuàng)建一個 NumPy 數(shù)組。

my_list = np.arange(10)#ORmy_list = np.arange(0,10)

這產(chǎn)生了 0~10 的十個數(shù)字。

要注意的是 arange() 函數(shù)中有三個參數(shù)。第三個參數(shù)表示步長。例如,要得到 0~10 中的偶數(shù),只需要將步長設(shè)置為 2 就可以了,如下所示:

my_list = np.arange(0,11,2)

還可以創(chuàng)建有 7 個 0 的一維數(shù)組:

my_zeros = np.zeros(7)

也可以創(chuàng)建有 5 個 1 的一維數(shù)組:

my_ones = np.ones(5)

同樣,我們可以生成內(nèi)容都為 0 的 3 行 5 列二維數(shù)組:

two_d = np.zeros((3,5))

使用 linspace() 內(nèi)置函數(shù)創(chuàng)建 NumPy 數(shù)組

linspace() 函數(shù)返回的數(shù)字都具有指定的間隔。也就是說,如果我們想要 1 到 3 中間隔相等的 15 個點,我們只需使用以下命令:

lin_arr = np.linspace(1, 3, 15)

該命令可生成一維向量。

與 arange() 函數(shù)不同,linspace() 的第三個參數(shù)是要創(chuàng)建的數(shù)據(jù)點數(shù)量。

在 NumPy 中創(chuàng)建一個恒等矩陣

處理線性代數(shù)時,恒等矩陣是非常有用的。一般而言,恒等矩陣是一個二維方矩陣,也就是說在這個矩陣中列數(shù)與行數(shù)相等。有一點要注意的是,恒等矩陣的對角線都是 1,其他的都是 0。恒等矩陣一般只有一個參數(shù),下述命令說明了要如何創(chuàng)建恒等矩陣:

my_matrx = np.eye(6) #6 is the number of columns/rows you want

用 NumPy 創(chuàng)建一個隨機數(shù)組成的數(shù)組

我們可以使用 rand()、randn() 或 randint() 函數(shù)生成一個隨機數(shù)組成的數(shù)組。

使用 random.rand(),我們可以生成一個從 0~1 均勻產(chǎn)生的隨機數(shù)組成的數(shù)組。

例如,如果想要一個由 4 個對象組成的一維數(shù)組,且這 4 個對象均勻分布在 0~1,可以這樣做:

my_rand = np.random.rand(4)

如果我們想要一個有 5 行 4 列的二維數(shù)組,則:

my_rand = np.random.rand(5, 4)my_rand

使用 randn(),我們可以從以 0 為中心的標準正態(tài)分布或高斯分布中產(chǎn)生隨機樣本。例如,我們這樣生成 7 個隨機數(shù):

my_randn = np.random.randn(7)my_randn

繪制結(jié)果后會得到一個正態(tài)分布曲線。

同樣地,如需創(chuàng)建一個 3 行 5 列的二維數(shù)組,這樣做即可:

np.random.randn(3,5)

最后,我們可以使用 randint() 函數(shù)生成整數(shù)數(shù)組。randint() 函數(shù)最多可以有三個參數(shù):最小值(包含),最大值(不包含)以及數(shù)組的大小。

np.random.randint(20) #generates a random integer exclusive of 20np.random.randint(2, 20) #generates a random integer including 2 but excluding 20np.random.randint(2, 20, 7) #generates 7 random integers including 2 but excluding 20

將一維數(shù)組轉(zhuǎn)換成二維數(shù)組

先創(chuàng)建一個有 25 個隨機整數(shù)的一維數(shù)組:

arr = np.random.rand(25)

然后使用 reshape() 函數(shù)將其轉(zhuǎn)換為二維數(shù)組:

arr.reshape(5,5)

注意:reshape() 僅可轉(zhuǎn)換成行列數(shù)目相等,且行列數(shù)相乘后要與元素數(shù)量相等。上例中的 arr 包含 25 個元素,因此只能重塑為 5*5 的矩陣。

定位 NumPy 數(shù)組中的最大值和最小值

使用 max() 和 min() 函數(shù),我們可以得到數(shù)組中的最大值或最小值:

arr_2 = np.random.randint(0, 20, 10)arr_2.max() #This gives the highest value in the arrayarr_2.min() #This gives the lowest value in the array

使用 argmax() 和 argmin() 函數(shù),我們可以定位數(shù)組中最大值和最小值的索引:

arr_2.argmax() #This shows the index of the highest value in the array arr_2.argmin() #This shows the index of the lowest value in the array

假設(shè)存在大量數(shù)組,而你需要弄清楚數(shù)組的形態(tài),你想知道這個數(shù)組是一維數(shù)組還是二維數(shù)組,只需要使用 shape 函數(shù)即可:

arr.shape

從 NumPy 數(shù)組中索引/選擇多個元素(組)

在 NumPy 數(shù)組中進行索引與 Python 類似,只需輸入想要的索引即可:

my_array = np.arange(0,11)my_array[8] #This gives us the value of element at index 8

為了獲得數(shù)組中的一系列值,我們可以使用切片符「:」,就像在 Python 中一樣:

my_array[2:6] #This returns everything from index 2 to 6(exclusive)my_array[:6] #This returns everything from index 0 to 6(exclusive)my_array[5:] #This returns everything from index 5 to the end of the array.

類似地,我們也可以通過使用 [ ][ ] 或 [,] 在二維數(shù)組中選擇元素。

使用 [ ][ ] 從下面的二維數(shù)組中抓取出值「60」:

two_d_arr = np.array([[10,20,30], [40,50,60], [70,80,90]])two_d_arr[1][2] #The value 60 appears is in row index 1, and column index 2

使用 [,] 從上面的二維數(shù)組中抓取出值「20」:

two_d_arr[0,1]

也可以用切片符抓取二維數(shù)組的子部分。使用下面的操作從數(shù)組中抓取一些元素:

two_d_arr[:1, :2] # This returns [[10, 20]]two_d_arr[:2, 1:] # This returns ([[20, 30], [50, 60]])two_d_arr[:2, :2] #This returns ([[10, 20], [40, 50]])

我們還可以索引一整行或一整列。只需使用索引數(shù)字即可抓取任意一行:

two_d_arr[0] #This grabs row 0 of the array ([10, 20, 30])two_d_arr[:2] #This grabs everything before row 2 ([[10, 20, 30], [40, 50, 60]])

還可以使用 &、|、<、> 和 == 運算符對數(shù)組執(zhí)行條件選擇和邏輯選擇,從而對比數(shù)組中的值和給定值:

new_arr = np.arange(5,15)new_arr > 10 #This returns TRUE where the elements are greater than 10 [False, False, False, False, False, False, True, True, True, True]

現(xiàn)在我們可以輸出符合上述條件的元素:

bool_arr = new_arr > 10new_arr[bool_arr] #This returns elements greater than 10 [11, 12, 13, 14]new_arr[new_arr>10] #A shorter way to do what we have just done

組合使用條件運算符和邏輯運算符,我們可以得到值大于 6 小于 10 的元素:

new_arr[(new_arr>6) & (new_arr<10)]

預(yù)期結(jié)果為:([7, 8, 9])

廣播機制

廣播機制是一種快速改變 NumPy 數(shù)組中的值的方式。

my_array[0:3] = 50#Result is:[50, 50, 50, 3, 4, 5, 6, 7, 8, 9, 10]

在這個例子中,我們將索引為 0 到 3 的元素的初始值改為 50。

對 NumPy 數(shù)組執(zhí)行數(shù)學(xué)運算

arr = np.arange(1,11)arr * arr #Multiplies each element by itselfarr - arr #Subtracts each element from itselfarr + arr #Adds each element to itselfarr / arr #Divides each element by itself

我們還可以對數(shù)組執(zhí)行標量運算,NumPy 通過廣播機制使其成為可能:

arr + 50 #This adds 50 to every element in that array

NumPy 還允許在數(shù)組上執(zhí)行通用函數(shù),如平方根函數(shù)、指數(shù)函數(shù)和三角函數(shù)等。

np.sqrt(arr) #Returns the square root of each elementnp.exp(arr) #Returns the exponentials of each elementnp.sin(arr) #Returns the sin of each elementnp.cos(arr) #Returns the cosine of each elementnp.log(arr) #Returns the logarithm of each elementnp.sum(arr) #Returns the sum total of elements in the arraynp.std(arr) #Returns the standard deviation of in the array

我們還可以在二維數(shù)組中抓取行或列的總和:

mat = np.arange(1,26).reshape(5,5)mat.sum() #Returns the sum of all the values in matmat.sum(axis=0) #Returns the sum of all the columns in matmat.sum(axis=1) #Returns the sum of all the rows in mat

現(xiàn)在,這篇 NumPy 教程進入了尾聲!希望對大家有所幫助。

如何在Python中從零開始實現(xiàn)隨機森林 公司視頻課程

img

最后

關(guān)注

更多騰訊海量技術(shù)文章,請關(guān)注云+社區(qū):https://cloud.tencent/developer

決策樹可能會受到高度變異的影響,使得結(jié)果對所使用的特定測試數(shù)據(jù)而言變得脆弱。

根據(jù)您的測試數(shù)據(jù)樣本構(gòu)建多個模型(稱為套袋)可以減少這種差異,但是樹本身是高度相關(guān)的。

隨機森林是套袋(方法)的延伸,除了基于多個測試數(shù)據(jù)樣本構(gòu)建樹木之外,它還限制了可用于構(gòu)建樹木的特征,使得樹木間具有差異。這反過來可以提升算法的表現(xiàn)。

在本教程中,您將了解如何在Python中從頭開始實現(xiàn)隨機森林算法。

完成本教程后,您將知道:

套袋決策樹和隨機森林算法的區(qū)別。

如何構(gòu)造更多方差的袋裝決策樹。

如何將隨機森林算法應(yīng)用于預(yù)測建模問題。

讓我們開始吧。

2017年1月更新:將cross_validation_split()中fold_size的計算更改為始終為整數(shù)。修復(fù)了Python 3的問題。

2017年2月更新:修復(fù)了build_tree中的錯誤。

2017年8月更新:修正了基尼計算中的一個錯誤,增加了群組大?。ɑ谶~克爾!)。

如何在Python中從頭開始實現(xiàn)隨機森林

注:圖片來自 InspireFate Photography,保留部分權(quán)利。

描述

本節(jié)簡要介紹本教程中使用的隨機森林算法和Sonar數(shù)據(jù)集。

隨機森林算法

決策樹涉及從數(shù)據(jù)集中(利用)貪婪選擇選取最佳分割點過程中的每一步。

如果不精簡(該算法),此算法容易使決策樹出現(xiàn)高方差。這種高方差(結(jié)果)可以通過創(chuàng)建包含測試數(shù)據(jù)集中(多個)不同的實例(問題的不同觀點)的多重樹,接著將實例所有的可能結(jié)果結(jié)合,這種方法簡稱為bootstrap聚合或套袋。

套袋的局限性在于,它使用相同的貪婪算法來創(chuàng)建每棵樹,這意味著在每棵樹中可能會選擇相同或非常相似的分割點,使得不同的樹非常相似(樹將被關(guān)聯(lián))。這反過來又使他們的預(yù)測相似,從而縮減了最初尋求的差異。

我們可以通過貪婪算法在創(chuàng)建樹時在每個分割點評估的特征(行)來限制決策樹不同。這被稱為隨機森林算法。

像裝袋一樣,測試數(shù)據(jù)集的多個樣本在被采集后,接著在每個樣本上訓(xùn)練不同的樹。不同之處在于在每一點上,拆分是在數(shù)據(jù)中進行并添加到樹中的,且只考慮固定的屬性子集。

對于分類問題,我們將在本教程中討論的問題的類型——分割中輸入特點數(shù)的平方根值對為分割操作考慮的屬性個數(shù)的限制。

這一小變化的結(jié)果是樹之間變得更加不同(不關(guān)聯(lián)),作為結(jié)果會有更加多樣化的預(yù)測,這樣的結(jié)果往往好于一個單獨的樹或者單獨套袋得到的結(jié)果。

聲納數(shù)據(jù)集

我們將在本教程中使用的數(shù)據(jù)集是Sonar數(shù)據(jù)集。

這是一個描述聲納聲音從不同曲面反彈后返回(數(shù)據(jù))的數(shù)據(jù)集。輸入的60個變量是聲吶從不同角度返回的力度值。這是一個二元分類問題,需要一個模型來區(qū)分金屬圓柱中的巖石。這里有208個觀察對象。

這是一個很好理解的數(shù)據(jù)集。所有變量都是連續(xù)的且范圍一般是0到1。輸出變量是“Mine”字符串中的“M”和“rock”中的“R”,需要轉(zhuǎn)換為整數(shù)1和0。

通過預(yù)測在數(shù)據(jù)集(“M”或“mines”)中觀測數(shù)最多的類,零規(guī)則算法可以達到53%的準確度。

您可以在UCI Machine Learning repository了解關(guān)于此數(shù)據(jù)集的更多信息。

下載免費的數(shù)據(jù)集,并將其放置在工作目錄中,文件名為sonar.all-data.csv。

教程

本教程分為2個步驟。

計算分割。

聲納數(shù)據(jù)集案例研究。

這些步驟為您需要將隨機森林算法應(yīng)用于自己的預(yù)測建模問題奠定了基礎(chǔ)。

1.計算分割

在決策樹中,通過利用最低成本找到指定屬性和該屬性的值方法來確定分割點。

對于分類問題,這個成本函數(shù)通常是基尼指數(shù),它計算分割點創(chuàng)建的數(shù)據(jù)組的純度?;嶂笖?shù)為0是完美純度,其中在兩類分類問題的情況下,將類別值完全分成兩組。

在決策樹中找到最佳分割點涉及到為每個輸入的變量評估訓(xùn)練數(shù)據(jù)集中每個值的成本。

對于裝袋和隨機森林,這個程序是在測試數(shù)據(jù)集的樣本上執(zhí)行的,并且是可替換的。更換取樣意味著同一行(數(shù)據(jù))會不止一次的被選擇并將其添加到取樣中。

我們可以優(yōu)化隨機森林的這個程序。我們可以創(chuàng)建一個輸入屬性樣本來考慮,而不是在搜索中枚舉輸入屬性的所有值。

這個輸入屬性的樣本可以隨機選擇而不需要替換,這意味著每個輸入屬性在查找具有最低成本的分割點的過程中只被考慮一次。

下面是實現(xiàn)此過程的函數(shù)名稱get_split()。它將數(shù)據(jù)集和固定數(shù)量的輸入要素作為輸入?yún)?shù)進行評估,此數(shù)據(jù)集可能是實際測試數(shù)據(jù)集的一個樣本。

helper函數(shù)test_split()用于通過候選分割點拆分數(shù)據(jù)集,gini_index()用于根據(jù)創(chuàng)建的行組來計算給定拆分的花費。

我們可以看到,通過隨機選擇特征索引并將其添加到列表(稱為特征)來創(chuàng)建特征列表,然后枚舉該特征列表并且將測試數(shù)據(jù)集中的特定值評估作為分割點。

現(xiàn)在我們知道如何修改決策樹算法以便與隨機森林算法一起使用,我們可以將它與一個bagging實現(xiàn)一起使用,并將其應(yīng)用于現(xiàn)實生活中的數(shù)據(jù)集。

2.聲納數(shù)據(jù)集案例研究

在本節(jié)中,我們將把隨機森林算法應(yīng)用到聲納數(shù)據(jù)集。

該示例假定數(shù)據(jù)集的CSV副本位于當前工作目錄中,文件名為sonar.all-data.csv。

首先加載數(shù)據(jù)集,將字符串值轉(zhuǎn)換為數(shù)字,并將輸出列從字符串轉(zhuǎn)換為0和1的整數(shù)值。這可以通過使用幫助器函數(shù)load_csv(),str_column_to_float()和str_column_to_int()來加載和預(yù)備數(shù)據(jù)集。

我們將使用k-fold交叉驗證來估計未知數(shù)據(jù)的學(xué)習模型的性能。這意味著我們將構(gòu)建和評估k個模型,并將性能估計為平均模型誤差。分類準確性將用于評估每個模型。這些工具或是算法在cross_validation_split(),accuracy_metric()和evaluate_algorithm()輔助函數(shù)中提供。

我們也將使用適合套袋包括輔助功能分類和回歸樹(CART)算法的實現(xiàn))test_split(拆分數(shù)據(jù)集分成組,gini_index()來評估分割點,我們修改get_split()函數(shù)中討論在前一步中,to_terminal(),split()和build_tree()用于創(chuàng)建單個決策樹,預(yù)測()使用決策樹進行預(yù)測,subsample()創(chuàng)建訓(xùn)練數(shù)據(jù)集的子采樣,以及bagging_predict()用決策樹列表進行預(yù)測。

開發(fā)了一個新的函數(shù)名稱random_forest(),首先根據(jù)訓(xùn)練數(shù)據(jù)集的子樣本創(chuàng)建一個決策樹列表,然后使用它們進行預(yù)測。

正如我們上面所說的,隨機森林和袋裝決策樹之間的關(guān)鍵區(qū)別是對樹的創(chuàng)建方式中的一個小的改變,這里是在get_split()函數(shù)中。

完整的例子如下所示。

使用k值5進行交叉驗證,給定每個倍數(shù)值為208/5 = 41.6或者在每次迭代中剛好超過40個記錄被計算。

構(gòu)建深度樹的最大深度為10,每個節(jié)點的最小訓(xùn)練行數(shù)為1。訓(xùn)練數(shù)據(jù)集樣本的創(chuàng)建大小與原始數(shù)據(jù)集相同,這是隨機森林算法的默認期望值。

在每個分割點處考慮的特征的數(shù)量被設(shè)置為sqrt(num_features)或者sqrt(60)= 7.74被保留為7個特征。

對一套有著3種不同數(shù)量的樹木(示例)進行評測在此過程中進行比較,結(jié)果表明隨著更多樹木的添加,(處理)技能也隨之提升。

運行該示例將打印每個折疊的分數(shù)和每個配置的平均分數(shù)。

擴展

本節(jié)列出了您可能有興趣探索的關(guān)于本教程的擴展。

算法優(yōu)化。發(fā)現(xiàn)教程中使用的配置有一些試驗和錯誤,但沒有進行優(yōu)化。嘗試更多的樹木,不同數(shù)量的特征,甚至不同的樹形配置來提高性能。

更多的問題。將該技術(shù)應(yīng)用于其他分類問題,甚至將其應(yīng)用于回歸,具有新的成本函數(shù)和結(jié)合樹預(yù)測的新方法。

你有沒有嘗試這些擴展? 在下面的評論中分享你的經(jīng)驗。

評論

在本教程中,您了解了如何從頭開始實現(xiàn)隨機森林算法。

具體來說,你了解到:

隨機森林和Bagged決策樹的區(qū)別。

如何更新決策樹的創(chuàng)建以適應(yīng)隨機森林過程。

如何將隨機森林算法應(yīng)用于現(xiàn)實世界的預(yù)測建模問題。

翻譯人:一只懶惰的小白,該成員來自云+社區(qū)翻譯社

原文鏈接:https://machinelearningmastery/implement-random-forest-scratch-python/

原文作者:Jason Brownlee

img

在線咨詢

建站在線咨詢

img

微信咨詢

掃一掃添加
動力姐姐微信

img
img

TOP