將其整理成數(shù)據(jù)集為:
成都創(chuàng)新互聯(lián)總部坐落于成都市區(qū),致力網(wǎng)站建設(shè)服務(wù)有成都網(wǎng)站設(shè)計、網(wǎng)站制作、外貿(mào)營銷網(wǎng)站建設(shè)、網(wǎng)絡(luò)營銷策劃、網(wǎng)頁設(shè)計、網(wǎng)站維護、公眾號搭建、重慶小程序開發(fā)、軟件開發(fā)等為企業(yè)提供一整套的信息化建設(shè)解決方案。創(chuàng)造真正意義上的網(wǎng)站建設(shè),為互聯(lián)網(wǎng)品牌在互動行銷領(lǐng)域創(chuàng)造價值而不懈努力!
[ [1,0,"yes"],[1,1,"yes"],[0,1,"yes"],[0,0,"no"],[1,0,"no"] ]
算法過程:
1、計算原始的信息熵。
2、依次計算數(shù)據(jù)集中每個樣本的每個特征的信息熵。
3、比較不同特征信息熵的大小,選出信息熵最大的特征值并輸出。
運行結(jié)果:
col : 0 curInfoGain : 2.37744375108 baseInfoGain : 0.0
col : 1 curInfoGain : 1.37744375108 baseInfoGain : 2.37744375108
bestInfoGain : 2.37744375108 bestFeature: 0
結(jié)果分析:
說明按照第一列,即有無喉結(jié)這個特征來進行分類的效果更好。
思考:
1、能否利用決策樹算法,將樣本最終的分類結(jié)果進行輸出?如樣本1,2,3屬于男性,4屬于女性。
2、示例程序生成的決策樹只有一層,當特征量增多的時候,如何生成具有多層結(jié)構(gòu)的決策樹?
3、如何評判分類結(jié)果的好壞?
在下一篇文章中,我將主要對以上三個問題進行分析和解答。如果您也感興趣,歡迎您訂閱我的文章,也可以在下方進行評論,如果有疑問或認為不對的地方,您也可以留言,我將積極與您進行解答。
完整代碼如下:
from math import log
"""
計算信息熵
"""
def calcEntropy(dataset):
diclabel = {} ## 標簽字典,用于記錄每個分類標簽出現(xiàn)的次數(shù)
for record in dataset:
label = record[-1]
if label not in diclabel.keys():
diclabel[label] = 0
diclabel[label] += 1
### 計算熵
entropy = 0.0
cnt = len(dataset)
for label in diclabel.keys():
prob = float(1.0 * diclabel[label]/cnt)
entropy -= prob * log(prob,2)
return entropy
def initDataSet():
dataset = [[1,0,"yes"],[1,1,"yes"],[0,1,"yes"],[0,0,"no"],[1,0,"no"]]
label = ["male","female"]
return dataset,label
#### 拆分dataset ,根據(jù)指定的過濾選項值,去掉指定的列形成一個新的數(shù)據(jù)集
def splitDataset(dataset , col, value):
retset = [] ## 拆分后的數(shù)據(jù)集
for record in dataset:
if record[col] == value :
reducedFeatVec = record[:col]
reducedFeatVec.extend(record[col+1:]) ### 將指定的列剔除
retset.append(reducedFeatVec) ### 將新形成的特征值列表追加到返回的列表中
return retset
### 找出信息熵增益最大的特征值
### 參數(shù):
### dataset : 原始的數(shù)據(jù)集
def findBestFeature(dataset):
numFeatures = len(dataset[0]) - 1 ### 特征值的個數(shù)
baseEntropy = calcEntropy(dataset) ### 計算原始數(shù)據(jù)集的熵
baseInfoGain = 0.0 ### 初始信息增益
bestFeature = -1 ### 初始的最優(yōu)分類特征值索引
### 計算每個特征值的熵
for col in range(numFeatures):
features = [record[col] for record in dataset] ### 提取每一列的特征向量 如此處col= 0 ,則features = [1,1,0,0]
uniqueFeat = set(features)
curInfoGain = 0 ### 根據(jù)每一列進行拆分,所獲得的信息增益
for featVal in uniqueFeat:
subDataset = splitDataset(dataset,col,featVal) ### 根據(jù)col列的featVal特征值來對數(shù)據(jù)集進行劃分
prob = 1.0 * len(subDataset)/numFeatures ### 計算子特征數(shù)據(jù)集所占比例
curInfoGain += prob * calcEntropy(subDataset) ### 計算col列的特征值featVal所產(chǎn)生的信息增益
# print "col : " ,col , " featVal : " , featVal , " curInfoGain :" ,curInfoGain ," baseInfoGain : " ,baseInfoGain
print "col : " ,col , " curInfoGain :" ,curInfoGain ," baseInfoGain : " ,baseInfoGain
if curInfoGain baseInfoGain:
baseInfoGain = curInfoGain
bestFeature = col
return baseInfoGain,bestFeature ### 輸出最大的信息增益,以獲得該增益的列
dataset,label = initDataSet()
infogain , bestFeature = findBestFeature(dataset)
print "bestInfoGain :" , infogain, " bestFeature:",bestFeature
轉(zhuǎn)自:
注意 :tensorflow交叉熵計算函數(shù)輸入中的logits都不是softmax或sigmoid的 輸出 ,而是softmax或sigmoid函數(shù)的 輸入 ,因為它在 函數(shù)內(nèi)部進行sigmoid或softmax操作
tf.nn.sigmoid_cross_entropy_with_logits(_sentinel=None,labels=None, logits=None, name=None)
參數(shù): ?? _sentinel:本質(zhì)上是不用的參數(shù),不用填
? ? ?? logits:一個數(shù)據(jù)類型(type)是float32或float64;
? ? ?? shape:[batch_size,num_classes],單樣本是[num_classes]
? ? ?? labels:和logits具有相同的type(float)和shape的張量(tensor),
? ? ?? name:操作的名字,可填可不填
輸出:
? ? ?? loss,shape:[batch_size,num_classes]
Note: 它對于輸入的logits先通過sigmoid函數(shù)計算,再計算它們的交叉熵,但是它對交叉熵的計算方式進行了優(yōu)化,使得結(jié)果不至于溢出。它適用于每個類別相互獨立但互不排斥的情況:例如一幅圖可以同時包含一條狗和一只大象。output不是一個數(shù),而是一個batch中每個樣本的loss,所以一般配合tf.reduce_mea(loss)使用
計算公式:
Python 程序:
輸出的E1,E2結(jié)果相同
tf.nn.softmax_cross_entropy_with_logits(_sentinel=None, labels=None, logits=None, dim=-1, name=None)argument:
_sentinel: 本質(zhì)上是不用的參數(shù),不用填
logits:一個數(shù)據(jù)類型(type)是float32或float64;
shape :[batch_size,num_classes]
labels:和logits具有相同type和shape的張量(tensor),,是一個有效的概率,sum(labels)=1, one_hot=True(向量中只有一個值為1.0,其他值為0.0)
name:操作的名字,可填可不填
output: loss,shape:[batch_size]
Note: 它對于輸入的logits先通過softmax( 不同于sigmoid )函數(shù)計算,再計算它們的交叉熵,但是它對交叉熵的計算方式進行了優(yōu)化,使得結(jié)果不至于溢出。它適用于每個類別相互獨立且排斥的情況,一幅圖只能屬于一類,而不能同時包含一條狗和一只大象。output不是一個數(shù),而是一個batch中每個樣本的loss,所以一般配合tf.reduce_mean(loss)使用。
計算公式:
Python程序:
import tensorflow as tf
import numpy as np
def softmax(x):
sum_raw = np.sum(np.exp(x),axis=-1)
x1 = np.ones(np.shape(x))
for i in range(np.shape(x)[0]):
? ? x1[i] = np.exp(x[i])/sum_raw[i]
return x1
y = np.array([[1,0,0],[0,1,0],[0,0,1],[1,0,0],[0,1,0]])#每一行只有一個1
logits =np.array([[12,3,2],[3,10,1],[1,2,5],[4,6.5,1.2],[3,6,1]])
y_pred =softmax(logits)
E1 = -np.sum(y*np.log(y_pred),-1)
print(E1)
sess = tf.Session()
y = np.array(y).astype(np.float64)
E2 = sess.run(tf.nn.softmax_cross_entropy_with_logits(labels=y,logits=logits))
print(E2)
輸出的E1,E2結(jié)果相同
tf.nn.sparse_softmax_cross_entropy_with_logits(_sentinel=None,labels=None,logits=None, name=None)
argument:
_sentinel:本質(zhì)上是不用的參數(shù),不用填
logits:一個數(shù)據(jù)類型(type)是float32或float64;
shape:[batch_size,num_classes]
labels: shape為[batch_size],labels[i]是{0,1,2,……,num_classes-1}的一個索引, type為int32或int64
name:操作的名字,可填可不填
output:
loss,shape:[batch_size]
Note:它對于輸入的logits先通過softmax函數(shù)計算,再計算它們的交叉熵,但是它對交叉熵的計算方式進行了優(yōu)化,使得結(jié)果不至于溢出
它適用于每個類別相互獨立且排斥的情況,一幅圖只能屬于一類,而不能同時包含一條狗和一只大象
output不是一個數(shù),而是一個batch中每個樣本的loss,所以一般配合tf.reduce_mean(loss)使用
計算公式:
和tf.nn.softmax_cross_entropy_with_logits()一樣,只是要將labels轉(zhuǎn)換成tf.nn.softmax_cross_entropy_with_logits()中l(wèi)abels的形式
tf.nn.weighted_cross_entropy_with_logits(labels,logits, pos_weight, name=None)
計算具有權(quán)重的sigmoid交叉熵sigmoid_cross_entropy_with_logits()
argument:
_sentinel:本質(zhì)上是不用的參數(shù),不用填
logits:一個數(shù)據(jù)類型(type)是float32或float64;
shape:[batch_size,num_classes],單樣本是[num_classes]
labels:和logits具有相同的type(float)和shape的張量(tensor),
pos_weight:正樣本的一個系數(shù)
name:操作的名字,可填可不填
output:
loss,shape:[batch_size,num_classes]
計算公式:
平滑函數(shù)。
交叉熵損失函數(shù),也稱為對數(shù)損失或者logistic損失。當模型產(chǎn)生了預(yù)測值之后,將對類別的預(yù)測概率與真實值(由0或1組成)進行不比較,計算所產(chǎn)生的損失,然后基于此損失設(shè)置對數(shù)形式的懲罰項。
在神經(jīng)網(wǎng)絡(luò)中,所使用的Softmax函數(shù)是連續(xù)可導(dǎo)函數(shù),這使得可以計算出損失函數(shù)相對于神經(jīng)網(wǎng)絡(luò)中每個權(quán)重的導(dǎo)數(shù)(在《機器學(xué)習(xí)數(shù)學(xué)基礎(chǔ)》中有對此的完整推導(dǎo)過程和案例,這樣就可以相應(yīng)地調(diào)整模型的權(quán)重以最小化損失函數(shù)。
擴展資料:
注意事項:
當預(yù)測類別為二分類時,交叉熵損失函數(shù)的計算公式如下圖,其中y是真實類別(值為0或1),p是預(yù)測類別的概率(值為0~1之間的小數(shù))。
計算二分類的交叉熵損失函數(shù)的python代碼如下圖,其中esp是一個極小值,第五行代碼clip的目的是保證預(yù)測概率的值在0~1之間,輸出的損失值數(shù)組求和后,就是損失函數(shù)最后的返回值。
參考資料來源:百度百科-交叉熵
參考資料來源:百度百科-損失函數(shù)
一、基本原理
在信息論中,熵是對不確定性的一種度量。信息量越大,不確定性就越小,熵也就越??;信息量越小,不確定性越大,熵也越大。
根據(jù)熵的特性,可以通過計算熵值來判斷一個事件的隨機性及無序程度,也可以用熵值來判斷某個指標的離散程度,指標的離散程度越大,該指標對綜合評價的影響(權(quán)重)越大,其熵值越小。
二、熵值法步驟
1. 選取n個國家,m個指標,則為第i個國家的第j個指標的數(shù)值(i=1, 2…, n; j=1,2,…, m);
2. 指標的歸一化處理:異質(zhì)指標同質(zhì)化
由于各項指標的計量單位并不統(tǒng)一,因此在用它們計算綜合指標前,先要對它們進行標準化處理,即把指標的絕對值轉(zhuǎn)化為相對值,并令,從而解決各項不同質(zhì)指標值的同質(zhì)化問題。而且,由于正向指標和負向指標數(shù)值代表的含義不同(正向指標數(shù)值越高越好,負向指標數(shù)值越低越好),因此,對于高低指標我們用不同的算法進行數(shù)據(jù)標準化處理。其具體方法如下:
正向指標:
負向指標:
則為第i個國家的第j個指標的數(shù)值(i=1, 2…, n; j=1, 2,…, m)。為了方便起見,歸一化后的數(shù)據(jù)仍記為;
3. 計算第j項指標下第i個國家占該指標的比重:
4. 計算第j項指標的熵值:
其中. 滿足;
5. 計算信息熵冗余度:
6. 計算各項指標的權(quán)值:
7. 計算各國家的綜合得分:
[code]function [s,w]=shang(x)
% 函數(shù)shang.m, 實現(xiàn)用熵值法求各指標(列)的權(quán)重及各數(shù)據(jù)行的得分
% x為原始數(shù)據(jù)矩陣, 一行代表一個國家, 每列對應(yīng)一個指標
% s返回各行得分, w返回各列權(quán)重
[n,m]=size(x); % n=23個國家, m=5個指標
%% 數(shù)據(jù)的歸一化處理
% Matlab2010b,2011a,b版本都有bug,需如下處理. 其它版本直接用[X,ps]=mapminmax(x',0,1);即可
[X,ps]=mapminmax(x');
ps.ymin=0.002; % 歸一化后的最小值
ps.ymax=0.996; % 歸一化后的最大值
ps.yrange=ps.ymax-ps.ymin; % 歸一化后的極差,若不調(diào)整該值, 則逆運算會出錯
X=mapminmax(x',ps);
% mapminmax('reverse',xx,ps); % 反歸一化, 回到原數(shù)據(jù)
X=X'; % X為歸一化后的數(shù)據(jù), 23行(國家), 5列(指標)
%% 計算第j個指標下,第i個記錄占該指標的比重p(i,j)
for i=1:n
for j=1:m
p(i,j)=X(i,j)/sum(X(:,j));
end
end
%% 計算第j個指標的熵值e(j)
k=1/log(n);
for j=1:m
e(j)=-k*sum(p(:,j).*log(p(:,j)));
end
d=ones(1,m)-e; % 計算信息熵冗余度
w=d./sum(d); % 求權(quán)值w
s=w*p'; % 求綜合得分[\code]
測試程序:
data.txt 數(shù)據(jù)如下:
114.6 1.1 0.71 85.0 346
55.3 0.96 0.4 69.0 300
132.4 0.97 0.54 73.0 410
152.1 1.04 0.49 77.0 433
103.5 0.96 0.66 67.0 385
81.0 1.08 0.54 96.0 336
179.3 0.88 0.59 89.0 446
29.8 0.83 0.49 120.0 289
92.7 1.15 0.44 154.0 300
248.6 0.79 0.5 147.0 483
115.0 0.74 0.65 252.0 453
64.9 0.59 0.5 167.0 402
163.6 0.85 0.58 220.0 495
95.7 1.02 0.48 160.0 384
139.5 0.70 0.59 217.0 478
89.9 0.96 0.39 105.0 314
76.7 0.95 0.51 162.0 341
121.8 0.83 0.60 140.0 401
42.1 1.08 0.47 110.0 326
78.5 0.89 0.44 94.0 280
77.8 1.19 0.57 91.0 364
90.0 0.95 0.43 89.0 301
100.6 0.82 0.59 83.0 456
執(zhí)行代碼:
[code]x=load('data.txt'); % 讀入數(shù)據(jù)
[s,w]=shang(x)[\code]
運行結(jié)果:
s =
Columns 1 through 9
0.0431 0.0103 0.0371 0.0404 0.0369 0.0322 0.0507 0.0229 0.0397
Columns 10 through 18
0.0693 0.0878 0.0466 0.0860 0.0503 0.0800 0.0234 0.0456 0.0536
Columns 19 through 23
0.0272 0.0181 0.0364 0.0202 0.0420
w =
0.1660 0.0981 0.1757 0.3348 0.2254
要弄清楚這個問題,首先要弄懂決策樹三大流行算法ID3、C4.5和CART的原理,以及sklearn框架下DecisionTreeClassifier的幫助文檔。
3個算法的主要區(qū)別在于度量信息方法、選擇節(jié)點特征還有分支數(shù)量的不同。
ID3,采用熵(entropy)來度量信息不確定度,選擇“信息增益”最大的作為節(jié)點特征,它是多叉樹,即一個節(jié)點可以有多個分支。
C4.5,同樣采用熵(entropy)來度量信息不確定度,選擇“信息增益比”最大的作為節(jié)點特征,同樣是多叉樹,即一個節(jié)點可以有多個分支。
CART,采用基尼指數(shù)(Gini index)來度量信息不純度,選擇基尼指數(shù)最小的作為節(jié)點特征,它是二叉樹,即一個節(jié)點只分兩支。
然后你認真閱讀sklearn的DecisionTreeClassifier的幫助文檔,可以發(fā)現(xiàn),度量信息的方法默認是Gini,但可以改成entropy,請按需選擇;構(gòu)建的樹是二叉樹;可以通過設(shè)置max_deepth、max_leaf等來實現(xiàn)“剪枝”,這是根據(jù)CART的損失函數(shù)減少的理論進行的。
所以總結(jié)說,如果信息度量方法按照默認的設(shè)置,那么sklearn所用的決策樹分類器就是CART,如果改成了entropy,那么只是使用了別的度量方法而已。其實兩者差不多。
1、首先自定義一份數(shù)據(jù),分別計算信息熵,條件信息熵,從而計算信息增益。
2、然后我們按下圖輸入命令計算信息熵。
3、再按照下圖輸入命令計算條件信息熵。
4、再輸入下圖命令,計算信息增益。
5、輸入下列代碼計算信息增益比。
6、最后按照下圖代碼計算出基尼指數(shù)。