自动提取Tag算法

根据词频分析取tag

 

  分析;把每个帖子进行分词,然后把词的出现频率倒序排列,取出前N个就作为TAG了。当然要一个板块一个板块的提取tag,如果把军事板块和情感板块的帖子混杂在一起提取tag,提取出来的tag相关性比较差一些,如果分开提取,相关性要好一些,整体效果好。好多时候做训练算法,语料很重要。先分词吧,自己写分词算法也是弄个词库,自己用正向最大匹配来分词,或者两个两个字的来当词,所以还不如直接用中科院那套呢,直接使用了隐式马尔可夫算法,效果虽说不是很好吧,也能满足需求了,对吧。具体测试代码、分词组件、词库下载见以下链接

http://www.cnblogs.com/edison1024/archive/2006/05/03/390832.html
得点了他那个广告才能显示下载地址,你就点吧,人家提供下载也不容易。分词后要去除停止词,停止词自己从网上搜索一份,如果不去除停止词,最后肯定是“了”,“的”,“我”等词出现的频率最高,你不会把这些常用词做tags吧,呵呵。当然NICTCLAS是可以标注词性的,你可以分词后把语气词、副词等虚词去了,这样更好一些,但我就懒得做了,直接分词、去除停止词两步。
完了计算每个词出现的频率就好说了,弄一个全局的字典,每个词出现一次增加一个计数,第一次出现先添加到字典,并计数为0,最后把出现次数在某个阈值以上的词插入到数据库里,这就是你要的tag了,先来看一下我的效果吧(大家别笑哦,我是从一个美女贴图论坛提取了一些帖子的主题当语料的,为了不降低博客园的PR值,就贴图,不贴文字了)。

自动提取Tag算法

开始上代码
先贴分词

自动提取Tag算法namespace WawaSoft.Search.Common
自动提取Tag算法
{
自动提取Tag算法    
public sealed class WawaSplitWorder
自动提取Tag算法    
{
自动提取Tag算法        
static List<string> _stopWords = new List<string>();
自动提取Tag算法        
static NICTCLAS _nictclas;
自动提取Tag算法        
public static void Init()
自动提取Tag算法        
{
自动提取Tag算法            
try
自动提取Tag算法            
{
自动提取Tag算法                
//1、初始化分词器
自动提取Tag算法
                _nictclas = new NICTCLAS();
自动提取Tag算法                _nictclas.OperateType 
= eOperateType.OnlySegment;
自动提取Tag算法                _nictclas.OutputFormat 
= eOutputFormat.PKU;
自动提取Tag算法
自动提取Tag算法                
//2、加载停止词
自动提取Tag算法
                using (StreamReader sr =
自动提取Tag算法                    
new StreamReader("data\\StopWords.txt", Encoding.Default))
自动提取Tag算法                
{
自动提取Tag算法                    
string temp;
自动提取Tag算法                    
while ((temp = sr.ReadLine()) != null)
自动提取Tag算法                    
{
自动提取Tag算法                        _stopWords.Add(temp);
自动提取Tag算法                    }

自动提取Tag算法                }

自动提取Tag算法            }

自动提取Tag算法            
catch (Exception ex)
自动提取Tag算法            
{
自动提取Tag算法                Trace.TraceError(
"初始化分词器错误:{0}", ex);
自动提取Tag算法            }

自动提取Tag算法        }

自动提取Tag算法
自动提取Tag算法        
/// <summary>
自动提取Tag算法        
/// 分词并去除停止词
自动提取Tag算法        
/// </summary>
自动提取Tag算法        
/// <param name="input"></param>
自动提取Tag算法        
/// <returns></returns>

自动提取Tag算法        public static IEnumerable<string> SplitWords(string input)
自动提取Tag算法        
{
自动提取Tag算法            Console.WriteLine(input);
自动提取Tag算法            
自动提取Tag算法            
//预处理,不处理那个分词组件有可能内存读写错误,那玩意儿写的不太健壮,容错性8行的说,呵呵
自动提取Tag算法
            input = input.Replace("/""");
自动提取Tag算法            input 
= input.Replace(".""");
自动提取Tag算法            
string result = string.Empty;
自动提取Tag算法            List
<string> ret = null;
自动提取Tag算法            
try
自动提取Tag算法            
{
自动提取Tag算法                
//1、分词
自动提取Tag算法
                _nictclas.ParagraphProcessing(input, ref result);
自动提取Tag算法                ret 
= new List<string>(
自动提取Tag算法                    result.Split(
new string[] "  " }, StringSplitOptions.RemoveEmptyEntries));
自动提取Tag算法                
自动提取Tag算法                
//2、去除干扰词
自动提取Tag算法
                List<string> needRemove = new List<string>();
自动提取Tag算法                
foreach (string word in ret)
自动提取Tag算法                
{
自动提取Tag算法                    
foreach (string s in _stopWords)
自动提取Tag算法                    
{
自动提取Tag算法                        
if (string.Compare(s, word, false== 0)
自动提取Tag算法                        
{
自动提取Tag算法                            needRemove.Add(word);
自动提取Tag算法                            
break;
自动提取Tag算法                        }

自动提取Tag算法                    }

自动提取Tag算法                }

自动提取Tag算法
自动提取Tag算法                
foreach (string removeWord in needRemove)
自动提取Tag算法                
{
自动提取Tag算法                    ret.Remove(removeWord);
自动提取Tag算法                }

自动提取Tag算法            }

自动提取Tag算法            
catch (Exception ex)
自动提取Tag算法            
{
自动提取Tag算法                
//错误的时候除了打出错误详细信息后打出出错的上下文,传入的参数,临时变量等有助于从trace里分析错误,要不死了也不知道怎么死的
自动提取Tag算法
                Console.WriteLine("{0}\r\n{1}",input,ex);
自动提取Tag算法            }

自动提取Tag算法
自动提取Tag算法            
return ret;
自动提取Tag算法        }

自动提取Tag算法    }

自动提取Tag算法}

