关键词提取算法

1、先给本聚类内的所有文档进行分词,然后用一个字典保存每个词出现的次数;2、遍历每个词,得到每个词在所有文档里的IDF值,和在本聚类内出现的次数(TF)相乘的值;3、用一个字典(key是词,value是TF*IDF权重)来保存所有的词信息,然后按value对字典排序

摘要:昨天给大家演示简单的文本聚类,但要给每个聚类再提取一两个关键词用于表示该聚类。我们还是用TFIDF算法来做,因为这是比较简单的提取特征算法,不过这里的TF是指某词在本聚类内所有文章的词频,而不是本文章内出现的次数,IDF还是在所有文章里出现的倒文档频率。
原理:1、先给本聚类内的所有文档进行分词,然后用一个字典保存每个词出现的次数
2、遍历每个词,得到每个词在所有文档里的IDF值,和在本聚类内出现的次数(TF)相乘的值
3、用一个字典(key是词,value是TF*IDF权重)来保存所有的词信息,然后按value对字典排序,最后取权重排名靠前的几个词作为关键词

测试输入如下
================================
a 奥运 拳击 入场券 基本 分罄 邹市明 夺冠 对手 浮出 水面
a 股民 要 清楚 自己 的 目的
a 印花税 之 股民 四季
a ASP.NET 自定义 控件 复杂 属性 声明 持久性 浅析
a 运动员 行李 将 “后 上 先 下” 奥运 相关 人员 行李 实名制
a asp.net 控件 开发 显示 控件 内容
a 奥运 票务 网上 成功 订票 后 应 及时 到 银行 代售 网点 付款
a 某 心理 健康 站 开张 后 首 个 咨询 者 是 位 新 股民
a 残疾 女 青年 入围 奥运 游泳 比赛 创 奥运 历史 两 项 第一
a 介绍 一 个 ASP.net MVC 系列 教程
a 在 asp.net 中 实现 观察者 模式 ,或 有 更 好 的 方法 (续)
a 输 大钱 的 股民 给 我们 启迪
a Asp.Net 页面 执行 流程 分析
a 杭州 股民 放 鞭炮 庆祝 印花税 下调
================================
数据还是昨天的数据,但每个文章前面都加了个a,所以这个词的IDF肯定很低,如果单村用词频来提取关键词,这个a肯定被当场关键词了,所以要乘以IDF值来调整特征提取的精度。我们要用程序把上面的文档分成3类,并提取每个类的两个关键词

我给TFIDFMeasure类加了一个GetKeyword的方法,第一个参数是传入几个文档id列表,第二个参数是要在这几个文档里提取几个关键词,下面是使用该方法的代码

 

//4、初始化k-means算法,第一个参数表示输入数据,第二个参数表示要聚成几个类
WawaKMeans kmeans = new WawaKMeans(data, K);
//5、开始迭代

kmeans.Start();

//6、获取聚类结果并输出

WawaCluster[] clusters = kmeans.Clusters;
StringBuilder sb = new
 StringBuilder();
foreach (WawaCluster cluster in
 clusters)
{
    List<int> members =
 cluster.CurrentMembership;
    
    
//获取该聚类的关键词并打印

    IEnumerable<string> keywords = tf.GetKeyword(cluster.CurrentMembership, 2);
    StringBuilder sbTemp = new
 StringBuilder();
    sbTemp.Append("---------"
);
    
foreach (string s in
 keywords)
    
{
        sbTemp.AppendFormat("{0},"
, s);
    }

    sbTemp.Append(
"-------\r\n");
    Console.WriteLine(sbTemp);

    
//打印该聚类的成员

    sb.Append(sbTemp.ToString());
    
foreach (int i in
 members)
    
{
        Console.WriteLine(docs[i]);
        sb.AppendFormat("{0}\r\n"
, docs[i]);
    }

}


再看GetKeyword方法的实现

