python 소박 한 베 이 루스 기반 쓰레기 분류 알고리즘 구현

모형 방법
       본 공정 에서 사용 하 는 모델 방법 은 소박 한 베 이 루스 분류 알고리즘 으로 그의 핵심 알고리즘 사상 은 확률론 을 바탕 으로 한다.우리 가'소박'이 라 고 부 르 는 것 은 전체 형식화 과정 이 가장 원시 적 이 고 간단 한 가설 만 하기 때문이다.소박 한 베 이 루스 는 베 이 루스 결정 이론의 일부분 이기 때문에 소박 한 베 이 루스 를 이야기 하기 전에 베 이 루스 결정 이론 을 빨리 이해 할 필요 가 있다.현재 우리 에 게 데이터 세트 가 있다 고 가정 하면 두 가지 데이터 로 구성 되 고 데이터 분 포 는 다음 그림 과 같다.

        우 리 는 현재 p1(x,y)로 데이터 점(x,y)이 카 테 고리 1(그림 에서 원점 으로 표시 하 는 카 테 고리)에 속 할 확률 을 표시 하고 p2(x,y)로 데이터 점(x,y)이 카 테 고리 2(그림 에서 삼각형 으로 표시 하 는 카 테 고리)에 속 할 확률 을 표시 합 니 다.그러면 새로운 데이터 점(x,y)에 대해 다음 규칙 으로 카 테 고리 를 판단 할 수 있 습 니 다.
p1(x,y)>p2(x,y)라면 분 류 는 1 입 니 다.
p2(x,y)>p1(x,y)이 라면 분 류 는 2 입 니 다.
       높 은 확률 로 대응 하 는 유형 을 선택 하 겠 다 는 것 이다.이것 이 바로 베 이 루스 결정 이론의 핵심 사상,즉 가장 높 은 확률 을 가 진 결정 을 선택 하 는 것 이다.
본 공사 에서 우 리 는 조건 확률 을 사용 하여 분류 할 수 있다.그 조건 확률 공식 은 다음 과 같다.

       그 중에서 굵 은 w 는 이것 이 하나의 벡터 이 고 여러 개의 값 으로 구성 되 어 있다 는 것 을 나타 낸다.카 테 고리 i 는 분류의 개 수 를 표시 하고 본 프로젝트 에서 i=0 시 c0 은 스 팸 메 일이 아 닌 것 을 표시 합 니 다.i=1 시 c1 은 스 팸 메 일 을 표시 합 니 다.w 를 하나의 독립 적 인 특징 으로 전개 하면 상기 확률 로 p(w0,w1,w2.wn|ci)를 작성 할 수 있 습 니 다.여기 서 모든 단어 가 서로 독립 된다 고 가정 하면 이 가설 은 조건 독립 성 가설 이 라 고도 부른다.이것 은 p(w0|ci)p(w1|ci)p(w2|ci)...p(wn|ci)를 사용 하여 상기 확률 을 계산 할 수 있다 는 것 을 의미한다.이것 은 계산 과정 을 크게 간소화 한 것 도 소박 한 베 이 루스 라 고 불 리 는 이유 이다.이 프로젝트 에서 wj 는 제 i 의 단어 특징 을 나타 내 고 p(wj|ci)는 스 팸 메 일(또는 스 팸 메 일)에서 제 j 의 단어 가 나타 날 확률 을 나타 낸다.반면 p(w|ci)는 스 팸 메 일(또는 비 스 팸 메 일)의 전체 벡터 특징(단어 벡터 특징)이 나타 날 확률 을 나타 낸다.반면 p(ci|w)는 전체 벡터 특징(단어 벡터 특징)에서 스 팸 메 일(또는 비 스 팸 메 일)일 확률 을 나타 낸다.이 프로젝트 는 주로 p(ci|w)를 계산 합 니 다.p(ci)는 스 팸 메 일(또는 비 스 팸 메 일)의 확률 을 나타 낸다.
시스템 설계

