欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

python基础学习——第四天(决策树)

程序员文章站 2024-02-11 13:36:16
...

1.列表生成式:res=[x*x for x in range(5)]
2.匿名函数:
与普通函数的区别

#普通函数
1. def func(x,y):
       return x+y
#匿名函数
2. lambda x,y: x+y

3.决策树:
  1.基本算法是贪心(也就是每次取局部最优)
  2.在其生成过程中,分割方法即属性选择度量是关键。通过属性选择度量,选择出最好的将样本分类的属性。
  3.根据分割方法的不同,决策树可以分为两类:基于信息论的方法(较有代表性的是ID3、C4.5算法等)和最小GINI指标方法(常用的有CART、SLIQ及SPRINT算法等)。
4.决策树的结构

python基础学习——第四天(决策树)
5.决策树的基本算法(ID3):
  输入:训练样本
  输出:决策树
  什么是信息熵?
  根据香农(Shannon)给出的信息熵公式,对于任意一个随机变量X,它的信息熵定义如下,单位为比特(bit):
  用通俗的话来说:每种可能出现的情况概率乘以该概率的对数(一般以2为底),依次求和,最后取反
python基础学习——第四天(决策树)

  处理流程:
  1.得到结构化的数据集
  2.计算在当前数据集中哪个属性所对应的信息增益最大
    2.1对该数据集未进行属性划分前计算(基)信息熵
    2.2对该数据集按某个属性划分后计算划分后的信息熵
    2.3这个属性所对应的信息增益 就是未划分属性的信息熵-划分属性的信息熵
    2.4选择信息增益最大的那个属性作为此次划分的属性
  3.在数据集中把已经划分的属性列去除
  4.递归往下进行构造

6.练习

'''
1.读取test2.csv文件中的内容,对列M的平均学分绩点进行统计,规定GPA>3.5为优秀,
GPA>3.0为良好,GPA>2.0为合格,否则为不合格,统计每种类别的人数,并对平均学分绩点
这列属性求它的熵
'''
import csv
import math
def getEntropy(dic):
    sum=0
    for i in dic.values():
        sum+=i
    entropy=0
    for i in dic:
        prob=dic[i]/sum
        entropy+=prob*math.log(prob,2)
    return -entropy

file="D:\\winter_python\\test2.csv"
with open('D:\\winter_python\\test2.csv') as f:
    f_csv = csv.reader(f)
    next(f_csv)
    next(f_csv)
    gpa=[]
    for row in f_csv:
        if row[12]!='':
            gpa.append(float(row[12]))
#print(gpa)
dic={}
for i in gpa:
    if i >3.5:
        if '优秀' in dic.keys():
            dic['优秀']+=1
        else:
            dic['优秀']=1
    elif i>3.0:
        if '良好' in dic.keys():
            dic['良好']+=1
        else:
            dic['良好']=1
    elif i >2.0:
        if '合格' in dic.keys():
            dic['合格']+=1
        else:
            dic['合格']=1
    else:
        if '不合格' in dic.keys():
            dic['不合格']+=1
        else:
            dic['不合格']=1
#print(dic)
res=getEntropy(dic)
print(res)
'''
2.读取test2.csv文件中的ED列,EE列,输出2016年和2017年入馆次数前10分别是多少次
2016入馆次数 2017入馆次数
ED--> 5*26+3=107
'''
with open('D:\\winter_python\\test2.csv') as f:
    f_csv = csv.reader(f)
    next(f_csv)
    next(f_csv)
    cnt2016=[]
    cnt2017=[]
    for row in f_csv:
        if row[133]!='':
            cnt2016.append(int(row[133]))
        if row[134]!='':
            cnt2017.append(int(row[134]))
cnt2016.sort(reverse=True)
cnt2017.sort(reverse=True)
print(cnt2016[:10])
print(cnt2017[:10])
'''
4.读取0120.txt中的文件,构造成一个二维数组dataset(list嵌套list),
根据读取的元素计算未进行属性划分前的信息熵,以及按对应属性划分后所对应的信息熵,
通过信息熵作差求得每种属性所对应的信息增益,将计算值和PPT上的进行核对
'''
import math
def calcShannonEnt(dataSet):
    numEntries = len(dataSet)
    labelCounts = {}
    for featVec in dataSet: #统计每个类标签出现的次数,'yes'2次,'no'3次
        currentLabel = featVec[-1]
        if currentLabel not in labelCounts.keys(): labelCounts[currentLabel] = 0
        labelCounts[currentLabel] += 1
    shannonEnt = 0.0
    for key in labelCounts:
        prob = float(labelCounts[key])/numEntries
        shannonEnt -= prob * math.log(prob,2) 
    return shannonEnt


def chooseBestFeatureToSplit(dataSet):
    GainList=[]
    numFeatures = len(dataSet[0]) - 1      #返回属性个数
    baseEntropy = calcShannonEnt(dataSet)     #计算分裂前的信息熵
    bestInfoGain = 0.0; bestFeature = -1
    for i in range(numFeatures):        
        featList = [example[i] for example in dataSet]  #获取第i个属性的所有可能取值
        uniqueVals = set(featList)      #去除重复取值 
        newEntropy = 0.0
        for value in uniqueVals:      #计算按第i个属性划分后的信息熵
            subDataSet = splitDataSet(dataSet, i, value)
            prob = len(subDataSet)/float(len(dataSet))
            newEntropy += prob * calcShannonEnt(subDataSet)     
        infoGain = baseEntropy - newEntropy   #计算信息增益
        GainList.append(infoGain)
        if (infoGain > bestInfoGain):   #计算最好的信息增益及相应的属性
            bestInfoGain = infoGain         
            bestFeature = i
    print("GainList: ",GainList)
    return bestFeature                      


def splitDataSet(dataSet, axis, value):  #将dataSet中第axis列等于value的数据子集抽取后返回(去除第axis列)
    retDataSet = []
    for featVec in dataSet:
        if featVec[axis] == value:
            reducedFeatVec = featVec[:axis]    
            reducedFeatVec.extend(featVec[axis+1:])
            retDataSet.append(reducedFeatVec)
    return retDataSet


def solve(dataset):
    dic={}
    for i in dataset:
        label=i[-1]
        if label in dic.keys():
            dic[label]+=1
        else:
            dic[label]=1
    print(dic)
    baseEntropy=getEntropy(dic)

input=open("D:\\winter_python\\0120.txt")
res=input.readlines()
dataset=[]
for i in res:
    data=i.split()
    dataset.append(data)
#print(dataset)
#res=splitDataSet(dataset,1,'female')
chooseBestFeatureToSplit(dataset)