游戲AI的創造思路-技術基礎-決策樹(1)

決策樹,是每個游戲人必須要掌握的游戲AI構建技術,難度小,速度快,結果直觀,本篇將對決策樹進行小小解讀~~~~

目錄

1. 定義

2. 發展歷史

3. 決策樹的算法公式和函數

3.1. 信息增益(Information Gain)

3.2. 信息增益比(Gain Ratio)?

3.3. 基尼指數(Gini Index)

3.4. 三種劃分標準對比

4. 運行原理及步驟

5. 優缺點

6. 游戲AI使用決策樹算法進行NPC行為控制

6.1. 概述

6.2. 詳細過程

6.3. 實例

6.4. Python實現

7. 總述


1. 定義

決策樹算法是一種常用的機器學習算法,它通過遞歸地選擇最佳特征來對數據進行分類或回歸。

決策樹由節點和有向邊組成,內部節點表示一個特征或屬性,葉節點表示分類或回歸的結果。

在游戲AI中,決策樹可以幫助NPC更智能地做出決策,提高游戲的趣味性和挑戰性。

2. 發展歷史

決策樹算法的發展可以追溯到1959年,當時的研究人員試圖解決人工智能中的決策問題。

1986年,喬治·盧卡斯(George A. Quinlan)提出了ID3算法,這是決策樹學習的第一個主要成果。

隨后,盧卡斯又提出了C4.5算法,這是ID3算法的改進版本,具有更強的魯棒性和泛化能力。

CART(Classification and Regression Trees)算法也在此基礎上發展,它可以處理連續型特征,適用于回歸問題。

3. 決策樹的算法公式和函數

決策樹算法的核心在于如何選擇最優劃分特征,通常使用信息增益(Information Gain)、信息增益比(Gain Ratio)或基尼指數(Gini Index)作為劃分標準。

3.1. 信息增益(Information Gain)

  • 信息增益(Information Gain)公式
    [ Gain(D, A) = Ent(D) - \sum_{v=1}^{V} \frac{|D^v|}{|D|} Ent(D^v) ]
    其中,(Ent(D))是數據集D的信息熵,(D^v)是特征A上取值為v的樣本子集。

  • Python 實現信息增益

import numpy as np  def entropy(y):  n = len(y)  labels_count = {}  for label in y:  if label not in labels_count:  labels_count[label] = 0  labels_count[label] += 1  ent = 0.0  for label in labels_count:  p = labels_count[label] / n  ent -= p * np.log2(p)  return ent  def info_gain(X, y, feature):  n = len(y)  ent_before = entropy(y)  total_gain = 0.0  feature_values = np.unique(X[:, feature])  for value in feature_values:  sub_X = X[X[:, feature] == value]  sub_y = y[X[:, feature] == value]  prob = len(sub_X) / n  total_gain += prob * entropy(sub_y)  return ent_before - total_gain

3.2. 信息增益比(Gain Ratio)?

決策樹使用信息增益比(Gain Ratio)作為劃分標準時,其公式是基于信息增益的,但增加了一個分裂信息(Split Information)的項來規范化信息增益,從而避免偏向于選擇取值較多的特征。

  • 信息增益比公式
  1. 信息增益(Information Gain)
    [ Gain(D, A) = Ent(D) - \sum_{v=1}^{V} \frac{|D^v|}{|D|} Ent(D^v) ]

  2. 分裂信息(Split Information)
    [ SplitInfo(D, A) = -\sum_{v=1}^{V} \frac{|D^v|}{|D|} \log_2 \frac{|D^v|}{|D|} ]

  3. 信息增益比(Gain Ratio)
    [ GainRatio(D, A) = \frac{Gain(D, A)}{SplitInfo(D, A)} ]

  • Python實現代碼

以下是使用Python實現信息增益比的代碼:

