决策树ID3基本代码,周志华《机器学习》练习

# -*- coding: utf-8 -*-
"""
Created on Wed Dec 28 09:33:11 2016

@author: ZQ
"""
import numpy as np

#计算信息熵
def Infor_Ent(data):
    data_count = len(data)
    labelcounts = {}
    for featvec in data:
        currentlabel = featvec[-1]
        if currentlabel not in labelcounts.keys():
            labelcounts[currentlabel] = 0
        labelcounts[currentlabel] += 1
    ent = 0.0
    for key in labelcounts:
        prob = float(labelcounts[key])/data_count
        ent -= prob*np.log2(prob)
    return ent

#计算标签的信息增益中的被减数
def Infor_Gain_Label(data,axis):
    featset = set(data[:,axis])
    data_count = len(data)
    v_ent = 0.0
    for f in featset:
        f_data = []
        f_count = 0
        for featvec in data:
            if featvec[axis] == f:
                f_count += 1
                f_data.append(featvec)
        v_ent += f_count/data_count*Infor_Ent(f_data)      
    return v_ent

#计算连续值中信息增益中的被减数(由于数据中浮点数是str类型,需要特殊处理)
def Infor_Gain_Num(data,axis):
    data_count = len(data)
    feat_lsit = list(map(float,data[:,axis]))
    T_list = []
    maxGain_inf_T = 0
    maxGain_inf = 1
    v_ent = 0.0
    for i in range(len(feat_lsit)-1):
        T_list.append((feat_lsit[i]+feat_lsit[i+1])/2)
    for t in T_list:
        f_gl = []
        f_gt = []
        f_count_gl = 0
        for featvec in data:
            if float(featvec[axis]) < t:
                f_count_gl += 1
                f_gl.append(featvec)
            else:
                f_gt.append(featvec)
        v_ent = f_count_gl/data_count*Infor_Ent(f_gl) + (data_count-f_count_gl)/data_count*Infor_Ent(f_gt)
        if v_ent < maxGain_inf:
            maxGain_inf_T = t
            maxGain_inf = v_ent
    return maxGain_inf_T,maxGain_inf

#寻找最佳分割属性        
def bestFeattosplit(data):
    Featlabel = data[0][:-1]
    # 用于统计非连续值的长度
    label_lengh = 0
    num_lengh = 0
    for l in Featlabel:
        if l == '密度' or l == '含糖量':            
            num_lengh += 1
        else:
            label_lengh += 1
    bestLabel = ''
    bestLabel_i = -1
    bestInfoGain = -1
    best_T = -1
    ent = Infor_Ent(data[1:])
    #print(label_lengh,num_lengh)
    for i in range(label_lengh):
        Gain_infor = ent - Infor_Gain_Label(data[1:],i)
        if Gain_infor > bestInfoGain:
            bestInfoGain = Gain_infor
            bestLabel = Featlabel[i]
            bestLabel_i = i
    for i in range(label_lengh,label_lengh+num_lengh):
        T,v_ent = Infor_Gain_Num(data[1:],i)
        Gain_infor = ent - v_ent
        if Gain_infor > bestInfoGain:
            bestInfoGain = Gain_infor
            bestLabel = Featlabel[i]
            best_T = T
            bestLabel_i = i
    return bestInfoGain,bestLabel,best_T,bestLabel_i

