前文參考: Python爬蟲(一)——開封市58同城租房資訊 Python爬蟲(二)——對開封市58同城出租房資料進行分析 Python爬蟲(三)——對豆瓣圖書各子產品評論數與評分圖形化分析
資料的建構

在這張表中我們可以發現這裡有5個資料,這裡有兩個特征(房租是否少于2000,房屋面積是否大于50)來劃分這5個出租房是否租借。
現在我們要做的就是是要根據第一個特征,第二個特征還是第三個特征來劃分資料,進行分類。
1 def createDataSet():
2 dataSet = [[1, 1, 'yes'],
3 [1, 1, 'yes'],
4 [1, 0, 'no'],
5 [0, 1, 'no'],
6 [0, 0, 'no']
7 ]
8
9 labels = ['no surfacing','flippers']
10
11 return dataSet, labels
計算給定資料的資訊熵
根據資訊論的方法找到最合适的特征來劃分資料集。在這裡,我們首先要計算所有類别的所有可能值的香農熵,根據香農熵來我們按照取最大資訊增益的方法劃分資料集。
以資訊增益度量屬性選擇,選擇分裂後資訊增益最大的屬性進行分裂。資訊熵是用來衡量一個随機變量出現的期望值。如果資訊的不确定性越大,熵的值也就越大,出現的各種情況也就越多。
其中,S為所有事件集合,p為發生機率,c為特征總數。注意:熵是以2進制位的個數來度量編碼長度的,是以熵的最大值是log2C。
資訊增益(information gain)是指資訊劃分前後的熵的變化,也就是說由于使用這個屬性分割樣例而導緻的期望熵降低。也就是說,資訊增益就是原有資訊熵與屬性劃分後資訊熵(需要對劃分後的資訊熵取期望值)的內插補點,具體計算法如下:
1 def calcShannonEnt(dataSet):
2 countDataSet = len(dataSet)
3 labelCounts={}
4 for featVec in dataSet:
5 currentLabel=featVec[-1]
6 if currentLabel not in labelCounts.keys():
7 labelCounts[currentLabel] = 0
8 labelCounts[currentLabel] += 1
9 getshang = 0.0
10
11 for key in labelCounts:
12 prob = float(labelCounts[key])/countDataSet
13 getshang -= prob * log(prob,2)
14
15
16 return getshang
劃分資料集
在度量資料集的無序程度的時候,分類算法除了需要測量資訊熵,還需要劃分資料集,度量花費資料集的熵,以便判斷目前是否正确的劃分了資料集。
我們将對每個特征資料集劃分的結果計算一次資訊熵,然後判斷按照那個特征劃分資料集是最好的劃分方式。
也就是說,我們依次選取我們資料集當中的所有特征作為我們劃定的特征,然後計算選取該特征時的資訊增益,當資訊增益最大時我們就選取對應資訊增益最大的特征作為我們分類的最佳特征。

1 dataSet = [
2 [1, 1, 'yes'],
3 [1, 0, 'no'],
4 [1, 1, 'yes'],
5 [0, 1, 'no'],
6 [0, 0, 'no']
7 ]
在這個資料集當中有三個特征,就是每個樣本的第一列和第二列,最後一列是它們所屬的分類。
我們劃分資料集是為了計算根據那個特征我們可以得到最大的資訊增益,那麼根據這個特征來劃分資料就是最好的分類方法。
是以我們需要周遊每一個特征,然後計算按照這種劃分方式得出的資訊增益。資訊增益是指資料集在劃分資料前後資訊的變化量。
計算資訊增益
依次周遊每一個特征,在這裡我們的特征隻有兩個,就是房租是否少于2000,房屋面積是否大于50。然後計算出根據每一個特征劃分産生的資料集的熵,和初始的資料集的熵比較,我們找出和初始資料集差距最大的。那麼這個特征就是我們劃分時最合适的分類特征。
1 def chooseBestFeatureToSplit(dataSet):
2 numFeatures = len(dataSet[0])-1
3 baseEntropy = calcShannonEnt(dataSet)
4 bestInfoGain =0.0
5 bestFeature = -1
6
7 for i in range(numFeatures):
8 featList = [sample[i] for sample in dataSet]
9 uniqueVals = set(featList)
10 newEntropy = 0.0
11 for value in uniqueVals:
12 subDataSet = splitDataSet(dataSet,i,value)
13 prob = len(subDataSet)/float(len(dataSet))
14 newEntropy += prob * calcShannonEnt(subDataSet)
15
16 infoGain = baseEntropy - newEntropy
17
18 if(infoGain > bestInfoGain):
19 bestInfoGain = infoGain
20 bestFeature = i
21
22 return bestFeature
資料檢測
sklearn實作交叉驗證十折交叉驗證流程
将資料集随機地切分為S個互不相交的大小相同的子集
然後挑選其中S-1個子集作為訓練集,訓練模型,用剩下的一個子集作測試集,獲得測試誤差或者評測名額
将上面過程對所有可能的S種選擇重複進行,即每次都是用不同的測試集
最後對S次實驗所得的資料(測試誤差或者評測名額)取均值。
1 train = np.array(myDat)
2 loop = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
3 kf = KFold(n_splits=10)
4
5 for train_index, test_index in kf.split(train):
6 print("train:",train_index, "test:", test_index)
7 X_train, X_test = train[train_index], train[test_index]
8 y_train, y_test = loop[train_index], loop[test_index]
9 print(calcShannonEnt(train[train_index]))