import numpy as np  def entropy(y):  """計算信息熵"""  n = len(y)  labels_count = {}  for label in y:  if label not in labels_count:  labels_count[label] = 0  labels_count[label] += 1  ent = 0.0  for label in labels_count:  p = labels_count[label] / n  ent -= p * np.log2(p)  return ent  def split_info(X, feature):  """計算分裂信息"""  n = len(X)  feature_values = np.unique(X[:, feature])  split_info = 0.0  for value in feature_values:  sub_X = X[X[:, feature] == value]  prob = len(sub_X) / n  split_info -= prob * np.log2(prob)  return split_info  def info_gain(X, y, feature):  """計算信息增益"""  n = len(y)  ent_before = entropy(y)  total_gain = 0.0  feature_values = np.unique(X[:, feature])  for value in feature_values:  sub_X = X[X[:, feature] == value]  sub_y = y[X[:, feature] == value]  prob = len(sub_X) / n  total_gain += prob * entropy(sub_y)  return ent_before - total_gain  def gain_ratio(X, y, feature):  """計算信息增益比"""  gain = info_gain(X, y, feature)  split_info = split_info(X, feature)  if split_info == 0:  # 避免除以0的情況  return 0  return gain / split_info  # 示例數據  
X = np.array([[1, 0], [1, 1], [0, 0], [0, 1]])  
y = np.array([0, 0, 1, 1])  # 計算特征0和特征1的信息增益比  
print("Gain Ratio for feature 0:", gain_ratio(X, y, 0))  
print("Gain Ratio for feature 1:", gain_ratio(X, y, 1))

這段代碼定義了計算信息熵、分裂信息、信息增益和信息增益比的函數,然后在示例數據上計算了特征0和特征1的信息增益比。

3.3. 基尼指數(Gini Index)

決策樹使用基尼指數(Gini index)作為劃分標準時,其公式主要用于衡量數據集或數據子集的不純度。基尼指數越小,表示數據集或數據子集的純度越高,即選定的特征越好。

  • 基尼指數公式

對于給定的數據集?D,其基尼指數?Gini(D)?可以通過以下公式計算:

[ Gini(D) = 1 - \sum_{k=1}{J} p_k2 ]

其中,pk??是數據集?D?中選擇第?k?類的概率,J?是類的總數。

對于特征?A,假設它有?V?個可能的取值?{a1,a2,…,aV},如果使用特征?A?對數據集?D?進行劃分,可以得到?V?個子集?{D1,D2,…,DV},其中?Dv?包含所有在特征?A?上取值為?av?的樣本。此時,特征?A?對數據集?D?的基尼指數?Gini(D,A)可以通過以下公式計算:

[ Gini(D, A) = \frac{\sum_{v=1}^{V} |D^v| \cdot Gini(D^v)}{|D|} ]

其中,Gini(Dv)是子集?Dv?的基尼指數,∣Dv∣?是子集?Dv?的樣本數量,∣D∣?是數據集?D?的樣本總數。

  • Python實現代碼

以下是使用Python實現基尼指數的代碼:

import numpy as np  def gini_index(y):  """計算數據集的基尼指數"""  n = len(y)  labels_count = {}  for label in y:  if label not in labels_count:  labels_count[label] = 0  labels_count[label] += 1  gini = 1.0  for label in labels_count:  p = labels_count[label] / n  gini -= p**2  return gini  def gini_index_feature(X, y, feature):  """計算特征對數據集的基尼指數"""  n = len(y)  feature_values = np.unique(X[:, feature])  total_gini = 0.0  for value in feature_values:  sub_X = X[X[:, feature] == value]  sub_y = y[X[:, feature] == value]  prob = len(sub_X) / n  total_gini += prob * gini_index(sub_y)  return total_gini  # 示例數據  
X = np.array([[1, 0], [1, 1], [0, 0], [0, 1]])  
y = np.array([0, 0, 1, 1])  # 計算特征0和特征1的基尼指數  
print("Gini index for feature 0:", gini_index_feature(X, y, 0))  
print("Gini index for feature 1:", gini_index_feature(X, y, 1))

這段代碼定義了計算數據集基尼指數的函數?gini_index。

