R語言使用特徵工程泰坦尼克號數據分析應用案例

原文參考:http://tecdat.cn/?p=4491正則表達式

特徵工程對於模型的執行很是重要,即便是具備強大功能的簡單模型也能夠賽過複雜的算法。實際上,特徵工程被認爲是決定預測模型成功或失敗的最重要因素。特徵工程真正歸結爲機器學習中的人爲因素。經過人類的直覺和創造力,您對數據的瞭解程度能夠帶來不一樣。算法

那麼什麼是特徵工程?對於不一樣的問題,它可能意味着許多事情,但在泰坦尼克號的競爭中,它可能意味着砍伐,並結合咱們在Kaggle的優秀人員給予的不一樣屬性來從中榨取更多的價值。一般,機器學習算法能夠更容易地從工程學習算法中消化和制定規則,而不是從其導出的變量。app

得到更多機器學習魔力的最初嫌疑人是咱們上次從未發送到決策樹的三個文本字段。票號,艙位和名稱都是每位乘客獨有的; 也許能夠提取這些文本字符串的一部分以構建新的預測屬性。讓咱們從名稱字段開始。若是咱們看一下第一位乘客的名字,咱們會看到如下內容:機器學習

> train$Name[1]

[1] Braund, Mr. Owen Harris

891 Levels: Abbing, Mr. Anthony Abbott, Mr. Rossmore Edward ... Zimmerman, Mr. Leo

之前咱們只經過子集化訪問乘客組,如今咱們經過使用行號1做爲索引來訪問我的。好吧,船上沒有其餘人有這個名字,這幾乎能夠確定,但他們還有什麼共享?好吧,我確信船上有不少先生。也許人物頭銜可能會給咱們更多的洞察力。函數

若是咱們滾動數據集,咱們會看到更多的標題,包括Miss,Mrs,Master,甚至是Countess!標題「大師」如今有點過期,但在這些日子裏,它被保留給未婚男孩。此外,像咱們伯爵夫人這樣的貴族也可能對低級無產階級採起不一樣的行動。在這方面彷佛有不多的模式可能性比咱們以前看過的年齡,性別等組合更深刻。學習

爲了提取這些標題以建立新變量,咱們須要在訓練集和測試集上執行相同的操做,以便這些功能可用於增加咱們的決策樹,並對看不見的測試數據進行預測。在兩個數據集上同時執行相同過程的簡單方法是合併它們。在R中咱們可使用rbind,它表明行綁定,只要兩個數據幀具備彼此相同的列。因爲咱們在測試集中顯然缺乏Survived列,讓咱們建立一個完整的缺失值(NAs),而後將兩個數據集行綁定在一塊兒:測試

> test$Survived <- NA

> combi <- rbind(train, test)

如今咱們有了一個名爲「combi」的新數據框,其中包含與原始兩個數據集徹底相同的行,按照咱們指定的順序堆疊:先訓練,而後測試第二。編碼

若是你回顧一下咱們對Owen的調查結果,他的名字仍然被編碼爲一個因素。正如咱們在教程系列前面提到的那樣,字符串會自動導入R中的因子,即便它沒有意義。因此咱們須要將此列轉換回文本字符串。要作到這一點,咱們使用as.character。讓咱們這樣作,而後再看看歐文:spa

> combi$Name <- as.character(combi$Name)

> combi$Name[1]

[1] "Braund, Mr. Owen Harris"

爲了分解字符串,咱們須要一些鉤子來告訴程序要查找。很好,咱們看到人名後面有一個逗號,而且在他們的頭銜以後有一個句號。咱們能夠很容易地使用函數strsplit(表明字符串拆分)來區分這兩個符號的原始名稱。讓咱們試試布朗德先生:code

> strsplit(combi$Name[1], split='[,.]')

[[1]]

[1] "Braund" " Mr" " Owen Harris"

好的。在這裏,咱們發送strsplit了感興趣的單元格,並在分割字符串時爲其選擇了一些符號,能夠是逗號或句點。方括號中的那些符號稱爲正則表達式,雖然這是一個很是簡單的符號,若是您打算使用大量文本,我確定會建議習慣使用它們!

咱們看到標題已經單獨打破了,雖然在它開始以前有一個奇怪的空間,由於逗號發生在姓氏的末尾。可是,咱們如何得到這個標題並清除其餘咱們不想要的東西呢?[[1]]在文本部分以前打印索引。讓咱們嘗試經過將全部方括號附加到原始命令來深刻研究這種新類型的容器:

> strsplit(combi$Name[1], split='[,.]')[[1]]

[1] "Braund" " Mr" " Owen Harris"

字符串拆分使用雙重堆疊矩陣,由於它永遠不能肯定給定的正則表達式將具備相同數量的塊。若是名稱中有更多逗號或句點,則會建立更多段,所以它會將它們隱藏得更深,以維護咱們習慣使用的矩形類型的容器,例如電子表格或如今的數據幀!讓咱們深刻了解索引混亂並提取標題。這是這個嵌套列表中的第二個項目,因此讓咱們深刻研究這個新容器的索引號2:

