nlpir不知道大家用的多不多,其实用起来挺简单的,官网(https://github.com/NLPIR-team/NLPIR)的例子都有,就是要花钱,免费30天用的又不过瘾,还要定期维护。这里说一下最新版本的DeepClassify文本分类功能吧,因为新版的文本分类 java版在linux上坑挺多的,文档又少,这里我就补充点文档(仅限于linux 64 java版本,因为windows64版本是没有问题的)。
首先我们的目录结构如图所示
注意点:linux64下,Data目录是不一样的,需要手动添加一个DeepClassifier文件夹,并且把授权文件deepclassifier.user添加到这个文件夹下,该文件夹下的其他文件不需要管,是执行训练后自动生成的。windows64不需要这个文件夹,授权文件也只需要放到Data目录下即可
按照文档说明,先训练在分类,以下都是指linux环境下
@Test
public void didTrain() throws IOException {
//1、训练过程--初始化
boolean flag = DeepClassifierLibrary.Instance.DC_Init("", 1, 800, "");
if (flag) {
System.out.println("deepClassifier初始化成功");
} else {
System.out.println("deepClassifier初始化失败:" + DeepClassifierLibrary.Instance.DC_GetLastErrorMsg());
System.exit(1);
}
//2、训练过程--遍历训练分类文本的文件夹,添加所有的训练分类文本
ArrayList list = FileOperateUtils.getAllFilesPath(new File("训练分类用文本"));
for (int i = 0; i < list.size(); i++) {
File f = new File(list.get(i).toString());
String className = f.getParent();
className = className
.substring(className.lastIndexOf("\\") + 1);
//将训练分类文本加载到内存中
String contentText = FileUtils.readFileToString(f, "utf-8");
DeepClassifierLibrary.Instance.DC_AddTrain(
className, contentText);
}
//3、训练过程--开始训练
DeepClassifierLibrary.Instance.DC_Train();
//4、训练过程--训练结束,退出
DeepClassifierLibrary.Instance.DC_Exit();
}
/**
* 分类过程
* @throws IOException
*/
@Test
public void didClassify() throws IOException {
//1、分类过程--初始化
if (DeepClassifierLibrary.Instance.DC_Init("", 1, 800, "")) {
System.out.println("deepClassifier初始化成功");
} else {
System.out.println("deepClassifier初始化失败:" + DeepClassifierLibrary.Instance.DC_GetLastErrorMsg());
System.exit(1);
}
//2、分类过程--加载训练结果
DeepClassifierLibrary.Instance.DC_LoadTrainResult();
//3、分类过程--读取待分类的文本
String content = FileOperateUtils.getFileContent("test.txt", "utf-8");
//4、分类过程--输出分类结果
System.out.println("分类结果:" + DeepClassifierLibrary.Instance.DC_Classify(content));
//5、分类过程--退出
DeepClassifierLibrary.Instance.DC_Exit();
}
会发现分类结果为null,但是控制台会打印初始化成功
amd64 // 64位系统
deepClassifier初始化成功 // 成功调用了DC_Init
但是根目录下会出现一个错误日志,查看github issues得知,要使用DC_NewInstance初始化一个分类器实例
但是最坑的来了,DeepClassifierLibrary.java压根就没有这个方法好吗!!!但是我发现老版本是有的,想骂人,也就是说我下载的这个版本linux上压根跑不起来,虽然最后解决了,但是浪费了很多时间
解决办法就是手动在DeepClassifierLibrary.java接口里面加方法,幸好的是DeepClassifier.so这个库文件里面有对应的方法,就是不知道为什么后来的版本把这些方法都删了
package com.lingjoin.deepClassify;
import com.lingjoin.fileutil.OSinfo;
import com.sun.jna.Library;
import com.sun.jna.Native;
public interface DeepClassifierLibrary extends Library{
DeepClassifierLibrary Instance =
(DeepClassifierLibrary)Native.loadLibrary(OSinfo.getSysAndBit("DeepClassifier"), DeepClassifierLibrary.class);
/**
* @param sDataPath
* @param encode
* @param nFeatureCount 特征词,默认是800
* @param sLicenceCode
* @return
*/
public boolean DC_Init(String sDataPath,int encode,int nFeatureCount,String sLicenceCode);
public boolean DC_Exit();
public boolean DC_AddTrain(String sClassName,String sText);
public boolean DC_AddTrainFile(String sClassName,String sFilePath);
public boolean DC_AddTrain(String sClassName,String sText,Long handle);
public Long DC_NewInstance(Long nFeatureCount);
public boolean DC_Train(Long handle);
public boolean DC_Train();
public boolean DC_LoadTrainResult();
public boolean DC_LoadTrainResult(Long handle);
public String DC_Classify(String sText,Long handle);
public String DC_Classify(String sText);
public String DC_ClassifyFile(String sFilename);
public String DC_GetLastErrorMsg();
public static final int ENCODING_GBK = 0;
public static final int ENCODING_UTF8 = 1;
}
然后案例方法也得改
package com.lingjoin.deepClassify;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import org.apache.commons.io.FileUtils;
import org.junit.Test;
import com.lingjoin.fileutil.FileOperateUtils;
public class DeepClassifierTest {
/**
* 训练过程
* @throws IOException
*/
@Test
public void didTrain() throws IOException {
//1、训练过程--初始化
boolean flag = DeepClassifierLibrary.Instance.DC_Init("", 1, 800, "");
if (flag) {
System.out.println("deepClassifier初始化成功");
} else {
System.out.println("deepClassifier初始化失败:" + DeepClassifierLibrary.Instance.DC_GetLastErrorMsg());
System.exit(1);
}
Long DC_Handle = DeepClassifierLibrary.Instance.DC_NewInstance((long)800);
//2、训练过程--遍历训练分类文本的文件夹,添加所有的训练分类文本
ArrayList list = FileOperateUtils.getAllFilesPath(new File("训练分类用文本"));
for (int i = 0; i < list.size(); i++) {
File f = new File(list.get(i).toString());
String className = f.getParent();
className = className
.substring(className.lastIndexOf("/") + 1);
//将训练分类文本加载到内存中
String contentText = FileUtils.readFileToString(f, "utf-8");
boolean dc_AddTrain = DeepClassifierLibrary.Instance.DC_AddTrain(
className, contentText,DC_Handle);
if(!dc_AddTrain){
System.out.println(DeepClassifierLibrary.Instance.DC_GetLastErrorMsg());
}
}
//3、训练过程--开始训练
boolean dc_Train = DeepClassifierLibrary.Instance.DC_Train(DC_Handle);
//4、训练过程--训练结束,退出
DeepClassifierLibrary.Instance.DC_Exit();
}
/**
* 分类过程
* @throws IOException
*/
@Test
public void didClassify() throws IOException {
//1、分类过程--初始化
if (DeepClassifierLibrary.Instance.DC_Init("", 1, 800, "")) {
System.out.println("deepClassifier初始化成功");
} else {
System.out.println("deepClassifier初始化失败:" + DeepClassifierLibrary.Instance.DC_GetLastErrorMsg());
System.exit(1);
}
Long DC_Handle = DeepClassifierLibrary.Instance.DC_NewInstance((long)800);
//2、分类过程--加载训练结果
DeepClassifierLibrary.Instance.DC_LoadTrainResult(DC_Handle);
//3、分类过程--读取待分类的文本
String content = FileOperateUtils.getFileContent("test.txt", "utf-8");
//4、分类过程--输出分类结果
System.out.println("分类结果:" + DeepClassifierLibrary.Instance.DC_Classify(content,DC_Handle));
//5、分类过程--退出
DeepClassifierLibrary.Instance.DC_Exit();
}
}
好了,这样才成功,但是我在解决的过程中当然不是一帆风顺的。。。下面在说下我遇到的坑吧,避免大家在犯错。
就是DC_Handle必须要是对的值,不然程序就会退出,然后报下面这个错。
好了,填坑到此为止,对了,windows64下是好的,下载的例子可以直接跑,如果大家有什么问题,可以回复我,希望大家不踩坑