文本挖掘之文本聚类(借力打力)

刘勇    Email:lyssym@sina.com

简介

  在文本相似度判定中,作者将该算法用于文本聚类中,其核心思想通过比较两个文本向量中元素的相似度,即向量中所含的元素相似个数越多,则两个向量越相似,继而上述文本越相似。作者在短文本相似判定中采用了余弦相似度该算法来实现,本文借鉴数学集合取交集,借用现有组件来实现上述算法功能,继而减少工作量,也具备便捷性,也能取得较好的效果。

数学集合

  该方法的思想为:先将文本数据采用中文切分,将其切分为词汇(词组、短语、词汇的统称,本文不做细粒度划分),并以某种特征表示进行量化(本文按词频量化),通过取文本向量的交集,若交集的重复率为70%,则判定两篇文本相似。通过将相似文本聚合成链表存储,进而能实现文本聚类。

  以下内容则以python中具体实现来阐述。

1 def match_topic(self, keywords, topics):
2         keywords = set(keywords)
3         keywords_count = len(keywords)
4         for topic in topics:
5             intersection = keywords.intersection(topic['keywords'])
6             if len(intersection) > keywords_count * 0.7 or len(intersection) > len(topic['keywords']) * 0.7:
7                 yield topic

  备注:keywords 制定匹配话题关键字列表,tipics为待匹配文本数据,每条数据为一个JSON对象,其中包含Web文本数据的标题、内容、发布时间等信息。其中涉及到长句与短句的关系,因此文本采用“或”操作来确定匹配话题,实现话题聚类。

Elasticsearch

  Elasticsearch是全文检索服务器,采用倒排索引对词汇建立索引,因此在文本检索方面具有较大的效率优势。本文将该工具以类似数学集合的方式来组织,继而实现文本聚类。

  以下内容则以Java中具体实现来阐述。

 1 import org.elasticsearch.action.index.IndexRequestBuilder;
 2 import org.elasticsearch.action.index.IndexResponse;
 3 import org.elasticsearch.action.search.SearchResponse;
 4 import org.elasticsearch.client.Client;
 5 import org.elasticsearch.client.transport.TransportClient;
 6 import org.elasticsearch.common.transport.InetSocketTransportAddress;
 7 import org.elasticsearch.index.query.QueryBuilder;
 8 import org.elasticsearch.index.query.QueryBuilders;
 9 import org.elasticsearch.search.SearchHit;
10 import org.elasticsearch.search.SearchHits;
11 
12 import java.util.List;
13 import org.elasticsearch.node.NodeBuilder.*;
14 
15 public class SearchHandler {
16     private Client client;
17     
18     public SearchHandler(String ipAddress) 
19     {
20         client = new TransportClient().addTransportAddress(new InetSocketTransportAddress(ipAddress, 9300));
21     }
22     
23     
24     public void createIndexResponse(String indexName, String type, List<String> data) 
25     {
26         IndexRequestBuilder requestBuilder = client.prepareIndex(indexName, type).setRefresh(true);
27         int len = data.size();
28         for (int i = 0; i < len; i++) 
29             requestBuilder.setSource(data.get(i)).execute().actionGet();
30             
31     }
32     
33     
34     public IndexResponse createIndexResponse(String indexName, String type, String data)
35     {
36         IndexResponse response = client.prepareIndex(indexName, type).setSource(data).execute().actionGet();
37         return response;
38     }
39 
40     
41     public void searchResponse(QueryBuilder queryBuilder, String indexName, String type) 
42     {
43         SearchResponse searchResponse = client.prepareSearch(indexName).setTypes(type)
44                 .setQuery(queryBuilder)
45                 .setMinScore((float)3)
46                 .setSize(10)
47                 .execute()
48                 .actionGet();
49         SearchHits hits = searchResponse.getHits();
50         System.out.println("查询到记录数=" + hits.getTotalHits());
51         SearchHit[] searchHits = hits.getHits();
52         for (SearchHit hit : searchHits) {
53             String keywords = (String)hit.getSource().get("title");
54             System.out.println(keywords);
55         }
56     }    
57 }
 1 import org.elasticsearch.index.query.QueryBuilder;
 2 import org.elasticsearch.index.query.QueryBuilders;
 3 
 4 public class Test {
 5 
 6     public static void main(String[] args) {
 7         SearchHandler sh = new SearchHandler("192.168.101.243");
 8         String indexName = "title";
 9         String type = "test";
10                 
11         QueryBuilder qb = QueryBuilders.matchQuery(indexName, "主持政治局常委会").minimumShouldMatch("70%").boost((float)0.2);
12         long start = System.currentTimeMillis();
13         sh.searchResponse(qb, indexName, type);
14         long end = System.currentTimeMillis();
15         
16         System.out.println("查询所需时间为: " + (end -start) + " ms");
17     }
18 }

  针对匹配存在长句与短句特例,详细内容见文本相似度判定中具体描述,其解决方案为采用两次检索实现,以下内容根据项目中实际经验设定的数值,读者可根据应用场景具体设置:

  1)若匹配文本为长句,见matchQuery,则设定minimumShouldMatch("70%"),该部分与集合取交集等同,然后设置setMinScore((float)3),即将Elasticsearch检索的评分稍微设置高一点;

  2)若待匹配文本为短句,则设定minimumShouldMatch("90%"),该部分与集合取交集等同,然后设置setMinScore((float)0.7),即将Elasticsearch检索的评分稍微设置低一点。

总结

  本文介绍了两种借助现有组件实现文本聚类的方法,上述方法具有便捷性,经过实际大量Web文本数据测试,上述方法均实用、可行。本文作者推荐采用Elasticsearch实现的方法,由于对文本处理应用经常会使用文本检索服务,因此引入Elasticsearch,可以为后续应用扩展提供便利。后续本文作者将从机器学习角度介绍文本聚类算法。

 

 


  作者:志青云集
  出处:http://www.cnblogs.com/lyssym
  如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的【推荐】。
  如果,您希望更容易地发现我的新博客,不妨点击一下左下角的【关注我】。
  如果,您对我的博客所讲述的内容有兴趣,请继续关注我的后续博客,我是【志青云集】。
  本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。


 

posted on 2015-10-25 11:03  志青云集  阅读(2853)  评论(0编辑  收藏  举报

导航