Warning: WP_Syntax::substituteToken(): Argument #1 ($match) must be passed by reference, value given in /www/wwwroot/fawdlstty.com/wp-content/plugins/wp-syntax/wp-syntax.php on line 383
Warning: WP_Syntax::substituteToken(): Argument #1 ($match) must be passed by reference, value given in /www/wwwroot/fawdlstty.com/wp-content/plugins/wp-syntax/wp-syntax.php on line 383
Warning: WP_Syntax::substituteToken(): Argument #1 ($match) must be passed by reference, value given in /www/wwwroot/fawdlstty.com/wp-content/plugins/wp-syntax/wp-syntax.php on line 383
Warning: WP_Syntax::substituteToken(): Argument #1 ($match) must be passed by reference, value given in /www/wwwroot/fawdlstty.com/wp-content/plugins/wp-syntax/wp-syntax.php on line 383
部分资料下载地址: http://pan.baidu.com/s/1bpsgt5t 提取码fwxf
源码下载地址:https://github.com/fawdlstty/hm_ML
朴素贝叶斯这东西呢,主要用于文本相关处理,比如通过邮件内容判断是否是垃圾邮件等等。
具体实现思路是:比如判断某个邮件的内容是否是垃圾邮件,那么弄两个文本向量,分别代表正常邮件的关键字与垃圾邮件关键字,然后计算哪边关键字出现的多就按次数多的定义。比如正常邮件关键字有3个,垃圾邮件关键字有20个,那么这邮件是垃圾邮件的概率大于这是正常邮件的概率,那就定义这邮件为垃圾邮件。
这个对于英文来说非常容易实现,但对于中文来说就不是那么回事了,因为中华汉字博大精深嘛,关键字非常不好找,算法的学习也是一件非常耗时的工作。所以这儿呢,我就简单实现一个类似的东西吧,我将实现,判断一句话的情感状态。
首先是分词,我选择friso;然后是情感词库,我找的一个网上的情感词汇本体库。这些东西在上面的源代码下载里面已经包括了。
接下来是实现。首先,基于C语言的friso的引用,是一件坑爹的事情:
1 2 3 4 5 6 7 8 | #ifdef __cplusplus extern "C" { #endif #include "friso/friso.h" #ifdef __cplusplus } #endif #pragma comment(lib, "friso/friso.lib") |
接下来是朴素贝叶斯的实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | class Bayes : public Feature_Object_Collection { public: Bayes (std::initializer_list<Feature_Object> list) : Feature_Object_Collection (list) {} Bayes (Feature_Object_Collection& o) : Feature_Object_Collection (o) {} Bayes (const Bayes &o) : Feature_Object_Collection (o) {} Bayes () : Feature_Object_Collection () { std::ifstream ifs ("words/words_gbk.csv"); std::string tmp_str; std::vector<std::string> v; std::getline (ifs, tmp_str); while (std::getline (ifs, tmp_str)) { if (tmp_str.length () > 0) { v.clear (); hTools::str::split (tmp_str, v, ','); Feature_Object fo (v [0]); auto p = m_map.lower_bound (v [4]); if (p != m_map.upper_bound (v [4])) { fo << p->second; fo << std::stoi (v [5]); add_feature (fo); } } } ifs.close (); } std::string calc (std::string &doc) { ptrdiff_t feel_size = m_map2.size (); ptrdiff_t *feel = new ptrdiff_t [feel_size]; ::memset (feel, 0, sizeof (ptrdiff_t)*feel_size); friso_t friso = ::friso_new (); friso_config_t config = ::friso_new_config (); if (1 != ::friso_init_from_ifile (friso, config, "friso/friso.ini")) { return "加载friso配置文件失败!"; } friso_task_t task = ::friso_new_task (); ::friso_set_text (task, &doc [0]); ptrdiff_t size = get_size (), index; std::string word; while (::friso_next (friso, config, task) != NULL) { word = task->hits->word; for (index = 0; index < size; ++index) if (data [index].get_label () == word) break; if (index != size) feel [(ptrdiff_t) (data [index]) [0]] += (ptrdiff_t) (data [index]) [1]; } ::friso_free_task (task); //friso_free_config (config); ::friso_free (friso); for (index = 0, size = 0; index < feel_size; ++index) if (feel [index] > feel [size]) size = index; if (0 == feel [size]) { word = "未知"; } else { word = m_map2 [size]; } delete[] feel; return word; } protected: static std::map<std::string, int> m_map; static std::map<int, std::string> m_map2; }; |
以及静态变量的定义
1 2 | std::map<std::string, int> FawLearn::Bayes::m_map ({ { "PA", 0 }, { "PE", 1 }, { "PD", 2 }, { "PH", 3 }, { "PG", 4 }, { "PB", 5 }, { "PK", 6 }, { "NA", 7 }, { "NB", 8 }, { "NJ", 9 }, { "NH", 10 }, { "PF", 11 }, { "NI", 12 }, { "NC", 13 }, { "NG", 14 }, { "NE", 15 }, { "ND", 16 }, { "NN", 17 }, { "NK", 18 }, { "NL", 19 }, { "PC", 20 } }); std::map<int, std::string> FawLearn::Bayes::m_map2 ({ { 0, "快乐" }, { 1, "安心" }, { 2, "尊敬" }, { 3, "赞扬" }, { 4, "相信" }, { 5, "喜爱" }, { 6, "祝愿" }, { 7, "愤怒" }, { 8, "悲伤" }, { 9, "失望" }, { 10, "疚" }, { 11, "思" }, { 12, "慌" }, { 13, "恐惧" }, { 14, "羞" }, { 15, "烦闷" }, { 16, "憎恶" }, { 17, "贬责" }, { 18, "妒忌" }, { 19, "怀疑" }, { 20, "惊奇" } }); |
稍微解释下。Bayes()构造函数,用于加载情感词汇库文件,这文件里面也有,注意路径。
接下来,这个情感词汇库里面对每个情感词汇均加入了“权”值,这意味着更方便我们的实现。具体参考压缩包里面的压缩包的里面的文档。
还有就是friso.ini这配置文件里面的有个路径,必须要是绝对路径,并且路径中不能出现空格,否则运行之后会给你警告。(这儿的警告基本代表这次运行注定失败)。
然后静态变量的定义,这个定义是我根据文档写的。
最后,我这个实现并不科学,科学的做法是通过map来存储情感词汇,但我这儿为了方便,直接用之前实现的vector就存放了。后来的各路大神就别学我偷懒了。
噢对了,这次的代码调用了我之前的一个字符串处理库,详情请见C++中std::string实现trim、format等函数
以上代码告一段落,还剩调用了。调用就简单了,比如如下代码:
1 2 3 4 5 6 7 | int main(int argc, char* argv[]) { Bayes b; string s = b.calc (string ("那个女孩真漂亮")); cout << "目标文字语义状态:" << s << endl; return 0; } |
以上代码运行结果为这样:
对这个感兴趣的朋友们可以试着加入学习功能,通过对垃圾邮件或者脏话关键字的学习,就可以实现过滤垃圾邮件、脏话过滤算法了。
沙发!未来机器女仆敬上!