용어 빈도 / 역 문서 빈도 (TF / IDF) : 가중치


12

1000 개의 문서와 그 안에 나타나는 모든 단어를 나타내는 데이터 세트가 있습니다. 따라서 행은 문서를 나타내고 열은 단어를 나타냅니다. 그래서 예를 들어, 셀의 값은 시간을 나타내며, 워드 문서 발생 . 이제 tf / idf 방법을 사용하여 단어의 '무게'를 찾아야하지만 실제로이 작업을 수행하는 방법을 모르겠습니다. 누군가 나를 도울 수 있습니까?j i(i,j)ji


키워드 추출을위한 tf- idf-
Raffael

답변:


12

Wikipedia에는 ​​주제에 대한 좋은 기사가 있으며 수식이 있습니다. 행렬의 값은 주파수라는 용어입니다. idf : (log((total documents)/(number of docs with the term))와 2 개의 값을 여러 개 찾아야 합니다.

R에서는 다음과 같이 할 수 있습니다.

set.seed(42)
d <- data.frame(w=sample(LETTERS, 50, replace=TRUE))
d <- model.matrix(~0+w, data=d)

tf <- d
idf <- log(nrow(d)/colSums(d))
tfidf <- d

for(word in names(idf)){
  tfidf[,word] <- tf[,word] * idf[word]
}

데이터 세트는 다음과 같습니다.

> colSums(d)
wA wC wD wF wG wH wJ wK wL wM wN wO wP wQ wR wS wT wV wX wY wZ 
 3  1  3  1  1  1  1  2  4  2  2  1  1  3  2  2  2  4  5  5  4 
> head(d)
  wA wC wD wF wG wH wJ wK wL wM wN wO wP wQ wR wS wT wV wX wY wZ
1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  1  0  0
2  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  1  0
3  0  0  0  0  0  1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
4  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  1  0  0  0
5  0  0  0  0  0  0  0  0  0  0  0  0  0  1  0  0  0  0  0  0  0
6  0  0  0  0  0  0  0  0  0  0  1  0  0  0  0  0  0  0  0  0  0
> head(round(tfidf, 2))
  wA wC wD wF wG   wH wJ wK wL wM   wN wO wP   wQ wR wS wT   wV  wX  wY wZ
1  0  0  0  0  0 0.00  0  0  0  0 0.00  0  0 0.00  0  0  0 0.00 2.3 0.0  0
2  0  0  0  0  0 0.00  0  0  0  0 0.00  0  0 0.00  0  0  0 0.00 0.0 2.3  0
3  0  0  0  0  0 3.91  0  0  0  0 0.00  0  0 0.00  0  0  0 0.00 0.0 0.0  0
4  0  0  0  0  0 0.00  0  0  0  0 0.00  0  0 0.00  0  0  0 2.53 0.0 0.0  0
5  0  0  0  0  0 0.00  0  0  0  0 0.00  0  0 2.81  0  0  0 0.00 0.0 0.0  0
6  0  0  0  0  0 0.00  0  0  0  0 3.22  0  0 0.00  0  0  0 0.00 0.0 0.0  0

각 용어의 idf를 볼 수도 있습니다.

> log(nrow(d)/colSums(d))
      wA       wC       wD       wF       wG       wH       wJ       wK       wL       wM       wN       wO       wP       wQ       wR       wS       wT       wV       wX       wY       wZ 
2.813411 3.912023 2.813411 3.912023 3.912023 3.912023 3.912023 3.218876 2.525729 3.218876 3.218876 3.912023 3.912023 2.813411 3.218876 3.218876 3.218876 2.525729 2.302585 2.302585 2.525729 

당신의 도움을 주셔서 감사합니다! 그러나 전체 행렬 대신 가중치를 나타내는 각 단어에 대해 약간의 값을 얻을 수 있습니까? 이제 우리는 전체 가중치 행렬을 갖습니다. 일부 기능을 선택하고 tf / idf를 필터 방법으로 사용하고 싶습니다.
ABC

@ABC tf-idf는 정의에 따라 가중치의 전체 행렬을 나타냅니다. 아마도 당신은 idf weights에만 관심이 있습니다 log((number of docs)/(number of docs containing the term)). 드물게 용어를 필터링 할 수도 있습니다.
Zach

매우 명확한! 정말 감사합니다.
ABC

13

tm (텍스트 마이닝) http://cran.r-project.org/web/packages/tm/index.html 패키지 가 있습니다.

#read 1000 txt articles from directory data/txt
corpus  <-Corpus(DirSource("data/txt"), readerControl = list(blank.lines.skip=TRUE));
#some preprocessing
corpus <- tm_map(corpus, removeWords, stopwords("english"))
corpus <- tm_map(corpus, stripWhitespace)
corpus <- tm_map(corpus, stemDocument, language="english")
#creating term matrix with TF-IDF weighting
terms <-DocumentTermMatrix(corpus,control = list(weighting = function(x) weightTfIdf(x, normalize = FALSE)))

#or compute cosine distance among documents
dissimilarity(tdm, method = "cosine")

R은 함수형 언어이므로 코드를 읽는 것이 까다로울 수 있습니다 (예 : x)


2

코드에 오류가 있습니다. colSums는 단어가있는 텍스트 수가 아니라 모음에서의 발생 수를 계산합니다.

그러한 버전 컴퓨팅은 다음과 같습니다.

tfidf=function(mat){
  tf <- mat
  id=function(col){sum(!col==0)}
  idf <- log(nrow(mat)/apply(mat, 2, id))
  tfidf <- mat
  for(word in names(idf)){tfidf[,word] <- tf[,word] * idf[word]}
  return(tfidf)
  }

1

이것을 할 수있는 새로운 R 패키지가 있습니다 : textir : 텍스트 분석을위한 역 회귀

관련 명령은 tfidf매뉴얼의 예입니다.

data(we8there)
## 20 high-variance tf-idf terms
colnames(we8thereCounts)[
order(-sdev(tfidf(we8thereCounts)))[1:20]]

1

나는이 파티에 늦었지만 tc-idf 의 개념을 가지고 놀고 있었다 . {tm: Text Mining Package}언급 된 것처럼 패키지로 더 쉽게 수행 할 수 있으며 , 내가 얻은 것이이 질문과 관련이 있거나 어쨌든 게시하기에 좋은 장소 일 수 있다고 생각합니다.


SET-UP : 나는이 신체5인쇄 매체에서 촬영 긴 단락 text 1을 통해 5같은 뉴욕 타임즈를 . 추정되게, 그것은 매우 작은 "몸"작은 도서관은 말하자면,이다, 그러나 이 "디지털"라이브러리에있는 항목은 임의하지 같습니다 첫 번째다섯 번째 항목은 '소셜 클럽'의 축구 (또는 '축구'처리 (?) 주변), 더 구체적으로 오늘 가장 위대한 팀에 대해. 예를 들어 다음과 같이 text 1시작합니다.

"지난 9 년 동안 메시는 FC 바르셀로나를 국가 및 국제 타이틀로 이끌면서 다른 세계적으로 보이는 방식으로 개인 기록을 깨뜨 렸습니다 ..."

아주 좋아요! 반면에 사이에있는 세 항목의 내용을 건너 뛰고 싶을 것입니다. 다음은 예입니다 ( text 2).

"텍사스 전역에서 몇 시간 동안 루비오는 Mr. Trump가 바지로 소변을 보았으며 불법 이민자들을 사용하여 끊임없는 트위터 메시지를 활용했다고 제안했습니다."

그래서 어떤에서 "서핑"모든 비용을 피하기 위해해야 할 일 text 1하기 text 2에, 계속하는 동안은 전능하신 바르셀로나 FC에 대한 문헌에 기뻐 text 5?


TC-IDF : 모든 단어 text를 긴 벡터로 분리했습니다. 그런 다음 각 단어의 빈도를 계산하여 text해당 단어에서 발견 된 단어 만 계산되는 5 개의 벡터 (각 1 개씩 ) 를 만듭니다. text다른 texts에 속하는 다른 모든 단어 는 0으로 평가되었습니다. 예를 들어의 첫 번째 스 니펫에서 text 1벡터는 "Messi"라는 단어의 개수는 1이고 "Trump"는 0입니다. 이것은 tc 부분입니다.

IDF의 일부는 각각에 대해 개별적으로 계산 된 text우리의 작은 라이브러리 주어진 단지 제로부터 5까지 안타깝게도 문서 (의 계수의 대수 변환을 포함하는 (I는 I 데이터 프레임들로 처리 생각한다), 5 '벡터'초래 )는 다음과 같이 주어진 단어를 포함합니다.

01log(No. documents1+No. docs containing a word) . 문서 수는 5입니다. 여기에 OP에 응답 할 수있는 부분이 있습니다. 각 idf 계산에 대해 text고려 대상이 탈리에서 제외되었습니다 . 그러나 단어가 모든 문서에 나타난 경우 분모 의 로 인해 idf는 여전히 예를 들어 단어 "the"는 모든 s 에 있었기 때문에 중요성이 0이었습니다 .01text

의 항목이 많다는 곱셈 모든에 대한이 있었다 모든 단어의 중요성 라이브러리 항목 각각에 대해 - 로컬 유행, 세계적으로 희귀 한 단어 .tc×idftext


비교 : 이제는 이러한 "단어 중요도 벡터"중에서 내적을 수행하는 문제였습니다.

예측할 수 있듯이 text 1with 의 내적 text 513.42645이고 text 1v text2는 단지 2.511799였습니다.

교묘 한 R 코드 (모방 할 것이 없음)는 여기에 있습니다 .

다시 말하지만 이것은 매우 기초적인 시뮬레이션이지만 매우 그래픽 적이라고 생각합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.