然后定義了計算特征對數據集基尼指數的函數?gini_index_feature

最后,在示例數據上計算了特征0和特征1的基尼指數。

3.4. 三種劃分標準對比

決策樹在構建過程中,選擇合適的劃分標準至關重要,這直接影響到決策樹的性能和效率。信息增益(Information Gain)、信息增益比(Gain Ratio)和基尼指數(Gini Index)是三種常用的劃分標準,它們各自具有不同的優點和缺陷。

  • 信息增益(Information Gain)

優點

  1. 直觀易懂:信息增益的計算過程簡單明了,易于理解和解釋。它反映了使用某個特征進行劃分后,數據集純度的提升程度。
  2. 適應性強:信息增益可以適應多個類別之間的分類問題,并可以應用于離散型和連續型的特征。
  3. 多特征值偏好:信息增益在計算時考慮了特征的不確定性程度,因此對于具有更多特征值的特征更有利,這有助于捕捉數據中的細節信息。

缺陷

  1. 特征值偏好:信息增益傾向于選擇具有更多特征值的特征作為劃分特征,這可能導致決策樹過于復雜,增加過擬合的風險。
  2. 忽略相關性:信息增益獨立地計算每個特征的重要性,可能忽視了特征之間的相關性,而特征之間的相關性對于分類問題具有重要意義。
  • 信息增益比(Gain Ratio)

優點

  1. 規范化信息增益:信息增益比通過引入分裂信息(Split Information)對信息增益進行了規范化,從而減少了信息增益對具有更多特征值特征的偏好。
  2. 處理特征值偏差:在信息增益的基礎上,信息增益比更好地處理了特征值分布偏差大的情況,提高了決策樹的健壯性。

缺陷

  1. 計算復雜度:由于需要計算分裂信息,信息增益比的計算復雜度略高于信息增益,特別是在處理大規模數據集時。
  2. 可能偏向取值少的特征:在某些情況下,信息增益比可能過于偏向取值數目較少的特征,這需要根據具體數據集進行權衡。
  • 基尼指數(Gini Index)

優點

  1. 計算效率高:基尼指數的計算方式相對簡單,不涉及對數運算,因此在處理大規模數據集時具有較高的效率。
  2. 不偏向特征值:基尼指數在計算特征重要性時不考慮特征的不確定性程度,因此不會偏向于具有更多特征值的特征。
  3. 二分類友好:基尼指數特別適用于二分類問題,能夠直觀地反映分類的準確性。

缺陷

  1. 不直觀:基尼指數作為一個概率指標,其計算過程相對較為抽象,不如信息增益直觀易懂。
  2. 多分類問題:雖然基尼指數可以應用于多分類問題,但在處理多個類別之間的分類時,其效果可能不如信息增益或信息增益比。
  • 小結

三種劃分標準各有優缺點,選擇哪種標準取決于具體問題的特點和數據集的特征。

在實際應用中,可以通過交叉驗證等方法來評估不同劃分標準對決策樹性能的影響,從而選擇最適合的劃分標準。

4. 運行原理及步驟

決策樹的構建過程包括選擇最佳劃分特征、遞歸地劃分數據集、剪枝等步驟。

  • 步驟
    1. 選擇最佳劃分特征:根據信息增益、信息增益比或基尼指數選擇最佳劃分特征。
    2. 劃分數據集:根據選擇的特征和特征值劃分數據集。
    3. 遞歸構建決策樹:對每個子數據集重復上述步驟,直到滿足停止條件(如所有樣本屬于同一類,或沒有更多特征等)。
    4. 剪枝:為了防止過擬合,通常需要對決策樹進行剪枝。
  • Python 實現決策樹構建
