机器学习:决策树python实现
2016-03-14 21:19
519 查看
机器学习:决策树python实现源码笔记
打算今天开始回顾一下ml的经典算法,就去按照书上实现了决策树。其实,ml代码模式有很大的相似之处,特征的划分等等。
打算今天开始回顾一下ml的经典算法,就去按照书上实现了决策树。其实,ml代码模式有很大的相似之处,特征的划分等等。
def createDataSet(): dataSet = [[1, 1, 'yes'], [1, 1, 'yes'], [1, 0, 'no'], [0, 1, 'no'], [0, 1, 'no']] # 下面的标签labels主要是对应dataset上的1和0,yes和no代表的是标签 labels = ['no surfacing','flippers'] return dataSet, labels //计算数据集的信息熵 def calcShannonEnt(dataSet): numEntries = len(dataSet) labelCounts = {} for featVec in dataSet: //主要是实现对标签的计数 currentLabel = featVec[-1]//这里对应数据标签 if currentLabel not in labelCounts.keys(): //当前的标签还不存在在labelcounts中 labelCounts[currentLabel] = 0 labelCounts[currentLabel] += 1 shannonEnt = 0.0 for key in labelCounts://计算信息熵 //每个标签所占比率计算 prob = float(labelCounts[key])/numEntries shannonEnt -= prob * log(prob,2) return shannonEnt //按照不同的属性列划分数据 axis--列索引,value--当前的列所对应的数据 def splitDataSet(dataSet, axis, value): retDataSet = [] for featVec in dataSet: //属性列中不同的数据进行不同的划分 if featVec[axis] == value: //数据的从新组合--去掉当前的value。 //[1,2,3]-->[1,3]-->用数值2去划分 reducedFeatVec = featVec[:axis] reducedFeatVec.extend(featVec[axis+1:]) retDataSet.append(reducedFeatVec) return retDataSet //选择最好的划分属性所对应的索引-->也就是选择划分前后entory变化最大的划分 def chooseBestFeatureToSplit(dataSet): numFeatures = len(dataSet[0]) - 1//特征的个数 baseEntropy = calcShannonEnt(dataSet)//计算当前data的entory bestInfoGain = 0.0; bestFeature = -1 for i in range(numFeatures)://对不同的特征进行遍历 featList = [example[i] for example in dataSet]//找出当前特征下所对应的数值 uniqueVals = set(featList)//去掉相同的数值 newEntropy = 0.0 for value in uniqueVals: //对特征i下不同的value进行划分数据,在计算划分之后的entory subDataSet = splitDataSet(dataSet, i, value) //划分之后每个数据集所占的比例 prob = len(subDataSet)/float(len(dataSet)) //计算划分之后的entory newEntropy += prob * calcShannonEnt(subDataSet) //计算划分前后entory的差 infoGain = baseEntropy - newEntropy if (infoGain > bestInfoGain): bestInfoGain = infoGain bestFeature = i return bestFeature //考虑到存在就算划分到最后,有些节点的还会存在两种以上的label //那就找出划分之后节点中label最多的那个label def majorityCnt(classList): classCount={} for vote in classList://计算每个label所对应的个数 if vote not in classCount.keys(): classCount[vote] = 0 classCount[vote] += 1 //进行排序 sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True) return sortedClassCount[0][0] def createTree(dataSet,labels): //找出当前数据中存在的labels classList = [example[-1] for example in dataSet] //只有一种label的话也就代表当前的data停止划分 if classList.count(classList[0]) == len(classList): return classList[0] //当前的data中只有一个特征,就不要再划分了。 if len(dataSet[0]) == 1: return majorityCnt(classList) //找出最好的划分特征索引 bestFeat = chooseBestFeatureToSplit(dataSet) //得到特征 bestFeatLabel = labels[bestFeat] //把当前的特征作为tree的根 myTree = {bestFeatLabel:{}} del(labels[bestFeat])//当前的label已经划分过之后就不会再划分,删除 //得到索引所对应的全部属性值 featValues = [example[bestFeat] for example in dataSet] uniqueVals = set(featValues) for value in uniqueVals: subLabels = labels[:]// 因为当列表在作为参数的时候,传递的是引用,会改变原有值,所以进行拷贝 myTree[bestFeatLabel][value] = createTree(splitDataSet(dataSet, bestFeat, value),subLabels) return myTree
相关文章推荐
- python随机数
- PythonChallenge Mission 8
- Python自然语言处理-系列一
- PythonChallenge Mission 7
- Apriori2(关联规则)
- PythonChallenge Mission 6
- Python之模块篇
- Apriori算法
- python函数传参是传值还是传引用?
- Python学习笔记——语法基础
- python的reduce函数
- Python学习:常见的内建模块(1)
- python使用select监听非阻塞socket遇到的问题
- python小练习之将字符串转换成第一个字母大写后面字母小写的形式
- 『Python』 多线程 共享变量的实现
- 《与小卡特一起学Python》Code4 GUI easygui的使用
- 【转】Python @classmethod @staticmethod
- Windows8.1下安装theano和CUDA
- Python爬虫_自动下载图片
- python爬虫被封异常处理