加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

蛙蛙牌自动提取Tag算法

发布时间:2020-12-12 15:55:06 所属栏目:MsSql教程 来源:网络整理
导读:蛙蛙牌自动提取Tag算法 摘要:Tag系统是Web2.0的一个招牌应用,如果你有一个经营了好几年的论坛,是不是也想生成自己的一套TAG。别听他们说什么语义WEB,文本聚类算法,TIIDF,余弦定理,相似度算法啥的高深算法(我一个也没整明白),跟我来,简单的计算词

蛙蛙牌自动提取Tag算法

摘要:Tag系统是Web2.0的一个招牌应用,如果你有一个经营了好几年的论坛,是不是也想生成自己的一套TAG。别听他们说什么语义WEB,文本聚类算法,TIIDF,余弦定理,相似度算法啥的高深算法(我一个也没整明白),跟我来,简单的计算词频来提取tag的效果就很好。

分析;把每个帖子进行分词,然后把词的出现频率倒序排列,取出前N个就作为TAG了。当然要一个板块一个板块的提取tag,如果把军事板块和情感板块的帖子混杂在一起提取tag,提取出来的tag相关性比较差一些,如果分开提取,相关性要好一些,整体效果好。好多时候做训练算法,语料很重要。先分词吧,自己写分词算法也是弄个词库,自己用正向最大匹配来分词,或者两个两个字的来当词,所以还不如直接用中科院那套呢,直接使用了隐式马尔可夫算法,效果虽说不是很好吧,也能满足需求了,对吧。具体测试代码、分词组件、词库下载见以下链接
http://www.cnblogs.com/edison1024/archive/2006/05/03/390832.html
得点了他那个广告才能显示下载地址,你就点吧,人家提供下载也不容易。分词后要去除停止词,停止词自己从网上搜索一份,如果不去除停止词,最后肯定是“了”,“的”,“我”等词出现的频率最高,你不会把这些常用词做tags吧,呵呵。当然NICTCLAS是可以标注词性的,你可以分词后把语气词、副词等虚词去了,这样更好一些,但我就懒得做了,直接分词、去除停止词两步。
完了计算每个词出现的频率就好说了,弄一个全局的字典,每个词出现一次增加一个计数,第一次出现先添加到字典,并计数为0,最后把出现次数在某个阈值以上的词插入到数据库里,这就是你要的tag了,先来看一下我的效果吧(大家别笑哦,我是从一个美女贴图论坛提取了一些帖子的主题当语料的,为了不降低博客园的PR值,就贴图,不贴文字了)。

开始上代码
先贴分词

namespace ?WawaSoft.Search.Common

{

????
public?sealed?class?WawaSplitWorder

????
{

????????
static?List<string>?_stopWords?=?new?List<string>();

????????
static?NICTCLAS?_nictclas;

????????
public?static?void?Init()

????????
{

????????????
try

????????????
{

????????????????
//1、初始化分词器

????????????????_nictclas?=?new?NICTCLAS();

????????????????_nictclas.OperateType?
=?eOperateType.OnlySegment;

????????????????_nictclas.OutputFormat?
=?eOutputFormat.PKU;


????????????????
//2、加载停止词

????????????????using?(StreamReader?sr?=

????????????????????
new?StreamReader("data//StopWords.txt",?Encoding.Default))

????????????????
{

????????????????????
string?temp;

????????????????????
while?((temp?=?sr.ReadLine())?!=?null)

????????????????????
{

????????????????????????_stopWords.Add(temp);

????????????????????}

????????????????}

????????????}

????????????
catch?(Exception?ex)

????????????
{

????????????????Trace.TraceError(
"初始化分词器错误:{0}",?ex);

????????????}

????????}


????????
///?<summary>

????????
///?分词并去除停止词

????????
///?</summary>

????????
///?<param?name="input"></param>

????????
///?<returns></returns>

????????public?static?IEnumerable<string>?SplitWords(string?input)

????????
{

????????????Console.WriteLine(input);

????????????

????????????
//预处理,不处理那个分词组件有可能内存读写错误,那玩意儿写的不太健壮,容错性8行的说,呵呵

????????????input?=?input.Replace("/",?"");

????????????input?
=?input.Replace(".",?"");

????????????
string?result?=?string.Empty;

????????????List
<string>?ret?=?null;

????????????
try

????????????
{

????????????????
//1、分词

????????????????_nictclas.ParagraphProcessing(input,?ref?result);

????????????????ret?
=?new?List<string>(

????????????????????result.Split(
new?string[]?{?"??"?},?StringSplitOptions.RemoveEmptyEntries));

????????????????

????????????????
//2、去除干扰词

????????????????List<string>?needRemove?=?new?List<string>();

????????????????
foreach?(string?word?in?ret)

????????????????
{

????????????????????
foreach?(string?s?in?_stopWords)

????????????????????
{

????????????????????????
if?(string.Compare(s,?word,?false)?==?0)

????????????????????????
{

????????????????????????????needRemove.Add(word);

????????????????????????????
break;

????????????????????????}

????????????????????}

????????????????}


????????????????
foreach?(string?removeWord?in?needRemove)

????????????????
{

????????????????????ret.Remove(removeWord);

????????????????}

????????????}

????????????
catch?(Exception?ex)

????????????
{

????????????????
//错误的时候除了打出错误详细信息后打出出错的上下文,传入的参数,临时变量等有助于从trace里分析错误,要不死了也不知道怎么死的

????????????????Console.WriteLine("{0}/r/n{1}",input,ex);

????????????}


????????????
return?ret;

????????}

????}

}



计算词频

class ?AutoGenTag

{

????
//大字典,保存每个词的词频,key是词,value是词频

????static?Dictionary<string,int>?_hashlist?=?new?Dictionary<string,?int>(10240);


????
public?static?void?Excute()

????
{

????????
//1、取出帖子,越多越好,越多提取的准确性越高

????????IEnumerable<string>?source?=?Dao.GetPostTitles();

????????
foreach?(string?str?in?source)

????????
{

????????????
//2、把每个帖子主题分词

????????????IEnumerable<string>?words?=?WawaSplitWorder.SplitWords(str);

????????????
if(words?==?null)

????????????????
continue;


????????????
//3、把每个词插入到大字典里,以前存在就把词频加1

????????????foreach?(string?word?in?words)

????????????
{

????????????????
if(_hashlist.ContainsKey(word))

????????????????
{

????????????????????_hashlist[word]
++;

????????????????}

????????????????
else

????????????????
{

????????????????????_hashlist.Add(word,
0);

????????????????}

????????????}

????????}

????????
//4、把大于某个阈值(这里是20)的词插入数据

????????foreach?(KeyValuePair<string,?int>?pair?in?_hashlist)

????????
{

????????????
//如果一次循环插入几万个词,SQLSERVE每秒提交的批会很高,有可能CPU瞬间很高,Sleep(0)能让CPU长得慢点儿,Sleep(1)也行,不过我不知道这两个的区别。或者直接?用sqlserver的bulkcopy 性能也8错

????????????Thread.Sleep(0);

????????????
if?(pair.Value?>?20)

????????????
{

????????????????Console.WriteLine(
"{0}-{1}",pair.Key,pair.Value);

????????????????Dao.addtags(pair.Key,?pair.Value);

????????????}

????????}

????}

}



代码写的比较糙,大家凑合看,都是随手写的。最后写一个sql查出tag并按词频倒序排列,选出一个datatable,用datalist一绑定就O了。当然了,我这是提取标签的土法,大师们看了别吐,呵呵。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读