IKAnalyzer配合echarts-wordcloud实现高频词统计,以及词云展示

794 阅读4分钟

image.png

    先来看看这个图,这个是由echarts-wordcloud生成的一个词云图,其中包含的是一些数据中出现的高频词汇。这样的词云图能直观的展示一段时间内的高频热词,能在一定程度上起到一个分析数据的作用。

    想要实现这个功能,一共分为三步。第一,中文分词,实现大段文字解析词语。第二,高频词统计,统计词语出现次数,并且排序,取其中排名靠前是词语。第三,生成词云,界面展示。

一、中文分词

使用IKAnalyzer实现中文分词

1、引入pom依赖

<!-- https://mvnrepository.com/artifact/com.jianggujin/IKAnalyzer-lucene -->
       <dependency>
           <groupId>com.jianggujin</groupId>
           <artifactId>IKAnalyzer-lucene</artifactId>
           <version>8.0.0</version>
       </dependency>

2、引入配置文件到resource目录

image.png

IKAnalyzer.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">  
<properties>  
   <comment>IK Analyzer 扩展配置</comment>
   <!--用户可以在这里配置自己的扩展字典 -->
   <entry key="ext_dict">ext.dic;</entry> 
   <!--用户可以在这里配置自己的扩展停止词字典-->
   <entry key="ext_stopwords">stopword.dic;</entry>
</properties>



image.png

3、创建分词对象

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotEmpty;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Accessors(chain = true)
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = false)
@ApiModel(value = "IkAnalyzerResult", description = "Ik分词结果")
public class IkAnalyzerResult {



/**
 * 分词内容
 */
@ApiModelProperty(value = &quot;分词内容&quot;)
private String term;

/**
 * 分词类型 CN_CHAR 中文字符  CN_WORD 中文单词 ARABIC 阿拉伯数字 ENGLISH 英文
 */
@ApiModelProperty(value = &quot;分词类型 CN_CHAR 中文字符  CN_WORD 中文单词 ARABIC 阿拉伯数字 ENGLISH 英文&quot;)
private String type;

/**
 * 分词起始下标
 */
@ApiModelProperty(value = &quot;分词起始下标&quot;)
private Integer startOffset;

/**
 * 分词结束下标
 */
@ApiModelProperty(value = &quot;分词结束下标&quot;)
private Integer endOffset;


}

4、实现分词功能

/**
 *
 * @param analysisText 分析文本
 * @param useSmart 是否开启智能分词
 * @param typeList 显示分词类型 如不设置则不进行过滤 CN_CHAR 中文字符  CN_WORD 中文单词 ARABIC 阿拉伯数字 ENGLISH 英文
 * @return List<IkAnalyzerResult>
 * @throws IOException
 */
