- 機器學習 之線性迴歸
- 機器學習 之邏輯迴歸及python實現
- 機器學習專案實戰 交易資料異常檢測
- 機器學習之 決策樹(Decision Tree)
- 機器學習之 決策樹(Decision Tree)python實現
- 機器學習之 PCA(主成分分析)
- 機器學習之 特徵工程
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from math import log
複製程式碼
我們使用西瓜書中的一個資料集,來進行我們的決策樹的建立
data = pd.read_csv("decision_tree_data3.txt",names=['編號','色澤','根蒂','敲聲','紋理','臍部','觸感','密度','含糖率','好瓜' ])
data.head()
複製程式碼
編號 | 色澤 | 根蒂 | 敲聲 | 紋理 | 臍部 | 觸感 | 密度 | 含糖率 | 好瓜 | |
---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 青綠 | 蜷縮 | 濁響 | 清晰 | 凹陷 | 硬滑 | 0.697 | 0.460 | 是 |
1 | 2 | 烏黑 | 蜷縮 | 沉悶 | 清晰 | 凹陷 | 硬滑 | 0.774 | 0.376 | 是 |
2 | 3 | 烏黑 | 蜷縮 | 濁響 | 清晰 | 凹陷 | 硬滑 | 0.634 | 0.264 | 是 |
3 | 4 | 青綠 | 蜷縮 | 沉悶 | 清晰 | 凹陷 | 硬滑 | 0.608 | 0.318 | 是 |
4 | 5 | 淺白 | 蜷縮 | 濁響 | 清晰 | 凹陷 | 硬滑 | 0.556 | 0.215 | 是 |
首先,我們需要將資料集做下處理,將對應文字轉換成離散型資料
# def initdata_feature(data):
# len_columns = data.shape[1]
# data_columns = data.columns
# for i in range(len_columns):
# if(i>0 and i<len_columns-3):
# str_values = data.iloc[:,i].unique()
# for j in range(len(str_values)):
# data.loc[data[data_columns[i]]==str_values[j],data_columns[i]] = j
def initdata_y(data):
data.loc[data.好瓜 == '是 ','好瓜'] = 1
data.loc[data.好瓜 == '否 ','好瓜'] = 0
複製程式碼
測試下看看
# initdata_feature(data)
initdata_y(data)
data
複製程式碼
編號 | 色澤 | 根蒂 | 敲聲 | 紋理 | 臍部 | 觸感 | 密度 | 含糖率 | 好瓜 | |
---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 青綠 | 蜷縮 | 濁響 | 清晰 | 凹陷 | 硬滑 | 0.697 | 0.460 | 1 |
1 | 2 | 烏黑 | 蜷縮 | 沉悶 | 清晰 | 凹陷 | 硬滑 | 0.774 | 0.376 | 1 |
2 | 3 | 烏黑 | 蜷縮 | 濁響 | 清晰 | 凹陷 | 硬滑 | 0.634 | 0.264 | 1 |
3 | 4 | 青綠 | 蜷縮 | 沉悶 | 清晰 | 凹陷 | 硬滑 | 0.608 | 0.318 | 1 |
4 | 5 | 淺白 | 蜷縮 | 濁響 | 清晰 | 凹陷 | 硬滑 | 0.556 | 0.215 | 1 |
5 | 6 | 青綠 | 稍蜷 | 濁響 | 清晰 | 稍凹 | 軟粘 | 0.403 | 0.237 | 1 |
6 | 7 | 烏黑 | 稍蜷 | 濁響 | 稍糊 | 稍凹 | 軟粘 | 0.481 | 0.149 | 1 |
7 | 8 | 烏黑 | 稍蜷 | 濁響 | 清晰 | 稍凹 | 硬滑 | 0.437 | 0.211 | 1 |
8 | 9 | 烏黑 | 稍蜷 | 沉悶 | 稍糊 | 稍凹 | 硬滑 | 0.666 | 0.091 | 0 |
9 | 10 | 青綠 | 硬挺 | 清脆 | 清晰 | 平坦 | 軟粘 | 0.243 | 0.267 | 0 |
10 | 11 | 淺白 | 硬挺 | 清脆 | 模糊 | 平坦 | 硬滑 | 0.245 | 0.057 | 0 |
11 | 12 | 淺白 | 蜷縮 | 濁響 | 模糊 | 平坦 | 軟粘 | 0.343 | 0.099 | 0 |
12 | 13 | 青綠 | 稍蜷 | 濁響 | 稍糊 | 凹陷 | 硬滑 | 0.639 | 0.161 | 0 |
13 | 14 | 淺白 | 稍蜷 | 沉悶 | 稍糊 | 凹陷 | 硬滑 | 0.657 | 0.198 | 0 |
14 | 15 | 烏黑 | 稍蜷 | 濁響 | 清晰 | 稍凹 | 軟粘 | 0.360 | 0.370 | 0 |
15 | 16 | 淺白 | 蜷縮 | 濁響 | 模糊 | 平坦 | 硬滑 | 0.593 | 0.042 | 0 |
16 | 17 | 青綠 | 蜷縮 | 沉悶 | 稍糊 | 稍凹 | 硬滑 | 0.719 | 0.103 | 0 |
先把編號那個無用的特徵去掉
data = data.drop('編號', axis = 1)
data
複製程式碼
色澤 | 根蒂 | 敲聲 | 紋理 | 臍部 | 觸感 | 密度 | 含糖率 | 好瓜 | |
---|---|---|---|---|---|---|---|---|---|
0 | 青綠 | 蜷縮 | 濁響 | 清晰 | 凹陷 | 硬滑 | 0.697 | 0.460 | 1 |
1 | 烏黑 | 蜷縮 | 沉悶 | 清晰 | 凹陷 | 硬滑 | 0.774 | 0.376 | 1 |
2 | 烏黑 | 蜷縮 | 濁響 | 清晰 | 凹陷 | 硬滑 | 0.634 | 0.264 | 1 |
3 | 青綠 | 蜷縮 | 沉悶 | 清晰 | 凹陷 | 硬滑 | 0.608 | 0.318 | 1 |
4 | 淺白 | 蜷縮 | 濁響 | 清晰 | 凹陷 | 硬滑 | 0.556 | 0.215 | 1 |
5 | 青綠 | 稍蜷 | 濁響 | 清晰 | 稍凹 | 軟粘 | 0.403 | 0.237 | 1 |
6 | 烏黑 | 稍蜷 | 濁響 | 稍糊 | 稍凹 | 軟粘 | 0.481 | 0.149 | 1 |
7 | 烏黑 | 稍蜷 | 濁響 | 清晰 | 稍凹 | 硬滑 | 0.437 | 0.211 | 1 |
8 | 烏黑 | 稍蜷 | 沉悶 | 稍糊 | 稍凹 | 硬滑 | 0.666 | 0.091 | 0 |
9 | 青綠 | 硬挺 | 清脆 | 清晰 | 平坦 | 軟粘 | 0.243 | 0.267 | 0 |
10 | 淺白 | 硬挺 | 清脆 | 模糊 | 平坦 | 硬滑 | 0.245 | 0.057 | 0 |
11 | 淺白 | 蜷縮 | 濁響 | 模糊 | 平坦 | 軟粘 | 0.343 | 0.099 | 0 |
12 | 青綠 | 稍蜷 | 濁響 | 稍糊 | 凹陷 | 硬滑 | 0.639 | 0.161 | 0 |
13 | 淺白 | 稍蜷 | 沉悶 | 稍糊 | 凹陷 | 硬滑 | 0.657 | 0.198 | 0 |
14 | 烏黑 | 稍蜷 | 濁響 | 清晰 | 稍凹 | 軟粘 | 0.360 | 0.370 | 0 |
15 | 淺白 | 蜷縮 | 濁響 | 模糊 | 平坦 | 硬滑 | 0.593 | 0.042 | 0 |
16 | 青綠 | 蜷縮 | 沉悶 | 稍糊 | 稍凹 | 硬滑 | 0.719 | 0.103 | 0 |
下面就開始實現決策樹演算法,上篇文章已經知道,要根據樣本集建立一棵決策樹,具體演算法流程如下:
下面我們來分模組進行實現。
首先,來看下給定資料集的資訊熵的求解
#求對應資料集的資訊熵
def getInfoEntropy(data):
#print('################################')
#print(data)
count_class = pd.value_counts(data.iloc[:,-1], sort=True) #根據輸出值,統計不同樣本個數
#print(count_class)
data_count = len(data.iloc[:,-1])
#print(data_count)
Entropy = 0.0
for i in range(len(count_class)):
p = count_class.iloc[i]/data_count
Entropy = Entropy + (-p * log(p,2))
#print('當前資料集的資訊熵為:',Entropy)
return Entropy
複製程式碼
測試下看看,求取下整個樣本集的資訊熵
getInfoEntropy(data)
複製程式碼
0.9975025463691153
複製程式碼
下來我們實現下,根據對應特徵,劃分資料。需要分兩種情況
- 離散型特徵,直接根據離散的相應類別進行劃分
- 連續型資料,需要參照資料離散化,選出最優的劃分值。具體原理可檢視上篇文章中的連續型特徵處理
下面來看下具體程式碼實現
#離散型資料劃分
def split_data(data, column):
splt_datas = pd.Series() #將劃分的多個資料集儲存在Series中
str_values = data.iloc[:,column].unique() #獲取當前資料集中,對應特徵的所有類別
for i in range(len(str_values)): #遍歷對應類別,找出類別所對應的資料集
df = data.loc[data.iloc[:,column] == str_values[i]]
# print(df)
splt_datas[str(i)] = df
return splt_datas
#連續型資料劃分
#返回劃分後的左右兩個資料集以及所對應的最優劃分點,還有以此劃分點進行劃分資料後,對應的資訊熵
def split_continuous(data,column):
splt_datas = pd.Series()
series_data_sort = data.iloc[:,column].sort_values() #對應對應連續型特徵的在當前資料集中的所有值,進行從小到大排序
split_values = [] #建立一個list,用於儲存所有的劃分點
# print(series_data_sort)
for i in range(len(series_data_sort)-1): #求得所有劃分點
split_values.append((series_data_sort.iloc[i] + series_data_sort.iloc[i+1])/2) # 注意,這塊不能用series_data_sort[i]
best_split_value = 0. #所要找出的最佳劃分點
minInfoGain = 100.
# print(split_values)
for i in range(len(split_values)): #遍歷所有劃分點
# print('split_values[i]==',split_values[i])
#根據對應劃分點,將資料集劃分為左右兩個資料集(即二分)
left_data = data.loc[data.iloc[:,column]<=split_values[i]]
right_data = data.loc[data.iloc[:,column]>split_values[i]]
#求得對應資訊熵
InfoGain = len(left_data)/len(data) * getInfoEntropy(left_data) + len(right_data)/len(data) * getInfoEntropy(right_data)
#print('InfoGain====',InfoGain)
if(InfoGain < minInfoGain): #找出最小的資訊熵
minInfoGain = InfoGain
best_split_value = split_values[i]
left_data = data.loc[data.iloc[:,column]<=best_split_value]
right_data = data.loc[data.iloc[:,column]>best_split_value]
series = pd.Series()
series['0'] = left_data
series['1'] = right_data
return series,best_split_value,minInfoGain
複製程式碼
測試下看看
seris = split_data(data,0)
for i in range(len(seris)):
print (seris.iloc[i])
複製程式碼
色澤 根蒂 敲聲 紋理 臍部 觸感 密度 含糖率 好瓜
0 青綠 蜷縮 濁響 清晰 凹陷 硬滑 0.697 0.460 1
3 青綠 蜷縮 沉悶 清晰 凹陷 硬滑 0.608 0.318 1
5 青綠 稍蜷 濁響 清晰 稍凹 軟粘 0.403 0.237 1
9 青綠 硬挺 清脆 清晰 平坦 軟粘 0.243 0.267 0
12 青綠 稍蜷 濁響 稍糊 凹陷 硬滑 0.639 0.161 0
16 青綠 蜷縮 沉悶 稍糊 稍凹 硬滑 0.719 0.103 0
色澤 根蒂 敲聲 紋理 臍部 觸感 密度 含糖率 好瓜
1 烏黑 蜷縮 沉悶 清晰 凹陷 硬滑 0.774 0.376 1
2 烏黑 蜷縮 濁響 清晰 凹陷 硬滑 0.634 0.264 1
6 烏黑 稍蜷 濁響 稍糊 稍凹 軟粘 0.481 0.149 1
7 烏黑 稍蜷 濁響 清晰 稍凹 硬滑 0.437 0.211 1
8 烏黑 稍蜷 沉悶 稍糊 稍凹 硬滑 0.666 0.091 0
14 烏黑 稍蜷 濁響 清晰 稍凹 軟粘 0.360 0.370 0
色澤 根蒂 敲聲 紋理 臍部 觸感 密度 含糖率 好瓜
4 淺白 蜷縮 濁響 清晰 凹陷 硬滑 0.556 0.215 1
10 淺白 硬挺 清脆 模糊 平坦 硬滑 0.245 0.057 0
11 淺白 蜷縮 濁響 模糊 平坦 軟粘 0.343 0.099 0
13 淺白 稍蜷 沉悶 稍糊 凹陷 硬滑 0.657 0.198 0
15 淺白 蜷縮 濁響 模糊 平坦 硬滑 0.593 0.042 0
複製程式碼
series,best_split_value,minInfoGain = split_continuous(data,6)
for i in range(len(series)):
print (series.iloc[i])
複製程式碼
色澤 根蒂 敲聲 紋理 臍部 觸感 密度 含糖率 好瓜
9 青綠 硬挺 清脆 清晰 平坦 軟粘 0.243 0.267 0
10 淺白 硬挺 清脆 模糊 平坦 硬滑 0.245 0.057 0
11 淺白 蜷縮 濁響 模糊 平坦 軟粘 0.343 0.099 0
14 烏黑 稍蜷 濁響 清晰 稍凹 軟粘 0.360 0.370 0
色澤 根蒂 敲聲 紋理 臍部 觸感 密度 含糖率 好瓜
0 青綠 蜷縮 濁響 清晰 凹陷 硬滑 0.697 0.460 1
1 烏黑 蜷縮 沉悶 清晰 凹陷 硬滑 0.774 0.376 1
2 烏黑 蜷縮 濁響 清晰 凹陷 硬滑 0.634 0.264 1
3 青綠 蜷縮 沉悶 清晰 凹陷 硬滑 0.608 0.318 1
4 淺白 蜷縮 濁響 清晰 凹陷 硬滑 0.556 0.215 1
5 青綠 稍蜷 濁響 清晰 稍凹 軟粘 0.403 0.237 1
6 烏黑 稍蜷 濁響 稍糊 稍凹 軟粘 0.481 0.149 1
7 烏黑 稍蜷 濁響 清晰 稍凹 硬滑 0.437 0.211 1
8 烏黑 稍蜷 沉悶 稍糊 稍凹 硬滑 0.666 0.091 0
12 青綠 稍蜷 濁響 稍糊 凹陷 硬滑 0.639 0.161 0
13 淺白 稍蜷 沉悶 稍糊 凹陷 硬滑 0.657 0.198 0
15 淺白 蜷縮 濁響 模糊 平坦 硬滑 0.593 0.042 0
16 青綠 蜷縮 沉悶 稍糊 稍凹 硬滑 0.719 0.103 0
複製程式碼
接下來,我們要做的就是,給定一個資料集,我們需要求得最優的劃分特徵,先來來看下程式碼實現
# 查詢當前資料集data 的 最優劃分特徵。返回對應最優特徵在資料集data中的索引
def find_best_feature(data):
best_feature_index = 0 #用來儲存最優劃分特徵的索引
minInfoGain = 100. #儲存資訊增益
samplenumber = len(data) #當前資料集的個數
best_split_value_return = 0. #如果最優劃分特徵是個連續型別的,則還需要儲存對應的連續特徵的最優劃分點
best_split_value = 0.
best_Series = pd.Series()
for i in range(data.shape[1]-1): #遍歷資料集的所有特徵
InfoGain = 0.
series = pd.Series()
if(i < data.shape[1]-3): #離散型屬性
series = split_data(data, i) #根據特徵劃分資料,將劃分的多個資料集(DataFrame)儲存在一個Series中返回
for j in range(len(series)):
df = series[j]
InfoGain = InfoGain +len(df)/samplenumber *(getInfoEntropy(df))
# print('InfoGain==',InfoGain,'----i=',i)
else: #連續型屬性
series,best_split_value, InfoGain = split_continuous(data,i)
# print('InfoGain==',InfoGain,'----i=',i)
if(InfoGain < minInfoGain):
minInfoGain = InfoGain
InfoGain = 0.0
best_feature_index = i
best_Series = series
if(i >= data.shape[1]-3):
best_split_value_return = best_split_value
return data.columns[best_feature_index],best_Series,best_split_value_return
複製程式碼
測試下看看
find_best_feature(data)
複製程式碼
('紋理', 0 色澤 根蒂 敲聲 紋理 臍部 觸感 密度 含糖率 好瓜
0...
1 色澤 根蒂 敲聲 紋理 臍部 觸感 密度 含糖率 好瓜
6...
2 色澤 根蒂 敲聲 紋理 臍部 觸感 密度 含糖率 好瓜
1...
dtype: object, 0.0)
複製程式碼
接下來就要實現決策樹的構建了
#建立樹模型
def creat_Tree(data):
y_values = data.iloc[:,-1].unique() #得到當前資料集的y的類別
if(len(y_values) == 1): #如果只剩下一個類別,說明已經是純淨的資料,不需要再分,直接返回
return y_values[0]
flag = 0
for i in range(data.shape[1]-1): #當前節點中的所有樣本在當前所剩屬性集中取值相同,則直接返回當前資料集中類別樣本多的那個類別
if(len(data.iloc[:,i].unique()) != 1):
flag = 1
break
if(flag == 0):
value_count = pd.value_counts(data.iloc[:,-1])
return value_count.index[0]
best_feature, best_Series,best_split_value = find_best_feature(data) #尋找最優特徵,返回最優特徵,劃分後的資料集,已經如果是連續型特徵,還需要劃分點
Tree = {best_feature:{}} #用字典來模擬樹
for j in range(len(best_Series)): #遍歷劃分後的資料集
split_data = best_Series.iloc[j]
value = ''
if(best_split_value == 0.0): #說明是離散型特徵
value = split_data.loc[:,best_feature].unique()[0] #獲取對應劃分的特徵中,對應的特徵類別
split_data = split_data.drop(best_feature, axis = 1) #離散型型特徵,用完後需要刪除
else: #否則,說明是連續型特徵
if(j == 0):
value = '<='+str(best_split_value)
else:
value = '>'+str(best_split_value)
Tree[best_feature][value] = creat_Tree(split_data) #採用遞迴思想,繼續構建
return Tree
複製程式碼
Tree = creat_Tree(data)
Tree
複製程式碼
{'紋理': {'模糊': 0,
'清晰': {'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}},
'稍糊': {'觸感': {'硬滑': 0, '軟粘': 1}}}}
複製程式碼
接下來,來實現下,使用訓練出來的決策樹,對新的資料進行分類
#預測一個樣本
def classification_one(Tree, data):
print(Tree)
first_key = list(Tree.keys())[0] #獲取根節點的key
first_value = Tree[first_key] #獲取根節點對應的value
result = -1 #初始化,用來儲存當前節點的結果
if('<' in list(first_value.keys())[0]): #連續型特徵
#解釋下下面兩行程式碼,裡面的 list(first_value.keys())[0] 獲取來的就是‘<=0.38...’這種格式,需要從這個裡面解析出0.38...這個分割點
left_key = list(first_value.keys())[0] #'<=分割點'
right_key = list(first_value.keys())[1] #'>分割點'
split_poit = float(''.join(list(left_key)[2:])) # '分割點'
if(data[first_key] <= split_poit): #如果屬於左分支
if(isinstance(first_value[left_key], dict)): #判斷是否是葉子節點,如果對應的value還是一個dict字典,則說明是個非葉子節點,繼續遞迴
result = classification_one(first_value[left_key],data)
else: #如果是葉子節點,返回結果值
result = first_value[left_key]
else: #如果屬於左分支
if(isinstance(first_value[right_key], dict)):
result = classification_one(first_value[right_key],data)
else:
result = first_value[right_key]
else: #離散型特徵
if(isinstance(first_value[data[first_key]], dict)):
result = classification_one(first_value[data[first_key]],data)
else:
result = first_value[data[first_key]]
return result
#預測多個樣本
def classification_more(Tree, data):
result_list = []
for i in range(data.shape[0]):
result = classification_one(Tree, data.iloc[i])
result_list.append(result)
return result_list
複製程式碼
classification_more(Tree,data)
複製程式碼
{'紋理': {'清晰': {'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}, '稍糊': {'觸感': {'軟粘': 1, '硬滑': 0}}, '模糊': 0}}
{'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}
{'紋理': {'清晰': {'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}, '稍糊': {'觸感': {'軟粘': 1, '硬滑': 0}}, '模糊': 0}}
{'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}
{'紋理': {'清晰': {'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}, '稍糊': {'觸感': {'軟粘': 1, '硬滑': 0}}, '模糊': 0}}
{'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}
{'紋理': {'清晰': {'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}, '稍糊': {'觸感': {'軟粘': 1, '硬滑': 0}}, '模糊': 0}}
{'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}
{'紋理': {'清晰': {'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}, '稍糊': {'觸感': {'軟粘': 1, '硬滑': 0}}, '模糊': 0}}
{'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}
{'紋理': {'清晰': {'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}, '稍糊': {'觸感': {'軟粘': 1, '硬滑': 0}}, '模糊': 0}}
{'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}
{'紋理': {'清晰': {'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}, '稍糊': {'觸感': {'軟粘': 1, '硬滑': 0}}, '模糊': 0}}
{'觸感': {'軟粘': 1, '硬滑': 0}}
{'紋理': {'清晰': {'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}, '稍糊': {'觸感': {'軟粘': 1, '硬滑': 0}}, '模糊': 0}}
{'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}
{'紋理': {'清晰': {'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}, '稍糊': {'觸感': {'軟粘': 1, '硬滑': 0}}, '模糊': 0}}
{'觸感': {'軟粘': 1, '硬滑': 0}}
{'紋理': {'清晰': {'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}, '稍糊': {'觸感': {'軟粘': 1, '硬滑': 0}}, '模糊': 0}}
{'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}
{'紋理': {'清晰': {'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}, '稍糊': {'觸感': {'軟粘': 1, '硬滑': 0}}, '模糊': 0}}
{'紋理': {'清晰': {'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}, '稍糊': {'觸感': {'軟粘': 1, '硬滑': 0}}, '模糊': 0}}
{'紋理': {'清晰': {'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}, '稍糊': {'觸感': {'軟粘': 1, '硬滑': 0}}, '模糊': 0}}
{'觸感': {'軟粘': 1, '硬滑': 0}}
{'紋理': {'清晰': {'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}, '稍糊': {'觸感': {'軟粘': 1, '硬滑': 0}}, '模糊': 0}}
{'觸感': {'軟粘': 1, '硬滑': 0}}
{'紋理': {'清晰': {'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}, '稍糊': {'觸感': {'軟粘': 1, '硬滑': 0}}, '模糊': 0}}
{'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}
{'紋理': {'清晰': {'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}, '稍糊': {'觸感': {'軟粘': 1, '硬滑': 0}}, '模糊': 0}}
{'紋理': {'清晰': {'密度': {'<=0.38149999999999995': 0, '>0.38149999999999995': 1}}, '稍糊': {'觸感': {'軟粘': 1, '硬滑': 0}}, '模糊': 0}}
{'觸感': {'軟粘': 1, '硬滑': 0}}
[1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
複製程式碼
我們還是使用的上面的那個資料集用來驗證,可以看到,已經完全擬合了訓練集,
但是,這樣真的好嗎?正如上篇文章說的,決策樹如果不進行剪枝的話,肯定最後會一直分下去,直到所分的各個資料集完全是純淨的,這樣,非常容易導致過擬合現象。所以,還需要進行剪枝操作。具體程式碼這塊不演示了,只要掌握了整個決策樹構建的原理,實現起來也很簡單。
上面,演示的只是ID3演算法的相關實現,還有決策的其他演算法,例如C4.5決策樹演算法,主要區別就是最優劃分特徵的選擇標準不同。流程基本都是一致的。