使用 python 基于朴素贝叶斯进行文本分类学习笔记之四:增加测试文本和计算正确率

当前的代码可以通过下面的链接下载,我在 github 上更新的可能比较快,所以下面给出代码历史版本:

bayes.py: https://github.com/chinapnr/fish_base/blob/55a34478425d0395a0b09fe7fce5c30b3f8cd966/fish_base/bayes/bayes.py

bayes_test.py
https://github.com/chinapnr/fish_base/blob/55a34478425d0395a0b09fe7fce5c30b3f8cd966/demo/bayes_test.py

最新版的代码可以在这里找到: https://github.com/chinapnr/fish_base, demo 在 demo 路径下。我把 naive bayes 代码合并到我们的 fish_base 库中了。

除了正面和负面文本训练以外,现在增加了测试文本,并且计算正确率,这样改进算法、改进训练之后的结果就可以通过正确率进行比较了。所以在优化停用词、中文标点前,先增加了这个功能,代码如下。

 # 2016.5.18
    # 根据测试样本来测试分类的准确率
    # 输出 人工正确/机器判断正确 人工错误/机器判断错误 的两个百分比
    def test_nb(self, filename):

        test_doc_list = []
        pre_class_list = []

        # 设定测试结果 dict
        test_result_dict = {'11': 0, '10': 0, '00': 0, '01': 0}

        # 打开测试文本
        with open(filename, 'r') as f:
            for line in f:
                # 获得人工设定的类别
                pre_class_list.append(line[0:1])
                # 获得需要测试的文本
                test_doc_list.append(line[2:])

        # 测试文本的长度
        test_doc_count = len(test_doc_list)

        for i, item in enumerate(test_doc_list):

            s = list(jieba.cut(item))

            # 获得程序分类结果
            computer_class = self.run_nb(s)
            # 获得人工设定的分类结果
            pre_class = pre_class_list[i]

            # 结果记录到测试结果 dict 中
            index = '**'

            if pre_class == '1':
                index = str(10 + computer_class)
            if pre_class == '0':
                index = '0' + str(computer_class)

            test_result_dict[index] += 1

            print(s, pre_class, computer_class)

        print(test_result_dict)

        # 返回结果, 假设测试文本中正面和负面各占一半
        return test_result_dict['00'] / (test_doc_count / 2), test_result_dict['11'] / (test_doc_count / 2)

 

测试代码也做了修改,更加简化了,先进行中文分词初始化,然后训练,然后测试,就可以了。

nb.init_cut_word()

nb.open_train_doc_ch('train_bayes/good.txt', 0)
nb.open_train_doc_ch('train_bayes/bad.txt', 1)

nb.train()
print(nb.p0_v, nb.p1_v, nb.p_ab)

print(nb.test_nb('train_bayes/test.txt'))

 

测试文本举例如下。

0|这手机真不错
0|大屏幕,我很喜欢
0|速度快,质量好
0|买了给妈妈的,快递很快,服务好
0|挺喜欢这个手机的
0|手机屏幕大,挺好的
0|手机挺好的
0|很喜欢这个手机
1|破手机
1|什么破机器,速度那么慢
1|手机很一般,速度慢
1|不太喜欢
1|不能开机,已经保修
1|屏幕上有划痕,不开心
1|不相信国产手机了,质量一般,做工粗糙
1|已经退货了

 

第一个数字是标注这一行内容是正面还是负面,然后程序通过比较运行分类器的结果和人工预先设定的这个结果,得到正确率。最重要的自然是应该是正面且判断为正面,应该是负面且判断为负面这两个比例。

{'01': 1, '10': 5, '00': 7, '11': 3}
(0.875, 0.375)

 

我用 dict 来记录应该是正面负面和判断为正面负面(分别用0和1)四个值
之后的比例,就是前面说的两个比例,从目前的情况来看,对于正面的判断比较准确,对于负面的判断还在50% 以下,之后需要继续提高,先从停用词开始。

使用 python 基于朴素贝叶斯进行文本分类学习笔记之一:开始
使用 python 基于朴素贝叶斯进行文本分类学习笔记之二:将原书程序修改并转换为类
使用 python 基于朴素贝叶斯进行文本分类学习笔记之三:中文内容的倾向性判断初步
使用 python 基于朴素贝叶斯进行文本分类学习笔记之四:增加测试文本和计算正确率
使用 python 基于朴素贝叶斯进行文本分类学习笔记之五:增加停用词

