문제

꽤 일반적인 상황, 나는 베팅 할 것입니다. 귀하는 블로그 나 뉴스 사이트가 있으며 많은 기사 나 블래그 또는 귀하가 부르는 모든 것을 가지고 있으며, 각각의 맨 아래에는 관련이있는 것으로 보이는 다른 사람들을 제안합니다.

각 항목에 대한 메타 데이터가 거의 없다고 가정 해 봅시다. 즉, 태그, 카테고리가 없습니다. 제목과 저자 이름을 포함하여 하나의 큰 텍스트로 취급하십시오.

관련 문서를 찾는 방법은 무엇입니까?

Ruby 또는 Python에서 구현 된 것을 보거나 MySQL 또는 PGSQL에 의존하는 것이 좋습니다.

편집하다: 현재 대답은 꽤 좋지만 더보고 싶습니다. 어쩌면 어떤 일에 대한 예제 코드 일 수도 있습니다.

도움이 되었습니까?

해결책

이것은 사람들이 여기에서 제시 한 답변 외에도 몇 가지 정보 검색 수업을 위해 음절을 추적하고 할당 된 교과서와 논문을 확인하는 것이 좋습니다. 즉, 여기 내 대학원생 시절의 간단한 개요가 있습니다.

가장 간단한 접근법을 a라고합니다 단어의 가방. 각 문서는 드문 벡터로 축소됩니다 {word: wordcount} 쌍, 그리고 문서 세트를 나타내는 벡터 세트에 순진한 (또는 다른) 분류기를 던지거나 각 백과 다른 가방 사이의 유사성 점수를 계산할 수 있습니다 (이것은 K-Nearest-Seighbour 분류라고합니다). KNN은 조회를 위해 빠르지 만 점수 매트릭스에 대한 O (n^2) 스토리지가 필요합니다. 그러나 블로그의 경우 N은 그리 크지 않습니다. 큰 신문의 크기에 대해 KNN은 빠르게 비현실적으로되므로 비행 금전 분류 알고리즘이 때로는 더 좋습니다. 이 경우 a를 고려할 수 있습니다 지원 벡터 머신 순위. SVM은 당신을 선형 유사성 측정으로 제한하지 않기 때문에 깔끔합니다.

스템 밍 단어의 가방 기술을위한 일반적인 전처리 단계입니다. 여기에는 "고양이"및 "고양이", "밥"및 "밥"또는 "밥"또는 "유사한"및 "유사하게"와 같은 형태 학적으로 관련된 단어를 줄이는 것이 포함됩니다. 거기에는 다양한 줄기 알고리즘이 있습니다. Wikipedia 페이지에는 여러 구현에 대한 링크가 있습니다.

Word-of-Words 유사성이 충분하지 않으면 층을 bag-of-n-grams 유사성으로 추상화 할 수 있습니다. 여기서 단어의 쌍이나 트리플을 기반으로 문서를 나타내는 벡터를 만들 수 있습니다. (4- 튜플 또는 더 큰 튜플을 사용할 수는 있지만 실제로는 큰 도움이되지 않습니다.) 이것은 훨씬 더 큰 벡터를 생산하는 단점이 있으며, 분류는 더 많은 작업을 수행 할 것이지만, 당신이 얻는 일치는 훨씬 더 가까워 질 것입니다. 구문 적으로. Otoh, 당신은 아마도 의미 론적 유사성을 위해 이것을 필요로하지 않을 것입니다. 표절 탐지와 같은 것들에게는 더 좋습니다. 청킹, 또는 가벼운 구문 분석 나무로 문서를 줄이는 것도 사용할 수 있지만 (나무에 대한 분류 알고리즘이 있음), 이것은 저작권 문제 ( "알려지지 않은 기원 문서, 누가 그것을 쓴 사람이 있습니까?")와 같은 것들에 더 유용합니다. .

유스 케이스에 더 유용 할 수 있습니다. Wordnet), 그런 다음 사용 된 개념 간의 유사성을 기반으로 문서를 분류합니다. 단어에서 개념으로의 매핑은 환원 적이지만, 전처리 단계는 시간이 많이 걸릴 수 있기 때문에 종종 단어 기반 유사성 분류보다 더 효율적입니다.

마지막으로, 거기에 있습니다 담론 구문 분석, 의미 구조에 대한 문서를 구문 분석하는 것; 담석 나무에서 유사성 분류기를 청크 문서에서 할 수있는 것과 같은 방식으로 실행할 수 있습니다.

거의 모든 것이 구조화되지 않은 텍스트에서 메타 데이터를 생성하는 것과 관련이 있습니다. 원시 블록의 텍스트 블록을 직접 비교하는 것은 다루기 어려워서 사람들은 먼저 문서를 메타 데이터로 전처리합니다.

다른 팁

