import numpy as np
import pandas as pd
def calEnt(dataSet) :
n = dataSet.shape[0]
iset = dataSet.iloc[: , -1] . value_counts()
p = iset/n
ent = (-p*np.log2(p)).sum()
return ent
def createDataSet() :
row_data = { 'no surfacing' : [ 1, 1, 1,0,0] , 'flippers' : [1, 1, 0,1,1] , 'fish' : [ 'yes' , 'yes' , 'no' , 'no' , 'no']}
dataSet = pd.DataFrame(row_data)
return dataSet
dataSet = createDataSet()
print(calEnt(dataSet))
def bestSplit(dataSet) :
baseEnt = calEnt(dataSet)
bestGain = 0
axis = -1
for i in range(dataSet.shape[1]-1):
levels= dataSet.iloc[: , i ] . value_counts().index
ents = 0
for j in levels:
childSet = dataSet[dataSet.iloc[: , i ] ==j]
ent = calEnt(childSet)
ents += (childSet.shape[0]/dataSet.shape[0])*ent
infoGain = baseEnt-ents
if (infoGain > bestGain):
bestGain = infoGain
axis = i
return axis
print(bestSplit(dataSet))
def mySplit(dataSet,axis,value):
col = dataSet.columns[axis]
redataSet = dataSet.loc[dataSet[col]==value, : ] . drop(col , axis=1)
return redataSet
print(mySplit(dataSet,0,1))
def createTree(dataSet):
featlist = list(dataSet.columns)
classlist = dataSet.iloc[: , -1] . value_counts()
if classlist[0]==dataSet.shape[0] or dataSet.shape[1] == 1:
return classlist.index[0]
axis = bestSplit(dataSet)
bestfeat = featlist[axis]
myTree = {bestfeat:{}}
del featlist[axis]
valuelist = set(dataSet.iloc[: , axis])
for value in valuelist:
myTree[bestfeat] [value] = createTree(mySplit(dataSet,axis,value))
return myTree
np.save('myTree.npy' , createTree(dataSet))
read_myTree = np.load('myTree.npy',allow_pickle=True).item()
print(read_myTree)
def classify(inputTree,labels, testVec):
firstStr = next(iter(inputTree))
secondDict = inputTree[firstStr]
featIndex = labels.index(firstStr)
for key in secondDict.keys():
if testVec[featIndex] == key:
if type(secondDict[key]) == dict :
classLabel = classify(secondDict[key] , labels, testVec)
else:
classLabel = secondDict[key]
return classLabel
def acc_classify(train,test) :
inputTree = createTree(train)
labels = list(train.columns)
result = []
for i in range(test.shape[0]) :
testVec = test.iloc[i , : -1]
classLabel = classify(inputTree,labels,testVec)
result.append(classLabel)
test['predict']=result
acc = (test.iloc[: , -1]==test.iloc[: , -2]) . mean()
print(f' 模型预测准确率为 {acc}')
return test
train = dataSet
test = dataSet.iloc[:3, : ]
acc_classify(train,test)