在學習機器學習的原始碼,記錄下對該**的理解。
1.1 計算資料集的熵
待分析的資料集列表如下,首先根據表3-1構建資料集。
原始碼如下:
def createdataset():
dataset = [[1, 1, 'yes'], #index=0,就是「不浮出水面是否可以生存」,index=1,就是「是否有腳蹼」,最後乙個是"是否魚類"
[1, 1, 'yes'],
[1, 0, 'no'],
[0, 1, 'no'],
[0, 1, 'no']]
labels = ['no su***cing','flippers']
#change to discrete values
return dataset, labels
這個比較簡單。
計算該資料集熵的原始碼:
def calcshannonent(dataset):
numentries = len(dataset)#該資料集長度,即有多少個資料,這裡等於5
labelcounts = {}#特徵結果字典,比如以index=2,對資料集進行分類,則labelcounts就是yes和no的個數統計,yes:2, no:3;這樣的字典。
for featvec in dataset: #the the number of unique elements and their occurance,逐行遍歷
currentlabel = featvec[-1]#取每個元素的倒數第乙個值,也就是index=2這一列
if currentlabel not in labelcounts.keys(): labelcounts[currentlabel] = 0#如果字典中,不包含當前特徵值,則字典中加入該特徵。
labelcounts[currentlabel] += 1#該特徵計數
shannonent = 0.0
for key in labelcounts:
prob = float(labelcounts[key])/numentries#分別計算yes和no 出現的概率,這裡分別為0.6,和0.4
shannonent -= prob * log(prob,2) #log base 2#根據計數公式,計算熵
return shannonent
1.2 根據特徵,劃分資料集
dataset就是資料集,axis就是選擇的特徵,value,就是對應特徵的值。
這個方法比較簡單,以上面的dataset為例,如果axis=0,就是選擇第一列特徵,即:"不浮出水面是否可以生存";這個特徵有兩個值,就是1和0,所以對應的value就是1和0;
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:])
return retdataset
如果分別執行執行以下**:
subdataset1 = splitdataset(dataset, 0, 1)
subdataset2= splitdataset(dataset, 0, 0)
分別得到結果是:
可見,這個方法就是根據特徵值的不同把資料集劃分子資料集。在這裡,就是根據特徵「不浮出水面是否可以生存」的值1和0,分成了兩個上圖兩個子集。
1.3 選擇最佳分類特徵
當我們拿到乙個資料集,需要用決策樹進行分類是,我們如何從眾多特徵中選擇乙個特徵,作為決策樹的第乙個分類點呢?比如上述「不浮出水面是否可以生存」 和「是否有腳蹼」這兩個特徵,我們應該先選哪個特徵進行分類呢?
這就需要用到1.1和1.2的分類方法。
def choosebestfeaturetosplit(dataset):
numfeatures = len(dataset[0]) - 1 #the last column is used for the labels 計算特徵個數,這個例子中等於2
baseentropy = calcshannonent(dataset)#計算原始資料集的熵
bestinfogain = 0.0; bestfeature = -1
for i in range(numfeatures): #iterate over all the features,根據特徵進行迭代,從index=0,到1;
#獲取index=0的特徵對應的所有值,即取dataset矩陣每列的所有值。
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,統計每個特徵對應的值有多少可能,比如這裡index=0的特徵,只有兩個值0,1
newentropy = 0.0
for value in uniquevals:
subdataset = splitdataset(dataset, i, value)#針對每個特徵,劃分子集
#比如對index=0的特徵進行子集劃分,特徵值為0的有2個,為1的有3個;權重分別為2/5, 3/5
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
綜合來說,就是根據特徵值,進行分類,計算每個分類之後熵值的大小,然後進行排序,熵值越小,分類越合理。
就優先以該特徵值進行劃分。
python原始碼解析
demo資料夾裡放的是一些例子 doc資料夾裡放的是文件,grammer是語法分析器,include是python所包含的一些標頭檔案,lib是python的庫,都是用python語言寫的,moduels是用c寫的python模組,parser是分詞器。是最生動的文字,現在我來附上我所理解的pyth...
《機器學習實戰》原始碼解析(九) PCA
from numpy import import matplotlib import matplotlib.pyplot as plt pca演算法,共兩個函式 第乙個函式,用於清洗資料 輸入 原始資料集,分隔符 輸出 清洗後的資料集,乙個可以計算的矩陣 defloaddataset filenam...
Python簡單原始碼解析
批量修改檔案型別 def batch rename work dir,old ext,new ext for filename in os.listdir work dir file ext os.path.splitext filename 1 if file ext old ext newfil...