
在自然语言处理(NLP)领域,文本预处理是至关重要的一步,其中移除停用词(Stop Words)是常见的操作。停用词通常指那些在文本中频繁出现但对文本语义贡献不大的词汇,例如“的”、“是”、“在”等。移除这些词汇有助于降低数据维度,提高后续文本分析(如词频统计、文本分类)的效率和准确性。本教程将详细介绍如何利用Java实现这一过程,并在此基础上进行词频统计。
我们将分步实现:首先读取主文本文件和停用词文件,然后从主文本中移除停用词,最后统计剩余词汇的频率。
首先,我们需要将 hello.txt(主文本)和 stopwords.txt(停用词列表)的内容读取到内存中。Files.readString() 方法是读取小型到中型文件内容的理想选择。
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class TextProcessor {
public static void main(String[] args) {
try {
// 读取主文本文件内容
String mainTextContent = Files.readString(Paths.get("hello.txt"), Charset.defaultCharset());
// 读取停用词文件内容
String stopWordsContent = Files.readString(Paths.get("stopwords.txt"), Charset.defaultCharset());
System.out.println("原始文本内容:
" + mainTextContent);
System.out.println("停用词内容:
" + stopWordsContent);
// ... 后续处理
} catch (IOException e) {
System.err.println("文件读取错误: " + e.getMessage());
e.printStackTrace();
}
}
}示例文件内容:
立即学习“Java免费学习笔记(深入)”;
读取停用词后,我们需要将它们从主文本内容中移除。这里我们将停用词文件内容按空白字符分割成单独的词汇,然后遍历这些词汇,使用 String.replaceAll() 方法将它们从主文本中替换掉。为了确保只替换完整的单词,而不是单词的一部分,我们将结合正则表达式的单词边界 。
// ... (接上一步代码)
String[] stopWordsArray = stopWordsContent.split("\s+"); // 使用 \s+ 匹配一个或多个空白字符
String cleanedText = mainTextContent;
for (String stopWord : stopWordsArray) {
// 构建正则表达式,使用 确保匹配整个单词
// 例如,如果 stopWord 是 "remove",则匹配 "remove"
// 忽略大小写,并处理可能的标点符号
cleanedText = cleanedText.replaceAll("(?i)\b" + stopWord + "\b", "");
}
// 清理多余的空白字符,将多个空格替换为单个空格,并去除首尾空格
cleanedText = cleanedText.replaceAll("\s+", " ").trim();
System.out.println("
清洗后的文本内容:
" + cleanedText);
// ...注意事项:
清洗后的文本现在只包含有意义的词汇。接下来,我们将统计这些词汇的出现频率,并按频率降序排列,以找出最常出现的词。
// ... (接上一步代码)
// 将清洗后的文本分割成单词
// 使用正则表达式匹配非字母数字字符作为分隔符,并转换为小写
String[] words = cleanedText.toLowerCase().split("[^a-zA-Z0-9]+");
// 使用 HashMap 存储词频
Map<String, Long> wordFrequencies = Arrays.stream(words)
.filter(word -> !word.isEmpty()) // 过滤空字符串
.collect(Collectors.groupingBy(
String::valueOf, // 词汇本身作为键
Collectors.counting() // 统计出现次数
));
// 将词频Map转换为List,以便排序
// 使用LinkedHashMap保持插入顺序(在排序后重新构建时有用)
Map<String, Long> sortedWordFrequencies = wordFrequencies.entrySet()
.stream()
.sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())) // 按值降序排序
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(oldValue, newValue) -> oldValue, // 合并函数,这里不应该发生键冲突
LinkedHashMap::new // 保持排序顺序
));
System.out.println("
词频统计 (降序):");
sortedWordFrequencies.forEach((word, count) -> System.out.println(word + ": " + count));
// 如果需要显示Top N词汇
int topN = 3; // 例如,显示前3个
System.out.println("
Top " + topN + " 词汇:");
sortedWordFrequencies.entrySet()
.stream()
.limit(topN)
.forEach(entry -> System.out.println(entry.getKey() + ": " + entry.getValue()));
// ...解释:
如果需要将清洗后的文本或词频统计结果保存到文件中,可以使用 Files.write() 方法。
// ... (接上一步代码)
// 将清洗后的文本写入新文件
// Files.write(Paths.get("cleaned_hello.txt"), cleanedText.getBytes(Charset.defaultCharset()));
// System.out.println("
清洗后的文本已保存到 cleaned_hello.txt");
// 将词频统计结果写入文件
// StringBuilder freqOutput = new StringBuilder();
// sortedWordFrequencies.forEach((word, count) -> freqOutput.append(word).append(": ").append(count).append("
"));
// Files.write(Paths.get("word_frequencies.txt"), freqOutput.toString().getBytes(Charset.defaultCharset()));
// System.out.println("词频统计结果已保存到 word_frequencies.txt");
// ...import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class TextProcessor {
public static void main(String[] args) {
try {
// 1. 读取文件内容
String mainTextContent = Files.readString(Paths.get("hello.txt"), Charset.defaultCharset());
String stopWordsContent = Files.readString(Paths.get("stopwords.txt"), Charset.defaultCharset());
System.out.println("--- 原始数据 ---");
System.out.println("原始文本内容:
" + mainTextContent);
System.out.println("停用词内容:
" + stopWordsContent);
// 2. 移除停用词
String[] stopWordsArray = stopWordsContent.split("\s+");
String cleanedText = mainTextContent;
for (String stopWord : stopWordsArray) {
// 使用 确保匹配整个单词,(?i) 忽略大小写
cleanedText = cleanedText.replaceAll("(?i)\b" + stopWord + "\b", "");
}
// 清理多余的空白字符
cleanedText = cleanedText.replaceAll("\s+", " ").trim();
System.out.println("
--- 文本清洗结果 ---");
System.out.println("清洗后的文本内容:
" + cleanedText);
// 3. 词频统计与排序
// 将清洗后的文本分割成单词,转换为小写,并过滤空字符串
String[] words = cleanedText.toLowerCase().split("[^a-zA-Z0-9]+");
Map<String, Long> wordFrequencies = Arrays.stream(words)
.filter(word -> !word.isEmpty())
.collect(Collectors.groupingBy(
String::valueOf,
Collectors.counting()
));
// 按词频降序排序
Map<String, Long> sortedWordFrequencies = wordFrequencies.entrySet()
.stream()
.sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
.collect(Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(oldValue, newValue) -> oldValue,
LinkedHashMap::new
));
System.out.println("
--- 词频统计 (降序) ---");
sortedWordFrequencies.forEach((word, count) -> System.out.println(word + ": " + count));
// 4. 显示Top N词汇 (例如 Top 3)
int topN = 3;
System.out.println("
--- Top " + topN + " 词汇 ---");
sortedWordFrequencies.entrySet()
.stream()
.limit(topN)
.forEach(entry -> System.out.println(entry.getKey() + ": " + entry.getValue()));
// 可选:将清洗后的文本写入文件
// Files.write(Paths.get("cleaned_hello.txt"), cleanedText.getBytes(Charset.defaultCharset()));
// System.out.println("
清洗后的文本已保存到 cleaned_hello.txt");
} catch (IOException e) {
System.err.println("文件操作错误: " + e.getMessage());
e.printStackTrace();
}
}
}运行上述代码,如果 hello.txt 和 stopwords.txt 存在于项目根目录,将得到类似以下输出:
--- 原始数据 --- 原始文本内容: remove leave remove leave remove leave re move remov e leave remove hello remove world! 停用词内容: remove world --- 文本清洗结果 --- 清洗后的文本内容: leave leave leave re move remov e leave hello ! --- 词频统计 (降序) --- leave: 4 re: 1 move: 1 remov: 1 e: 1 hello: 1 --- Top 3 词汇 --- leave: 4 re: 1 move: 1
通过本教程,我们学习了如何利用Java NIO.2、字符串处理和Stream API来高效地实现文本文件的停用词移除和词频统计。这个过程是许多文本分析任务的基础,掌握这些技术将有助于更好地处理和理解文本数据。在实际应用中,根据具体需求,可以进一步优化和扩展这些功能,例如支持不同语言的停用词、更复杂的文本清洗规则等。
以上就是Java文本处理:高效移除停用词与词频统计的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号