本来早就写完了,但出了两个小错误,我又不会debug,只能一点点代码试哪里错了,真的烦死了,旁边还有蚊子叫,烦上加烦,好在最后找到错误原因了。
import numpy as np
from pandas import DataFrame, Series
def cal_shannon(frame):
val_count = frame.iloc[:, -1].value_counts()
pct_val = val_count / val_count.sum()
log_pct = pct_val.map(np.log2)
shannon_ent = -(pct_val * log_pct).sum()
return shannon_ent
def bfts(frame):
fea_num = frame.shape[1] - 1
ent_ser = Series([])
for i in range(fea_num):
ent_ser[i] = (frame.groupby(frame.iloc[:, i]).apply(cal_shannon)*\
(frame.iloc[:, i].value_counts()/frame.shape[0])).sum()
best_features_tosplit = ent_ser.idxmin()
return best_features_tosplit
def create_tree(frame, labels):
if len(frame.iloc[:, -1].unique()) == 1:
return frame.iloc[0, -1]
if frame.shape[1] == 1:
return frame.iloc[:, -1].value_counts().index[0]
bestfeat = bfts(frame)
bestfeatlabel = labels[bestfeat]
mytree = {bestfeatlabel: {}}
del (labels[bestfeat])
unique_values = frame.iloc[:, bestfeat].unique()
for value in unique_values:
sublabels = labels
subframe = frame[frame.iloc[:, bestfeat] == value].drop(frame.columns[bestfeat], axis=1)
mytree[bestfeatlabel][value] = create_tree(subframe, sublabels)
return mytree
frame = DataFrame([[1, 1, 'yes'],
[1, 1, 'yes'],
[1, 0, 'no'],
[0, 1, 'no'],
[0, 1, 'no']])
labels = ['no surfacing', 'flippers']
print create_tree(frame, labels)
{'no surfacing': {0: 'no', 1: {'flippers': {0: 'no', 1: 'yes'}}}}
第一处错误是
subframe = frame[frame.iloc[:, bestfeat] == value].drop(frame.columns[bestfeat], axis=1)
这地方的iloc顺手写了个ix,按说ix可以替代iloc的,结果还是报错,是因为列名是数字的原因吗?
然后就是drop的列名那,我开始图省事直接写的
drop(bestfeat, axis=1)`
当时本来正确的写法已经构思好了,写的时候稍微想反正数字列名,直接写应该也可以?
看看第一轮运行也没问题,就这样写了,一念之差又报个错,唉,真的蛋疼。
以后写代码一定要严谨。
以后写代码一定要严谨。
以后写代码一定要严谨。
!!!!!!!!!!