> strsplit(combi$Name[1], split='[,.]')[[1]][2]

[1] " Mr"

因爲咱們不得不深刻研究這個容器以得到標題,只需嘗試combi$Title <- strsplit(combi$Name, split='[,.]')[[1]][2]遍歷整個名稱向量就會致使咱們全部的行都具備相同的Mr.,因此咱們須要更加努力。不出所料,將函數應用於數據幀或向量中的大量單元格會使用applyR的函數套件:

> combi$Title <- sapply(combi$Name, FUN=function(x) {strsplit(x, split='[,.]')[[1]][2]})

R的應用功能都以稍微不一樣的方式sapply工做,但在這裏工做得很好。咱們提供sapply了咱們剛剛提出的名稱向量和函數。它遍歷名稱向量的行,並將每一個名稱發送到函數。全部這些字符串拆分的結果都被組合成一個向量做爲sapply函數的輸出,而後咱們將其存儲到原始數據幀中的一個新列,稱爲Title。

最後,咱們可能但願從標題的開頭剝離這些空格。在這裏,咱們能夠用任何東西替換第一次出現的空格。咱們可使用sub這個:

> combi$Title <- sub(' ', '', combi$Title)

好吧,咱們如今有一個很好的新標題列,讓咱們來看看它:

> table(combi$Title)

Capt Col Don Dona Dr Jonkheer Lady

1 4 1 1 8 1 1

Major Master Miss Mlle Mme Mr Mrs

2 61 260 2 1 757 197

Ms Rev Sir the Countess

2 8 1 1

嗯,這裏有一些很是罕見的標題,不會給咱們的模型不少,因此讓咱們結合一些最不尋常的。讓咱們將它們組合成一個類別:

> combi$Title[combi$Title %in% c('Mme', 'Mlle')] <- 'Mlle'

咱們在這作了什麼?該%in%運營商檢查是否值是咱們比較它與載體的一部分。因此在這裏咱們將兩個標題「Mme」和「Mlle」組合成一個新的臨時向量,使用c()運算符並查看整個Title列中的任何現有標題是否與它們中的任何一個匹配。而後咱們用「Mlle」替換任何一場比賽。

咱們一直在尋找冗餘。對於咱們這裏的集合來講,很是富有彷佛是一個問題。對於這些男人來講,咱們有一些只有一兩個被祝福的頭銜:船長,少校和先生。全部這些都是軍事頭銜,或者是出生時擁有大片土地的富裕傢伙。

對於女士們,咱們有Dona,Lady,Jonkheer(*見下面的評論),固然還有咱們的伯爵夫人。全部這些人都是富人,因爲他們的高貴出生,他們的行爲可能有些類似。讓咱們將這兩個組合在一塊兒,並將因子級別的數量減小到決策樹可能理解的範圍:

< combi$Title[combi$Title %in% c('Dona', 'Lady', 'the Countess', 'Jonkheer')] <- 'Lady'

咱們的最後一步是將變量類型更改回一個因子,由於這些基本上是咱們建立的類別:

> combi$Title <- factor(combi$Title)

好的。咱們如今已經完成了乘客的頭銜。咱們還能想到什麼呢?那麼,有兩個變量SibSb和Parch代表乘客隨行的家庭成員人數。彷佛有理由認爲一個你們庭可能沒法追蹤小約翰尼,由於他們都爭先恐後地下沉沉船,因此讓咱們將這兩個變量合併爲一個新的,FamilySize:

> combi$FamilySize <- combi$SibSp + combi$Parch + 1

很簡單!咱們只是添加乘客與他們在一塊兒的兄弟姐妹,配偶,父母和孩子的數量,固然還有一個用於他們本身的存在,而且有一個新的變量代表他們旅行的家庭的大小。

更多的東西?好吧,咱們只是想到一個你們庭一塊兒遇到救生艇的問題,但也許特定的家庭比其餘家庭更麻煩?咱們能夠嘗試提取乘客的姓氏並將他們分組以尋找家人,但像約翰遜這樣的常見姓氏可能會在船上增長一些非相關人員。事實上,在一個3歲的家庭中有三個約翰遜,另外三個可能無關的約翰遜都是獨自旅行。

將姓氏與家庭大小相結合能夠解決這個問題。沒有兩個家族 - 約翰遜應該在如此小的船上擁有相同的FamilySize變量。讓咱們首先提取乘客的姓氏。這應該是咱們以前運行的標題提取代碼的一個很是簡單的變化,如今咱們只想要strsplit輸出的第一部分:

> combi$Surname <- sapply(combi$Name, FUN=function(x) {strsplit(x, split='[,.]')[[1]][1]})

而後咱們想要將FamilySize變量附加到它的前面,但正如咱們所看到的那樣,字符串操做須要字符串。所以,讓咱們將FamilySize變量臨時轉換爲字符串,並將其與Surname結合使用以獲取新的FamilyID變量:

