약 2년전 HMM 라이브러리를 공개한 적이 있습니다.


2년이 지난 지금도 많은 분들이 관련 내용에 대해서 문의를 주십니다.


또한 소스 요청도 종종 받고 있습니다. 이름, 소속 및 사용 용도를 메일로 보내주신 분에 한하여 소스를 드렸습니다. 


2년이라는 시간이 흘렀지만 보잘것 없는 라이브러리를 지금도 찾아주셔서 감사하기도 하고 한편으로는 저 자신에게 부끄럽기도 합니다. 


용기를 내어서 소스를 공개하고자 합니다.


사용법은 소스 내에 있는 toy example을 참고하시면 될 것 같습니다.



hmm_shineware_2.0.zip


또한 아래 페이지에서도 다운로드 가능합니다.


git : https://github.com/shin285/HMM


나름대로 안정화를 많이 시켰지만 부족한 부분이 많이 있습니다.


이와 관련하여 피드백을 주시면 반영하도록 하겠습니다. 감사합니다.

'Opensource > Shineware' 카테고리의 다른 글

자바 HMM 라이브러리 소스 공개  (1) 2014.11.13
[FileUtil] 자바 파일 읽기  (2) 2012.11.06
자바 HMM 라이브러리  (20) 2012.10.31
형태소 분석기 오픈소스  (2) 2012.10.31
  1. 대학원생 2016.01.06 18:06 신고

    공개 정말 감사드립니다. 비슷한 모델을 공부중으로 HMM 구현에 레퍼런스로 삼을만한 소스코드를 찾고 있었습니다. 정말 감사합니다

먼저 루씬은 참 쓰기 편하면서도 커스터마이징하기는 참 불편한 특징을 갖고 있습니다. (물론 제 수준상으로...)


그래서 루씬을 이용해서 쓰기 편하게(?) 나름대로 만들어봤습니다.


지금부터 루씬을 이용해서 기본적인 검색기를 뚝딱 만들어보겠습니다.


먼저 색인할 데이터를 다운 받습니다.


[트윗 데이터]


data.zip



위 파일은 JSON 형태의 트윗을 모아둔 파일로 압축을 풀면 약 45M 정도가 됩니다.


먼저 이 데이터를 원하시는 경로에 풀어둡니다.


저는 D:/tweet/ 에 압축을 풀겠습니다.


트윗을 담기 위한 객체를 만들어 둡니다.


객체 이름은 당연히 Tweet으로 하고 소스 내용은 아래와 같습니다.



package kr.peopleware.lucene.model;

import java.util.List;

import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.NumericField;

public class Tweet extends BaseModel{
	private long tweetId;
	private String contents;
	private long createdAt;
	private long crawledAt;	
	private boolean linked;
	private List<String> urls;	
	public long getTweetId() {
		return tweetId;
	}
	public void setTweetId(long tweetId) {		
		this.tweetId = tweetId;
	}
	public String getContents() {
		return contents;
	}
	public void setContents(String contents) {
		this.contents = contents;
	}
	public long getCreatedAt() {
		return createdAt;
	}
	public void setCreatedAt(long createdAt) {
		this.createdAt = createdAt;
	}
	public long getCrawledAt() {
		return crawledAt;
	}
	public void setCrawledAt(long crawledAt) {
		this.crawledAt = crawledAt;
	}	
	public boolean isLinked() {
		return linked;
	}
	public void setLinked(boolean linked) {
		this.linked = linked;
	}
	public List<String> getUrls() {
		return urls;
	}
	public void setUrls(List<String> urls) {
		this.urls = urls;
	}
	@Override
	public Document convetDocument() {
		Document doc = new Document();
		NumericField createdAt = new NumericField("createdAt",Field.Store.YES,true);
		createdAt.setLongValue(this.getCreatedAt());		
		doc.add(createdAt);		
	
		
		NumericField tweetId = new NumericField("tweetId",Field.Store.YES,false);		
		tweetId.setLongValue(this.getTweetId());
		doc.add(tweetId);
		
		String type = "all";
		if(this.getUrls() == null || this.getUrls().size() == 0){
			type="link";
		}
		
		doc.add(new Field("type",type,Field.Store.NO,Field.Index.NOT_ANALYZED));
		if(this.getUrls() != null){
			doc.add(new Field("urls",this.getUrls().toString(),Field.Store.YES,Field.Index.NOT_ANALYZED));
		}		
		doc.add(new Field("contents", this.getContents(), Field.Store.YES, Field.Index.ANALYZED));
		return doc;
	}	
}