class DecisionTree:  def __init__(self, max_depth=None, min_samples_split=2):  self.max_depth = max_depth  self.min_samples_split = min_samples_split  self.root = None  def fit(self, X, y):  self.root = self._build_tree(X, y, 0)  def _build_tree(self, X, y, depth):  # 停止條件  if depth >= self.max_depth or len(np.unique(y)) == 1 or len(X) < self.min_samples_split:  return Node(value=np.argmax(np.bincount(y)))  # 選擇最佳劃分特征  best_feature, best_thresh = self._best_split(X, y)  # 劃分數據集  left_idxs, right_idxs = self._split(X[:, best_feature], best_thresh)  # 遞歸構建子樹  left = self._build_tree(X[left_idxs, :], y[left_idxs], depth + 1)  right = self._build_tree(X[right_idxs, :], y[right_idxs], depth + 1)  return Node(best_feature, best_thresh, left, right)  # 輔助函數:選擇最佳劃分特征和閾值、劃分數據集等

5. 優缺點

  • 優點
    • 易于理解和實現。
    • 計算效率高,對于分類問題表現良好。
    • 能夠處理非線性關系。
    • 可以清晰地顯示決策過程,便于解釋。
  • 缺點
    • 容易過擬合,需要通過剪枝等技術解決。
    • 對缺失值比較敏感,需要額外處理。
    • 在某些復雜問題上可能不如神經網絡等算法表現優異。

6. 游戲AI使用決策樹算法進行NPC行為控制

在游戲開發中,NPC(非玩家角色)的行為控制是一個重要方面。

使用決策樹算法可以有效地管理和控制NPC的行為,使其根據游戲環境和玩家行為做出合理的反應。

6.1. 概述

決策樹是一種基于樹結構的決策模型,其中每個內部節點表示一個屬性上的判斷,每個分支代表一個判斷結果的輸出,最后每個葉節點代表一種分類結果。

6.2. 詳細過程

  1. 定義行為: 確定NPC可能執行的所有行為,例如攻擊、逃跑、對話等。
  2. 確定屬性: 選擇影響NPC行為的屬性,如玩家距離、玩家狀態(攻擊、防御等)、NPC當前狀態等。
  3. 構建決策樹: 使用屬性構建決策節點,每個節點根據屬性做出決策,并決定下一步的行為。
  4. 實施行為: 根據決策樹的結果,NPC執行相應的行為。

6.3. 實例

假設我們有一個簡單的游戲,NPC可以執行兩種行為:攻擊和逃跑。我們考慮兩個屬性:玩家距離和玩家狀態。

  • 如果玩家距離小于5米且玩家處于攻擊狀態,NPC選擇逃跑。
  • 如果玩家距離小于5米且玩家不處于攻擊狀態,NPC選擇對話。
  • 如果玩家距離大于等于5米,NPC選擇巡邏。

6.4. Python實現

class NPC:  def __init__(self, name):  self.name = name  def decide_action(self, player_distance, player_is_attacking):  # 根據玩家距離和玩家狀態決定NPC的行為  if player_distance < 5:  if player_is_attacking:  return "逃跑"  else:  return "對話"  else:  return "巡邏"  # 實例化NPC  
npc = NPC("守衛")  # 調用decide_action方法決定NPC的行為,并打印結果  
action = npc.decide_action(3, True)  
print(f"{npc.name}決定{action}")

這段代碼定義了一個NPC類,其中__init__方法是構造函數,用于初始化NPC的姓名。

decide_action方法根據傳入的玩家距離(player_distance)和玩家是否處于攻擊狀態(player_is_attacking)來決定NPC應該執行的行為,并返回該行為。

最后,代碼創建了一個名為“守衛”的NPC實例,并調用decide_action方法來決定其行為,然后打印出結果。

7. 總述

決策樹算法運用于游戲的AI中,歷史悠久,難度相對其他算法來說最低,也是運用最廣的一種方法。簡單的決策樹早就在紅白機時代就已初見雛形。隨著近年來的發展,決策樹更多的關注于自動決策樹生成,后面有機會會著重于此部分論述。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/41793.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/41793.shtml
英文地址,請注明出處:http://en.pswp.cn/web/41793.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

深度解析:STM32對接米家平臺,打造WiFi智能插座(ESP8266、電流檢測)