combi$FamilyID <- paste(as.character(combi$FamilySize), combi$Surname, sep="")

咱們使用該函數paste將兩個字符串組合在一塊兒,並告訴它經過sep參數將它們分開。這被存儲到一個名爲FamilyID的新列中。可是那三個單身的約翰遜人都擁有相同的家庭ID。鑑於咱們最初假設你們庭可能難以在恐慌中堅持到一塊兒,讓咱們將任何兩個或更少的家庭大小淘汰,稱之爲「小」家庭。這也將解決約翰遜問題。

> combi$FamilyID[combi$FamilySize <= 2] <- 'Small'

讓咱們看看咱們如何識別這些家庭羣體:

> table(combi$FamilyID)

11Sage 3Abbott 3Appleton 3Beckwith 3Boulos

11 3 1 2 3

3Bourke 3Brown 3Caldwell 3Christy 3Collyer

3 4 3 2 3

3Compton 3Cornell 3Coutts 3Crosby 3Danbom

3 1 3 3 3 . . .

嗯,有幾個彷佛已經從這裏的裂縫中滑落。有不少FamilyID只有一兩個成員,即便咱們只想要3或更多的家庭成員。也許有些家庭有不一樣的姓氏,但不管如何,全部這些一兩我的羣體都是咱們試圖避免的三我的的截止。讓咱們開始清理它:

> famIDs <- data.frame(table(combi$FamilyID))

如今咱們將上面的表存儲到數據幀中。是的,若是您願意,能夠將大多數表存儲到數據框中,因此讓咱們經過在資源管理器中單擊它來查看它:

在這裏,咱們再次看到全部那些與咱們的假設不能很好地合做的頑皮家庭,因此讓咱們將這個數據框的子集只顯示那些意外小的FamilyID組。

famIDs <- famIDs[famIDs$Freq <= 2,]

而後,咱們須要在數據集中覆蓋未正確識別的組中的任何族ID,並最終將其轉換爲因子:

咱們如今準備將測試和訓練集分解回原始狀態,用它們帶來咱們新奇的工程變量。咱們剛剛作的最好的部分是如何在R中處理因子。在幕後,因子基本上存儲爲整數,可是用它們的文本名稱掩蓋以供咱們查看。若是在單獨的測試和訓練集上建立上述因子,則沒法保證兩組中都存在兩個組。

例如,先前討論的「3Johnson」族在測試集中不存在。咱們知道他們三個都從訓練集數據中倖存下來。若是咱們孤立地創建了咱們的因素,那麼測試集就沒有因素「3Johnson」。這會擾亂任何機器學習模型,由於用於構建模型的訓練集與要求它預測的測試集之間的因素不一致。即。若是你嘗試,R會向你拋出錯誤。

由於咱們在單個數據幀上構建了因子,而後在構建它們以後將它們拆分,R將爲全部新數據幀提供全部因子級別,即便該因子不存在於一個數據幀中也是如此。它仍然具備因子水平,但在集合中沒有實際觀察。整潔的把戲對嗎?我向您保證,手動更新因子水平是一件痛苦的事。

所以,讓咱們將它們分開並對咱們新的花哨工程變量作一些預測:

這裏咱們介紹R中的另外一種子集方法; 有不少取決於您但願如何切割數據。咱們已根據原始列車和測試集的大小隔離了組合數據集的某些行範圍。以後的逗號後面沒有數字表示咱們想要使用此子集獲取全部列並將其存儲到指定的數據幀。這爲咱們提供了原始行數,以及全部新變量,包括一致的因子水平。

是時候作咱們的預測了!咱們有一堆新變量,因此讓咱們將它們發送到一個新的決策樹。上次默認的複雜性很是好,因此讓咱們用香草控件生成一棵樹,看看它能作什麼:

有趣的是,咱們的新變量基本上管理着咱們的樹。這是我上次沒有提到的決策樹的另外一個缺點:它們偏向於支持多層次的因素。看看咱們的61級FamilyID因素在這裏是如此突出,而且樹挑出了全部比其餘家庭更偏向的家庭。這樣,決策節點能夠將數據切割並改變爲如下節點的純度的最佳可能組合。

但除此以外,您應該知道如何從決策樹建立提交,因此讓咱們看看它是如何執行的!

太棒了,咱們的排名幾乎減半了!全部這一切都是經過從咱們已經擁有的東西中榨取更多的價值。這只是您能夠在此數據集中找到的示例。

繼續嘗試建立更多工程變量!和之前同樣,我也很是鼓勵你玩複雜性參數,也許能夠嘗試修剪一些更深的樹,看它是否有助於或阻礙你的等級。您甚至能夠考慮從樹中排除一些變量,看看它是否也發生了變化。

但在大多數狀況下,因爲決策樹的貪婪性,標題或性別變量將決定第一個決策。對於多層次因素的偏見也不會消失,若是沒有實際提交意見書,過分擬合問題很難衡量,但良好的判斷力可能會有所幫助。

有問題歡迎下方留言!

相關文章
相關標籤/搜索