2012-10-27 2 views
0

나는 약 1500 개의 문서 모음을 가지고 있습니다. 각 문서를 파싱하고 토큰을 추출합니다. 이러한 토큰은 해시 맵 (키)으로 저장되고 컬렉션에서 발생하는 총 횟수 (즉, 빈도)는 값으로 저장됩니다.Java 논리에서 역 색인 작성

역 색인을 만들기 위해 이것을 확장해야합니다. 즉, 용어 (키) | 발생하는 문서의 수 -> DocNo | 해당 문서의 빈도. 부여 됨으로써,

Term  DocFreq DocNum  TermFreq 
    data   3   1   12 
          23   31 
          100   17 
    customer  2   22   43 
          19   2 

현재, 나는

hashmap<string,integer> 
for(each document) 
{ 
    extract line 
    for(each line) 
    { 
     extract word 
     for(each word) 
     { 
      perform some operations 
      get value for word from hashmap and increment by one 
     } 
    } 
} 

이 코드에 구축해야, 자바에서 다음 있습니다. 역 색인을 구현하는 좋은 방법을 생각할 수는 없습니다. 지금까지 저는 2D 배열을 가치있게 생각했습니다. 따라서 용어가 핵심이며 값 (즉, 2D 배열)은 docId 및 termFreq를 저장합니다.

제 논리가 정확한지 알려주세요.

+1

나는 당신이하고 싶은 것을 이해하지 못한다. DocFreq, DocNum 및 TermFreq는 무엇입니까? 역 색인의 키와 값은 무엇이되어야합니까? –

+0

문서 모음이 있습니다. 각 문서를 분석하고 각 단어를 추출합니다. 이제 각각의 단어에 대해 다음 정보를 저장/계산해야합니다 : 용어 (단어), DocFreq (이 특정 단어가 나오는 문서의 수) -> DocNum 및 TermFreq (문서 ID 및 발생 빈도 그 문서에서). 예를 들어, '데이터'라는 단어는 3 (DocFreq) 문서에서 발생합니다. 이 3 개의 문서는 1,2,3,100 (DocNum)이며 DocNum 1의 'data'는 12 회 (TermFreq) 발생합니다. DocNum 23에서는 '데이터'가 31 회 발생하고 DocNum 100에서는 '데이터'가 17 회 발생합니다. – aquafatz

답변

1

Map<docnum, Map<term,termFreq>>Map<term, Set<docnum>>의 두 가지 구조가 가장 바람직하다고 생각합니다. docFreqs는 두 번째 맵의 값에서 set.size으로 읽을 수 있습니다. 이 솔루션에는 사용자 지정 클래스가 없으므로 필요한 모든 항목을 빠르게 검색 할 수 있습니다.

첫 번째지도에는 모든 정보 제공 물이 포함되어 있으며 두 번째지도 정보는 용어로 빠른 검색을 허용하는 파생물입니다. 문서를 처리 할 때 첫 번째 맵을 채 웁니다. 이후에 두 번째 맵을 파생시킬 수는 있지만 한 번에 쉽게 수행 할 수 있습니다.

+0

감사합니다. 정말 단순화 된 것입니다. 첫 번째 맵 인 Map >을 만들었습니다. 하지만 두 번째 맵을 만들려면 어떻게해야합니까? – aquafatz

+0

글쎄, 당신이 문서에서 발생하는 각 용어에 대해, 그 문서를 용어의 키 아래 집합에 추가하기 만하면됩니다. 이미 termFreq를 업데이트하는 것과 같은 종류의 논리입니다. 'Set '을 사용하고 있기 때문에, 중복 파일은 자동으로 거부됩니다. –

+0

알았습니다! 고맙습니다!! – aquafatz

3

Map<String, TermFrequencies>을 사용하면됩니다. 이지도는 발견 된 각 용어에 대해 TermFrequencies 객체를 유지합니다. TermFrequencies 객체는 다음과 같은 방법을 것이다 :

void addOccurrence(String documentId); 
int getTotalNumberOfOccurrences(); 
Set<String> getDocumentIds(); 
int getNumberOfOccurrencesInDocument(String documentId); 

그것은 용어가 문서의 용어의 발생 횟수에 발생하는 각 문서를 연결하는 데 내부적으로 Map<String, Integer>을 사용합니다.

알고리즘은 매우 간단 할 것 :

for(each document) { 
    extract line 
    for(each line) { 
     extract word 
     for(each word) { 
      TermFrequencies termFrequencies = map.get(word); 
      if (termFrequencies == null) { 
       termFrequencies = new TermFrequencies(word); 
      } 
      termFrequencies.addOccurrence(document); 
     } 
    } 
} 

addOccurrence() 방법은 단순히 사건의 총 수에 대한 카운터를 증가 것이며, 삽입하거나 internam 맵에서 발생 횟수를 업데이트 할 것입니다.

+0

이것은 위대합니다. 하지만 난 해시 맵에 익숙하지 않아 객체로 값을 다뤄 본 적이 없다. 가능하다면 더 설명해 주시겠습니까? 감사합니다. – aquafatz

+0

HashMap은 값으로 객체 만 가질 수 있습니다. TermFrequencies의 인스턴스를 값으로 HashMap에 저장하는 것은 String 또는 Integer 인스턴스를 저장하는 것과 다르지 않습니다. 너는 무엇에 문제가 있니? –

0

한 번 당신이 요구하는 것을 구현했습니다. 당신의 접근법에 대한 문제점은 추상적이지는 않다는 것입니다. 객체를 사용하여 용어, 문서 및 관계를 모델링해야합니다. 첫 번째 실행에서는 용어 색인 및 문서 객체를 만들고 용어 색인을 채우는 동안 문서의 모든 용어를 반복합니다. 그 다음에는 원하는 출력으로 쉽게 변형 할 수있는 메모리 표현이 있습니다. 객체 지향 언어에서 2 차원 배열을 생각하지 마십시오. 수학적 문제를 해결하거나 무언가를 최적화하고 싶지 않다면 대부분의 경우 올바른 접근 방식이 아닙니다.

+0

예 .. 여기 JB가 설명했던 것 같습니다. 맞습니까? 감사합니다. – aquafatz

0

나는이 여전히 뜨거운 질문 인 경우 몰라요,하지만 난 이런 식으로 작업을 수행 할 추천 :

당신은 모든 문서를 통해 실행하고 증가하는 순서로 그들에게 ID를 제공합니다. 각 문서에 대해 모든 단어를 실행합니다.

문자열 (단어)을 DocTermObjects 배열에 매핑하는 해시 맵이 있습니다.DocTermObject는 docId와 TermFrequency를 포함합니다.

문서의 각 단어에 대해 작성한 DocTermObjects 배열이 포함되어 있지 않으면 HashMap에서 찾은 다음 그렇지 않으면 매우 마지막 요소 만 봅니다 (이는 런타임 때문에 중요합니다). 생각 해봐.) 이 요소에 현재 처리중인 docId가 있으면 TermFrequency가 증가합니다. 또는 Array가 비어 있으면 실제 DocId와 함께 새 DocTermObject를 추가하고 TermFrequency를 1로 설정합니다.

나중에이 데이터 구조를 사용하여 예를 들어 점수를 계산할 수 있습니다. DoctermObjects에 저장할 수있는 점수도 있습니다.

도움이 되었으면 좋겠다.

관련 문제