????在使用pytorch深度學(xué)習(xí)框架,計(jì)算損失函數(shù)的時(shí)候經(jīng)常回到這么一個(gè)個(gè)函數(shù):

創(chuàng)新互聯(lián)公司專(zhuān)注于尼元陽(yáng)網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠(chéng)為您提供尼元陽(yáng)營(yíng)銷(xiāo)型網(wǎng)站建設(shè),尼元陽(yáng)網(wǎng)站制作、尼元陽(yáng)網(wǎng)頁(yè)設(shè)計(jì)、尼元陽(yáng)網(wǎng)站官網(wǎng)定制、微信小程序開(kāi)發(fā)服務(wù),打造尼元陽(yáng)網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供尼元陽(yáng)網(wǎng)站排名全網(wǎng)營(yíng)銷(xiāo)落地服務(wù)。
????該損失函數(shù)結(jié)合了 和 兩個(gè)函數(shù)。它在做分類(lèi)(具體幾類(lèi))訓(xùn)練的時(shí)候是非常有用的。在訓(xùn)練過(guò)程中,對(duì)于每個(gè)類(lèi)分配權(quán)值,可選的參數(shù)權(quán)值應(yīng)該是一個(gè)1D張量。當(dāng)你有一個(gè)不平衡的訓(xùn)練集時(shí),這是是非常有用的。那么針對(duì)這個(gè)函數(shù),下面將做詳細(xì)的介紹。
???? 交叉熵主要是用來(lái)判定實(shí)際的輸出與期望的輸出的接近程度 ,為什么這么說(shuō)呢,舉個(gè)例子:在做分類(lèi)的訓(xùn)練的時(shí)候,如果一個(gè)樣本屬于第K類(lèi),那么這個(gè)類(lèi)別所對(duì)應(yīng)的的輸出節(jié)點(diǎn)的輸出值應(yīng)該為1,而其他節(jié)點(diǎn)的輸出都為0,即[0,0,1,0,….0,0],這個(gè)數(shù)組也就是樣本的Label,是神經(jīng)網(wǎng)絡(luò)最期望的輸出結(jié)果。也就是說(shuō)用它來(lái)衡量網(wǎng)絡(luò)的輸出與標(biāo)簽的差異,利用這種差異經(jīng)過(guò)反向傳播去更新網(wǎng)絡(luò)參數(shù)。
在說(shuō)交叉熵之前,先說(shuō)一下 信息量 與 熵 。
???? 信息量: 它是用來(lái)衡量一個(gè)事件的不確定性的;一個(gè)事件發(fā)生的概率越大,不確定性越小,則它所攜帶的信息量就越小。假設(shè)X是一個(gè)離散型隨機(jī)變量,其取值集合為X,概率分布函數(shù)為 ,我們定義事件 的信息量為:
當(dāng) 時(shí),熵將等于0,也就是說(shuō)該事件的發(fā)生不會(huì)導(dǎo)致任何信息量的增加。
???? 熵: 它是用來(lái)衡量一個(gè)系統(tǒng)的混亂程度的,代表一個(gè)系統(tǒng)中信息量的總和;信息量總和越大,表明這個(gè)系統(tǒng)不確定性就越大。
????舉個(gè)例子:假如小明和小王去打靶,那么打靶結(jié)果其實(shí)是一個(gè)0-1分布,X的取值有{0:打中,1:打不中}。在打靶之前我們知道小明和小王打中的先驗(yàn)概率為10%,99.9%。根據(jù)上面的信息量的介紹,我們可以分別得到小明和小王打靶打中的信息量。但是如果我們想進(jìn)一步度量小明打靶結(jié)果的不確定度,這就需要用到熵的概念了。那么如何度量呢,那就要采用 期望 了。我們對(duì)所有可能事件所帶來(lái)的信息量求期望,其結(jié)果就能衡量小明打靶的不確定度:
與之對(duì)應(yīng)的,小王的熵(打靶的不確定度)為: ????雖然小明打靶結(jié)果的不確定度較低,畢竟十次有9次都脫靶;但是小王打靶結(jié)果的不確定度更低,1000次射擊只有1次脫靶,結(jié)果相當(dāng)?shù)拇_定。
???? 交叉熵: 它主要刻畫(huà)的是實(shí)際輸出(概率)與期望輸出(概率)的距離,也就是交叉熵的值越小,兩個(gè)概率分布就越接近。假設(shè)概率分布p為期望輸出,概率分布q為實(shí)際輸出, 為交叉熵,則 ????那么該公式如何表示,舉個(gè)例子,假設(shè)N=3,期望輸出為 ,實(shí)際輸出 , ,那么: 通過(guò)上面可以看出,q2與p更為接近,它的交叉熵也更小。
????Pytorch中計(jì)算的交叉熵并不是采用 這種方式計(jì)算得到的,而是交叉熵的另外一種方式計(jì)算得到的: 它是交叉熵的另外一種方式。
????Pytorch中CrossEntropyLoss()函數(shù)的主要是將softmax-log-NLLLoss合并到一塊得到的結(jié)果。
????1、Softmax后的數(shù)值都在0~1之間,所以ln之后值域是負(fù)無(wú)窮到0。
????2、然后將Softmax之后的結(jié)果取log,將乘法改成加法減少計(jì)算量,同時(shí)保障函數(shù)的單調(diào)性
????3、NLLLoss的結(jié)果就是把上面的輸出與Label對(duì)應(yīng)的那個(gè)值拿出來(lái)(下面例子中就是:將log_output\logsoftmax_output中與y_target對(duì)應(yīng)的值拿出來(lái)),去掉負(fù)號(hào),再求均值。
下面是我仿真寫(xiě)的一個(gè)例子:
最計(jì)算得到的結(jié)果為:
????通過(guò)上面的結(jié)果可以看出,直接使用pytorch中的loss_func=nn.CrossEntropyLoss()計(jì)算得到的結(jié)果與softmax-log-NLLLoss計(jì)算得到的結(jié)果是一致的。
[1]
[2]
[3]
更多自然語(yǔ)言處理、pytorch相關(guān)知識(shí),還請(qǐng)關(guān)注 AINLPer 公眾號(hào),極品干貨即刻送達(dá)。
可以使用Python版的opencv 來(lái)實(shí)現(xiàn)。
現(xiàn)讀取圖片:
import?cv2
import?numpy?as?np
from?matplotlib?import?pyplot?as?plt
image=cv2.imread('./src/q5.png')
HSV=cv2.cvtColor(image,cv2.COLOR_BGR2HSV)
計(jì)算熵
img?=?np.array(HSV)
for?i?in?range(len(img)):
for?j?in?range(len(img[i])):
val?=?img[i][j]
tmp[val]?=?float(tmp[val]?+?1)
k?=??float(k?+?1)
for?i?in?range(len(tmp)):
tmp[i]?=?float(tmp[i]?/?k)
for?i?in?range(len(tmp)):
if(tmp[i]?==?0):
res?=?res
else:
res?=?float(res?-?tmp[i]?*?(math.log(tmp[i])?/?math.log(2.0)))
保存:
HSV圖形可以直接存儲(chǔ),特征可以存xml中~
cv2.imwrite("具體路徑",HSV)
ID3算法介紹
ID3算法全稱(chēng)為迭代二叉樹(shù)3代算法(Iterative Dichotomiser 3)
該算法要先進(jìn)行特征選擇,再生成決策樹(shù),其中特征選擇是基于“信息增益”最大的原則進(jìn)行的。
但由于決策樹(shù)完全基于訓(xùn)練集生成的,有可能對(duì)訓(xùn)練集過(guò)于“依賴(lài)”,即產(chǎn)生過(guò)擬合現(xiàn)象。因此在生成決策樹(shù)后,需要對(duì)決策樹(shù)進(jìn)行剪枝。剪枝有兩種形式,分別為前剪枝(Pre-Pruning)和后剪枝(Post-Pruning),一般采用后剪枝。
信息熵、條件熵和信息增益
信息熵:來(lái)自于香農(nóng)定理,表示信息集合所含信息的平均不確定性。信息熵越大,表示不確定性越大,所含的信息量也就越大。
設(shè)x 1 , x 2 , x 3 , . . . x n {x_1, x_2, x_3, ...x_n}x
1
,x
2
,x
3
,...x
n
為信息集合X的n個(gè)取值,則x i x_ix
i
的概率:
P ( X = i ) = p i , i = 1 , 2 , 3 , . . . , n P(X=i) = p_i, i=1,2,3,...,n
P(X=i)=p
i
,i=1,2,3,...,n
信息集合X的信息熵為:
H ( X ) = ? ∑ i = 1 n p i log ? p i H(X) =- \sum_{i=1}^{n}{p_i}\log{p_i}
H(X)=?
i=1
∑
n
p
i
logp
i
條件熵:指已知某個(gè)隨機(jī)變量的情況下,信息集合的信息熵。
設(shè)信息集合X中有y 1 , y 2 , y 3 , . . . y m {y_1, y_2, y_3, ...y_m}y
1
,y
2
,y
3
,...y
m
組成的隨機(jī)變量集合Y,則隨機(jī)變量(X,Y)的聯(lián)合概率分布為
P ( x = i , y = j ) = p i j P(x=i,y=j) = p_{ij}
P(x=i,y=j)=p
ij
條件熵:
H ( X ∣ Y ) = ∑ j = 1 m p ( y j ) H ( X ∣ y j ) H(X|Y) = \sum_{j=1}^m{p(y_j)H(X|y_j)}
H(X∣Y)=
j=1
∑
m
p(y
j
)H(X∣y
j
)
由
H ( X ∣ y j ) = ? ∑ j = 1 m p ( y j ) ∑ i = 1 n p ( x i ∣ y j ) log ? p ( x i ∣ y j ) H(X|y_j) = - \sum_{j=1}^m{p(y_j)}\sum_{i=1}^n{p(x_i|y_j)}\log{p(x_i|y_j)}
H(X∣y
j
)=?
j=1
∑
m
p(y
j
)
i=1
∑
n
p(x
i
∣y
j
)logp(x
i
∣y
j
)
和貝葉斯公式:
p ( x i y j ) = p ( x i ∣ y j ) p ( y j ) p(x_iy_j) = p(x_i|y_j)p(y_j)
p(x
i
y
j
)=p(x
i
∣y
j
)p(y
j
)
可以化簡(jiǎn)條件熵的計(jì)算公式為:
H ( X ∣ Y ) = ∑ j = 1 m ∑ i = 1 n p ( x i , y j ) log ? p ( x i ) p ( x i , y j ) H(X|Y) = \sum_{j=1}^m \sum_{i=1}^n{p(x_i, y_j)\log\frac{p(x_i)}{p(x_i, y_j)}}
H(X∣Y)=
j=1
∑
m
i=1
∑
n
p(x
i
,y
j
)log
p(x
i
,y
j
)
p(x
i
)
信息增益:信息熵-條件熵,用于衡量在知道已知隨機(jī)變量后,信息不確定性減小越大。
d ( X , Y ) = H ( X ) ? H ( X ∣ Y ) d(X,Y) = H(X) - H(X|Y)
d(X,Y)=H(X)?H(X∣Y)
python代碼實(shí)現(xiàn)
import numpy as np
import math
def calShannonEnt(dataSet):
""" 計(jì)算信息熵 """
labelCountDict = {}
for d in dataSet:
label = d[-1]
if label not in labelCountDict.keys():
labelCountDict[label] = 1
else:
labelCountDict[label] += 1
entropy = 0.0
for l, c in labelCountDict.items():
p = 1.0 * c / len(dataSet)
entropy -= p * math.log(p, 2)
return entropy
def filterSubDataSet(dataSet, colIndex, value):
"""返回colIndex特征列l(wèi)abel等于value,并且過(guò)濾掉改特征列的數(shù)據(jù)集"""
subDataSetList = []
for r in dataSet:
if r[colIndex] == value:
newR = r[:colIndex]
newR = np.append(newR, (r[colIndex + 1:]))
subDataSetList.append(newR)
return np.array(subDataSetList)
def chooseFeature(dataSet):
""" 通過(guò)計(jì)算信息增益選擇最合適的特征"""
featureNum = dataSet.shape[1] - 1
entropy = calShannonEnt(dataSet)
bestInfoGain = 0.0
bestFeatureIndex = -1
for i in range(featureNum):
uniqueValues = np.unique(dataSet[:, i])
condition_entropy = 0.0
for v in uniqueValues: #計(jì)算條件熵
subDataSet = filterSubDataSet(dataSet, i, v)
p = 1.0 * len(subDataSet) / len(dataSet)
condition_entropy += p * calShannonEnt(subDataSet)
infoGain = entropy - condition_entropy #計(jì)算信息增益
if infoGain = bestInfoGain: #選擇最大信息增益
bestInfoGain = infoGain
bestFeatureIndex = i
return bestFeatureIndex
def creatDecisionTree(dataSet, featNames):
""" 通過(guò)訓(xùn)練集生成決策樹(shù) """
featureName = featNames[:] # 拷貝featNames,此處不能直接用賦值操作,否則新變量會(huì)指向舊變量的地址
classList = list(dataSet[:, -1])
if len(set(classList)) == 1: # 只有一個(gè)類(lèi)別
return classList[0]
if dataSet.shape[1] == 1: #當(dāng)所有特征屬性都利用完仍然無(wú)法判斷樣本屬于哪一類(lèi),此時(shí)歸為該數(shù)據(jù)集中數(shù)量最多的那一類(lèi)
return max(set(classList), key=classList.count)
bestFeatureIndex = chooseFeature(dataSet) #選擇特征
bestFeatureName = featNames[bestFeatureIndex]
del featureName[bestFeatureIndex] #移除已選特征列
decisionTree = {bestFeatureName: {}}
featureValueUnique = sorted(set(dataSet[:, bestFeatureIndex])) #已選特征列所包含的類(lèi)別, 通過(guò)遞歸生成決策樹(shù)
for v in featureValueUnique:
copyFeatureName = featureName[:]
subDataSet = filterSubDataSet(dataSet, bestFeatureIndex, v)
decisionTree[bestFeatureName][v] = creatDecisionTree(subDataSet, copyFeatureName)
return decisionTree
def classify(decisionTree, featnames, featList):
""" 使用訓(xùn)練所得的決策樹(shù)進(jìn)行分類(lèi) """
classLabel = None
root = decisionTree.keys()[0]
firstGenDict = decisionTree[root]
featIndex = featnames.index(root)
for k in firstGenDict.keys():
if featList[featIndex] == k:
if isinstance(firstGenDict[k], dict): #若子節(jié)點(diǎn)仍是樹(shù),則遞歸查找
classLabel = classify(firstGenDict[k], featnames, featList)
else:
classLabel = firstGenDict[k]
return classLabel
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
下面用鳶尾花數(shù)據(jù)集對(duì)該算法進(jìn)行測(cè)試。由于ID3算法只能用于標(biāo)稱(chēng)型數(shù)據(jù),因此用在對(duì)連續(xù)型的數(shù)值數(shù)據(jù)上時(shí),還需要對(duì)數(shù)據(jù)進(jìn)行離散化,離散化的方法稍后說(shuō)明,此處為了簡(jiǎn)化,先使用每一種特征所有連續(xù)性數(shù)值的中值作為分界點(diǎn),小于中值的標(biāo)記為1,大于中值的標(biāo)記為0。訓(xùn)練1000次,統(tǒng)計(jì)準(zhǔn)確率均值。
from sklearn import datasets
from sklearn.model_selection import train_test_split
iris = datasets.load_iris()
data = np.c_[iris.data, iris.target]
scoreL = []
for i in range(1000): #對(duì)該過(guò)程進(jìn)行10000次
trainData, testData = train_test_split(data) #區(qū)分測(cè)試集和訓(xùn)練集
featNames = iris.feature_names[:]
for i in range(trainData.shape[1] - 1): #對(duì)訓(xùn)練集每個(gè)特征,以中值為分界點(diǎn)進(jìn)行離散化
splitPoint = np.mean(trainData[:, i])
featNames[i] = featNames[i]+'='+'{:.3f}'.format(splitPoint)
trainData[:, i] = [1 if x = splitPoint else 0 for x in trainData[:, i]]
testData[:, i] = [1 if x = splitPoint else 0 for x in testData[:, i]]
decisionTree = creatDecisionTree(trainData, featNames)
classifyLable = [classify(decisionTree, featNames, td) for td in testData]
scoreL.append(1.0 * sum(classifyLable == testData[:, -1]) / len(classifyLable))
print 'score: ', np.mean(scoreL)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
輸出結(jié)果為:score: 0.7335,即準(zhǔn)確率有73%。每次訓(xùn)練和預(yù)測(cè)的準(zhǔn)確率分布如下:
數(shù)據(jù)離散化
然而,在上例中對(duì)特征值離散化的劃分點(diǎn)實(shí)際上過(guò)于“野蠻”,此處介紹一種通過(guò)信息增益最大的標(biāo)準(zhǔn)來(lái)對(duì)數(shù)據(jù)進(jìn)行離散化。原理很簡(jiǎn)單,當(dāng)信息增益最大時(shí),說(shuō)明用該點(diǎn)劃分能最大程度降低數(shù)據(jù)集的不確定性。
具體步驟如下:
對(duì)每個(gè)特征所包含的數(shù)值型特征值排序
對(duì)相鄰兩個(gè)特征值取均值,這些均值就是待選的劃分點(diǎn)
用每一個(gè)待選點(diǎn)把該特征的特征值劃分成兩類(lèi),小于該特征點(diǎn)置為1, 大于該特征點(diǎn)置為0,計(jì)算此時(shí)的條件熵,并計(jì)算出信息增益
選擇信息使信息增益最大的劃分點(diǎn)進(jìn)行特征離散化
實(shí)現(xiàn)代碼如下:
def filterRawData(dataSet, colIndex, value, tag):
""" 用于把每個(gè)特征的連續(xù)值按照區(qū)分點(diǎn)分成兩類(lèi),加入tag參數(shù),可用于標(biāo)記篩選的是哪一部分?jǐn)?shù)據(jù)"""
filterDataList = []
for r in dataSet:
if (tag and r[colIndex] = value) or ((not tag) and r[colIndex] value):
newR = r[:colIndex]
newR = np.append(newR, (r[colIndex + 1:]))
filterDataList.append(newR)
return np.array(filterDataList)
def dataDiscretization(dataSet, featName):
""" 對(duì)數(shù)據(jù)每個(gè)特征的數(shù)值型特征值進(jìn)行離散化 """
featureNum = dataSet.shape[1] - 1
entropy = calShannonEnt(dataSet)
for featIndex in range(featureNum): #對(duì)于每一個(gè)特征
uniqueValues = sorted(np.unique(dataSet[:, featIndex]))
meanPoint = []
for i in range(len(uniqueValues) - 1): # 求出相鄰兩個(gè)值的平均值
meanPoint.append(float(uniqueValues[i+1] + uniqueValues[i]) / 2.0)
bestInfoGain = 0.0
bestMeanPoint = -1
for mp in meanPoint: #對(duì)于每個(gè)劃分點(diǎn)
subEntropy = 0.0 #計(jì)算該劃分點(diǎn)的信息熵
for tag in range(2): #分別劃分為兩類(lèi)
subDataSet = filterRawData(dataSet, featIndex, mp, tag)
p = 1.0 * len(subDataSet) / len(dataSet)
subEntropy += p * calShannonEnt(subDataSet)
## 計(jì)算信息增益
infoGain = entropy - subEntropy
## 選擇最大信息增益
if infoGain = bestInfoGain:
bestInfoGain = infoGain
bestMeanPoint = mp
featName[featIndex] = featName[featIndex] + "=" + "{:.3f}".format(bestMeanPoint)
dataSet[:, featIndex] = [1 if x = bestMeanPoint else 0 for x in dataSet[:, featIndex]]
return dataSet, featName
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
重新對(duì)數(shù)據(jù)進(jìn)行離散化,并重復(fù)該步驟1000次,同時(shí)用sklearn中的DecisionTreeClassifier對(duì)相同數(shù)據(jù)進(jìn)行分類(lèi),分別統(tǒng)計(jì)平均準(zhǔn)確率。運(yùn)行代碼如下:
from sklearn.tree import DecisionTreeClassifier
import matplotlib.pyplot as plt
scoreL = []
scoreL_sk = []
for i in range(1000): #對(duì)該過(guò)程進(jìn)行1000次
featNames = iris.feature_names[:]
trainData, testData = train_test_split(data) #區(qū)分測(cè)試集和訓(xùn)練集
trainData_tmp = copy.copy(trainData)
testData_tmp = copy.copy(testData)
discritizationData, discritizationFeatName= dataDiscretization(trainData, featNames) #根據(jù)信息增益離散化
for i in range(testData.shape[1]-1): #根據(jù)測(cè)試集的區(qū)分點(diǎn)離散化訓(xùn)練集
splitPoint = float(discritizationFeatName[i].split('=')[-1])
testData[:, i] = [1 if x=splitPoint else 0 for x in testData[:, i]]
decisionTree = creatDecisionTree(trainData, featNames)
classifyLable = [classify(decisionTree, featNames, td) for td in testData]
scoreL.append(1.0 * sum(classifyLable == testData[:, -1]) / len(classifyLable))
clf = DecisionTreeClassifier('entropy')
clf.fit(trainData[:, :-1], trainData[:, -1])
clf.predict(testData[:, :-1])
scoreL_sk.append(clf.score(testData[:, :-1], testData[:, -1]))
print 'score: ', np.mean(scoreL)
print 'score-sk: ', np.mean(scoreL_sk)
fig = plt.figure(figsize=(10, 4))
plt.subplot(1,2,1)
pd.Series(scoreL).hist(grid=False, bins=10)
plt.subplot(1,2,2)
pd.Series(scoreL_sk).hist(grid=False, bins=10)
plt.show()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
兩者準(zhǔn)確率分別為:
score: 0.7037894736842105
score-sk: 0.7044736842105263
準(zhǔn)確率分布如下:
兩者的結(jié)果非常一樣。
(但是。。為什么根據(jù)信息熵離散化得到的準(zhǔn)確率比直接用均值離散化的準(zhǔn)確率還要低啊??哇的哭出聲。。)
最后一次決策樹(shù)圖形如下:
決策樹(shù)剪枝
由于決策樹(shù)是完全依照訓(xùn)練集生成的,有可能會(huì)有過(guò)擬合現(xiàn)象,因此一般會(huì)對(duì)生成的決策樹(shù)進(jìn)行剪枝。常用的是通過(guò)決策樹(shù)損失函數(shù)剪枝,決策樹(shù)損失函數(shù)表示為:
C a ( T ) = ∑ t = 1 T N t H t ( T ) + α ∣ T ∣ C_a(T) = \sum_{t=1}^TN_tH_t(T) +\alpha|T|
C
a
(T)=
t=1
∑
T
N
t
H
t
(T)+α∣T∣
其中,H t ( T ) H_t(T)H
t
(T)表示葉子節(jié)點(diǎn)t的熵值,T表示決策樹(shù)的深度。前項(xiàng)∑ t = 1 T N t H t ( T ) \sum_{t=1}^TN_tH_t(T)∑
t=1
T
N
t
H
t
(T)是決策樹(shù)的經(jīng)驗(yàn)損失函數(shù)當(dāng)隨著T的增加,該節(jié)點(diǎn)被不停的劃分的時(shí)候,熵值可以達(dá)到最小,然而T的增加會(huì)使后項(xiàng)的值增大。決策樹(shù)損失函數(shù)要做的就是在兩者之間進(jìn)行平衡,使得該值最小。
對(duì)于決策樹(shù)損失函數(shù)的理解,如何理解決策樹(shù)的損失函數(shù)? - 陶輕松的回答 - 知乎這個(gè)回答寫(xiě)得挺好,可以按照答主的思路理解一下
C4.5算法
ID3算法通過(guò)信息增益來(lái)進(jìn)行特征選擇會(huì)有一個(gè)比較明顯的缺點(diǎn):即在選擇的過(guò)程中該算法會(huì)優(yōu)先選擇類(lèi)別較多的屬性(這些屬性的不確定性小,條件熵小,因此信息增益會(huì)大),另外,ID3算法無(wú)法解決當(dāng)每個(gè)特征屬性中每個(gè)分類(lèi)都只有一個(gè)樣本的情況(此時(shí)每個(gè)屬性的條件熵都為0)。
C4.5算法ID3算法的改進(jìn),它不是依據(jù)信息增益進(jìn)行特征選擇,而是依據(jù)信息增益率,它添加了特征分裂信息作為懲罰項(xiàng)。定義分裂信息:
S p l i t I n f o ( X , Y ) = ? ∑ i n ∣ X i ∣ ∣ X ∣ log ? ∣ X i ∣ ∣ X ∣ SplitInfo(X, Y) =-\sum_i^n\frac{|X_i|}{|X|}\log\frac{|X_i|}{|X|}
SplitInfo(X,Y)=?
i
∑
n
∣X∣
∣X
i
∣
log
∣X∣
∣X
i
∣
則信息增益率為:
G a i n R a t i o ( X , Y ) = d ( X , Y ) S p l i t I n f o ( X , Y ) GainRatio(X,Y)=\frac{d(X,Y)}{SplitInfo(X, Y)}
GainRatio(X,Y)=
SplitInfo(X,Y)
d(X,Y)
關(guān)于ID3和C4.5算法
在學(xué)習(xí)分類(lèi)回歸決策樹(shù)算法時(shí),看了不少的資料和博客。關(guān)于這兩個(gè)算法,ID3算法是最早的分類(lèi)算法,這個(gè)算法剛出生的時(shí)候其實(shí)帶有很多缺陷:
無(wú)法處理連續(xù)性特征數(shù)據(jù)
特征選取會(huì)傾向于分類(lèi)較多的特征
沒(méi)有解決過(guò)擬合的問(wèn)題
沒(méi)有解決缺失值的問(wèn)題
即該算法出生時(shí)是沒(méi)有帶有連續(xù)特征離散化、剪枝等步驟的。C4.5作為ID3的改進(jìn)版本彌補(bǔ)列ID3算法不少的缺陷:
通過(guò)信息最大增益的標(biāo)準(zhǔn)離散化連續(xù)的特征數(shù)據(jù)
在選擇特征是標(biāo)準(zhǔn)從“最大信息增益”改為“最大信息增益率”
通過(guò)加入正則項(xiàng)系數(shù)對(duì)決策樹(shù)進(jìn)行剪枝
對(duì)缺失值的處理體現(xiàn)在兩個(gè)方面:特征選擇和生成決策樹(shù)。初始條件下對(duì)每個(gè)樣本的權(quán)重置為1。
特征選擇:在選取最優(yōu)特征時(shí),計(jì)算出每個(gè)特征的信息增益后,需要乘以一個(gè)**“非缺失值樣本權(quán)重占總樣本權(quán)重的比例”**作為系數(shù)來(lái)對(duì)比每個(gè)特征信息增益的大小
生成決策樹(shù):在生成決策樹(shù)時(shí),對(duì)于缺失的樣本我們按照一定比例把它歸屬到每個(gè)特征值中,比例為該特征每一個(gè)特征值占非缺失數(shù)據(jù)的比重
關(guān)于C4.5和CART回歸樹(shù)
作為ID3的改進(jìn)版本,C4.5克服了許多缺陷,但是它自身還是存在不少問(wèn)題:
C4.5的熵運(yùn)算中涉及了對(duì)數(shù)運(yùn)算,在數(shù)據(jù)量大的時(shí)候效率非常低。
C4.5的剪枝過(guò)于簡(jiǎn)單
C4.5只能用于分類(lèi)運(yùn)算不能用于回歸
當(dāng)特征有多個(gè)特征值是C4.5生成多叉樹(shù)會(huì)使樹(shù)的深度加深
————————————————
版權(quán)聲明:本文為CSDN博主「Sarah Huang」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接及本聲明。
原文鏈接:
平滑函數(shù)。
交叉熵?fù)p失函數(shù),也稱(chēng)為對(duì)數(shù)損失或者logistic損失。當(dāng)模型產(chǎn)生了預(yù)測(cè)值之后,將對(duì)類(lèi)別的預(yù)測(cè)概率與真實(shí)值(由0或1組成)進(jìn)行不比較,計(jì)算所產(chǎn)生的損失,然后基于此損失設(shè)置對(duì)數(shù)形式的懲罰項(xiàng)。
在神經(jīng)網(wǎng)絡(luò)中,所使用的Softmax函數(shù)是連續(xù)可導(dǎo)函數(shù),這使得可以計(jì)算出損失函數(shù)相對(duì)于神經(jīng)網(wǎng)絡(luò)中每個(gè)權(quán)重的導(dǎo)數(shù)(在《機(jī)器學(xué)習(xí)數(shù)學(xué)基礎(chǔ)》中有對(duì)此的完整推導(dǎo)過(guò)程和案例,這樣就可以相應(yīng)地調(diào)整模型的權(quán)重以最小化損失函數(shù)。
擴(kuò)展資料:
注意事項(xiàng):
當(dāng)預(yù)測(cè)類(lèi)別為二分類(lèi)時(shí),交叉熵?fù)p失函數(shù)的計(jì)算公式如下圖,其中y是真實(shí)類(lèi)別(值為0或1),p是預(yù)測(cè)類(lèi)別的概率(值為0~1之間的小數(shù))。
計(jì)算二分類(lèi)的交叉熵?fù)p失函數(shù)的python代碼如下圖,其中esp是一個(gè)極小值,第五行代碼clip的目的是保證預(yù)測(cè)概率的值在0~1之間,輸出的損失值數(shù)組求和后,就是損失函數(shù)最后的返回值。
參考資料來(lái)源:百度百科-交叉熵
參考資料來(lái)源:百度百科-損失函數(shù)
一、基本原理
在信息論中,熵是對(duì)不確定性的一種度量。信息量越大,不確定性就越小,熵也就越小;信息量越小,不確定性越大,熵也越大。
根據(jù)熵的特性,可以通過(guò)計(jì)算熵值來(lái)判斷一個(gè)事件的隨機(jī)性及無(wú)序程度,也可以用熵值來(lái)判斷某個(gè)指標(biāo)的離散程度,指標(biāo)的離散程度越大,該指標(biāo)對(duì)綜合評(píng)價(jià)的影響(權(quán)重)越大,其熵值越小。
二、熵值法步驟
1. 選取n個(gè)國(guó)家,m個(gè)指標(biāo),則為第i個(gè)國(guó)家的第j個(gè)指標(biāo)的數(shù)值(i=1, 2…, n; j=1,2,…, m);
2. 指標(biāo)的歸一化處理:異質(zhì)指標(biāo)同質(zhì)化
由于各項(xiàng)指標(biāo)的計(jì)量單位并不統(tǒng)一,因此在用它們計(jì)算綜合指標(biāo)前,先要對(duì)它們進(jìn)行標(biāo)準(zhǔn)化處理,即把指標(biāo)的絕對(duì)值轉(zhuǎn)化為相對(duì)值,并令,從而解決各項(xiàng)不同質(zhì)指標(biāo)值的同質(zhì)化問(wèn)題。而且,由于正向指標(biāo)和負(fù)向指標(biāo)數(shù)值代表的含義不同(正向指標(biāo)數(shù)值越高越好,負(fù)向指標(biāo)數(shù)值越低越好),因此,對(duì)于高低指標(biāo)我們用不同的算法進(jìn)行數(shù)據(jù)標(biāo)準(zhǔn)化處理。其具體方法如下:
正向指標(biāo):
負(fù)向指標(biāo):
則為第i個(gè)國(guó)家的第j個(gè)指標(biāo)的數(shù)值(i=1, 2…, n; j=1, 2,…, m)。為了方便起見(jiàn),歸一化后的數(shù)據(jù)仍記為;
3. 計(jì)算第j項(xiàng)指標(biāo)下第i個(gè)國(guó)家占該指標(biāo)的比重:
4. 計(jì)算第j項(xiàng)指標(biāo)的熵值:
其中. 滿(mǎn)足;
5. 計(jì)算信息熵冗余度:
6. 計(jì)算各項(xiàng)指標(biāo)的權(quán)值:
7. 計(jì)算各國(guó)家的綜合得分:
[code]function [s,w]=shang(x)
% 函數(shù)shang.m, 實(shí)現(xiàn)用熵值法求各指標(biāo)(列)的權(quán)重及各數(shù)據(jù)行的得分
% x為原始數(shù)據(jù)矩陣, 一行代表一個(gè)國(guó)家, 每列對(duì)應(yīng)一個(gè)指標(biāo)
% s返回各行得分, w返回各列權(quán)重
[n,m]=size(x); % n=23個(gè)國(guó)家, m=5個(gè)指標(biāo)
%% 數(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)整該值, 則逆運(yùn)算會(huì)出錯(cuò)
X=mapminmax(x',ps);
% mapminmax('reverse',xx,ps); % 反歸一化, 回到原數(shù)據(jù)
X=X'; % X為歸一化后的數(shù)據(jù), 23行(國(guó)家), 5列(指標(biāo))
%% 計(jì)算第j個(gè)指標(biāo)下,第i個(gè)記錄占該指標(biāo)的比重p(i,j)
for i=1:n
for j=1:m
p(i,j)=X(i,j)/sum(X(:,j));
end
end
%% 計(jì)算第j個(gè)指標(biāo)的熵值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; % 計(jì)算信息熵冗余度
w=d./sum(d); % 求權(quán)值w
s=w*p'; % 求綜合得分[\code]
測(cè)試程序:
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]
運(yùn)行結(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
標(biāo)題名稱(chēng):包含python實(shí)現(xiàn)熵函數(shù)的詞條
分享鏈接:http://chinadenli.net/article30/hhjdso.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)建站、靜態(tài)網(wǎng)站、定制網(wǎng)站、電子商務(wù)、品牌網(wǎng)站建設(shè)、App設(shè)計(jì)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)