決策樹①——信息熵&信息增益&基尼系數
決策樹②——決策樹算法原理(ID3,C4.5,CART)
決策樹③——決策樹參數介紹(分類和回歸)
決策樹④——決策樹Sklearn調參(GridSearchCV調參及過程做圖)
決策樹應用實例①——泰坦尼克號分類
決策樹應用實例②——用戶流失預測模型
決策樹應用實例③——銀行借貸模型
上一篇總結了Sklearn庫用GridSearchCV調參的過程,今天用python依據現代女生的審美創建一顆簡單的決策樹,看下是否能代表大眾的心聲~~
from math import log
import operator
def calcShannonEnt(dataset):
numEntries = len(dataset) # 輸入樣本個數
labelCounts = {} # 存類別及相應的數量
for featVec in dataset: # 一行即是一個特征向量
currentLable = featVec[-1] # 取每個樣本的類別
if currentLable not in labelCounts.keys():# 如果變量已經有類別,則在數量上+1,如果沒有,則先新建一個再+1
labelCounts[currentLable] = 0
labelCounts[currentLable] += 1
shannoEnt = 0
for key in labelCounts:
prob = float(labelCounts[key])/float(numEntries)
shannoEnt += -prob*log(prob, 2) # 計算所有樣本的信息熵
return shannoEnt
def creaDataSet1():
dataSet = [['高', '富', '帥','同意'],
['高', '富', '丑','同意'],
['高', '窮', '丑','同意'],
['高', '窮', '帥','同意'],
['矮', '窮', '帥','拒絕'],
['矮', '富', '帥', '同意'],
['矮', '窮', '丑', '拒絕'],
['矮', '富', '丑', '拒絕']]
labels = ['身高', '財富', '外貌']
return dataSet, labels
def splitDataSet(dataSet, axis, value):
retDataset = []
for feaVec in dataSet: # 迭代每一個樣本
if feaVec[axis] == value: # 如果樣本的這個特征值=要求的值
reducedFeatVec = feaVec[:axis] # 取這個樣本的前N個特征,直到篩選的這個特征
reducedFeatVec.extend(feaVec[axis+1:]) #拼接這個特征之后的所有特征值,相當于去掉這個特征
retDataset.append(reducedFeatVec) # 給出按這個特征值分類后的剩余特征
return retDataset
def chooseBestFeatureToSplit(dataset):
numFeatures = len(dataset[0]) - 1 #特征個數
baseEntropy = calcShannonEnt(dataset) # 計算信息熵
bestInfoGain = 0
bestFeature = -1
for i in range(numFeatures):# 迭代每一個特征
featList = [example[i] for example in dataset] # 找出這個特征的所有屬性值
uniqueVals = set(featList) # 這個特征的唯一屬性值
newEntropy = 0
for value in uniqueVals:
subDataset = splitDataSet(dataset, i, value) # 按這個特征這個屬性值分類后的子集
prob = float(len(subDataset))/float(len(dataset)) # 子集在全樣本集中的概率
newEntropy += prob*calcShannonEnt(subDataset) # 計算按這個特征這個屬性分裂后的信息熵,直接迭代完這個特征所有的屬性值,得到按這個特征分裂后所有的條件熵
infoGain = baseEntropy - newEntropy # 計算信息增益
if (infoGain>bestInfoGain):
bestInfoGain = infoGain # 最佳的信息增益
bestFeature = i # 最佳的特征
return bestFeature
def majorityCnt(classList):
classCount = {}
for vote in classList: # 對提供的樣本類別列表進行計數
if vote not in classCount.keys():
classCount[vote] = 0
classCount[vote] += 1
sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True) # 倒排,找到個數最多的樣品類別,則為這個節點的類別
return sortedClassCount[0][0]
def createTree(dataset, labels):
classList = [example[-1] for example in dataset] # 得到所有樣本的類別
if classList.count(classList[0]) == len(classList): # 如果樣本都是一個類別,則直接按這個類別就行了
return classList[0]
if len(dataset[0]) == 1: # 如果只剩下一個特征,?
return majorityCnt(classList)
bestFeat = chooseBestFeatureToSplit(dataset) # 篩選最佳的特征
print(labels) # 對應的特征名
bestFeatLabel = labels[bestFeat] # 得到最佳的特征名
myTree = {bestFeatLabel:{}}
del (labels[bestFeat]) # 刪除已經用于分裂的特征
featValues = [example[bestFeat] for example in dataset] # 按此特征的所有特征值
uniqueVals = set(featValues) # 特征值的唯一
for value in uniqueVals:
subLablels = labels[:] # 剩余可以用于分裂的特征
print('sub"', subLablels)
myTree[bestFeatLabel][value] = createTree(splitDataSet(dataset, bestFeat, value), subLablels)
# 先按最優特征值的某一個屬性分裂,得到子集,對子集再找最優特征分裂,直到全部類別一樣,或者已經沒有特征可選時采用最大投票法得出分類結果;迭代的結果全部依次存入mytree字典中
return myTree
if __name__ == '__main__':
dataSet, labels = creaDataSet1()
map = createTree(dataSet, labels)
print(map)
從結果看出,女生在身高,財富和外貌中,最重視的還是身高,如果身高較高,不會在意其它2個條件,如果身高不高,則會再看財富,如果有錢且長得還行,能接受,如果有錢但長得不好則拒絕,如果沒錢則直接拒絕。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
