C#中先验算法的数据挖掘问题
Data Mining issue with the apriori algorithm in C#
我正在用 C# 创建我自己的先验算法实现。对于这个项目,我不允许使用其他库等用于先验算法。
下面是我的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" ]
]
}
当我单击一个按钮来处理数据以及我需要的值时,minSupport
和 minConfidence
(还不需要),我将我的 JSON 反序列化为一个对象并保存它进入一个名为 database
的 public 变量下面是数据库 class.
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
C1
的值是:
循环完成后,我需要得到类似的东西:
BC, BD, BA, CD, CA, DA
如果我插入 AB, AD, BC, BD, CD
,结果将是 ABD, BCD
等等。
基本上,我需要为交易找到 Frequent Itemsets
。
问题: 考虑到我的 itemPairs 只得到 BC, CD, DA
,而不是 BC, BD, BA, CD, CA, DA
,我知道我的逻辑是错误的。我的循环会是什么样子才能让它工作?
正如您指出的那样,C1.Keys.ToList()
给您 {"B", "C", "D", "A"}
。
您的代码所做的是遍历该列表并添加下一个元素以创建一对(假设它不是最后一个元素。
单步执行您的代码 - 您会看到第一次迭代给您 {"B", "C"}
,下一次迭代给您 {"C", "D"}
,然后是下一次迭代给您 {"D", "A"}
。最后一次迭代将针对列表的最后一个元素,因此 items.Last()
的计算结果为真,并且不会添加任何内容。
使您现在的工作正常进行的一种简单方法是在损坏的循环内添加另一个循环。这样做的目的是,当您迭代 "B"
时,您不仅会添加 {"B", "C"}
,还会添加 {"B", "D"}
和 {"B", "A"}
,同样地,您会添加 "C"
的外部迭代会找到 {"C", "D"}
和 {"C", "A"}
.
希望这对您有所帮助 - 如果您对此仍有困难,请随时在 C# 聊天中联系我。
我正在用 C# 创建我自己的先验算法实现。对于这个项目,我不允许使用其他库等用于先验算法。
下面是我的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" ]
]
}
当我单击一个按钮来处理数据以及我需要的值时,minSupport
和 minConfidence
(还不需要),我将我的 JSON 反序列化为一个对象并保存它进入一个名为 database
的 public 变量下面是数据库 class.
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
C1
的值是:
循环完成后,我需要得到类似的东西:
BC, BD, BA, CD, CA, DA
如果我插入 AB, AD, BC, BD, CD
,结果将是 ABD, BCD
等等。
基本上,我需要为交易找到 Frequent Itemsets
。
问题: 考虑到我的 itemPairs 只得到 BC, CD, DA
,而不是 BC, BD, BA, CD, CA, DA
,我知道我的逻辑是错误的。我的循环会是什么样子才能让它工作?
正如您指出的那样,C1.Keys.ToList()
给您 {"B", "C", "D", "A"}
。
您的代码所做的是遍历该列表并添加下一个元素以创建一对(假设它不是最后一个元素。
单步执行您的代码 - 您会看到第一次迭代给您 {"B", "C"}
,下一次迭代给您 {"C", "D"}
,然后是下一次迭代给您 {"D", "A"}
。最后一次迭代将针对列表的最后一个元素,因此 items.Last()
的计算结果为真,并且不会添加任何内容。
使您现在的工作正常进行的一种简单方法是在损坏的循环内添加另一个循环。这样做的目的是,当您迭代 "B"
时,您不仅会添加 {"B", "C"}
,还会添加 {"B", "D"}
和 {"B", "A"}
,同样地,您会添加 "C"
的外部迭代会找到 {"C", "D"}
和 {"C", "A"}
.
希望这对您有所帮助 - 如果您对此仍有困难,请随时在 C# 聊天中联系我。