def creatTree(data):
    classList = [f[-1] for f in data[1:]]
    # 类别完全相同时就返回
    if classList.count(classList[0]) == len(classList):
        return classList[0]
    InfoGain,best_Label,best_T,best_i = bestFeattosplit(data)   
    tree = {best_Label:{}}
    print(best_Label)
    if best_T != -1:
        # 大于或者小于处理
        subdata_gl = []
        subdata_gt = []
        subdata_gl.append(data[0])
        subdata_gt.append(data[0])
        for f in data[1:]:
            if float(f[best_i]) > best_T:
                subdata_gt.append(f)
            else:
                subdata_gl.append(f)
        #temp_label = best_Label
        #InfoGain,best_Label,best_T,best_i = bestFeattosplit(subdata_gl)
        subdata_gl = np.delete(subdata_gl,best_i,axis = 1)
        tree[best_Label]['<'+str(best_T)] = creatTree(subdata_gl)
        #InfoGain,best_Label,best_T,best_i = bestFeattosplit(subdata_gt)
        subdata_gt = np.delete(subdata_gt,best_i,axis = 1)
        tree[best_Label]['>'+str(best_T)] = creatTree(subdata_gt)
    else:
        featValues = [f[best_i] for f in data[1:]]
        uniqueVals = set(featValues)
        # 移除已经使用的属性,对每个属性值进行分割
        for value in uniqueVals: 
            subdata = []
            subdata.append(data[0])
            for f in data[1:]:
                if f[best_i] == value:
                    subdata.append(f)
            subdata = np.delete(subdata,best_i,axis = 1)
            #temp_label = best_Label
            #InfoGain,best_Label,best_T,best_i = bestFeattosplit(subdata)   
            tree[best_Label][value] = creatTree(subdata)
    return tree
def loadData():
    data = []
    with open('watermelon3.0.txt') as f:
        for line in f.readlines():
            word = line.strip().split('\t')[1:]
            data.append(word)
    return np.array(data)

if __name__ == '__main__':
    data = loadData()
    #InfoGain,Label,T = bestFeattosplit(data)
    tree = creatTree(data)

中间一些部分参考了《机器学习实战》中决策树这一章节的相关代码。
该代码个人觉得有些问题,希望大家多多指正
数据如下:
编号	色泽	根蒂	敲声	纹理	脐部	触感	密度	含糖量	好瓜
1	青绿	蜷缩	浊响	清晰	凹陷	硬滑	0.697	0.46	是
2	乌黑	蜷缩	沉闷	清晰	凹陷	硬滑	0.774	0.376	是
3	乌黑	蜷缩	浊响	清晰	凹陷	硬滑	0.634	0.264	是
4	青绿	蜷缩	沉闷	清晰	凹陷	硬滑	0.608	0.318	是
5	浅白	蜷缩	浊响	清晰	凹陷	硬滑	0.556	0.215	是
6	青绿	稍蜷	浊响	清晰	稍凹	软粘	0.403	0.237	是
7	乌黑	稍蜷	浊响	稍糊	稍凹	软粘	0.481	0.149	是
8	乌黑	稍蜷	浊响	清晰	稍凹	硬滑	0.437	0.211	是
9	乌黑	稍蜷	沉闷	稍糊	稍凹	硬滑	0.666	0.091	否
10	青绿	硬挺	清脆	清晰	平坦	软粘	0.243	0.267	否
11	浅白	硬挺	清脆	模糊	平坦	硬滑	0.245	0.057	否
12	浅白	蜷缩	浊响	模糊	平坦	软粘	0.343	0.099	否
13	青绿	稍蜷	浊响	稍糊	凹陷	硬滑	0.639	0.161	否
14	浅白	稍蜷	沉闷	稍糊	凹陷	硬滑	0.657	0.198	否
15	乌黑	稍蜷	浊响	清晰	稍凹	软粘	0.36	0.37	否
16	浅白	蜷缩	浊响	模糊	平坦	硬滑	0.593	0.042	否
17	青绿	蜷缩	沉闷	稍糊	稍凹	硬滑	0.719	0.103	否




  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