/**//// <summary>
/// 获取某组文档的关键词
/// </summary>

/// <param name="arr"></param>
/// <param name="count"></param>
/// <returns></returns>

public IEnumerable<string> GetKeyword(List<int> arr, int count)
{
    
//1、给每个文档分词并保存在一个列表里

    List<string> allWords = new List<string>();
    
foreach (int i in
 arr)
    
{
      
//这里把一个文档里出现的多个词进行消重

        allWords.AddRange(GetDistinctWords(_tokenizer.Partition(_docs[i])));
    }


    
//2、用一个字典保存词的词频,key是词,value是重复次数
    Dictionary<string , int> tfDict = SortByDuplicateCount(allWords);

    
//
3、遍历已排序的词频字典,并获取每个词的IDF值,并把更新后的结果放入一个tfidfDict词典
    
//该词典的key是词,value是tfidf值

    Dictionary<string,float> tfidfDict = new Dictionary<stringfloat>(tfDict.Count);
    
foreach (KeyValuePair<stringint> pair in
 tfDict)
    
{
        
int
 tremIndex;
        
if(_tremIndex.TryGetValue(pair.Key,out
 tremIndex))
        
{
            
float idf =
 GetInverseDocumentFrequency(tremIndex);
            tfidfDict.Add(pair.Key, pair.Value *
 idf);
        }

    }


    
//4、给tfidf字典俺权重排序
    tfidfDict = GetSortByValueDict(tfidfDict);

    
//5、更新要提取的关键词数量

    int keywordCount = count;
    
if (keywordCount >
 tfidfDict.Count)
        keywordCount =
 tfidfDict.Count;
    
    
//6、用一个数组保存tfidf字典的keys,这些key已排序

    string[] keywordArr = new string[tfidfDict.Count];
    tfidfDict.Keys.CopyTo(keywordArr,0
);

    
//7、在关键词数组里取出前几个关键词返回给调用者

    List<string> result = new List<string>(keywordCount);
    
int tempCount = 0
;
    
foreach (string str in
 keywordArr)
    
{
        tempCount++
;
        result.Add(str);
        
if(tempCount >=keywordCount) break
;
    }

    
return result;
}



 

这里面用到一个SortByDuplicateCount方法,是对一个集合里的元素按重复次数排序,输出一个字典,字典的key是原始元素,value是出现次数,并按出现次数从大到小排序,像 { "abcd", "ab", "b", "a", "abcd", "ab", "ab", "ab", "cd", "cd", "cd" }这样一个集合应该输入如下结果。
ab-4
cd-3
abcd-2
b-1
a-1
原理是先用一个字典计算每个元素的出现次数,然后把该字典按value的大小排序,下面是实现代码

/**//// <summary>
/// 把一个集合按重复次数排序
/// </summary>

/// <typeparam name="T"></typeparam>
/// <param name="inputList"></param>
/// <returns></returns>

public static Dictionary<T, int> SortByDuplicateCount<T>(IList<T> inputList)
{
    
//用于计算每个元素出现的次数,key是元素,value是出现次数

    Dictionary<T, int> distinctDict = new Dictionary<T, int>();
    
for (int i = 0; i < inputList.Count; i++
)
    
{
        
//这里没用trygetvalue,会计算两次hash

        if (distinctDict.ContainsKey(inputList[i]))
            distinctDict[inputList[i]]++
;
        
else

            distinctDict.Add(inputList[i], 
1);
    }


    Dictionary
<T, int> sortByValueDict = GetSortByValueDict(distinctDict);
    
return
 sortByValueDict;
}



这里用到一个把一个字典按值的大小排序的方法GetSortByValueDict,代码如下,是泛型的

/**//// <summary>
/// 把一个字典俺value的顺序排序
/// </summary>
/// <typeparam name="K"></typeparam>
/// <typeparam name="V"></typeparam>
/// <param name="distinctDict"></param>
/// <returns></returns>

