TF-IDF 為一種文字探勘處理的工具,使用 TF 詞頻 (Term Frequency)和 IDF 逆向文件頻率 (Inverse Document Frequent)的乘積,得出權重(Weight),讓使用的人可以在多個文件中找到頻詞高,且在各個文件中“較為獨特”的文字。
而在這次的練習中,我參考了助教給的網站的概念,觀察ptt鄉民對於我最喜歡的球員「字母哥」Giannis Antetokounmpo,有著什麼樣的回應和評論,那就讓我們繼續往下看吧~~
library(bitops)
library(httr)
library(RCurl)
library(XML)
library(NLP)
library(tm)
library(tmcn)
library(jiebaRD)
library(jiebaR)
library(dplyr)
data <- list()
title <- list()
#抓取從明星賽後到現在的 ptt NBA版的貼文
for( i in c(5674:5810)){
tmp <- paste(i, '.html', sep='')
url <- paste('www.ptt.cc/bbs/NBA/index', tmp, sep='')
html <- htmlParse(GET(url),encoding = "UTF-8")
title.list <- xpathSApply(html, "//div[@class='title']/a[@href]", xmlValue)
url.list <- xpathSApply(html, "//div[@class='title']/a[@href]", xmlAttrs)
data <- rbind(data, as.matrix(paste('www.ptt.cc', url.list, sep='')))
title <- rbind(title, as.matrix(title.list))
}
# data 存網址 title 存標題
data <- unlist(data)
title <- unlist(title)
原本用getURL 結果發現url.list裡面是NULL 改用GET後就正確了
Giannis <- c()
Giannis.url <- c()
# 找出有關鍵字的標題並分類
giannis1 <- grep("Giannis", title)
giannis2 <- grep("字母", title)
Giannis <- c(Giannis,title[giannis1])
Giannis <- c(Giannis,title[giannis2])
Giannis.url <- c(Giannis.url, data[giannis1])
Giannis.url <- c(Giannis.url, data[giannis2])
message <- list()
cc = worker()
GATDF <- data.frame()
#爬取每篇有字母哥或是Giannis文章的留言
for(i in c(1:length(Giannis))){
html <- htmlParse(GET(Giannis.url[i]),encoding = "UTF-8")
message.list <- xpathSApply(html, "//div[@class='push']/span[@class='f3 push-content']", xmlValue)
message <- unlist(message.list)
#文本清理
d.corpus <- VCorpus( VectorSource(message) )
d.corpus <- tm_map(d.corpus, removePunctuation)
d.corpus <- tm_map(d.corpus, removeNumbers)
d.corpus <- tm_map(d.corpus, function(word) {
gsub("[A-Za-z0-9]", "", word)
})
#斷詞
abc <- data.frame(table(cc[as.character(d.corpus)]))
colnames(abc) <- c("word", as.character(i))
#合併
if(i == 1){
GATDF <- abc}
else{
GATDF <- merge(GATDF, abc, by = "word", all = T)}
}
#將遺漏值設為 0
GATDF[is.na(GATDF)] <- 0
library(knitr)
kable(head(GATDF))
| word | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
|---|---|---|---|---|---|---|---|---|---|---|
| 被 | 1 | 3 | 0 | 11 | 4 | 1 | 0 | 2 | 12 | 1 |
| 不會 | 2 | 7 | 1 | 0 | 3 | 5 | 0 | 1 | 1 | 0 |
| 第三篇 | 2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 都 | 1 | 22 | 4 | 4 | 4 | 6 | 7 | 7 | 8 | 2 |
| 發文 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 罰錢 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
n <- length(Giannis)
tf <- apply(as.matrix(GATDF[,2:(n+1)]), 2, sum)
#print(tf)
library(Matrix)
idfCal <- function(word_doc)
{
log2( n / nnzero(word_doc) )
}
idf <- apply(as.matrix(GATDF[,2:(n+1)]), 1, idfCal)
#print(ncol(GATDF))
doc.tfidf <- GATDF
for(x in 1:nrow(GATDF))
{
for(y in 2:ncol(GATDF))
{
doc.tfidf[x,y] <- (doc.tfidf[x,y] / tf[y-1]) * idf[x]
}
}
topwords <- subset(head(doc.tfidf[order(doc.tfidf[2], decreasing = TRUE), ]), select = c(word,`1`))
for (i in c(3:ncol(doc.tfidf))){
topwords <- cbind(topwords, head(doc.tfidf[order(doc.tfidf[i], decreasing = TRUE),])[1])
topwords <- cbind(topwords, head(doc.tfidf[order(doc.tfidf[i], decreasing = TRUE),])[i])
}
kable(topwords)
| word | 1 | word | 2 | word | 3 | word | 4 | word | 5 | word | 6 | word | 7 | word | 8 | word | 9 | word | 10 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 3 | 第三篇 | 0.1898245 | 球衣 | 0.0660774 | 勇士 | 0.0981160 | 反觀 | 0.0928489 | 弟 | 0.0346034 | 六步 | 0.0396115 | 鞋 | 0.0914292 | 一步 | 0.0305396 | 虐 | 0.0629749 | 藏 | 0.0353397 |
| 27 | ㄣ | 0.1898245 | 投 | 0.0329774 | 嘴綠 | 0.0560663 | 得體 | 0.0825324 | 哥哥 | 0.0346034 | 三分 | 0.0211806 | 簽名 | 0.0812704 | 可能 | 0.0290853 | 姆 | 0.0330132 | 得手 | 0.0353397 |
| 5 | 發文 | 0.0949122 | 名字 | 0.0245869 | 轉隊 | 0.0350414 | 人品 | 0.0550216 | 體重 | 0.0276827 | 灌籃 | 0.0195953 | 中國 | 0.0406352 | 公尺 | 0.0204350 | 被姆斯 | 0.0314875 | 毒 | 0.0353397 |
| 7 | 齁 | 0.0949122 | 灌票 | 0.0219850 | 綠 | 0.0210249 | 推 | 0.0511146 | 弟弟 | 0.0207621 | 足夠 | 0.0189392 | 澳洲人 | 0.0304764 | 跳 | 0.0204350 | 慘虐 | 0.0314875 | 方式 | 0.0353397 |
| 10 | 檢查 | 0.0949122 | 賽 | 0.0219850 | 拿頂 | 0.0210249 | 讚 | 0.0343885 | 瘦 | 0.0207621 | 從 | 0.0158855 | 出 | 0.0304764 | 用 | 0.0133760 | 吃 | 0.0314875 | 防不勝防 | 0.0353397 |
| 11 | 看有 | 0.0949122 | 投票 | 0.0219850 | 適合 | 0.0210249 | 錄影帶 | 0.0240719 | 個 | 0.0193494 | 跑 | 0.0158446 | 非 | 0.0304764 | 全力 | 0.0127719 | 吹 | 0.0314875 | 哥給 | 0.0353397 |
從得出的重要詞彙結果來看 較為有意義的分別是 第二篇的勇士 嘴綠(Draymond Green) 轉隊 第四篇的反觀 得體 人品 第五篇的 簽名 鞋
從上述可知道 我們家字母哥 在最近的討論中 有跟勇士和其隊員有關 甚至可能有轉隊的念頭(還是鄉民的一廂情願xD)
而第四篇的得體 人品 則知道 字母哥是個善良又有人品的好球員 想必一定是做了什麼好事情 讓鄉民連連稱讚
而第五篇的 簽名 鞋 則可推測 字母哥即將推出新一款的簽名球鞋
這次TFIDF的分析 不僅大量過濾掉了不必要的贅詞 更讓我們看到個別文章中的重要詞彙 是個非常好的分析方法 而視覺化的呈現 則會在project1中 有更清楚和更多元的圖表來做說明