이때 BaseModel을 익스텐드 시켜서 사용했는데 BaseModel은 아래와 같습니다.


package kr.peopleware.lucene.model;

import org.apache.lucene.document.Document;

public abstract class BaseModel {
	public abstract Document convetDocument();
}

BaseModel은 Tweet이란 객체를 루씬 색인에 사용할 수 있게끔 Document로 변환시켜주는 역할을 합니다.


그럼 이제 데이터를 담아둘 객체는 생성이 끝났습니다.


이제 데이터를 가져오는 부분을 만들어 보겠습니다.


간단히 만들기 위해서 main 클래스 내에 getTweets라는 메소드를 만들겠습니다.


이 메소드는 주어진 경로에 따라서 데이터를 List 형태로 반환하는 역할을 합니다.





	private static List<Tweet> getTweets(String path) {
		List<Tweet> tweetList = new ArrayList<Tweet>();
		List<String> filenames = FileUtil.getFileNames(path);

		for (String filename : filenames) {
			List<String> lines = null;
			try {
				lines = FileUtil.load2List(filename);
			} catch (Exception e) {
				e.printStackTrace();
			}
			if(lines == null){
				continue;
			}
			for (String line : lines) {

				Tweet t = convertTweet((DBObject) JSON.parse(line));				

				tweetList.add(t);
			}
			//			System.out.println(filename);
		}
		return tweetList;
	}


여기서 주어진 path로부터 데이터를 한줄 한줄 가져오게 됩니다. 이 때 각 한줄 한줄을 Tweet이라는 객체로 변환 시켜야합니다. 그래서 convertTweet이라는 메소드를 생성하여 변환시켜줍니다. JSON 형태를 Tweet이라는 객체로 변환시켜주는 역할을 합니다. 그리고 JSON.parse는 몽고디비 라이브러리에서 제공하는 유틸리티입니다. 


convertTweet역시 귀찮기 때문에 main 클래스 내에 만들겠습니다.



	private static Tweet convertTweet(DBObject obj) {		
		Tweet tweet = new Tweet();
		tweet.setTweetId((Long) obj.get("tweetId"));
		tweet.setContents((String) obj.get("contents"));		
		tweet.setCreatedAt((Long) obj.get("createdAt"));
		tweet.setCrawledAt((Long) obj.get("crawledAt"));
		tweet.setLinked((Boolean)obj.get("linked"));
		@SuppressWarnings("unchecked")
		List<String> urls = (List<String>) obj.get("urls");
		if(urls != null){
			tweet.setUrls(urls);
		}				

		return tweet;
	}


그럼 여기까지 데이터를 가져와서 객체에 담는것 까진 완성이 되었습니다.


그럼 이제 실제 색인을 해보도록 하겠습니다. 


이 글에서는 루씬을 해부하는 것이 아니라 루씬을 이용한 검색기를 만드는 것이 중요하기 때문에 루씬 자체에 대한 사용방법은 이 글에서는 생략하겠습니다.


먼저 위에 getTweets와 convertTweet이 포함된 메인 클래스 입니다.



package kr.peopleware.lucene.index.test;

import java.util.ArrayList;
import java.util.List;

import kr.peopleware.lucene.index.Indexer;
import kr.peopleware.lucene.index.properties.PropertiesManager;
import kr.peopleware.lucene.model.Tweet;
import kr.peopleware.util.file.FileUtil;

import org.apache.lucene.analysis.cjk.CJKAnalyzer;
import org.apache.lucene.util.Version;

