随机森林 python_如何轻松使用python的随机森林
如何輕松的使用Python中的隨機森林
從來沒有比現在更好的時間來學習機器學習了。隨著vailable在線學習資源,免費的開源工具的提供,以及任何可以想到的算法的實現方法,并通過云服務,例如廉價AWS計算能力,機器學習由互聯網領域已經大眾化。任何能夠使用筆記本電腦并樂于學習的人都可以在幾分鐘內嘗試最先進的算法。再多花一點時間,您就可以開發實用的模型來為您的日常生活或工作提供幫助(甚至切換到機器學習領域并獲得經濟利益))。這篇文章將引導您完成功能強大的隨機森林機器學習模型的建立。它旨在補充我對隨機森林的概念性解釋,但只要您對決策樹和隨機森林有基本了解,就可以完全單獨閱讀。后面還會介紹更深的隨機森林優化。
理所應當的這里會有Python代碼,但是,任何人都可以訪問這些機器學習資源!數據文件和Jupyter Notebook也可以從Google云端硬盤下載。您所需要的只是一臺安裝了Python的筆記本電腦,并且具有啟動Jupyter Notebook的能力,您可以繼續學習。這里將涉及一些必要的機器學習主題,但是我將盡力使它們變得清晰,并為感興趣的人提供更多的學習資源。
11. 問題介紹
我們將要解決的問題是使用一年的過去天氣數據來預測我們城市明天的最高溫度。我正在使用華盛頓州西雅圖市,但是可以使用NOAA在線氣候數據工具隨意查找您自己城市的數據。我們將進行預測,假設我們無法獲得任何天氣預報一樣,而且,我們要做出我們自己的預測而不是依靠其他預測會更有趣。我們所能獲得的是一年的歷史最高氣溫,前兩天的氣溫,以及一個一直聲稱對天氣有所了解的朋友的估計。這是有監督的回歸機器學習問題。之所以受到監督,是因為我們同時具有要預測的特征(城市數據)和目標(溫度)。在訓練期間,我們為隨機森林提供了特征和目標,并且它必須學習如何將數據映射到預測。此外,這是一項回歸任務,因為目標值是連續的(與分類中的離散類相對)。這幾乎是我們需要的所有背景,所以讓我們開始吧!
2. 路線圖
在我們直接進行編程之前,我們應該先制定一份簡短的指南,以保持我們方向正確。一旦我們想到了問題和模型,以下步驟將是任何機器學習工作流程的基礎:
步驟1已被我們已經完成!我們的問題:“我們能預測明天城市的最高溫度嗎?” 而且我們知道我們可以獲取過去一年華盛頓州西雅圖市的歷史最高氣溫。
3. 數據采集
首先,我們需要一些數據。舉一個現實的例子,我使用NOAA氣候數據在線工具從2016年檢索了華盛頓州西雅圖的天氣數據。通常,大約80%的數據分析時間是清理和檢索數據,但是可以通過查找高質量的數據源來減少此工作量。NOAA工具非常的易用,溫度數據可以以干凈的csv文件的形式下載,可以用Python或R等語言進行解析。
地址為:https://drive.google.com/file/d/1pko9oRmCllAxipZoa3aoztGZfPAD2iwj/view
以下Python代碼在csv數據中加載并顯示數據的結構:
信息采用整潔的數據格式,每一行構成一個觀察值,各列中包含變量值。
以下是各列的說明:
year:所有數據點均為2016年
month:一年中的月份號
day:一年中的天數
week:星期幾作為字符串
temp_2: 2天之前的最高溫度
temp_1: 1天前的最高溫度
average:歷史平均最高溫度
actual:最高溫度測量
friend:您朋友的預測,是隨機數在平均值以下20到平均值以上20之間
4. 識別異常/丟失數據
如果我們看一下數據的維度,就會發現只有348行,這與2016年我們知道的366天并不完全一致。通過NOAA的數據,我注意到有幾天丟失了,這極大地提醒了我們,在現實世界中收集的數據永遠不會是完美的。數據丟失可能會影響分析,不正確的數據或異常值也會影響分析。在這種情況下,丟失的數據不會有很大的影響,并且由于源的原因,數據質量也很好。我們還可以看到有9個列代表8個功能和一個目標(“實際”)。
print('The shape of our features is:', features.shape) The shape of our features is: (348, 9)為了識別異常,我們可以快速計算摘要統計信息。
# Descriptive statistics for each column features.describe() 1一眼望去,在任何列中都沒有明顯顯示為異常的數據點。驗證數據質量的另一種方法是繪制圖。通常,在圖形中發現異常比在數字中發現異常更容易。我在這里省略了實際的代碼,因為使用Python進行繪圖是不直觀的,但是可以隨時訪問github以獲取完整的code(就像任何優秀的數據科學家一樣,我幾乎從Stack Overflow復制并粘貼了繪圖代碼,哈哈)。
1檢查定量統計數據和圖表,我們可以對數據的高質量充滿信心。沒有明顯的異常值,盡管存在一些遺漏點,但它們不會影響分析。
5. 資料準備
不幸的是,我們還不能完全將原始數據輸入模型并返回答案(盡管人們正在為此做準備)!我們將需要做一些小的修改,以使我們的數據成為機器可理解的數據形式。我們將使用Python-Pandas進行數據處理,它依賴于稱為數據框的結構,該結構基本上是具有行和列的excel電子表格。
數據準備的確切步驟將取決于所使用的模型和收集的數據,但是任何機器學習應用程序都將需要一定數量的數據處理。
5.1 One-Hot Encoding
我們的第一步被稱為單熱編碼的數據。此過程將使用類別變量(例如星期幾),并將其轉換為數字表示形式,而無需進行任意排序。一周中的幾天對我們來說很直觀,因為我們一直都在使用它們。但是機器沒有任何直觀的知識。計算機知道的是只有數字,所以當進行機器學習,我們必須的數據必須只包含數字。但如果我們簡單地將一周中的幾天映射為數字1至7(label方法),但這可能會導致算法在星期日上更加重要,因為它具有較高的數值。相反,我們將工作日的單列更改為7列二進制數據。最好用圖形說明。熱門編碼采用此方法:
1并變成
1因此,如果數據點是星期三,則在星期三列中將有一個1,在所有其他列中將有一個0。此過程可以在一行中的pandas中完成!
# One-hot encode the data using pandas get_dummies features = pd.get_dummies(features) # Display the first 5 rows of the last 12 columns features.iloc[:,5:].head(5)一鍵編碼后的數據:
1現在我們的數據形狀為349 x 15,并且所有列都是數字,就像算法喜歡的數據樣式!
6. 特征和目標并將數據轉換為數組
現在,我們需要將數據分為特征和目標。目標(也稱為標簽)是我們要預測的值,在這種情況下,實際最高溫度和特征是模型用來進行預測的所有列。我們還將pandas數據框轉換為Numpy數組,因為這是該算法的工作方式。(我將列標題(即特征名稱)保存到列表中,以用于以后的可視化)。
# Use numpy to convert to arrays import numpy as np # Labels are the values we want to predict labels = np.array(features['actual']) # Remove the labels from the features # axis 1 refers to the columns features= features.drop('actual', axis = 1) # Saving feature names for later use feature_list = list(features.columns) # Convert to numpy array features = np.array(features)6. 訓練集和測試集
數據準備的最后一步是:將數據分為訓練和測試集。在訓練過程中,我們讓模型“看到”答案,在本模型中為實際溫度,因此它可以學習如何根據特征預測溫度。我們期望所有特征與目標值之間存在某種關系,并且模型的工作是在訓練過程中學習這種關系。然后,當需要評估模型時,我們要求它在只能訪問特征(而不能訪問答案)的測試集中進行預測!因為我們有測試集的真實值,所以我們可以將這些預測值與真實值進行比較,以判斷模型的準確性。通常,在訓練模型時,我們將數據隨機分為訓練和測試集 為了獲得所有數據點的表示形式(如果我們在一年的前九個月進行了培訓,然后將最后三個月用于預測,則我們的算法將無法很好地執行,因為它沒有看到過去三個月的任何數據。)我將隨機種子設置為42,這意味著每次運行代碼,結果都將相同。
以下代碼用另一行分割數據集:
我們可以查看所有數據的形狀,以確保正確完成了所有操作。我們希望訓練功能的列數與測試功能的列數相匹配,行數與各個訓練和測試功能及標簽相匹配:
print('Training Features Shape:',train_features.shape) print('Training Labels Shape:',train_labels.shape) print('Testing Features Shape:',test_features.shape) print('Testing Labels Shape:',test_labels。形狀) Training Features Shape: (261, 14) Training Labels Shape: (261,) Testing Features Shape: (87, 14) Testing Labels Shape: (87,)看來一切都井然有序!回顧一下,為了使數據成為機器學習可以接受的形式,我們:
根據初始數據集,可能需要進行額外的工作,例如刪除異常值,估算缺失值或將時間變量轉換為循環表示。這些步驟乍一看似乎是任意的,但是一旦您獲得了基本的工作流程,對于任何機器學習問題來說,它通常都是相同的。這一切都是關于將人類可讀的數據放入一種機器學習模型可以理解的形式。
7. 建立base
在做出和評估預測之前,我們需要建立一個基線,這是我們希望與我們的模型相比較的措施。如果我們的模型不能在基線上得到改善,那將是一個失敗,我們應該嘗試其他模型,或者承認機器學習不適合我們的問題。我們的案例的基線預測可以是歷史最高溫度平均值。換句話說,我們的基線是如果我們僅預測所有天的平均最高溫度,就會得到的誤差。
# The baseline predictions are the historical averages baseline_preds = test_features[:, feature_list.index('average')] # Baseline errors, and display average baseline error baseline_errors = abs(baseline_preds - test_labels) print('Average baseline error: ', round(np.mean(baseline_errors), 2)) Average baseline error: 5.06 degrees.現在我們有了目標!如果我們無法提升5度的平均誤差,那么我們需要重新考慮我們的方法。
7. 訓練模型
在完成所有數據準備工作之后,使用Scikit-learn即可輕松創建和訓練模型。我們從skicit-learn導入隨機森林回歸模型,然后將模型(訓練的scikit-learn名稱)適配fit于訓練數據。(再次將隨機狀態設置為可再現的結果)。整個過程在scikit-learn中只有3行!
# Import the model we are using from sklearn.ensemble import RandomForestRegressor # Instantiate model with 1000 decision trees rf = RandomForestRegressor(n_estimators = 1000, random_state = 42) # Train the model on training data rf.fit(train_features, train_labels);8. 測試集進行預測
現在,我們的模型已經過訓練,可以學習特征與目標之間的關系。下一步是弄清楚模型的好壞!為此,我們對測試功能進行預測(永遠不允許模型查看測試答案)。然后,我們將預測與已知答案進行比較。在執行回歸時,我們需要確保使用絕對誤差,因為我們的某些答案很低,而有些答案則很高,但我們對平均預測值與實際值相距多遠感興趣,因此我們采用了絕對值(建立基線時也是如此)。
用模型進行預測是Skicit-learn中的另一條1行命令。
我們的平均估計相差3.83度。這比基準平均提高了1度以上。盡管這看起來似乎并不重要,但它比基準高出近25%,根據領域和問題的不同,基準可能會給公司帶來數百萬美元的收入。
9. 確定性能指標
為了正確理解我們的預測,我們可以使用從100%中減去的平均百分比誤差來計算準確性。
# Calculate mean absolute percentage error (MAPE) mape = 100 * (errors / test_labels) # Calculate and display accuracy accuracy = 100 - np.mean(mape) print('Accuracy:', round(accuracy, 2), '%.') Accuracy: 93.99 %.看起來不錯!我們的模型學習了如何以94%的準確度預測西雅圖第二天的最高溫度。
10. 必要時改進模型
在通常的機器學習工作流程中,這將是在開始超參數調整時。這是一個復雜的短語,意為“調整設置以提高性能”(這些設置稱為超參數,可將其與訓練期間學習的模型參數區分開)。最常見的方法是簡單地制作一堆具有不同設置的模型,在相同的驗證集上對它們進行評估,然后看看哪個模型效果最好。當然,這將是手工完成的繁瑣過程,并且在Skicit-learn中有自動方法可以完成此過程。與基于理論的調優相比,超參數調優通常更具工程性,我鼓勵任何有興趣的人查看文檔開始玩吧!94%的精度對于此問題是令人滿意的,但請記住,第一個構建的模型幾乎永遠不會成為可投入生產的模型。
11. 解釋模型并報告結果
在這一點上,我們知道我們的模型是好的,但是它幾乎是一個黑匣子。我們輸入一些Numpy數組進行訓練,要求它做出預測,評估這些預測,并確定它們是合理的。問題是:此模型如何得出值?有兩種方法可以獲取隨機森林的內幕:首先,我們可以查看森林中的一棵樹,其次,我們可以查看解釋變量的特征重要性。
12. 可視化單個決策樹
Skicit-learn中Random Forest實現最酷的部分之一是,我們實際上可以檢查森林中的任何一顆決策樹。我們將選擇一棵樹,并將整棵樹保存為圖像。
# Import tools needed for visualization from sklearn.tree import export_graphviz import pydot # Pull out one tree from the forest tree = rf.estimators_[5] # Import tools needed for visualization from sklearn.tree import export_graphviz import pydot # Pull out one tree from the forest tree = rf.estimators_[5] # Export the image to a dot file export_graphviz(tree, out_file = 'tree.dot', feature_names = feature_list, rounded = True, precision = 1) # Use dot file to create a graph (graph, ) = pydot.graph_from_dot_file('tree.dot') # Write graph to a png file graph.write_png('tree.png')12.1 森林中的單個完整決策樹
哇!這看起來像是一棵有15層的膨脹樹(實際上,與我見過的一些樹相比,這是一棵很小的樹)。您可以自己下載此圖像并進行更詳細的檢查,但是為了使操作更容易,我將限制森林中樹木的深度以生成可理解的圖像。
# Limit depth of tree to 3 levels rf_small = RandomForestRegressor(n_estimators=10, max_depth = 3) rf_small.fit(train_features, train_labels) # Extract the small tree tree_small = rf_small.estimators_[5] # Save the tree as a png image export_graphviz(tree_small, out_file = 'small_tree.dot', feature_names = feature_list, rounded = True, precision = 1) (graph, ) = pydot.graph_from_dot_file('small_tree.dot') graph.write_png('small_tree.png') 1這是帶有標簽注釋的尺寸縮小的樹
1僅基于此樹,我們就可以對任何新數據點進行預測。讓我們以對2017年12月27日星期三進行預測為例。(實際)變量為:temp_2 = 39, temp_1 = 35, average = 44, friend = 30。我們從根節點開始,第一個答案為真,因為temp_1≤59.5。我們向左移動并遇到第二個問題,當平均≤46.8時也為True。向下移動到第三個也是最后一個也是True的問題,因為temp_1≤44.5。因此,我們得出結論,如葉節點中的值所示,我們對最高溫度的估計為41.0度。有趣的觀察是,盡管有261個訓練數據點,但在根節點中只有162個樣本。(創建森林時,我們可以通過設置bootstrap = False來關閉替換采樣并使用所有數據點)。數據點的隨機采樣,再結合在樹的每個節點上對特征子集的隨機采樣,是將模型稱為“隨機”森林的原因。
此外,請注意,在我們的樹中,實際上只有2個變量可用于進行預測!根據此特定決策樹,其余特征對于進行預測并不重要。一年中的月份、月中的某天、以及我們朋友的預測對于明天預測最高氣溫完全沒有用!根據我們的簡單樹,唯一重要的信息是:1天前的溫度和歷史平均值。可視化樹增加了我們對該問題的領域知識,并且現在我們知道如果要求我們進行預測將查找哪些數據!
13. 特征重要性
為了量化整個隨機森林中所有變量的有用性,我們可以查看變量的相對重要性。
Skicit-learn中返回的重要性表示包含特定變量在多大程度上可以改善預測結果。重要性的實際計算超出了本文的范圍,但是我們可以使用數字在變量之間進行相對比較。
此處的代碼利用了Python語言中的許多技巧,即列表綜合,zip,排序和參數解壓縮。暫時了解這些并不是很重要,但是如果您想熟練使用Python,那么這些都是您應該擁有的工具!
列表的頂部是temp_1,即前一天的最高溫度。這告訴我們一天最高溫度的最佳預測指標是前一天的最高溫度,這是一個相當直觀的發現。第二個最重要的因素是歷史平均最高溫度,也就不足為奇了。事實證明,您的朋友以及前兩天的星期幾,年,月和溫度不是很有幫助。這些重要性都是有道理的,因為我們不希望一周中的某天成為最高氣溫的預測指標,因為它與天氣無關。此外,所有數據點的年份都相同,因此沒有為我們提供預測最高溫度的信息。
在模型的未來實現中,我們可以刪除那些不重要的變量,并且性能不會受到影響。另外,如果我們使用不同的模型(例如支持向量機),則可以將隨機森林特征重要性用作一種特征選擇方法。讓我們快速創建一個僅包含兩個最重要變量的隨機森林,即前1天的最高溫度和歷史平均值,并查看性能之間的比較。
# New random forest with only the two most important variables rf_most_important = RandomForestRegressor(n_estimators= 1000, random_state=42) # Extract the two most important features important_indices = [feature_list.index('temp_1'), feature_list.index('average')] train_important = train_features[:, important_indices] test_important = test_features[:, important_indices] # Train the random forest rf_most_important.fit(train_important, train_labels) # Make predictions and determine the error predictions = rf_most_important.predict(test_important) errors = abs(predictions - test_labels) # Display the performance metrics print('Mean Absolute Error:', round(np.mean(errors), 2), 'degrees.') mape = np.mean(100 * (errors / test_labels)) accuracy = 100 - mape print('Accuracy:', round(accuracy, 2), '%.') Mean Absolute Error: 3.9 degrees. Accuracy: 93.8 %.這告訴我們,實際上我們不需要收集到的所有數據來進行準確的預測!如果要繼續使用此模型,我們只能收集兩個變量并獲得幾乎相同的性能。在生產環境中,我們需要權衡準確性下降與獲取更多信息所需的額外時間。知道如何在性能和成本之間找到合適的平衡是機器學習工程師的一項基本技能,并且最終將取決于問題!
至此,我們已經涵蓋了關于監督回歸問題的隨機森林的基本實現的幾乎所有知識。我們可以放心,我們的模型可以根據一年的歷史數據以94%的準確度預測明天的最高溫度。從這里開始,可以隨意使用該示例,或者在您選擇的數據集上使用該模型。我將通過一些可視化來結束這篇文章。數據科學中我最喜歡的兩個部分是圖形繪制和建模,因此我自然必須繪制一些圖表!圖表除了令人賞心悅目之外,還可以幫助我們診斷模型,因為它們將大量數字壓縮成可以快速檢查的圖像。
可視化
我將制作的第一個圖表是功能重要性的簡單條形圖,以說明變量相對重要性的差異。使用Python進行繪圖是一種非直覺的工作,當我制作圖形時,我最終要在Stack Overflow上查找幾乎所有內容。不用擔心這里的代碼不太有意義,有時不必完全了解代碼即可獲得所需的最終結果!
接下來,我們可以繪制突出顯示預測的整個數據集。這需要一點數據操作,但是并不太困難。我們可以使用該圖來確定數據或我們的預測中是否存在異常值。
# Use datetime for creating date objects for plotting import datetime # Dates of training values months = features[:, feature_list.index('month')] days = features[:, feature_list.index('day')] years = features[:, feature_list.index('year')] # List and then convert to datetime object dates = [str(int(year)) + '-' + str(int(month)) + '-' + str(int(day)) for year, month, day in zip(years, months, days)] dates = [datetime.datetime.strptime(date, '%Y-%m-%d') for date in dates] # Dataframe with true values and dates true_data = pd.DataFrame(data = {'date': dates, 'actual': labels}) # Dates of predictions months = test_features[:, feature_list.index('month')] days = test_features[:, feature_list.index('day')] years = test_features[:, feature_list.index('year')] # Column of dates test_dates = [str(int(year)) + '-' + str(int(month)) + '-' + str(int(day)) for year, month, day in zip(years, months, days)] # Convert to datetime objects test_dates = [datetime.datetime.strptime(date, '%Y-%m-%d') for date in test_dates] # Dataframe with predictions and dates predictions_data = pd.DataFrame(data = {'date': test_dates, 'prediction': predictions}) # Plot the actual values plt.plot(true_data['date'], true_data['actual'], 'b-', label = 'actual') # Plot the predicted values plt.plot(predictions_data['date'], predictions_data['prediction'], 'ro', label = 'prediction') plt.xticks(rotation = '60'); plt.legend() # Graph labels plt.xlabel('Date'); plt.ylabel('Maximum Temperature (F)'); plt.title('Actual and Predicted Values'); 1做一點點漂亮的圖形工作!看起來我們似乎沒有任何需要糾正的異常值。為了進一步診斷模型,我們可以繪制殘差(誤差)以查看我們的模型是否傾向于過度預測或預測不足,還可以查看殘差是否為正態分布。但是,我將制作一張最終圖表,顯示實際值,前一天的溫度,歷史平均值以及我們朋友的預測。這將使我們看到有用變量和不是那么有用的變量之間的區別
# Make the data accessible for plotting true_data['temp_1'] = features[:, feature_list.index('temp_1')] true_data['average'] = features[:, feature_list.index('average')] true_data['friend'] = features[:, feature_list.index('friend')] # Plot all the data as lines plt.plot(true_data['date'], true_data['actual'], 'b-', label = 'actual', alpha = 1.0) plt.plot(true_data['date'], true_data['temp_1'], 'y-', label = 'temp_1', alpha = 1.0) plt.plot(true_data['date'], true_data['average'], 'k-', label = 'average', alpha = 0.8) plt.plot(true_data['date'], true_data['friend'], 'r-', label = 'friend', alpha = 0.3) # Formatting plot plt.legend(); plt.xticks(rotation = '60'); # Lables and title plt.xlabel('Date'); plt.ylabel('Maximum Temperature (F)'); plt.title('Actual Max Temp and Variables') 1找出所有界線有點困難,但是我們可以看到為什么前一天的最高溫度和歷史最高溫度對預測最高溫度有用,而我們的朋友卻沒有(不要放棄,但也許也不要對他們的估算值施加太大的壓力!)。這樣的圖形通常有助于提前制作,因此我們可以選擇要包含的變量,但是它們也可以用于診斷。就像在Anscombe的四重奏中一樣,圖形通常比定量數字更具啟發性,并且應該成為任何機器學習工作流程的一部分。
結論
借助這些圖形,我們完成了一個完整的端到端機器學習示例!在這一點上,如果要改進模型,可以嘗試使用不同的超參數(設置)嘗試使用不同的算法,或者最好的方法是收集更多數據!任何模型的性能都與可以從中學習的有效數據量成正比,而我們使用的信息量非常有限。我鼓勵任何人嘗試并改進此模型并分享結果。在這里,您可以使用大量的在線(免費)資源來深入研究隨機森林理論和應用。對于那些希望一本書涵蓋機器學習模型的理論和Python實現的人,我強烈建議使用Scikit-Learn和Tensorflow進行動手機器學習。此外,我希望所有通過學習的人都可以看到機器學習的普及程度.
總結
以上是生活随笔為你收集整理的随机森林 python_如何轻松使用python的随机森林的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 北京联通机顶盒-中兴B860A破解
- 下一篇: AWS之VPC、Subnet与CIDR