Java中的卡片相似度计算

Java中的卡片相似度计算,java,Java,下面的代码循环遍历数组列表(mainItems),找到最相似的两个数组,并将它们放入sortedTransactions中。对于小数据(10000个事务),它运行良好,但对于88000个事务,它将永远运行。我们可以做些什么来让它为大数据服务 import java.util.*; public class Sort { static private List<Transactions> trans = ReadFile.transactions; sta

下面的代码循环遍历数组列表(mainItems),找到最相似的两个数组,并将它们放入sortedTransactions中。对于小数据(10000个事务),它运行良好,但对于88000个事务,它将永远运行。我们可以做些什么来让它为大数据服务

import java.util.*;

    public class Sort {

    static private  List<Transactions> trans = ReadFile.transactions;
    static public   List<int[]> mainItems;
    static public   ArrayList<int[]> sortedTransactions = new ArrayList<int[]>();

    static {
        mainItems = new ArrayList<int[]>();

        for (Transactions t : trans) {
            mainItems.add(t.getItems());
        }
    }

    static private  double jaccardSimilarity(int[] a, int[] b) {

        Set<Integer> s1 = new LinkedHashSet<Integer>();
        for(int i =0; i< a.length; i++){
            s1.add(a[i]);
        }
        Set<Integer> s2 = new LinkedHashSet<Integer>();
        for(int i =0; i< b.length; i++){
            s2.add(b[i]);
        }

        Set<Integer> intersection = new LinkedHashSet<>(s1);
        intersection.retainAll(s2);

        Set<Integer> union = new LinkedHashSet<Integer>(s1); 
        union.addAll(s2); 

        double jaccardSimilarity = (double)intersection.size()/ (double)union.size();
        //System.out.println(intersection);
        return jaccardSimilarity;
    }

    static private boolean isAllEqual(List<Double> a){

        for(int i=1; i<a.size(); i++){
            if(a.get(0) != a.get(i)){
                return false;
            }
        }

        return true;
    }


    static public void generatePairs() {

        for (int i = 0; i < mainItems.size() - 1; i++) {

            if (!sortedTransactions.contains(mainItems.get(i))) {

                List<Double> myd = new ArrayList<Double>();
                List<int[]> mys = new ArrayList<int[]>();

                for (int j = i + 1; j < mainItems.size(); j++) {

                    if (!sortedTransactions.contains(mainItems.get(j))) {

                        myd.add(jaccardSimilarity(mainItems.get(i),mainItems.get(j)));
                        mys.add(mainItems.get(j));
                    }
                }

                if (isAllEqual(myd) == false) {

                    sortedTransactions.add(mainItems.get(i));
                    sortedTransactions.add(mys.get(maxValue(myd)));
                }
            }
        }
    }

    static private int maxValue(List<Double> d) {

        double max = d.get(0);
        int f = 0;

        for(int i =1; i< d.size(); i++){

            if(d.get(i) > max){

                max= d.get(i); 
                f= i; 
            }
        }
        return f;
    }
}
import java.util.*;
公共类排序{
静态私有列表trans=ReadFile.transactions;
静态公共列表主要项目;
静态公共ArrayList sortedTransactions=new ArrayList();
静止的{
mainItems=新的ArrayList();
交易记录(t:trans){
添加(t.getItems());
}
}
静态私有双重相似性(int[]a,int[]b){
Set s1=新LinkedHashSet();
for(int i=0;i
您不必创建联合集(联合(s1,s2)。size()是s1.size()+s2.size()-交集(s1,s2.size())

静态私有双重相似性(int[]a,int[]b){
Set s1=新的HashSet();
for(int i=0;i
如果不在本地运行,很难确认,但您可以尝试对其进行
Collections
排序,将列表按从大到小的数字顺序排列,然后选择第一个值,而不是在
maxValue
中对列表进行暴力迭代。Java中的排序非常快速,并且经过了很好的优化。不幸的是,要提高具有许多循环的程序的性能,通常需要对结构进行彻底的重新思考。以下库包括一个Jaccard相似性实现,可能有用-
static private double jaccardSimilarity(int[] a, int[] b) {

    Set<Integer> s1 = new HashSet<Integer>();
    for (int i = 0; i < a.length; i++) {
        s1.add(a[i]);
    }
    Set<Integer> s2 = new HashSet<Integer>();
    for (int i = 0; i < b.length; i++) {
        s2.add(b[i]);
    }

    final int sa = s1.size();
    final int sb = s2.size();
    s1.retainAll(s2);
    final int intersection = s1.size();
    return 1d / (sa + sb - intersection) * intersection;
}