public static Dictionary<K, V> GetSortByValueDict<K,V>(IDictionary<K, V> distinctDict)
{
    
//用于给tempDict.Values排序的临时数组
  V[] tempSortList = new V[distinctDict.Count];
  distinctDict.Values.CopyTo(tempSortList, 0);
  Array.Sort(tempSortList); //给数据排序
  Array.Reverse(tempSortList);//反转

  
//用于保存按value排序的字典
  Dictionary<K, V> sortByValueDict =
      
new Dictionary<K, V>(distinctDict.Count);
  
for (int i = 0; i < tempSortList.Length; i++)
  
{
      
foreach (KeyValuePair<K, V> pair in distinctDict)
      
{
            
//比较两个泛型是否相当要用Equals,不能用==操作符
            if (pair.Value.Equals(tempSortList[i]) && !sortByValueDict.ContainsKey(pair.Key))
              sortByValueDict.Add(pair.Key, pair.Value);
      }

  }

  
return sortByValueDict;
}



对一个文章内出现的多个词进行消重是因为如果一个文章里堆叠关键词会影响本聚类关键词提取的准确性,所以要排重,算法如下,也是泛型的

/**//// <summary>
/// 对一个数组进行排重
/// </summary>
/// <param name="scanKeys"></param>
/// <returns></returns>

public static IEnumerable<T> GetDistinctWords<T>(IEnumerable<T> scanKeys)
{
    T temp = default(T);
    
if (scanKeys.Equals(temp))
        
return new T[0];
    
else
    
{
        Dictionary<T, T> fixKeys = new Dictionary<T, T>();
        
foreach (T key in scanKeys)
        
{
            fixKeys[key] = key;
        }

        T[] result = new T[fixKeys.Count];
        fixKeys.Values.CopyTo(result, 0);
        
return result;
    }

}

最后效果如下
Iteration 0...
Iteration 1...
---------asp,net,-------

a ASP.NET 自定义 控件 复杂 属性 声明 持久性 浅析
a asp.net 控件 开发 显示 控件 内容
a 介绍 一 个 ASP.net MVC 系列 教程
a 在 asp.net 中 实现 观察者 模式 ,或 有 更 好 的 方法 (续)
a Asp.Net 页面 执行 流程 分析
---------股民,印花税,-------

a 股民 要 清楚 自己 的 目的
a 印花税 之 股民 四季
a 某 心理 健康 站 开张 后 首 个 咨询 者 是 位 新 股民
a 输 大钱 的 股民 给 我们 启迪
a 杭州 股民 放 鞭炮 庆祝 印花税 下调
---------奥运,拳击,-------

a 奥运 拳击 入场券 基本 分罄 邹市明 夺冠 对手 浮出 水面
a 运动员 行李 将 “后 上 先 下” 奥运 相关 人员 行李 实名制
a 奥运 票务 网上 成功 订票 后 应 及时 到 银行 代售 网点 付款
a 残疾 女 青年 入围 奥运 游泳 比赛 创 奥运 历史 两 项 第一

可以看到,提取的关键字还是准确的,并没把a当成关键字。

转载于:https://www.cnblogs.com/lindayyh/archive/2009/10/13/1582299.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/411246.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JavaWeb的分页

1.什么是分页 第N页/共M页 首页 上一页 1 2 3 4 5 6 7 8 9 下一页 尾页 [ ] go 分页的优点&#xff1a;只查询一页&#xff0c;不用查询所有页&#xff01; 2.分页数据 页面的数据都是由Servlet传递过来的&#xff01; Servlet&#xff1a; 1.*当前页&#xff1a;pageCod…

中反应器体积_缠绕管式反应器大幅提高能效,移热能力较列管式反应器提升逾50%...

武汉东海石化重型装备有限公司与中科院过程工程研究所联合开展的高效缠绕管式反应器研发课题二期研究日前结题。该研究建立了一套与不同工作原理相适应的缠绕管式反应器设计方法&#xff0c;使缠绕管式反应器的移热能力较列管式固定床反应器提升逾50%&#xff0c;可极大提高企业…

