我正在创建自己的apriori算法在c_中的实现。对于这个项目,我不允许使用apriori算法的其他库等。
下面是我的testData.json请注意,这些是字符串,这意味着我的项集可能不仅仅是A这样的字符,而是candy这样的单词。
注意:我将在测试时使用20(20%)支持。

{
    "transactions": [
        [ "B", "C" ],
        [ "B", "C", "D" ],
        [ "A", "D" ],
        [ "A", "B", "C", "D" ],
        [ "C", "D" ],
        [ "C", "D", "E" ],
        [ "A", "B" ]
    ]
}

当我单击一个按钮来处理数据以及所需的值minSupportminConfidence(还不需要)时,我将json反序列化为一个对象,并将其保存到名为database的公共变量中,下面是数据库类。
public class Database
{
    public List<List<string>> transactions { get; set; }
}

单击按钮时,我调用方法GenerateCandidateItemSet()这是我遇到问题的地方。以下内容:
private Dictionary<string, int> C1 = new Dictionary<string, int>();
private void GenerateCandidateItemSet()
{
    foreach (List<string> transaction in database.transactions)
    {
        foreach (string item in transaction)
        {
            if (C1.ContainsKey(item))
            {
                C1[item]++;
            }
            else
            {
                C1.Add(item, 1);
            }
        }
    }

    // Check our frequency, remove items with low support
    foreach (string key in C1.Keys.ToList())
    {
        double frequency = (C1[key] * 100) / (database.transactions.Count);
        if (frequency < minSupport)
        {
            C1.Remove(key);
        }
    }

    // Pairing check stuff
    List<string[]> itemPairs = new List<string[]>();
    List<string> items = C1.Keys.ToList();

    foreach (string item in items)
    {
        // FIX THIS LOOP LATER TO CONTAIN ALL PAIRS
        List<string> itemArray = new List<string>();
        if (item != items.Last())
        {
            itemArray.Add(item);
            itemArray.Add(items[items.IndexOf(item) + 1]);
            itemPairs.Add(itemArray.ToArray());
        }
    }
    GenerateItemSetRecursive(itemPairs);
}

就在截面之前://Pairing check stuff的值是:
循环完成后,我需要得到如下信息:
BC, BD, BA, CD, CA, DA

如果我插入C1,结果将是AB, AD, BC, BD, CD等等。
基本上,我需要找到事务的ABD, BCD
问题:考虑到我的项目对只得到Frequent Itemsets,而不是BC, CD, DA,我知道我的逻辑是错误的我的循环会是什么样的?

最佳答案

正如你所指出的,C1.Keys.ToList()给你{"B", "C", "D", "A"}
代码所做的是遍历该列表并添加下一个元素以创建一对(假设它不是最后一个元素)。
逐步检查代码-您将看到第一次迭代给您{"B", "C"},下一次迭代给您{"C", "D"},之后的一次迭代给您{"D", "A"}。最后一次迭代将用于列表的最后一个元素,因此items.Last()将计算为true,并且不会添加任何内容。
一个简单的方法,使你现在的工作是添加另一个循环,在你的破碎循环其目的是当您为"B"进行迭代时,不仅要添加{"B", "C"},而且还要添加{"B", "D"}{"B", "A"},同样,您为"C"进行的外部迭代将同时找到{"C", "D"}{"C", "A"}
我希望这有帮助-如果你仍然有困难的话,请随时打电话给我。

10-08 08:32
查看更多