日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

sklearn 决策树例子_决策树DecisionTree(附代码实现)

發布時間:2025/3/15 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 sklearn 决策树例子_决策树DecisionTree(附代码实现) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

開局一張圖(網圖,隨便找的)。

對這種類型的圖很熟悉的小伙伴應該馬上就看出來了,這是一顆決策樹,沒錯今天我們的主題就是理解和實現決策樹。

決策樹和我們以前學過的算法稍微有點不一樣,它是個樹形結構。決策樹的決策流程就是從所有輸入特征中選擇一個特征做為決策的依據,找出一個閾值來決定將其劃分到哪一類。

也就是說,創建一個決策樹的主要問題在于:

1.決策樹中每個節點在哪個維度的特征上面進行劃分?

2.被選中的維度的特征具體在哪個值上進行劃分?

為了解決這兩個問題我們引入信息熵的概念。

信息熵的概念本身是信息論中的一個重要概念,因為我們的重點是決策樹,所以就不多涉及信息論的知識,我們只需要知道信息熵是什么。

信息熵簡單的來說就是表示隨機變量不確定度的度量。

熵越大,數據的不確定性就越大。

熵越小,數據的不確定性就越小,也就是越確定。

信息熵的計算公式

其中

是指,數據中一共有n類信息,就是指第i類數據所占的比例。

舉個例子,假設我們的數據中一共有三類。每一類所占比例為

,那么信息熵就是

假設我們數據一共有三類,每類所占比例是0,0,1,那么信息熵就是

(注:實際上log(0)是不能計算的,定義上不允許,真實場景會做其他處理解決這個問題)

很顯然第二組數據比第一組數據信息熵小,也就是不確定性要少,換句話講就是更為確定。

根據這兩個例子,應該就能理解信息熵是隨機變量不確定度的度量了。

如果我們的數據偏向于某一個類別,隨機變量的不確定性就降低了,會變的更為確定。

現在來回答關于決策樹的兩個問題:

1.決策樹中每個節點在哪個維度的特征上面進行劃分?

2.被選中的維度的特征具體在哪個值上進行劃分?

我們希望決策樹每次劃分數據都能讓信息熵降低,當劃分到最后一個葉子節點里面只有一類數據的時候,信息熵就自然的降為了0,所屬的類別就完全確定了。

那么問題來了,我們怎樣找到一個這樣的劃分使得劃分后的信息熵會降低?答案是對著所有維度的特征來一次搜索就行了。

我們來模擬一下這個過程。

導入數據和包

from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split import numpy as np import matplotlib.pyplot as plt from collections import Counter from math import logiris = load_iris() x = iris.data y = iris.target x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=666666)

計算熵

def entropy(y_label):counter = Counter(y_label)ent = 0.0for num in counter.values():p = num / len(y_label)ent += -p * log(p)return ent

劃分數據集

def split(x_data, y_label, dimension, value):"""x_data:輸入特征y_label:輸入標簽類別dimension:選取輸入特征的維度索引value:劃分特征的數值return 左子樹特征,右子樹特征,左子樹標簽,右子樹標簽"""index_left = (x_data[:,dimension] <= value)index_right = (x_data[:,dimension] > value)return x_data[index_left], x_data[index_right], y_label[index_left], y_label[index_right]

劃分一次數據集

遍歷所有維度的特征,不斷尋找一個合適的劃分數值,找到能把熵降到最低的那個特征和數值

def one_split(x_data, y_label):best_entropy = float('inf')best_dimension = -1best_value = -1for d in range(x_data.shape[1]):sorted_index = np.argsort(x_data[:, d])for i in range(1,len(x_data)):if x_data[sorted_index[i], d] != x_data[sorted_index[i - 1], d]:value = (x_data[sorted_index[i], d] + x_data[sorted_index[i-1], d]) / 2x_left, x_right, y_left, y_right = split(x_data, y_label, d, value)p_left = len(x_left) / len(x_data)p_right = len(x_right) / len(x_data)ent = p_left * entropy(y_left) + p_right * entropy(y_right)if ent < best_entropy:best_entropy = entbest_dimension = dbest_value = valuereturn best_entropy, best_dimension, best_value

第一次模擬劃分

找出最好的劃分維度和對應的數值

