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