클로이의 데이터 여행기

[JAVA] 동의어 처리 후 키워드 카운트 알고리즘 (코드 및 설명) 본문

JAVA

[JAVA] 동의어 처리 후 키워드 카운트 알고리즘 (코드 및 설명)

징느K 2019. 8. 16. 08:30

안녕하세요:)

오늘은 자바로 '동의어 처리 후 키워드 카운트하는 알고리즘'에 대해 살펴보려고 합니다.

 

이전에 '키워드 카운트 알고리즘(https://data-traveler.tistory.com/23?category=719589)'은 다룬적이 있는데요.

혹 동의어 처리가 따로 필요없는 데이터라면 위의 포스팅을 활용하시는게 좋겠습니다.

 

 

package highFrequency;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;

public class GetHighFrequencySyn {
	static String[] coreKwd;
	static ArrayList<String> rawList = new ArrayList<String>();
	static ArrayList<String> synList = new ArrayList<String>();
	static ArrayList<String> cleanList = new ArrayList<String>();

	static HashMap<String, Integer> kwdMap = new HashMap<String, Integer>();
	static HashMap<String, Integer> uuqKwdMap = new HashMap<String, Integer>();

	static String NEWLINE = System.getProperty("line.separator");

	// 문장을 공백 단위로 끊어 rawList에 담는 메소드
	public static void getData() {
		File file = new File("C:/data/input/getHighFrequency/test_internet_ner.txt");
		String line = "";
		try {
			BufferedReader inFiles = new BufferedReader(
					new InputStreamReader(new FileInputStream(file.getAbsolutePath()), "UTF8"));
			while ((line = inFiles.readLine()) != null) {
				// 전처리 ② : 핵심역량에서 특수문자를 제거('replace'활용)한 뒤,
				// 라인단위("|*|")로 split하여 키워드를 coreComp에 담음
				coreKwd = line.replace("|*|", " ").replace(".", "").replace("!", "").replace(",", " ")
						.replace("(", " ").replace(")", " ").replace("[", " ").replace("]", " ").replace("/", " ")
						.replace("합니다", " ").split(" ");
				for (int k = 0; k < coreKwd.length; k++) {
					if (coreKwd[k].length() != 0)
						rawList.add(coreKwd[k]);
				}
			}
			inFiles.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// 동의어 사전을 arraylist로 담는 메소드
	public static void getSynDic() {
		File file = new File("C:/data/input/getHighFrequency/syn.txt");
		String synline = "";
		try {
			BufferedReader inFiles = new BufferedReader(
					new InputStreamReader(new FileInputStream(file.getAbsolutePath()), "UTF8"));
			while ((synline = inFiles.readLine()) != null) {
				synList.add(synline.toLowerCase());
			}
			inFiles.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// 키워드 카운트 전 동의어를 대표어로 통일하는 메소드
	public static void changeSyn() {
		for (int k = 0; k < rawList.size(); k++) {
			String rawKwd = rawList.get(k).toLowerCase();
			for (int j = 0; j < synList.size(); j++) {
				if (synList.get(j).contains(rawKwd)) {
					String[] syn = synList.get(j).split(",");
					for (int i=0; i<syn.length; i++) {
						if(syn[i].equals(rawKwd)) {
							if (rawKwd == syn[0]) {
								continue;
							} else {
								rawKwd = syn[0];
							}
						}
					}
				}
			}
			cleanList.add(rawKwd);
		}
	}

	// 키워드 카운트를 하는 메소드
	public static void getKwdCnt() {
		int cnt = 1;

		for (int k = 0; k < cleanList.size(); k++) {
			if (kwdMap.containsKey(cleanList.get(k))) {
				cnt = kwdMap.get(cleanList.get(k)) + 1;
			} else {
				cnt = 1;
			}
			kwdMap.put(cleanList.get(k), cnt);
		}
	}

	// 파일 작성하는 메소드
	public static void writeFile() {
		String filename = "C:/data/output/getHighFrequency/test_internet_ner_title_cleankwd_Frq.txt";
		try {
			File output = new File(filename);
			BufferedWriter writer = new BufferedWriter(new FileWriter(output));

			if (output.isFile() && output.canWrite()) {
				for (String key : kwdMap.keySet()) {
					// if (coreCntMap.get(key) > 20) {

					StringBuilder sb = new StringBuilder();
					sb.append(key);
					sb.append(",");
					sb.append(kwdMap.get(key));
					sb.append(NEWLINE);

					String resultString = sb.toString();
					writer.write(resultString);
					// }
				}
			}
			writer.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		getData();
		getSynDic();
		changeSyn();
		getKwdCnt();
		writeFile();
		System.out.println("END");
	}
}

 

 

코드는 메소드 3개로 구성되어 있으며 내용은 메소드별 설명은 아래와 같습니다.

 

① getData()

 - 메소드 기능 : 문장을 공백 단위로 끊어 rawList에 담음.

 - 상세내용 : 대체/제거하고 싶은 특수문자 처리한 뒤, 문장을 공백으로 spilt하여 rawList로 담음.

 

② getSynDic()

 - 메소드 기능 : 핵심역량 키워드의 카운트.

 - 상세내용 : rawList에 중복으로 담겨있는 키워드를 뽑아와서 coreCntMap<키워드,카운트>로 담음.

              이 때, coreCntMap에 이미 담겨있으면 카운트(value)에 1을 더함.  

 

③ changeSyn()

- 메소드 기능 : 키워드 카운트 전 동의어를 대표어로 통일.

- 상세내용 :  rawList를 하나씩 불러와서 대표어가 아닌 동의어 일때, 해당 키워드를 대표어로 치환.

 

 

④ getKwdCnt()

- 메소드 기능 : 동의어 사전을 arrayList로 담는 메소드.

- 상세내용 : 동의어 사전을 한 줄씩 불러와서 synList에 담음.

 

 

⑤ writeFile()

- 메소드 기능 : 파일을 작성하는 메소드

- 상세내용 : <키워드,카운트>가 담긴 맵을 파일로 작성.

 

이상입니다.

좀 더 효율적인 방법이 있을 것 같다는 생각이 마구마구 드는 코드이지만(ㅋㅋ) 일단 기록으로 남겨두려고 합니다.

추후에 보완해보도록 하겠습니다.

 

감사합니다 '◡'

 

 

 

Comments