招聘網(wǎng)站源碼下載色盲測試圖
任務(wù)描述
本關(guān)任務(wù):使用決策樹進行分類
相關(guān)知識
為了完成本關(guān)任務(wù),你需要掌握:1.使用決策樹進行分類
使用決策樹進行分類
依靠訓練數(shù)據(jù)構(gòu)造了決策樹之后,我們可以將它用于實際數(shù)據(jù)的分類。在執(zhí)行數(shù)據(jù)分類時,需要決策樹以及用于構(gòu)造樹的標簽向量。然后,程序比較測試數(shù)據(jù)與決策樹上的數(shù)值,遞歸執(zhí)行該過程直到進人葉子節(jié)點;最后將測試數(shù)據(jù)定義為葉子節(jié)點所屬的類型。 使用決策樹的分類函數(shù)如下:
"""
Parameters:
inputTree - 已經(jīng)生成的決策樹
featLabels - 存儲選擇的最優(yōu)特征標簽
testVec - 測試數(shù)據(jù)列表,順序?qū)?yīng)最優(yōu)特征標簽
Returns:
classLabel - 分類結(jié)果
"""
# 函數(shù)說明:使用決策樹分類
def classify(inputTree, featLabels, testVec):
firstStr = next(iter(inputTree)) #獲取決策樹結(jié)點
secondDict = inputTree[firstStr] #下一個字典
featIndex = featLabels.index(firstStr)
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
編程要求
根據(jù)提示,在右側(cè)編輯器補充代碼,運用決策樹分類
測試說明
平臺會對你編寫的代碼進行測試:
開始你的任務(wù)吧,祝你成功!
完整代碼如下:
# -*- coding: UTF-8 -*-
from math import log
import operator"""
Parameters:dataSet - 數(shù)據(jù)集
Returns:shannonEnt - 經(jīng)驗熵(香農(nóng)熵)
"""
# 函數(shù)說明:計算給定數(shù)據(jù)集的經(jīng)驗熵(香農(nóng)熵)
def calcShannonEnt(dataSet):numEntires = len(dataSet) #返回數(shù)據(jù)集的行數(shù)labelCounts = {} #保存每個標簽(Label)出現(xiàn)次數(shù)的字典for featVec in dataSet: #對每組特征向量進行統(tǒng)計currentLabel = featVec[-1] #提取標簽(Label)信息if currentLabel not in labelCounts.keys(): #如果標簽(Label)沒有放入統(tǒng)計次數(shù)的字典,添加進去labelCounts[currentLabel] = 0labelCounts[currentLabel] += 1 #Label計數(shù)shannonEnt = 0.0 #經(jīng)驗熵(香農(nóng)熵)for key in labelCounts: #計算香農(nóng)熵prob = float(labelCounts[key]) / numEntires#選擇該標簽(Label)的概率shannonEnt -= prob * log(prob, 2) #利用公式計算return shannonEnt #返回經(jīng)驗熵(香農(nóng)熵)"""
Parameters:無
Returns:dataSet - 數(shù)據(jù)集labels - 特征標簽
"""
# 函數(shù)說明:創(chuàng)建測試數(shù)據(jù)集
def createDataSet():dataSet = [[0, 0, 0, 0, 'no'],#數(shù)據(jù)集[0, 0, 0, 1, 'no'],[0, 1, 0, 1, 'yes'],[0, 1, 1, 0, 'yes'],[0, 0, 0, 0, 'no'],[1, 0, 0, 0, 'no'],[1, 0, 0, 1, 'no'],[1, 1, 1, 1, 'yes'],[1, 0, 1, 2, 'yes'],[1, 0, 1, 2, 'yes'],[2, 0, 1, 2, 'yes'],[2, 0, 1, 1, 'yes'],[2, 1, 0, 1, 'yes'],[2, 1, 0, 2, 'yes'],[2, 0, 0, 0, 'no']]labels = ['年齡', '有工作', '有自己的房子', '信貸情況']#特征標簽return dataSet, labels#返回數(shù)據(jù)集和分類屬性"""
Parameters:dataSet - 待劃分的數(shù)據(jù)集axis - 劃分數(shù)據(jù)集的特征value - 需要返回的特征的值
Returns:無
"""
# 函數(shù)說明:按照給定特征劃分數(shù)據(jù)集
def splitDataSet(dataSet, axis, value):retDataSet = [] #創(chuàng)建返回的數(shù)據(jù)集列表for featVec in dataSet: #遍歷數(shù)據(jù)集if featVec[axis] == value:reducedFeatVec = featVec[:axis] #去掉axis特征reducedFeatVec.extend(featVec[axis+1:])#將符合條件的添加到返回的數(shù)據(jù)集retDataSet.append(reducedFeatVec)return retDataSet #返回劃分后的數(shù)據(jù)集"""
Parameters:dataSet - 數(shù)據(jù)集
Returns:bestFeature - 信息增益最大的(最優(yōu))特征的索引值
"""
# 函數(shù)說明:選擇最優(yōu)特征
def chooseBestFeatureToSplit(dataSet):numFeatures = len(dataSet[0]) - 1 #特征數(shù)量baseEntropy = calcShannonEnt(dataSet) #計算數(shù)據(jù)集的香農(nóng)熵bestInfoGain = 0.0 #信息增益bestFeature = -1 #最優(yōu)特征的索引值for i in range(numFeatures): #遍歷所有特征#獲取dataSet的第i個所有特征featList = [example[i] for example in dataSet]uniqueVals = set(featList) #創(chuàng)建set集合{},元素不可重復newEntropy = 0.0 #經(jīng)驗條件熵for value in uniqueVals: #計算信息增益subDataSet = splitDataSet(dataSet, i, value) #subDataSet劃分后的子集prob = len(subDataSet) / float(len(dataSet)) #計算子集的概率newEntropy += prob * calcShannonEnt(subDataSet)#根據(jù)公式計算經(jīng)驗條件熵infoGain = baseEntropy - newEntropy #信息增益# print("第%d個特征的增益為%.3f" % (i, infoGain)) #打印每個特征的信息增益if (infoGain > bestInfoGain): #計算信息增益bestInfoGain = infoGain #更新信息增益,找到最大的信息增益bestFeature = i #記錄信息增益最大的特征的索引值return bestFeature #返回信息增益最大的特征的索引值"""
Parameters:classList - 類標簽列表
Returns:sortedClassCount[0][0] - 出現(xiàn)此處最多的元素(類標簽)
"""
# 函數(shù)說明:統(tǒng)計classList中出現(xiàn)此處最多的元素(類標簽)
def majorityCnt(classList):classCount = {}for vote in classList: #統(tǒng)計classList中每個元素出現(xiàn)的次數(shù)if vote not in classCount.keys():classCount[vote] = 0classCount[vote] += 1sortedClassCount = sorted(classCount.items(), key = operator.itemgetter(1), reverse = True)#根據(jù)字典的值降序排序return sortedClassCount[0][0] #返回classList中出現(xiàn)次數(shù)最多的元素"""
Parameters:dataSet - 訓練數(shù)據(jù)集labels - 分類屬性標簽featLabels - 存儲選擇的最優(yōu)特征標簽
Returns:myTree - 決策樹
"""
# 函數(shù)說明:創(chuàng)建決策樹
def createTree(dataSet, labels, featLabels):classList = [example[-1] for example in dataSet] #取分類標簽(是否放貸:yes or no)if classList.count(classList[0]) == len(classList): #如果類別完全相同則停止繼續(xù)劃分return classList[0]if len(dataSet[0]) == 1: #遍歷完所有特征時返回出現(xiàn)次數(shù)最多的類標簽return majorityCnt(classList)bestFeat = chooseBestFeatureToSplit(dataSet) #選擇最優(yōu)特征bestFeatLabel = labels[bestFeat] #最優(yōu)特征的標簽featLabels.append(bestFeatLabel)myTree = {bestFeatLabel:{}} #根據(jù)最優(yōu)特征的標簽生成樹del(labels[bestFeat]) #刪除已經(jīng)使用特征標簽featValues = [example[bestFeat] for example in dataSet]#得到訓練集中所有最優(yōu)特征的屬性值uniqueVals = set(featValues) #去掉重復的屬性值for value in uniqueVals: #遍歷特征,創(chuàng)建決策樹。myTree[bestFeatLabel][value] = createTree(splitDataSet(dataSet, bestFeat, value), labels, featLabels)return myTree"""
Parameters:inputTree - 已經(jīng)生成的決策樹featLabels - 存儲選擇的最優(yōu)特征標簽testVec - 測試數(shù)據(jù)列表,順序?qū)?yīng)最優(yōu)特征標簽
Returns:classLabel - 分類結(jié)果
"""
# 函數(shù)說明:使用決策樹分類
def classify(inputTree, featLabels, testVec):firstStr = next(iter(inputTree)) #獲取決策樹結(jié)點secondDict = inputTree[firstStr] #下一個字典featIndex = featLabels.index(firstStr)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 classLabelif __name__ == '__main__':##########請輸入你的代碼dataSet, labels = createDataSet() #得到數(shù)據(jù)集featLabels = []myTree = createTree(dataSet, labels, featLabels) #創(chuàng)造樹testVec = [0,1] #測試數(shù)據(jù)result = classify(myTree, featLabels, testVec) #進行分類#########if result == 'yes':print('放貸')if result == 'no':print('不放貸')