【异常(待解决)】org.apache.http.NoHttpResponseException: api.weixin.qq.com:443 failed to respond...

一、记录下异常堆栈信息 2019-06-01 10:26:58.246 [http-nio-9850-exec-3] ERROR weixin.popular.client.LocalHttpClient - execute error org.apache.http.NoHttpResponseException: api.weixin.qq.com:443 failed to respondat org.apache.http.impl.conn.DefaultHttpRespon…

企业内容管理-互联网应用

企业内容管理-互联网应用 当你第一次听到企业内容管理这个名字&#xff0c;很容易联想到ERP这种复杂无比的系统。实际上也确实如此&#xff0c;目前几大主要的ECM系统都是复杂无比&#xff0c;所以我想从互联网应用&#xff0c;一般网民可以使用的角度来谈谈企业内容管理。 从…

计算机做游戏到大学要学什么,大学学什么专业,毕业才能从事电竞行业?

原标题&#xff1a;大学学什么专业&#xff0c;毕业才能从事电竞行业&#xff1f;电竞可不只是打游戏这么简单。想必最近很多同学已经陆陆续续收到录取通知书了&#xff0c;大学的美好生活已经在等着你们啦&#xff01;今天化学姐想和大家聊聊就业已经游戏行业相关的事儿。电子…

layui中table监听单元格_最全总结 | 聊聊 Python 办公自动化之 PPT(中)

点击上方 “AirPython”&#xff0c;选择 “加为星标”第一时间关注 Python 技术干货&#xff01;1. 前言上一篇文章简单地介绍了 PPT 的文档结构&#xff0c;并使用 python-pptx 这个依赖库完成对 PPT 文档最基本的操作最全总结 | 聊聊 Python 办公自动化之 PPT(上)作为 PPT 系…

东北考生到南方学计算机,为啥东北考生都想去南方,而南方学生很少考东北,看看他们怎么说...

原标题&#xff1a;为啥东北考生都想去南方&#xff0c;而南方学生很少考东北&#xff0c;看看他们怎么说文/晓宁说教育高考对于众多考生来说&#xff0c;是人生中最重要的一场考试&#xff0c;如果能在高考中发挥出好成绩&#xff0c;就可以顺利的考上一所自己理想的大学。按照…

用excel制作双层饼图_双层饼图,让你的工作更出彩

在Excel中饼图是很常见的图表类型&#xff0c;做起来也很简单&#xff0c;相信大家都会做。但双层饼图你会做吗&#xff1f;如下图所示&#xff0c;根据左侧的数据源&#xff0c;做出右侧的双层饼图。这么漂亮的双层饼图是怎么制做出来的呢&#xff1f;今天我就来给大家分享一下…

Comet OJ - 2019 六一欢乐赛

传送门 #A&#xff1a; 思路&#xff1a;等差数列求和,看成俩次12… n,多加的n减去&#xff0c;所以 ans n*(n1) - n。 AC代码&#xff1a; 1 #include<iostream>2 #include<algorithm>3 #include<string>4 using namespace std;5 int main()6 {7 int n…

三个子系统_「正点原子Linux连载」第五十八章Linux INPUT子系统实验(一)

1)实验平台&#xff1a;正点原子Linux开发板2)摘自《正点原子I.MX6U嵌入式Linux驱动开发指南》关注官方微信号公众号&#xff0c;获取更多资料&#xff1a;正点原子第五十八章Linux INPUT子系统实按键、鼠标、键盘、触摸屏等都属于输入(input)设备&#xff0c;Linux内核为此专门…

【翻译】eXpressAppFramework QuickStart 业务模型设计(十)——在代码中实现数据验证...

