R语言分析 报告关于抑郁的Twitter情感文本分析

关于抑郁的Twitter情感分析

介绍

抑郁对全球公共健康带来了巨大挑战。每天,数百万人患有抑郁症,只有很少一部分人接受适当的治疗。过去,医生通常通过面对面的对话使用诊断标准来确定抑郁(如DSM-5抑郁症诊断标准)来诊断患者。然而,先前的研究表明,大多数患者在抑郁的早期阶段不会寻求医生的帮助,这将导致他们的心理健康下降。另一方面,许多人每天都使用社交媒体平台分享自己的情感。从那时起,关于使用社交媒体预测心理和身体疾病的研究已经很多,如心脏停搏、寨卡病毒以及处方药滥用的心理健康。这项研究关注使用社交媒体数据来检测社交媒体用户的抑郁思绪。本质上,该研究结合了文本分析,并专注于从书面交流中提取见解,以得出数据是否与抑郁思绪有关的结论。

本项目旨在分享他们的心理健康感受,判断是否存在焦虑和抑郁,对数据集进行EDA分析,并对Twitter文本进行情感分析。

数据

数据以未经清洗的格式收集,使用Twitter API进行收集。数据已被过滤,仅保留了英文内容。它针对的是用户在推文级别的心理健康分类。

  • post_id:帖子的ID
  • post_created:帖子创建时间
  • post_text:未经清洗的推文文本
  • user_id:用户标识
  • followers:粉丝数量
  • friends:好友数量
  • favourites:收藏数量
  • statuses:总状态数
  • redata:当前推文的转发总数
  • label:用于分类的标签(1表示抑郁,0表示无抑郁)

此示例的目标是使用监控数据来估计预测模型,并确定用户是否患有抑郁症。

换句话说,我们希望构建一个模型,可以根据其内容将数据分类为“抑郁”和“无抑郁”。我可以想出许多原因,为什么这种事情如此酷。我提出的原因之一是可以根据用户的情绪来判断他们的心理状况,并推广相关产品。例如,患有抑郁症的人可以推广药物。药物是治疗抑郁症最有效的方法之一,因此,将推文分类为“抑郁”和“无抑郁”对此非常有用。该项目的步骤如下:1. 对文本进行初步清理。2. 数据可视化。3. 使用“tm”包将其转换为格式。4. 将数据分成“训练”和“测试”集。5. 使用“一次性热编码”方法定义分类模型的“特征”。6. 在“e1071”包中应用朴素贝叶斯算法于“训练”数据。7. 使用该模型从“测试”数据中进行预测。

数据清理

接下来,下载数据集并使用以下代码进行读取:
我要做的第一件事是将“label”字段强制转换为因子,而不是值。

## 
## no depression    depression 
##         10000         10000

有10000条抑郁数据和10000条无抑郁数据
这第二步有点小技巧。我尝试过使用tidyr和tm包来处理文本挖掘应用。它们都具有内置的功能,可以清理正则表达式和其他从文本数据中提取复杂内容的功能。由于某种原因,我在处理某些特殊字符(如非ASCII或转义字符)时一直遇到问题。在这里,我使用了一个简单的gsub()操作,将推文文本中的一些内容清除掉。

“词袋”模型会将每个推文视为一大袋词语。使用tm包来组织数据,我们首先要做的是创建一个语料库(Corpus)。语料库是一个文档集合。在这种情况下,每个推文都是一个文档。

## <<SimpleCorpus>>
## Metadata:  corpus specific: 1, document level (indexed): 0
## Content:  documents: 20000

现在我们有一个包含20000个文档(数据)的语料库。
tm包具有一些内置方法,可以去除标点符号和停用词等内容。我们将使用这些方法从语料库中删除一些内容:

## <<SimpleCorpus>>
## Metadata:  corpus specific: 1, document level (indexed): 0
## Content:  documents: 5
## 
## [1] just year sinc diagnos anxieti depress today im take moment reflect far ive come sinc       
## [2] sunday need break im plan spend littl time possibl                                          
## [3] awak tire need sleep brain idea                                                             
## [4] rt sewhq retro bear make perfect gift great beginn get stitch octob sew sale now yay httptco
## [5] hard say whether pack list make life easier just reinforc much still need movinghous anxieti

数据可视化

词云提供了一种直观的方式来可视化语料库中词汇的频率。

词在语料库中出现的频率越高,其词体大小在词云中就越大。

我们可以通过使用wordcloud包中的wordcloud()函数轻松创建词云。

绘制没有抑郁的人的推文中的单词

绘制有抑郁的人的推文中的单词

在20000条推文中,许多用户重复发推。总共调查了72名用户,其中54名患有抑郁,另外18名没有抑郁。

文档矩阵

在下一部分中,有几个需要注意的事项:

  1. 存在一个TermDocumentMatrix,将语料库中的术语沿着行排列,而将文档沿着列排列。
  2. 然后有一个DocumentTermMatrix,将文档沿着行排列,术语沿着列排列。
    这个应用程序主要涉及DocumentTermMatrix。这是因为在应用朴素贝叶斯算法时,将观察数据放在行中,将特征(单词)放在列中是方便的。
## [1] 20000 28725

目前的文档-术语矩阵包含了从20000条推文中提取的28725个单词。这些单词将用于决定一条推文是否是积极或消极的。
文档-术语矩阵的稀疏性为100%,这意味着没有单词被留在矩阵之外。

## [1] 20000  1109
## <<DocumentTermMatrix (documents: 10, terms: 15)>>
## Non-/sparse entries: 20/130
## Sparsity           : 87%
## Maximal term length: 7
## Weighting          : term frequency (tf)
## Sample             :
##     Terms
## Docs anxieti come depress diagnos far ive just need sinc take
##   1        1    1       1       1   1   1    1    0    2    1
##   10       0    0       0       0   0   0    0    0    0    0
##   2        0    0       0       0   0   0    0    1    0    0
##   3        0    0       0       0   0   0    0    1    0    0
##   4        0    0       0       0   0   0    0    0    0    0
##   5        1    0       0       0   0   0    1    1    0    0
##   6        0    0       0       0   0   0    0    0    0    0
##   7        0    0       0       0   0   0    0    0    0    0
##   8        0    0       0       0   0   0    0    0    0    0
##   9        0    0       0       0   0   0    0    0    0    1

regular inspect()方法的信息量不是很大。但是,如果我们想知道一些单词或短语在语料库中出现的频率,我们可以做的一件事是将这些术语作为字典传递给DocumentTermMatrix()方法。
只是为了跟进。在上面的输出中,我们看到文件1有1次出现短语“焦虑”和1次出现“抑郁”。如果我们查看原始推文文本数据帧,我们可以看到:

## [1] "Its just over 2 years since I was diagnosed with anxiety and depression Today Im taking a moment to reflect on how far Ive come since"

能看一眼出现700多次的单词是件好事。

##            word freq
## like       like 1035
## depress depress  953
## just       just  943
## dont       dont  832
## get         get  794
## one         one  746

模型

朴素贝叶斯对分类数据进行训练,将数值数据转换为分类数据。我们将通过创建一个函数来转换数字特征,该函数将任何非零正值转换为“是”,将所有零值转换为“否”,以说明文档中是否存在特定术语。
此例程将DocumentTermMatrix的元素从字数更改为存在/不存在。以下是斯坦福大学的一门课程中关于NLP的一些很好的开源笔记。其中包括对二进制(布尔特征)朴素贝叶斯算法的一些讨论。
我们现在将数据集拆分为训练和测试数据集。我们将使用90%的数据进行训练,其余10%用于测试。

##    user  system elapsed 
##    0.72    0.01    0.74

Model Evaluation for Naive Bayes

