我們的目的已經(jīng)很明確了宏榕,就是依次遍歷每一個特征,在這里我們的特征只有兩個蒙秒,就是需不需要浮出水面,有沒有腳蹼宵统。然后計算出根據(jù)每一個特征劃分產(chǎn)生的數(shù)據(jù)集的熵晕讲,和初始的數(shù)據(jù)集的熵比較,我們找出和初始數(shù)據(jù)集差距最大的马澈。那么這個特征就是我們劃分時最合適的分類特征瓢省。
def chooseBestFeatureToSplit(dataSet):
numFeatures = len(dataSet[0])-1 # 獲取我們樣本集中的某一個樣本的特征數(shù)(因為每一個樣本的特征數(shù)是相同的,相當(dāng)于這個代碼就是我們可以作為分類依據(jù)的所有特征個數(shù))我們的樣本最后一列是樣本所屬的類別痊班,所以要減去類別信息勤婚,在我們的例子中特征數(shù)就是2
baseEntropy = calcShannonEnt(dataSet) #計算樣本的初始香農(nóng)熵
bestInfoGain =0.0 #初始化最大信息增益
bestFeature = -1 #和最佳劃分特征
for i in range(numFeatures): # range(2)那么i的取值就是0,1。 在這里i表示的我們的第幾個特征
featList = [sample[i] for sample in dataSet]
# 我們首先遍歷整個數(shù)據(jù)集涤伐,首先得到第一個特征值可能的取值馒胆,然后把它賦值給一個鏈表,我們第一個特征值取值是[1,1,1,0,0],其實只有【1,0】兩個取值
uniqueVals = set(featList)#我們使用集合這個數(shù)據(jù)類型刪除多余重復(fù)的原始使得其中只有唯一的值凝果。
#執(zhí)行的結(jié)果如下所示:
In [8]: featList=[1,1,1,0,0]
In [9]: uniqueVals=set(featList)
In [10]: uniqueVals
Out[10]: {0, 1}
newEntropy = 0.0
for value in uniqueVals: #uniqueVals中保存的是我們某個樣本的特征值的所有的取值的可能性
subDataSet = splitDataSet(dataSet,i,value)
# 在這里劃分數(shù)據(jù)集国章,比如說第一個特征的第一個取值得到一個子集,第一個特征的特征又會得到另一個特征豆村。當(dāng)然這是第二次循環(huán)
prob = len(subDataSet)/float(len(dataSet))#我們以第一個特征來說明液兽,根據(jù)第一個特征可能的取值劃分出來的子集的概率
newEntropy += prob * calcShannonEnt(subDataSet)# 這里比較難理解我們下面在詳細說明
infoGain = baseEntropy - newEntropy # 計算出信息增益
#找出最佳信息增益,是個學(xué)計算機的小朋友都懂吧掌动,哨兵法
if(infoGain > bestInfoGain):
bestInfoGain = infoGain
bestFeature = i
return bestFeature