best_entropy, best_dimension, best_value = one_split(x_train, y_train) print(best_entropy) print(best_dimension) #第二個維度的特征 print(best_value) #劃分的數值

獲取左子樹特征,右子樹特征,左子樹標簽,右子樹標簽

x_left, x_right, y_left, y_right = split(x_train, y_train, best_dimension, best_value)

再來一輪劃分

  • 左子樹的熵已經是0了,沒必要劃分了
best_entropy, best_dimension, best_value = one_split(x_left, y_left) print(best_entropy) print(best_dimension) #第0個維度的特征 print(best_value) #劃分的數值

我們繼續劃分右子樹

best_entropy, best_dimension, best_value = one_split(x_right, y_right) print(best_entropy) print(best_dimension) print(best_value)

x_left2, x_right2, y_left2, y_right2 = split(x_right,y_right,best_dimension,best_value)

經過了兩輪劃分,基本上決策樹已經劃分的差不多了,根據對應維度的特征和閾值決策就行了。如果你熟悉數據結構中的二叉樹結構的話自己就能將決策樹給建起來。

下面給出封裝好的代碼,可以像調用sklearn的決策樹一樣調用它。

class Node:def __init__(self,x_data, y_label, dimension, value):self.x_data = x_dataself.y_label = y_labelself.dimension = dimensionself.value = valueself.left = Noneself.right = Noneclass DTree:def __init__(self):self.root = Nonedef fit(self,x_train, y_train):def entropy(y_label):counter = Counter(y_label)ent = 0.0for num in counter.values():p = num / len(y_label)ent += -p * log(p)return entdef one_split(x_data, y_label):best_entropy = float('inf')best_dimension = -1best_value = -1for d in range(x_data.shape[1]):sorted_index = np.argsort(x_data[:, d])for i in range(1,len(x_data)):if x_data[sorted_index[i], d] != x_data[sorted_index[i - 1], d]:value = (x_data[sorted_index[i], d] + x_data[sorted_index[i-1], d]) / 2x_left, x_right, y_left, y_right = split(x_data, y_label, d, value)p_left = len(x_left) / len(x_data)p_right = len(x_right) / len(x_data)ent = p_left * entropy(y_left) + p_right * entropy(y_right)if ent < best_entropy:best_entropy = entbest_dimension = dbest_value = valuereturn best_entropy, best_dimension, best_valuedef split(x_data, y_label, dimension, value):"""x_data:輸入特征y_label:輸入標簽類別dimension:選取輸入特征的維度索引value:劃分特征的數值return 左子樹特征,右子樹特征,左子樹標簽,右子樹標簽"""index_left = (x_data[:,dimension] <= value)index_right = (x_data[:,dimension] > value)return x_data[index_left], x_data[index_right], y_label[index_left], y_label[index_right]def create_tree(x_data, y_label):ent, dim, value = one_split(x_data, y_label)x_left, x_right, y_left, y_right = split(x_data, y_label, dim, value)node = Node(x_data, y_label, dim, value)if ent < 0.000000001:return nodenode.left = create_tree(x_left, y_left)node.right = create_tree(x_right, y_right)return nodeself.root = create_tree(x_train, y_train)return selfdef predict(self,x_predict):def travel(x_data, node):p = nodeif x_data[p.dimension] <= p.value and p.left:pred = travel(x_data, p.left)elif x_data[p.dimension] > p.value and p.right:pred = travel(x_data, p.right)else:counter = Counter(p.y_label)pred = counter.most_common(1)[0][0]return predy_predict = []for data in x_predict:y_pred = travel(data, self.root)y_predict.append(y_pred)return np.array(y_predict)def score(self,x_test,y_test):y_predict = self.predict(x_test)return np.sum(y_predict == y_test) / len(y_predict)def __repr__(self):return "DTree(criterion='entropy')"

測試一下我們的決策樹

dt = DTree() dt.fit(x_train, y_train) dt.score(x_test,y_test)

sklearn的決策樹

dt_clf = DecisionTreeClassifier() dt_clf.fit(x_train, y_train) dt_clf.score(x_test, y_test)

結果一模一樣,完美!

與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的sklearn 决策树例子_决策树DecisionTree(附代码实现)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。