## Confusion Matrix and Statistics
## 
##                Reference
## Prediction      no depression depression
##   no depression          1006          0
##   depression                0        970
##                                        
##                Accuracy : 1            
##                  95% CI : (0.9981, 1)  
##     No Information Rate : 0.5091       
##     P-Value [Acc > NIR] : < 2.2e-16    
##                                        
##                   Kappa : 1            
##                                        
##  Mcnemar's Test P-Value : NA           
##                                        
##             Sensitivity : 1.0000       
##             Specificity : 1.0000       
##          Pos Pred Value : 1.0000       
##          Neg Pred Value : 1.0000       
##              Prevalence : 0.5091       
##          Detection Rate : 0.5091       
##    Detection Prevalence : 0.5091       
##       Balanced Accuracy : 1.0000       
##                                        
##        'Positive' Class : no depression

与分别为100%和100%的支持向量机和随机森林模型相比,朴素贝叶斯模型以100%的准确率表现最好。Naive Bayes的工作原理是假设数据集的特征彼此独立 — 因此被称为Naive。

结果

该项目根据推特文本对文本进行分类,以预测他们是否患有抑郁症。贝叶斯模型在测试集中的准确性已经达到了一个非常好的水平。患者过去活泼开朗,但他们最近的推特非常沮丧,或者他们的状态发生了变化,比如睡眠问题和身体问题。这类用户可能患有抑郁症

代码

library(tidyverse)
library(ggthemes)
library(e1071) # has the naiveBayes algorithm
library(caret) # good ML package, I like the confusionMatrix() function
library(tm) # for text mining
# Load package
library(wordcloud)
Sys.setenv(LANG="en_US.UTF-8")
###  https://www.kaggle.com/datasets/infamouscoder/mental-health-social-media
data <- read_csv("Mental-Health-Twitter.csv")
data$label <- factor(data$label,levels = c(0,1),
                     labels  = c("no depression","depression"))
table(data$label)

data$post_text <- gsub("[^[:alnum:][:blank:]?&/\\-]", "", data$post_text)
corpus <- Corpus(VectorSource(data$post_text))
corpus
clean.corpus <- corpus %>% tm_map(tolower) %>%
    tm_map(removeNumbers) %>%
    tm_map(removeWords, stopwords()) %>%
    tm_map(removePunctuation) %>%
    tm_map(stripWhitespace)%>%
    tm_map(stemDocument)
inspect(clean.corpus[1:5])
no_depression <- subset(data,label=="no depression")
wordcloud(no_depression$post_text, max.words = 100, scale = c(3,0.5))
depression <- subset(data,label=="depression")
wordcloud(depression$post_text, max.words = 100, scale = c(3,0.5))
df <- data%>%
    group_by(user_id,label)%>%
    count()

ggplot(df, aes(x = label)) +
  geom_bar() +
  geom_text(aes(label = ..count..), stat = "count", vjust = 2, colour = "white")  + ylab("people")
# Create the Document Term Matrix 
dtm <- DocumentTermMatrix(clean.corpus)
dim(dtm)
dtm = removeSparseTerms(dtm, 0.999)
dim(dtm)
#Inspecting the the first 10 tweets and the first 15 words in the dataset
inspect(dtm[0:10, 1:15])
data$post_text[1]
freq<- sort(colSums(as.matrix(dtm)), decreasing=TRUE)
wf<- data.frame(word=names(freq), freq=freq)
head(wf)
ggplot(head(wf,10),aes(x = fct_reorder(word,freq),y = freq)) + geom_col() + xlab("word") + ggtitle("Top 10 words in Tweets")
convert_count <- function(x) {
    y <- ifelse(x > 0, 1,0)
    y <- factor(y, levels=c(0,1), labels=c("No", "Yes"))
    y
}
# Apply the convert_count function to get final training and testing DTMs
datasetNB <- apply(dtm, 2, convert_count)

猜你喜欢

转载自blog.csdn.net/weixin_54707168/article/details/132531343