public static List<IkAnalyzerResult> IkAnalyzerText(String analysisText,boolean useSmart,List<String> typeList) throws IOException {
    // 返回结果
    List<IkAnalyzerResult> resultList=new ArrayList<IkAnalyzerResult>();
    //创建一个标准分析器对象   是否开启智能分词
    Analyzer analyzer=new IKAnalyzer(useSmart);
    //获取tokenStream对象
    //参数1域名 2要分析的文本内容
    TokenStream tokenStream=analyzer.tokenStream("",analysisText);
    //添加引用,用于获取每个关键词
    CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class);
    //获取当前分词的类型
    TypeAttribute typeAttribute = tokenStream.addAttribute(TypeAttribute.class);
    //添加一个偏移量的引用,记录了关键词的开始位置以及结束位置
    OffsetAttribute offsetAttribute = tokenStream.addAttribute(OffsetAttribute.class);
    //将指针调整到列表的头部
    tokenStream.reset();
    //遍历关键词列表,incrementToken判断是否结束
    while (tokenStream.incrementToken()) {
        // 分词类型
        String type =String.valueOf(typeAttribute.type());
        // 类型集合不为空 则按类型
        if(CollectionUtil.isNotEmpty(typeList)){
            // 包含的类型,才加入结果中
            if(typeList.contains(type)){
                // 创建分词对象
                IkAnalyzerResult ikAnalyzerResult=new IkAnalyzerResult();
                // 设置分词内容
                ikAnalyzerResult.setTerm(String.valueOf(charTermAttribute));
                // 设置分词类型
                ikAnalyzerResult.setType(type);
                // 设置分词起始下标
                ikAnalyzerResult.setStartOffset(offsetAttribute.startOffset());
                // 设置分词结束下标
                ikAnalyzerResult.setStartOffset(offsetAttribute.endOffset());
                // 添加到集合中
                resultList.add(ikAnalyzerResult);
            }
        // 集合类型为空 则全部添加到返回结果中
        }else{
            // 创建分词对象
            IkAnalyzerResult ikAnalyzerResult=new IkAnalyzerResult();
            // 设置分词内容
            ikAnalyzerResult.setTerm(String.valueOf(charTermAttribute));
            // 设置分词类型
            ikAnalyzerResult.setType(type);
            // 设置分词起始下标
            ikAnalyzerResult.setStartOffset(offsetAttribute.startOffset());
            // 设置分词结束下标
            ikAnalyzerResult.setStartOffset(offsetAttribute.endOffset());
            // 添加到集合中
            resultList.add(ikAnalyzerResult);
        }
    }
    tokenStream.close();
    return resultList;
}


二、高频词统计

/**
 * 高频词统计和排序
 * @param ikAnalyzerResultList 分词结果集合
 * @param sortFlag 排序方式 asc 正序 desc 倒序
 * @param statisticsCount 统计数量(如果最终数量大于统计数量则以统计数量为准)
 * @return String元素 包括分词内容+"|"+出现频率
 */
public static List<String> HighWordFrequencyStatisticsAndSort(List<IkAnalyzerResult> ikAnalyzerResultList,String sortFlag,Integer statisticsCount){
    // 返回结果
    List<String> resultList=new ArrayList<String>();
    // 分词频率统计map
    Map<String,Integer> wordFrequencyMap=new HashMap<String,Integer>();
    // 判断传入分词结果集合不为空
    if(CollectionUtil.isNotEmpty(ikAnalyzerResultList)){
        // 遍历分词结果
        ikAnalyzerResultList.stream().forEach(ikAnalyzerResult -> {
            // map包含该分词
            if(wordFrequencyMap.containsKey(ikAnalyzerResult.getTerm())){
                // 分词频率+1
                wordFrequencyMap.put(ikAnalyzerResult.getTerm(),wordFrequencyMap.get(ikAnalyzerResult.getTerm())+1);
            }else{
                // 分词频率设置为1
                wordFrequencyMap.put(ikAnalyzerResult.getTerm(),1);
            }
        });
        // 遍历
        for(Map.Entry<String, Integer> entry:wordFrequencyMap.entrySet()){
            // 添加到集合中
            resultList.add(entry.getKey()+"|"+entry.getValue());
        }
        // 排序
        resultList= resultList.stream().sorted(((o1, o2) -> {
            Integer count1=Integer.parseInt(o1.substring(o1.lastIndexOf("|")+1));
            Integer count2=Integer.parseInt(o2.substring(o2.lastIndexOf("|")+1));
            // 正序
            if("asc".equals(sortFlag)){
                return count1 - count2;
            // 倒序
            }else {
                return count2 - count1;
            }
        })).collect(Collectors.toList());
    }

// 如果结果数量大于统计数量,则截取统计数量的数据
if(resultList.size()&gt;statisticsCount){
    resultList=resultList.subList(0,statisticsCount);
}
return resultList;




}


三、生成词云

1、词云数据接口调用

