欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

python實(shí)現(xiàn)ID3決策樹(shù)算法

 更新時(shí)間:2021年10月29日 09:41:55   作者:zhihua_oba  
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)ID3決策樹(shù)算法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

決策樹(shù)之ID3算法及其Python實(shí)現(xiàn),具體內(nèi)容如下

主要內(nèi)容

決策樹(shù)背景知識(shí)
決策樹(shù)一般構(gòu)建過(guò)程
ID3算法分裂屬性的選擇
ID3算法流程及其優(yōu)缺點(diǎn)分析
ID3算法Python代碼實(shí)現(xiàn)

1. 決策樹(shù)背景知識(shí)

  決策樹(shù)是數(shù)據(jù)挖掘中最重要且最常用的方法之一,主要應(yīng)用于數(shù)據(jù)挖掘中的分類(lèi)和預(yù)測(cè)。決策樹(shù)是知識(shí)的一種呈現(xiàn)方式,決策樹(shù)中從頂點(diǎn)到每個(gè)結(jié)點(diǎn)的路徑都是一條分類(lèi)規(guī)則。決策樹(shù)算法最先基于信息論發(fā)展起來(lái),經(jīng)過(guò)幾十年發(fā)展,目前常用的算法有:ID3、C4.5、CART算法等。

2. 決策樹(shù)一般構(gòu)建過(guò)程

  構(gòu)建決策樹(shù)是一個(gè)自頂向下的過(guò)程。樹(shù)的生長(zhǎng)過(guò)程是一個(gè)不斷把數(shù)據(jù)進(jìn)行切分細(xì)分的過(guò)程,每一次切分都會(huì)產(chǎn)生一個(gè)數(shù)據(jù)子集對(duì)應(yīng)的節(jié)點(diǎn)。從包含所有數(shù)據(jù)的根節(jié)點(diǎn)開(kāi)始,根據(jù)選取分裂屬性的屬性值把訓(xùn)練集劃分成不同的數(shù)據(jù)子集,生成由每個(gè)訓(xùn)練數(shù)據(jù)子集對(duì)應(yīng)新的非葉子節(jié)點(diǎn)。對(duì)生成的非葉子節(jié)點(diǎn)再重復(fù)以上過(guò)程,直到滿(mǎn)足特定的終止條件,停止對(duì)數(shù)據(jù)子集劃分,生成數(shù)據(jù)子集對(duì)應(yīng)的葉子節(jié)點(diǎn),即所需類(lèi)別。測(cè)試集在決策樹(shù)構(gòu)建完成后檢驗(yàn)其性能。如果性能不達(dá)標(biāo),我們需要對(duì)決策樹(shù)算法進(jìn)行改善,直到達(dá)到預(yù)期的性能指標(biāo)。
  注:分裂屬性的選取是決策樹(shù)生產(chǎn)過(guò)程中的關(guān)鍵,它決定了生成的決策樹(shù)的性能、結(jié)構(gòu)。分裂屬性選擇的評(píng)判標(biāo)準(zhǔn)是決策樹(shù)算法之間的根本區(qū)別。

3. ID3算法分裂屬性的選擇——信息增益

  屬性的選擇是決策樹(shù)算法中的核心。是對(duì)決策樹(shù)的結(jié)構(gòu)、性能起到?jīng)Q定性的作用。ID3算法基于信息增益的分裂屬性選擇?;谛畔⒃鲆娴膶傩赃x擇是指以信息熵的下降速度作為選擇屬性的方法。它以的信息論為基礎(chǔ),選擇具有最高信息增益的屬性作為當(dāng)前節(jié)點(diǎn)的分裂屬性。選擇該屬性作為分裂屬性后,使得分裂后的樣本的信息量最大,不確定性最小,即熵最小。
  信息增益的定義為變化前后熵的差值,而熵的定義為信息的期望值,因此在了解熵和信息增益之前,我們需要了解信息的定義。
  信息:分類(lèi)標(biāo)簽xi 在樣本集 S 中出現(xiàn)的頻率記為 p(xi),則 xi 的信息定義為:−log2p(xi) 。
  分裂之前樣本集的熵:E(S)=−∑Ni=1p(xi)log2p(xi),其中 N 為分類(lèi)標(biāo)簽的個(gè)數(shù)。
  通過(guò)屬性A分裂之后樣本集的熵:EA(S)=−∑mj=1|Sj||S|E(Sj),其中 m 代表原始樣本集通過(guò)屬性A的屬性值劃分為 m 個(gè)子樣本集,|Sj| 表示第j個(gè)子樣本集中樣本數(shù)量,|S| 表示分裂之前數(shù)據(jù)集中樣本總數(shù)量。
  通過(guò)屬性A分裂之后樣本集的信息增益:InfoGain(S,A)=E(S)−EA(S)
  注:分裂屬性的選擇標(biāo)準(zhǔn)為:分裂前后信息增益越大越好,即分裂后的熵越小越好。