摘要: 智能插座作為智能家居的入門級設備&#xff0c;憑借其低成本、易部署等優勢&#xff0c;受到了廣大用戶的青睞。本文將引領你從零開始&#xff0c;使用功能強大的STM32微控制器、廣受歡迎的ESP8266 WiFi模塊以及功能豐富的米家IoT平臺&#xff0c;一步步打造出一款能夠遠…

el-form rules動態限制

情景描述&#xff1a; el-form 的ref“obj” rules 對象obj有a,b,c三個字段&#xff0c;點擊按鈕a&#xff0c;a和b字段必填,點擊按鈕c,c字段必填&#xff0c;如何通過 this.$refs.obj.validate((valid)>{})去判斷呢 <template><div><!-- 你的表單組件 --&g…

代碼隨想錄-Day50

1143. 最長公共子序列 給定兩個字符串 text1 和 text2&#xff0c;返回這兩個字符串的最長 公共子序列 的長度。如果不存在 公共子序列 &#xff0c;返回 0 。 一個字符串的 子序列 是指這樣一個新的字符串&#xff1a;它是由原字符串在不改變字符的相對順序的情況下刪除某些…

【Linux】supervisor離線源碼安裝

一、安裝meld wget https://pypi.python.org/packages/45/a0/317c6422b26c12fe0161e936fc35f36552069ba8e6f7ecbd99bbffe32a5f/meld3-1.0.2.tar.gz#md53ccc78cd79cffd63a751ad7684c02c91tar -zxvf meld3-1.0.2.tar.gz cd meld3-1.0.2 python setup.py install二、安裝supervis…

Linux環境中安裝JDK

1.下載安裝包 可以通過訪問oracle官網&#xff1a;Java Downloads | Oracle 中國 下載對應的安裝包。 本文使用的是java8的安裝包&#xff0c;包名為&#xff1a;jdk-8u401-linux-x64.tar.gz 2.上傳安裝包到Linux環境 3.進入/usr目錄下&#xff0c;新建一個java的目錄&#…

Python數據分析-歐洲經濟聚類和主成分分析

一、研究背景 歐洲經濟長期以來是全球經濟體系中的重要組成部分。無論是在全球金融危機后的復蘇過程中&#xff0c;還是在新冠疫情期間&#xff0c;歐洲經濟的表現都對世界經濟產生了深遠的影響。歐洲各國經濟體之間既存在相似性&#xff0c;也存在顯著的差異。這些差異不僅體…

Linux下QT程序啟動失敗問題排查方法

文章目錄 0.問題背景1.程序啟動失敗常見原因2.排查依賴庫問題2.1 依賴庫缺失2.2 依賴庫加載路徑錯誤2.3 依賴庫版本不匹配2.4 QT插件庫缺失2.4.1 QT插件庫缺失2.4.2 插件庫自身的依賴庫缺失 2.5 系統基礎C庫不匹配 3.資源問題3.1 缺少翻譯文件3.2 缺少依賴的資源文件3.3 缺少依…

Unity3D批量修改名稱工具

介紹 該工具用于批量修改某游戲對象的一級子對象名稱&#xff0c;功能包括批量添加前后綴、批量修改公共名稱字段和批量修改為同一名稱&#xff0c;包括撤銷和恢復功能。 批量添加前后綴可使用預設從指定數字遞增或遞減至指定數字。 資源下載 GitHub 百度網盤&#xff08…

水果商城系統 SpringBoot+Vue

1、技術棧 技術棧&#xff1a;SpringBootVueMybatis等使用環境&#xff1a;Windows10 谷歌瀏覽器開發環境&#xff1a;jdk1.8 Maven mysql Idea 數據庫僅供學習參考 【已經答辯過的畢業設計】 項目源碼地址 2、功能劃分 3、效果演示

化工廠定位的意義?如何有效解決管理難題

化工廠定位是運用于工廠人員定位管理的新技術&#xff0c;這一技術的應用具有特殊的意義&#xff0c;和傳統管理模式相比具有很大的區別&#xff0c;那么&#xff0c;你是否清楚化工廠定位的意義&#xff0c;它是如何有效的去解決工廠現存的管理難題呢? 傳統化工廠管理到底有哪…