import com.mongodb.DBObject;
import com.mongodb.util.JSON;

public class IndexTester {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		PropertiesManager pm = new PropertiesManager("index.properties");
		Indexer indexer = new Indexer(new CJKAnalyzer(Version.LUCENE_36),"index.properties");		
		List<Tweet> tweetList = getTweets(pm.getProperty("TARGET_PATH"));			
		for (Tweet tweet : tweetList ) {
			indexer.index(tweet);
		}
		indexer.commit();
		indexer.close();
	}

	private static List<Tweet> getTweets(String path) {
		List<Tweet> tweetList = new ArrayList<Tweet>();
		List<String> filenames = FileUtil.getFileNames(path);

		for (String filename : filenames) {
			List<String> lines = null;
			try {
				lines = FileUtil.load2List(filename);
			} catch (Exception e) {
				e.printStackTrace();
			}
			if(lines == null){
				continue;
			}
			for (String line : lines) {

				Tweet t = convertTweet((DBObject) JSON.parse(line));				

				tweetList.add(t);
			}
			//			System.out.println(filename);
		}
		return tweetList;
	}
	private static Tweet convertTweet(DBObject obj) {		
		Tweet tweet = new Tweet();
		tweet.setTweetId((Long) obj.get("tweetId"));
		tweet.setContents((String) obj.get("contents"));		
		tweet.setCreatedAt((Long) obj.get("createdAt"));
		tweet.setCrawledAt((Long) obj.get("crawledAt"));
		tweet.setLinked((Boolean)obj.get("linked"));
		@SuppressWarnings("unchecked")
		List<String> urls = (List<String>) obj.get("urls");
		if(urls != null){
			tweet.setUrls(urls);
		}				

		return tweet;
	}

}


메인클래스에서 보면 "index.properties"라는 인자를 사용하게 됩니다.


이는 properties에서 색인 할 데이터의 경로, 색인이 저장될 경로등을 설정하기 위한 것입니다.


index.properties 파일 내용을 살펴보면




	SHUTDOWN	=	false	
	TARGET_PATH	=	D://tweet
	INDEX_PATH	=	D://tweetIndex
	
	#open mode (create,append,create_or_append)
	OPEN_MODE	=	create
	
	#merge setting
	MERGE_POLICY	=	true
	MAX_MERGE_AT_ONCE	=	100
	SEGMENTS_PER_TIER	=	100


아래 merge setting은 루씬과 직접적인 관계가 있는 설정입니다만, 기본적인 검색기를 만드는데는 그냥 저 값을 사용해도 무방합니다.


SHUTDOWN은 추후에 실시간 색인을 위한 옵션으로 현재는 사용하지 않습니다.


TARGET_PATH는 아까 data.zip의 압축을 푼 경로를 적습니다.


INDEX_PATH는 색인 데이터가 저장될 공간으로 원하는 곳에 경로를 적어주시면 됩니다.


OPEN_MODE는 색인기를 실행시에 기존 데이터를 새로 덮어쓸지(create), 기존 데이터에 추가 할 지(append)의 여부를 나타냅니다.


위 설정 파일의 설정을 마치면 이제 실행만 시키면 색인이 완료됩니다.




======================= 색인 끝 ======================




색인이 완료된 후 색인된 데이터를 검색해보도록 하겠습니다.


검색은 매우 심플합니다.



package kr.peopleware.lucene.search.test;

import java.util.Date;

import kr.peopleware.lucene.search.Searcher;
import kr.peopleware.lucene.util.QueryBuilder;

import org.apache.lucene.analysis.cjk.CJKAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.util.Version;

public class SearchTester {

