C4.5决策树代码详细解析以及C4.5程序调用(正确的代码!!!)_c语言训练决策树回归器代码-程序员宅基地

技术标签: C4.5  

正确的代码传上来了,对上一篇博客中刚提到的几点错误做了更改,都是一些比较小的细节,可能不仔细看看不出来,可以和上文对比一下....不过本次用了新的数据集用来生成决策树,亲测正确!数据集也会放上来.....

C4.5代码:

    function test_targets = Use_C4_5(train_patterns, train_targets, test_patterns, inc_node, Nu)  
      
    % Classify using Quinlan's C4.5 algorithm  
    % Inputs:  
    %   training_patterns   - Train patterns 训练样本  每一列代表一个样本 每一行代表一个特征
    %   training_targets    - Train targets  1×训练样本个数 每个训练样本对应的判别值
    %   test_patterns       - Test  patterns 测试样本,每一列代表一个样本  
    %   inc_node            - Percentage of incorrectly assigned samples at a node  一个节点上未正确分配的样本的百分比
    %   inc_node为防止过拟合,表示样本数小于一定阈值结束递归,可设置为5-10
    %   注意inc_node设置太大的话会导致分类准确率下降,太小的话可能会导致过拟合  
    %  Nu is to determine whether the variable is discrete or continuous (the value is always set to 10)  
    %  Nu用于确定变量是离散还是连续(该值始终设置为10)
    %  这里用10作为一个阈值,如果某个特征的无重复的特征值的数目比这个阈值还小,就认为这个特征是离散的
    % Outputs  
    %   test_targets        - Predicted targets 1×测试样本个数 得到每个测试样本对应的判别值
    %   也就是输出所有测试样本最终的判别情况
      
    %NOTE: In this implementation it is assumed that a pattern vector with fewer than 10 unique values (the parameter Nu)  
    %is discrete, and will be treated as such. Other vectors will be treated as continuous  
    % 在该实现中,假设具有少于10个无重复值的特征向量(参数Nu)是离散的。 其他向量将被视为连续的
  
    [Ni, M]     = size(train_patterns); %M是训练样本数,Ni是训练样本维数,即是特征数目
    inc_node    = inc_node*M/100;  % 5*训练样本数目/100
      
    %Find which of the input patterns are discrete, and discretisize the corresponding dimension on the test patterns  
    %查找哪些输入模式(特征)是离散的,并离散测试模式上的相应维
    discrete_dim = zeros(1,Ni); %用于记录每一个特征是否是离散特征,初始化都记为0,代表都是连续特征,
    %如果后面更改,则意味着是离散特征,这个值会更改为这个离散特征的无重复特征值的数目 
    for i = 1:Ni  %遍历每个特征
        Ub = unique(train_patterns(i,:));  %取每个特征的不重复的特征值构成的向量 
        Nb = length(Ub);    %得到无重复的特征值的数目
        if (Nb <= Nu)  %如果这个特征的无重复的特征值的数目比这个阈值还小,就认为这个特征是离散的  
            %This is a discrete pattern  
            discrete_dim(i) = Nb; %得到训练样本中,这个特征的无重复的特征值的数目 存放在discrete_dim(i)中,i表示第i个特征