PySide6開發桌面程序,PySide6入門實戰(上)

文章目錄 系列文章索引一、前期準備1、簡介及安裝2、PyCharm PySide6環境搭建&#xff08;1&#xff09;基礎環境&#xff08;2&#xff09;配置QT Designer、PyUIC、PyRCC&#xff08;3&#xff09;使用pyside6項目&#xff08;4&#xff09;資源文件編寫與編譯 二、QT常用控件…

排序矩陣查找

題目鏈接 排序矩陣查找 題目描述 注意點 每一行、每一列都按升序排列 解答思路 可以從右上角開始遍歷&#xff0c;如果當前元素就等于target&#xff0c;直接返回true&#xff1b;如果當前元素小于target&#xff0c;則target肯定在當前位置下方&#xff1b;如果當前元素大…

基于深度學習的電力分配

基于深度學習的電力分配是一項利用深度學習算法優化電力系統中的電力資源分配、負荷預測、故障檢測和系統管理的技術。該技術旨在提高電力系統的運行效率、穩定性和可靠性。以下是關于這一領域的系統介紹&#xff1a; 1. 任務和目標 電力分配的主要任務是優化電力系統中的電力…

挑戰杯 LSTM的預測算法 - 股票預測 天氣預測 房價預測

0 簡介 今天學長向大家介紹LSTM基礎 基于LSTM的預測算法 - 股票預測 天氣預測 房價預測 這是一個較為新穎的競賽課題方向&#xff0c;學長非常推薦&#xff01; &#x1f9ff; 更多資料, 項目分享&#xff1a; https://gitee.com/dancheng-senior/postgraduate 1 基于 Ke…

手機飛行模式是什么意思?3個方法教你如何開啟

在現代生活中&#xff0c;手機已經成為我們日常生活中不可或缺的一部分。然而&#xff0c;有時我們需要暫時切斷手機的通信功能&#xff0c;比如在飛機上、開會時或需要安靜休息的時候。這時候&#xff0c;蘋果手機上的“飛行模式”功能就派上了用場。 那么&#xff0c;手機飛…

人臉表情識別Facial Expression Recognition基于Python3和Keras2(TensorFlow后端)

人臉表情識別項目是一個結合了計算機視覺和深度學習技術的高級應用&#xff0c;主要用于分析和理解人類面部表情所傳達的情感狀態。這樣的系統可以用于多種場景&#xff0c;比如情緒分析、用戶交互、市場調研、醫療診斷以及人機接口等領域。 一個典型的人臉表情識別項目可以分…

端到端自動駕駛新突破:Nvidia提出全并行PARA-Drive,斬獲CVPR挑戰賽冠軍

論文標題&#xff1a; PARA-Drive: Parallelized Architecture for Real-time Autonomous Driving 論文作者&#xff1a; Xinshuo Weng, Boris Ivanovic, Yan Wang, Yue Wang, Marco Pavone 導讀&#xff1a; 本文系統分析了自動駕駛高級架構的設計空間&#xff0c;提出了關…

了解安全端口

安全端口的定義和重要性 安全端口是指在網絡通信中&#xff0c;用于特定服務或應用程序的端口&#xff0c;這些端口通常被設計為在網絡層面提供額外的安全性。安全端口的選擇和配置對于保護網絡資源免受未經授權的訪問和攻擊至關重要。 常見的安全端口及其用途 以下是一些常見…

提升內容分享類營銷效果的秘籍大公開

今天有豐富實戰經驗的“蚓鏈數字化營銷平臺”來給大家分享一些能有效提高內容分享類數字化營銷方案中用戶的參與度和轉化率的方法。 創造有價值且引人入勝的內容 一定要讓分享的內容實用、有趣或者獨特&#xff0c;滿足大家的需求和興趣。多運用生動的故事、案例和數據來支持觀…