	/**
	 * @param args
	 */
	public static void main(String[] args) {	
		
		//설정 파일을 세팅하여 Searcher 생성
		Searcher search = new Searcher("search.properties");
		
//		search.setSort("tweetId",SortField.LONG,true);
		
		//색인된 데이터의 contents에 "감기"라는 검색어를 넣어서 검색
		Document[] docs = search.getDocuments(QueryBuilder.makeQuery("contents", "감기",new CJKAnalyzer(Version.LUCENE_36)));

		int count = 0;
		for (Document document : docs) {
			if(count == 10)break;
			System.out.println("["+count+"]");			
			System.out.println(document.get("urls"));
			System.out.println(document.get("tweetId"));
			Date date = new Date(Long.parseLong(document.get("createdAt")));
			System.out.println(date);
			System.out.println(document.get("contents"));
			System.out.println();
			count++;
		}
		System.out.println(docs.length);
		search.close();
	}

}


역시 search.properties란 파일을 사용하는데 search.properties에는 아래와 같이 색인 파일의 경로만이 저장되어있습니다.



	INDEX_PATH	=	D://tweetIndex


또한 QueryBuilder라는 static 메소드가 있는데 이는 질의어를 만들어주기 위한 메소드입니다. 


소스 내용은 아래와 같습니다만, 굳이 보실 필요는 없을 것 같습니다.



package kr.peopleware.lucene.util;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.NumericRangeQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.QueryTermVector;
import org.apache.lucene.search.TermQuery;

public class QueryBuilder {
 	public static Query makeQuery(String field,String q,Analyzer analyzer)
	{
		BooleanQuery bq = new BooleanQuery();
		QueryTermVector qtv = new QueryTermVector(q, analyzer);
		for(int i=0;i<qtv.size();i++)
		{
			bq.add(new TermQuery(new Term(field,qtv.getTerms()[i])), BooleanClause.Occur.MUST);
		}
		return bq;
	}
 	public static Query makeQuery(String field, Object a,Object b){
		Query nq = null;
		if(a.getClass() == Integer.class){
			nq = NumericRangeQuery.newIntRange(field, (Integer)a, (Integer)b, true, true);
			
		}else if(a.getClass() == Double.class){
			nq = NumericRangeQuery.newDoubleRange(field, (Double)a, (Double)b, true, true);
			
		}else if(a.getClass() == Float.class){
			nq = NumericRangeQuery.newFloatRange(field, (Float)a, (Float)b, true, true);
			
		}else if(a.getClass() == Long.class){
			nq = NumericRangeQuery.newLongRange(field, (Long)a, (Long)b, true, true);
			
		}
		return nq;
	}
}


이제 검색을 해보면 아래와 같은 결과를 보실 수 있습니다.





이클립스 프로젝트 파일도 함께 올려두겠습니다.


[루씬 프로젝트 파일]


lucene.zip


[루씬 프로젝트를 사용하는데 필요한 라이브러리]


common.zip



기본적인 검색 엔진은 이제 만들 수 있습니다만,


한글 검색 엔진은 "색인어 추출기"가 핵심이라고 말씀드릴 수 있습니다.


시간이 나는대로 형태소 분석기를 마무리 지어서 공개하도록 하겠습니다.

'Opensource > Lucene' 카테고리의 다른 글