4. ID3算法

  ID3算法是一種基于信息增益屬性選擇的決策樹(shù)學(xué)習(xí)方法。核心思想是:通過(guò)計(jì)算屬性的信息增益來(lái)選擇決策樹(shù)各級(jí)節(jié)點(diǎn)上的分裂屬性,使得在每一個(gè)非葉子節(jié)點(diǎn)進(jìn)行測(cè)試時(shí),獲得關(guān)于被測(cè)試樣本最大的類(lèi)別信息?;痉椒ㄊ牵河?jì)算所有的屬性,選擇信息增益最大的屬性分裂產(chǎn)生決策樹(shù)節(jié)點(diǎn),基于該屬性的不同屬性值建立各分支,再對(duì)各分支的子集遞歸調(diào)用該方法建立子節(jié)點(diǎn)的分支,直到所有子集僅包括同一類(lèi)別或沒(méi)有可分裂的屬性為止。由此得到一棵決策樹(shù),可用來(lái)對(duì)新樣本數(shù)據(jù)進(jìn)行分類(lèi)。

ID3算法流程:

(1) 創(chuàng)建一個(gè)初始節(jié)點(diǎn)。如果該節(jié)點(diǎn)中的樣本都在同一類(lèi)別,則算法終止,把該節(jié)點(diǎn)標(biāo)記為葉節(jié)點(diǎn),并用該類(lèi)別標(biāo)記。
(2) 否則,依據(jù)算法選取信息增益最大的屬性,該屬性作為該節(jié)點(diǎn)的分裂屬性。
(3) 對(duì)該分裂屬性中的每一個(gè)值,延伸相應(yīng)的一個(gè)分支,并依據(jù)屬性值劃分樣本。
(4) 使用同樣的過(guò)程,自頂向下的遞歸,直到滿(mǎn)足下面三個(gè)條件中的一個(gè)時(shí)就停止遞歸。
  A、待分裂節(jié)點(diǎn)的所有樣本同屬于一類(lèi)。
  B、訓(xùn)練樣本集中所有樣本均完成分類(lèi)。
  C、所有屬性均被作為分裂屬性執(zhí)行一次。若此時(shí),葉子結(jié)點(diǎn)中仍有屬于不同類(lèi)別的樣本時(shí),選取葉子結(jié)點(diǎn)中包含樣本最多的類(lèi)別,作為該葉子結(jié)點(diǎn)的分類(lèi)。

ID3算法優(yōu)缺點(diǎn)分析

優(yōu)點(diǎn):構(gòu)建決策樹(shù)的速度比較快,算法實(shí)現(xiàn)簡(jiǎn)單,生成的規(guī)則容易理解。
缺點(diǎn):在屬性選擇時(shí),傾向于選擇那些擁有多個(gè)屬性值的屬性作為分裂屬性,而這些屬性不一定是最佳分裂屬性;不能處理屬性值連續(xù)的屬性;無(wú)修剪過(guò)程,無(wú)法對(duì)決策樹(shù)進(jìn)行優(yōu)化,生成的決策樹(shù)可能存在過(guò)度擬合的情況。

5. ID3算法Python代碼實(shí)現(xiàn)

# -*- coding: utf-8 -*-
__author__ = 'zhihua_oba'