这一讲&#xff0c;你将学到如何给业务对象和他们的属性设置规则。最终用户在执行赋值操作后将验证这些规则。你可以实现必填规则使得Position.Title属性不能为空。此规则将在Position对象保存的时候被验证。你还能够看到打破规则的界面提示。在此之前&#xff0c;我建议你去读…

注册机patch起什么作用_电机滑环起什么作用?

电机滑环起什么作用?发电机滑环就是我们传统的集电环&#xff0c;用于电机的换向器上作为导出导入电流的滑动接触体&#xff0c;它的导电、导热以及润滑性能良好&#xff0c;并具有一定的机械强度和换向性火花的本能。几乎所有的电机都使用碳刷&#xff0c;它是电机的重要组成…

《Java并发编程的艺术》之synchronized的底层实现原理

在学习锁优化时&#xff0c;对象头(Mark Word) 是必不可缺的一环&#xff0c;因为synchronized 用的锁是存在对象头里的。32位的虚拟机上对象头占64位&#xff08;8字节&#xff09;&#xff0c;64位的虚拟机上对象头占128位(16字节&#xff09;[^objectHead]&#xff1b;而不同…

文字投影_店铺门口投影灯,引领店铺新潮流

在社会的进步下&#xff0c;现在人们物质生活越来越好&#xff0c;在原来消费的基础上也更加注重消费时店铺的装修、氛围。装修精致、环境优雅的店铺不仅更加容易吸引顾客&#xff0c;并且更加容易让顾客打卡发圈&#xff0c;无形中也帮自己做了一波宣传。上次我们出去游玩的时…

实验5

一、 1 #ifndef MACHINEPETS_H2 #define MACHINEPETS_H3 #include<iostream>4 #include<string>5 using namespace std;6 class MachinePets7 {8 public:9 MachinePets(const string s) :nickname(s) {} 10 virtual string talk()0; 11 string getnick…

计算机网络ieee,博士生程珂论文连续两年被计算机网络顶级会议IEEE INFOCOM录用...

近日&#xff0c;第39届IEEE国际计算机通信会议(IEEE International Conference on Computer Communications, IEEE INFOCOM 2020)录用结果揭晓&#xff0c;陕西省网络与系统安全重点实验室沈玉龙教授课题组博士生程珂的论文《A Lightweight Auction Framework for Spectrum Al…

去除标题_资深运营导师-云中教你轻松写标题

一、标题作用解读标题对于产品的意义买家购买逻辑想到一款产品&#xff0c;并知道他的名称去网上搜索&#xff0c;看到图片等信息类比价格评价等内容&#xff0c;下单收到货和自己根据标题照片评判商品核心要点&#xff1a;买家是根据产品名字作为购买切入点&#xff1b;照片和…

报名学校计算机考试在哪里报,全国计算机等级考试报名流程

全国计算机等级考试报名流程全国计算机等级考试采用全国统一命题&#xff0c;统一考试的形式&#xff0c;各科目均为上机操作考试。1&#xff0e;上网填报基本信息考生可任意选择地点并在规定时间内上网填报、修改及查询本人信息。填报过程分为登录、查看提示信息、输入并提交报…

卸载一直在创建还原点_如何创建系统还原点以及如何恢复?

如何创建系统还原点1、在搜索框中输入“创建还原点”并打开。2、在“系统保护”选项卡中点击“创建”。3、为此次还原点添加备注描述&#xff0c;此处命名为测试&#xff0c;点击创建即可。恢复系统至上一个还原点1、在刚才的“系统保护”界面中点击“系统还原”。2、在弹出的系…

学生党的Surface Pro 5乞丐版使用体验

因为已经装了台式机&#xff0c;大一开学时买的厚重且续航差的华硕游戏本&#xff08;i5GTX950M8G)对我这个考研党已经显得不合适了。恰巧有一同学笔记本坏了&#xff0c;我便将游戏本低价出了&#xff0c;然后用两三倍的价格&#xff0c;入手了surface pro5 (new surface)的最…