루씬 기본적인 검색 엔진  (7) 2012.11.06
루씬 한글 검색 엔진 제작  (0) 2012.11.06
  1. darkly0828@naver.com 2013.01.15 14:59 신고

    글 잘 보았습니다. 많은 도움이 되네요~

  2. 안상준 2014.07.14 11:53 신고

    죄송하지만 Common page 를 어떻게 임포트 해야하는지 ;;;;;;;;;;;;;;;; 다른놈들은 에러없이 다 그냥 나오는데 kr.peopleware.util.file.FileUtil;
    이놈이 임포트 에러 뜨네요 폴더 자체를 Libarary 추가 해줫는데 해결이 안되네요 ㅠㅠ

    • shine_ing 2014.07.21 12:28 신고

      common도 별개의 프로젝트입니다. 그렇기 때문에 프로젝트 형식으로 import 해주시고 이클립스(를 사용하신다는 가정 하에)에서 빌드패스 부분에서 프로젝트를 통째로 잡아주시면 됩니다. 그래도 안되신다면 댓글 부탁드립니다~

  3. 2014.11.25 01:28

    비밀댓글입니다

  4. 아롱사태남 2014.11.25 01:29 신고

    안녕하세요 ^^ 요즘 오프소스에 관심이 많은 신입 개발자입니다.
    오픈소스 검색엔진에 대하여 검색하다가 루씬과 국내에서 개발한 패스트캣서치가 있던데
    신입인 저에게는 어떤걸로 먼저 뛰어드는게 좋을까요?
    루씬 단점은 한글 분석기가 지원이 안되고 초보자는 만들기 어렵다고 하더라구요 ㅜ
    패스트캣서치 단점은 국내에서 개발한지 별로되지않아 컴폼 받기가 힘들구요...
    사용해보시면서 루씬의 단점이라고 느겼던점과 장점을 가르쳐주셨으면 좋겠어요 그리고
    신입이라면 루씬을 도전해야할지 패스트캣서치를 도전해야할지 가르쳐주세요 !!

    • shine_ing 2014.11.25 09:51 신고

      저도 사실 루씬과 패스트캣 서치에 대해서 잘 알지는 못합니다만, 패스트캣서치가 루씬 베이스로 동작하기 때문에 아마 루씬을 먼저 보는게 낫지 않을까요? 그러나 업무상 적용할 용도라면 패스트캣서치가 훨씬 편리할 듯 보이네요

위치


kr.peopleware.util.common.file


소스


/**

 * 입력된 파일의 내용을 라인별 List 형태로 반환

 * @param filename 읽어들일 파일 이름

 * @param encoding 읽어들일 파일의 인코딩

 * @return 파일의 한라인씩 순차적으로 저장된 리스트

 */

public static List<String> load2List(String filename,String encoding){         

       BufferedReader br;

       List<String> resultList = new ArrayList<String>();

       try {

             br = new BufferedReader(new InputStreamReader(new FileInputStream(filename), encoding));

             String line;

             while ((line = br.readLine()) != null) {

                    resultList.add(line);

             }

             br.close();        

       } catch (Exception e) {

             e.printStackTrace();

       }

        

       return resultList;

}

 

/**

 * 입력된 파일의 내용을 라인별 List 형태로 반환

 * @param filename 읽어들일 파일 이름 (기본 인코딩 형식은 UTF-8)

 * @return 파일의 한라인씩 순차적으로 저장된 리스트

 */

public static List<String> load2List(String filename){            

       return load2List(filename,"UTF-8");

}




사용법


List<String> lines = FileUtil.load2List("www.com.001", "EUC-KR");

for (String line : lines) {

       System.out.println(line);

}

'Opensource > Shineware' 카테고리의 다른 글

자바 HMM 라이브러리 소스 공개  (1) 2014.11.13
[FileUtil] 자바 파일 읽기  (2) 2012.11.06
자바 HMM 라이브러리  (20) 2012.10.31
형태소 분석기 오픈소스  (2) 2012.10.31
  1. 홍수몬 2012.11.16 16:07 신고

    이걸 말한게 아닙니다 선배님

국내에서 루씬을 사용하는 검색 솔루션 업체가 상당히 많이 늘어나고 있습니다.


물론 분산 검색을 위해서 루씬을 포함하고 있는 Solr를 사용하는 업체도 늘어나고 있습니다.


물론 제가 루씬 검색 엔진을 제작한다고 하더라도 눈여겨볼 사람은 많지 않습니다.


단지 제가 하고 싶은건 검색 엔진의 이해가 아닌 검색 엔진의 활용 방안입니다.


검색 엔진을 이해하려면 사실 루씬의 색인 파일구조를 살펴봐야 합니다.


그러나 웬만한 실력이 아니고서야 ( 저를 포함 ) 그 어려운 소스를 뜯어서 파일을 분석해낸 후 자기 것으로 이해시키기에는 어려움이 있을 것입니다.


그래서 일단은 루씬을 이용해서 검색엔진을 만들어보고,


추후에 검색과 관련된 내용을 포스팅 할까 합니다.


제가 만들 내용은 "루씬을 이용한 실시간 분산 검색 엔진"입니다.


