zoukankan      html  css  js  c++  java
  • K-近邻分类法及tabulate、rng、categorical、varfun、discretize函数用法介绍

    原理:简单比喻为——人以群分,物以类聚。

    优点:对于类域的交叉或重叠较多的待分样本集来说,K-NN较其他方法更合适。

    缺点:计算量较大,因为会计算全体已知样本的距离。

    改进方法:

    (1)解决计算量大,事先对已知样本点进行剪辑,去除对分类作用不大的成分。

    (2)尽可能将计算压缩到接近测试样本领域的小范围内,避免盲目地与训练样本集中的每个样本进行距离计算。

    算法步骤:

    (1)初始化距离为最大值,计算未知样本和每个样本的距离dist.

    (2)得到目前k个最邻近样本的最大距离maxdist,若dist<maxdist,则将该训练样本作为K-近邻样本。

    (3)重复上述计算距离的步骤,直到所有未知样本与所有训练样本的距离计算完。

    (4)统计k个最近邻样本中每个类别出现的次数。

    (5)选择出现频率最大的类别作为未知样本的类别。

    实例介绍:

    根据客户的16个属性,为一家银行建一个分类器,判断客户是否愿意购买理财产品:

     1 %% ———————————机器学习———————————————%%
     2 %%%%%%%%%%%%%%%%%%%%%%%1.K-近邻分类%%%%%%%%%%%%%%%%%%%%%%%%%
     3 %16个属性分别为:
     4 %age   job   marital  education default  balance  housing loan   contact
     5 %day  month  duration  campaign    pdays    previous    poutcome    y(是否愿意)  
     6 load 'E:数学建模学习资料程序_MATLAB数学建模方法与实践_卓金武等Cha5Classification_method_examplesank.mat';%载入记录数据
     7 names = bank.Properties.VariableNames;%使用数据文件,记录自变量和因变量的属性名
     8 category = varfun(@iscellstr,bank,'Output','uniform'); %输出格式为数值格式。为字符串的返回结果为1,为数字的返回结果为0
     9 for i = find(category)
    10     bank.(names{i}) = categorical(bank.(names{i}));
    11     %将bank中的属性创建分类数组。bank.(names{i}) 的类别是bank.(names{i})经过分类后的唯一值且经过排序
    12 end
    13 catPred = category(1:end-1);
    14 rng('default');%设置随机数的生成方式,‘default’可以生成相同的随机数
    15 figure(1)
    16 gscatter(bank.balance,bank.duration,bank.y,'kk','xo')
    17 set(gca,'linewidth',2);
    18 X = table2array(varfun(@double,bank(:,1:end-1)));%预测变量
    19 Y = bank.y;
    20 disp('数据中YES&No的统计结果');
    21 tabulate(Y) %求重复数字的个数使用tabulate,占比率
    22 Xnum = [X(:,~catPred) dummyvar(X(:,catPred))];
    23 Ynum = double(Y)-1;
    24 
    25 %%%设置交叉验证方式
    26 cv = cvpartition(height(bank),'holdout',0.40);
    27 Xtrain = X(training(cv),:);
    28 Ytrain = Y(training(cv),:);
    29 XtrainNum = Xnum(training(cv),:);
    30 YtrainNum = Ynum(training(cv),:);
    31 Xtest = X(test(cv),:);
    32 Ytest = Y(test(cv),:);
    33 XtestNum = Xnum(test(cv),:);
    34 YtestNum = Ynum(test(cv),:);
    35 disp('训练集');
    36 tabulate(Ytrain);
    37 disp('测试集');
    38 tabulate(Ytest);
    39 
    40 %%%训练K-NN分类器
    41 knn = ClassificationKNN.fit(Xtrain,Ytrain,'Distance','seuclidean','NumNeighbors',5);
    42 %进行预测
    43 [Y_knn,Yscore_knn] = knn.predict(Xtest);
    44 Yscore_knn = Yscore_knn(:,2);
    45 %计算混淆矩阵
    46 disp('最近邻方法分类结果:');
    47 C_knn = confusionmat(Ytest,Y_knn)
    MATLAB实现代码

    2.题中有关函数用法简介:

    【1】varfun函数:

    语法:

    1)B = varfun(func,A) 分别向表或时间表 A 的每个变量应用函数 func,并在表或时间表 B 中返回值。

    函数 func 必须取一个输入参数,并在每次调用时返回行数相同的数组。输出参数中的第 i 个变量 B{:,i} 等于 func(A{:,i})。

    如果 A 是时间表,而 func 跨多个行组聚合数据,则 varfun 将 A 中每个行组的第一个行时间指定为 B 中对应的行时间。要以表的形式返回 B 而不带行时间,请将 'OutputFormat' 指定为 'table'。

    2)B = varfun(func,A,Name,Value) 通过一个或多个 Name,Value 对组参数指定的其他选项,分别向表或时间表 A 的每个变量应用函数 func。

    例如,您可以指定要传递给该函数的变量。

    参数说明:

    1)= varfun(func,A,Name,Value),'OutputFormat' - B 的格式:'table' (默认) | 'timetable' | 'uniform' | 'cell';若想返回数值向量而非表则可输入B = varfun(func,A,'OutputFormat','uniform')。B = varfun(func,A,'GroupingVariables','Var1')表示将A中“Var1”变量进行分组(统计个数),会有单独一列进行显示,再将func函数(同一类别)计算出的值列出。

    【2】categorical函数:

     函数说明:

    categorical 是为一组有限的离散类别(例如 HighMedLow)赋值的数据类型。这些类别可以采用您指定的数学排序,例如 High > Med > Low,但这并非必须。分类数组可用来有效地存储并方便地处理非数值数据,同时还为数值赋予有意义的名称。分类数组的常见用法是用来指定构成表的各组行。

    语法:

    B = categorical(A)
    B = categorical(A,valueset)
    B = categorical(A,valueset,catnames)
    B = categorical(A,___,Name,Value)
    MATLAB实例(摘自math works官网):

    转换数组并按类别选择数据

    创建一个包含气象站标签的分类数组。将其添加到温度读数表中。然后使用类别按气象站选择温度读数。

    首先,创建包含温度读数、日期和气象站标签的数组。

    Temps = [58; 72; 56; 90; 76];
    Dates = {'2017-04-17';'2017-04-18';'2017-04-30';'2017-05-01';'2017-04-27'};
    Stations = {'S1';'S2';'S1';'S3';'S2'};

    Stations 转换为分类数组。

    Stations = categorical(Stations)
    Stations = 5x1 categorical array
         S1 
         S2 
         S1 
         S3 
         S2 
    
    

    显示类别。三个气象站标签为类别。

    categories(Stations)
    ans = 3x1 cell array
        {'S1'}
        {'S2'}
        {'S3'}
    
    

    创建包含温度、日期和气象站标签的表。

    T = table(Temps,Dates,Stations)
    T=5x3 table
        Temps       Dates        Stations
        _____    ____________    ________
    
        58       '2017-04-17'    S1      
        72       '2017-04-18'    S2      
        56       '2017-04-30'    S1      
        90       '2017-05-01'    S3      
        76       '2017-04-27'    S2      
    
    

    显示从气象站 S2 获得的读数。您可以使用 == 运算符找出等于 S2Station 的值。然后使用逻辑索引选择包含气象站 S2 的数据的表行。

    TF = (T.Stations == 'S2');
    T(TF,:)
    ans=2x3 table
        Temps       Dates        Stations
        _____    ____________    ________
    
        72       '2017-04-18'    S2      
        76       '2017-04-27'    S2      
    
    

    【3】discretize函数(本题未用到):将数据分组到 bin 或类别中

    例如:使用 discretize 函数(而不是 categorical)将 100 个随机数划分为三个类别。

    x = rand(100,1);

    y = discretize(x,[0 .25 .75 1],'categorical',{'small','medium','large'});

    summary(y)

    运行结果是:

          small       22

         medium      46

         large       32

    【4】rng随机数生成设置函数:

    rng(seed) 使用非负整数 seed 为随机数生成函数提供种子,以使 rand、randi 和 randn 生成可预测的数字序列。

    rng('shuffle') 根据当前时间为随机数生成函数提供种子。这样,rand、randi 和 randn 会在您每次调用 rng 时生成不同的数字序列。

    rng(seed, generator) 和 rng('shuffle', generator) 另外指定 rand、randi 和 randn 使用的随机数生成函数的类型。generator 输入为以下项之一:

        'twister':Mersenne Twister

        'simdTwister':面向 SIMD 的快速 Mersenne Twister 算法

        'combRecursive':合并的多个递归

        'multFibonacci':乘法滞后 Fibonacci

        'v5uniform':传统 MATLAB® 5.0 均匀生成函数

        'v5normal':传统 MATLAB 5.0 正常生成函数

        'v4':传统 MATLAB 4.0 生成函数

    rng('default') 将 rand、randi 和 randn 使用的随机数生成函数的设置重置为其默认值。这样,会生成相同的随机数,就好像您重新启动了 MATLAB。默认设置是种子为 0 的 Mersenne Twister。

    scurr = rng 返回 rand、randi 和 randn 使用的随机数生成函数的当前设置。这些设置将在包含字段 'Type'、'Seed' 和 'State' 的结构体 scurr 中返回。

    rng(s) 将 rand、randi 和 randn 使用的随机数生成函数的设置还原回之前用 s = rng 等命令捕获的值。

    sprev = rng(...) 返回 rand、randi 和 randn 使用的随机数生成函数的以前设置,然后更改这些设置。

    【5】tabulate函数;

    可以计算函数的个数以及在数组或矩阵中的占比率.

    例如;

    test = [1 2 3 3 3 5 4 1 2];

    tabulate(test);

    运行结果:

      Value    Count   Percent

          1        2     22.22%

          2        2     22.22%

          3        3     33.33%

          4        1     11.11%

          5        1     11.11%

    test = [{'a'},{'aaa'},{'a'}];

    tabulate(test)

    运行结果:

    Value    Count   Percent

          a        2     66.67%

        aaa        1     33.33%

  • 相关阅读:
    完整的CRUD——javaweb
    JDBC预编译语句表名占位异常
    自定义标签2.x
    实现一个自定义<table>标签
    带动态属性的自定义标签
    自定义标签库_tag
    poj 3783
    The North American Invitational Programming Contest 2018 E. Prefix Free Code
    hdu 6383
    ACM-ICPC 2016 Qingdao Preliminary Contest G. Sort
  • 原文地址:https://www.cnblogs.com/somedayLi/p/9554938.html
Copyright © 2011-2022 走看看