import operator
from numpy import *
from math import log

#文件讀取
def file2matrix(filename, attribute_num): #傳入?yún)?shù):文件名,屬性個(gè)數(shù)
 fr = open(filename)
 arrayOLines = fr.readlines()
 numberOfLines = len(arrayOLines) #統(tǒng)計(jì)數(shù)據(jù)集行數(shù)(樣本個(gè)數(shù))
 dataMat = zeros((numberOfLines, attribute_num))
 classLabelVector = [] #分類(lèi)標(biāo)簽
 index = 0
 for line in arrayOLines:
  line = line.strip() #strip() 刪除字符串中的'\n'
  listFromLine = line.split() #將一個(gè)字符串分裂成多個(gè)字符串組成的列表,不帶參數(shù)時(shí)以空格進(jìn)行分割,當(dāng)代參數(shù)時(shí),以該參數(shù)進(jìn)行分割
  dataMat[index, : ] = listFromLine[0:attribute_num] #讀取數(shù)據(jù)對(duì)象屬性值
  classLabelVector.append(listFromLine[-1]) #讀取分類(lèi)信息
  index += 1
 dataSet = [] #數(shù)組轉(zhuǎn)化成列表
 index = 0
 for index in range(0, numberOfLines):
  temp = list(dataMat[index, :])
  temp.append(classLabelVector[index])
  dataSet.append(temp)
 return dataSet

#劃分?jǐn)?shù)據(jù)集
def splitDataSet(dataSet, axis, value):
 retDataSet = []
 for featvec in dataSet: #每行
  if featvec[axis] == value: #每行中第axis個(gè)元素和value相等 #刪除對(duì)應(yīng)的元素,并將此行,加入到rerDataSet
   reducedFeatVec = featvec[:axis]
   reducedFeatVec.extend(featvec[axis+1:])
   retDataSet.append(reducedFeatVec)
 return retDataSet

#計(jì)算香農(nóng)熵 #計(jì)算數(shù)據(jù)集的香農(nóng)熵 == 計(jì)算數(shù)據(jù)集類(lèi)標(biāo)簽的香農(nóng)熵
def calcShannonEnt(dataSet):
 numEntries = len(dataSet) #數(shù)據(jù)集樣本點(diǎn)個(gè)數(shù)
 labelCounts = {} #類(lèi)標(biāo)簽
 for featVec in dataSet: #統(tǒng)計(jì)數(shù)據(jù)集類(lèi)標(biāo)簽的個(gè)數(shù),字典形式
  currentLabel = featVec[-1]
  if currentLabel not in labelCounts.keys():
   labelCounts[currentLabel] = 0
  labelCounts[currentLabel] += 1
 shannonEnt = 0.0
 for key in labelCounts:
  prob = float(labelCounts[key])/numEntries
  shannonEnt -= prob * log(prob, 2)
 return shannonEnt

#根據(jù)香農(nóng)熵,選擇最優(yōu)的劃分方式 #根據(jù)某一屬性劃分后,類(lèi)標(biāo)簽香農(nóng)熵越低,效果越好
def chooseBestFeatureToSplit(dataSet):
 baseEntropy = calcShannonEnt(dataSet) #計(jì)算數(shù)據(jù)集的香農(nóng)熵
 numFeatures = len(dataSet[0])-1
 bestInfoGain = 0.0 #最大信息增益
 bestFeature = 0 #最優(yōu)特征
 for i in range(0, numFeatures):
  featList = [example[i] for example in dataSet] #所有子列表(每行)的第i個(gè)元素,組成一個(gè)新的列表
  uniqueVals = set(featList)
  newEntorpy = 0.0
  for value in uniqueVals: #數(shù)據(jù)集根據(jù)第i個(gè)屬性進(jìn)行劃分,計(jì)算劃分后數(shù)據(jù)集的香農(nóng)熵
   subDataSet = splitDataSet(dataSet, i, value)
   prob = len(subDataSet)/float(len(dataSet))
   newEntorpy += prob*calcShannonEnt(subDataSet)
  infoGain = baseEntropy-newEntorpy #劃分后的數(shù)據(jù)集,香農(nóng)熵越小越好,即信息增益越大越好
  if(infoGain > bestInfoGain):
   bestInfoGain = infoGain
   bestFeature = i
 return bestFeature