실제로 만드는 과정을 하나하나 포스팅 할테니 많은 지적부탁드립니다.

'Opensource > Lucene' 카테고리의 다른 글

루씬 기본적인 검색 엔진  (7) 2012.11.06
루씬 한글 검색 엔진 제작  (0) 2012.11.06

직접 구현한 HMM 라이브러리를 오픈소스로 공개하려 합니다.


사용방법은 첨부된 pdf 파일을 참조해주시기 바랍니다.


개발실력이 거의 없다고 보시면됩니다.


그러나 연구 및 개발을 하는데 있어서 HMM을 잘 모르는데 만들어야하는 고충에 빠지신 분들과 


아직 학교에서 연구에 매진중인 미래의 연구자 분들께서 사용하셨으면 좋겠습니다.


문의사항은 이메일이나 댓글로 남겨주시면 확인하는대로 답변드리겠습니다.



peopleware-common 라이브러리는 hmm 구동에 필요한 내부 라이브러리로 사용되고 있습니다.


반드시 함께 import하여 사용해주시기 바랍니다.



.jar 파일


peopleware-common-0.1.9.jar


peopleware-hmm-0.0.3.jar


설명서



HMM Library.pdf



https://github.com/shin285/HMM 에 가시면 다운로드 하실 수 있습니다.


'Opensource > Shineware' 카테고리의 다른 글

자바 HMM 라이브러리 소스 공개  (1) 2014.11.13
[FileUtil] 자바 파일 읽기  (2) 2012.11.06
자바 HMM 라이브러리  (20) 2012.10.31
형태소 분석기 오픈소스  (2) 2012.10.31
  1. 고요한고흐 2013.05.28 11:22 신고

    안녕하세요
    학교에 재학중인 대학생입니다
    HMM알고리즘을 공부하다가 이런 좋은 라이브러리를 발견하게 되어
    소스코드를 받아볼 수 있을까 해서 이렇게 글을 씁니다 ㅎㅎ
    시간이 되시면 anstnzja@nvaer.com 로 보내주시면 감사합니다 ㅎㅎ

    • shine_ing 2013.05.28 11:27 신고

      안녕하세요. 반갑습니다^^
      금일 밤에 보내드리도록 하겠습니다~

  2. MinjuneLee 2013.06.04 20:41 신고

    안녕하세요.
    대학교에서 컴퓨터 공학을 전공 중인 학생입니다.
    개인적으로 HMM 알고리즘의 구현에 대해서 알고 싶어서
    소스를 받고 싶은데,,,,
    윗 분 처럼 메일로 좀 보내주시면 안될까요?
    tlsdmq12@gmail.com
    입니다. 부탁드려요 ㅎㅎ

    • shine_ing 2013.06.04 22:58 신고

      안녕하세요. 반갑습니다^^
      개인적인 사정으로 금주는 조금 어려울 것 같습니다. 다음주에 바로 쏴드리겠습니다^^;

  3. 2013.07.08 00:52

    비밀댓글입니다

  4. soy 2013.07.30 15:55 신고

    안녕하세요 대학교에서 컴퓨터전공 공부를 하고 있는 학생입니다.
    좋은 라이브러리를 공개해주셔서 감사합니다^^
    알고리즘 구현에 대해 좀더 자세히 알고싶어서 그러는데 혹시 소스를 받을 수 있을까요?
    jiyun0681@naver.com 입니다. 부탁드립니다^^

  5. Akira 2013.09.05 11:53 신고

    안녕하세요..
    HMM 관련하여 연구를 진행하고 있으면서, 많은 도움을 받고 있어 감사드립니다.
    논문을 진행하는데 있어 필요한 HMM에 대해서 자바 코드를 도움받고자 글을 남기게되었습니다.
    akira107@naver.com 으로 보내주시면 감사하겠습니다.
    쾌차를 바랍니다.

  6. 2013.10.01 17:28

    비밀댓글입니다

  7. si 2013.10.18 23:43 신고

    안녕하세요 HMM관련 연구를 진행중인 학생입니다.
    라이브러리를 오픈소스로 공개해 주셔서 많은 도움이될 것 같습니다.
    알고리즘 구현한 부분도 가능하다면 참고하고 싶습니다.
    tony07ysi@nate.com으로 보내주시면 감사하겠습니다.

    • shine_ing 2013.10.25 00:57 신고

      안녕하세요. 먼저 이렇게 찾아와주셔서 감사를 드립니다. 위의 내용에도 기술한것처럼 이름과 소속을 말씀해주시면 확인후에 소스를 보내드리겠습니다. 모 기업의 사원이 학생인척 현재 소스를 그대로 업무에 사용하여 서로 곤란했던 적이 있었기 때문에 이러한 간단한 인증(?)이 필요하게 되었습니다. 양해부탁드립니다.

  8. 2013.10.25 18:51

    비밀댓글입니다

  9. 2014.01.02 16:25

    비밀댓글입니다

  10. 2014.01.09 16:17

    비밀댓글입니다

  11. 랏드 2014.04.25 17:18 신고

    안녕하세요, 현직 프로그래머인데 최근 HMM에 관심있어서 개인적으로 연구를 진행중에 있습니다.
    이론적으로는 이해가 되는데, 실제 구현이 궁금합니다. 혹시 자바 코드를 받을 수 있을까요?
    148eur@gmail.com 으로 보내주시면 고맙겠습니다.

  12. 2014.11.07 16:49

    비밀댓글입니다

  13. 2014.11.10 14:14

    비밀댓글입니다

  14. 2016.01.26 22:07

    비밀댓글입니다

  15. 2016.03.15 17:34

    비밀댓글입니다

  16. toson90 2016.05.31 13:35 신고

    안녕하십니까. 단국대학교에서 공부중인 학생입니다. 생체신호 패턴인식과 관련되어 공부중입니다. 라이브러리 및 문서를 보고 혹시 소스가 오픈소스인지, 오픈소스라면 혹시 소스코드를 구할수 있는지 문의드리고 싶습니다.
    가능하다면 tooson9010@naver.com으로 받을수 있는지 궁금합니다. 감사합니다.

    • shine_ing 2016.05.31 13:37 신고

      안녕하세요. 본문에 작성되어 있는 링크 https://github.com/shin285/HMM에 가시면 소스 코드를 다운로드 받으실 수 있습니다. 감사합니다.

