软件工程应用与实践——词云的获取
Posted 叶卡捷琳堡
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了软件工程应用与实践——词云的获取相关的知识,希望对你有一定的参考价值。
2021SC@SDUSC
文章目录
一、简介
经过小组分工和讨论后,决定由我负责分析词云的获取和整理的部分。在老年健康知识图谱系统中,词云图表示了知识图谱中出现的专业名词及其出现频率。
二、word文档分词
2.1 java引入jieba分词
引入依赖
本项目使用jieba分词对word文档中的文本实现分词,jieba-analysis库用于实现在java语言中进行jieba分词
<dependency>
<groupId>com.huaban</groupId>
<artifactId>jieba-analysis</artifactId>
<version>1.0.2</version>
</dependency>
在引入jieba分词后,利用hutool工具中的TokenizerEngine完成中文分词,以下是一个小例子
//分词测试
@Test
public void testJieba()
TokenizerEngine engine = TokenizerUtil.createEngine();
String text = "这是一句话";
Result result = engine.parse(text);
String resultStr = CollUtil.join((Iterator<Word>)result, " ");
//这是 一句 话
System.out.println(resultStr);
TokenizerEngine会根据用户引入的依赖自动判断使用哪个分词引擎,查阅hutool官网可知,目前hutool支持的分词有以下几种
2.2 读取word文档完成分词
上面的小例子是对一个简单的字符串进行中文分词,在本项目中需要对word文档进行分词,因此需要首先读取word文档,再对word文档进行分词
FileReader fileReader = new FileReader("filePath");
List<String> list = fileReader.readLines();
List<String> finalResult = new ArrayList<>();
list.forEach(l->
TokenizerEngine engine = TokenizerUtil.createEngine();
String text = l;
Result result = engine.parse(text);
String resultStr = CollUtil.join((Iterator<Word>)result, " ");
finalResult.add(resultStr)
)
三、词云的获取
在对word文档进行分词分词之后,由于word文档中有很多与医学无关的停用词,这一部分词不能显示到首页上,需要进行筛选,删除停用词后展示到首页。在本项目中,首先从文件中获取停用词,再对获取到的词语进行筛选。
3.1 获取所有词
本项目通过dao层访问数据库,服务层调用dao层接口,controller层调用服务层。mybatis完成dao层接口与sql语句的映射
保存词云的实体类
- 使用lombok的@Data注解,当编译时自动为实体类添加get,set,equals,hashcode,toString方法
- 使用lombok的@AllArgsConstructor注解,为类自动添加带参的构造方法
- 使用lombok的@NoArgsConstructor注解,为类自动添加无参的构造方法
- 使用lombok的@Accessors注解,可以实现链式调用
package com.sdu.nurse.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class WordCloudData
//词云名称
private String name;
//词云数据
private Integer value;
延伸说明:链式调用的进一步解释
当我们平时使用实体类,为实体类赋值时,需要反复调用set方法。假设我们有一个User类,里面有name,age,id三个属性,我们需要分别调用三次set方法
User user = new User();
user.setName("name");
user.setAge(20);
user.setId("id");
由于普通set方法的返回值是void,因此无法实现链式调用。在lombok中,使用@Accessors(chain = true)注解可以使set方法返回本对象,因此使用链式调用可以简化操作,不需要重复写多个set语句,仅需在一个语句中重复调用set方法即可
User user = new User();
user.setName("name").setAge(20).setId("id");
dao层接口
dao接口中的getWordCloudData()方法完成词云图的获取
package com.sdu.nurse.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.sdu.nurse.entity.WordCloudData;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface WordCloudDataDao extends BaseMapper<WordCloudData>
List<WordCloudData> getWordCloudData();
mysql中的正则匹配
在使用sql语句从数据库中获取词云的过程中,需要排除非中文字符,本项目中使用mysql中的
REGEXP '[\\u4e00-\\u9fa5]'
函数用于匹配中文字符
3.2 去除停用词
在本项目中,在service层去除停用词,停用词保存在一个文件中,通过hutool的FileReader类按行获取停用词(readLines方法),并保存在List中。之后再对获取的所有词进行筛选,去除停用词即可。本项目利用了list集合中的contains方法判断集合中是否已经存在字符串
service层对应的代码
public List<WordCloudData> getWordCloudData()
//获取停用词列表到List中
FileReader fileReader = new FileReader("../../src/main/resources/static/info/停用词.txt");
List<String> list = fileReader.readLines();
//去除List集合中的无用词
List<WordCloudData> words = wordCloudDataDao.getWordCloudData();
List<WordCloudData> results = new ArrayList<>();
int length = words.size();
for(int i = 0;i < length;i++)
if(!list.contains(words.get(i).getName()))
results.add(words.get(i));
return results;
关于hutool工具中封装的FileReader源码分析
hutool工具对java中一些繁琐的操作(比如日期转换,类型转换,文件读取等)进行了一些封装。由于本课程源码分析,因此我希望在阅读基本的项目代码的基础上,还能进一步了解java工具当中的部分源码。在上面的例子中,我使用了FileReader类,通过传入路径获取FileReader类对象,我们来看一下FileReader底层是怎么实现的
首先找到对应的构造方法,发现这个方法调用了另一个该类中的构造方法
public FileReader(String filePath)
this(filePath, DEFAULT_CHARSET);
这里的DEFAULT_CHARSET在源码中也有体现。首先FileReader继承FileWrapper,而在FileWrapper类中的static代码块中,声明了DEFAULT_CHARSET为UTF-8
static
DEFAULT_CHARSET = StandardCharsets.UTF_8;
发现调用该构造方法后,这个构造方法又调用了一个新的构造方法
public FileReader(String filePath, Charset charset)
this(FileUtil.file(filePath), charset);
下面这个构造方法被调用
public FileReader(File file, Charset charset)
super(file, charset);
this.checkFile();
而FileUtil.file(filePath)方法在底层实际上调用了java中的File类,并且使用三元运算符判断用户传入的路径是否为空
public static File file(String path)
return null == path ? null : new File(getAbsolutePath(path));
checkFile方法用于判断文件是否存在,如果不存在则会抛出异常
private void checkFile() throws IORuntimeException
if (!this.file.exists())
throw new IORuntimeException("File not exist: " + this.file);
else if (!this.file.isFile())
throw new IORuntimeException("Not a file:" + this.file);
通过以上分析,可以知道,FileReader对象实际上是一个java中File对象的增强版。
四、总结
本博客重点介绍了如何对word文档进行分词,并去除停用词的过程,顺便拓展了lombok注解和hutool文件工具类的底层源码。总的来说,通过这一部分的分析,我和队友进一步了解了项目的构建过程,为下一步的代码阅读打下了基础。
以上是关于软件工程应用与实践——词云的获取的主要内容,如果未能解决你的问题,请参考以下文章