Minería de datos Java - Implementación del algoritmo Apriori

1. Pre-conocimiento del algoritmo A priori

El algoritmo a priori es un algoritmo de conjuntos de elementos frecuentes para la minería de reglas de asociación. Su idea central es extraer conjuntos de elementos frecuentes a través de dos etapas de generación de conjuntos de candidatos y detección de cierre descendente.

La minería de reglas de asociación es uno de los métodos de investigación más activos en la minería de datos.La motivación original se propone para el problema del análisis de la canasta de mercado, y su propósito es descubrir las reglas de práctica entre diferentes productos básicos en la base de datos de transacciones. A través del soporte mínimo proporcionado por el usuario, busque todos los conjuntos de elementos frecuentes, es decir, todos los subconjuntos de elementos que satisfacen el soporte no menos que Minsupport. A través de la mínima credibilidad otorgada por el usuario, en cada conjunto de elementos de máxima frecuencia, encontrar reglas de asociación cuya Confianza no sea inferior a Minconfidencia.

Soporte : El soporte es la proporción del número de veces que aparecen varios datos asociados en el conjunto de datos con respecto al conjunto de datos total. O la probabilidad de ocurrencia de varias asociaciones de datos.

Confianza : la confianza refleja la probabilidad de que aparezcan otros datos después de que aparezca un dato, o la probabilidad condicional de los datos.

2. La idea básica del algoritmo a priori

Primero escanee los datos a analizar en la base de datos, después de establecer el grado de soporte y el grado de confianza, genere elementos frecuentes con el soporte del grado mínimo de soporte, es decir, cuente la frecuencia de uno o más elementos en todos los conjuntos de elementos y encuentre fuera más que o El conjunto de elementos igual al conjunto de apoyo. El segundo es la autocombinación de elementos frecuentes. Además, si el subconjunto de elementos frecuentes desde la conexión no es un elemento frecuente, se realiza la poda. Luego, los artículos frecuentes se procesan para generar artículos candidatos. El último ciclo llama para generar conjuntos de elementos frecuentes.

3. Ejemplos de algoritmo a priori y minería de reglas de asociación fuerte

Ejemplo de algoritmo a priori
inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

Ejemplos de algoritmos para la minería de reglas de asociación fuerte
inserte la descripción de la imagen aquí

4. Proceso de implementación del algoritmo a priori

Contenido del experimento
Hay los siguientes registros de transacciones, escriba un programa para implementar el algoritmo Apriori, extraiga los conjuntos de elementos frecuentes en los registros de transacciones y extraiga todas las reglas de asociación sólidas, establezca el soporte mínimo en 50% y la confianza mínima en 50 %:
inserte la descripción de la imagen aquí

Idea experimental
(1) Defina el conjunto de datos, el soporte mínimo, el número de soporte mínimo, la confianza mínima y una colección de mapas que almacene todos los conjuntos de elementos frecuentes. Llame al método initDataList() encapsulado para inicializar los datos.
(2) Llame al método getAllElement() para obtener todos los elementos de categoría allElement contenidos en el conjunto de datos, y organice y combine la matriz allElement para obtener el conjunto de candidatos candidatoL1. Llame al método getItemSets () para recorrer el candidato L1 y agregue elementos cuyos tiempos de ocurrencia no sean inferiores al recuento mínimo de soporte minSupportCount a itemSets. Una vez que se completa el recorrido, se obtiene el conjunto de elementos frecuentes L1 y se imprime L1.
(3) Inicie el bucle para encontrar k-conjuntos de elementos frecuentes hasta que el conjunto de elementos k-frecuentes obtenido Lk esté vacío, luego salte fuera del bucle. Dentro del cuerpo del ciclo, llame al método getCombination() con todos los elementos de categoría allElementLast contenidos en el conjunto de candidatos k-1 candidatoÚltimo como parámetros para obtener el conjunto de candidatos k candidato Ahora, recorra el conjunto de candidatos k y seleccione el número de ocurrencias no menos que el número mínimo de soporte Los elementos se agregan a los conjuntos de elementos y se devuelven para obtener el conjunto de elementos frecuentes Lk. Si el conjunto de elementos k-frecuentes está vacío, el ciclo finaliza. Si Lk no está vacío, agregue Lk a la colección de todos los conjuntos de elementos frecuentes allItemSets, lo cual es conveniente para encontrar reglas de asociación sólidas más adelante.
(4) Llame al método de correlación () para extraer reglas de asociación sólidas. Dentro del cuerpo del método, recorra todos los conjuntos de elementos frecuentes, obtenga el conjunto de subconjuntos no vacíos subconjunto de cada conjunto de elementos frecuentes, recorra el subconjunto no vacío de cada conjunto de elementos frecuentes y use este subconjunto no vacío y este conjunto de elementos frecuentes como parámetros , llame al método isConfidence() para juzgar si el grado de confianza es mayor que el grado de confianza mínimo y, de ser así, genere el complemento del subconjunto no vacío ==> subconjunto no vacío.

