连续值处理:
决策树处理的是离散数据,当离散数据中混杂着连续数据时,我们希望将连续数据离散化。
我们可以将连续取值的值域划分为多个区间,每个区间视为一个属性取值,这样就将连续数据离散化了。
例如:属性a的取值范围为0-100,我们划分为0-25, 25-50, 50-75, 75-100四个区间,作为属性a的四种取值
那么,划分边界的选择就是我们需要解决的问题。我们以二分为例(化为两个子区间):
设一个属性a={a1, a2, ..., an}的所有取值:
(0.697, 0.774, 0.634, 0.608, 0.556, 0.403, 0.481, 0.437, 0.666, 0.243, 0.245, 0.343, 0.639, 0.657, 0.360, 0.593, 0.719)
将属性a的所有的取值进行排序:
(0.774, 0.719, 0.697, 0.666, 0.657, 0.639, 0.634, 0.608, 0.593, 0.556, 0.481, 0.437, 0.403, 0.36, 0.343, 0.245, 0.243)
我们可以取任意相邻取值的中位点,作为划分点,例如:我们可以使用0.634和0.608的中位点进行划分,我们希望划分之后的数据集更加纯净,所以我们依然用信息熵来度量划分的效果,我们选取划分效果最好的点作为划分点。
候选的n-1个中位点:
求按照每个中位点划分的信息熵,信息熵最小的就是最优划分点
我们以西瓜数据集,来实现以下:
色泽 根蒂 敲声 纹理 脐部 触感 密度 含糖率 好瓜
青绿 蜷缩 浊响 清晰 凹陷 硬滑 0.697 0.46 是
乌黑 蜷缩 沉闷 清晰 凹陷 硬滑 0.774 0.376 是
乌黑 蜷缩 浊响 清晰 凹陷 硬滑 0.634 0.264 是
青绿 蜷缩 沉闷 清晰 凹陷 硬滑 0.608 0.318 是
浅白 蜷缩 浊响 清晰 凹陷 硬滑 0.556 0.215 是
青绿 稍蜷 浊响 清晰 稍凹 软粘 0.403 0.237 是
乌黑 稍蜷 浊响 稍糊 稍凹 软粘 0.481 0.149 是
乌黑 稍蜷 浊响 清晰 稍凹 硬滑 0.437 0.211 是
乌黑 稍蜷 沉闷 稍糊 稍凹 硬滑 0.666 0.091 否
青绿 硬挺 清脆 清晰 平坦 软粘 0.243 0.267 否
浅白 硬挺 清脆 模糊 平坦 硬滑 0.245 0.057 否
浅白 蜷缩 浊响 模糊 平坦 软粘 0.343 0.099 否
青绿 稍蜷 浊响 稍糊 凹陷 硬滑 0.639 0.161 否
浅白 稍蜷 沉闷 稍糊 凹陷 硬滑 0.657 0.198 否
乌黑 稍蜷 浊响 清晰 稍凹 软粘 0.36 0.37 否
浅白 蜷缩 浊响 模糊 平坦 硬滑 0.593 0.042 否
青绿 蜷缩 沉闷 稍糊 稍凹 硬滑 0.719 0.103 否
读取数据:
def loaddataset(filename):
dataset = []
fp = open(filename)
for i in fp.readlines():
a = i.strip().split()
dataset.append(a)
attribute_name = dataset.pop(0)
del(attribute_name[-1])
return dataset, attribute_name
dataset:
[['青绿', '蜷缩', '浊响', '清晰', '凹陷', '硬滑', '0.697', '0.46', '是'], ['乌黑', '蜷缩', '沉闷', '清晰', '凹陷', '硬滑', '0.774', '0.376', '是'], ['乌黑', '蜷缩', '浊响', '清晰', '凹陷', '硬滑', '0.634', '0.264', '是'], ['青绿', '蜷缩', '沉闷', '清晰', '凹陷', '硬滑', '0.608', '0.318', '是'], ['浅白', '蜷缩', '浊响', '清晰', '凹陷', '硬滑', '0.556', '0.215', '是'], ['青绿', '稍蜷', '浊响', '清晰', '稍凹', '软粘', '0.403', '0.237', '是'], ['乌黑', '稍蜷', '浊响', '稍糊', '稍凹', '软粘', '0.481', '0.149', '是'], ['乌黑', '稍蜷', '浊响', '清晰', '稍凹', '硬滑', '0.437', '0.211', '是'], ['乌黑', '稍蜷', '沉闷', '稍糊', '稍凹', '硬滑', '0.666', '0.091', '否'], ['青绿', '硬挺', '清脆', '清晰', '平坦', '软粘', '0.243', '0.267', '否'], ['浅白', '硬挺', '清脆', '模糊', '平坦', '硬滑', '0.245', '0.057', '否'], ['浅白', '蜷缩', '浊响', '模糊', '平坦', '软粘', '0.343', '0.099', '否'], ['青绿', '稍蜷', '浊响', '稍糊', '凹陷', '硬滑', '0.639', '0.161', '否'], ['浅白', '稍蜷', '沉闷', '稍糊', '凹陷', '硬滑', '0.657', '0.198', '否'], ['乌黑', '稍蜷', '浊响', '清晰', '稍凹', '软粘', '0.36', '0.37', '否'], ['浅白', '蜷缩', '浊响', '模糊', '平坦', '硬滑', '0.593', '0.042', '否'], ['青绿', '蜷缩', '沉闷', '稍糊', '稍凹', '硬滑', '0.719', '0.103', '否']]
[Finished in 0.4s]
attribute_name:
['色泽', '根蒂', '敲声', '纹理', '脐部', '触感', '密度', '含糖率']
[Finished in 0.2s]
计算以某点划分的信息熵:
def calculate_EntD(dataset, n, m):
#计算信息熵时,先将原连续数据改为字符串形式(<=m, >m)的离散数据
dataset_new = copy.deepcopy(dataset)
for i in range(len(dataset_new)):
a = str(m)
if float(dataset_new[i][n]) <= m:
dataset_new[i][n] = '<='+a
else:
dataset_new[i][n] = '>'+a
#这里计算信息熵的函数,直接使用决策树中的相关函数
entd = EntD(dataset_new)
count = statistics(dataset_new, n)
entdv = EntDv(count)
gaind = GainD(entd, entdv, len(dataset_new))
#返回信息熵
return gaind
我们在属性密度上用0.5作为划分,其划分后的信息熵为(密度属性是第七个属性,n=6):
gaind = calculate_EntD(dataset, 6, 0.5)
0.003585078590305768
[Finished in 0.2s]
根据相关信息修改原数据集:
def change_dataset(dataset):
data = {}
for i in dataset:
for j in i:
#筛选出连续的数值型属性时,使用差错控制方法,来判断字符串是否可以转化为数字
try:
float(j)
if i.index(j) not in data:
data[i.index(j)] = [float(j)]
else:
data[i.index(j)].append(float(j))
except:
continue
#记录所有候选的中位点
Ta_set = []
for i in data:
#对属性的所有取值排序
a = sorted(data[i], reverse = True)
#记录每个中位点划分的信息熵
gaind_set = []
for j in range(len(a)-1):
Ta = (a[j] + a[j+1]) / 2
#calculate_EntD计算每种划分的信息熵
gaind_set.append(calculate_EntD(dataset, i, Ta))
#选取信息熵最小的那个划分点
b = min(gaind_set)
k = gaind_set.index(b)
Ta_set.append((a[k] + a[k+1]) / 2)
#处理数据集,将连续数据替换为字符串形式(<=m, >m)的离散形式
dataset_new = copy.deepcopy(dataset)
n = 0
for i in data:
c = str(Ta_set[n])
for j in range(len(dataset_new)):
if float(dataset_new[j][i]) <= Ta_set[n]:
dataset_new[j][i] = '<=' + c
else:
dataset_new[j][i] = '>' + c
n += 1
return dataset_new
返回的新数据集,就可以使用在决策树模型中,我们直接使用上一篇文章中的决策树模型算法,得到模型如下:
[['纹理清晰', ['根蒂蜷缩', '是'], ['根蒂稍蜷', ['含糖率<=0.2655', '是'], ['含糖率>0.2655', '否']], ['根蒂硬挺', '否']], ['纹理稍糊', ['触感软粘', '是'], ['触感硬滑', '否']], ['纹理模糊', '否']]
[Finished in 0.2s]
评论(0)
您还未登录,请登录后发表或查看评论