#如果數(shù)據(jù)集已經(jīng)處理了所有屬性,但葉子結(jié)點(diǎn)中類(lèi)標(biāo)簽依然不是唯一的,此時(shí)需要決定如何定義該葉子結(jié)點(diǎn)。這種情況下,采用多數(shù)表決方法,對(duì)該葉子結(jié)點(diǎn)進(jìn)行分類(lèi)
def majorityCnt(classList): #傳入?yún)?shù):葉子結(jié)點(diǎn)中的類(lèi)標(biāo)簽
 classCount = {}
 for vote in classList:
  if vote not in classCount.keys():
   classCount[vote] = 0
   classCount[vote] += 1
 sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True)
 return sortedClassCount[0][0]

#創(chuàng)建樹(shù)
def createTree(dataSet, labels): #傳入?yún)?shù):數(shù)據(jù)集,屬性標(biāo)簽(屬性標(biāo)簽作用:在輸出結(jié)果時(shí),決策樹(shù)的構(gòu)建更加清晰)
 classList = [example[-1] for example in dataSet] #數(shù)據(jù)集樣本的類(lèi)標(biāo)簽
 if classList.count(classList[0]) == len(classList): #如果數(shù)據(jù)集樣本屬于同一類(lèi),說(shuō)明該葉子結(jié)點(diǎn)劃分完畢
  return classList[0]
 if len(dataSet[0]) == 1: #如果數(shù)據(jù)集樣本只有一列(該列是類(lèi)標(biāo)簽),說(shuō)明所有屬性都劃分完畢,則根據(jù)多數(shù)表決方法,對(duì)該葉子結(jié)點(diǎn)進(jìn)行分類(lèi)
  return majorityCnt(classList)
 bestFeat = chooseBestFeatureToSplit(dataSet) #根據(jù)香農(nóng)熵,選擇最優(yōu)的劃分方式
 bestFeatLabel = labels[bestFeat] #記錄該屬性標(biāo)簽
 myTree = {bestFeatLabel:{}} #樹(shù)
 del(labels[bestFeat]) #在屬性標(biāo)簽中刪除該屬性
 #根據(jù)最優(yōu)屬性構(gòu)建樹(shù)
 featValues = [example[bestFeat] for example in dataSet]
 uniqueVals = set(featValues)
 for value in uniqueVals:
  subLabels = labels[:]
  subDataSet = splitDataSet(dataSet, bestFeat, value)
  myTree[bestFeatLabel][value] = createTree(subDataSet, subLabels)
 return myTree

#測(cè)試算法:使用決策樹(shù),對(duì)待分類(lèi)樣本進(jìn)行分類(lèi)
def classify(inputTree, featLabels, testVec): #傳入?yún)?shù):決策樹(shù),屬性標(biāo)簽,待分類(lèi)樣本
 firstStr = inputTree.keys()[0] #樹(shù)根代表的屬性
 secondDict = inputTree[firstStr]
 featIndex = featLabels.index(firstStr) #樹(shù)根代表的屬性,所在屬性標(biāo)簽中的位置,即第幾個(gè)屬性
 for key in secondDict.keys():
  if testVec[featIndex] == key:
   if type(secondDict[key]).__name__ == 'dict':
    classLabel = classify(secondDict[key], featLabels, testVec)
   else:
    classLabel = secondDict[key]
 return classLabel

def main():
 dataSet = file2matrix('test_sample.txt', 4)
 labels = ['attr01', 'attr02', 'attr03', 'attr04']
 labelsForCreateTree = labels[:]
 Tree = createTree(dataSet, labelsForCreateTree )
 testvec = [2, 3, 2, 3]
 print classify(Tree, labels, testvec)
