在trainNB0()函数中,估计条件概率时的分母:
书中:p1Denom += sum(trainMatrix[i])。这个我在第一遍看的时候没有看懂为什么要这样做,第二遍看了《统计学习方法》中关于估计条件概率的公式之后发现这里应该是写错了。正确:p1Denom += 1;p0Denom += 1.2020.12.25更正本条:原书中p0Denom += sum(trainMatrix[i]), p1Denom += sum(trainMatrix[i])式子是对的,是我当时搞错了。
p0Denom的意思是计算类别为0的文档中的总词数。我当时理解成了计算类别为0的文档在整个文档矩阵中出现的次数,其实trainNB0()函数中pAbusive已经做了这个事情。先验概率及条件概率的估计公式见朴素贝叶斯法相关概念及原理2.2
利用正则表达式来切分文本的时候:
书中用的是\W*,用这个来切分文本时发现,将文本切成了一个字母一个字母的样子,并没有完整的单词,如下图: 正确的应该是:\W+。奉上正则表达式的小知识:
\w:用于匹配字母,数字或下划线字符; \W:用于匹配所有与\w不匹配的字符;*:前一个字符0次或多次扩展;+:前一个字符1次或多次扩展;re.compile(pattern, flags=0) Compile a regular expression pattern, returning a pattern object.返回一个匹配对象,它单独使用就没有任何意义,需要和findall(), search(), match()等搭配使用。运行spamTest()函数时,总是报错:UnicodeDecodeError: ‘gbk’ codec can’t decode byte 0xae in position 199: illegal multib;在open()函数中加入encoding="utf-8"依然报错。
在循环解析中加入print(i)进行定位,发现问题出在email\ham\23.txt,打开文件发现23中包含一个?字符(非法字符),“SciFinance?is”,将?替换成空格,问题解决。
解析中的非法字符问题解决之后,函数还是报错,不过这次是报了TypeError: ‘range’ object doesn’t support item deletion,查阅资料发现是python版本问题,在python3.x中range返回的是range对象,不返回数组对象。
解决办法:把range对象转换成列表对象。即,把trainingSet = range(50) 改为 trainingSet = list(range(50))
书中作者的意思是以来自源 http://newyork.craigslist.org/stp/index.rss 中的文章作为分类为1的文章,以来自源 http://sfbay.craigslist.org/stp/index.rss 中的文章作为分类为0的文章,但是由于FW的原因,访问不到作者所说的数据,所以在网上找了两个替代源:
NASA Image of the Day:http://www.nasa.gov/rss/dyn/image_of_the_day.rss Yahoo Sports - NBA - Houston Rockets News:http://sports.yahoo.com/nba/teams/hou/rss.xml
代码跑通,但是这两个源数据也比较少,所以程序的效果一般。
参考资料: 1.《统计学习方法》(李航),第4章。 2.TypeError 3.另外的RSS源