데이터 수집 및 저장
메 일의 수집 은 인터넷 에서 유래 하여 이메일 폴 더 에 저 장 됩 니 다.그 중에서 이메일 은 두 개의 키 파일 로 나 뉘 는데 하 나 는 ham 폴 더(비 스 팸 메 일 저장)이 고 다른 하 나 는 spam 폴 더(스 팸 메 일 저장)이다.ham 과 spam 에 각각 25 개의 메 일 을 저장 하고 x.txt(x 는 1 에서 25)로 저장 합 니 다.
훈련 집 과 테스트 집의 선택
수 집 된 메 일의 개수 가 제한 되 어 있 기 때문에 80%의 메 일 을 훈련 집 으로 선택 하고 그 방식 은 무 작위 로 선택한다.나머지 20%의 메 일 을 테스트 세트 로 합 니 다.
특징 벡터 구축
특징 벡터 의 구축 은 두 가지 로 나 뉘 는데 하 나 는 훈련 집합 에 대한 특징 벡터 구축 이다.테스트 집합 을 위 한 특징 벡터 구축메 일 은 스 팸 메 일과 비 스 팸 메 일 로 나 뉘 기 때문에 훈련 집의 특징 벡터 는 두 가지 로 나 눌 수 있다.특징 벡터 는 훈련 집중 모든 스 팸 메 일 에 구 성 된 특징 벡터(w 로 기록)와 훈련 집중 모든 비 스 팸 메 일 구성 특징 벡터(w 로 기록)로 나 뉜 다.w 에 대한 계산 은 실제 적 으로 모든 훈련 집중 스 팸 메 일 에 있 는 모든 단어의 발생 상황 을 통계 하고 나타 나 면 횟수 에 1 을 더 하 는 것 이다.그 계수 의 초기 값 은 1 이 고 정상 적 인 상황 에 따라 0 이 어야 합 니 다.소박 한 베 이 루스 알고리즘 을 사용 하기 때문에 모든 단어 가 서로 독립 된다 고 가정 하면 p(w|ci)=p(w0|ci)p(w1|ci)p(w2|ci)...p(wn|ci)가 있 습 니 다.그래서 i 번 째 단어 와 이 가 특징 벡터 에 나타 나 지 않 으 면 p(와 이|ci)=0 이 있어 p(w|ci)가 결과 의 부정 확 성 을 초래 합 니 다.그래서 우 리 는 아예 모든 단 어 를 한 번 씩 묵인 하기 때문에 1 부터 계산한다.w'의 계산 과 w 의 계산 방법 이 같 으 니,여 기 는 군말 하지 않 는 다.
테스트 집합 에 대한 특징 벡터 구축 은 모든 메 일 에 단어 가 나타 나 는 횟수 를 통계 하 는 것 으로 그 단어 표 는 50 개의 메 일 에 있 는 모든 단어 에서 유래 할 수 있다.모든 메 일 에 단어 가 나타 나 면 1 을 추가 하고 초기 값 은 0 입 니 다.모든 테스트 집합 메 일 은 특징 벡터 를 구축 해 야 합 니 다.그 특징 벡터 는 python 에서 목록 으로 표시 할 수 있 습 니 다.
베 일 스 분류 기 구축
분류 기 훈련 목적 에 대한 세 가지 매개 변 수 는 p1 Vect(w 에서 단어 마다 나타 날 확률 로 구 성 된 특징 벡터),p0 Vect(w'에서 단어 마다 나타 날 확률 로 구 성 된 특징 벡터)와 pAbusive(훈련 집중 스 팸 메 일의 확률)이다.p1 Vect,p0 Vect 계산 에 있어 서 넘 칠 수 있 습 니 다.이것 은 너무 많은 작은 수의 상승 으로 인 한 것 입 니 다.곱 하기 p(w0|ci)p(w1|ci)p(w2|ci)...p(wn|ci)를 계산 할 때 대부분의 인자 가 매우 작 기 때문에 프로그램 이 넘 치 거나 정확 하지 않 은 답 을 얻 을 수 있 습 니 다.하나의 해결 방법 은 곱 하기 자연 대 수 를 취 하 는 것 이다.대수 에 ln(a*b)=ln(a)+ln(b)이 있 기 때문에 대 수 를 구하 면 넘 치 거나 부동 소수점 반올림 으로 인 한 오 류 를 피 할 수 있 습 니 다.동시에 자연 대수 로 처리 하면 아무런 손실 도 없 을 것 이다.그림 1 은 함수 f(x)와 ln(f(x))의 곡선 을 보 여 준다.이 두 곡선 을 검사 하면 같은 구역 에서 동시에 증가 하거나 감소 하 며 같은 점 에서 극치 를 얻 는 것 을 발견 할 수 있다.그들의 수 치 는 비록 다 르 지만 최종 결과 에 영향 을 주지 않 는 다.

그래서 p1 Vect=log(w/p1 Denom),p0 Vect=log(w'/p0 Denom),그 중에서 p1 Denom,p0 Denom 은 스 팸 메 일 에 있 는 단어의 총수 와 비 스 팸 메 일 에 있 는 단어의 총수 이다.pAbusive 는 집중 스 팸 메 일 총수 와 훈련 집중 메 일 총수 의 비례 를 훈련 하 는 것 과 같다.
테스트 집합 검증 및 평가
스 팸 메 일 인지 아 닌 지 를 판단 하기 위해 서 는 모든 메 일 에 대해 p(c0|w)(스 팸 메 일이 아 닌 확률)와 p(c1|w)(스 팸 메 일의 확률)만 판단 해 야 한다.
q.p(c0|w)>p(c1|w)라면 이 메 일 은 스 팸 메 일이 아 닙 니 다.
q 만약 p(c0|w)       그러나 p(ci|w)(i=0 또는 1)의 계산 은 p(w|ci)와 p(ci)의 계산 에 의존 하고 p(w)는 계산 할 필요 가 없다.그래서 최종 결 과 는 pi=p(w|ci)·p(ci)에 의존한다.p(w|ci)가 작 기 때문에 아래로 넘 칠 수 있 습 니 다.그래서 우 리 는 10 을 밑 으로 하 는 로그(pi)=로그(p(w|ci)+로그(p(ci))를 취하 기 때문에 다음 과 같은 결론 을 얻 을 수 있다.
q.log(p0)>log(p1)가 있 으 면 이 메 일 은 스 팸 메 일이 아 닙 니 다.
q.log(p0)그 중에서 p(w|ci)는 스 팸 메 일(또는 비 스 팸 메 일)의 전체 벡터 특징(단어 벡터 특징)이 나타 날 확률 이 고 p(ci)는 스 팸 메 일(또는 비 스 팸 메 일)을 훈련 하기 위해 집중 할 확률 이다.
3.시스템 시연 과 실험 결과 분석 비교
       훈련 집(40 개)과 테스트 집(개)의 견본 수량 이 비교적 작 기 때문에 테스트 의 분류 결과 의 정확성 은 90%-100%사이 이다.다음 그림 과 같다.


        본 공 사 는 메 일 을 두 가지 로 분류 할 뿐 베 이 루스 알고리즘 도 여러 가지 분류 문 제 를 처리 할 수 있다.예 를 들 어 뉴스의 분류,예 를 들 어 군사,체육,과학기술 등 이다.물론 이 공 사 는 영어 스 팸 메 일 만 분류 할 수 있 지만 중국어 스 팸 메 일 분류(python 의 jieba 라 이브 러 리 모듈 로 중국어 단 어 를 나 눌 수 있 습 니 다).
4.코드 구현

#coding=UTF-8
import random
from numpy import *
 
#      ,     
def textParse(bigString):
 #        
 listOfTokens = bigString.split()
 #        2     
 return [tok.lower() for tok in listOfTokens if len(tok)>2]
 
#        ,        
def createVocaList(dataSet):
 vocabSet = set({})
 #     ,   
 for document in dataSet:
 vocabSet = vocabSet | set(document)
 return list(vocabSet)
 
#      (   )          ,        
def setOfWordsToVec(vocabList,inputSet): 
 #  0  ,          
 returnVec = [0]*len(vocabList)
 #            
 for word in inputSet:
 if word in vocabList:
  returnVec[vocabList.index(word)] += 1
 return returnVec
 
#            
def trainNB0(trainMatrix,trainCategory): 
 #       
 numTrainDocs = len(trainMatrix)
 #          
 numWords = len(trainMatrix[0])
 #     (  p(Ci)),         
 pAbusive = sum(trainCategory)/float(numTrainDocs)
 #                      (    )
 p0Num = ones(numWords)
 #                     (    )
 p1Num = ones(numWords)
 #             (    )
 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]
  p0Denom +=sum(trainMatrix[i])
 #                (    )
 p1Vect = log(p1Num/p1Denom)
 #                 (    )
 p0Vect = log(p0Num/p0Denom)  
 return p0Vect,p1Vect,pAbusive
#         
def classifyNB(vec2Classify,p0Vec,p1Vec,pClass1):
 p1 = sum(vec2Classify*p1Vec)+log(pClass1)
 p0 = sum(vec2Classify*p0Vec)+log(1.0 - pClass1)
 if p1 > p0:
 return 1
 else :
 return 0
#test
def spamtest():
 #         
 docList =[];classList=[];fullText = []
 for i in range(1,26):
 #   i     ,        
 wordList = textParse(open('email/spam/{0}.txt'.format(i)).read())
 #       
 docList.append(wordList)
 #        
 fullText.extend(wordList)
 #         
 classList.append(1)
 #   i      ,        
 wordList = textParse(open('email/ham/{0}.txt'.format(i)).read())
 #       
 docList.append(wordList)
 #        
 fullText.extend(wordList)
 #          
 classList.append(0)
 #         
 vocabList = createVocaList(docList)
 #   , 40 doc
 trainingSet = [x for x in range(50)]
 #   , 10 doc
 testSet = []
 #  10 doc    
 for i in range(10):
 randIndex = int(random.uniform(0,len(trainingSet)))
 testSet.append(trainingSet[randIndex])
 del trainingSet[randIndex]
 trainMat = [];trainClasses=[]
 #  40 doc    
 for docIndex in trainingSet:
 trainMat.append(setOfWordsToVec(vocabList, docList[docIndex]))
 trainClasses.append(classList[docIndex])
 p0V,p1V,pSpam = trainNB0(array(trainMat), array(trainClasses))
 #      
 errorCount = 0
 for docIndex in testSet:
 wordVector = setOfWordsToVec(vocabList,docList[docIndex])
 if classifyNB(array(wordVector), p0V, p1V, pSpam)!=classList[docIndex]:
  errorCount+=1
 print("    :{0}".format(float(errorCount)/len(testSet)))
spamtest()
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기