mirror of
https://github.com/apachecn/ailearning.git
synced 2026-05-08 23:12:06 +08:00
@@ -1,50 +1,24 @@
|
||||
|
||||
# 4) 朴素贝叶斯
|
||||
|
||||
|
||||
|
||||
* 假设: 特征之间强(朴素)独立
|
||||
* 概率模型
|
||||
|
||||
* P(C|F1F2...Fn) = P(F1F2...Fn|C)P(C) / P(F1F2...Fn)
|
||||
|
||||
* 由于对于所有类别,P(F1F2...Fn)都是相同的,比较P(C|F1F2...Fn)只用比较P(F1F2...Fn|C)P(C)就好了
|
||||
|
||||
* 朴素贝叶斯的特点
|
||||
|
||||
* 优点:在数据较少的情况下仍然有效,可以处理多类别问题
|
||||
|
||||
* 缺点:对于输入数据的准备方式较为敏感
|
||||
|
||||
* 适用数据类型:标称型数据
|
||||
|
||||
* 朴素贝叶斯的一般过程
|
||||
|
||||
* 收集数据:可以使用任何方法
|
||||
|
||||
* 准备数据:需要数值型或者布尔型数据
|
||||
|
||||
* 分析数据:有大量特征时,绘制特征作用不大,此时使用直方图效果更好。
|
||||
|
||||
* 训练算法:计算不同的独立特征的条件概率
|
||||
|
||||
* 测试算法:计算错误率
|
||||
|
||||
* 使用算法:文本分类等
|
||||
|
||||
* 优化
|
||||
|
||||
* 为了避免一个概率为0导致P(F1|C)*P(F2|C)....P(Fn|C)整个为0,所以优化为将所有词的出现数都初始化为1,并将分母初始化为2.
|
||||
|
||||
* 由于大部分因子比较小,乘积之后得到的数不易比较,程序误差较大。所以取对数后可将乘法转化为加法:P(F1|C)*P(F2|C)....P(Fn|C)P(C) -> log(P(F1|C))+log(P(F2|C))+....+log(P(Fn|C))+log(P(C))
|
||||
|
||||
* 总结
|
||||
|
||||
* 这一块代码比较乱,最好先把公式理一理再看
|
||||
|
||||
* 可以参考一下[阮一峰的博客](http://www.ruanyifeng.com/blog/2013/12/naive_bayes_classifier.html)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -64,8 +64,8 @@ def _trainNB0(trainMatrix, trainCategory):
|
||||
# 侮辱性文件的出现概率
|
||||
pAbusive = sum(trainCategory) / float(numTrainDocs)
|
||||
# 构造单词出现次数列表
|
||||
p0Num = zeros(numWords)[0,0,0,.....]
|
||||
p1Num = zeros(numWords)[0,0,0,.....]
|
||||
p0Num = zeros(numWords) # [0,0,0,.....]
|
||||
p1Num = zeros(numWords) # [0,0,0,.....]
|
||||
|
||||
# 整个数据集单词出现总数
|
||||
p0Denom = 0.0
|
||||
@@ -91,22 +91,28 @@ def trainNB0(trainMatrix, trainCategory):
|
||||
:param trainCategory: 文件对应的类别
|
||||
:return:
|
||||
"""
|
||||
# 文件数
|
||||
# 总文件数
|
||||
numTrainDocs = len(trainMatrix)
|
||||
# 单词数
|
||||
# 总单词数
|
||||
numWords = len(trainMatrix[0])
|
||||
# 侮辱性文件的出现概率
|
||||
pAbusive = sum(trainCategory) / float(numTrainDocs)
|
||||
# 构造单词出现次数列表
|
||||
# p0Num 正常的统计
|
||||
# p1Num 侮辱的统计
|
||||
p0Num = ones(numWords)#[0,0......]->[1,1,1,1,1.....]
|
||||
p1Num = ones(numWords)
|
||||
|
||||
# 整个数据集单词出现总数,2.0根据样本/实际调查结果调整分母的值
|
||||
# 整个数据集单词出现总数,2.0根据样本/实际调查结果调整分母的值(2主要是避免分母为0,当然值可以调整)
|
||||
# p0Denom 正常的统计
|
||||
# p1Denom 侮辱的统计
|
||||
p0Denom = 2.0
|
||||
p1Denom = 2.0
|
||||
for i in range(numTrainDocs):
|
||||
if trainCategory[i] == 1:
|
||||
# 累加辱骂词的频次
|
||||
p1Num += trainMatrix[i]
|
||||
# 对每篇文章的辱骂的频次 进行统计汇总
|
||||
p1Denom += sum(trainMatrix[i])
|
||||
else:
|
||||
p0Num += trainMatrix[i]
|
||||
@@ -120,7 +126,10 @@ def trainNB0(trainMatrix, trainCategory):
|
||||
|
||||
def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):
|
||||
"""
|
||||
使用算法
|
||||
使用算法:
|
||||
# 将乘法转坏为加法
|
||||
乘法:P(C|F1F2...Fn) = P(F1F2...Fn|C)P(C)/P(F1F2...Fn)
|
||||
加法:P(F1|C)*P(F2|C)....P(Fn|C)P(C) -> log(P(F1|C))+log(P(F2|C))+....+log(P(Fn|C))+log(P(C))
|
||||
:param vec2Classify: 待测数据[0,1,1,1,1...]
|
||||
:param p0Vec: 类别1,即侮辱性文档的[log(P(F1|C1)),log(P(F2|C1)),log(P(F3|C1)),log(P(F4|C1)),log(P(F5|C1))....]列表
|
||||
:param p1Vec: 类别0,即正常文档的[log(P(F1|C0)),log(P(F2|C0)),log(P(F3|C0)),log(P(F4|C0)),log(P(F5|C0))....]列表
|
||||
@@ -155,6 +164,7 @@ def testingNB():
|
||||
# 3. 计算单词是否出现并创建数据矩阵
|
||||
trainMat = []
|
||||
for postinDoc in listOPosts:
|
||||
# 返回m*len(myVocabList)的矩阵, 记录的都是0,1信息
|
||||
trainMat.append(setOfWords2Vec(myVocabList, postinDoc))
|
||||
# 4. 训练数据
|
||||
p0V, p1V, pAb = trainNB0(array(trainMat), array(listClasses))
|
||||
@@ -167,4 +177,5 @@ def testingNB():
|
||||
print testEntry, 'classified as: ', classifyNB(thisDoc, p0V, p1V, pAb)
|
||||
|
||||
|
||||
testingNB()
|
||||
if __name__ == "__main__":
|
||||
testingNB()
|
||||
|
||||
Reference in New Issue
Block a user