关于python损失函数代码的信息( 八 )


77
78
79
80
81
82
83
84
下面用鸢尾花数据集对该算法进行测试 。由于ID3算法只能用于标称型数据,因此用在对连续型的数值数据上时,还需要对数据进行离散化,离散化的方法稍后说明,此处为了简化,先使用每一种特征所有连续性数值的中值作为分界点 , 小于中值的标记为1 , 大于中值的标记为0 。训练1000次,统计准确率均值 。
from sklearn import datasets
from sklearn.model_selection import train_test_split
iris = datasets.load_iris()
data = https://www.04ip.com/post/np.c_[iris.data, iris.target]
scoreL = []
for i in range(1000):#对该过程进行10000次
trainData, testData = https://www.04ip.com/post/train_test_split(data)#区分测试集和训练集
featNames = iris.feature_names[:]
for i in range(trainData.shape[1] - 1):#对训练集每个特征,以中值为分界点进行离散化
splitPoint = np.mean(trainData[:, i])
featNames[i] = featNames[i]+'='+'{:.3f}'.format(splitPoint)
trainData[:, i] = [1 if x = splitPoint else 0for 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
输出结果为:score: 0.7335,即准确率有73% 。每次训练和预测的准确率分布如下:
数据离散化
然而 , 在上例中对特征值离散化的划分点实际上过于“野蛮”,此处介绍一种通过信息增益最大的标准来对数据进行离散化 。原理很简单,当信息增益最大时 , 说明用该点划分能最大程度降低数据集的不确定性 。
具体步骤如下:
对每个特征所包含的数值型特征值排序
对相邻两个特征值取均值,这些均值就是待选的划分点
用每一个待选点把该特征的特征值划分成两类,小于该特征点置为1, 大于该特征点置为0,计算此时的条件熵,并计算出信息增益
选择信息使信息增益最大的划分点进行特征离散化
实现代码如下:
def filterRawData(dataSet, colIndex, value, tag):
""" 用于把每个特征的连续值按照区分点分成两类,加入tag参数,可用于标记筛选的是哪一部分数据"""
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):
""" 对数据每个特征的数值型特征值进行离散化 """
featureNum = dataSet.shape[1] - 1
entropy = calShannonEnt(dataSet)
for featIndex in range(featureNum):#对于每一个特征
uniqueValues = sorted(np.unique(dataSet[:, featIndex]))
meanPoint = []
for i in range(len(uniqueValues) - 1):# 求出相邻两个值的平均值
meanPoint.append(float(uniqueValues[i+1] + uniqueValues[i]) / 2.0)
bestInfoGain = 0.0
bestMeanPoint = -1
for mp in meanPoint:#对于每个划分点
subEntropy = 0.0#计算该划分点的信息熵
for tag in range(2):#分别划分为两类
subDataSet = filterRawData(dataSet, featIndex, mp, tag)
p = 1.0 * len(subDataSet) / len(dataSet)
subEntropy += p * calShannonEnt(subDataSet)
## 计算信息增益
infoGain = entropy - subEntropy

推荐阅读