Le code source GitHub ( https://github.com/fansking/Machine/blob/master/Machine/trees.py) dans
une variété d'attributs de choses, mais beaucoup de propriété ne détermine pas si c'était cette chose. Par exemple, certains chats sont velues, certains chats sont sans poils, pas tous les cheveux ne sont pas un chat ne peut pas décider. Ensuite , pour tant d'attributs, comment nous choisissons d'ici un ou plusieurs attributs comme un facteur décisif dans ce. Ici , nous devons introduire le concept de gain de l' entropie et l' information.
Lorsque l' on ajoute un attribut à une chose catégorie et attribut particulier de manière cohérente, par exemple, que ce soit pour augmenter les poissons peuvent vivre dans l'eau à nouveau, la plupart des poissons est oui, mais pas la plupart des poissons ne peuvent pas vivre dans l'eau. Ce ne sera pas séparé du poisson très bonne zone, peut apporter une bonne information de gain vie sous - marine. Alors , comment pouvons-nous trouver cette propriété?
C'est (tous les attributs ensemble des attentes d'information) - (valeur attendue d'une propriété pour supprimer les informations), plus la valeur alors il y a la plus grande influence sur la précision de la classification lorsque ce montant.
entropie de Shannon est calculée comme suit, où p (xi) est la caractéristique de fréquence de cette propriété apparaît.
Et une construction d'arbre de décision est disposé dans un des facteurs de l' ordre descendant vers le bas construits.
Voici une description d'une fonction d'une fonction:
def createDataSet():
dataSet = [[1, 1, 'yes'],
[1, 1, 'yes'],
[1, 0, 'no'],
[0, 1, 'no'],
[0, 1, 'no']]
labels = ['no surfacing','flippers']
#change to discrete values
return dataSet, labels
def calcShannonEnt(dataSet):
numEntries = len(dataSet)
labelCounts = {}
for featVec in dataSet: #the the number of unique elements and their occurance
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) #log base 2
return shannonEnt
La première fonction est ici pour construire un ensemble de données, il est notre prochain données. des données correspondant à la deuxième ligne de la première colonne de l'étiquette dans les deux données de caractéristiques, le dernier de ses catégories. La deuxième fonction est donnée à un ensemble de données pour calculer la valeur de l'entropie de Shannon.
def splitDataSet(dataSet, axis, value):
retDataSet = []
for featVec in dataSet:
if featVec[axis] == value:
reducedFeatVec = featVec[:axis] #chop out axis used for splitting
reducedFeatVec.extend(featVec[axis+1:])
retDataSet.append(reducedFeatVec)
return retDataSet
def chooseBestFeatureToSplit(dataSet):
numFeatures = len(dataSet[0]) - 1 #the last column is used for the labels
baseEntropy = calcShannonEnt(dataSet)
bestInfoGain = 0.0; bestFeature = -1
for i in range(numFeatures): #iterate over all the features
featList = [example[i] for example in dataSet]#create a list of all the examples of this feature
uniqueVals = set(featList) #get a set of unique values
newEntropy = 0.0
for value in uniqueVals:
subDataSet = splitDataSet(dataSet, i, value) #subDataSet是除去本次遍历的列的内容,我们需要得到他的长度,并根据长度求得权重系数
prob = len(subDataSet)/float(len(dataSet))
newEntropy += prob * calcShannonEnt(subDataSet)
infoGain = baseEntropy - newEntropy #calculate the info gain; ie reduction in entropy
if (infoGain > bestInfoGain): #compare this to the best gain so far
bestInfoGain = infoGain #if better than current best, set to best
bestFeature = i
return bestFeature #returns an integer
Voici la première fonction d'un ensemble de données, supprimer la colonne d'index spécifiée et retourne le sous-ensemble de données.
La deuxième fonction est un début à - dire à travers toutes les colonnes, le plus grand impact est le plus grand des données caractéristiques entropie change're calculée après la suppression regardant cette colonne, renvoie l'index correspondant aux caractéristiques des données.
def majorityCnt(classList):
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]
def createTree(dataSet,labels):
classList = [example[-1] for example in dataSet]
if classList.count(classList[0]) == len(classList): #当剩下的所有类别都相同时说明对于这个数据特征的值来讲就是对应这个分类的,已经是叶子结点无需递归,直接退出
return classList[0]#stop splitting when all of the classes are equal
if len(dataSet[0]) == 1: #即当没有更多特征时,一定到达了递归出口(叶子结点),对最后一个特征使用举手表决的方式,哪个对应的标签最多就选择哪个标签
return majorityCnt(classList)
bestFeat = chooseBestFeatureToSplit(dataSet)
bestFeatLabel = labels[bestFeat]
myTree = {bestFeatLabel:{}}
del(labels[bestFeat])
featValues = [example[bestFeat] for example in dataSet]
uniqueVals = set(featValues)
for value in uniqueVals:
subLabels = labels[:] #python是使用引用的方式来传递变量,所以直接用等号会导致同步变化,我们需要拷贝一份新的值给子标签
myTree[bestFeatLabel][value] = createTree(splitDataSet(dataSet, bestFeat, value),subLabels)#递归得到下一层内容
return myTree
La première fonction est à main levée, beaucoup d' explication
deuxième fonction est une structure arborescente récursif (dictionnaire), sont ajoutés à chaque donnée des caractéristiques les plus élevées d'impact.
Les résultats obtenus sont les suivants: