首页 > 也谈贝叶斯分类(C#)版本

也谈贝叶斯分类(C#)版本

   

代码下载

 最近在做一个大作业。搭建一个信息检索平台。用到了贝叶斯分类参考了洞庭散人大哥的技术博客

http://www.cnblogs.com/phinecos/archive/2008/10/21/1316044.html

但是,他的算法运行起来很慢,原因是IO操作过于频繁,而且有些IO操作是可以避免的。下面开始介绍我的贝叶斯分类算法实现。

采用分词器为河北理工大学吕震宇老师的SHARPICTCLAS 该分词器没有Lucene接口,自己实现Analyzer 和Tokenizer 类如下

 

ExpandedBlockStart.gifICTCLASAnalyzer
using System;

using System.Collections.Generic;

using System.Text;

using System.IO;

using Lucene.Net.Analysis;

using Lucene.Net.Analysis.Standard;



namespace Bayes

{

    
class ICTCLASAnalyzer:Analyzer

    {

        
public static readonly System.String[] CHINESE_ENGLISH_STOP_WORDS = new string[400];

        
public string NoisePath = Environment.CurrentDirectory + "\data\stopwords.txt";

        
public ICTCLASAnalyzer()

        {

           StreamReader reader 
= new StreamReader(NoisePath, System.Text.Encoding.Default);

            
string noise = reader.ReadLine();

            
int i = 0;

           

            
while (!string.IsNullOrEmpty(noise)&&i<400)

            {

                CHINESE_ENGLISH_STOP_WORDS[i] 
= noise;

               noise 
= reader.ReadLine();

               i
++;

             }

            

      }



               
/**//**//**//// Constructs a {@link StandardTokenizer} filtered by a {@link

       
/// StandardFilter}, a {@link LowerCaseFilter} and a {@link StopFilter}. 

       
/// 

        public override TokenStream TokenStream(System.String fieldName, System.IO.TextReader reader)

        {

           TokenStream result 
= new ICTCLASTokenizer(reader);

            result 
= new StandardFilter(result);

            result 
= new LowerCaseFilter(result);

            result 
= new StopFilter(result, CHINESE_ENGLISH_STOP_WORDS);

           
return result;

        }





    }

}

 

 

 

ExpandedBlockStart.gifICTCLASTokenizer
using System;

using System.Collections.Generic;

using System.Text;

using Lucene.Net.Analysis;

using Lucene.Net.Documents;

using Lucene.Net.Analysis.Standard;

using System.IO;

using SharpICTCLAS;





namespace Bayes

{

    
class ICTCLASTokenizer:Tokenizer

    {

         
int nKind = 1;

         List
<WordResult[]> result;

         
int startIndex = 0;

         
int endIndex = 0;

         
int i = 1;

         
/**//**/

         
/**//// 

        
/// 待分词的句子

        
/// 

        private string sentence;

         
/**//**/

        
/**//// Constructs a tokenizer for this Reader. 

        public ICTCLASTokenizer(System.IO.TextReader reader)

        {

             
this.input = reader;

             sentence 
= input.ReadToEnd();

             sentence 
= sentence.Replace(" """);

             
string DictPath = Path.Combine(Environment.CurrentDirectory, "Data"+ Path.DirectorySeparatorChar;

            
//Console.WriteLine("正在初始化字典库,请稍候");

            WordSegment wordSegment = new WordSegment();

             wordSegment.InitWordSegment(DictPath);

             result 
= wordSegment.Segment(sentence, nKind);

         }

 

         
/**//**/

         
/**//// 进行切词,返回数据流中下一个token或者数据流为空时返回null

         
/// 

         public override Token Next()

         {

             Token token 
= null;

            
while (i < result[0].Length - 1)

             {

                 
string word = result[0][i].sWord;

                 endIndex 
= startIndex + word.Length - 1;

                 token 
= new Token(word, startIndex, endIndex);

                startIndex 
= endIndex + 1;



                 i
++;

                 
return token;



            }

            
return null;

         }



    }

}

 

 

 下面开始介绍我的实现:分为五个类: ChineseSpliter用于分词,ClassifyResult用于储存结果。MemoryTrainingDataManager,用于管理IO操作 FastNaiveBayesClassification 用于实现贝叶斯算法。和洞庭散人不同之处在于我的各个计算前向概率,条件概率,联合概率的函数写在了一个类里,而不是多个类,这样做的目的在于避免不必要的IO操作。

 

ExpandedBlockStart.gifClassifyResult
using System;

using System.Collections.Generic;

using System.Text;



namespace Bayes

{

    
class ClassifyResult

    {

        
public string className;

        
public float score;

        
public ClassifyResult()

        {

            className 
= "";

            score 
= 0;

        }

    

    

    }

}

 

 

 

ExpandedBlockStart.gifChineseSpliter
using System;

using System.Collections.Generic;

using System.Text;

using System.IO;

using Lucene.Net.Analysis;





namespace Bayes

{

    
class ChineseSpliter

    {    
public string Split(string text,string splitToken)

        {

          StringBuilder sb 
= new StringBuilder();



            Analyzer an 
= new ICTCLASAnalyzer();



            
//TokenStream ts = an.ReusableTokenStream("", new StringReader(text));



           TokenStream ts 
= an.TokenStream(""new StringReader(text));



             Lucene.Net.Analysis.Token token;

              
while ((token = ts.Next()) != null)

              {

                   sb.Append(splitToken 
+ token.TermText());

               }

 

             
return sb.ToString().Substring(1);

         }

        
public string[] GetTerms(string result, string spliter)

        {

            
string[] terms = result.Split(new string[] { spliter }, StringSplitOptions.RemoveEmptyEntries);

            
return terms;



        }



    }

}

 

 

  

ExpandedBlockStart.gifMemoryTrainingDataManager
using System;

using System.Collections.Generic;

using System.Text;

using System.IO;







namespace Bayes

{

    
class MemoryTrainingDataManager

    {   
//调用 函数GetClassifications()获取类别子目录在磁盘中的储存位置,为公有成员变量 txtClassification赋值

        
//调用 GetTtotalFileCount() 获取总共的样本集文章数目,为公有成员变量 totalFileCount赋值

        public String[] txtClassifications;//训练语料分类集合

        private static String defaultPath = "F:\TrainingSet";

        
public int totalFileCount;

        
public void   GetClassifications()

        {

            
this.txtClassifications = Directory.GetDirectories(defaultPath);

           

        }



        
public int GetSubClassFileCount(string subclass)

        {

            
string[] paths = Directory.GetFiles(subclass);

            
return paths.Length;

        }

        
public void  GetTotalFileCount()

        {

            
int count = 0;

            
for (int i = 0; i < txtClassifications.Length; i++)

            {

                count 
+= GetSubClassFileCount(txtClassifications[i]);

            }

            totalFileCount 
= count;

        }

       

        
public string GetText(string filePath)

        {

            StreamReader sr 
= new StreamReader(filePath, Encoding.Default);

            
string text = sr.ReadToEnd();

            sr.Close();

            
return text;

        }

        
public void  SetMainMemoryStructure(ref StoreClass sc ,string subclass)

        {

           

               
string []paths=Directory.GetFiles(subclass);

                sc.classificationName 
= subclass;

               sc.classificationCount 
= paths.Length;

               sc.strFileContentList 
= new string[sc.classificationCount];

                
for (int k = 0; k < paths.Length; k++)

                {

                    sc.strFileContentList[k]
=GetText(paths[k]);

                }

           }



        
public int GetKeyCountOfSubClass(string key, ref StoreClass sc)

        {

            
int count = 0;

            
for (int i = 0;  i < sc.classificationCount; i++)

            {

                
if (sc.strFileContentList[i].Contains(key))

                {

                    count
++;

                }

            }

                
return count;





        }

         

        









    }

}

 

 

ExpandedBlockStart.gifFastNaiveBayesClassification
using System;

using System.Collections.Generic;

using System.Text;



namespace Bayes

{

    
class FastNaiveBayesClassification

    {

       
// public  StoreClass memorystore=new StoreClass();

        public MemoryTrainingDataManager mtdm=new MemoryTrainingDataManager();

        
private ChineseSpliter spliter = new ChineseSpliter();

        
private static float ZoomFactor = 10;

       

        
public FastNaiveBayesClassification()

        {

            mtdm.GetClassifications();

            mtdm.GetTotalFileCount();

        }

        
/// 

        
/// Nc 表示属于c类的文本数,N表示总文件数

        
/// 


        
/// 

        
/// 

        
/// 

        public float CalculatePriorProbability(float Nc,float N)

        {

            
float ret = 0F;

            ret 
= Nc / N;

            
return ret;

        }

        
/// 

        
/// 

        
/// 


        
/// 某一类别中某一词频出现的文件数

        
/// 该类别文件总数

        
/// 

        public float CalculateConditionalProbability(float NxC, float Nc)

        {

            
float M = 0F;

            
float ret = 0F;

            ret 
= (NxC + 1/ (Nc + M + mtdm.txtClassifications.Length);

            
return ret;

        }

        
public float CalculateJointProbability(float []NxC, float Nc, float  N)

        {

            
float ret = 1;

            
for (int i = 0; i < NxC.Length; i++)

            {

                ret 
*= CalculateConditionalProbability(NxC[i], Nc) * ZoomFactor;

            }

            ret 
= ret * CalculatePriorProbability(Nc, N) ;

            
return ret;



        }

        
public string[] SplitTerms(string text)

        {

            
//string result = tokenizer.TextSplit(text, "@@@");

            
// string[] terms = tokenizer.GetTerms(result, "@@@");

            string result = spliter.Split(text, "@@@");

            
string[] terms = spliter.GetTerms(result, "@@@");

            
return terms;

        }



        
public ClassifyResult Classify(string text)

        {   
int end=mtdm.txtClassifications.Length;

            ClassifyResult[] results 
= new ClassifyResult[end];

            
for (int i = 0; i < end; i++)

            {

                results[i] 
= new ClassifyResult();

            }

            
string[] terms = SplitTerms(text);

            
float N = mtdm.totalFileCount;

            
for (int i = 0; i < end; i++)

            {

                StoreClass sc 
= new StoreClass();

                mtdm.SetMainMemoryStructure(
ref sc,  mtdm.txtClassifications[i]);

                
float  Nc = sc.classificationCount;

                
float[] Nxc = new float[terms.Length];

               

                
for(int k=0;k<terms.Length;k++)

                {

                  Nxc[k]
=mtdm.GetKeyCountOfSubClass(terms[k],ref sc);

                 
// Console.WriteLine("含有的关键词数量{0}",Nxc[k]);

                }

                 results[i].score
= CalculateJointProbability(Nxc, Nc, N);  

                 results[i].className 
= sc.classificationName;

                 Console.WriteLine(
"类别{0},分数{1}", results[i].className, results[i].score);

            

            }

            
//选择法排序

            for (int m = 0; m < results.Length - 1; m++)

            {

                
int k = m;

                
for (int n = m + 1; n < results.Length; n++)

                {

                    
if (results[n].score > results[k].score)

                    {

                        k 
= n;

                    }

                }

                
if (k != m)

                {

                    ClassifyResult temp 
= new ClassifyResult();

                    temp.score 
= results[k].score;

                    temp.className 
= results[k].className;

                    results[k].className 
= results[m].className;

                    results[k].score 
= results[m].score;

                    results[m].score 
= temp.score;

                    results[m].className 
= temp.className;

                }

            }

            
return results[0];



        }

    }

}

 

更多相关:

  • importjava.security.SecureRandom;importjavax.crypto.Cipher;importjavax.crypto.SecretKey;importjavax.crypto.SecretKeyFactory;importjavax.crypto.spec.DESKeySpec;//结果与DES算...

  • 题目:替换空格 请实现一个函数,把字符串 s 中的每个空格替换成"%20"。 输入:s = "We are happy." 输出:"We%20are%20happy." 限制: 0 <= s 的长度 <= 10000 解题: 时间复杂度:O(n) 空间复杂度:O(n) class Solution { public:s...

  • 在C++11标准库中,string.h已经添加了to_string方法,方便从其他类型(如整形)快速转换成字面值。 例如: for (size_t i = 0; i < texArrSize; i++)RTX_Shader.SetInt(string("TexArr[") + to_string(i) + "]", 7 + i);...

  • Ubuntu 14.04安装并升级之后,变成楷体字体非常难看,我昨天搞了一晚上,终于理了个头绪,这里整理一下。 经过网上调研,大家的一致看法是,使用开源字体库文泉驿的微黑字体效果比较理想,甚至效果不输windows平台的雅黑字体。下面我打算微黑来美化Ubuntu 14.04. 1.安装文泉驿微黑字体库 sudo aptitude...

  • 使用string时发现了一些坑。 我们知道stl 容器并不是线程安全的,所以在使用它们的过程中往往需要一些同步机制来保证并发场景下的同步更新。 应该踩的坑还是一个不拉的踩了进去,所以还是记录一下吧。 string作为一个容器,随着我们的append 或者 针对string的+ 操作都会让string内部的数据域动态增加,而动态增加的...

  • IHostingEnviroment 获取环境相关洗洗 IsDevelopment()、IsStaging()、IsProduction() 分别为:开发、准生产、生产环境 IsEnviroment("Uat") 自定义环境,比如自定义Uat环境 新建: appsettings.Uat.json文件 {"Enviroment":...

  • 七. DockPanel DockPanel定义一个区域,在此区域中,您可以使子元素通过描点的形式排列,这些对象位于 Children 属性中。停靠面板其实就是在WinForm类似于Dock属性的元 素。DockPanel会对每个子元素进行排序,并停靠在面板的一侧,多个停靠在同侧的元素则按顺序排序。     如果将 LastChild...

  • 该链接有导入,导出源码,我的代码有下链接改写,完善而成的, http://www.cnblogs.com/colder/p/3611906.html using System;using System.Collections.Generic;using System.Linq;using System.Web;using System...

  • 转载请注明出自天外归云的博客园:http://www.cnblogs.com/LanTianYou/ 对于SharePoint中已经是Record的Item,我们想要修改他的属性,这在UI界面是无法完成的: 这时需要通过Records.BypassLocks API来完成。设计一个tool,利用Records.BypassLocks...

  • C# async await 学习笔记1(http://www.cnblogs.com/siso/p/3691059.html)  提到了ThreadId是一样的,突然想到在WinForm中,非UI线程是无法直接更新UI线程上的控件的问题。 于是做了如下测试: using System; using System.Collectio...

  • 在.Net Framework中,配置文件一般采用的是XML格式的,.NET Framework提供了专门的ConfigurationManager来读取配置文件的内容,.net core中推荐使用json格式的配置文件,那么在.net core中该如何读取json文件呢?1、在Startup类中读取json配置文件1、使用Confi...

  •   1 public class FrameSubject extends JFrame {   2    3   …………..   4    5   //因为无法使用多重继承,这儿就只能使用对象组合的方式来引入一个   6    7   //java.util.Observerable对象了。   8    9   DateSub...

  • 本案例主要说明如何使用NSwag 工具使用桌面工具快速生成c# 客户端代码、快速的访问Web Api。 NSwagStudio 下载地址 比较强大、可以生成TypeScript、WebApi Controller、CSharp Client  1、运行WebApi项目  URL http://yourserver/swagger 然后...

  •   在绑定完Action的所有参数后,WebAPI并不会马上执行该方法,而要对参数进行验证,以保证输入的合法性.   ModelState 在ApiController中一个ModelState属性用来获取参数验证结果.   public abstract class ApiController : IHttpController,...

  • 1# 引用  C:AVEVAMarineOH12.1.SP4Aveva.ApplicationFramework.dll C:AVEVAMarineOH12.1.SP4Aveva.ApplicationFramework.Presentation.dll 2# 引用命名空间, using Aveva.Applicati...