mac osx 下建立 python package 以及在github 上开源项目的操作过程

怎么建立一个 python 包,并且发布到 pypi,有很多文章介绍了。同样,怎么在 github 建立一个开源项目,也不难。

把这两个事情一起做,加上我用 pycharm 来辅助完成 python 包的建立,以及用 source tree 来管理 github 项目,事情可就不少了。

小结一下经验体会:

1 建立 python 包,网上大部分教程没什么问题,如果用 pycharm 会更加容易一些,在菜单 Tools 中,会看到 Create setup.py,pycharm 会做一些目录结构调整、生成最基本的需要的文件,以及输入版本作者之类的事情。

2 文件结构转换为包的形式后,pycharm 很聪明的会在菜单 Tools 中,增加一个 Run setup.py Task。可以节约一些工作量,比如 sdist,这是必须执行的,upload 上传也是必须执行的。不过这里有一个坑,在 sdist 执行好之后,就可以选择 install 命令安装自己的包,然后在程序里面 import 什么都可以了,但是如果这时候你想上传 pypi 可能会报错:

error: no dist file created in earlier command

 

当然,肯定已经在 pypi 注册过用户了,查了不少资料,原来是要先这样操作:

python setup.py sdist upload

 

没有在 pycharm 中找到相应的命令,在终端模式下输入吧。

然后就可以 upload 了。所以,如果你 upload 到 pypi 同样碰到上面的错误,不妨试试看先这样操作一下。

来源这个老外的博客文章,写的很有趣也很清楚。

补充:直接执行上面的命令,应该是连 sdist 和 upload 一起都运行了,这样是最方便的。

running sdist
running check
warning: sdist: manifest template 'MANIFEST.in' does not exist (using default file list)

writing manifest file 'MANIFEST'
creating fish_base-1.0.2
creating fish_base-1.0.2/fish_base
making hard links in fish_base-1.0.2...
hard linking README.txt -> fish_base-1.0.2
hard linking setup.py -> fish_base-1.0.2
hard linking fish_base/__init__.py -> fish_base-1.0.2/fish_base
Creating tar archive
removing 'fish_base-1.0.2' (and everything under it)
running upload
Submitting dist/fish_base-1.0.2.tar.gz to https://pypi.python.org/pypi
HTTP Error 500: Internal Server Error
error: HTTP Error 500: Internal Server Error

 

看这里的操作,当 upload 后,显示了错误的信息,但是到 pypi 上看,已经传上去了,略有奇怪,可能这里的网络不稳定。

3 github 中碰到的问题,就是 https 模式下,用户名密码始终通不过验证,然后换成用 ssh 证书模式,按照 github 上的操作是最靠谱的,并且他们区分了不同操作系统,个人私钥的文件名一定要叫 id_rsa,反正我这里不叫这个就是通不过。
严格按照 github 上的步骤,以及测试 ssh 是否通顺的方法,如果不能通过,肯定是不能用的。

4 在项目的 .git 目录下,有一个 config 文件,可以修改其中的 https 模式到 ssh 模式。

5 osx EI Capitan 在 Finder 中显示隐藏信息的方法和之前版本有所改变:

defaults write com.apple.finder AppleShowAllFiles -bool true
killall Finder  

 

关键是后面那句。

source tree 作为一个免费强大的版本管理软件,没什么好说的,使用起来也很方便。

好了,我要修改代码了,为了试验,所传的项目代码都很烂,需要好好修改一下。

开始分享delphi xe4 for iphone的学习

我觉得大部分的程序中的80%是基础的模块,所以我觉得80%的程序员其实也是和我一样是平凡的,不是大牛。

其实,大多数行业都是这样的比例。

这也不光是职业的规律,人生大概也如此。

所以,作为一个平凡的程序员,当然年龄的确比大多数程序员大,和我一起开始编程的,大部分都不再是程序员了(其实我也不是,编程已经是业余爱好了)。分享一下。

delphi本身的语言能力很强,而易博龙从xe2开始引入的firemonkey框架,到了xe4的确更加强大了,用delphi进行智能手机开发,进行iphone开发(以及已经看到的xe5 for android),至少是一个选择。

我自学delphi xe4 for iphone的程序放在了github上,地址: https://github.com/wingfish/delphi_mobile_study

现在只有一个例子程序,文档要延后补了。

我从十年前就不想介入到什么语言好的讨论,合适就行,包容的心,这也是成熟的标志吧!