%             dist            = abs(ones(Nb ,1)*test_patterns(i,:) - Ub'*ones(1, size(test_patterns,2))); 
%             %前面是把测试样本中,这个特征的那一行复制成Nb行,Nb是训练样本的这个特征中,无重复的特征值的数目
%             %后面是把这几个无重复的特征值构成的向量复制成测试样本个数列
%             %求这两个矩阵相应位置差的绝对值
%             [m, in]         = min(dist);  %找到每一列绝对差的最小值,构成m(1×样本数目)   并找到每一列绝对差最小值所在行的位置,构成in(1×样本数目)
%             %其实,这个in的中每个值就是代表了每个测试样本的特征值等于无重复的特征值中的哪一个或者更接近于哪一个
%             %如=3,就是指这个特征值等于无重复的特征值向量中的第3个或者更接近于无重复的特征值向量中的第3个
%             test_patterns(i,:)  = Ub(in);  %得到这个离散特征
        end  
    end  
      
    %Build the tree recursively  递归地构造树
    disp('Building tree')  
    tree            = make_tree(train_patterns, train_targets, inc_node, discrete_dim, max(discrete_dim), 0);  
    
    %加入悲观剪枝的操作
    %在完全生长的决策树的基础上,对生长后分类效果不佳的子树进行修剪,减小决策树的复杂度,降低过拟合的影响
%     treeplot(tree);
    
    %Classify test samples  
    disp('Classify test samples using the tree')  
    test_targets    = use_tree(test_patterns, 1:size(test_patterns,2), tree, discrete_dim, unique(train_targets));  
    %1:size(test_patterns,2)其实是索引
    %END  Use_C4_5
      
    
    function targets = use_tree(patterns, indices, tree, discrete_dim, Uc)  
    %Classify recursively using a tree  
      
    targets = zeros(1, size(patterns,2)); %设置每个样本的初始预测标签都是0 
      
    if (tree.dim == 0)  %这说明达到了树的叶子节点
        %Reached the end of the tree  
        targets(indices) = tree.child;  %得到样本对应的标签是tree.child
        return  
    end  
      
    %This is not the last level of the tree, so:  
    %First, find the dimension we are to work on  
    dim = tree.dim;  %得到分裂特征
    dims= 1:size(patterns,1);  %得到特征索引
      
    %And classify according to it  根据得到的决策树对测试样本进行分类
    if (discrete_dim(dim) == 0) %如果当前分裂特征是个连续特征 
        %Continuous pattern  
        in              = indices(find(patterns(dim, indices) <= tree.split_loc));  %找到当前测试样本中这个特征的特征值<=分裂值的样本索引
        targets     = targets + use_tree(patterns(dims, :), in, tree.child(1), discrete_dim(dims), Uc);  %对这部分样本再分叉
        in              = indices(find(patterns(dim, indices) >  tree.split_loc));  %找到当前测试样本中这个特征的特征值>分裂值的样本索引
        targets     = targets + use_tree(patterns(dims, :), in, tree.child(2), discrete_dim(dims), Uc);  %对这部分样本再分叉 
    else  %如果当前分裂特征是个离散特征
        %Discrete pattern  
        Uf              = unique(patterns(dim,:)); %得到这个样本集中这个特征的无重复特征值
        for i = 1:length(Uf)  %遍历每个特征值  
            if any(Uf(i) == tree.Nf)  %tree.Nf为树的分类特征向量 当前所有样本的这个特征的特征值
                in      = indices(find(patterns(dim, indices) == Uf(i)));  %找到当前测试样本中这个特征的特征值==分裂值的样本索引
                targets = targets + use_tree(patterns(dims, :), in, tree.child(find(Uf(i)==tree.Nf)), discrete_dim(dims), Uc);%对这部分样本再分叉 
            end  
        end  
    end       
    %END use_tree  
      
    
    function tree = make_tree(patterns, targets, inc_node, discrete_dim, maxNbin, base)  
%         make_tree(train_patterns, train_targets, inc_node, discrete_dim, max(discrete_dim), 0);  
    %Build a tree recursively   递归地构造树
      
    [Ni, L]                     = size(patterns);  %%L为当前的样本总数,Ni为特征数目
    Uc                          = unique(targets);  %训练样本对应的判别标签   无重复的取得这些标签  也就是得到判别标签的个数
    tree.dim                    = 0;  %初始化树的分裂特征为第0个
    %tree.child(1:maxNbin)  = zeros(1,maxNbin);  
    tree.split_loc              = inf;  %初始化分裂位置是inf
      
    if isempty(patterns) 
        return  
    end  
      
    %When to stop: If the dimension is one or the number of examples is small 
    % inc_node为防止过拟合,表示样本数小于一定阈值结束递归,可设置为5-10
    if ((inc_node > L) | (L == 1) | (length(Uc) == 1)) %如果剩余训练样本太小(小于inc_node),或只剩一个,或只剩一类标签,退出  
        H                   = hist(targets, length(Uc));  %统计样本的标签,分别属于每个标签的数目    H(1×标签数目)
        [m, largest]    = max(H); %得到包含样本数最多的那个标签的索引,记为largest 包含多少个样本,记为m
        tree.Nf         = [];  
        tree.split_loc  = [];  
        tree.child      = Uc(largest);%姑且直接返回其中包含样本数最多一类作为其标签 
        return  
    end  
      
    %Compute the node's I  
    for i = 1:length(Uc) %遍历判别标签的数目 
        Pnode(i) = length(find(targets == Uc(i))) / L;  %得到当前所有样本中 标签=第i个标签 的样本的数目  占样本总数的比例  存放在Pnode(i)中
    end  
%   计算当前的信息熵(分类期望信息)
% 	例如,数据集D包含14个训练样本,9个属于类别“Yes”,5个属于类别“No”,Inode = -9/14 * log2(9/14) - 5/14 * log2(5/14) = 0.940
    Inode = -sum(Pnode.*log(Pnode)/log(2));  
      
    %For each dimension, compute the gain ratio impurity %对于每维,计算杂质的增益比  对特征集中每个特征分别计算信息熵
    %This is done separately for discrete and continuous patterns     %对于离散和连续特征,分开计算
    delta_Ib    = zeros(1, Ni);  %Ni是特征维数  用于记录每个特征的信息增益率
    split_loc   = ones(1, Ni)*inf;  %初始化每个特征的分裂值是inf
      
    for i = 1:Ni %遍历每个特征  
        data    = patterns(i,:);  %得到当前所有样本的这个特征的特征值
        Ud      = unique(data);   %得到无重复的特征值构成向量Ud
        Nbins   = length(Ud);     %得到无重复的特征值的数目
        if (discrete_dim(i)) %如果这个特征是离散特征 
            %This is a discrete pattern  
            P   = zeros(length(Uc), Nbins);  %Uc是判别标签的个数   判别标签个数×无重复的特征值的数目
            for j = 1:length(Uc) %遍历每个标签  
                for k = 1:Nbins %遍历每个特征值  
                    indices     = find((targets == Uc(j)) & (patterns(i,:) == Ud(k)));  
                    % &适用于矩阵间的逻辑运算 &&不适用,只能用于单个元素 &的意思也是与
                    %找到 (样本标签==第j个标签  并且 当前所有样本的这个特征==第k个特征值) 的样本个数
                    P(j,k)  = length(indices);  %记为P(j,k)
                end  
            end  
            Pk          = sum(P);  %取P的每一列的和,也就是得到当前所有样本中,这个特征的特征值==这个特征值的样本数目   Pk(1×特征值数目)表示这个特征的特征值等于每个特征值的样本数目
            P1          = repmat(Pk, length(Uc), 1);  %把Pk复制成 判别标签个数 行
            P1          = P1 + eps*(P1==0);  %这主要在保证P1作被除数时不等于0
            P           = P./P1;  %得到当前所有样本中,这个特征的值等于每个特征值且标签等于每个标签的样本,占当前这个特征值中的样本的比例
            Pk          = Pk/sum(Pk);  %得到当前所有样本中,这个特征的值等于每个特征值的样本,占当前样本总数的比例
            info        = sum(-P.*log(eps+P)/log(2));  %对特征集中每个特征分别计算信息熵  info(1×特征值数目)
            delta_Ib(i) = (Inode-sum(Pk.*info))/(-sum(Pk.*log(eps+Pk)/log(2))); %计算得到当前特征的信息增益率
            %计算信息增益率(GainRatio),公式为Gain(A)/I(A),
            %其中Gain(A)=Inode-sum(Pk.*info)就是属性A的信息增益
            %其中I(A)=-sum(Pk.*log(eps+Pk)/log(2))为属性A的所包含的信息
        else   %对于连续特征(主要要找到合适的分裂值,使数据离散化)
            %This is a continuous pattern  
            P   = zeros(length(Uc), 2);  %   P(判别标签数目×2)  列1代表前..个样本中的标签分布情况   列2代表除前..个样本之外的标签分布情况  这个..就是各个分裂位置
      
            %Sort the patterns  
            [sorted_data, indices] = sort(data);  %data里存放的是当前所有训练样本的这个特征的特征值   从小到大排序  sorted_data是排序好的数据 indices是索引
            sorted_targets = targets(indices);  %当然,判别标签也要随着样本顺序调整而调整
      
            %Calculate the information for each possible split  计算分裂信息度量
              I = zeros(1,Nbins);
              delta_Ib_inter    = zeros(1, Nbins);
              for j = 1:Nbins-1
                  P(:, 1) = hist(sorted_targets(find(sorted_data <= Ud(j))) , Uc);  %记录<=当前特征值的样本的标签的分布情况
                  P(:, 2) = hist(sorted_targets(find(sorted_data > Ud(j))) , Uc);  %记录>当前特征值的样本的标签的分布情况
                  Ps      = sum(P)/L;  %sum(P)是得到分裂位置前面和后面各有样本数占当前样本总数的比例
                  P       = P/L;  %占样本总数的比例
                  Pk      = sum(P);   %%sum(P)是得到分裂位置前面和后面各有多少个样本 比例 
                  P1      = repmat(Pk, length(Uc), 1);  %把Pk复制成 判别标签个数 行
                  P1      = P1 + eps*(P1==0);  
                  info    = sum(-P./P1.*log(eps+P./P1)/log(2));  %计算信息熵(分类期望信息)
                  I(j)    = Inode - sum(info.*Ps);  %Inode-sum(info.*Ps)就是以第j个样本分裂的的信息增益   
                  delta_Ib_inter(j) =  I(j)/(-sum(Ps.*log(eps+Ps)/log(2))); %计算得到当前特征值的信息增益率
              end

            [~, s] = max(I);  %找到信息增益最大的划分方法  delta_Ib(i)中存放的是对于当前第i个特征而言,最大的信息增益作为这个特征的信息增益  s存放这个划分方法
            delta_Ib(i) = delta_Ib_inter(s);  %得到这个分类特征值对应的信息增益率
            split_loc(i) = Ud(s);  %对应特征i的划分位置就是能使信息增益最大的划分值
        end  
    end  
      
    %Find the dimension minimizing delta_Ib    %找到当前要作为分裂特征的特征
    [m, dim]    = max(delta_Ib);  %找到所有特征中最大的信息增益对应的特征,记为dim
    dims        = 1:Ni;  %Ni特征数目
    tree.dim    = dim;  %记为树的分裂特征
      
    %Split along the 'dim' dimension  
    Nf      = unique(patterns(dim,:));  %得到选择的这个作为分裂特征的特征的那一行  也就是得到当前所有样本的这个特征的特征值
    Nbins   = length(Nf);  %得到这个特征的无重复的特征值的数目
    tree.Nf = Nf;  %记为树的分类特征向量 当前所有样本的这个特征的特征值
    tree.split_loc      = split_loc(dim);  %把这个特征的划分位置记为树的分裂位置  可是如果选择的是一个离散特征,split_loc(dim)是初始值inf啊???
      
    %If only one value remains for this pattern, one cannot split it.  
    if (Nbins == 1)  %无重复的特征值的数目==1,即这个特征只有这一个特征值,就不能进行分裂
        H               = hist(targets, length(Uc));  %统计当前所有样本的标签,分别属于每个标签的数目    H(1×标签数目)
        [m, largest]    = max(H);  %得到包含样本数最多的那个标签的索引,记为largest 包含多少个样本,记为m
        tree.Nf         = [];  %因为不以这个特征进行分裂,所以Nf和split_loc都为空
        tree.split_loc  = [];  
        tree.child      = Uc(largest);  %姑且将这个特征的标签就记为包含样本数最多的那个标签
        return  
    end  
      
    if (discrete_dim(dim))  %如果当前选择的这个作为分裂特征的特征是个离散特征 
        %Discrete pattern  
        for i = 1:Nbins   %遍历这个特征下无重复的特征值的数目
            indices         = find(patterns(dim, :) == Nf(i));  %找到当前所有样本的这个特征的特征值为Nf(i)的索引们
            tree.child(i)   = make_tree(patterns(dims, indices), targets(indices), inc_node, discrete_dim(dims), maxNbin, base);%递归
            %因为这是个离散特征,所以分叉成Nbins个,分别针对每个特征值里的样本,进行再分叉
        end  
    else  
        %Continuous pattern  %如果当前选择的这个作为分裂特征的特征是个连续特征 
        indices1            = find(patterns(dim,:) <= split_loc(dim));  %找到特征值<=分裂值的样本的索引们
        indices2            = find(patterns(dim,:) > split_loc(dim));   %找到特征值>分裂值的样本的索引们
        if ~(isempty(indices1) | isempty(indices2))  %如果<=分裂值 >分裂值的样本数目都不等于0  
            tree.child(1)   = make_tree(patterns(dims, indices1), targets(indices1), inc_node, discrete_dim(dims), maxNbin, base+1);%递归 
            %对<=分裂值的样本进行再分叉
            tree.child(2)   = make_tree(patterns(dims, indices2), targets(indices2), inc_node, discrete_dim(dims), maxNbin, base+1);%递归 
            %对>分裂值的样本进行再分叉
        else  
            H               = hist(targets, length(Uc));  %统计当前所有样本的标签,分别属于每个标签的数目    H(1×标签数目)
            [m, largest]    = max(H);   %得到包含样本数最多的那个标签的索引,记为largest 包含多少个样本,记为m
            tree.child      = Uc(largest);  %姑且将这个特征的标签就记为包含样本数最多的那个标签  
            tree.dim                = 0;  %树的分裂特征记为0
        end  
    end  



仍然用上文的train_and_test_with_C4_5.m的数据集,得到的决策树和上文是不一样的,亲测这个是正确的.....



于是,我又用了一个新的数据集,如下:



这个数据集既有离散属性,也有连续属性,而且属性值涉及到了文字,所以需要在生成决策树之前,对数据进行处理,处理之后效果是图中这样的,不同属性类别用不同数字代替,涉及到的代码generate_for_data_with_C4_5.m如下:


clear all;
clc;
% 因为数据中既包含数字,又包含文字,所以获取到cell中,在进行处理;
% [~,~,rawdata] = xlsread('Training_data',1,'A2:F16');  %sheet1中的样本
[~,~,rawdata] = xlsread('Training_data',2,'B2:F15');  %sheet2中的样本
Training_data = inf(size(rawdata));  %一会儿用于存储最终要用的训练样本
judge = cell(1,size(rawdata,2)); %用于存储数据是否为数字,一会儿把不是文字的转换成数字
for i = 1:size(rawdata,2)
    judge{1,i} = rawdata{1,i};        
end
judge_num_ornot = cellfun(@(x)isnumeric(x),judge);%此时1代表对应的那一列属性为数字   0代表对应的那一列属性为文字
numer_index = find(judge_num_ornot == 1); %找到数值属性对应的列的索引
Text_index = find(judge_num_ornot == 0);%找到文字属性对应的列的索引
for i = 1:length(numer_index)
    trans_before = cell2mat(rawdata(:,numer_index(i)));
    Training_data(:,numer_index(i)) = trans_before; %数值属性不用处理,直接存到最终的Training_data中就可以了
end
% native2unicode([186 186])
%其实对文字属性的处理有问题,就是通过cell2mat这个函数只能获取每个属性值的第一个汉字或字符,后面都获取不到
% for i = 1:length(Text_index)
%     text_length = inf(1,size(rawdata,1));  %用于一会儿放每个属性值的文字有多长,如果一个属性中的属性值不一样长,还得处理
%     tmp = rawdata(:,Text_index(i));
%     for v = 1:length(tmp)
%         text_length(v) = length(tmp{v});  %记录当前属性的每个属性值的长度
%     end
%     if length(unique(text_length)) == 1     %如果一个属性中的属性值一样长,就可以用cell2mat这个函数
%          trans_before = cell2mat(tmp);
%     else   %如果一个属性中的属性值不一样长,比如,‘买’ ‘不买’ 这时需要以最长的字符串为标准,补全短的字符串
%         max_length = max(text_length);
% %         add_num=repmat(max_length,[1,length(tmp)])-text_length; %计算需要补充的空字符的个数
%         deal_index = find(text_length ~= max_length);
%         for u = 1:length(deal_index)
%             add_num = max_length - text_length(deal_index(u));
%             tmp(deal_index(u)) = cellfun(@strcat, tmp(deal_index(u)), cellstr(repmat('a',[1,add_num])),'Unif',0);
%         end
%         trans_before = cell2mat(tmp);    
%     end
%     trans_after = inf(size(rawdata,1),1);
%     a_num = unique(trans_before(:,Text_index(i)),'rows');
%     for j = 1:length(a_num)
%         index = find(rawdata(:,Text_index(i)) == a_num{j});
%         trans_after(index) = mark;     
%         fprintf('属性%d中的属性值"%s"用%d表示\n',Text_index(i),a_num(j),mark);
%         mark = mark+1;
%     end
%     Training_data(:,Text_index(i)) = trans_after;
% end
%以上内容是在对读入的数据作处理,因为有些属性是文字,要转换成不同的数字
for i = 1:length(Text_index)
    trans_after = inf(size(rawdata,1),1);
    a_num = unique(rawdata(:,Text_index(i)));
%     a_num = unique(trans_before,'rows'); %得到这个属性的不重复的属性值  文字属性一般都是离散属性
    mark = 1:length(a_num);
    for j = 1:length(a_num)
        for v = 1:size(rawdata,1)
            if strcmp(rawdata{v,Text_index(i)},a_num{j}) %两个字符串比较只能用strcmp,不能用==
                trans_after(v) = mark(j);
            end
        end
        fprintf('属性%d中的属性值"%s"用%d表示\n',Text_index(i),a_num{j},mark(j));
    end
    Training_data(:,Text_index(i)) = trans_after;
end



 train_patterns=Training_data(:,1:(size(Training_data,2)-1));  %得到训练样本
 train_targets=Training_data(:,size(Training_data,2))';   %得到训练样本的标签   1×训练样本数目
 test_patterns=[];
 test_targets_predict = Use_C4_5(train_patterns', train_targets, test_patterns', 5, 5);  
 

由此生成的决策树是这样的:


然后,又用了另一个数据集:


之前注释掉的代码在这里不太试用,主要是因为属性值的文字是被送入不同的cell中,这样就导致对不同文字属性值的识别只考虑到了第一个字母或者汉字,当然这里面没有涉及到两个不同属性值首字母相同的情况,这样的情况之前注释掉的代码是判断不出来的,所以修改了一下,也就是上面注释掉的一大段代码后面的几行,不知道说清楚了没有,看一下这个例子可能更明白一些:



得到的决策树是这样的:



决策树本身就是100%完美拟合训练样本的产物(尤其我设置的停止阈值比较小....),但是这会带来一个问题,如果训练样本中包含了一些错误,按照这种算法,这些错误也会100%一点不留得被决策树学习了,也就是产生了“过拟合”,所以需要进行剪枝。C4.5采用的是悲观剪枝,看完了很多博客都介绍的悲观剪枝的算法原理,不过我还没有用程序实现出来.....本系列待续.....QAQ

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/sgfmby1994/article/details/52963021

智能推荐

分布式光纤传感器的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告_预计2026年中国分布式传感器市场规模有多大-程序员宅基地

文章浏览阅读3.2k次。本文研究全球与中国市场分布式光纤传感器的发展现状及未来发展趋势,分别从生产和消费的角度分析分布式光纤传感器的主要生产地区、主要消费地区以及主要的生产商。重点分析全球与中国市场的主要厂商产品特点、产品规格、不同规格产品的价格、产量、产值及全球和中国市场主要生产商的市场份额。主要生产商包括:FISO TechnologiesBrugg KabelSensor HighwayOmnisensAFL GlobalQinetiQ GroupLockheed MartinOSENSA Innovati_预计2026年中国分布式传感器市场规模有多大

07_08 常用组合逻辑电路结构——为IC设计的延时估计铺垫_基4布斯算法代码-程序员宅基地

文章浏览阅读1.1k次,点赞2次,收藏12次。常用组合逻辑电路结构——为IC设计的延时估计铺垫学习目的:估计模块间的delay,确保写的代码的timing 综合能给到多少HZ,以满足需求!_基4布斯算法代码

OpenAI Manager助手(基于SpringBoot和Vue)_chatgpt网页版-程序员宅基地

文章浏览阅读3.3k次,点赞3次,收藏5次。OpenAI Manager助手(基于SpringBoot和Vue)_chatgpt网页版

关于美国计算机奥赛USACO,你想知道的都在这_usaco可以多次提交吗-程序员宅基地

文章浏览阅读2.2k次。USACO自1992年举办,到目前为止已经举办了27届,目的是为了帮助美国信息学国家队选拔IOI的队员,目前逐渐发展为全球热门的线上赛事,成为美国大学申请条件下,含金量相当高的官方竞赛。USACO的比赛成绩可以助力计算机专业留学,越来越多的学生进入了康奈尔,麻省理工,普林斯顿,哈佛和耶鲁等大学,这些同学的共同点是他们都参加了美国计算机科学竞赛(USACO),并且取得过非常好的成绩。适合参赛人群USACO适合国内在读学生有意向申请美国大学的或者想锻炼自己编程能力的同学,高三学生也可以参加12月的第_usaco可以多次提交吗

MySQL存储过程和自定义函数_mysql自定义函数和存储过程-程序员宅基地

文章浏览阅读394次。1.1 存储程序1.2 创建存储过程1.3 创建自定义函数1.3.1 示例1.4 自定义函数和存储过程的区别1.5 变量的使用1.6 定义条件和处理程序1.6.1 定义条件1.6.1.1 示例1.6.2 定义处理程序1.6.2.1 示例1.7 光标的使用1.7.1 声明光标1.7.2 打开光标1.7.3 使用光标1.7.4 关闭光标1.8 流程控制的使用1.8.1 IF语句1.8.2 CASE语句1.8.3 LOOP语句1.8.4 LEAVE语句1.8.5 ITERATE语句1.8.6 REPEAT语句。_mysql自定义函数和存储过程

半导体基础知识与PN结_本征半导体电流为0-程序员宅基地

文章浏览阅读188次。半导体二极管——集成电路最小组成单元。_本征半导体电流为0

随便推点

【Unity3d Shader】水面和岩浆效果_unity 岩浆shader-程序员宅基地

文章浏览阅读2.8k次,点赞3次,收藏18次。游戏水面特效实现方式太多。咱们这边介绍的是一最简单的UV动画(无顶点位移),整个mesh由4个顶点构成。实现了水面效果(左图),不动代码稍微修改下参数和贴图可以实现岩浆效果(右图)。有要思路是1,uv按时间去做正弦波移动2,在1的基础上加个凹凸图混合uv3,在1、2的基础上加个水流方向4,加上对雾效的支持,如没必要请自行删除雾效代码(把包含fog的几行代码删除)S..._unity 岩浆shader

广义线性模型——Logistic回归模型(1)_广义线性回归模型-程序员宅基地

文章浏览阅读5k次。广义线性模型是线性模型的扩展,它通过连接函数建立响应变量的数学期望值与线性组合的预测变量之间的关系。广义线性模型拟合的形式为:其中g(μY)是条件均值的函数(称为连接函数)。另外,你可放松Y为正态分布的假设,改为Y 服从指数分布族中的一种分布即可。设定好连接函数和概率分布后,便可以通过最大似然估计的多次迭代推导出各参数值。在大部分情况下,线性模型就可以通过一系列连续型或类别型预测变量来预测正态分布的响应变量的工作。但是,有时候我们要进行非正态因变量的分析,例如:(1)类别型.._广义线性回归模型

HTML+CSS大作业 环境网页设计与实现(垃圾分类) web前端开发技术 web课程设计 网页规划与设计_垃圾分类网页设计目标怎么写-程序员宅基地

文章浏览阅读69次。环境保护、 保护地球、 校园环保、垃圾分类、绿色家园、等网站的设计与制作。 总结了一些学生网页制作的经验:一般的网页需要融入以下知识点:div+css布局、浮动、定位、高级css、表格、表单及验证、js轮播图、音频 视频 Flash的应用、ul li、下拉导航栏、鼠标划过效果等知识点,网页的风格主题也很全面:如爱好、风景、校园、美食、动漫、游戏、咖啡、音乐、家乡、电影、名人、商城以及个人主页等主题,学生、新手可参考下方页面的布局和设计和HTML源码(有用点赞△) 一套A+的网_垃圾分类网页设计目标怎么写

C# .Net 发布后,把dll全部放在一个文件夹中,让软件目录更整洁_.net dll 全局目录-程序员宅基地

文章浏览阅读614次,点赞7次,收藏11次。之前找到一个修改 exe 中 DLL地址 的方法, 不太好使,虽然能正确启动, 但无法改变 exe 的工作目录,这就影响了.Net 中很多获取 exe 执行目录来拼接的地址 ( 相对路径 ),比如 wwwroot 和 代码中相对目录还有一些复制到目录的普通文件 等等,它们的地址都会指向原来 exe 的目录, 而不是自定义的 “lib” 目录,根本原因就是没有修改 exe 的工作目录这次来搞一个启动程序,把 .net 的所有东西都放在一个文件夹,在文件夹同级的目录制作一个 exe._.net dll 全局目录

BRIEF特征点描述算法_breif description calculation 特征点-程序员宅基地

文章浏览阅读1.5k次。本文为转载,原博客地址:http://blog.csdn.net/hujingshuang/article/details/46910259简介 BRIEF是2010年的一篇名为《BRIEF:Binary Robust Independent Elementary Features》的文章中提出,BRIEF是对已检测到的特征点进行描述,它是一种二进制编码的描述子,摈弃了利用区域灰度..._breif description calculation 特征点

房屋租赁管理系统的设计和实现,SpringBoot计算机毕业设计论文_基于spring boot的房屋租赁系统论文-程序员宅基地

文章浏览阅读4.1k次,点赞21次,收藏79次。本文是《基于SpringBoot的房屋租赁管理系统》的配套原创说明文档,可以给应届毕业生提供格式撰写参考,也可以给开发类似系统的朋友们提供功能业务设计思路。_基于spring boot的房屋租赁系统论文