本文作者:合肥工业大学 电子商务研究所 钱洋 email:[email protected] 。
内容可能有不到之处,欢迎交流。
未经本人允许禁止转载。
在主题模型中,常见的评估指标包括Perplexity(即困惑度)以及Coherence Score、Topic Consensus等。而在计算Coherence Score有几种方案:
其一是基于点互信息的,如下所示:
使用这种方式,需要第三方数据来评估,如这里提及的Wikipedia。
其二是,基于Mimno et al.提出的一种指标,这种指标被实验证明与人工评估的结果相一致。其计算如下:
使用这种指标计算是不需要依赖于外部数据集,只需要原始语料就行。
对于做管理学或其他问题的研究者来说,往往寻找合适的外部评估数据较难,因此第二种指标是一种不错的方案。
以下为一种Coherence Score计算的原始论文。
Mimno D, Wallach H, Talley E, et al. Optimizing semantic coherence in topic models[C]//Proceedings of the 2011 Conference on Empirical Methods in Natural Language Processing. 2011: 262-272.
计算公式如下:
在原始论文中,作者给了一个直观的案例,来说明话题中有哪些词汇的学习效果较差,如下图所示:
为此,我们在使用主题模型开展具体问题研究时,也给采用Coherence Score和这种共现矩阵联合展示的方式,来说明某一话题学习的好坏。
实际上,构建这种矩阵非常的简单。这里,我通过一个具体的案例,以方便不怎么会写代码的人参考。我使用的代码为JAVA。
给定原始文档"coherenceCount/test.txt"以及某一主题的top N个词汇(“coherenceCount/example1”)。原始文档如下:
111 2115 163 3126 2615
2115 163 111
163 3126
3126 2615
2615 3126 2615
Top 5个词汇如下:
111
2115
163
3126
2615
存储目录如下:
下面,为一个简单的JAVA代码可实现该操作:
package countNumberCoherence;
import java.io.IOException;
import java.util.ArrayList;
import util.FileUtil;
public class Count {
public static void main(String[] args) {
//读原始数据
ArrayList<String> docLines = new ArrayList<String>();
FileUtil.readLines("coherenceCount/test.txt", docLines,"gbk");
//读取词汇
ArrayList<String> words = new ArrayList<String>();
FileUtil.readLines("coherenceCount/example1", words,"gbk");
StringBuilder sBuilder = new StringBuilder(); //用于写入文本
for (int i = 0; i < words.size(); i++) {
String word1 = words.get(i);
sBuilder.append(word1 + "\t");
for (int j = 0; j < words.size(); j++) {
String word2 = words.get(j);
//原始数据匹配
int countNumber = 0;
for (int k = 0; k < docLines.size(); k++) {
String[] oneDocWords = docLines.get(k).split(" ");
if (word1.equals(word2)) {
if (isContainKey(oneDocWords,word1)) {
countNumber++;
}
}else {
if (isContainKey(oneDocWords,word1)&&isContainKey(oneDocWords,word2)) {
countNumber++;
}
}
}
sBuilder.append(countNumber + "\t");
}
sBuilder.append("\n");
}
//结果写入指定文本
try {
FileUtil.writeFile("coherenceCount/result.txt", sBuilder.toString(),"gbk");
} catch (IOException e) {
e.printStackTrace();
}
}
public static boolean isContainKey(String[] arr, String targetV) {
for (String s : arr) {
if (s.equals(targetV))
return true;
}
return false;
}
}
如输出结果为“coherenceCount/result.txt”。
111 2 2 2 1 1
2115 2 2 2 1 1
163 2 2 3 2 1
3126 1 1 2 4 3
2615 1 1 1 3 3
上述代码中涉及了FileUtil类中的两个方法,如下所示:
//read a file to list
public static void readLines(String file, ArrayList<String> lines, String code) {
BufferedReader reader = null;
try {
reader = new BufferedReader( new InputStreamReader( new FileInputStream( new File(file)),code));
String line = null;
while ((line = reader.readLine()) != null) {
lines.add(line);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
以及:
/**
*
* @param file
* @param content
* @param code
* @throws IOException
*/
public static void writeFile(String file, String content,String code) throws IOException {
File fileOutput = new File(file);
OutputStream out = new FileOutputStream(fileOutput, false);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(out, code));
bw.write(content);
bw.close();
out.close();
}
Morstatter F, Liu H. In search of coherence and consensus: measuring the interpretability of statistical topics[J]. The Journal of Machine Learning Research, 2017, 18(1): 6177-6208.
Stevens K, Kegelmeyer P, Andrzejewski D, et al. Exploring topic coherence over many models and many topics[C]//Proceedings of the 2012 Joint Conference on Empirical Methods in Natural Language Processing and Computational Natural Language Learning. 2012: 952-961.