读入文件存入dataframe
-
readfiles(path): 对path下的每一个文件, 跳过文件头部无用信息, 以line+'\n'的格式存储在message中,每读完一个文件便返回该文件完整路径path和message
-
dataFrameFromDirectory(path,classification),调用readfiles,返回DataFrame格式文件, 其中包含index=path[], message=message[], class=传递的分类信息
-
带有 yield 的函数不再是一个普通函数,而是一个生成器generator,可用于迭代, 迭代从上次yield出去的地方开始
import os
import io
import numpy
from pandas import DataFrame
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.naive_bayes import MultinomialNB
def readFiles(path):
for root,dirnames,filenames, in os.walk(path):#返回path下的所有文件夹和文件
for filename in filenames:
path=os.path.join(root,filename) #创建path
inBody=False #标记头部信息
lines=[]
f=io.open(path,'r',encoding='latin1')#打开文件
for line in f:
if inBody:
lines.append(line)
elif line=='\n': #先把头部信息跳过,找到第一个空行 表明头部信息已经结束
inBody=True
f.close()
message='\n'.join(lines)
yield path,message
def dataFrameFromDirectory(path,classification):
rows=[]
index=[]
for filename,message in readFiles(path):
rows.append({'message':message,'class':classification})
index.append(filename)
return DataFrame(rows,index=index)
data=DataFrame({'message':[],'class':[]})
data = data.append(dataFrameFromDirectory('C:\\Users\\Sitch\\Downloads\\DataScienceCourse\\emails\\spam', 'spam'))
data = data.append(dataFrameFromDirectory('C:\\Users\\Sitch\\Downloads\\DataScienceCourse\\emails\\ham', 'ham'))
data.head()
计算朴素贝叶斯
-
CountVectorizer是特征数值计算类
-
CountVectorizer.fit_transform函数将文本中的词语转换为词频矩阵return,矩阵元素a[i][j] 表示j词在第i个文本下的词频。
-
MultinomialNB是先验为多项式分布的朴素贝叶斯类
-
MultinomialNB.fit(x,y)根据x,y进行拟合,x={array-like,sparse martix}[i][j],i组j维向量,y=array-like[i]
vectorizer=CountVectorizer()
counts=vectorizer.fit_transform(data['message'].values)#将单词转换为哈希数,然后计算个数
classifier=MultinomialNB()
targets=data['class'].values #分类信息
classifier.fit(counts,targets)
测试分类器
examples=['Free Money now!!!!',"Hi,I'm Sitch,how about make a friend?"]
example_counts=vectorizer.transform(examples)
predictions=classifier.predict(example_counts)
划分训练集和测试集再实验
train_data=data.sample(frac=0.6)
test_data=data[~data.index.isin(train_data.index)]
vectorizer=CountVectorizer()
counts=vectorizer.fit_transform(train_data['message'].values)
classifier=MultinomialNB()
targets=train_data['class'].values
classifier.fit(counts,targets)
i=0
SC=0
test_counts=vectorizer.transform(test_data['message'].values)
predictions=classifier.predict(test_counts)
for i in range(0,predictions.size):
if test_data['class'].values[i]==predictions[i]:
SC+=1
print("测试集成功率 ",end=' : ')
print(SC/predictions.size)