使用 Encog 框架的垃圾邮件过滤示例

Posted

技术标签:

【中文标题】使用 Encog 框架的垃圾邮件过滤示例【英文标题】:Spam Filtering Example Using Encog Framework 【发布时间】:2014-03-09 10:23:47 【问题描述】:

我正在寻找有关如何使用 Encog 框架创建简单的垃圾邮件过滤/分类或集群应用程序的示例。我一直无法在谷歌上找到任何东西。

我还购买了 Jeff Heaton 的书,用 C# 中的 Encog3 编程神经网络,但我找不到此类应用程序的任何示例。

任何人都可以提供有关如何根据主题和正文将电子邮件分类为垃圾邮件的简单应用程序的任何信息吗?

编辑:我已经看到了如何在 Python 中执行此操作的方法,但我想问,谁能提供任何 Encog + C# 特定示例来说明如何创建垃圾邮件过滤/分类应用程序?

【问题讨论】:

@JeffHeaton 你在外面吗!? 【参考方案1】:

大多数垃圾邮件过滤器使用一种贝叶斯分类,即最流行的朴素贝叶斯分类。 这是一些无需任何额外框架即可使用的代码。

public void TrainClassifier(DataTable table)

dataSet.Tables.Add(table);

//table
DataTable GaussianDistribution = dataSet.Tables.Add("Gaussian");
GaussianDistribution.Columns.Add(table.Columns[0].ColumnName);

//columns
for (int i = 1; i < table.Columns.Count; i++)

    GaussianDistribution.Columns.Add(table.Columns[i].ColumnName + "Mean");
    GaussianDistribution.Columns.Add(table.Columns[i].ColumnName + "Variance");


//calc data
var results = (from myRow in table.AsEnumerable()
               group myRow by myRow.Field<string>(table.Columns[0].ColumnName) into g
               select new  Name = g.Key, Count = g.Count() ).ToList();

for (int j = 0; j < results.Count; j++)

    DataRow row = GaussianDistribution.Rows.Add();
    row[0] = results[j].Name;

    int a = 1;
    for (int i = 1; i < table.Columns.Count; i++)
    
        row[a] = Helper.Mean(SelectRows(table, i, string.Format("0 = '1'", 
                             table.Columns[0].ColumnName, results[j].Name)));
        row[++a] = Helper.Variance(SelectRows(table, i, 
                   string.Format("0 = '1'", 
                   table.Columns[0].ColumnName, results[j].Name)));
        a++;
    

public string Classify(double[] obj)

Dictionary<string,> score = new Dictionary<string,>();

var results = (from myRow in dataSet.Tables[0].AsEnumerable()
               group myRow by myRow.Field<string>(
                     dataSet.Tables[0].Columns[0].ColumnName) into g
               select new  Name = g.Key, Count = g.Count() ).ToList();

for (int i = 0; i < results.Count; i++)

    List<double> subScoreList = new List<double>();
    int a = 1, b = 1;
    for (int k = 1; k < dataSet.Tables["Gaussian"].Columns.Count; k = k + 2)
    
        double mean = Convert.ToDouble(dataSet.Tables["Gaussian"].Rows[i][a]);
        double variance = Convert.ToDouble(dataSet.Tables["Gaussian"].Rows[i][++a]);
        double result = Helper.NormalDist(obj[b - 1], mean, Helper.SquareRoot(variance));
        subScoreList.Add(result);
        a++; b++;
    

    double finalScore = 0;
    for (int z = 0; z < subScoreList.Count; z++)
    
        if (finalScore == 0)
        
            finalScore = subScoreList[z];
            continue;
        

        finalScore = finalScore * subScoreList[z];
    

    score.Add(results[i].Name, finalScore * 0.5);


double maxOne = score.Max(c => c.Value);
var name = (from c in score
            where c.Value == maxOne
            select c.Key).First();

return name;

编辑:这就是你如何使用它!

    DataTable table = new DataTable(); 
    table.Columns.Add("Sex"); 
    table.Columns.Add("Height", typeof(double)); 
    table.Columns.Add("Weight", typeof(double)); 
    table.Columns.Add("FootSize", typeof(double)); 

    //training data. 
    table.Rows.Add("male", 6, 180, 12); 
    table.Rows.Add("male", 5.92, 190, 11); 
    table.Rows.Add("male", 5.58, 170, 12); 
    table.Rows.Add("male", 5.92, 165, 10); 
    table.Rows.Add("female", 5, 100, 6); 
    table.Rows.Add("female", 5.5, 150, 8); 
    table.Rows.Add("female", 5.42, 130, 7); 
    table.Rows.Add("female", 5.75, 150, 9); 
    table.Rows.Add("transgender", 4, 200, 5); 
    table.Rows.Add("transgender", 4.10, 150, 8); 
    table.Rows.Add("transgender", 5.42, 190, 7); 
    table.Rows.Add("transgender", 5.50, 150, 9);

    Classifier classifier = new Classifier(); 
    classifier.TrainClassifier(table);
    //output would be transgender.
    Console.WriteLine(classifier.Classify(new double[]  4, 150, 12 ));
    Console.Read();

【讨论】:

感谢您在没有其他人愿意的情况下提供答案。我试图研究你的代码,但我有两个问题:1)我将如何初始化 dataSet 变量以运行测试? 2) 我将什么类型的对象传递给 Classify() 方法以返回结果?我只是想找到一种方法来运行此代码以查看它的实际运行情况。 编辑了帖子 :) 希望这也能回答您的 Classify() 问题。 感谢您的代码。我不确定如何将其应用于垃圾邮件过滤;但是,也许随着我继续学习,这将变得更加清晰。 您应该找到一组垃圾邮件并检索每个单词及其频率。使用频率作为输入节点,您可以计算电子邮件是垃圾邮件的概率。我建议寻找html标签。 你能展示一下 Helper.Mean 和 Helper.Variance 方法的内容吗?

以上是关于使用 Encog 框架的垃圾邮件过滤示例的主要内容,如果未能解决你的问题,请参考以下文章

如何用 Java 利用贝叶斯算法实现垃圾邮件过滤

在贝叶斯垃圾邮件过滤器中计算令牌成为垃圾邮件的概率

实例讲解:基于贝叶斯分类的垃圾邮件识别

目前最好的垃圾邮件过滤算法

绕过 Gmail 的垃圾邮件过滤器(使用 PHP 从共享主机发送的邮件)

在朴素贝叶斯垃圾邮件过滤中结合个体概率