Darse cuenta del código fuente

package com.data.mining.main;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import org.paukov.combinatorics3.Generator;
import org.paukov.combinatorics3.IGenerator;

import java.util.*;

public class Apriori {
    
    

    //定义单行数据
    public static String[] item1,item2,item3,item4,item5,item6,item7,item8,item9,item10,item11,item12,item13,item14;
    //定义数据集
    public static List<String[]> dataList = new ArrayList<>();
    //定义最小支持度
    public static double minSupport = 0.5;
    //定义最小支持数
    public static double minSupportCount = 0.0;
    //定义最小置信度
    public static double minConfidence = 0.5;
    //存放所有频繁项目集
    public static Map<Integer, Multimap<Integer, String[]>> allItemSets = new HashMap<>();

    public static void main(String[] args) {
    
    
        // 初始化数据集
        initDataList();
        String[] allElement = getAllElement(dataList);
        //获取候选集L1
        List<String[]> candidateL1 = getCombination(allElement, 1);
        Multimap<Integer, String[]> itemSetsL1 = getItemSets(candidateL1);
        allItemSets.put(1, itemSetsL1);

        printResult(itemSetsL1, 1);

        List<List<String[]>> stack = new ArrayList<>();
        stack.add(candidateL1);
        for (int k = 2; true; k++) {
    
    
            List<String[]> candidateLast = stack.get(0);
            String[] allElementLast = getAllElement(candidateLast);
            List<String[]> candidateNow = getCombination(allElementLast, k);
            Multimap<Integer, String[]> itemSetsLk = getItemSets(candidateNow);
            if (itemSetsLk.isEmpty()) break;
            allItemSets.put(k, itemSetsLk);
            printResult(itemSetsLk, k);
            stack.remove(0);
            stack.add(candidateNow);
        }
        correlation();
    }

    public static boolean isConfidence(String[] subSetStr1, String[] value){
    
    
        double confidence = getCountByConfidence(value) * 1.0 / getCountByConfidence(subSetStr1);
        if (confidence >= minConfidence) return true;
        return false;
    }

    public static Integer getCountByConfidence(String[] subSetStr){
    
    
        int count = 0; //存放子集在数据集中出现的次数
        for (String[] dataItem : dataList) {
    
    
            //比如在数据集第一项{A,B,C,D,E,F,G}中是否出现过A,B.C
            int index = -1;
            for (int i = 0; i < subSetStr.length; i++) {
    
    
                //比如A出现过,则index>0,若A没出现过,则index=-1
                index = Arrays.binarySearch(dataItem, subSetStr[i]);
                if (index < 0) break;
            }
            if (index >= 0){
    
     //出现过ABC
                count++;
            }
        }
        return count;
    }

