精华内容
下载资源
问答
  • BIRCH (balanced iterative reducing and clustering using hierarchies) is an unsupervised data mining algorithm used to perform hierarchical clustering over particularly large data-sets.[1] An advantage...
  • BIRCH算法(基于层次的聚类算法)

    热门讨论 2011-12-03 10:19:19
    基于层次的聚类算法(以BIRCH算法为例) 算法形式化描述 输入:包含N个对象的数据集合D 输出:簇集合。
  • * * Exam Questions What is the main limitation of BIRCH? Since each node in a CF tree can hold only a limited number of entries due to the size, a CF tree node doesnt always correspond to what a user
  • BIRCH聚类算法

    2018-06-21 09:03:49
    BIRCH算法的过程就是要把待分类的数据插入一棵树中,并且原始数据都在叶子节点上。这棵树看起来是这个样子: 在这棵树中有3种类型的节点:Nonleaf、Leaf、MinCluster,Root可能是一种Nonleaf,也可能是一种Leaf。...
  • 插值与拟合实验,代数方程组的解法,微分方程实验,优化问题实验
  • BIRCH算法源码

    热门讨论 2011-10-23 09:18:35
    BIRCH算法源码,C++实现,已在solaris下编译通过
  • BIRCH算法本身上属于一种聚类算法,不过他克服了一些K-Means算法的缺点,比如说这个k的确定,因为这个算法事先本身就没有设定有多少个聚类。他是通过CF-Tree,(ClusterFeature-Tree)聚类特征树实现的。BIRCH的一个...

    更多数据挖掘代码:https://github.com/linyiqun/DataMiningAlgorithm

    介绍

    BIRCH算法本身上属于一种聚类算法,不过他克服了一些K-Means算法的缺点,比如说这个k的确定,因为这个算法事先本身就没有设定有多少个聚类。他是通过CF-Tree,(ClusterFeature-Tree)聚类特征树实现的。BIRCH的一个重要考虑是最小化I/O,通过扫描数据库,建立一棵存放于内存的初始CF-树,可以看做多数据的多层压缩。

    算法原理

    CF聚类特征

    说到算法原理,首先就要先知道,什么是聚类特征,何为聚类特征,定义如下:

    CF = <n, LS, SS>

    聚类特征为一个3维向量,n为数据点总数,LS为n个点的线性和,SS为n个点的平方和。因此又可以得到

    x0 = LS/n为簇的中心,以此计算簇与簇之间的距离。

    簇内对象的平均距离簇直径,这个可以用阈值T限制,保证簇的一个整体的紧凑程度。簇和簇之间可以进行叠加,其实就是向量的叠加。

    CF-Tree的构造过程

    在介绍CF-Tree树,要先介绍3个变量,内部节点平衡因子B,叶节点平衡因子L,簇直径阈值T。B是用来限制非叶子节点的子节点数,L是用来限制叶子节点的子簇个数,T是用来限制簇的紧密程度的,比较的是D--簇内平均对象的距离。下面是主要的构造过程:

    1、首先读入第一条数据,构造一个叶子节点和一个子簇,子簇包含在叶子节点中。

    2、当读入后面的第2条,第3条,封装为一个簇,加入到一个叶子节点时,如果此时的待加入的簇C的簇直径已经大于T,则需要新建簇作为C的兄弟节点,如果作为兄弟节点,如果此时的叶子节点的孩子节点超过阈值L,则需对叶子节点进行分裂。分裂的规则是选出簇间距离最大的2个孩子,分别作为2个叶子,然后其他的孩子按照就近分配。非叶子节点的分裂规则同上。具体可以对照后面我写的代码。

    3、最终的构造模样大致如此:


    算法的优点:

    1、算法只需扫描一遍就可以得到一个好的聚类效果,而且不需事先设定聚类个数。

    2、聚类通过聚类特征树的形式,一定程度上保存了对数据的压缩。

    算法的缺点:

    1、该算法比较适合球形的簇,如果簇不是球形的,则聚簇的效果将不会很好。

    算法的代码实现:

    下面提供部分核心代码(如果想获取所有的代码,请点击我的数据挖掘代码):

    数据的输入:

    [java]  view plain copy print ?
    1. 5.1     3.5     1.4     0.2  
    2. 4.9     3.0     1.4     0.2  
    3. 4.7     3.2     1.3     0.8  
    4. 4.6     3.1     1.5     0.8  
    5. 5.0     3.6     1.8     0.6  
    6. 4.7     3.2     1.4     0.8  

    ClusteringFeature.java:

    [java]  view plain copy print ?
    1. package DataMining_BIRCH;  
    2.   
    3. import java.util.ArrayList;  
    4.   
    5. /** 
    6.  * 聚类特征基本属性 
    7.  *  
    8.  * @author lyq 
    9.  *  
    10.  */  
    11. public abstract class ClusteringFeature {  
    12.     // 子类中节点的总数目  
    13.     protected int N;  
    14.     // 子类中N个节点的线性和  
    15.     protected double[] LS;  
    16.     // 子类中N个节点的平方和  
    17.     protected double[] SS;  
    18.     //节点深度,用于CF树的输出  
    19.     protected int level;  
    20.   
    21.     public int getN() {  
    22.         return N;  
    23.     }  
    24.   
    25.     public void setN(int n) {  
    26.         N = n;  
    27.     }  
    28.   
    29.     public double[] getLS() {  
    30.         return LS;  
    31.     }  
    32.   
    33.     public void setLS(double[] lS) {  
    34.         LS = lS;  
    35.     }  
    36.   
    37.     public double[] getSS() {  
    38.         return SS;  
    39.     }  
    40.   
    41.     public void setSS(double[] sS) {  
    42.         SS = sS;  
    43.     }  
    44.   
    45.     protected void setN(ArrayList<double[]> dataRecords) {  
    46.         this.N = dataRecords.size();  
    47.     }  
    48.       
    49.     public int getLevel() {  
    50.         return level;  
    51.     }  
    52.   
    53.     public void setLevel(int level) {  
    54.         this.level = level;  
    55.     }  
    56.   
    57.     /** 
    58.      * 根据节点数据计算线性和 
    59.      *  
    60.      * @param dataRecords 
    61.      *            节点数据记录 
    62.      */  
    63.     protected void setLS(ArrayList<double[]> dataRecords) {  
    64.         int num = dataRecords.get(0).length;  
    65.         double[] record;  
    66.         LS = new double[num];  
    67.         for (int j = 0; j < num; j++) {  
    68.             LS[j] = 0;  
    69.         }  
    70.   
    71.         for (int i = 0; i < dataRecords.size(); i++) {  
    72.             record = dataRecords.get(i);  
    73.             for (int j = 0; j < record.length; j++) {  
    74.                 LS[j] += record[j];  
    75.             }  
    76.         }  
    77.     }  
    78.   
    79.     /** 
    80.      * 根据节点数据计算平方 
    81.      *  
    82.      * @param dataRecords 
    83.      *            节点数据 
    84.      */  
    85.     protected void setSS(ArrayList<double[]> dataRecords) {  
    86.         int num = dataRecords.get(0).length;  
    87.         double[] record;  
    88.         SS = new double[num];  
    89.         for (int j = 0; j < num; j++) {  
    90.             SS[j] = 0;  
    91.         }  
    92.   
    93.         for (int i = 0; i < dataRecords.size(); i++) {  
    94.             record = dataRecords.get(i);  
    95.             for (int j = 0; j < record.length; j++) {  
    96.                 SS[j] += record[j] * record[j];  
    97.             }  
    98.         }  
    99.     }  
    100.   
    101.     /** 
    102.      * CF向量特征的叠加,无须考虑划分 
    103.      *  
    104.      * @param node 
    105.      */  
    106.     protected void directAddCluster(ClusteringFeature node) {  
    107.         int N = node.getN();  
    108.         double[] otherLS = node.getLS();  
    109.         double[] otherSS = node.getSS();  
    110.           
    111.         if(LS == null){  
    112.             this.N = 0;  
    113.             LS = new double[otherLS.length];  
    114.             SS = new double[otherLS.length];  
    115.               
    116.             for(int i=0; i<LS.length; i++){  
    117.                 LS[i] = 0;  
    118.                 SS[i] = 0;  
    119.             }  
    120.         }  
    121.   
    122.         // 3个数量上进行叠加  
    123.         for (int i = 0; i < LS.length; i++) {  
    124.             LS[i] += otherLS[i];  
    125.             SS[i] += otherSS[i];  
    126.         }  
    127.         this.N += N;  
    128.     }  
    129.   
    130.     /** 
    131.      * 计算簇与簇之间的距离即簇中心之间的距离 
    132.      *  
    133.      * @return 
    134.      */  
    135.     protected double computerClusterDistance(ClusteringFeature cluster) {  
    136.         double distance = 0;  
    137.         double[] otherLS = cluster.LS;  
    138.         int num = N;  
    139.           
    140.         int otherNum = cluster.N;  
    141.   
    142.         for (int i = 0; i < LS.length; i++) {  
    143.             distance += (LS[i] / num - otherLS[i] / otherNum)  
    144.                     * (LS[i] / num - otherLS[i] / otherNum);  
    145.         }  
    146.         distance = Math.sqrt(distance);  
    147.   
    148.         return distance;  
    149.     }  
    150.   
    151.     /** 
    152.      * 计算簇内对象的平均距离 
    153.      *  
    154.      * @param records 
    155.      *            簇内的数据记录 
    156.      * @return 
    157.      */  
    158.     protected double computerInClusterDistance(ArrayList<double[]> records) {  
    159.         double sumDistance = 0;  
    160.         double[] data1;  
    161.         double[] data2;  
    162.         // 数据总数  
    163.         int totalNum = records.size();  
    164.   
    165.         for (int i = 0; i < totalNum - 1; i++) {  
    166.             data1 = records.get(i);  
    167.             for (int j = i + 1; j < totalNum; j++) {  
    168.                 data2 = records.get(j);  
    169.                 sumDistance += computeOuDistance(data1, data2);  
    170.             }  
    171.         }  
    172.   
    173.         // 返回的值除以总对数,总对数应减半,会重复算一次  
    174.         return Math.sqrt(sumDistance / (totalNum * (totalNum - 1) / 2));  
    175.     }  
    176.   
    177.     /** 
    178.      * 对给定的2个向量,计算欧式距离 
    179.      *  
    180.      * @param record1 
    181.      *            向量点1 
    182.      * @param record2 
    183.      *            向量点2 
    184.      */  
    185.     private double computeOuDistance(double[] record1, double[] record2) {  
    186.         double distance = 0;  
    187.   
    188.         for (int i = 0; i < record1.length; i++) {  
    189.             distance += (record1[i] - record2[i]) * (record1[i] - record2[i]);  
    190.         }  
    191.   
    192.         return distance;  
    193.     }  
    194.   
    195.     /** 
    196.      * 聚类添加节点包括,超出阈值进行分裂的操作 
    197.      *  
    198.      * @param clusteringFeature 
    199.      *            待添加聚簇 
    200.      */  
    201.     public abstract void addingCluster(ClusteringFeature clusteringFeature);  
    202. }  
    BIRCHTool.java:

    [java]  view plain copy print ?
    1. package DataMining_BIRCH;  
    2.   
    3. import java.io.BufferedReader;  
    4. import java.io.File;  
    5. import java.io.FileReader;  
    6. import java.io.IOException;  
    7. import java.text.MessageFormat;  
    8. import java.util.ArrayList;  
    9. import java.util.LinkedList;  
    10.   
    11. /** 
    12.  * BIRCH聚类算法工具类 
    13.  *  
    14.  * @author lyq 
    15.  *  
    16.  */  
    17. public class BIRCHTool {  
    18.     // 节点类型名称  
    19.     public static final String NON_LEAFNODE = "【NonLeafNode】";  
    20.     public static final String LEAFNODE = "【LeafNode】";  
    21.     public static final String CLUSTER = "【Cluster】";  
    22.   
    23.     // 测试数据文件地址  
    24.     private String filePath;  
    25.     // 内部节点平衡因子B  
    26.     public static int B;  
    27.     // 叶子节点平衡因子L  
    28.     public static int L;  
    29.     // 簇直径阈值T  
    30.     public static double T;  
    31.     // 总的测试数据记录  
    32.     private ArrayList<String[]> totalDataRecords;  
    33.   
    34.     public BIRCHTool(String filePath, int B, int L, double T) {  
    35.         this.filePath = filePath;  
    36.         this.B = B;  
    37.         this.L = L;  
    38.         this.T = T;  
    39.         readDataFile();  
    40.     }  
    41.   
    42.     /** 
    43.      * 从文件中读取数据 
    44.      */  
    45.     private void readDataFile() {  
    46.         File file = new File(filePath);  
    47.         ArrayList<String[]> dataArray = new ArrayList<String[]>();  
    48.   
    49.         try {  
    50.             BufferedReader in = new BufferedReader(new FileReader(file));  
    51.             String str;  
    52.             String[] tempArray;  
    53.             while ((str = in.readLine()) != null) {  
    54.                 tempArray = str.split("     ");  
    55.                 dataArray.add(tempArray);  
    56.             }  
    57.             in.close();  
    58.         } catch (IOException e) {  
    59.             e.getStackTrace();  
    60.         }  
    61.   
    62.         totalDataRecords = new ArrayList<>();  
    63.         for (String[] array : dataArray) {  
    64.             totalDataRecords.add(array);  
    65.         }  
    66.     }  
    67.   
    68.     /** 
    69.      * 构建CF聚类特征树 
    70.      *  
    71.      * @return 
    72.      */  
    73.     private ClusteringFeature buildCFTree() {  
    74.         NonLeafNode rootNode = null;  
    75.         LeafNode leafNode = null;  
    76.         Cluster cluster = null;  
    77.   
    78.         for (String[] record : totalDataRecords) {  
    79.             cluster = new Cluster(record);  
    80.   
    81.             if (rootNode == null) {  
    82.                 // CF树只有1个节点的时候的情况  
    83.                 if (leafNode == null) {  
    84.                     leafNode = new LeafNode();  
    85.                 }  
    86.                 leafNode.addingCluster(cluster);  
    87.                 if (leafNode.getParentNode() != null) {  
    88.                     rootNode = leafNode.getParentNode();  
    89.                 }  
    90.             } else {  
    91.                 if (rootNode.getParentNode() != null) {  
    92.                     rootNode = rootNode.getParentNode();  
    93.                 }  
    94.   
    95.                 // 从根节点开始,从上往下寻找到最近的添加目标叶子节点  
    96.                 LeafNode temp = rootNode.findedClosestNode(cluster);  
    97.                 temp.addingCluster(cluster);  
    98.             }  
    99.         }  
    100.   
    101.         // 从下往上找出最上面的节点  
    102.         LeafNode node = cluster.getParentNode();  
    103.         NonLeafNode upNode = node.getParentNode();  
    104.         if (upNode == null) {  
    105.             return node;  
    106.         } else {  
    107.             while (upNode.getParentNode() != null) {  
    108.                 upNode = upNode.getParentNode();  
    109.             }  
    110.   
    111.             return upNode;  
    112.         }  
    113.     }  
    114.   
    115.     /** 
    116.      * 开始构建CF聚类特征树 
    117.      */  
    118.     public void startBuilding() {  
    119.         // 树深度  
    120.         int level = 1;  
    121.         ClusteringFeature rootNode = buildCFTree();  
    122.   
    123.         setTreeLevel(rootNode, level);  
    124.         showCFTree(rootNode);  
    125.     }  
    126.   
    127.     /** 
    128.      * 设置节点深度 
    129.      *  
    130.      * @param clusteringFeature 
    131.      *            当前节点 
    132.      * @param level 
    133.      *            当前深度值 
    134.      */  
    135.     private void setTreeLevel(ClusteringFeature clusteringFeature, int level) {  
    136.         LeafNode leafNode = null;  
    137.         NonLeafNode nonLeafNode = null;  
    138.   
    139.         if (clusteringFeature instanceof LeafNode) {  
    140.             leafNode = (LeafNode) clusteringFeature;  
    141.         } else if (clusteringFeature instanceof NonLeafNode) {  
    142.             nonLeafNode = (NonLeafNode) clusteringFeature;  
    143.         }  
    144.   
    145.         if (nonLeafNode != null) {  
    146.             nonLeafNode.setLevel(level);  
    147.             level++;  
    148.             // 设置子节点  
    149.             if (nonLeafNode.getNonLeafChilds() != null) {  
    150.                 for (NonLeafNode n1 : nonLeafNode.getNonLeafChilds()) {  
    151.                     setTreeLevel(n1, level);  
    152.                 }  
    153.             } else {  
    154.                 for (LeafNode n2 : nonLeafNode.getLeafChilds()) {  
    155.                     setTreeLevel(n2, level);  
    156.                 }  
    157.             }  
    158.         } else {  
    159.             leafNode.setLevel(level);  
    160.             level++;  
    161.             // 设置子聚簇  
    162.             for (Cluster c : leafNode.getClusterChilds()) {  
    163.                 c.setLevel(level);  
    164.             }  
    165.         }  
    166.     }  
    167.   
    168.     /** 
    169.      * 显示CF聚类特征树 
    170.      *  
    171.      * @param rootNode 
    172.      *            CF树根节点 
    173.      */  
    174.     private void showCFTree(ClusteringFeature rootNode) {  
    175.         // 空格数,用于输出  
    176.         int blankNum = 5;  
    177.         // 当前树深度  
    178.         int currentLevel = 1;  
    179.         LinkedList<ClusteringFeature> nodeQueue = new LinkedList<>();  
    180.         ClusteringFeature cf;  
    181.         LeafNode leafNode;  
    182.         NonLeafNode nonLeafNode;  
    183.         ArrayList<Cluster> clusterList = new ArrayList<>();  
    184.         String typeName;  
    185.   
    186.         nodeQueue.add(rootNode);  
    187.         while (nodeQueue.size() > 0) {  
    188.             cf = nodeQueue.poll();  
    189.   
    190.             if (cf instanceof LeafNode) {  
    191.                 leafNode = (LeafNode) cf;  
    192.                 typeName = LEAFNODE;  
    193.   
    194.                 if (leafNode.getClusterChilds() != null) {  
    195.                     for (Cluster c : leafNode.getClusterChilds()) {  
    196.                         nodeQueue.add(c);  
    197.                     }  
    198.                 }  
    199.             } else if (cf instanceof NonLeafNode) {  
    200.                 nonLeafNode = (NonLeafNode) cf;  
    201.                 typeName = NON_LEAFNODE;  
    202.   
    203.                 if (nonLeafNode.getNonLeafChilds() != null) {  
    204.                     for (NonLeafNode n1 : nonLeafNode.getNonLeafChilds()) {  
    205.                         nodeQueue.add(n1);  
    206.                     }  
    207.                 } else {  
    208.                     for (LeafNode n2 : nonLeafNode.getLeafChilds()) {  
    209.                         nodeQueue.add(n2);  
    210.                     }  
    211.                 }  
    212.             } else {  
    213.                 clusterList.add((Cluster)cf);  
    214.                 typeName = CLUSTER;  
    215.             }  
    216.   
    217.             if (currentLevel != cf.getLevel()) {  
    218.                 currentLevel = cf.getLevel();  
    219.                 System.out.println();  
    220.                 System.out.println("|");  
    221.                 System.out.println("|");  
    222.             }else if(currentLevel == cf.getLevel() && currentLevel != 1){  
    223.                 for (int i = 0; i < blankNum; i++) {  
    224.                     System.out.print("-");  
    225.                 }  
    226.             }  
    227.               
    228.             System.out.print(typeName);  
    229.             System.out.print("N:" + cf.getN() + ", LS:");  
    230.             System.out.print("[");  
    231.             for (double d : cf.getLS()) {  
    232.                 System.out.print(MessageFormat.format("{0}, ",  d));  
    233.             }  
    234.             System.out.print("]");  
    235.         }  
    236.           
    237.         System.out.println();  
    238.         System.out.println("*******最终分好的聚簇****");  
    239.         //显示已经分好类的聚簇点  
    240.         for(int i=0; i<clusterList.size(); i++){  
    241.             System.out.println("Cluster" + (i+1) + ":");  
    242.             for(double[] point: clusterList.get(i).getData()){  
    243.                 System.out.print("[");  
    244.                 for (double d : point) {  
    245.                     System.out.print(MessageFormat.format("{0}, ",  d));  
    246.                 }  
    247.                 System.out.println("]");  
    248.             }  
    249.         }  
    250.     }  
    251.   
    252. }  
    由于代码量比较大,剩下的LeafNode.java,NonLeafNode.java, 和Cluster聚簇类可以在 我的数据挖掘代码 中查看。

    结果输出:

    [java]  view plain copy print ?
    1. 【NonLeafNode】N:6, LS:[2919.68.83.4, ]  
    2. |  
    3. |  
    4. 【LeafNode】N:3, LS:[149.54.22.4, ]-----【LeafNode】N:3, LS:[1510.14.61, ]  
    5. |  
    6. |  
    7. 【Cluster】N:3, LS:[149.54.22.4, ]-----【Cluster】N:1, LS:[53.61.80.6, ]-----【Cluster】N:2, LS:[106.52.80.4, ]  
    8. *******最终分好的聚簇****  
    9. Cluster1:  
    10. [4.73.21.30.8, ]  
    11. [4.63.11.50.8, ]  
    12. [4.73.21.40.8, ]  
    13. Cluster2:  
    14. [53.61.80.6, ]  
    15. Cluster3:  
    16. [5.13.51.40.2, ]  
    17. [4.931.40.2, ]  

    算法实现时的难点

    1、算簇间距离的时候,代了一下公式,发现不对劲,向量的运算不应该是这样的,于是就把他归与簇心之间的距离计算。还有簇内对象的平均距离也没有代入公式,网上的各种版本的向量计算,不知道哪种是对的,又按最原始的方式计算,一对对计算距离,求平均值。

    2、算法在节点分裂的时候,如果父节点不为空,需要把自己从父亲中的孩子列表中移除,然后再添加分裂后的2个节点,这里的把自己移除掉容易忘记。

    3、节点CF聚类特征值的更新,需要在每次节点的变化时,其所涉及的父类,父类的父类都需要更新,为此用了责任链模式,一个一个往上传,分裂的规则时也用了此模式,需要关注一下。

    4、代码将CF聚类特征量进行抽象提取,定义了共有的方法,不过在实现时还是由于节点类型的不同,在实际的过程中需要转化。

    5、最后的难点在与测试的复杂,因为程序经过千辛万苦的编写终于完成,但是如何测试时一个大问题,因为要把分裂的情况都测准,需要准确的把握T.,B.L,的设计,尤其是T簇直径,所以在捏造测试的时候自己也是经过很多的手动计算。

    我对BIRCH算法的理解

    在实现的整个完成的过程中 ,我对BIRCH算法的最大的感触就是通过聚类特征,一个新节点从根节点开始,从上往先寻找,离哪个簇近,就被分到哪个簇中,自发的形成了一个比较好的聚簇,这个过程是算法的神奇所在。

    展开全文
  • birch聚类算法的原理与实现

    千次阅读 2015-09-20 20:19:51
    参考百度百科http://baike.baidu.com/link?url=LDYen7bEqt8o2l5mUrnZjQk1topFi36-MwLuhjuGf-1z4sQFtFq1xCEe0TCJwYVjGbu0C6cpuVMFIxNglvSnoa 外加...学习birch聚类最好有

    参考百度百科http://baike.baidu.com/link?url=LDYen7bEqt8o2l5mUrnZjQk1topFi36-MwLuhjuGf-1z4sQFtFq1xCEe0TCJwYVjGbu0C6cpuVMFIxNglvSnoa

    外加http://www.cnblogs.com/zhangchaoyang/articles/2200800.html

    学习birch聚类最好有B-树的知识

    结合了B-树的特性,birch算法适合于处理大数据。

    原因是:

    (1)CF 结构概括了簇的基本信息,并且是高度压缩的,它存储了小于实际数据点的聚类信息。每个新添加的数据其作为个体消失了,将信息融入的集合簇中

    (2)增量式的学习方法,不用一次将数据全部加载到内存,可以一边添加数据一边进行学习


    下面是我的实现


    // birch-cluster.cpp : 定义控制台应用程序的入口点。
    //
    
    ///************birch-cluster*************///
    ///*******   author Marshall     ********///
    ///*******   2015.9.18           ********///
    ///*******   version 1.0         ********///
    
    
    #include "stdafx.h"
    #include<vector>
    #include<iostream>
    #include<cstdlib>
    #include<time.h>
    
    #define BirchType int
    
    using namespace std;
    
    
    
    vector<BirchType> operator+(vector<BirchType>aa, vector<BirchType>&bb){
    	_ASSERTE(aa.size() == bb.size());
    	for (int i = 0; i < aa.size(); i++)
    		aa[i] += bb[i];
    	return aa;
    }
    
    vector<BirchType> operator*(vector<BirchType>aa, vector<BirchType>&bb){
    	_ASSERTE(aa.size() == bb.size());
    	for (int i = 0; i < aa.size(); i++)
    		aa[i] *= bb[i];
    	return aa;
    }
    
    vector<BirchType> operator-(vector<BirchType>aa, vector<BirchType>&bb){
    	_ASSERTE(aa.size() == bb.size());
    	for (int i = 0; i < aa.size(); i++)
    		aa[i] -= bb[i];
    	return aa;
    }
    
    vector<BirchType> operator*(vector<BirchType>aa, double k){
    
    	for (int i = 0; i < aa.size(); i++)
    		aa[i] = double(aa[i])* k;
    	return aa;
    }
    vector<BirchType> operator*(int k, vector<BirchType>aa){
    
    	for (int i = 0; i < aa.size(); i++)
    		aa[i] *= k;
    	return aa;
    }
    class birch
    {
    public:
    	struct Attribute
    	{
    		unsigned int dim;
    		vector<BirchType>data;
    		Attribute(unsigned int d) :dim(d)
    		{
    			data.resize(dim);
    		}
    	};
    	struct CF
    	{
    		unsigned int N;
    		vector<BirchType> LS;
    		vector<BirchType> SS;
    		CF(unsigned int N,
    			vector<BirchType> LS,
    			vector<BirchType>SS) :N(N), LS(LS), SS(SS){}
    		/*CF(CF& cc){//shallow copy is enough
    			this->N = cc.N;
    			this->LS = cc.LS;
    			this->SS = cc.SS;
    			}*/
    		CF(unsigned int dim){
    			N = 0;
    			LS.resize(dim);
    			SS.resize(dim);
    		};
    		CF(){};
    	};
    
    	struct Leaf;
    	struct MinCluster
    	{
    		CF cf;
    		Leaf*parent;
    		MinCluster()
    		{
    			parent = NULL;
    		}
    		MinCluster(CF cf)
    		{
    			parent = NULL;
    			this->cf = cf;
    		}
    	};
    
    	struct Leaf
    	{
    		Leaf*pre, *next;//to make up a leaf-list.for Nonleaf,NULL
    		Leaf*parent;
    		vector<Leaf*>*child;//对Leaf而言为NULL
    		vector<MinCluster>*cluster;//对NonLeaf而言为NULL
    		CF cf;
    		Leaf()
    		{
    			parent = pre = next = NULL;
    			child = NULL;
    			cluster = NULL;
    		}
    	};
    	void generate_data(int num, int dim, vector<int>&span)
    	{
    		this->dim = dim;
    		_ASSERTE(span.size() == dim);
    		for (int i = 0; i < num; i++)
    		{
    			Attribute att(dim);
    			for (int j = 0; j < dim; j++)
    				att.data[j] = span[j] * double(rand()) / double(RAND_MAX + 1.0);
    			dataset.push_back(att);
    		}
    	}
    	vector<Attribute>dataset;
    
    	int absorbnum;
    
    public:
    	birch(unsigned int b, unsigned int l, unsigned int t)
    		:B(b), L(l), T(t){
    		_ASSERTE(B > 2);
    		_ASSERTE(L > 3);
    		root = NULL;
    		time_t tt;
    		srand(time(&tt));
    		absorbnum = 0;
    	}
    	~birch();
    	void insert(Attribute att);
    
    
    private:
    
    	unsigned int B; //maximal num of child a Nonleaf will have
    	unsigned int L;//maximal num of MinCluster a leaf will haveLeaf
    	unsigned int T;// MinCluster的直径不能超过T
    	Leaf*root;
    	Leaf*head;//the head of the leaf-list at the bottom of the tree
    	int dim;
    
    
    private:
    	inline double lengthofvec(vector<BirchType>&aa){
    		double len = 0;
    		for (int i = 0; i < aa.size(); i++)
    			len += pow(aa[i], 2.0);
    		return sqrt(len);
    	}
    	double sumofvec(vector<BirchType>&aa){
    		double sum = 0;
    		for (int i = 0; i < aa.size(); i++)
    			sum += aa[i];
    		return sum;
    	}
    
    	double cal_inter_cluster_dis(CF &cf1, CF &cf2);
    	double cal_intra_cluster_dis();
    	double merge_cluster_diameter(CF &cf1, CF &cf2);
    	vector<BirchType>updateSS(vector<BirchType>&LS, vector<BirchType>&SS)
    	{
    		for (int i = 0; i < LS.size(); i++)
    			SS[i] += pow(LS[i], 2.0);
    		return SS;
    	}
    	CF updateCF(CF &c1, CF &c2)
    	{
    		return CF(c1.N + c2.N, c1.LS + c2.LS, c1.SS + c2.SS);
    	}
    	void updateCF(Leaf*leaf)
    	{
    		CF cf(dim);
    		if (leaf->cluster != NULL)
    		{
    
    			for (int i = 0; i < leaf->cluster->size(); i++)
    			{
    				cf.N = cf.N + (*leaf->cluster)[i].cf.N;
    				cf.LS = cf.LS + (*leaf->cluster)[i].cf.LS;
    				cf.SS = cf.SS + (*leaf->cluster)[i].cf.SS;
    			}
    		}
    		else if (leaf->child != NULL)
    		{
    			for (int i = 0; i < leaf->child->size(); i++)
    			{
    				cf.N = cf.N + (*leaf->child)[i]->cf.N;
    				cf.LS = cf.LS + (*leaf->child)[i]->cf.LS;
    				cf.SS = cf.SS + (*leaf->child)[i]->cf.SS;
    			}
    		}
    		leaf->cf = cf;
    	}
    
    	MinCluster create_mincluster(Attribute att)
    	{
    		vector<BirchType>aa;
    		aa.resize(att.dim);
    		return MinCluster(CF(1, att.data, updateSS(att.data, aa)));
    	}
    
    	void insert(Leaf*close, bool &split, MinCluster &clu);
    
    
    
    };
    
    birch::~birch()
    {
    	Leaf*plist = head;
    	while (plist != NULL)
    	{
    		delete plist->cluster;
    		plist = plist->next;
    	}
    	vector<Leaf*>aa, bb;
    	aa.push_back(root);
    	while (!aa.empty())
    	{
    		Leaf*pleaf = aa.back();
    		aa.pop_back();
    		bb.push_back(pleaf);
    		if (pleaf->child != NULL)
    			aa.insert(aa.end(), pleaf->child->begin(), pleaf->child->end());
    	}
    	for (int i = 0; i < bb.size(); i++)
    	{
    		if (bb[i]->child != NULL)
    			delete bb[i]->child;
    		delete bb[i];
    	}
    }
    /*double birch::merge_cluster_diameter(CF &cf1, CF &cf2)
    {
    return sqrt(sumofvec(cf1.SS *(1.0 / double(cf1.N))
    + cf2.SS *(1.0 / double(cf1.N)) -
    2 * cf1.LS*cf2.LS*(1.0 / double(cf1.N + cf2.N))));
    }*/
    
    double birch::merge_cluster_diameter(CF &cf1, CF &cf2)
    {
    	return sqrt(sumofvec(cf1.SS *(1.0 / double(cf1.N))
    		+ cf2.SS *(1.0 / double(cf1.N)) -
    		2 * cf1.LS*cf2.LS*(1.0 / double(cf1.N + cf2.N))));
    }
    
    
    void birch::insert(Attribute att)
    {
    	if (root == NULL)
    	{
    		root = new Leaf;
    		root->cluster = new vector < MinCluster > ;
    		(*root->cluster).push_back(create_mincluster(att));
    		root->cf = CF((*root->cluster)[0].cf);
    		head = root;
    		head->pre = NULL;
    		head->next = NULL;
    		return;
    	}
    	MinCluster clu = create_mincluster(att);
    	Leaf*leaf = root;
    
    	vector<int>path;
    
    	while (leaf->cluster == NULL)
    	{
    		int k = -1;
    		double mindis = 10000000000000;
    		double dd;
    		for (int i = 0; i < (*leaf->child).size(); i++)
    		{
    			double dis = cal_inter_cluster_dis(clu.cf, (*leaf->child)[i]->cf);
    			if (dis < mindis)
    			{
    				mindis = dis;
    				k = i;
    			}
    			dd = dis;
    		}
    
    		_ASSERTE(k >= 0);
    		path.push_back(k);
    		leaf = (*leaf->child)[k];
    	}
    
    
    
    	int k = -1;
    	//mindis = 100000;
    	double mindis = 100000;
    	for (int i = 0; i < (*leaf->cluster).size(); i++)
    	{
    		double dis = cal_inter_cluster_dis(clu.cf, (*leaf->cluster)[i].cf);
    		if (dis < mindis)
    		{
    			mindis = dis;
    			k = i;
    		}
    		_ASSERTE(k >= 0);
    	}
    	//double ttt = merge_cluster_diameter(clu.cf, (*leaf->cluster)[k].cf);
    
    	double ttt = cal_inter_cluster_dis(clu.cf, (*leaf->cluster)[k].cf);
    	if (ttt < T)
    	{
    		//absorb
    		(*leaf->cluster)[k].cf = updateCF((*leaf->cluster)[k].cf, clu.cf);
    		absorbnum++;
    	}
    	else
    	{
    		(*leaf->cluster).push_back(clu);
    	}
    	//update CF value along the path
    	Leaf*lea = root;
    	(*lea).cf = updateCF((*lea).cf, clu.cf);
    	for (int i = 0; i < path.size(); i++)
    	{
    		(*lea->child)[path[i]]->cf = updateCF((*lea->child)[path[i]]->cf, clu.cf);
    		lea = (*lea->child)[path[i]];
    	}
    
    	if ((*leaf->cluster).size() > L)
    	{
    		double maxdis = 0;
    		int th1 = -1;
    		int th2 = -1;
    		double**dismatrix = new double*[(*leaf->cluster).size()];
    		for (int i = 0; i < (*leaf->cluster).size(); i++)
    			dismatrix[i] = new double[(*leaf->cluster).size()];
    		//找到距离最远的两个簇
    		for (int i = 0; i < (*leaf->cluster).size() - 1; i++)
    			for (int h = i + 1; h < (*leaf->cluster).size(); h++)
    			{
    				double dis = cal_inter_cluster_dis((*leaf->cluster)[i].cf, (*leaf->cluster)[h].cf);
    				dismatrix[i][h] = dis;
    				dismatrix[h][i] = dis;
    				if (dis > maxdis)
    				{
    					maxdis = dis;
    					th1 = i; th2 = h;
    				}
    			}
    		Leaf*new_leaf = new Leaf;
    		new_leaf->cluster = new vector < MinCluster > ;
    		new_leaf->cluster->push_back((*leaf->cluster)[th2]);
    		int len = (*leaf->cluster).size();
    		(*leaf->cluster)[th2].parent = new_leaf;
    
    		//根据各簇与两个新簇的距离分配到两个新簇中
    		for (int i = 0; i < len; i++)
    		{
    			if (i == th1 || i == th2)
    				continue;
    			if (dismatrix[i][th2] < dismatrix[i][th1])
    			{
    				(*leaf->cluster)[i].parent = new_leaf;
    				new_leaf->cluster->push_back((*leaf->cluster)[i]);
    
    			}
    		}
    		for (int i = 0; i < (*leaf->cluster).size(); i++)
    			delete[] dismatrix[i];
    		delete[]dismatrix;
    
    		vector < MinCluster >::iterator it, it1;
    		it = (*leaf->cluster).begin();
    		while (it != (*leaf->cluster).end())
    		{
    			if (it->parent == new_leaf)
    				it = (*leaf->cluster).erase(it);
    			else
    			{
    				it++;
    			}
    		}
    		//不要忘了更新leaf和new_leaf的cf值
    		updateCF(leaf);
    		updateCF(new_leaf);
    		//不要忘了将new_leaf加入到链表中
    		Leaf*next = leaf->next;
    		leaf->next = new_leaf;
    		new_leaf->pre = leaf;
    		new_leaf->next = next;
    		if (next)
    			next->pre = new_leaf;
    		if (leaf->parent != NULL)
    		{
    			leaf->parent->child->push_back(new_leaf);
    			new_leaf->parent = leaf->parent;
    		}
    		else//leaf is root,then a new root should be created
    		{
    			Leaf*new_root = new Leaf;
    			new_root->child = new vector < Leaf* > ;
    			new_root->child->push_back(leaf);
    			new_root->child->push_back(new_leaf);
    			leaf->parent = new_root;
    			new_leaf->parent = new_root;
    			updateCF(new_root);
    			root = new_root;
    			return;
    		}
    	}
    	Leaf*cur = leaf->parent;
    	while (cur != NULL&&cur->child->size() > B)
    	{
    		double maxdis = 0;
    		int th1 = -1;
    		int th2 = -1;
    		double**dismatrix = new double*[cur->child->size()];
    		for (int i = 0; i < cur->child->size(); i++)
    			dismatrix[i] = new double[cur->child->size()];
    		//找到距离最远的两个leaf
    		for (int i = 0; i < cur->child->size() - 1; i++)
    			for (int h = i + 1; h < cur->child->size(); h++)
    			{
    				double dis = cal_inter_cluster_dis((*cur->child)[i]->cf, (*cur->child)[h]->cf);
    				dismatrix[i][h] = dis;
    				dismatrix[h][i] = dis;
    				if (dis > maxdis)
    				{
    					maxdis = dis;
    					th1 = i; th2 = h;
    				}
    			}
    
    		Leaf*new_leaf1 = new Leaf;
    		new_leaf1->child = new vector < Leaf* > ;
    		(*cur->child)[th2]->parent = new_leaf1;
    		(*new_leaf1->child).push_back((*cur->child)[th2]);
    		int len = (*cur->child).size();
    
    		//rearrange other leaves to th1 th2 as their child
    		for (int i = 0; i < len; i++)
    		{
    			if (i == th1 || i == th2)
    				continue;
    			if (dismatrix[i][th2] < dismatrix[i][th1])
    			{
    				(*cur->child)[i]->parent = new_leaf1;
    				new_leaf1->child->push_back((*cur->child)[i]);
    
    			}
    		}
    		for (int i = 0; i < (*cur->child).size(); i++)
    			delete[] dismatrix[i];
    		delete[]dismatrix;
    
    		vector < Leaf* >::iterator it;
    		it = (*cur->child).begin();
    		while (it != (*cur->child).end())
    		{
    			if ((*it)->parent == new_leaf1)
    				it = (*cur->child).erase(it);
    			else
    				it++;
    		}
    		//不要忘了更新cur和new_leaf1的cf值
    		updateCF(cur);
    		updateCF(new_leaf1);
    
    		//if cur is root,then a new root should be created
    		if (cur->parent == NULL)
    		{
    			Leaf*new_root = new Leaf;
    			new_root->child = new vector < Leaf* > ;
    			new_root->child->push_back(cur);
    			new_root->child->push_back(new_leaf1);
    			cur->parent = new_root;
    			new_leaf1->parent = new_root;
    			updateCF(new_root);
    			root = new_root;
    			return;
    		}
    
    		//cur is not root
    		//不要忘了将new_leaf1加入cur的父亲节点的child
    		cur->parent->child->push_back(new_leaf1);
    		new_leaf1->parent = cur->parent;
    		cur = cur->parent;
    	}
    
    }
    
    
    
    //根据CF值计算簇间距离
    /*double birch::cal_inter_cluster_dis(CF &cf1, CF &cf2)
    {
    return sqrt(sumofvec((2 * (cf1.N + cf2.N)*(cf1.SS + cf2.SS)
    - 2 * (cf1.LS + cf2.LS)*(cf1.LS + cf2.LS))*
    (1.0 / double(cf1.N + cf2.N)*(cf1.N + cf2.N - 1))));
    }*/
    
    double birch::cal_inter_cluster_dis(CF &cf1, CF &cf2)
    {
    	double dis = 0;
    	double temp;
    	for (int i = 0; i < dim; i++)
    	{
    		double t1 = double(cf1.LS[i]) / double(cf1.N);
    		double t2 = double(cf2.LS[i]) / double(cf2.N);
    		temp = t1 - t2;
    		dis += temp*temp;
    	}
    
    	return sqrt(dis);
    }
    
    
    
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	//vector<int*>aa, bb;
    	//int *p1 = new int;
    	//int *p2 = new int;
    	//int *p3 = new int;
    	//*p1 = 8;
    	//*p2 = 9;
    	//*p3 = 88;
    	//aa.push_back(p1);
    	//aa.push_back(p2);
    	//aa.push_back(p3);
    	//*aa[2] = 999;
    	//bb.push_back(p3);
    	//vector<int*>::iterator it = aa.begin() + 1;
    	delete aa[0];
    	//it = aa.erase(it);
    
    	//cout << *bb[0] << endl;
    	//cout << **it << endl;
    	//for (it = aa.begin(); it != aa.end(); it++)
    	//	cout << **it << endl;
    
    	birch bir(5, 6, 20);
    	int dim = 2;
    	int num = 1000;
    	vector<int>span;
    	for (int i = 0; i < dim; i++)
    		span.push_back(1000);
    	bir.generate_data(num, dim, span);
    	for (int i = 0; i < num; i++)
    		bir.insert(bir.dataset[i]);
    	cout << bir.absorbnum << endl;
    	system("pause");
    	return 0;
    }
    


    展开全文
  • matlab 算法集锦

    2021-09-06 19:15:25
    算法集锦 决策树-划分点 function [n,h]=huafendian1(x) %n返回增益 %h返回划分点 %假设0代表第一类 %假设1代表第二类 %输入x第一列为属性,第二列为用于学习的分类结果 [~,m]=sort(x(:,1));%按小到大排序 x=x(m,:)...

    算法集锦

    决策树-划分点

    function [n,h]=huafendian1(x)
    %n返回增益
    %h返回划分点
    %假设0代表第一类
    %假设1代表第二类
    %输入x第一列为属性,第二列为用于学习的分类结果
    
    [~,m]=sort(x(:,1));%按小到大排序
    x=x(m,:);
    t=[];
    for i=1:size(x,1)-1
    t=[t;(x(i,1)+x(i+1,1))/2];%生成划分点
    end
    %原分类结果信息熵
    E1=[];
    C1=length(find(x(:,2)==0))/size(x,1);%第一类比例
    C2=length(find(x(:,2)==1))/size(x,1);%第二类比例
    E1=-[C1*log2(C1),C2*log2(C2)];
    E1(find(isnan(E1),1))=0;%0*log2(0)=NaN,这里是将NaN转化为0,如果纯度100%,则信息熵为0
    E1=sum(E1);
    %候选划分点信息增益
    Ent=[];
    if E1>0
    for i=1:size(t,1)
    x1=x(:,1);
    %根据划分点将数据列转化成0和1
    %这里默认的是数据越小越倾向第一类
    b1=find(x1<=t(i,1));
    b2=find(x1>t(i,1));
    x1(b1)=0;
    x1(b2)=1;
    x2=[x1,x(:,2)];%【重新划分的数据列,因变量】
    c1=length(find(x2(:,1)==0))/size(x2,1);
    c2=length(find(x2(:,1)==1))/size(x2,1);
    d1=length(find(x2(find(x2(:,1)==0),2)==0))/size(find(x2(:,1)==0),1);
    d2=length(find(x2(find(x2(:,1)==0),2)==1))/size(find(x2(:,1)==0),1);
    d3=length(find(x2(find(x2(:,1)==1),2)==0))/size(find(x2(:,1)==1),1);
    d4=length(find(x2(find(x2(:,1)==1),2)==1))/size(find(x2(:,1)==1),1);
    E=[d1*log2(d1),d2*log2(d2);d3*log2(d3),d4*log2(d4)];
    E(find(isnan(E),1))=0;%0*log2(0)=NaN,这里是将NaN转化为0,最多有三个NaN,这里预设三个语句即可
    E(find(isnan(E),1))=0;
    E(find(isnan(E),1))=0;
    E=sum(sum(-E.*[c1,c1;c2,c2]));%重新划分后的信息熵
    Ent(i,1)=E1-E;%信息增益
    end
    [n,m]=max(Ent);
    h=t(m);
    
    else%如果已经达到100%纯度则n和h均返回0
    n=0;
    h=0;
    end
    

    随机森林
    RBF神经网络(多维)

    clc,clear;
    close all;
    %% 产生训练样本(训练输入,训练输出)
    % ld为样本例数
    ld=400; 
    % 产生2*ld的矩阵 
    x=rand(2,ld); 
    % 将x转换到[-1.5 1.5]之间
    x=(x-0.5)*1.5*2; 
    % x的第一行为x1,第二行为x2.
    x1=x(1,:);
    x2=x(2,:);
    % 计算网络输出F值
    F=20+x1.^2-10*cos(2*pi*x1)+x2.^2-10*cos(2*pi*x2);
    %% 建立RBF神经网络 
    eg=1e-30;%目标误差
    sc=1;%扩展速度
    mn=ld;%最大聚类中心数
    display=1;%训练展示,如果是1每增加一个隐藏节点,也就是聚类中心,就会展示下训练误差情况,默认间隔50打印出一次训练误差
    net = newrb(x,F,eg,sc,mn,display);%RBF网络训练
    %% 建立测试样本
    interval=0.1;
    [i, j]=meshgrid(-1.5:interval:1.5);
    row=size(i);
    tx1=i(:);
    tx1=tx1';
    tx2=j(:);
    tx2=tx2';
    tx=[tx1;tx2];
    %% 使用建立的RBF网络进行模拟,得出网络输出
    ty=sim(net,tx);
    %% 使用图像,画出3维图
    % 真正的函数图像
    interval=0.1;
    [x1, x2]=meshgrid(-1.5:interval:1.5);
    F = 20+x1.^2-10*cos(2*pi*x1)+x2.^2-10*cos(2*pi*x2);
    figure
    subplot(1,3,1)
    mesh(x1,x2,F);
    zlim([0,60])
    title('真正的函数图像')
    % 网络得出的函数图像
    v=reshape(ty,row);
    subplot(1,3,2)
    mesh(i,j,v);
    zlim([0,60])
    title('RBF神经网络结果')
    % 误差图像
    subplot(1,3,3)
    mesh(x1,x2,F-v);
    zlim([0,60])
    title('误差图像')
    

    主成分分析

    
    X=[124.3000 134.7000 193.3000 118.6000 94.9000 123.8000
     2.4200 2.5000 2.5600 2.5200 2.6000 2.6500
     25.9800 21.0000 29.2600 31.1900 28.5600 28.1200
     19.0000 19.2500 19.3100 19.3600 19.4500 19.6200
     3.1000 3.3400 3.4500 3.5700 3.3900 3.5800
     79.0000 84.0000 92.0000 105.0000 108.0000 108.0000
     54.1000 53.7000 54.0000 53.9000 53.6000 53.3000
     6.1400 6.7400 7.1800 8.2000 8.3400 8.5100
     3.5700 3.5500 3.4000 3.2700 3.2000 3.1000
     64.0000 64.9600 65.6500 67.0100 65.3400 66.9900]';
    mapping.mean = mean(X, 1);
    X = X - repmat(mapping.mean, [size(X, 1) 1]);%去均值
    C = cov(X);%协方差矩阵
    C(isnan(C)) = 0;
    C(isinf(C)) = 0;
    [M, lambda] = eig(C);%求C矩阵特征向量及特征值
    [lambda, ind] = sort(diag(lambda), 'descend');%排序
    lambda=lambda./sum(lambda);
    lambda=cumsum(lambda);
    mapping.lambda = lambda;
    k=find(lambda>0.95);
    M = M(:,ind(1:k(1)));%%取前k列
    mappedX = X * M;%降维后的X
    mapping.M = M;%映射的基
    

    方差分析

    A=[31.9   24.8   22.1
       27.9   25.7   23.6
       31.8   26.8   27.3
       28.4   27.9   24.9
       35.9   26.2   25.8]; %原始数据输入
    [p,anovatab,stats]=anova1(A);%单因素方差分析
    fa=finv(0.95,anovatab{2,3},anovatab{3,3});%计算fa
    F=anovatab{2,5};%F值
    if p<=0.01 && F>fa
        disp('非常显著')
    elseif p<=0.05 && F>fa
        disp('显著')
    else
        disp('不显著')
    end
    

    logistic回归

    clc,clear;
    close all;
    shuju = [0.8+0.2*rand(20,2),ones(20,1)
        0.7+0.2*rand(20,2),zeros(20,1)];
    X=shuju;
    a1=find(X(:,end)==0);
    a2=find(X(:,end)==1);
    figure
    hold on
    plot(shuju(a1,1),shuju(a1,2),'r*')
    plot(shuju(a2,1),shuju(a2,2),'b*')
    
    Y=X(:,end);
    X(:,end)=[];
    X=[ones(size(X,1),1) X];%新增一列常数项
    [m,n]=size(X);
    %数据归一化处理
    X=mapminmax(X',0,1)';
    
    %设定学习率为0.01
    delta=0.1;
    %初始化参数
    f=@(a,x)1./(1+exp(-(a(1).*x(1,:)+a(2).*x(2,:)+a(3).*x(3,:))));
    a=lsqcurvefit(f,[1 1 1],X',Y');
    theta1=a;
    
    %%训练模型
    %正则化后的梯度下降算法θ的更新公式
    num=100000;
    while num>0
        tmp=X*theta1';
        h=1./(1+exp(-tmp));
        theta1=theta1-delta*mean((h-Y));
        num =num-1;
    end
    
    %测试算法准确率
    cc=0;
    tmp=X*theta1';
    Y1=1./(1+exp(-tmp));
    for i=1:m
        if Y1(i)>=0.5
            Y1(i)=1;
        else
            Y1(i)=0;
        end
    end
    1-sum(abs(Y1-Y))/size(Y,1)
    a1=find(Y1==0);
    a2=find(Y1==1);
    hold on
    plot(shuju(a1,1),shuju(a1,2),'ro')
    plot(shuju(a2,1),shuju(a2,2),'bo')
    legend({'第1类','第2类','logistic第1类','logistic第2类'},'Location','northwest','NumColumns',1)
    

    非线性最小二乘

    clc,clear;
    close all;
    shuju=[1.54  1.61 1.62 1.66 1.71 1.72 1.73 1.86 1.92  2 2.21 2.29  2.34 2.38 2.42 2.44  2.57 2.64 2.71 2.85  2.93 3.01 3.14 3.22  3.34 3.49 3.55 3.79  3.99 4.12
        20.1 20.1 20.3 20.4 20.4 20.5 20.6 20.7 20.9 21.1 21.3 21.5 21.7 21.9 22 22.2 22.4 22.5 22.7 22.7 22.8 22.9 23.4 23.7 24.4 24.9 25.3 27.4 28.4 29.1
        5.17 5.14 5.13 5.10  5.08 5.03 5.01 4.99  4.93 4.91 4.89 4.81  4.77 4.75 4.62 4.56  4.5  4.48 4.46 4.31 4.28  4.19 4.12 3.99 3.91  3.84 3.75 3.64 3.51  3.5];
    x1=shuju(1,:);%x1、x2为自变量
    x2=shuju(2,:);
    c=shuju(3,:);%c为因变量
    x0=[1 1 1 1];%四个参数的初始值
    d=length(x0);
    f=@(a,x)0.08*(ones(1,30)-(x(1,:)./7).*(ones(1,30)-a(1)*(ones(1,30)-((x(1,:)./7).^a(2))).*exp(a(3)*sqrt((x(2,:))./2982))))+ones(1,30)*a(4);
    a=lsqcurvefit(f,x0,[x1;x2],c)
    %%作图
    B=0.08*(ones(1,30)-(x1./7).*(ones(1,30)-a(1)*(ones(1,30)-((x1./7).^a(2))).*exp(a(3)*sqrt((x2)./2982))))+a(4)*ones(1,30);
    figure
    plot3(x1,x2,c,'*')
    hold on
    plot3(x1,x2,B)
    legend('原数据','拟合数据')
    
    figure
    plot(c-B)
    

    词云图

    figure
    wordcloud(ZZ,cs);
    title('词云')
    

    数据包络评价

    数据包络分析(Data envelopment
    analysis,DEA)是运筹学和研究经济生产边界的一种方法。该方法一般被用来测量一些决策部门的生产效率。

    clc,clear;
    close all;
    format long
    data=[14.40 0.65 31.30 3621.00 0.00
    16.90 0.72 32.20 3943.00 0.09
    15.53 0.72 31.87 4086.67 0.07
    15.40 0.76 32.23 4904.67 0.13
    14.17 0.76 32.40 6311.67 0.37
    13.33 0.69 30.77 8173.33 0.59
    12.83 0.61 29.23 10236.00 0.51
    13.00 0.63 28.20 12094.33 0.44
    13.40 0.75 28.80 13603.33 0.58
    14.00 0.84 29.10 14841.00 1.00]';
     
    X=data([1:3],:);%X为输入变量
    Y=data([4:5],:);%Y为输出变量
    [m,n]=size(X);
    s=size(Y,1);
    A=[-X' Y'];%由于目标函数求最小,这里的-X就转化成了求最大
    b=zeros(n,1);
    LB=zeros(m+s,1);UB=[];
    for i=1:n
       f=[zeros(1,m) -Y(:,i)'];
       Aeq=[X(:,i)',zeros(1,s)];
       beq=1;
       w(:,i)=linprog(f,A,b,Aeq,beq,LB,UB);%前3列为投入系数,后2列为产出系数
       E(i,i)=Y(:,i)'*w(m+1:m+s,i);%产出值*产出系数
    end
    theta=diag(E)';
    fprintf('用DEA方法对此的相对评价结果为:\n');
    disp(theta);
    

    协同推荐算法
    FCM聚类
    K-means聚类

    clc,clear;
    close all;
    data=rand(50,2);
    K=3
    [Idx,C,sumD,D]=kmeans(data,K,'dist','sqEuclidean','rep',4);
    %K: 表示将X划分为几类,为整数
    %Idx: N*1的向量,存储的是每个点的聚类标号
    %C: K*P的矩阵,存储的是K个聚类质心位置
    %sumD: 1*K的和向量,存储的是类间所有点与该类质心点距离之和
    %D: N*K的矩阵,存储的是每个点与所有质心的距离
    
    %'dist’(距离测度)
    %'sqEuclidean' 欧式距离(默认时,采用此距离方式)
    %'cityblock' 绝度误差和,又称:L1
    %'cosine' 针对向量
    %'correlation'  针对有时序关系的值
    %'Hamming' 只针对二进制数据
    
    %'Start'(初始质心位置选择方法)
    %'sample' 从X中随机选取K个质心点
    %'uniform' 根据X的分布范围均匀的随机生成K个质心
    
    %kmeans函数详情请edit调出函数文件查看
    
    %绘制散点图
    gscatter(data(:,1),data(:,2),Idx)
    

    KNN分类算法

    邻近算法,或者说K最近邻(KNN,K-NearestNeighbor)分类算法是数据挖掘分类技术中最简单的方法之一。所谓K最近邻,就是K个最近的邻居的意思,说的是每个样本都可以用它最接近的K个邻近值来代表。近邻算法就是将数据集合中每一个记录进行分类的方法

    %在Matlab中利用kNN进行最近邻查询
    X=[0.5.*rand(50,1);0.3+0.5.*rand(50,1)];%产生X
    Y=[0.5.*rand(50,1);0.3+0.5.*rand(50,1)];%产生Y
    Z=[ones(50,1);2.*ones(50,1)];%产生类别
    figure
    gscatter(X,Y,Z)  %点图,颜色根据Z中类别区分
    legend('Location','best')  %自动生成图列
    newpoint = [0.8*rand 0.8*rand];  %待分类的点
    line(newpoint(1),newpoint(2),'marker','x','color','k','markersize',10,'linewidth',2)  %绘制待分类的点
    Mdl = KDTreeSearcher([X,Y])  ;%创建K树,默认采用欧式距离
    %也可以替换距离公式,例如
    %Mdl.Distance='cityblock' 曼哈顿距离
    %Mdl.Distance='chebychev' 契比雪夫距离
    %Mdl.Distance='minkowski' 闵可夫斯基距离
    K=10; %邻近点数
    [n,d] = knnsearch(Mdl,newpoint,'k',K);  %执行KNN(K近邻)搜索,n返回这K个点的编号,d返回的是距离
    line(X(n,1),Y(n,1),'color',[.5 .5 .5],'marker','o','linestyle','none','markersize',10) %绘制周围K个邻近点
    tabulate(Z(n));%统计K个邻近点中各类别点的比例,该点归为比例高的一类
    

    PCA图像压缩
    缺失数据预测问题(粒子滤波算法)

    DBSCAN(Density-Based Spatial Clustering of Applications with
    Noise,具有噪声的基于密度的聚类方法)是一种很典型的密度聚类算法,和K-Means,BIRCH这些一般只适用于凸样本集的聚类相比,DBSCAN既可以适用于凸样本集,也可以适用于非凸样本集。

    组合评价模型—模糊Borda
    BP神经网络
    熵权法

    clc,clear;
    X=[124.3000    2.4200   25.9800   19.0000    3.1000   79.0000   54.1000    6.1400    3.5700   64.0000
      134.7000    2.5000   21.0000   19.2500    3.3400   84.0000   53.7000    6.7400    3.5500   64.9600
      193.3000    2.5600   29.2600   19.3100    3.4500   92.0000   54.0000    7.1800    3.4000   65.6500
      118.6000    2.5200   31.1900   19.3600    3.5700  105.0000   53.9000    8.2000    3.2700   67.0100
       94.9000    2.6000   28.5600   19.4500    3.3900  108.0000   53.6000    8.3400    3.2000   65.3400
      123.8000    2.6500   28.1200   19.6200    3.5800  108.0000   53.3000    8.5100    3.1000   66.9900];
    [n,m]=size(X);
    for i=1:n
        for j=1:m
            p(i,j)=X(i,j)/sum(X(:,j));
        end
    end
    %% 计算第 j 个指标的熵值 e(j)
    k=1/log(n);
    for j=1:m
        e(j)=-k*sum(p(:,j).*log(p(:,j)));
    end
    d=ones(1,m)-e; % 计算信息熵冗余度
    w=d./sum(d) % 求权值 w
    

    层次聚类
    LOF异常数据点检测算法
    Pearson相关系数,Kendall相关系数和Spearman相关系数
    GRNN神经网络
    广义回归神经网络general regression neural network(GRNN)
    概率神经网络(Probabilistic Neural Network)
    秩和比综合评价法

    展开全文
  • http://www.cnblogs.com/zhangchaoyang/articles/2200800.html ...     BIRCH(Balanced Iterative Reducing and Clustering using Hierarchies)天生就是为处理超...

    http://www.cnblogs.com/zhangchaoyang/articles/2200800.html

    http://blog.csdn.net/qll125596718/article/details/6895291

     

     

    BIRCH(Balanced Iterative Reducing and Clustering using Hierarchies)天生就是为处理超大规模(至少要让你的内存容不下)的数据集而设计的,它可以在任何给定的内存下运行。关于BIRCH的更多特点先不介绍,我先讲一下算法的完整实现细节,对算法的实现过程搞清楚后再去看别人对该算法的评价才会感受深刻。

    你不需要具备B树的相关知识,我接下来会讲得很清楚。

    BIRCH算法的过程就是要把待分类的数据插入一棵树中,并且原始数据都在叶子节点上。这棵树看起来是这个样子:

    在这棵树中有3种类型的节点:Nonleaf、Leaf、MinCluster,Root可能是一种Nonleaf,也可能是一种Leaf。所有的Leaf放入一个双向链表中。每一个节点都包含一个CF值,CF是一个三元组,其中data point instance的个数,是与数据点同维度的向量,是线性和,是平方和。比如有一个MinCluster里包含3个数据点(1,2,3),(4,5,6),(7,8,9),则

    N=3,

    =(1+4+7,2+5+8,3+6+9)=(12,15,18),

    =(1+16+49,4+25+64,9+36+81)。 

    就拿这个MinCluster为例,我们可以计算它的

    簇中心

    簇半径

    簇直径

    我们还可以计算两个簇之间的距离,当然你也可以使用D0,D1,D3等等,不过在这里我们使用D2。

    有意思的是簇中心、簇半径、簇直径以及两簇之间的距离D0到D3都可以由CF来计算,比如

    簇直径

    簇间距离,这里的N,LS和SS是指两簇合并后大簇的N,LS和SS。所谓两簇合并只需要两个对应的CF相加那可

    CF1 + CF2 = (N1 + N2 , LS1 + LS2, SS1 + SS2)

    每个节点的CF值就是其所有孩子节点CF值之和,以每个节点为根节点的子树都可以看成 是一个簇。

    Nonleaf、Leaf、MinCluster都是有大小限制的,Nonleaf的孩子节点不能超过B个,Leaf最多只能有L个MinCluster,而一个MinCluster的直径不能超过T。

    算法起初,我们扫描数据库,拿到第一个data point instance--(1,2,3),我们创建一个空的Leaf和MinCluster,把点(1,2,3)的id值放入Mincluster,更新MinCluster的CF值为(1,(1,2,3),(1,4,9)),把MinCluster作为Leaf的一个孩子,更新Leaf的CF值为(1,(1,2,3),(1,4,9))。实际上只要往树中放入一个CF(这里我们用CF作为Nonleaf、Leaf、MinCluster的统称),就要更新从Root到该叶子节点的路径上所有节点的CF值。

    当又有一个数据点要插入树中时,把这个点封装为一个MinCluster(这样它就有了一个CF值),把新到的数据点记为CF_new,我们拿到树的根节点的各个孩子节点的CF值,根据D2来找到CF_new与哪个节点最近,就把CF_new加入那个子树上面去。这是一个递归的过程。递归的终止点是要把CF_new加入到一个MinCluster中,如果加入之后MinCluster的直径没有超过T,则直接加入,否则譔CF_new要单独作为一个簇,成为MinCluster的兄弟结点。插入之后注意更新该节点及其所有祖先节点的CF值。

    插入新节点后,可能有些节点的孩子数大于了B(或L),此时该节点要分裂。对于Leaf,它现在有L+1个MinCluster,我们要新创建一个Leaf,使它作为原Leaf的兄弟结点,同时注意每新创建一个Leaf都要把它插入到双向链表中。L+1个MinCluster要分到这两个Leaf中,怎么分呢?找出这L+1个MinCluster中距离最远的两个Cluster(根据D2),剩下的Cluster看离哪个近就跟谁站在一起。分好后更新两个Leaf的CF值,其祖先节点的CF值没有变化,不需要更新。这可能导致祖先节点的递归分裂,因为Leaf分裂后恰好其父节点的孩子数超过了B。Nonleaf的分裂方法与Leaf的相似,只不过产生新的Nonleaf后不需要把它放入一个双向链表中。如果是树的根节点要分裂,则树的高度加1。

    CF.java

      MinCluster.java

      TreeNode.java

      NonleafNode.java

      LeafNode.java

      BIRCH.java

    最后我们来总结一BIRCH的优势和劣势。

    优点:

    1. 节省内在。叶子节点放在磁盘分区上,非叶子节点仅仅是存储了一个CF值,外加指向父节点和孩子节点的指针。
    2. 快。合并两个两簇只需要两个CF算术相加即可;计算两个簇的距离只需要用到(N,LS,SS)这三个值足矣。
    3. 一遍扫描数据库即可建立B树。
    4. 可识别噪声点。建立好B树后把那些包含数据点少的MinCluster当作outlier。
    5. 由于B树是高度平衡的,所以在树上进行插入或查找操作很快。

    缺点:

    1. 结果依赖于数据点的插入顺序。本属于同一个簇的点可能由于插入顺序相差很远而分到不同的簇中,即使同一个点在不同的时刻被插入,也会被分到不同的簇中。
    2. 对非球状的簇聚类效果不好。这取决于簇直径和簇间距离的计算方法。
    3. 对高维数据聚类效果不好。
    4. 由于每个节点只能包含一定数目的子节点,最后得出来的簇可能和自然簇相差很大。
    5. BIRCH适合于处理需要数十上百小时聚类的数据,但在整个过程中算法一旦中断,一切必须从头再来。
    6. 局部性也导致了BIRCH的聚类效果欠佳。当一个新点要插入B树时,它只跟很少一部分簇进行了相似性(通过计算簇间距离)比较,高的efficient导致低的effective。

     

    1.BIRCH算法概念

              BIRCH(Balanced Iterative Reducing and Clustering Using Hierarchies)全称是:利用层次方法的平衡迭代规约和聚类。BIRCH算法是1996年由Tian Zhang提出来的,参考文献1。首先,BIRCH是一种聚类算法,它最大的特点是能利用有限的内存资源完成对大数据集的高质量的聚类,同时通过单遍扫描数据集能最小化I/O代价。

              首先解释一下什么是聚类,从统计学的观点来看,聚类就是给定一个包含N个数据点的数据集和一个距离度量函数F(例如计算簇内每两个数据点之间的平均距离的函数),要求将这个数据集划分为K个簇(或者不给出数量K,由算法自动发现最佳的簇数量),最后的结果是找到一种对于数据集的最佳划分,使得距离度量函数F的值最小。从机器学习的角度来看,聚类是一种非监督的学习算法,通过将数据集聚成n个簇,使得簇内点之间距离最小化,簇之间的距离最大化。

              BIRCH算法特点:

              (1)BIRCH试图利用可用的资源来生成最好的聚类结果,给定有限的主存,一个重要的考虑是最小化I/O时间。

              (2)BIRCH采用了一种多阶段聚类技术:数据集的单边扫描产生了一个基本的聚类,一或多遍的额外扫描可以进一步改进聚类质量。

              (3)BIRCH是一种增量的聚类方法,因为它对每一个数据点的聚类的决策都是基于当前已经处理过的数据点,而不是基于全局的数据点。

              (4)如果簇不是球形的,BIRCH不能很好的工作,因为它用了半径或直径的概念来控制聚类的边界。

              BIRCH算法中引入了两个概念:聚类特征和聚类特征树,以下分别介绍。

    1.1 聚类特征(CF)

               CF是BIRCH增量聚类算法的核心,CF树中得节点都是由CF组成,一个CF是一个三元组,这个三元组就代表了簇的所有信息。给定N个d维的数据点{x1,x2,....,xn},CF定义如下:

    CF=(N,LS,SS)

                其中,N是子类中节点的数目,LS是N个节点的线性和,SS是N个节点的平方和。

               CF有个特性,即可以求和,具体说明如下:CF1=(n1,LS1,SS1),CF2=(n2,LS2,SS2),则CF1+CF2=(n1+n2, LS1+LS2, SS1+SS2)。

               例如:

               假设簇C1中有三个数据点:(2,3),(4,5),(5,6),则CF1={3,(2+4+5,3+5+6),(2^2+4^2+5^2,3^2+5^2+6^2)}={3,(11,14),(45,70)},同样的,簇C2的CF2={4,(40,42),(100,101)},那么,由簇C1和簇C2合并而来的簇C3的聚类特征CF3计算如下:

    CF3={3+4,(11+40,14+42),(45+100,70+101)}={7,(51,56),(145,171)}

               另外在介绍两个概念:簇的质心和簇的半径。假如一个簇中包含n个数据点:{Xi},i=1,2,3...n.,则质心C和半径R计算公式如下:

    C=(X1+X2+...+Xn)/n,(这里X1+X2+...+Xn是向量加)

    R=(|X1-C|^2+|X2-C|^2+...+|Xn-C|^2)/n

               其中,簇半径表示簇中所有点到簇质心的平均距离。CF中存储的是簇中所有数据点的特性的统计和,所以当我们把一个数据点加入某个簇的时候,那么这个数据点的详细特征,例如属性值,就丢失了,由于这个特征,BIRCH聚类可以在很大程度上对数据集进行压缩。

    1.2 聚类特征树(CF tree)

                CF tree的结构类似于一棵B-树,它有两个参数:内部节点平衡因子B,叶节点平衡因子L,簇半径阈值T。树中每个节点最多包含B个孩子节点,记为(CFi,CHILDi),1<=i<=B,CFi是这个节点中的第i个聚类特征,CHILDi指向节点的第i个孩子节点,对应于这个节点的第i个聚类特征。例如,一棵高度为3,B为6,L为5的一棵CF树的例子如图所示:

                一棵CF树是一个数据集的压缩表示,叶子节点的每一个输入都代表一个簇C,簇C中包含若干个数据点,并且原始数据集中越密集的区域,簇C中包含的数据点越多,越稀疏的区域,簇C中包含的数据点越少,簇C的半径小于等于T。随着数据点的加入,CF树被动态的构建,插入过程有点类似于B-树。加入算法表示如下:

     

    [cpp]  view plain  copy
     
    1. (1)从根节点开始,自上而下选择最近的孩子节点  
    2. (2)到达叶子节点后,检查最近的元组CFi能否吸收此数据点  
    3.     是,更新CF值  
    4.     否,是否可以添加一个新的元组  
    5.         是,添加一个新的元组  
    6.         否则,分裂最远的一对元组,作为种子,按最近距离重新分配其它元组  
    7. (3)更新每个非叶节点的CF信息,如果分裂节点,在父节点中插入新的元组,检查分裂,直到root  


               计算节点之间的距离函数有多种选择,常见的有欧几里得距离函数和曼哈顿距离函数,具体公式如下:

     

               构建CF树的过程中,一个重要的参数是簇半径阈值T,因为它决定了CF tree的规模,从而让CF tree适应当前内存的大小。如果T太小,那么簇的数量将会非常的大,从而导致树节点数量也会增大,这样可能会导致所有数据点还没有扫描完之前内存就不够用了。

    2.算法流程

               BIRCH算法流程如下图所示:

                  整个算法的实现分为四个阶段:

                  (1)扫描所有数据,建立初始化的CF树,把稠密数据分成簇,稀疏数据作为孤立点对待

                  (2)这个阶段是可选的,阶段3的全局或半全局聚类算法有着输入范围的要求,以达到速度与质量的要求,所以此阶段在阶段1的基础上,建立一个更小的CF树

                  (3)补救由于输入顺序和页面大小带来的分裂,使用全局/半全局算法对全部叶节点进行聚类

                  (4)这个阶段也是可选的,把阶段3的中心点作为种子,将数据点重新分配到最近的种子上,保证重复数据分到同一个簇中,同时添加簇标签

                  详细流程请参考文献1。

    3.算法实现

              BIRCH算法的发明者于1996年完成了BIRCH算法的实现,是用c++语言实现的,已在solaris下编译通过。

            另外算法的实现也可参考:http://blog.sina.com.cn/s/blog_6e85bf420100om1i.html

     

     

    参考文献:

    1.BIRCH:An Efficient Data Clustering Method for Very Large Databases

    展开全文
  • 基于网格的聚类算法

    2021-01-27 15:10:58
    聚类算法很多,包括基于划分的聚类算法(如:kmeans),基于层次的聚类算法(如:BIRCH),基于密度的聚类算法(如:DBScan),基于网格的聚类算法等等。基于划分和层次聚类方法都无法发现非凸面形状的簇,真正能...
  • 关于k-means聚类算法matlab实现

    千次阅读 2014-07-21 15:39:14
    此文用matlab实现了k-means聚类算法,虽然代码仍然有bug,但是就结果来说还是很正确的.通读此文对kmeans聚类算法有了更清晰的认识.
  • BIRCH好用但运算复杂 一层次聚类 1层次聚类的原理及分类 1层次法 Hierarchical methods 先计算样本之间的距离每次将距离最近的点合并到同一个类然后再计算类与类之间的距离将距离最近的类合并为一个大类不停的合 并...
  • DBSCAN(Density-Based Spatial Clustering of Applications with Noise,具有噪声的基于密度的聚类方法)是一种很典型的密度聚类算法,和K-Means,BIRCH这些一般只适用于凸样本集的聚类相比,DBSCAN既可以适用于凸...
  • matlab做聚类分析

    2012-06-12 10:30:00
    Matlab提供了两种方法进行聚类分析。 一种是利用clusterdata函数对样本数据进行一次聚类,其缺点为可供用户选择的面较窄,不能更改距离的计算方法; 另一种是分步聚类:(1)找到数据集合中变量两两之间的相似性和...
  • 聚类算法

    千次阅读 2020-04-30 22:26:08
    除了Birch聚类算法的python算法调用了sklearn.cluster里的Birch函数,没有未搜到Clique聚类的matlab版本的算法。其余算法python和matlab算法都是根据原理所编。喜欢的给个star~喔。github项目 2.聚类算法 实际类别...
  • 基于网格的聚类算法CLIQUE
  • 基于连通图的分裂聚类算法

    千次阅读 2015-03-19 20:22:51
    参考文献:基于连通图动态分裂的聚类算法.作者:邓健爽 郑启伦 彭宏...从文章的标题可以看出,今天我所介绍的算法又是一个聚类算法,不过他比较特殊,用到了图方面的知识,而且是一种动态的算法,与BIRCH算法一样,他也
  • 推荐阅读: 原型聚类;聚类划分;K-means9.4 原型聚类原型聚类亦称基于原型聚类(prototype-based clustering),原型指的是样本空间中具有代表性的点。基于原型的定义是每个...常见的原型聚类算法有: K-means;LVQ
  • 数学建模常用模型算法学习(部分)

    千次阅读 多人点赞 2019-08-16 16:19:40
    数学建模常用模型算法学习(部分)神经网络(较好)混沌序列预测(高大上)数据包络(DEA)分析法(较好)支持向量机(高大上)多元分析1. 聚类分析2. 判别分析3. 多维标度法(一般)分类与判别1. 距离聚类(系统...
  • 1、K-近邻算法(KNN)概述(有监督算法,分类算法) 最简单最初级的分类器是将全部的训练数据所对应的类别都记录下来,当测试对象的属性和某个训练对象的属性完全匹配时,便可以对其进行分类。但是怎么可能所有...
  • 常见聚类算法分类

    万次阅读 2016-10-15 10:56:41
    聚类划分: (1)划分聚类 k-means、k-medoids、k-modes、k-...、divisive、BIRCH、ROCK、Chameleon (3)密度聚类 DBSCAN、OPTICS (4)网格聚类 STING (5)模型聚类 GMM (6)图聚类 Spectral Cluste
  • matlab代码最小生成树精灵:具有噪声点检测的快速和鲁棒的层次聚类。 Genie可以输出有意义的簇,并且即使在大型数据集上也很快。 有关文档,教程和基准的信息,请参见。 关于 Genie的更快,更强大的版本-健壮且抗...
  • DBSCAN聚类算法

    2020-07-19 15:43:42
     DBSCAN是一种基于密度的聚类算法,这类密度聚类算法一般假定类别可以通过样本分布的紧密程度决定。同一类别的样本,他们之间的紧密相连的,也就是说,在该类别任意样本周围不远处一定有同类别的样本存在。 通过将...
  • matlab源码求一元函数 数据挖掘算法 算法目录 18大DM算法 包名 目录名 算法名 AssociationAnalysis DataMining_Apriori Apriori-关联规则挖掘算法 AssociationAnalysis DataMining_FPTree FPTree-频繁模式树算法 ...
  • 为使用Python采用BIRCH聚类算法进行的特征聚类源码 本方案的特征定义清楚后,后续完全可以采用其他机器学习方案(监督、无监督)方案进行分类的研究。相对于聚类方案,依然有较为突出的标签,和有价值的应用场景。

空空如也

空空如也

1 2 3 4 5
收藏数 97
精华内容 38
关键字:

birch算法matlab

matlab 订阅