Describe ë�°ë¸”ìŠ¤ìº í”„2011/ë‘˜ì§¸ë‚ /Machine-Learning/NaiveBayesClassifier/ê¹€ë�™ì¤€ here
Train.java
Train ì�˜ Politics.txt 파ì�¼ ì �중ë�„ : 0.94 (94%)
ì „ì²´ í�‰ê· ì �중ë�„ : 0.885 (88.5%)
위ì�˜ 주ì„�처럼 필요없는 (http, //, blog, yahoo, empas, tistory ê°™ì�€) 단어를 ì œì™¸í•˜ê³ ìž‘ì„±í• ìˆ˜ 있게 ìˆ˜ì •í–ˆìŠµë‹ˆë‹¤.
ê°� 단어중 특별한 단어ì—� Advantage 를 부과했는ë�°, 단어가 해당 Section ì—� Unique í•˜ê³ ê·¸ 빈ë�„ê°€ í�´ìˆ˜ë¡� Advantage를 í�¬ê²Œ 부과했습니다. (하지만 ì�´ë�„ ë¶„ì„�한 Sectionì—� ìƒ�대ì �입니다.)
그래서 그런지 결과엔 0.5% 차�밖� 없�군요..
ì�´ 결과를 ë³¼ 수 있었으면 ì¢‹ê² ë„¤ìš” ^^;;
Train.java
package org.zeropage.machinelearn;
import java.io.*;
import java.util.*;
class Trainer {
private Map<String,Integer> sectionWord;
private int sectionWordNum;
private int sectionArticleNum;
private File fileName;
// 들어온 ë�°ì�´í„°ì�˜ ì‹ ë¢°ì„±ì�„ ì²´í�¬í•˜ëŠ” 함수. ì‹ ë¢°ì„±ì�´ 없는경우 False 반환
private boolean isSkipData(String inputStr) {
if(inputStr.length() == 1 || inputStr.equals("http") || inputStr.equals("blog") || inputStr.equals("com") ||
inputStr.equals("naver") || inputStr.equals("empas") || inputStr.equals("daum") || inputStr.equals("yahoo") ||
inputStr.equals("tistory") || inputStr.equals("co") || inputStr.equals("kr") || inputStr.equals("www") || inputStr.equals("ohmynews") ||
inputStr.equals("//") || inputStr.equals("블로그")) {
return true;
}
else { return false; }
}
// �성�
public Trainer(File f) {
this.fileName = f;
}
// Data� 대한 학습 시행
public void TrainData() {
this.sectionWordNum = 0;
this.sectionArticleNum = 0;
this.sectionWord = new HashMap<String,Integer>();
try {
Scanner sectionLearn = new Scanner(this.fileName);
while(sectionLearn.hasNextLine()) {
this.sectionArticleNum++;
String[] a = sectionLearn.nextLine().split("\\s+");
for(String wordTmp:a) {
if(isSkipData(wordTmp)) {continue;} // 1글ìž�Data, 사ì�´íЏ, 블로그, 페ì�´ì§€ 주소ì�˜ 경우 연관성ë°� ì‹ ë¢°ì„±ì�´ 떨어지므로 검색ì—�서 ì œì™¸
if( this.sectionWord.get(wordTmp) == null) { // 해당 단어가 없으면
this.sectionWord.put(wordTmp, 1); // 1개로 새로 ë„£ê³ ì¶”ê°€
}
else { this.sectionWord.put(wordTmp, this.sectionWord.get(wordTmp)+1); } // 있는경우 ìž�ì‹ ì�˜ 것ì—� 갯수를 한개 ë�” 추가
this.sectionWordNum++; //Word 수는 중복과 �관없� 갯수를 Count 하므로 무조건 �가시킨다.
}
}
sectionLearn.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
// 학습� ��터를 반환
public HashMap<String,Integer> getSectionData() {
return (HashMap<String, Integer>) this.sectionWord;
}
// � 단어수를 반환
public int getSectionWordsNumber() {
return this.sectionWordNum;
}
// íŠ¹ì • 단어ì�˜ 갯수를 반환, 없는경우 1 반환
public int getSectionWordNumber(String word) {
return (sectionWord.get(word) == null) ? 1 : sectionWord.get(word)+1;
}
// ì „ì²´ 기사ì�˜ 수를 반환
public int getSectionArticleNumber() {
return this.sectionArticleNum;
}
}
Analyzer.java
package org.zeropage.machinelearn;
import java.util.*;
import java.io.*;
public class Analyzer {
private Trainer[] sectionTrain;
private int notInSectionArticleSum = 0;
private int notInSectionWordSum = 0;
private int notInSectionWordTotalSum = 0;
//�기 Section � 아닌 내용� Calculate 하는 함수. Index � 반�하며 수행시 초기화 후 계산한다.
private void CalculateNotInSection(int index) {
this.notInSectionArticleSum = 0;
for(int i = 0; i < sectionTrain.length; i++) {
if(i != index) { notInSectionArticleSum += sectionTrain[i].getSectionArticleNumber(); }
}
this.notInSectionWordTotalSum = 0;
for(int i = 0; i < sectionTrain.length; i++) {
if(i != index) { notInSectionWordTotalSum += sectionTrain[i].getSectionWordsNumber(); }
}
}
//해당 단어� 대한 �기 Section � 아닌 단어수를 Calculate 하는 함수. Index � 대�하며 수행시 초기화 후 계산한다.
private void CalculateNotInSectionWord(int index, String word) {
this.notInSectionWordSum = 0;
for(int i = 0; i < sectionTrain.length; i++) {
if(i != index) { notInSectionWordSum += sectionTrain[i].getSectionWordNumber(word); }
}
}
//해당 기사ì—� 대한 ì—°ì‚° 결과를 반환하는 함수. 양수ì�¼ 경우 해당 Index Section ì—� ì�¼ì¹˜í•˜ëŠ” 기사로 íŒ�단한 것ì�´ë©°, ì�Œìˆ˜ì�¼ 경우 해당 Index Section ì—� ì�¼ì¹˜í•˜ì§€ 않는 기사ë�¼ê³ íŒ�단한 것ì�´ë‹¤.
private double getWeight(int index, String Article) {
double reslt = getLnPsPns(index);
for(String wordTmp:Article.split("\\s+")) {
reslt += getLnPwsPwns(index, wordTmp);
}
return reslt;
}
// Ln[p(S) / p(!S)] 값� 계산하는 함수. Index � 대�한다.
private double getLnPsPns(int index) {
return Math.log((double)sectionTrain[index].getSectionArticleNumber() / notInSectionArticleSum);
}
// Sigma Ln[p(Wi ^ S) / p(Wi ^ !S)] ê°’ì�„ 계산하는 함수. Index ì—� 대ì�‘한다. 단 íŠ¹ì • 단어ì—� 대한 Advantage 를 부과한다. (Advantage 함수 참조)
private double getLnPwsPwns(int index, String word) {
CalculateNotInSectionWord(index, word);
return Math.log(((double)sectionTrain[index].getSectionWordNumber(word) / sectionTrain[index].getSectionWordsNumber()) / ((double)ArticleAdvantage(index, word) / notInSectionWordTotalSum));
}
// íŠ¹ì • 단어ì—� 대한 Advantage 부과함수. 해당 Index Section ì—�ë§Œ 존재하는 단어ì�¼ë•Œ 빈ë�„ì—� 따른 가산ì �ì�„ 부여한다. 가산ì�€ 해당단어수 / Section ì „ì²´ê¸°ì‚¬ìˆ˜ * 50 ì�´ë‹¤.
private double ArticleAdvantage(int index, String word) {
double advantageResult = 0;
for(int i = 0; i < sectionTrain.length; i++) {
if(i != index) {
if(sectionTrain[i].getSectionWordNumber(word) == 1 && sectionTrain[index].getSectionWordNumber(word) > 1) {
advantageResult += (1 - ((double)sectionTrain[index].getSectionWordNumber(word) / sectionTrain[index].getSectionArticleNumber() * 50));
}
else { advantageResult += sectionTrain[i].getSectionWordNumber(word); }
}
}
return advantageResult;
}
// 해당 File 변수ì—� 대한 Index Section ê³¼ì�˜ 매치율ì�„ 보여주는 함수. ë§žì�€ 것과 틀린것, ê·¸ë¦¬ê³ ê·¸ 것ì—� 대한 íŒ�단 í™•ë¥ ì�„ 반환한다.
public void DocumentResult(File f, int index) {
int negaNum = 0;
int posiNum = 0;
CalculateNotInSection(index);
try {
Scanner targetDocument = new Scanner(f);
while(targetDocument.hasNextLine()) {
if(getWeight(index, targetDocument.nextLine()) < 0) { negaNum++; }
else { posiNum++; }
}
targetDocument.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
System.out.println("Right : " + posiNum + " Wrong : " + negaNum + " Result : " + (getLnPsPns(index) + ((double)posiNum / (posiNum+negaNum))));
}
// ìƒ�성ìž�. File 갯수ì—� ë”°ë�¼ ì§€ì •ì�„ 해준다.
public Analyzer(File[] dataList) {
this.sectionTrain = new Trainer[dataList.length];
for(int i = 0; i < sectionTrain.length; i++) {
sectionTrain[i] = new Trainer(dataList[i]);
sectionTrain[i].TrainData();
}
}
}
Runner.java
package org.zeropage.machinelearn;
import java.io.File;
public class Runner {
public static void main(String[] args) {
File[] dbList =
{
new File("svm_data.tar/package/train/economy/index.economy.db"),
new File("svm_data.tar/package/train/politics/index.politics.db"),
};
Analyzer anal = new Analyzer(dbList); // Section ì�´ ë‘�ê°œì�´ë‹ˆ ë‘�개로 ì €ìž¥.
anal.DocumentResult(new File("svm_data.tar/package/test/economy/economy.txt"), 0);
anal.DocumentResult(new File("svm_data.tar/package/test/politics/politics.txt"), 1);
}
}
Train ì�˜ Economy.txt 파ì�¼ ì �중ë�„ : 0.83 (83%)Train ì�˜ Politics.txt 파ì�¼ ì �중ë�„ : 0.94 (94%)
ì „ì²´ í�‰ê· ì �중ë�„ : 0.885 (88.5%)
위ì�˜ 주ì„�처럼 필요없는 (http, //, blog, yahoo, empas, tistory ê°™ì�€) 단어를 ì œì™¸í•˜ê³ ìž‘ì„±í• ìˆ˜ 있게 ìˆ˜ì •í–ˆìŠµë‹ˆë‹¤.
ê°� 단어중 특별한 단어ì—� Advantage 를 부과했는ë�°, 단어가 해당 Section ì—� Unique í•˜ê³ ê·¸ 빈ë�„ê°€ í�´ìˆ˜ë¡� Advantage를 í�¬ê²Œ 부과했습니다. (하지만 ì�´ë�„ ë¶„ì„�한 Sectionì—� ìƒ�대ì �입니다.)
그래서 그런지 결과엔 0.5% 차�밖� 없�군요..
ì�´ 결과를 ë³¼ 수 있었으면 ì¢‹ê² ë„¤ìš” ^^;;