    /**
     * 找强关联规则
     */
    public static void correlation(){
    
    
        //遍历所有频繁项目集
        for (int k = 1; k <= allItemSets.size(); k++) {
    
    
            //获取k-频繁项目集
            Multimap<Integer, String[]> keyItemSet = allItemSets.get(k);
            Iterator<Map.Entry<Integer, String[]>> iterator = keyItemSet.entries().iterator();
            //遍历k频繁项目集
            while (iterator.hasNext()){
    
    
                Map.Entry<Integer, String[]> entry = iterator.next();
                String[] value = entry.getValue();
//                List<String> valueList = Arrays.asList(value);
//                List<String> valueList = new ArrayList<>();
//                Collections.addAll(valueList, value);
                //求value的非空子集
                for (int i = 1; i < value.length; i++) {
    
    
                    List<String[]> subSet = getCombination(value, i); //非空子集的集合
                    for (String[] subSetItem : subSet) {
    
     //subSetItm是频繁项目集每一个非空子集
                        List<String> valueList = new ArrayList<>();
                        Collections.addAll(valueList, value);
                        List<String> subSetItemList = Arrays.asList(subSetItem);
                        //去除已经求得子集后的valueList
                        valueList.removeAll(subSetItemList); //此时valueList中存放非空子集的补集
                        if (isConfidence(subSetItem, value)){
    
    
                            System.out.println(Arrays.toString(subSetItem) + "==>" + Arrays.toString(valueList.toArray(new String[valueList.size()])));
                        }
                    }
                }
            }
        }
    }

    /**
     * 打印出所有频繁项目集
     * @param itemSet
     * @param k
     */
    public static void printResult(Multimap<Integer, String[]> itemSet, int k){
    
    
        System.out.print("L" + k + "----------->");
        //使用迭代器遍历multimap
        Iterator<Map.Entry<Integer, String[]>> iterator = itemSet.entries().iterator();
        //遍历排列组合结果的每一项,将出现次数不小于minSupportCount的项加入到itemSets
        while (iterator.hasNext()){
    
    
            Map.Entry<Integer, String[]> entry = iterator.next();
//            System.out.println("key = " + entry.getKey() + "," + Arrays.toString(entry.getValue()));
            String[] value = entry.getValue();
            for (int i = 0; i < value.length; i++) {
    
    
                System.out.print(value[i]);
            }
            System.out.print(",");
        }
        System.out.println("");
//        System.out.println("-------------------------k=" + k + "-----------------------------------");
    }

    /**
     * 获取含有所有元素的数组
     * @param itemSet
     * @return
     */
    public static String[] getAllElement(List<String[]> itemSet){
    
    
        List<String> allElementList = new ArrayList<>(); //存放项目集中所有有的元素
        for (int i = 0; i < itemSet.size(); i++) {
    
    
            String[] item = itemSet.get(i);
            if (i == 0){
    
     //将第一项的所有元素加入到allElementList中
                for (int j = 0; j < item.length; j++) {
    
    
                    allElementList.add(item[j]);
                }
            }else {
    
    
                for (int z = 0; z < item.length; z++) {
    
    
                    //判断allElementList中是否已经存在item[z]
                    int isExist = Arrays.binarySearch(allElementList.toArray(new String[allElementList.size()]), item[z]);
                    if (isExist < 0){
    
     //不存在item[z]
                        allElementList.add(item[z]); //添加item[z]到allElementList中
                    }
                }
            }
        }
        return allElementList.toArray(new String[allElementList.size()]);
    }

    /**
     * 获取候选集
     * @param allItemStr 含频繁项目集所有元素的数组
     * @param k 要生成k候选集
     * @return
     */
    public static List<String[]> getCombination(String[] allItemStr, int k){
    
    
        //定义候选集
        List<String[]> candidateSets = new ArrayList<>();
        //对allItemStr进行k组合
        IGenerator<List<String>> candidateList = Generator.combination(allItemStr).simple(k);
        for (List<String> candidate : candidateList) {
    
    
            String[] candidateStr = candidate.toArray(new String[candidate.size()]);
            candidateSets.add(candidateStr);//将每一项组合放入候选集中
        }
        return candidateSets;
    }

    /**
     * 处理候选集,获取频繁项目集
     * @param itemList 候选集
     * @return 频繁项目集
     */
    public static Multimap<Integer, String[]> getItemSets(List<String[]> itemList){
    
    
        Multimap<Integer, String[]> itemSets = ArrayListMultimap.create(); //项目集
        //得到排列组合结果(候选集)每一项在数据集中出现的次数
        Multimap<Integer, String[]> itemCount = getItemCount(itemList);
        //使用迭代器遍历multimap
        Iterator<Map.Entry<Integer, String[]>> iterator = itemCount.entries().iterator();
        //遍历排列组合结果的每一项,将出现次数不小于minSupportCount的项加入到itemSets
        while (iterator.hasNext()){
    
    
            Map.Entry<Integer, String[]> entry = iterator.next();
            if (entry.getKey() >= minSupportCount){
    
    
                itemSets.put(entry.getKey(), entry.getValue());
            }
        }
        return itemSets;
    }

