首页 > 试题广场 >

垃圾邮件分类问题

[编程题]垃圾邮件分类问题
  • 热度指数:222 时间限制:C/C++ 5秒,其他语言10秒 空间限制:C/C++ 128M,其他语言256M
  • 算法知识视频讲解
编写Naïve Bayes分类模型对邮件文本进行分类,判断该邮件是不是垃圾邮件(二分类)。我们已经通过数据预处理,将原始的邮件文本数据转化为分类器可用的数据向量形式,具体:数据表示为整型数向量x=(x1,x2,…,xd)。d是数据特征向量的维数,每个输入数据样本的格式为:
Label x1 x2 … xd

其中Label0或者1的整型数字(0表示正常邮件,1表示垃圾邮件);

        x1 x2 … xd是离散化后的特征,表示为从0开始的自然数;

        维度d小于20

        如果Label=?,则表示希望输出的预测类别值(需要预测的类别一定已在对应的训练数据中已经出现过)。


输入描述:
输入格式如下:

第一行三个数字M N d,M是训练集的大小,N是测试集的大小,d是数据维数。接下来是M行训练数据样本,然后是N行需要预测的样本。


输出描述:
期望的输出:每条待预测样本的标签
示例1

输入

4   2   3
1   13  0   10
0   6   11  2
1   17  2   14
0   8   16  13
?   20  3   19
?   2   13  18

输出

1
0

说明

分隔符为"\t"
import sys 
import math 


first_line =  sys.stdin.readline().rstrip().split('\t')
#M N d,M是训练集的大小,N是测试集的大小,d是数据维数。
train_size = int(first_line[0])
test_size = int(first_line[1])

train_data = []
train_label = []
for i in range(train_size):
    line = sys.stdin.readline().rstrip().split('\t')
    line = [int(x) for x in line]
    train_data.append(line[1:])
    train_label.append(line[0])

test_data = []
for i in range(test_size):
    line = sys.stdin.readline().rstrip().split('\t')
    line = [int(x) for x in line[1:]]
    test_data.append(line)
#print(train_data, train_label, test_data)

def trainNB(train_data, train_label):
    train_size = len(train_data)
    num_feature = len(train_data[0])
    pAbusive = sum(train_label)/float(train_size)
    p0Num = [1] * num_feature
    p1Num = [1] * num_feature
    p0Denom = 2.0 
    p1Denom = 2.0 
    for i in range(train_size):
        if train_label[i] == 1:
            for j in range(num_feature):
                p1Num[j] += train_data[i][j]
            p1Denom += sum(train_data[i])
        else:
            for j in range(num_feature):
                p0Num[j] += train_data[i][j]
            p0Denom += sum(train_data[i])
    p1Vect = [math.log(x/p1Denom) for x in p1Num]
    p0Vect = [math.log(x/p0Denom) for x in p0Num]
    return p0Vect,p1Vect,pAbusive

def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):
    p1 = 0
    p0 = 0
    for i in range(len(vec2Classify)):
        p1 += vec2Classify[i] * p1Vec[i]
        p0 += vec2Classify[i] * p0Vec[i]
        
    p1  += math.log(pClass1)    
    p0  +=  math.log(1.0 - pClass1)
    if p1 > p0:
        return 1
    else: 
        return 0
    
p0V,p1V,pSpam = trainNB( train_data , train_label) 
for i in range(test_size):
    print(classifyNB( test_data[i] ,p0V,p1V,pSpam))
    
    


习惯了调库,自己手写真的麻烦,连numpy都不让用。。。
编辑于 2020-08-08 14:58:24 回复(0)
这道题第一个测试用例有问题吧?(哭了)
[?,2,8]答案显示是0,我算出来是1,死活想不通。
发表于 2020-07-23 00:32:42 回复(4)