if __name__ == '__main__':
  main()

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • python pandas庫(kù)的安裝和創(chuàng)建

    python pandas庫(kù)的安裝和創(chuàng)建

    這篇文章主要介紹了python pandas庫(kù)的安裝和創(chuàng)建,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-01-01
  • Python通過(guò)類(lèi)的組合模擬街道紅綠燈

    Python通過(guò)類(lèi)的組合模擬街道紅綠燈

    這篇文章主要介紹了Python通過(guò)類(lèi)的組合模擬街道紅綠燈,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09
  • python的構(gòu)建工具setup.py的方法使用示例

    python的構(gòu)建工具setup.py的方法使用示例

    本篇文章主要介紹了python的構(gòu)建工具setup.py的方法示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-10-10
  • Python Pandas 獲取列匹配特定值的行的索引問(wèn)題

    Python Pandas 獲取列匹配特定值的行的索引問(wèn)題

    這篇文章主要介紹了Python Pandas 獲取列匹配特定值的行的索引問(wèn)題,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-07-07
  • Python3爬蟲(chóng)學(xué)習(xí)之應(yīng)對(duì)網(wǎng)站反爬蟲(chóng)機(jī)制的方法分析

    Python3爬蟲(chóng)學(xué)習(xí)之應(yīng)對(duì)網(wǎng)站反爬蟲(chóng)機(jī)制的方法分析

    這篇文章主要介紹了Python3爬蟲(chóng)學(xué)習(xí)之應(yīng)對(duì)網(wǎng)站反爬蟲(chóng)機(jī)制的方法,結(jié)合實(shí)例形式分析了Python3模擬瀏覽器運(yùn)行來(lái)應(yīng)對(duì)反爬蟲(chóng)機(jī)制的相關(guān)操作技巧,需要的朋友可以參考下
    2018-12-12
  • 詳解Python GUI工具取色器

    詳解Python GUI工具取色器

    作為Python開(kāi)發(fā)者,你遲早都會(huì)用到圖形用戶(hù)界面來(lái)開(kāi)發(fā)應(yīng)用。本文將推薦Python GUI工具取色器的一些知識(shí),感興趣的朋友一起看看吧
    2021-06-06
  • python對(duì)文件目錄的操作方法實(shí)例總結(jié)

    python對(duì)文件目錄的操作方法實(shí)例總結(jié)

    這篇文章主要介紹了python對(duì)文件目錄的操作方法,結(jié)合實(shí)例形式總結(jié)分析了Python針對(duì)文件目錄相關(guān)的遍歷、刪除、移動(dòng)、查找等操作技巧,需要的朋友可以參考下
    2019-06-06
  • 使用Python編程分析火爆全網(wǎng)的魷魚(yú)游戲豆瓣影評(píng)

    使用Python編程分析火爆全網(wǎng)的魷魚(yú)游戲豆瓣影評(píng)

    本文來(lái)為大家介紹如何使用Python爬取影評(píng)的操作,主要是爬取《魷魚(yú)游戲》在豆瓣上的一些影評(píng),對(duì)數(shù)據(jù)做一些簡(jiǎn)單的分析,用數(shù)據(jù)的角度重新審視下這部劇,有需要的朋友可以借鑒參考下
    2021-10-10
  • 用Python實(shí)現(xiàn)一個(gè)簡(jiǎn)單的抽獎(jiǎng)小程序

    用Python實(shí)現(xiàn)一個(gè)簡(jiǎn)單的抽獎(jiǎng)小程序

    最近開(kāi)始學(xué)習(xí)python相關(guān)知識(shí),看最近有不少隨機(jī)抽獎(jiǎng)小程序,自己也做一個(gè)試試,下面這篇文章主要給大家介紹了關(guān)于如何利用Python實(shí)現(xiàn)一個(gè)簡(jiǎn)單的抽獎(jiǎng)小程序的相關(guān)資料,需要的朋友可以參考下
    2023-05-05
  • Python+OpenCV采集本地?cái)z像頭的視頻

    Python+OpenCV采集本地?cái)z像頭的視頻

    這篇文章主要為大家詳細(xì)介紹了Python+OpenCV采集本地?cái)z像頭的視頻,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-04-04

最新評(píng)論