이것은 일반적인 경우입니다 문서 분류 모든 클래스의 기계 학습에서 연구됩니다. 통계, 수학 및 컴퓨터 과학을 좋아한다면 감독되지 않은 방법을 살펴 보는 것이 좋습니다. kmeans ++, 베이지안 방법 그리고 LDA. 특히 베이지안 방법은입니다 꽤 좋아 당신이 찾고있는 것에서, 그들의 유일한 문제는 느리다는 것입니다 (그러나 당신이 매우 큰 사이트를 운영하지 않는 한, 그것은 당신을 많이 괴롭히지 않아야합니다).

보다 실용적이고 덜 이론적 인 접근 방식으로, 나는 당신이 이것 그리고 이것은 다른 것입니다 훌륭한 코드 예제.

"Programming Collective Intelligence : Building Smart Web 2.0 응용 프로그램"(ISBN 0596529325)을 읽어야합니다!

일부 방법 및 코드의 경우 : 먼저 단어 일치를 기반으로 직접적인 유사성을 찾고 싶은지 또는 현재와 직접 관련이 없지만 동일한 기사 클러스터에 속하는 유사한 기사를 표시할지 여부를 스스로에게 물어보십시오.

보다 클러스터 분석 / 파티션 클러스터링.

찾기위한 매우 간단한 (그러나 이론적이고 느린) 방법 직접 유사점은 다음과 같습니다.

전처리 :

  1. 기사 당 평평한 단어 목록을 저장합니다 (중복 단어를 제거하지 마십시오).
  2. "Cross Join"The Articles : 기사 B의 동일한 단어와 일치하는 기사 A의 단어 수를 계산합니다. 이제 매트릭스가 있습니다. int word_matches[narticles][narticles] (A-> B의 유사성은 B-> A와 동일하므로 드문 매트릭스는 공간의 거의 절반을 절약합니다).
  3. Word_matches 카운트를 범위 0..1로 정상화하십시오! (Max Count를 찾은 다음 카운트를 이것으로 나눕니다) - ints가 아닌 수레를 저장해야합니다.)

유사한 기사 찾기 :

  1. Word_matches에서 가장 높은 일치하는 X 기사를 선택하십시오

루비의 작은 벡터 공간 모델 검색 엔진. 기본 아이디어는 두 개의 문서가 동일한 단어를 포함하는 경우 관련되어 있다는 것입니다. 따라서 각 문서에서 단어 발생을 계산 한 다음이 벡터 사이의 코사인을 계산합니다 (각 항은 고정 인덱스가 있습니다. 해당 인덱스에 1이있는 경우 0이 아닌 경우). 두 문서에 모든 용어가 공통적 인 경우 코사인이 1.0이고 공통 용어가없는 경우 0.0이됩니다. 이를 % 값으로 직접 변환 할 수 있습니다.

terms = Hash.new{|h,k|h[k]=h.size}
docs = DATA.collect { |line| 
  name = line.match(/^\d+/)
  words = line.downcase.scan(/[a-z]+/)
  vector = [] 
  words.each { |word| vector[terms[word]] = 1 }
  {:name=>name,:vector=>vector}
}
current = docs.first # or any other
docs.sort_by { |doc| 
  # assume we have defined cosine on arrays
  doc[:vector].cosine(current[:vector]) 
}
related = docs[1..5].collect{|doc|doc[:name]}

puts related

__END__
0 Human machine interface for Lab ABC computer applications
1 A survey of user opinion of computer system response time
2 The EPS user interface management system
3 System and human system engineering testing of EPS
4 Relation of user-perceived response time to error measurement
5 The generation of random, binary, unordered trees
6 The intersection graph of paths in trees
7 Graph minors IV: Widths of trees and well-quasi-ordering
8 Graph minors: A survey

의 정의 Array#cosine 독자에게 운동으로 남겨 둡니다 (NIL 값과 다른 길이를 다루어야하지만 우리가 얻은 것에 대해 Array#zip 오른쪽?)

BTW, 예제 문서는 Deerwester etal의 SVD 논문에서 가져온 것입니다 :)

얼마 전에 나는 비슷한 것을 구현했습니다. 어쩌면이 아이디어는 이제 구식이지만 도움이되기를 바랍니다.

나는 일반적인 작업을 프로그래밍하기 위해 ASP 3.0 웹 사이트를 운영 하고이 원칙에서 시작했습니다. 사용자는 의심의 여지가 있으며 해당 주제에 대한 흥미로운 콘텐츠를 찾을 수있는 한 웹 사이트에 머무를 것입니다.

사용자가 도착했을 때 ASP 3.0을 시작했습니다. Session 링크 된 목록과 마찬가지로 모든 사용자 탐색을 객체하고 기록했습니다. ~에 Session.OnEnd 이벤트, 첫 번째 링크를 취하고 다음 링크를 찾고 다음과 같은 카운터 열을 증가 시켰습니다.

<Article Title="Cookie problem A">
    <NextPage Title="Cookie problem B" Count="5" />
    <NextPage Title="Cookie problem C" Count="2" />
</Article>

그래서 관련 기사를 확인하려면 맨 위에 나열해야했습니다. N NextPage 카운터 열 내림차순으로 주문한 엔티티.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top