// 词云list
List<Map<String,Object>> chartsWordCloudEvalKeyList=new ArrayList<Map<String,Object>>();
// 设置过滤词类型
List<String> typeList=new ArrayList<String>();
typeList.add("CN_WORD");
// 文本分词
List<IkAnalyzerResult>  ikAnalyzerResultList= IkAnalyzerUtil.IkAnalyzerText(analysisContent.toString(),true,typeList);
// 高频词统计
List<String> result=IkAnalyzerUtil.HighWordFrequencyStatisticsAndSort(ikAnalyzerResultList,"desc",100);
// 判断不为空
if(CollectionUtil.isNotEmpty(result)){
    // 遍历结果集
    result.stream().forEach(s -> {
        // 获取名称
        String name=s.substring(0,s.lastIndexOf("|"));
        // 获取词频
        String value=s.substring(s.lastIndexOf("|")+1);
        // 创建map对象
        Map<String,Object> chartsMap=new HashMap<String,Object>();
        // 设置值
        chartsMap.put("name",name);
        chartsMap.put("value",value);
        // 添加到集合中
        chartsWordCloudEvalKeyList.add(chartsMap);
    });
}

2、echarts-wordcloud实现词云(vue版本)

<template>
  <div :class="className" :style="{height:height,width:width}" />
</template>

<script>
import echarts from 'echarts'
require('echarts/theme/macarons')
require('echarts-wordcloud')
import resize from '@/views/mobile-nurse/rule/data-analysis/mixins/resize.js'
import chartNoData from '@/assets/index/chartNoData.png'
export default {
  mixins: [resize],
  props: {
    echartsData: {
      type: Array,
      default: function() {
        return []
      }
    },
    className: {
      type: String,
      default: 'chart'
    },
    width: {
      type: String,
      default: '100%'
    },
    height: {
      type: String,
      default: '250px'
    }
  },
  data() {
    return {
      chart: null,
      echartsDataObj: {},
      echartsDataOptions: {},
      imageData: 'data:image/png;base64,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'
    }
  },
  watch: {
    echartsData: {
      handler(val) {
        this.echartsDataObj = val
        this.initChart()
      },
      immediate: true
    }
  },
  beforeDestroy() {
    if (!this.chart) {
      return
    }
    this.chart.dispose()
    this.chart = null
  },
  methods: {
    initChart(data) {
      data = this.echartsDataObj
      this.echartsDataOptions = {}
      this.echartsDataOptions.title = {
        text: '关键字词云',
        x: 'center'
      }
      if (!data.length) {
        this.echartsDataOptions.title = {
          text: ['{a|}', '{b|暂无数据}'].join('\n'),
          x: 'center',
          y: 'center'
        }
        this.echartsDataOptions.title.textStyle = {
          rich: {
            a: {
              backgroundColor: {
                image: chartNoData
              },
              height: 40
            },
            b: {
              color: '#C2C7CF'
            }
          }
        }
      }
      const maskImage = new Image()
      maskImage.src = this.imageData
      const _that = this
      maskImage.onload = function() {
        _that.echartsDataOptions.tooltip = {}
        _that.echartsDataOptions.legend = {}
        _that.echartsDataOptions.series = [{
          type: 'wordCloud',
          gridSize: 1,
          sizeRange: [12, 55],
          rotationRange: [-45, 0, 45, 90],
          maskImage: maskImage,
          textStyle: {
            normal: {
              color: function() {
                return 'rgb(' +
            Math.round(Math.random() * 255) +
            ', ' + Math.round(Math.random() * 255) +
            ', ' + Math.round(Math.random() * 255) + ')'
              }
            }
          },
          left: 'center',
          top: 'center',
          right: null,
          bottom: null,
          data: data
        }]

        _that.chart = echarts.init(_that.$el, 'macarons')
        _that.chart.clear()
        _that.chart.setOption(_that.echartsDataOptions)
        _that.chart.resize()
      }
    }
  }
}
</script>


注意事项:

echarts初始化方法需要在onload方法中,否则会出现词云加载不出来的问题。

image.png