# 如何在Python中從頭開始實現決策樹算法
> 原文: [https://machinelearningmastery.com/implement-decision-tree-algorithm-scratch-python/](https://machinelearningmastery.com/implement-decision-tree-algorithm-scratch-python/)
決策樹是一種強大的預測方法,非常受歡迎。
它們很受歡迎,因為最終模型很容易被從業者和領域專家所理解。最終決策樹可以準確解釋為什么進行特定預測,使其對操作使用非常有吸引力。
決策樹還為更先進的集合方法提供了基礎,例如裝袋,隨機森林和梯度增強。
在本教程中,您將了解如何使用Python從頭開始實現[分類和回歸樹算法](http://machinelearningmastery.com/classification-and-regression-trees-for-machine-learning/)。
完成本教程后,您將了解:
* 如何計算和評估數據中的候選分裂點。
* 如何安排拆分為決策樹結構。
* 如何將分類和回歸樹算法應用于實際問題。
讓我們開始吧。
* **2017年1月更新**:將cross_validation_split()中的fold_size計算更改為始終為整數。修復了Python 3的問題。
* **2017年2月更新**:修復了build_tree中的錯誤。
* **2017年8月更新**:修正了基尼計算中的一個錯誤,根據組大小添加了組基尼評分缺失的權重(感謝邁克爾!)。
* **更新Aug / 2018** :經過測試和更新,可與Python 3.6配合使用。

如何在Python中從頭開始實施決策樹算法
[Martin Cathrae](https://www.flickr.com/photos/suckamc/4325870801/) 的照片,保留一些權利。
## 說明
本節簡要介紹了本教程中使用的分類和回歸樹算法以及Banknote數據集。
### 分類和回歸樹
分類和回歸樹或簡稱CART是Leo Breiman引用的首字母縮略詞,用于指代可用于分類或回歸預測建模問題的決策樹算法。
我們將在本教程中專注于使用CART進行分類。
CART模型的表示是二叉樹。這是來自算法和數據結構的相同二叉樹,沒什么太花哨的(每個節點可以有零個,一個或兩個子節點)。
假設變量是數字,節點表示單個輸入變量(X)和該變量上的分割點。樹的葉節點(也稱為終端節點)包含用于進行預測的輸出變量(y)。
一旦創建,就可以使用拆分在每個分支之后使用新的數據行來導航樹,直到進行最終預測。
創建二元決策樹實際上是劃分輸入空間的過程。貪婪的方法用于劃分稱為遞歸二進制分裂的空間。這是一個數值程序,其中所有值都排成一行,并使用成本函數嘗試和測試不同的分裂點。
選擇具有最佳成本(最低成本,因為我們最小化成本)的分割。基于成本函數,以貪婪的方式評估和選擇所有輸入變量和所有可能的分裂點。
* **回歸**:為選擇分割點而最小化的成本函數是落在矩形內的所有訓練樣本的總和平方誤差。
* **分類**:使用基尼成本函數,其表示節點的純度,其中節點純度是指分配給每個節點的訓練數據的混合程度。
拆分繼續,直到節點包含最少數量的訓練示例或達到最大樹深度。
### 鈔票數據集
鈔票數據集涉及根據從照片中采取的若干措施來預測給定鈔票是否是真實的。
數據集包含1,372行,包含5個數字變量。這是兩個類的分類問題(二元分類)。
下面提供了數據集中五個變量的列表。
1. 小波變換圖像的方差(連續)。
2. 小波變換圖像的偏度(連續)。
3. 小波峰度變換圖像(連續)。
4. 圖像熵(連續)。
5. class(整數)。
下面是數據集的前5行的示例
```py
3.6216,8.6661,-2.8073,-0.44699,0
4.5459,8.1674,-2.4586,-1.4621,0
3.866,-2.6383,1.9242,0.10645,0
3.4566,9.5228,-4.0112,-3.5944,0
0.32924,-4.4552,4.5718,-0.9888,0
4.3684,9.6718,-3.9606,-3.1625,0
```
使用零規則算法預測最常見的類值,問題的基線準確率約為50%。
您可以從 [UCI機器學習庫](http://archive.ics.uci.edu/ml/datasets/banknote+authentication)了解更多信息并下載數據集。
下載數據集并將其放在當前工作目錄中,文件名為 **data_banknote_authentication.csv** 。
## 教程
本教程分為5個部分:
1. 基尼指數。
2. 創建拆分。
3. 建樹。
4. 做一個預測。
5. 鈔票案例研究。
這些步驟將為您提供從頭開始實施CART算法所需的基礎,并將其應用于您自己的預測建模問題。
### 基尼系數
Gini索引是用于評估數據集中拆分的成本函數的名稱。
數據集中的拆分涉及一個輸入屬性和該屬性的一個值。它可用于將訓練模式劃分為兩組行。
基尼分數通過分割創建的兩個組中的類的混合程度,可以了解分割的好壞程度。完美分離導致基尼評分為0,而最差情況分裂導致每組50/50分類導致基尼評分為0.5(對于2類問題)。
通過示例可以最好地演示計算基尼系數。
我們有兩組數據,每組有2行。第一組中的行都屬于類0,第二組中的行屬于類1,因此它是完美的分割。
我們首先需要計算每組中班級的比例。
```py
proportion = count(class_value) / count(rows)
```
這個例子的比例是:
```py
group_1_class_0 = 2 / 2 = 1
group_1_class_1 = 0 / 2 = 0
group_2_class_0 = 0 / 2 = 0
group_2_class_1 = 2 / 2 = 1
```
然后為每個子節點計算Gini,如下所示:
```py
gini_index = sum(proportion * (1.0 - proportion))
gini_index = 1.0 - sum(proportion * proportion)
```
然后,必須根據組的大小,相對于父組中的所有樣本,對每組的基尼系數進行加權。當前正在分組的所有樣本。我們可以將此權重添加到組的Gini計算中,如下所示:
```py
gini_index = (1.0 - sum(proportion * proportion)) * (group_size/total_samples)
```
在此示例中,每組的基尼評分計算如下:
```py
Gini(group_1) = (1 - (1*1 + 0*0)) * 2/4
Gini(group_1) = 0.0 * 0.5
Gini(group_1) = 0.0
Gini(group_2) = (1 - (0*0 + 1*1)) * 2/4
Gini(group_2) = 0.0 * 0.5
Gini(group_2) = 0.0
```
然后在分割點處的每個子節點上添加分數,以給出可以與其他候選分割點進行比較的分割點的最終基尼分數。
然后,此分裂點的基尼計算為0.0 + 0.0或完美基尼得分為0.0。
下面是一個名為 **gini_index()**的函數,它計算組列表的Gini索引和已知類值的列表。
你可以看到那里有一些安全檢查,以避免空組的除以零。
```py
# Calculate the Gini index for a split dataset
def gini_index(groups, classes):
# count all samples at split point
n_instances = float(sum([len(group) for group in groups]))
# sum weighted Gini index for each group
gini = 0.0
for group in groups:
size = float(len(group))
# avoid divide by zero
if size == 0:
continue
score = 0.0
# score the group based on the score for each class
for class_val in classes:
p = [row[-1] for row in group].count(class_val) / size
score += p * p
# weight the group score by its relative size
gini += (1.0 - score) * (size / n_instances)
return gini
```
我們可以使用上面的工作示例測試此函數。我們還可以測試每組中50/50分裂的最壞情況。下面列出了完整的示例。
```py
# Calculate the Gini index for a split dataset
def gini_index(groups, classes):
# count all samples at split point
n_instances = float(sum([len(group) for group in groups]))
# sum weighted Gini index for each group
gini = 0.0
for group in groups:
size = float(len(group))
# avoid divide by zero
if size == 0:
continue
score = 0.0
# score the group based on the score for each class
for class_val in classes:
p = [row[-1] for row in group].count(class_val) / size
score += p * p
# weight the group score by its relative size
gini += (1.0 - score) * (size / n_instances)
return gini
# test Gini values
print(gini_index([[[1, 1], [1, 0]], [[1, 1], [1, 0]]], [0, 1]))
print(gini_index([[[1, 0], [1, 0]], [[1, 1], [1, 1]]], [0, 1]))
```
運行該示例打印兩個Gini分數,首先是最差情況的分數為0.5,然后是最佳情況的分數為0.0。
```py
0.5
0.0
```
現在我們知道如何評估拆分的結果,讓我們看一下創建拆分。
### 2.創建拆分
拆分由數據集中的屬性和值組成。
我們可以將其概括為要拆分的屬性的索引以及在該屬性上拆分行的值。這只是索引數據行的有用簡寫。
創建拆分涉及三個部分,第一部分我們已經看過計算基尼評分。剩下的兩部分是:
1. 拆分數據集。
2. 評估所有拆分。
我們來看看每一個。
#### 2.1。拆分數據集
拆分數據集意味著在給定屬性索引和該屬性的拆分值的情況下將數據集分成兩個行列表。
一旦我們擁有這兩個組,我們就可以使用上面的Gini評分來評估拆分的成本。
拆分數據集涉及迭代每一行,檢查屬性值是低于還是高于拆分值,并分別將其分配給左側或右側組。
下面是一個名為 **test_split()**的函數,它實現了這個過程。
```py
# Split a dataset based on an attribute and an attribute value
def test_split(index, value, dataset):
left, right = list(), list()
for row in dataset:
if row[index] < value:
left.append(row)
else:
right.append(row)
return left, right
```
不是很多。
請注意,右側組包含索引值大于或等于拆分值的所有行。
#### 2.2。評估所有拆分
通過上面的Gini函數和測試分割函數,我們現在擁有評估分割所需的一切。
給定一個數據集,我們必須檢查每個屬性的每個值作為候選分割,評估分割的成本并找到我們可以做出的最佳分割。
找到最佳拆分后,我們可以將其用作決策樹中的節點。
這是一個詳盡而貪婪的算法。
我們將使用字典來表示決策樹中的節點,因為我們可以按名稱存儲數據。當選擇最佳分割并將其用作樹的新節點時,我們將存儲所選屬性的索引,要分割的屬性的值以及由所選分割點分割的兩組數據。
每組數據都是其自己的小數據集,只有那些通過拆分過程分配給左或右組的行。您可以想象我們如何在構建決策樹時遞歸地再次拆分每個組。
下面是一個名為 **get_split()**的函數,它實現了這個過程。您可以看到它迭代每個屬性(類值除外),然后遍歷該屬性的每個值,分割和評估拆分。
記錄最佳分割,然后在所有檢查完成后返回。
```py
# Select the best split point for a dataset
def get_split(dataset):
class_values = list(set(row[-1] for row in dataset))
b_index, b_value, b_score, b_groups = 999, 999, 999, None
for index in range(len(dataset[0])-1):
for row in dataset:
groups = test_split(index, row[index], dataset)
gini = gini_index(groups, class_values)
if gini < b_score:
b_index, b_value, b_score, b_groups = index, row[index], gini, groups
return {'index':b_index, 'value':b_value, 'groups':b_groups}
```
我們可以設計一個小數據集來測試這個函數和我們的整個數據集拆分過程。
```py
X1 X2 Y
2.771244718 1.784783929 0
1.728571309 1.169761413 0
3.678319846 2.81281357 0
3.961043357 2.61995032 0
2.999208922 2.209014212 0
7.497545867 3.162953546 1
9.00220326 3.339047188 1
7.444542326 0.476683375 1
10.12493903 3.234550982 1
6.642287351 3.319983761 1
```
我們可以為每個類使用單獨的顏色繪制此數據集。您可以看到,手動選擇X1的值(圖中的x軸)來分割此數據集并不困難。

CART Contrived Dataset
下面的例子將所有這些放在一起。
```py
# Split a dataset based on an attribute and an attribute value
def test_split(index, value, dataset):
left, right = list(), list()
for row in dataset:
if row[index] < value:
left.append(row)
else:
right.append(row)
return left, right
# Calculate the Gini index for a split dataset
def gini_index(groups, classes):
# count all samples at split point
n_instances = float(sum([len(group) for group in groups]))
# sum weighted Gini index for each group
gini = 0.0
for group in groups:
size = float(len(group))
# avoid divide by zero
if size == 0:
continue
score = 0.0
# score the group based on the score for each class
for class_val in classes:
p = [row[-1] for row in group].count(class_val) / size
score += p * p
# weight the group score by its relative size
gini += (1.0 - score) * (size / n_instances)
return gini
# Select the best split point for a dataset
def get_split(dataset):
class_values = list(set(row[-1] for row in dataset))
b_index, b_value, b_score, b_groups = 999, 999, 999, None
for index in range(len(dataset[0])-1):
for row in dataset:
groups = test_split(index, row[index], dataset)
gini = gini_index(groups, class_values)
print('X%d < %.3f Gini=%.3f' % ((index+1), row[index], gini))
if gini < b_score:
b_index, b_value, b_score, b_groups = index, row[index], gini, groups
return {'index':b_index, 'value':b_value, 'groups':b_groups}
dataset = [[2.771244718,1.784783929,0],
[1.728571309,1.169761413,0],
[3.678319846,2.81281357,0],
[3.961043357,2.61995032,0],
[2.999208922,2.209014212,0],
[7.497545867,3.162953546,1],
[9.00220326,3.339047188,1],
[7.444542326,0.476683375,1],
[10.12493903,3.234550982,1],
[6.642287351,3.319983761,1]]
split = get_split(dataset)
print('Split: [X%d < %.3f]' % ((split['index']+1), split['value']))
```
**get_split()**功能被修改為打印出每個分割點,并且在評估時它是基尼指數。
運行該示例打印所有Gini分數,然后在X1的數據集中打印最佳分割的分數&lt; 6.642,基尼指數為0.0或完美分裂。
```py
X1 < 2.771 Gini=0.444
X1 < 1.729 Gini=0.500
X1 < 3.678 Gini=0.286
X1 < 3.961 Gini=0.167
X1 < 2.999 Gini=0.375
X1 < 7.498 Gini=0.286
X1 < 9.002 Gini=0.375
X1 < 7.445 Gini=0.167
X1 < 10.125 Gini=0.444
X1 < 6.642 Gini=0.000
X2 < 1.785 Gini=0.500
X2 < 1.170 Gini=0.444
X2 < 2.813 Gini=0.320
X2 < 2.620 Gini=0.417
X2 < 2.209 Gini=0.476
X2 < 3.163 Gini=0.167
X2 < 3.339 Gini=0.444
X2 < 0.477 Gini=0.500
X2 < 3.235 Gini=0.286
X2 < 3.320 Gini=0.375
Split: [X1 < 6.642]
```
現在我們知道如何在數據集或行列表中找到最佳分割點,讓我們看看如何使用它來構建決策樹。
### 3.建造一棵樹
創建樹的根節點很簡單。
我們使用整個數據集調用上面的 **get_split()**函數。
向樹中添加更多節點更有趣。
構建樹可以分為3個主要部分:
1. 終端節點。
2. 遞歸拆分。
3. 建造一棵樹。
#### 3.1。終端節點
我們需要決定何時停止種樹。
我們可以使用節點在訓練數據集中負責的行數和行數來實現。
* **最大樹深**。這是樹的根節點的最大節點數。一旦滿足樹的最大深度,我們必須停止拆分添加新節點。更深的樹木更復雜,更有可能過度擬合訓練數據。
* **最小節點記錄**。這是給定節點負責的最小訓練模式數。一旦達到或低于此最小值,我們必須停止拆分和添加新節點。預計訓練模式太少的節點過于具體,可能會過度訓練訓練數據。
這兩種方法將是用戶指定的樹構建過程參數。
還有一個條件。可以選擇所有行屬于一個組的拆分。在這種情況下,我們將無法繼續拆分和添加子節點,因為我們將無法在一側或另一側拆分記錄。
現在我們有一些關于何時停止種植樹木的想法。當我們在給定點停止增長時,該節點被稱為終端節點并用于進行最終預測。
這是通過獲取分配給該節點的行組并選擇組中最常見的類值來完成的。這將用于進行預測。
下面是一個名為 **to_terminal()**的函數,它將為一組行選擇一個類值。它返回行列表中最常見的輸出值。
```py
# Create a terminal node value
def to_terminal(group):
outcomes = [row[-1] for row in group]
return max(set(outcomes), key=outcomes.count)
```
#### 3.2。遞歸拆分
我們知道如何以及何時創建終端節點,現在我們可以構建我們的樹。
構建決策樹涉及在為每個節點創建的組上反復調用上面開發的 **get_split()**函數。
添加到現有節點的新節點稱為子節點。節點可以具有零個子節點(終端節點),一個子節點(一側直接進行預測)或兩個子節點。我們將在給定節點的字典表示中將子節點稱為左和右。
創建節點后,我們可以通過再次調用相同的函數,對拆分中的每組數據遞歸創建子節點。
下面是一個實現此遞歸過程的函數。它將節點作為參數以及節點中的最大深度,最小模式數和節點的當前深度。
您可以想象這可能首先如何在根節點中傳遞,并且深度為1.此函數最好用以下步驟解釋:
1. 首先,提取節點分割的兩組數據以供使用并從節點中刪除。當我們處理這些組時,節點不再需要訪問這些數據。
2. 接下來,我們檢查左側或右側行組是否為空,如果是,我們使用我們擁有的記錄創建終端節點。
3. 然后我們檢查是否已達到最大深度,如果是,我們創建一個終端節點。
4. 然后我們處理左子節點,如果行組太小則創建終端節點,否則以深度優先方式創建和添加左節點,直到在該分支上到達樹的底部。
5. 然后以相同的方式處理右側,因為我們將構造的樹恢復到根。
```py
# Create child splits for a node or make terminal
def split(node, max_depth, min_size, depth):
left, right = node['groups']
del(node['groups'])
# check for a no split
if not left or not right:
node['left'] = node['right'] = to_terminal(left + right)
return
# check for max depth
if depth >= max_depth:
node['left'], node['right'] = to_terminal(left), to_terminal(right)
return
# process left child
if len(left) <= min_size:
node['left'] = to_terminal(left)
else:
node['left'] = get_split(left)
split(node['left'], max_depth, min_size, depth+1)
# process right child
if len(right) <= min_size:
node['right'] = to_terminal(right)
else:
node['right'] = get_split(right)
split(node['right'], max_depth, min_size, depth+1)
```
#### 3.3。建造一棵樹
我們現在可以將所有部分組合在一起。
構建樹包括創建根節點并調用 **split()**函數,然后遞歸調用自身以構建整個樹。
下面是實現此過程的小 **build_tree()**函數。
```py
# Build a decision tree
def build_tree(train, max_depth, min_size):
root = get_split(train)
split(root, max_depth, min_size, 1)
return root
```
我們可以使用上面設計的小數據集測試整個過程。
以下是完整的示例。
還包括一個小的 **print_tree()**函數,它遞歸地打印出決策樹的節點,每個節點一行。雖然沒有真正的決策樹圖那么引人注目,但它給出了樹結構和決策的概念。
```py
# Split a dataset based on an attribute and an attribute value
def test_split(index, value, dataset):
left, right = list(), list()
for row in dataset:
if row[index] < value:
left.append(row)
else:
right.append(row)
return left, right
# Calculate the Gini index for a split dataset
def gini_index(groups, classes):
# count all samples at split point
n_instances = float(sum([len(group) for group in groups]))
# sum weighted Gini index for each group
gini = 0.0
for group in groups:
size = float(len(group))
# avoid divide by zero
if size == 0:
continue
score = 0.0
# score the group based on the score for each class
for class_val in classes:
p = [row[-1] for row in group].count(class_val) / size
score += p * p
# weight the group score by its relative size
gini += (1.0 - score) * (size / n_instances)
return gini
# Select the best split point for a dataset
def get_split(dataset):
class_values = list(set(row[-1] for row in dataset))
b_index, b_value, b_score, b_groups = 999, 999, 999, None
for index in range(len(dataset[0])-1):
for row in dataset:
groups = test_split(index, row[index], dataset)
gini = gini_index(groups, class_values)
if gini < b_score:
b_index, b_value, b_score, b_groups = index, row[index], gini, groups
return {'index':b_index, 'value':b_value, 'groups':b_groups}
# Create a terminal node value
def to_terminal(group):
outcomes = [row[-1] for row in group]
return max(set(outcomes), key=outcomes.count)
# Create child splits for a node or make terminal
def split(node, max_depth, min_size, depth):
left, right = node['groups']
del(node['groups'])
# check for a no split
if not left or not right:
node['left'] = node['right'] = to_terminal(left + right)
return
# check for max depth
if depth >= max_depth:
node['left'], node['right'] = to_terminal(left), to_terminal(right)
return
# process left child
if len(left) <= min_size:
node['left'] = to_terminal(left)
else:
node['left'] = get_split(left)
split(node['left'], max_depth, min_size, depth+1)
# process right child
if len(right) <= min_size:
node['right'] = to_terminal(right)
else:
node['right'] = get_split(right)
split(node['right'], max_depth, min_size, depth+1)
# Build a decision tree
def build_tree(train, max_depth, min_size):
root = get_split(train)
split(root, max_depth, min_size, 1)
return root
# Print a decision tree
def print_tree(node, depth=0):
if isinstance(node, dict):
print('%s[X%d < %.3f]' % ((depth*' ', (node['index']+1), node['value'])))
print_tree(node['left'], depth+1)
print_tree(node['right'], depth+1)
else:
print('%s[%s]' % ((depth*' ', node)))
dataset = [[2.771244718,1.784783929,0],
[1.728571309,1.169761413,0],
[3.678319846,2.81281357,0],
[3.961043357,2.61995032,0],
[2.999208922,2.209014212,0],
[7.497545867,3.162953546,1],
[9.00220326,3.339047188,1],
[7.444542326,0.476683375,1],
[10.12493903,3.234550982,1],
[6.642287351,3.319983761,1]]
tree = build_tree(dataset, 1, 1)
print_tree(tree)
```
我們可以在運行此示例時更改最大深度參數,并查看對打印樹的影響。
最大深度為1(調用 **build_tree()**函數時的第二個參數),我們可以看到樹使用了我們在上一節中發現的完美分割。這是一個具有一個節點的樹,也稱為決策樹樁。
```py
[X1 < 6.642]
[0]
[1]
```
將最大深度增加到2,即使不需要,我們也會強制樹進行拆分。然后,根節點的左右子節點再次使用 **X1** 屬性來拆分已經完美的類混合。
```py
[X1 < 6.642]
[X1 < 2.771]
[0]
[0]
[X1 < 7.498]
[1]
[1]
```
最后,反過來說,我們可以強制一個更高級別的分裂,最大深度為3。
```py
[X1 < 6.642]
[X1 < 2.771]
[0]
[X1 < 2.771]
[0]
[0]
[X1 < 7.498]
[X1 < 7.445]
[1]
[1]
[X1 < 7.498]
[1]
[1]
```
這些測試表明,很有可能優化實現以避免不必要的拆分。這是一個擴展。
現在我們可以創建一個決策樹,讓我們看看如何使用它來對新數據進行預測。
### 4.進行預測
使用決策樹進行預測涉及使用專門提供的數據行導航樹。
同樣,我們可以使用遞歸函數實現此功能,其中使用左子節點或右子節點再次調用相同的預測例程,具體取決于拆分如何影響提供的數據。
我們必須檢查子節點是否是要作為預測返回的終端值,或者它是否是包含要考慮的另一級樹的字典節點。
下面是實現此過程的 **predict()**函數。您可以看到給定節點中的索引和值
您可以看到給定節點中的索引和值如何用于評估提供的數據行是否位于拆分的左側或右側。
```py
# Make a prediction with a decision tree
def predict(node, row):
if row[node['index']] < node['value']:
if isinstance(node['left'], dict):
return predict(node['left'], row)
else:
return node['left']
else:
if isinstance(node['right'], dict):
return predict(node['right'], row)
else:
return node['right']
```
我們可以使用我們設計的數據集來測試這個功能。下面是一個使用硬編碼決策樹的示例,該決策樹具有最佳分割數據的單個節點(決策樹樁)。
該示例對數據集中的每一行進行預測。
```py
# Make a prediction with a decision tree
def predict(node, row):
if row[node['index']] < node['value']:
if isinstance(node['left'], dict):
return predict(node['left'], row)
else:
return node['left']
else:
if isinstance(node['right'], dict):
return predict(node['right'], row)
else:
return node['right']
dataset = [[2.771244718,1.784783929,0],
[1.728571309,1.169761413,0],
[3.678319846,2.81281357,0],
[3.961043357,2.61995032,0],
[2.999208922,2.209014212,0],
[7.497545867,3.162953546,1],
[9.00220326,3.339047188,1],
[7.444542326,0.476683375,1],
[10.12493903,3.234550982,1],
[6.642287351,3.319983761,1]]
# predict with a stump
stump = {'index': 0, 'right': 1, 'value': 6.642287351, 'left': 0}
for row in dataset:
prediction = predict(stump, row)
print('Expected=%d, Got=%d' % (row[-1], prediction))
```
運行該示例將按預期為每行打印正確的預測。
```py
Expected=0, Got=0
Expected=0, Got=0
Expected=0, Got=0
Expected=0, Got=0
Expected=0, Got=0
Expected=1, Got=1
Expected=1, Got=1
Expected=1, Got=1
Expected=1, Got=1
Expected=1, Got=1
```
我們現在知道如何創建決策樹并使用它來進行預測。現在,讓我們將它應用于真實的數據集。
### 5.鈔票案例研究
本節將CART算法應用于Bank Note數據集。
第一步是加載數據集并將加載的數據轉換為可用于計算分割點的數字。為此,我們將使用輔助函數 **load_csv()**來加載文件,使用 **str_column_to_float()**將字符串數轉換為浮點數。
我們將使用5倍折疊交叉驗證來評估算法。這意味著每個折疊中將使用1372/5 = 274.4或僅超過270個記錄。我們將使用輔助函數 **evaluate_algorithm()**來評估具有交叉驗證的算法和 **accuracy_metric()**來計算預測的準確性。
開發了一個名為 **decision_tree()**的新函數來管理CART算法的應用,首先從訓練數據集創建樹,然后使用樹對測試數據集進行預測。
下面列出了完整的示例。
```py
# CART on the Bank Note dataset
from random import seed
from random import randrange
from csv import reader
# Load a CSV file
def load_csv(filename):
file = open(filename, "rb")
lines = reader(file)
dataset = list(lines)
return dataset
# Convert string column to float
def str_column_to_float(dataset, column):
for row in dataset:
row[column] = float(row[column].strip())
# Split a dataset into k folds
def cross_validation_split(dataset, n_folds):
dataset_split = list()
dataset_copy = list(dataset)
fold_size = int(len(dataset) / n_folds)
for i in range(n_folds):
fold = list()
while len(fold) < fold_size:
index = randrange(len(dataset_copy))
fold.append(dataset_copy.pop(index))
dataset_split.append(fold)
return dataset_split
# Calculate accuracy percentage
def accuracy_metric(actual, predicted):
correct = 0
for i in range(len(actual)):
if actual[i] == predicted[i]:
correct += 1
return correct / float(len(actual)) * 100.0
# Evaluate an algorithm using a cross validation split
def evaluate_algorithm(dataset, algorithm, n_folds, *args):
folds = cross_validation_split(dataset, n_folds)
scores = list()
for fold in folds:
train_set = list(folds)
train_set.remove(fold)
train_set = sum(train_set, [])
test_set = list()
for row in fold:
row_copy = list(row)
test_set.append(row_copy)
row_copy[-1] = None
predicted = algorithm(train_set, test_set, *args)
actual = [row[-1] for row in fold]
accuracy = accuracy_metric(actual, predicted)
scores.append(accuracy)
return scores
# Split a dataset based on an attribute and an attribute value
def test_split(index, value, dataset):
left, right = list(), list()
for row in dataset:
if row[index] < value:
left.append(row)
else:
right.append(row)
return left, right
# Calculate the Gini index for a split dataset
def gini_index(groups, classes):
# count all samples at split point
n_instances = float(sum([len(group) for group in groups]))
# sum weighted Gini index for each group
gini = 0.0
for group in groups:
size = float(len(group))
# avoid divide by zero
if size == 0:
continue
score = 0.0
# score the group based on the score for each class
for class_val in classes:
p = [row[-1] for row in group].count(class_val) / size
score += p * p
# weight the group score by its relative size
gini += (1.0 - score) * (size / n_instances)
return gini
# Select the best split point for a dataset
def get_split(dataset):
class_values = list(set(row[-1] for row in dataset))
b_index, b_value, b_score, b_groups = 999, 999, 999, None
for index in range(len(dataset[0])-1):
for row in dataset:
groups = test_split(index, row[index], dataset)
gini = gini_index(groups, class_values)
if gini < b_score:
b_index, b_value, b_score, b_groups = index, row[index], gini, groups
return {'index':b_index, 'value':b_value, 'groups':b_groups}
# Create a terminal node value
def to_terminal(group):
outcomes = [row[-1] for row in group]
return max(set(outcomes), key=outcomes.count)
# Create child splits for a node or make terminal
def split(node, max_depth, min_size, depth):
left, right = node['groups']
del(node['groups'])
# check for a no split
if not left or not right:
node['left'] = node['right'] = to_terminal(left + right)
return
# check for max depth
if depth >= max_depth:
node['left'], node['right'] = to_terminal(left), to_terminal(right)
return
# process left child
if len(left) <= min_size:
node['left'] = to_terminal(left)
else:
node['left'] = get_split(left)
split(node['left'], max_depth, min_size, depth+1)
# process right child
if len(right) <= min_size:
node['right'] = to_terminal(right)
else:
node['right'] = get_split(right)
split(node['right'], max_depth, min_size, depth+1)
# Build a decision tree
def build_tree(train, max_depth, min_size):
root = get_split(train)
split(root, max_depth, min_size, 1)
return root
# Make a prediction with a decision tree
def predict(node, row):
if row[node['index']] < node['value']:
if isinstance(node['left'], dict):
return predict(node['left'], row)
else:
return node['left']
else:
if isinstance(node['right'], dict):
return predict(node['right'], row)
else:
return node['right']
# Classification and Regression Tree Algorithm
def decision_tree(train, test, max_depth, min_size):
tree = build_tree(train, max_depth, min_size)
predictions = list()
for row in test:
prediction = predict(tree, row)
predictions.append(prediction)
return(predictions)
# Test CART on Bank Note dataset
seed(1)
# load and prepare data
filename = 'data_banknote_authentication.csv'
dataset = load_csv(filename)
# convert string attributes to integers
for i in range(len(dataset[0])):
str_column_to_float(dataset, i)
# evaluate algorithm
n_folds = 5
max_depth = 5
min_size = 10
scores = evaluate_algorithm(dataset, decision_tree, n_folds, max_depth, min_size)
print('Scores: %s' % scores)
print('Mean Accuracy: %.3f%%' % (sum(scores)/float(len(scores))))
```
該示例使用5層的最大樹深度和每個節點的最小行數為10.這些CART參數通過一些實驗選擇,但絕不是最佳的。
運行該示例打印每個折疊的平均分類準確度以及所有折疊的平均表現。
您可以看到CART和所選配置的平均分類精度達到了約97%,這明顯優于達到50%精度的零規則算法。
```py
Scores: [96.35036496350365, 97.08029197080292, 97.44525547445255, 98.17518248175182, 97.44525547445255]
Mean Accuracy: 97.299%
```
## 擴展
本節列出了您可能希望探索的本教程的擴展。
* **算法調整**。未調整CART在Bank Note數據集中的應用。嘗試使用不同的參數值,看看是否可以獲得更好的表現。
* **交叉熵**。用于評估分裂的另一個成本函數是交叉熵(logloss)。您可以實施和試驗此替代成本函數。
* **樹修剪**。減少訓練數據集過度擬合的一項重要技術是修剪樹木。調查并實施樹修剪方法。
* **分類數據集**。該示例設計用于具有數字或序數輸入屬性的輸入數據,嘗試分類輸入數據和可能使用相等而不是排名的拆分。
* **回歸**。使用不同的成本函數和方法調整樹以進行回歸以創建終端節點。
* **更多數據集**。將算法應用于UCI機器學習庫中的更多數據集。
**你有沒有探索過這些擴展?**
在下面的評論中分享您的經驗。
## 評論
在本教程中,您了解了如何使用Python從頭開始實現決策樹算法。
具體來說,你學到了:
* 如何選擇和評估訓練數據集中的分割點。
* 如何從多個拆分中遞歸構建決策樹。
* 如何將CART算法應用于現實世界的分類預測建模問題。
**你有什么問題嗎?**
在下面的評論中提出您的問題,我會盡力回答。
- Machine Learning Mastery 應用機器學習教程
- 5競爭機器學習的好處
- 過度擬合的簡單直覺,或者為什么測試訓練數據是一個壞主意
- 特征選擇簡介
- 應用機器學習作為一個搜索問題的溫和介紹
- 為什么應用機器學習很難
- 為什么我的結果不如我想的那么好?你可能過度擬合了
- 用ROC曲線評估和比較分類器表現
- BigML評論:發現本機學習即服務平臺的聰明功能
- BigML教程:開發您的第一個決策樹并進行預測
- 構建生產機器學習基礎設施
- 分類準確性不夠:可以使用更多表現測量
- 一種預測模型的巧妙應用
- 機器學習項目中常見的陷阱
- 數據清理:將凌亂的數據轉換為整潔的數據
- 機器學習中的數據泄漏
- 數據,學習和建模
- 數據管理至關重要以及為什么需要認真對待它
- 將預測模型部署到生產中
- 參數和超參數之間有什么區別?
- 測試和驗證數據集之間有什么區別?
- 發現特征工程,如何設計特征以及如何獲得它
- 如何開始使用Kaggle
- 超越預測
- 如何在評估機器學習算法時選擇正確的測試選項
- 如何定義機器學習問題
- 如何評估機器學習算法
- 如何獲得基線結果及其重要性
- 如何充分利用機器學習數據
- 如何識別數據中的異常值
- 如何提高機器學習效果
- 如何在競爭機器學習中踢屁股
- 如何知道您的機器學習模型是否具有良好的表現
- 如何布局和管理您的機器學習項目
- 如何為機器學習準備數據
- 如何減少最終機器學習模型中的方差
- 如何使用機器學習結果
- 如何解決像數據科學家這樣的問題
- 通過數據預處理提高模型精度
- 處理機器學習的大數據文件的7種方法
- 建立機器學習系統的經驗教訓
- 如何使用機器學習清單可靠地獲得準確的預測(即使您是初學者)
- 機器學習模型運行期間要做什么
- 機器學習表現改進備忘單
- 來自世界級從業者的機器學習技巧:Phil Brierley
- 模型預測精度與機器學習中的解釋
- 競爭機器學習的模型選擇技巧
- 機器學習需要多少訓練數據?
- 如何系統地規劃和運行機器學習實驗
- 應用機器學習過程
- 默認情況下可重現的機器學習結果
- 10個實踐應用機器學習的標準數據集
- 簡單的三步法到最佳機器學習算法
- 打擊機器學習數據集中不平衡類的8種策略
- 模型表現不匹配問題(以及如何處理)
- 黑箱機器學習的誘惑陷阱
- 如何培養最終的機器學習模型
- 使用探索性數據分析了解您的問題并獲得更好的結果
- 什么是數據挖掘和KDD
- 為什么One-Hot在機器學習中編碼數據?
- 為什么你應該在你的機器學習問題上進行抽樣檢查算法
- 所以,你正在研究機器學習問題......
- Machine Learning Mastery Keras 深度學習教程
- Keras 中神經網絡模型的 5 步生命周期
- 在 Python 迷你課程中應用深度學習
- Keras 深度學習庫的二元分類教程
- 如何用 Keras 構建多層感知器神經網絡模型
- 如何在 Keras 中檢查深度學習模型
- 10 個用于 Amazon Web Services 深度學習的命令行秘籍
- 機器學習卷積神經網絡的速成課程
- 如何在 Python 中使用 Keras 進行深度學習的度量
- 深度學習書籍
- 深度學習課程
- 你所知道的深度學習是一種謊言
- 如何設置 Amazon AWS EC2 GPU 以訓練 Keras 深度學習模型(分步)
- 神經網絡中批量和迭代之間的區別是什么?
- 在 Keras 展示深度學習模型訓練歷史
- 基于 Keras 的深度學習模型中的dropout正則化
- 評估 Keras 中深度學習模型的表現
- 如何評價深度學習模型的技巧
- 小批量梯度下降的簡要介紹以及如何配置批量大小
- 在 Keras 中獲得深度學習幫助的 9 種方法
- 如何使用 Keras 在 Python 中網格搜索深度學習模型的超參數
- 用 Keras 在 Python 中使用卷積神經網絡進行手寫數字識別
- 如何用 Keras 進行預測
- 用 Keras 進行深度學習的圖像增強
- 8 個深度學習的鼓舞人心的應用
- Python 深度學習庫 Keras 簡介
- Python 深度學習庫 TensorFlow 簡介
- Python 深度學習庫 Theano 簡介
- 如何使用 Keras 函數式 API 進行深度學習
- Keras 深度學習庫的多類分類教程
- 多層感知器神經網絡速成課程
- 基于卷積神經網絡的 Keras 深度學習庫中的目標識別
- 流行的深度學習庫
- 用深度學習預測電影評論的情感
- Python 中的 Keras 深度學習庫的回歸教程
- 如何使用 Keras 獲得可重現的結果
- 如何在 Linux 服務器上運行深度學習實驗
- 保存并加載您的 Keras 深度學習模型
- 用 Keras 逐步開發 Python 中的第一個神經網絡
- 用 Keras 理解 Python 中的有狀態 LSTM 循環神經網絡
- 在 Python 中使用 Keras 深度學習模型和 Scikit-Learn
- 如何使用預訓練的 VGG 模型對照片中的物體進行分類
- 在 Python 和 Keras 中對深度學習模型使用學習率調度
- 如何在 Keras 中可視化深度學習神經網絡模型
- 什么是深度學習?
- 何時使用 MLP,CNN 和 RNN 神經網絡
- 為什么用隨機權重初始化神經網絡?
- Machine Learning Mastery 深度學習 NLP 教程
- 深度學習在自然語言處理中的 7 個應用
- 如何實現自然語言處理的波束搜索解碼器
- 深度學習文檔分類的最佳實踐
- 關于自然語言處理的熱門書籍
- 在 Python 中計算文本 BLEU 分數的溫和介紹
- 使用編碼器 - 解碼器模型的用于字幕生成的注入和合并架構
- 如何用 Python 清理機器學習的文本
- 如何配置神經機器翻譯的編碼器 - 解碼器模型
- 如何開始深度學習自然語言處理(7 天迷你課程)
- 自然語言處理的數據集
- 如何開發一種深度學習的詞袋模型來預測電影評論情感
- 深度學習字幕生成模型的溫和介紹
- 如何在 Keras 中定義神經機器翻譯的編碼器 - 解碼器序列 - 序列模型
- 如何利用小實驗在 Keras 中開發字幕生成模型
- 如何從頭開發深度學習圖片標題生成器
- 如何在 Keras 中開發基于字符的神經語言模型
- 如何開發用于情感分析的 N-gram 多通道卷積神經網絡
- 如何從零開始開發神經機器翻譯系統
- 如何在 Python 中用 Keras 開發基于單詞的神經語言模型
- 如何開發一種預測電影評論情感的詞嵌入模型
- 如何使用 Gensim 在 Python 中開發詞嵌入
- 用于文本摘要的編碼器 - 解碼器深度學習模型
- Keras 中文本摘要的編碼器 - 解碼器模型
- 用于神經機器翻譯的編碼器 - 解碼器循環神經網絡模型
- 淺談詞袋模型
- 文本摘要的溫和介紹
- 編碼器 - 解碼器循環神經網絡中的注意力如何工作
- 如何利用深度學習自動生成照片的文本描述
- 如何開發一個單詞級神經語言模型并用它來生成文本
- 淺談神經機器翻譯
- 什么是自然語言處理?
- 牛津自然語言處理深度學習課程
- 如何為機器翻譯準備法語到英語的數據集
- 如何為情感分析準備電影評論數據
- 如何為文本摘要準備新聞文章
- 如何準備照片標題數據集以訓練深度學習模型
- 如何使用 Keras 為深度學習準備文本數據
- 如何使用 scikit-learn 為機器學習準備文本數據
- 自然語言處理神經網絡模型入門
- 對自然語言處理的深度學習的承諾
- 在 Python 中用 Keras 進行 LSTM 循環神經網絡的序列分類
- 斯坦福自然語言處理深度學習課程評價
- 統計語言建模和神經語言模型的簡要介紹
- 使用 Keras 在 Python 中進行 LSTM 循環神經網絡的文本生成
- 淺談機器學習中的轉換
- 如何使用 Keras 將詞嵌入層用于深度學習
- 什么是用于文本的詞嵌入
- Machine Learning Mastery 深度學習時間序列教程
- 如何開發人類活動識別的一維卷積神經網絡模型
- 人類活動識別的深度學習模型
- 如何評估人類活動識別的機器學習算法
- 時間序列預測的多層感知器網絡探索性配置
- 比較經典和機器學習方法進行時間序列預測的結果
- 如何通過深度學習快速獲得時間序列預測的結果
- 如何利用 Python 處理序列預測問題中的缺失時間步長
- 如何建立預測大氣污染日的概率預測模型
- 如何開發一種熟練的機器學習時間序列預測模型
- 如何構建家庭用電自回歸預測模型
- 如何開發多步空氣污染時間序列預測的自回歸預測模型
- 如何制定多站點多元空氣污染時間序列預測的基線預測
- 如何開發時間序列預測的卷積神經網絡模型
- 如何開發卷積神經網絡用于多步時間序列預測
- 如何開發單變量時間序列預測的深度學習模型
- 如何開發 LSTM 模型用于家庭用電的多步時間序列預測
- 如何開發 LSTM 模型進行時間序列預測
- 如何開發多元多步空氣污染時間序列預測的機器學習模型
- 如何開發多層感知器模型進行時間序列預測
- 如何開發人類活動識別時間序列分類的 RNN 模型
- 如何開始深度學習的時間序列預測(7 天迷你課程)
- 如何網格搜索深度學習模型進行時間序列預測
- 如何對單變量時間序列預測的網格搜索樸素方法
- 如何在 Python 中搜索 SARIMA 模型超參數用于時間序列預測
- 如何在 Python 中進行時間序列預測的網格搜索三次指數平滑
- 一個標準的人類活動識別問題的溫和介紹
- 如何加載和探索家庭用電數據
- 如何加載,可視化和探索復雜的多變量多步時間序列預測數據集
- 如何從智能手機數據模擬人類活動
- 如何根據環境因素預測房間占用率
- 如何使用腦波預測人眼是開放還是閉合
- 如何在 Python 中擴展長短期內存網絡的數據
- 如何使用 TimeseriesGenerator 進行 Keras 中的時間序列預測
- 基于機器學習算法的室內運動時間序列分類
- 用于時間序列預測的狀態 LSTM 在線學習的不穩定性
- 用于罕見事件時間序列預測的 LSTM 模型體系結構
- 用于時間序列預測的 4 種通用機器學習數據變換
- Python 中長短期記憶網絡的多步時間序列預測
- 家庭用電機器學習的多步時間序列預測
- Keras 中 LSTM 的多變量時間序列預測
- 如何開發和評估樸素的家庭用電量預測方法
- 如何為長短期記憶網絡準備單變量時間序列數據
- 循環神經網絡在時間序列預測中的應用
- 如何在 Python 中使用差異變換刪除趨勢和季節性
- 如何在 LSTM 中種子狀態用于 Python 中的時間序列預測
- 使用 Python 進行時間序列預測的有狀態和無狀態 LSTM
- 長短時記憶網絡在時間序列預測中的適用性
- 時間序列預測問題的分類
- Python 中長短期記憶網絡的時間序列預測
- 基于 Keras 的 Python 中 LSTM 循環神經網絡的時間序列預測
- Keras 中深度學習的時間序列預測
- 如何用 Keras 調整 LSTM 超參數進行時間序列預測
- 如何在時間序列預測訓練期間更新 LSTM 網絡
- 如何使用 LSTM 網絡的 Dropout 進行時間序列預測
- 如何使用 LSTM 網絡中的特征進行時間序列預測
- 如何在 LSTM 網絡中使用時間序列進行時間序列預測
- 如何利用 LSTM 網絡進行權重正則化進行時間序列預測
- Machine Learning Mastery 線性代數教程
- 機器學習數學符號的基礎知識
- 用 NumPy 陣列輕松介紹廣播
- 如何從 Python 中的 Scratch 計算主成分分析(PCA)
- 用于編碼器審查的計算線性代數
- 10 機器學習中的線性代數示例
- 線性代數的溫和介紹
- 用 NumPy 輕松介紹 Python 中的 N 維數組
- 機器學習向量的溫和介紹
- 如何在 Python 中為機器學習索引,切片和重塑 NumPy 數組
- 機器學習的矩陣和矩陣算法簡介
- 溫和地介紹機器學習的特征分解,特征值和特征向量
- NumPy 對預期價值,方差和協方差的簡要介紹
- 機器學習矩陣分解的溫和介紹
- 用 NumPy 輕松介紹機器學習的張量
- 用于機器學習的線性代數中的矩陣類型簡介
- 用于機器學習的線性代數備忘單
- 線性代數的深度學習
- 用于機器學習的線性代數(7 天迷你課程)
- 機器學習的線性代數
- 機器學習矩陣運算的溫和介紹
- 線性代數評論沒有廢話指南
- 學習機器學習線性代數的主要資源
- 淺談機器學習的奇異值分解
- 如何用線性代數求解線性回歸
- 用于機器學習的稀疏矩陣的溫和介紹
- 機器學習中向量規范的溫和介紹
- 學習線性代數用于機器學習的 5 個理由
- Machine Learning Mastery LSTM 教程
- Keras中長短期記憶模型的5步生命周期
- 長短時記憶循環神經網絡的注意事項
- CNN長短期記憶網絡
- 逆向神經網絡中的深度學習速成課程
- 可變長度輸入序列的數據準備
- 如何用Keras開發用于Python序列分類的雙向LSTM
- 如何開發Keras序列到序列預測的編碼器 - 解碼器模型
- 如何診斷LSTM模型的過度擬合和欠擬合
- 如何開發一種編碼器 - 解碼器模型,注重Keras中的序列到序列預測
- 編碼器 - 解碼器長短期存儲器網絡
- 神經網絡中爆炸梯度的溫和介紹
- 對時間反向傳播的溫和介紹
- 生成長短期記憶網絡的溫和介紹
- 專家對長短期記憶網絡的簡要介紹
- 在序列預測問題上充分利用LSTM
- 編輯器 - 解碼器循環神經網絡全局注意的溫和介紹
- 如何利用長短時記憶循環神經網絡處理很長的序列
- 如何在Python中對一個熱編碼序列數據
- 如何使用編碼器 - 解碼器LSTM來回顯隨機整數序列
- 具有注意力的編碼器 - 解碼器RNN體系結構的實現模式
- 學習使用編碼器解碼器LSTM循環神經網絡添加數字
- 如何學習長短時記憶循環神經網絡回聲隨機整數
- 具有Keras的長短期記憶循環神經網絡的迷你課程
- LSTM自動編碼器的溫和介紹
- 如何用Keras中的長短期記憶模型進行預測
- 用Python中的長短期內存網絡演示內存
- 基于循環神經網絡的序列預測模型的簡要介紹
- 深度學習的循環神經網絡算法之旅
- 如何重塑Keras中長短期存儲網絡的輸入數據
- 了解Keras中LSTM的返回序列和返回狀態之間的差異
- RNN展開的溫和介紹
- 5學習LSTM循環神經網絡的簡單序列預測問題的例子
- 使用序列進行預測
- 堆疊長短期內存網絡
- 什么是教師強制循環神經網絡?
- 如何在Python中使用TimeDistributed Layer for Long Short-Term Memory Networks
- 如何準備Keras中截斷反向傳播的序列預測
- 如何在使用LSTM進行訓練和預測時使用不同的批量大小
- Machine Learning Mastery 機器學習算法教程
- 機器學習算法之旅
- 用于機器學習的裝袋和隨機森林集合算法
- 從頭開始實施機器學習算法的好處
- 更好的樸素貝葉斯:從樸素貝葉斯算法中獲取最多的12個技巧
- 機器學習的提升和AdaBoost
- 選擇機器學習算法:Microsoft Azure的經驗教訓
- 機器學習的分類和回歸樹
- 什么是機器學習中的混淆矩陣
- 如何使用Python從頭開始創建算法測試工具
- 通過創建機器學習算法的目標列表來控制
- 從頭開始停止編碼機器學習算法
- 在實現機器學習算法時,不要從開源代碼開始
- 不要使用隨機猜測作為基線分類器
- 淺談機器學習中的概念漂移
- 溫和介紹機器學習中的偏差 - 方差權衡
- 機器學習的梯度下降
- 機器學習算法如何工作(他們學習輸入到輸出的映射)
- 如何建立機器學習算法的直覺
- 如何實現機器學習算法
- 如何研究機器學習算法行為
- 如何學習機器學習算法
- 如何研究機器學習算法
- 如何研究機器學習算法
- 如何在Python中從頭開始實現反向傳播算法
- 如何用Python從頭開始實現Bagging
- 如何用Python從頭開始實現基線機器學習算法
- 如何在Python中從頭開始實現決策樹算法
- 如何用Python從頭開始實現學習向量量化
- 如何利用Python從頭開始隨機梯度下降實現線性回歸
- 如何利用Python從頭開始隨機梯度下降實現Logistic回歸
- 如何用Python從頭開始實現機器學習算法表現指標
- 如何在Python中從頭開始實現感知器算法
- 如何在Python中從零開始實現隨機森林
- 如何在Python中從頭開始實現重采樣方法
- 如何用Python從頭開始實現簡單線性回歸
- 如何用Python從頭開始實現堆棧泛化(Stacking)
- K-Nearest Neighbors for Machine Learning
- 學習機器學習的向量量化
- 機器學習的線性判別分析
- 機器學習的線性回歸
- 使用梯度下降進行機器學習的線性回歸教程
- 如何在Python中從頭開始加載機器學習數據
- 機器學習的Logistic回歸
- 機器學習的Logistic回歸教程
- 機器學習算法迷你課程
- 如何在Python中從頭開始實現樸素貝葉斯
- 樸素貝葉斯機器學習
- 樸素貝葉斯機器學習教程
- 機器學習算法的過擬合和欠擬合
- 參數化和非參數機器學習算法
- 理解任何機器學習算法的6個問題
- 在機器學習中擁抱隨機性
- 如何使用Python從頭開始擴展機器學習數據
- 機器學習的簡單線性回歸教程
- 有監督和無監督的機器學習算法
- 用于機器學習的支持向量機
- 在沒有數學背景的情況下理解機器學習算法的5種技術
- 最好的機器學習算法
- 教程從頭開始在Python中實現k-Nearest Neighbors
- 通過從零開始實現它們來理解機器學習算法(以及繞過壞代碼的策略)
- 使用隨機森林:在121個數據集上測試179個分類器
- 為什么從零開始實現機器學習算法
- Machine Learning Mastery 機器學習入門教程
- 機器學習入門的四個步驟:初學者入門與實踐的自上而下策略
- 你應該培養的 5 個機器學習領域
- 一種選擇機器學習算法的數據驅動方法
- 機器學習中的分析與數值解
- 應用機器學習是一種精英政治
- 機器學習的基本概念
- 如何成為數據科學家
- 初學者如何在機器學習中弄錯
- 機器學習的最佳編程語言
- 構建機器學習組合
- 機器學習中分類與回歸的區別
- 評估自己作為數據科學家并利用結果建立驚人的數據科學團隊
- 探索 Kaggle 大師的方法論和心態:對 Diogo Ferreira 的采訪
- 擴展機器學習工具并展示掌握
- 通過尋找地標開始機器學習
- 溫和地介紹預測建模
- 通過提供結果在機器學習中獲得夢想的工作
- 如何開始機器學習:自學藍圖
- 開始并在機器學習方面取得進展
- 應用機器學習的 Hello World
- 初學者如何使用小型項目開始機器學習并在 Kaggle 上進行競爭
- 我如何開始機器學習? (簡短版)
- 我是如何開始機器學習的
- 如何在機器學習中取得更好的成績
- 如何從在銀行工作到擔任 Target 的高級數據科學家
- 如何學習任何機器學習工具
- 使用小型目標項目深入了解機器學習工具
- 獲得付費申請機器學習
- 映射機器學習工具的景觀
- 機器學習開發環境
- 機器學習金錢
- 程序員的機器學習
- 機器學習很有意思
- 機器學習是 Kaggle 比賽
- 機器學習現在很受歡迎
- 機器學習掌握方法
- 機器學習很重要
- 機器學習 Q&amp; A:概念漂移,更好的結果和學習更快
- 缺乏自學機器學習的路線圖
- 機器學習很重要
- 快速了解任何機器學習工具(即使您是初學者)
- 機器學習工具
- 找到你的機器學習部落
- 機器學習在一年
- 通過競爭一致的大師 Kaggle
- 5 程序員在機器學習中開始犯錯誤
- 哲學畢業生到機器學習從業者(Brian Thomas 采訪)
- 機器學習入門的實用建議
- 實用機器學習問題
- 使用來自 UCI 機器學習庫的數據集練習機器學習
- 使用秘籍的任何機器學習工具快速啟動
- 程序員可以進入機器學習
- 程序員應該進入機器學習
- 項目焦點:Shashank Singh 的人臉識別
- 項目焦點:使用 Mahout 和 Konstantin Slisenko 進行堆棧交換群集
- 機器學習自學指南
- 4 個自學機器學習項目
- álvaroLemos 如何在數據科學團隊中獲得機器學習實習
- 如何思考機器學習
- 現實世界機器學習問題之旅
- 有關機器學習的有用知識
- 如果我沒有學位怎么辦?
- 如果我不是一個優秀的程序員怎么辦?
- 如果我不擅長數學怎么辦?
- 為什么機器學習算法會處理以前從未見過的數據?
- 是什么阻礙了你的機器學習目標?
- 什么是機器學習?
- 機器學習適合哪里?
- 為什么要進入機器學習?
- 研究對您來說很重要的機器學習問題
- 你這樣做是錯的。為什么機器學習不必如此困難
- Machine Learning Mastery Sklearn 教程
- Scikit-Learn 的溫和介紹:Python 機器學習庫
- 使用 Python 管道和 scikit-learn 自動化機器學習工作流程
- 如何以及何時使用帶有 scikit-learn 的校準分類模型
- 如何比較 Python 中的機器學習算法與 scikit-learn
- 用于機器學習開發人員的 Python 崩潰課程
- 用 scikit-learn 在 Python 中集成機器學習算法
- 使用重采樣評估 Python 中機器學習算法的表現
- 使用 Scikit-Learn 在 Python 中進行特征選擇
- Python 中機器學習的特征選擇
- 如何使用 scikit-learn 在 Python 中生成測試數據集
- scikit-learn 中的機器學習算法秘籍
- 如何使用 Python 處理丟失的數據
- 如何開始使用 Python 進行機器學習
- 如何使用 Scikit-Learn 在 Python 中加載數據
- Python 中概率評分方法的簡要介紹
- 如何用 Scikit-Learn 調整算法參數
- 如何在 Mac OS X 上安裝 Python 3 環境以進行機器學習和深度學習
- 使用 scikit-learn 進行機器學習簡介
- 從 shell 到一本帶有 Fernando Perez 單一工具的書的 IPython
- 如何使用 Python 3 為機器學習開發創建 Linux 虛擬機
- 如何在 Python 中加載機器學習數據
- 您在 Python 中的第一個機器學習項目循序漸進
- 如何使用 scikit-learn 進行預測
- 用于評估 Python 中機器學習算法的度量標準
- 使用 Pandas 為 Python 中的機器學習準備數據
- 如何使用 Scikit-Learn 為 Python 機器學習準備數據
- 項目焦點:使用 Artem Yankov 在 Python 中進行事件推薦
- 用于機器學習的 Python 生態系統
- Python 是應用機器學習的成長平臺
- Python 機器學習書籍
- Python 機器學習迷你課程
- 使用 Pandas 快速和骯臟的數據分析
- 使用 Scikit-Learn 重新調整 Python 中的機器學習數據
- 如何以及何時使用 ROC 曲線和精確調用曲線進行 Python 分類
- 使用 scikit-learn 在 Python 中保存和加載機器學習模型
- scikit-learn Cookbook 書評
- 如何使用 Anaconda 為機器學習和深度學習設置 Python 環境
- 使用 scikit-learn 在 Python 中進行 Spot-Check 分類機器學習算法
- 如何在 Python 中開發可重復使用的抽樣檢查算法框架
- 使用 scikit-learn 在 Python 中進行 Spot-Check 回歸機器學習算法
- 使用 Python 中的描述性統計來了解您的機器學習數據
- 使用 OpenCV,Python 和模板匹配來播放“哪里是 Waldo?”
- 使用 Pandas 在 Python 中可視化機器學習數據
- Machine Learning Mastery 統計學教程
- 淺談計算正態匯總統計量
- 非參數統計的溫和介紹
- Python中常態測試的溫和介紹
- 淺談Bootstrap方法
- 淺談機器學習的中心極限定理
- 淺談機器學習中的大數定律
- 機器學習的所有統計數據
- 如何計算Python中機器學習結果的Bootstrap置信區間
- 淺談機器學習的Chi-Squared測試
- 機器學習的置信區間
- 隨機化在機器學習中解決混雜變量的作用
- 機器學習中的受控實驗
- 機器學習統計學速成班
- 統計假設檢驗的關鍵值以及如何在Python中計算它們
- 如何在機器學習中談論數據(統計學和計算機科學術語)
- Python中數據可視化方法的簡要介紹
- Python中效果大小度量的溫和介紹
- 估計隨機機器學習算法的實驗重復次數
- 機器學習評估統計的溫和介紹
- 如何計算Python中的非參數秩相關性
- 如何在Python中計算數據的5位數摘要
- 如何在Python中從頭開始編寫學生t檢驗
- 如何在Python中生成隨機數
- 如何轉換數據以更好地擬合正態分布
- 如何使用相關來理解變量之間的關系
- 如何使用統計信息識別數據中的異常值
- 用于Python機器學習的隨機數生成器簡介
- k-fold交叉驗證的溫和介紹
- 如何計算McNemar的比較兩種機器學習量詞的測試
- Python中非參數統計顯著性測試簡介
- 如何在Python中使用參數統計顯著性測試
- 機器學習的預測間隔
- 應用統計學與機器學習的密切關系
- 如何使用置信區間報告分類器表現
- 統計數據分布的簡要介紹
- 15 Python中的統計假設檢驗(備忘單)
- 統計假設檢驗的溫和介紹
- 10如何在機器學習項目中使用統計方法的示例
- Python中統計功效和功耗分析的簡要介紹
- 統計抽樣和重新抽樣的簡要介紹
- 比較機器學習算法的統計顯著性檢驗
- 機器學習中統計容差區間的溫和介紹
- 機器學習統計書籍
- 評估機器學習模型的統計數據
- 機器學習統計(7天迷你課程)
- 用于機器學習的簡明英語統計
- 如何使用統計顯著性檢驗來解釋機器學習結果
- 什么是統計(為什么它在機器學習中很重要)?
- Machine Learning Mastery 時間序列入門教程
- 如何在 Python 中為時間序列預測創建 ARIMA 模型
- 用 Python 進行時間序列預測的自回歸模型
- 如何回溯機器學習模型的時間序列預測
- Python 中基于時間序列數據的基本特征工程
- R 的時間序列預測熱門書籍
- 10 挑戰機器學習時間序列預測問題
- 如何將時間序列轉換為 Python 中的監督學習問題
- 如何將時間序列數據分解為趨勢和季節性
- 如何用 ARCH 和 GARCH 模擬波動率進行時間序列預測
- 如何將時間序列數據集與 Python 區分開來
- Python 中時間序列預測的指數平滑的溫和介紹
- 用 Python 進行時間序列預測的特征選擇
- 淺談自相關和部分自相關
- 時間序列預測的 Box-Jenkins 方法簡介
- 用 Python 簡要介紹時間序列的時間序列預測
- 如何使用 Python 網格搜索 ARIMA 模型超參數
- 如何在 Python 中加載和探索時間序列數據
- 如何使用 Python 對 ARIMA 模型進行手動預測
- 如何用 Python 進行時間序列預測的預測
- 如何使用 Python 中的 ARIMA 進行樣本外預測
- 如何利用 Python 模擬殘差錯誤來糾正時間序列預測
- 使用 Python 進行數據準備,特征工程和時間序列預測的移動平均平滑
- 多步時間序列預測的 4 種策略
- 如何在 Python 中規范化和標準化時間序列數據
- 如何利用 Python 進行時間序列預測的基線預測
- 如何使用 Python 對時間序列預測數據進行功率變換
- 用于時間序列預測的 Python 環境
- 如何重構時間序列預測問題
- 如何使用 Python 重新采樣和插值您的時間序列數據
- 用 Python 編寫 SARIMA 時間序列預測
- 如何在 Python 中保存 ARIMA 時間序列預測模型
- 使用 Python 進行季節性持久性預測
- 基于 ARIMA 的 Python 歷史規模敏感性預測技巧分析
- 簡單的時間序列預測模型進行測試,這樣你就不會欺騙自己
- 標準多變量,多步驟和多站點時間序列預測問題
- 如何使用 Python 檢查時間序列數據是否是固定的
- 使用 Python 進行時間序列數據可視化
- 7 個機器學習的時間序列數據集
- 時間序列預測案例研究與 Python:波士頓每月武裝搶劫案
- Python 的時間序列預測案例研究:巴爾的摩的年度用水量
- 使用 Python 進行時間序列預測研究:法國香檳的月銷售額
- 使用 Python 的置信區間理解時間序列預測不確定性
- 11 Python 中的經典時間序列預測方法(備忘單)
- 使用 Python 進行時間序列預測表現測量
- 使用 Python 7 天迷你課程進行時間序列預測
- 時間序列預測作為監督學習
- 什么是時間序列預測?
- 如何使用 Python 識別和刪除時間序列數據的季節性
- 如何在 Python 中使用和刪除時間序列數據中的趨勢信息
- 如何在 Python 中調整 ARIMA 參數
- 如何用 Python 可視化時間序列殘差預測錯誤
- 白噪聲時間序列與 Python
- 如何通過時間序列預測項目
- Machine Learning Mastery XGBoost 教程
- 通過在 Python 中使用 XGBoost 提前停止來避免過度擬合
- 如何在 Python 中調優 XGBoost 的多線程支持
- 如何配置梯度提升算法
- 在 Python 中使用 XGBoost 進行梯度提升的數據準備
- 如何使用 scikit-learn 在 Python 中開發您的第一個 XGBoost 模型
- 如何在 Python 中使用 XGBoost 評估梯度提升模型
- 在 Python 中使用 XGBoost 的特征重要性和特征選擇
- 淺談機器學習的梯度提升算法
- 應用機器學習的 XGBoost 簡介
- 如何在 macOS 上為 Python 安裝 XGBoost
- 如何在 Python 中使用 XGBoost 保存梯度提升模型
- 從梯度提升開始,比較 165 個數據集上的 13 種算法
- 在 Python 中使用 XGBoost 和 scikit-learn 進行隨機梯度提升
- 如何使用 Amazon Web Services 在云中訓練 XGBoost 模型
- 在 Python 中使用 XGBoost 調整梯度提升的學習率
- 如何在 Python 中使用 XGBoost 調整決策樹的數量和大小
- 如何在 Python 中使用 XGBoost 可視化梯度提升決策樹
- 在 Python 中開始使用 XGBoost 的 7 步迷你課程