自动提取Tag算法
自动提取Tag算法

 

计算词频

自动提取Tag算法class AutoGenTag
自动提取Tag算法
{
自动提取Tag算法    
//大字典,保存每个词的词频,key是词,value是词频
自动提取Tag算法
    static Dictionary<string,int> _hashlist = new Dictionary<stringint>(10240);
自动提取Tag算法
自动提取Tag算法    
public static void Excute()
自动提取Tag算法    
{
自动提取Tag算法        
//1、取出帖子,越多越好,越多提取的准确性越高
自动提取Tag算法
        IEnumerable<string> source = Dao.GetPostTitles();
自动提取Tag算法        
foreach (string str in source)
自动提取Tag算法        
{
自动提取Tag算法            
//2、把每个帖子主题分词
自动提取Tag算法
            IEnumerable<string> words = WawaSplitWorder.SplitWords(str);
自动提取Tag算法            
if(words == null)
自动提取Tag算法                
continue;
自动提取Tag算法
自动提取Tag算法            
//3、把每个词插入到大字典里,以前存在就把词频加1
自动提取Tag算法
            foreach (string word in words)
自动提取Tag算法            
{
自动提取Tag算法                
if(_hashlist.ContainsKey(word))
自动提取Tag算法                
{
自动提取Tag算法                    _hashlist[word]
++;
自动提取Tag算法                }

自动提取Tag算法                
else
自动提取Tag算法                
{
自动提取Tag算法                    _hashlist.Add(word,
0);
自动提取Tag算法                }

自动提取Tag算法            }

自动提取Tag算法        }

自动提取Tag算法        
//4、把大于某个阈值(这里是20)的词插入数据
自动提取Tag算法
        foreach (KeyValuePair<stringint> pair in _hashlist)
自动提取Tag算法        
{
自动提取Tag算法            
//如果一次循环插入几万个词,SQLSERVE每秒提交的批会很高,有可能CPU瞬间很高,Sleep(0)能让CPU长得慢点儿,Sleep(1)也行,不过我不知道这两个的区别。或者直接 用sqlserver的bilkcopy性能也8错
自动提取Tag算法
            Thread.Sleep(0);
自动提取Tag算法            
if (pair.Value > 20)
自动提取Tag算法            
{
自动提取Tag算法                Console.WriteLine(
"{0}-{1}",pair.Key,pair.Value);
自动提取Tag算法                Dao.addtags(pair.Key, pair.Value);
自动提取Tag算法            }

自动提取Tag算法        }

自动提取Tag算法    }

自动提取Tag算法}

自动提取Tag算法
自动提取Tag算法