국내에는 공개적으로 사용가능한 형태소 분석기가 몇개 없습니다.


자연어처리를 전공한 사람으로써 매우 안타깝다고 생각하고 있었습니다.


비록 성능은 좋지 못하지만 기본에 충실한 어절 단위 형태소 분석기를 오픈 소스로 공개하려합니다.


유능한 개발자 분들이 만들어두신 형태소 분석기도 있지만


사전이 잘못 됐는지는 모르겠으나 대부분 명사로 추출되는 경향이 강했습니다.


물론 루씬과 같은 검색기에서 주로 사용되는 품사는 명사류입니다만,


엄연히 말하자면 형태소 분석기와 색인기(명사 추출기)는 다르다고 말씀드리고 싶습니다.


비록 개발능력은 떨어지지만 고전 방식의 형태소 분석기를 제공하도록 하겠습니다.


다양한 분야에서 널리 사용되었으면 하는 작은 바람입니다.

'Opensource > Shineware' 카테고리의 다른 글

자바 HMM 라이브러리 소스 공개  (1) 2014.11.13
[FileUtil] 자바 파일 읽기  (2) 2012.11.06
자바 HMM 라이브러리  (20) 2012.10.31
형태소 분석기 오픈소스  (2) 2012.10.31
  1. 남호성 2015.05.24 16:29 신고

    안녕하세요 대학에서 컴퓨터 공부중인 학생입니다.
    한글 리뷰 분석 프로그램을 만들기 위해 필요한 api를 알아보던중 이글을 보게 되었습니다. 혹시 소스를 얻을수 있을까 해서 글남깁니다

+ Recent posts