对在使用NLPIR-ICTCLAS2014分词系统进行分词时候,也就是为系统加入用户字典时候出现了个小问题
当我的字典超过5MB的时候(具体为5.48MB),用记事本打开的时候已经是半天才能显示出来了,若在程序中调用NLPIR_ImportUserDict的时候,情况更加惨不忍睹,先是等了半天(基本是有20来分钟),最后还是出现错误
本来以为是字典文件太大,造成了整个函数的错误。后来想了个办法,把字典切分成24个不超过500KB的小文件会不会就行了?
终于,不出现bug了,速度也提了上来,虽然不是太快,不过也能忍受了。
但是,出现了一个情况,就是最终只加进来了一个字典集合,比如我上面的词组,只能认得dic24.txt上面的,其他集合中出现的词组,均不能识别。所以NLPIR_ImportUserDict看来只能调用一次,多次调用会进行覆盖。
所以找了一个更加可靠的方法,使用NLPIR_AddUserWord这个函数,可以直接加入用户字典中,他和上面的NLPIR_ImportUserDict不同的地方就是,他需要自己添加对应的词组和词性(也就是接收的是字符串)。那么好办了,我们可以先对这个字典文件进行读取,然后再挨个用NLPIR_AddUserWord进行添加
顺便测试了一下,整一个文件的读取速度,没有分开成小文件的读取速度快(但这个测试可能不太靠谱,不过以后这个能进行速度的提升)
94571ms是整个大文件的,93995ms是分割之后进行读取的
下面是整个读取并添加的代码:
// use_nlpir.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include "stdio.h" #include "string" #include "iostream" #include "fstream" #include "vector" using namespace std; #include "NLPIR.h" #pragma comment(lib, "NLPIR.lib") #include "get_time_define.h" int _tmain(int argc, _TCHAR* argv[]) { if(!NLPIR_Init()) { printf("Init fails\n"); return -1; } const char *sResult; BEGINE_GET_TIME; ifstream fin; string file_input; vector<string> dic_input; for (int index = 0; index < 24; index++) { char file_name[16]; sprintf(file_name, ".//dic//dic%d.txt", index + 1); // cout << file_name << endl; fin.open(file_name); if (!fin.is_open()) { continue; } while (fin >> file_input) { dic_input.push_back(file_input); } fin.close(); } vector<string>::const_iterator it = dic_input.begin(); for (; it != dic_input.end(); it++) { NLPIR_AddUserWord(it->c_str()); } ENG_GET_TIME; CONSOLE_TIME; // 如果需要把新加的词永久保存到用户字典中,则需要执行下面的语句,之后Data文件夹下面的UserDict.pdat会变大 // NLPIR_SaveTheUsrDic(); // BEGINE_GET_TIME; // ifstream fin; // string file_input; // vector<string> dic_input; // // fin.open("dic.txt"); // while (fin >> file_input) // { // dic_input.push_back(file_input); // } // fin.close(); // vector<string>::const_iterator it = dic_input.begin(); // for (; it != dic_input.end(); it++) // { // NLPIR_AddUserWord(it->c_str()); // } // ENG_GET_TIME; // CONSOLE_TIME; const char *sSentence = "一万年太久二次风内地汇票饫甘餍肥隔热板餐饮行业餐饮集团隔离变压器隔皮断货"; cout << "===============NLPIR_ParagraphProcess==================" << endl; sResult = NLPIR_ParagraphProcess(sSentence,1); cout << sResult << endl; cout << "=================================" << endl; NLPIR_Exit(); return 0; }
这是加入字典后的效果:
当然,如果不加入字典,是识别不了后面的这些词的:
如果解开NLPIR_SaveTheUsrDic的注释,那么会更新Data文件夹中的数据,这样就不用反复执行NLPIR_AddUserWord了