텍스트마이닝
텍스트마이닝 #5 실시간 뉴스 수집과 분석
yul_S2
2022. 12. 13. 11:36
반응형
# # #
# 1. 웹 문서 요청과 파싱 관련 패키지 설치 및 로딩
install.packages("httr") library(httr) install.packages("XML") library(XML) |
# 2. 웹 문서 요청
url <- "http://media.daum.net" web <- GET(url) web |
# 3. HTML 파싱하기
html <- htmlTreeParse(web, useInternalNodes = T, trim = T, encoding = "utf-8") rootNode <- xmlRoot(html) |
- htmlTreeParse
- useInternalNodes = T : ROOT 노드 찾을 수 있음
- trim = T : 앞뒤 공백제거
- ncoding => 인코딩 방식 설정
- rootNode <- xmlRoot(html) : ROOT 노드 찾기
# 4. 태그 자료 수집하기
news <- xpathSApply(rootNode, "//a[@class = 'link_txt']", xmlValue) news |
- root에 저장된 HTML 소스에서 해당 tag들중 조건( "//a[@class = 'link_txt']" )에 맞는 태그들의 Value, 내용을 뽑아서 벡터로 저장
# 5. 수집한 자료 전처리
# 5-1 자료 전처리 - 수집한 문서를 대상으로 불용어 제거
news_pre <- gsub("[\r\n\t]", ' ', news) news_pre <- gsub('[[:punct:]]', ' ', news_pre) news_pre <- gsub('[[:cntrl:]]', ' ', news_pre) # news_pre <- gsub('\\d+', ' ', news_pre) # corona19(covid19) 때문에 숫자 제거 생략 news_pre <- gsub('[a-z]+', ' ', news_pre) news_pre <- gsub('[A-Z]+', ' ', news_pre) news_pre <- gsub('\\s+', ' ', news_pre) news_pre |
- gsub("패턴", "교체문자", 원본
- [[:punct:]] => 문장부호
- [[:cntrl:]] => 특수문자
- [원하는문장부호] 제거
- \\d+ => 숫자
- [a-z]+ / [A-Z]+ => 소 / 대문자 영어
- \\s+ => 2개 이상 공백 교체
# 5-2 기사와 관계 없는 'TODAY', '검색어 순위' 등의 내용은 제거
news_data <- news_pre[1:32] news_data |
# 6 수집한 자료를 파일로 저장하고 읽기
write.csv(news_data, "news_data.csv", quote = F) # 파일저장 news_data <- read.csv("news_data.csv", header = T, stringsAsFactors = F) # 파일읽기 |
str(news_data) 'data.frame': 32 obs. of 2 variables: $ X: int 1 2 3 4 5 6 7 8 9 10 ... # $ x: chr " 단독 기재위 소위 협상 물꼬 트이나 與 민주당에 소위 신설 제안 " # " 인사이드 스토리 ①삼성생명이 펫보험 팔게 된다면 " # " 수능 하루전이지만 유통 외식업계 마케팅 활동 잠잠 " " 갑갑한 지하철 버스 꺼려지면 이것 의심을 " ... names(news_data) <- c("no", "news_text") head(news_data) # no news_text # 1 1 단독 기재위 소위 협상 물꼬 트이나 與 민주당에 소위 신설 제안 # 2 2 인사이드 스토리 ①삼성생명이 펫보험 팔게 된다면 # 3 3 수능 하루전이지만 유통 외식업계 마케팅 활동 잠잠 # 4 4 갑갑한 지하철 버스 꺼려지면 이것 의심을 # 5 5 수능 수험생 2317명 확진 판정 500명 내일 격리해제 종합 # 6 6 순방결산 한미일 중국 편 가르기 확실해졌다 news_text <- news_data$news_text news_text # [1] " 단독 기재위 소위 협상 물꼬 트이나 與 민주당에 소위 신설 제안 " # [2] " 인사이드 스토리 ①삼성생명이 펫보험 팔게 된다면 " # [3] " 수능 하루전이지만 유통 외식업계 마케팅 활동 잠잠 " # [4] " 갑갑한 지하철 버스 꺼려지면 이것 의심을 " # [5] " 수능 수험생 2317명 확진 판정 500명 내일 격리해제 종합 " # [6] " 순방결산 한미일 중국 편 가르기 확실해졌다 " # [7] " 미 당국 폴란드 떨어진 미사일 우크라 발사 요격 미사일 추정 " # [8] " 경찰이 통제해라 첫 112 신고 육성 들어보니 " # [9] " 검찰 급식 일감 몰아주기 최지성 삼성전자 기소 " # [10] " 현대해상 이어 손보도 신용대출 문턱 높인다 보험권 대출 한파 " # [11] " 바이든 시진핑 이어 美재무 中인민은행 총재도 대면 회의 건설적 " # [12] " 이재명 고금리 서민 고통 커 정부 역할 확대해 금융지원 강화 " # [13] " 3년 만에 정상개최 지스타 안전 재미 동시에 잡는다 " # [14] " 집값 하락 경기 침체에 부산 부동산시장 얼어붙었다 " # [15] " 경기침체 충격 본격화 코스피 상장사 영업익 30 줄었다 " # [16] " 김기현 빈곤 포르노 장경태 인간 아냐 동물을 어떻게 제소할까 " # [17] " 트럼프 3번째 대선 출마 선언 공화당 입장에선 최악 타이밍 " # [18] " 단독 정부 안전인력 감축 없다 더니 코레일 안전인력 784명 감축 검토 " # [19] " 日 다시 코로나 대유행하나 확진자 하루 10만 재돌파 " # [20] " 민주당 제주도당 이태원 참사 국정조사 특검 서명운동 " # [21] " 이앤피 서울시 지원 중단 내년 7월 2024년 여지 남았나 外 " # [22] " 오마이포토 참사 현장 추모의 벽 에 비닐 붙은 이유 " # [23] " 영상 왜 내 차쪽으로 쓸어 미화원 무릎 꿇린 부부에 공분 차이나픽 " # [24] " 자식 혁명 계승자로 키워야 北이 말하는 어머니 " # [25] " 친절한 경제 올해 김장 비용 걱정 안 해도 된다 배추 값 영향 " # [26] " 월드리포트 헤르손 해방된 도시 환호하는 시민들 이면의 상처 " # [27] " 소설 위대한 알코올중독자 모든 길은 술로 통한다 " # [28] " 이슈 직설 99 의 투자자는 안 낼까 금투세 에 뿔난 개미들 금투세 과세 대상자 15만 명 " # [29] "줄지어서 주의사항 듣는 수험생들" # [30] " 향숙이 예뻤다 화성 연쇄살인범 이춘재 대신 누명 윤성여 에 국가 19억 배상" # [31] " 참사 현장 추모의 벽 에 비닐 붙은 이유" # [32] "美 바이든 폴란드 미사일 피격에 7 나토 정상들과 긴급 회동 " |
# 7.토픽분석
# 7-1 세종 사전에 단어 추가
user_dic <- data.frame(term = c("펜데믹", "코로나19", "타다"), tag = 'ncn') buildDictionary(ext_dic = 'sejong', user_dic = user_dic) # 371005 words dictionary was built. |
# 7-2 단어 추출 사용자 함수 정의하기 ( 토픽분석 )
#(1) 사용자 정의 함수 작성
exNouns <- function(x) { paste(extractNoun(x), collapse = " ")} |
#(2) exNouns() 함수를 이용하어 단어 추출
news_nouns <- sapply(news_text, exNouns) news_nouns |
#(3) 추출 결과 확인
str(news_nouns) # Named chr [1:32] "단독 기재 위 협상 물꼬 與 민주 당 신설 저" "인사이드 스토리 1삼성생명이 펫보험 면" ... # - attr(*, "names")= chr [1:32] " 단독 기재위 소위 협상 물꼬 트이나 與 민주당에 소위 신설 제안 " # " 인사이드 스토리 ①삼성생명이 펫보험 팔게 된다면 " " 수능 하루전이지만 유통 외식업계 마케팅 활동 잠잠 " # " 갑갑한 지하철 버스 꺼려지면 이것 의심을 " ... |
# 7-3 말뭉치 생성과 집계 행렬 만들기
library(tm) |
#(1) 추출된 단어를 이용한 말뭉치(corpus) 생성
newsCorpus <- Corpus(VectorSource(news_nouns)) newsCorpus # <<SimpleCorpus>> # Metadata: corpus specific: 1, document level (indexed): 0 # Content: documents: 32 inspect(newsCorpus[1:5]) |
#(2) 단어 vs 문서 집계 행렬 만들기
TDM <- TermDocumentMatrix(newsCorpus, control = list(wordLengths = c(4, 16))) TDM # <<TermDocumentMatrix (terms: 175, documents: 32)>> # Non-/sparse entries: 190/5410 # Sparsity : 97% # Maximal term length: 6 # Weighting : term frequency (tf) |
#(3) matrix 자료구조를 data.frame 자료구조로 변경
tdm.df <- as.data.frame(as.matrix(TDM)) dim(tdm.df) # [1] 175 32 |
#7-4 단어 출현 빈도수 구하기
wordResult <- sort(rowSums(tdm.df), decreasing = TRUE) wordResult[1:10] # 미사일 안전 참사 단독 민주 수능 하루 수험생 폴란드 정부 # 3 3 3 2 2 2 2 2 2 2 |
#7-5 단어 구름 생성
#(1) 패키지 로딩과 단어 이름 추출
library(wordcloud) myNames <- names(wordResult) myNames |
# (2) 단어와 단어 빈도수 구하기
df <- data.frame(word = myNames, freq = wordResult) head(df) # word freq # 미사일 미사일 3 # 안전 안전 3 # 참사 참사 3 # 단독 단독 2 # 민주 민주 2 # 수능 수능 2 |
# (3) 단어 구름 생성
pal <- brewer.pal(12, "Paired") ### pas 대신--> pal wordcloud(df$word, df$freq, min.freq = 2, random.order = F, scale = c(4, 0.7), rot.per = .1, colors = pal, family = "malgun") |
반응형