机器学习是一门多领域交叉学科,涉及概率论、统计学、逼近论、凸分析、算法复杂度理论等多门学科。它专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能。机器学习是人工智能的核心,是使计算机具有智能的根本途径。 随着统计学的发展,统计学习在机器学习中占据了重要地位,支持向量机(SVM)、决策树和随机森林等算法的提出和发展,使得机器学习能够更好地处理分类、回归和聚类等任务。进入21世纪,深度学习成为机器学习领域的重要突破,采用多层神经网络模型,通过大量数据和强大的计算能力来训练模型,在计算机视觉、自然语言处理和语音识别等领域取得了显著的成果。 机器学习算法在各个领域都有广泛的应用,包括医疗保健、金融、零售和电子商务、智能交通、生产制造等。例如,在医疗领域,机器学习技术可以帮助医生识别医疗影像,辅助诊断疾病,预测病情发展趋势,并为患者提供个性化的治疗方案。在金融领域,机器学习模型可以分析金融数据,识别潜在风险,预测股票市场的走势等。 未来,随着传感器技术和计算能力的提升,机器学习将在自动驾驶、智能家居等领域发挥更大的作用。同时,随着物联网技术的普及,机器学习将助力智能家居设备实现更加智能化和个性化的功能。在工业制造领域,机器学习也将实现广泛应用,如智能制造、工艺优化和质量控制等。 总之,机器学习是一门具有广阔应用前景和深远影响的学科,它将持续推动人工智能技术的发展,为人类社会的进步做出重要贡献。
机器学习是一门多领域交叉学科,涉及概率论、统计学、逼近论、凸分析、算法复杂度理论等多门学科。它专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能。机器学习是人工智能的核心,是使计算机具有智能的根本途径。 随着统计学的发展,统计学习在机器学习中占据了重要地位,支持向量机(SVM)、决策树和随机森林等算法的提出和发展,使得机器学习能够更好地处理分类、回归和聚类等任务。进入21世纪,深度学习成为机器学习领域的重要突破,采用多层神经网络模型,通过大量数据和强大的计算能力来训练模型,在计算机视觉、自然语言处理和语音识别等领域取得了显著的成果。 机器学习算法在各个领域都有广泛的应用,包括医疗保健、金融、零售和电子商务、智能交通、生产制造等。例如,在医疗领域,机器学习技术可以帮助医生识别医疗影像,辅助诊断疾病,预测病情发展趋势,并为患者提供个性化的治疗方案。在金融领域,机器学习模型可以分析金融数据,识别潜在风险,预测股票市场的走势等。 未来,随着传感器技术和计算能力的提升,机器学习将在自动驾驶、智能家居等领域发挥更大的作用。同时,随着物联网技术的普及,机器学习将助力智能家居设备实现更加智能化和个性化的功能。在工业制造领域,机器学习也将实现广泛应用,如智能制造、工艺优化和质量控制等。 总之,机器学习是一门具有广阔应用前景和深远影响的学科,它将持续推动人工智能技术的发展,为人类社会的进步做出重要贡献。
机器学习涵盖了许多不同的算法,用于解决各种类型的问题。以下是一些常见的机器学习算法: 监督学习算法:线性回归(Linear Regression)逻辑回归(Logistic Regression)决策树(Decision Trees)随机森林(Random Forests)支持向量机(Support Vector Machines)朴素贝叶斯(Naive Bayes)K近邻算法(K-Nearest Neighbors)深度学习(Deep Learning)算法,如神经网络(Neural Networks) 无监督学习算法:K均值聚类(K-Means Clustering)层次聚类(Hierarchical Clustering)高斯混合模型(Gaussian Mixture Models)主成分分析(Principal Component Analysis,PCA)关联规则学习(Association Rule Learning) 这只是机器学习领域中的一小部分算法,还有许多其他的算法和技术。根据问题的性质和数据的特点,选择适合的算法是非常重要的。不同的算法有不同的假设和适用场景,因此在学习和应用机器学习算法时,需要综合考虑问题的需求和数据的特点。机器学习(Machine learning)是人工智能的子集,是实现人工智能的一种途径,但并不是唯一的途径。它是一门专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能的学科。大概在上世纪80年代开始蓬勃发展,诞生了一大批数学统计相关的机器学习模型。 深度学习(Deep learning)是机器学习的子集,灵感来自人脑,由人工神经网络(ANN)组成,它模仿人脑中存在的相似结构。在深度学习中,学习是通过相互关联的「神经元」的一个深层的、多层的「网络」来进行的。「深度」一词通常指的是神经网络中隐藏层的数量。大概在2012年以后爆炸式增长,广泛应用在很多的场景中。机器学习研究的是计算机怎样模拟人类的学习行为,以获取新的知识或技能,并重新组织已有的知识结构,使之不断改善自身。 从实践的意义上来说,机器学习是在大数据的支撑下,通过各种算法让机器对数据进行深层次的统计分析以进行「自学」,使得人工智能系统获得了归纳推理和决策能力。
以下是朴素贝叶斯分类器的伪代码: 1. 训练阶段: (1)对于每个类别 i,计算先验概率P(Y=i)。 (2)对于每个特征 j,计算在每个类别 i 下该特征的条件概率P(Xj=x|Y=i)。 2. 测试阶段: (1)对于输入样本 x,计算该样本属于每个类别 i 的条件概率P(Y=i|X=x)。 (2)将样本分到概率最大的类别中。 下面是朴素贝叶斯分类器的 C++ 代码实现,其中假设特征和类别都是离散的: ``` #include <iostream> #include <vector> #include <map> #include <cmath> using namespace std; // 计算先验概率 map<int, double> cal_prior_prob(vector<int>& labels) { map<int, double> prior_prob; int total = labels.size(); for (int i = 0; i < total; i++) { int label = labels[i]; if (prior_prob.find(label) == prior_prob.end()) { prior_prob[label] = 0.0; } prior_prob[label] += 1.0; } for (auto iter = prior_prob.begin(); iter != prior_prob.end(); iter++) { iter->second /= total; } return prior_prob; } // 计算条件概率 map<int, map<int, double>> cal_cond_prob(vector<vector<int>>& features, vector<int>& labels) { map<int, map<int, double>> cond_prob; int total = labels.size(); int feature_num = features[0].size(); for (int i = 0; i < total; i++) { int label = labels[i]; if (cond_prob.find(label) == cond_prob.end()) { cond_prob[label] = map<int, double>(); } for (int j = 0; j < feature_num; j++) { int feature = features[i][j]; if (cond_prob[label].find(j) == cond_prob[label].end()) { cond_prob[label][j] = map<int, double>(); } if (cond_prob[label][j].find(feature) == cond_prob[label][j].end()) { cond_prob[label][j][feature] = 0.0; } cond_prob[label][j][feature] += 1.0; } } for (auto iter1 = cond_prob.begin(); iter1 != cond_prob.end(); iter1++) { int label = iter1->first; for (auto iter2 = iter1->second.begin(); iter2 != iter1->second.end(); iter2++) { int feature = iter2->first; int feature_total = iter2->second.size(); for (auto iter3 = iter2->second.begin(); iter3 != iter2->second.end(); iter3++) { iter3->second /= feature_total; } } } return cond_prob; } // 预测 int predict(vector<int>& feature, map<int, double>& prior_prob, map<int, map<int, double>>& cond_prob) { int label = -1; double max_prob = -1.0; for (auto iter = prior_prob.begin(); iter != prior_prob.end(); iter++) { int cur_label = iter->first; double cur_prob = log(iter->second); for (int i = 0; i < feature.size(); i++) { cur_prob += log(cond_prob[cur_label][i][feature[i]]); } if (cur_prob > max_prob) { max_prob = cur_prob; label = cur_label; } } return label; } // 测试 void test(vector<vector<int>>& features, vector<int>& labels, map<int, double>& prior_prob, map<int, map<int, double>>& cond_prob) { int total = labels.size(); int correct = 0; for (int i = 0; i < total; i++) { int predict_label = predict(features[i], prior_prob, cond_prob); if (predict_label == labels[i]) { correct++; } } cout << "Accuracy: " << (double)correct / total << endl; } int main() { // 读取数据,features存放特征,labels存放类别 vector<vector<int>> features; vector<int> labels; // 训练 map<int, double> prior_prob = cal_prior_prob(labels); map<int, map<int, double>> cond_prob = cal_cond_prob(features, labels); // 测试 test(features, labels, prior_prob, cond_prob); return 0; } ``` 注意:这里的代码只是朴素贝叶斯分类器的一种实现方式,可能还有其他实现方式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值