    /**
     * 获取排列组合结果(候选集)每一项在数据集中出现的次数
     * @param itemList
     * @return
     */
    public static Multimap<Integer, String[]> getItemCount(List<String[]> itemList){
    
    
        Multimap<Integer, String[]> itemCount = ArrayListMultimap.create();
        //遍历项目集
        for (String[] item : itemList) {
    
    
            int count = 0; //存放A,B.C在数据集中出现的次数
            for (String[] dataItem : dataList) {
    
    
                //比如在数据集第一项{A,B,C,D,E,F,G}中是否出现过A,B.C
                int index = -1;
                for (int i = 0; i < item.length; i++) {
    
    
                    //比如A出现过,则index>0,若A没出现过,则index=-1
                    index = Arrays.binarySearch(dataItem, item[i]);
                    if (index < 0) break;
                }
                if (index >= 0){
    
     //出现过ABC
                    count++;
                }
            }
            itemCount.put(count, item); //存放(ABC出现的次数,{A,B,C})
        }
        return itemCount;
    }

    /**
     * 初始化数据集
     */
    public static void initDataList(){
    
    
        //初始化单行数据
        item1 = new String[]{
    
    "A", "B", "C", "D", "E", "F", "G"};
        item2 = new String[]{
    
    "A", "B", "C", "D", "E", "H"};
        item3 = new String[]{
    
    "A", "B", "C", "D", "E", "F", "G", "H"};
        item4 = new String[]{
    
    "A", "B", "C", "G", "H"};
        item5 = new String[]{
    
    "A", "B", "C", "D", "G", "H"};
        item6 = new String[]{
    
    "A", "B", "C", "D", "E", "F", "G", "H"};
        item7 = new String[]{
    
    "A", "B", "C", "D", "E", "F", "G"};
        item8 = new String[]{
    
    "A", "B", "C", "E", "G", "H"};
        item9 = new String[]{
    
    "A", "B", "C", "D", "E", "F", "H"};
        item10 = new String[]{
    
    "C", "D", "E", "F", "G", "H"};
        item11 = new String[]{
    
    "A", "B", "C", "D", "G", "H"};
        item12 = new String[]{
    
    "A", "C", "D", "E", "F", "G", "H"};
        item13 = new String[]{
    
    "A", "B", "C", "E", "F", "G", "H"};
        item14 = new String[]{
    
    "B", "C", "E", "F", "G", "H"};

        //初始化数据集
        dataList.add(item1);
        dataList.add(item2);
        dataList.add(item3);
        dataList.add(item4);
        dataList.add(item5);
        dataList.add(item6);
        dataList.add(item7);
        dataList.add(item8);
        dataList.add(item9);
        dataList.add(item10);
        dataList.add(item11);
        dataList.add(item12);
        dataList.add(item13);
        dataList.add(item14);

        //赋值给最小支持的数
        minSupportCount = dataList.size() * minSupport;
    }
}

Resultados experimentales
Todos los conjuntos de elementos frecuentes:
inserte la descripción de la imagen aquí
Todas las reglas de asociación fuertes son demasiadas para encajar, por lo que mostraré una parte como se muestra en la figura, pruébelo usted mismo:
inserte la descripción de la imagen aquí

5. Resumen experimental

El autor no garantiza que los resultados de este experimento sean correctos, solo proporciona una idea para implementar el algoritmo Apriori utilizando el lenguaje Java. Debido a que el experimento no dio una respuesta, el autor ingresó los datos experimentales con la respuesta en Internet en el programa, y ​​el resultado del programa es consistente con la respuesta, por lo que el problema no debería ser grande. Si hay algo que no está bien escrito, ¡por favor dame algunos consejos!
La página de inicio del autor también tiene un resumen de otros algoritmos de minería de datos, ¡bienvenido a patrocinar!

Supongo que te gusta

Origin blog.csdn.net/qq_54162207/article/details/128365867
Recomendado
Clasificación