# 互联网新闻情感分析
# 一、任务描述
## 1.1 赛题背景
随着各种社交平台的兴起,网络上用户的生成内容越来越多,产生大量的文本信息,如新闻、微博、博客等,面对如此庞大且富有情绪表达的文本信息,完全可以考虑通过探索他们潜在的价值为人们服务。因此近年来情绪分析受到计算机语言学领域研究者们的密切关注,成为一项进本的热点研究任务。
本赛题目标为在庞大的数据集中精准的区分文本的情感极性,情感分为正中负三类。面对浩如烟海的新闻信息,精确识别蕴藏在其中的情感倾向。
## 1.2 任务要求
对官方提供的新闻数据进行情感极性分类,其中正面情绪对应0,中性情绪对应1以及负面情绪对应2。根据提供的训练数据,通过算法或模型判断出测试集中新闻的情感极性。
## 1.3 数据描述
数据包由两个csv文件组成:第一个是Train_Dataset,包含7360条新闻的id号,新闻标题和新闻内容。第二个是Train_Dataset_Label,包含了Dataset中新闻的id号,以其新闻的情感得分(用0,1,2表示)。
# 二、实施方案
该问题实质上为对信息的分类处理,所以核心内容是使用一个合适的分类器。其次,由于新闻是由文本构成的语言,一条新闻的情感通常可以由文本中词语的情感性决定。于是,另一个重要的内容是如何将数据进行预处理,即删除无用文字,并将新闻文本切分成一个个中文词语。
## 2.1 数据预处理
观察训练集中新闻的内容,发现新闻文本乱七八糟,有各种不属于中文词库的符号。所以预处理的第一步就是将不属于中文的文本删除(包括各种标点符号)。预处理的第二步是将修正后的文本进行词语的切分,从而将一整段话切分为一个个词语。
## 2.2 分类器选择
情感标签有三种赋值:积极、中立和消极。于是所有的二分类器就不可以使用,比如标准意义下的SVM支持向量机等。考虑到运行时间和效率,我们将选择朴素贝叶斯分类器作为首选(事实上,测试结果也表明朴素贝叶斯分类器是效率和正确率均较高的分类器)
# 三、具体实现
实现细节,模型设计和选择,数据预处理方式
以下是整个处理过程的具体实现:
## 3.1 数据清理
对非中文无用数据的清理,需要将以下类别的数据从训练集和测试集中清除:
```c++
html = re.compile('<.*?>')
http = re.compile(r'http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+')
src = re.compile(r'\b(?!src|href)\w+=[\'\"].*?[\'\"](?=[\s\>])')
space = re.compile(r'[\\][n]')
ids = re.compile('[(]["微信"]?id:(.*?)[)]')
wopen = re.compile('window.open[(](.*?)[)]')
english = re.compile('[a-zA-Z]')
others= re.compile(u'[^\u4e00-\u9fa5\u0041-\u005A\u0061-\u007A\u0030-\u0039\u3002\uFF1F\uFF01\uFF0C\u3001\uFF1B\uFF1A\u300C\u300D\u300E\u300F\u2018\u2019\u201C\u201D\uFF08\uFF09\u3014\u3015\u3010\u3011\u2014\u2026\u2013\uFF0E\u300A\u300B\u3008\u3009\!\@\#\$\%\^\&\*\(\)\-\=\[\]\{\}\\\|\;\'\:\"\,\.\/\<\>\?\/\*\+\_"\u0020]+')
```
需要将html链接、数据来源、用户名、英语字符和其他单个非中文字符清除,采用以上正则表达式描述需要删除的类别,配合sub命令将其从训练集和数据集中删除。
## 3.2 数据划分
数据划分使用的库为jieba分词,具体的操作如下:
```c++
if __name__ =='__main__':
jieba.load_userdict('dict.txt')
jieba.enable_parallel(2)
print("Processing: cutting train data...")
cut_Train_Data = cutData('Train/preprocessed_train_data.csv')
cut_Train_Data.to_csv('Train/preprocessed_train_data.csv')
print("Processing: cutting test data...")
cut_Test_Data = cutData('Test/Test_DataSet_P.csv')
cut_Test_Data.to_csv('Test/result.csv')
```
我们使用的词典并非jieba的内置词典,而是用户自定义词典dict.txt,分词过程开双线程优化。
分词函数cutData的定义:
```python
def cutData(filePath):
cutData = pd.read_csv(filePath,index_col=0)
cutData['title'] = pd.DataFrame(cutData['title'].astype(str))
cutData['title'] = cutData['title'].apply(lambda x: cut_char(x))
cutData['content'] = pd.DataFrame(cutData['content'].astype(str))
cutData['content'] = cutData['content'].apply(lambda x: cut_char(x))
cutData['combine'] = cutData['content']+'/'+70*(cutData['title']+'/')
print(cutData.head())
return cutData
```
分别对数据集的title和content进行分词,并在处理结束之后将二者重新拼接,中间用“/”隔开。在后序的实验中我们发现,标题比文章更能准确地表述新闻的情感(在不碰到UC浏览器的新闻的情况下),所以使用70次重复标题中词语的内容来加大重要性(即其出现频率)。分词方式使用jieba的全精度分词方式。
## 3.3 构建词频矩阵
经过以上两步,我们已经将文本成功分割为独立的中文词语,接下来需要统计每个词出现的频率及分布。
```c++
stop_words=get_custom_stopwords('ChineseStopWords.txt')
```
首先需要获得停用词表。这里我们使用的是百度停用词表、哈工大停用词表、中文停用词表等多个词表的综合结果。
```python
Vectorizer = CountVectorizer( max_df = 0.8,
min_df = 2,
token_pattern = u'(?u)\\b[^\\d\\W]\\w+\\b',
stop_words =frozenset(stop_words)
)
Vectorizer_Title = CountVectorizer( max_df = 0.8,
min_df = 3,
token_pattern = u'(?u)\\b[^\\d\\W]\\w+\\b',
stop_words =frozenset(stop_words) )
```
CountVectorizer是通过fit_transform函数将文本中的词语转换为词频矩阵,矩阵元素a[i][j] 表示j词在第i个文本下的词频。即各个词语出现的次数,通过get_feature_names()可看到所有文本的关键字,通过toarray()可看到词频矩阵的结果。
```c++
X = trainData['content'].astype('U')
y = trainData.label
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=2019)
test = pd.DataFrame(Vectorizer.fit_transform(X_train).toarray(), columns=Vectorizer.get_feature_names())
```
先对文本内容进行词频统计。值得一提的是,在后序的操作中我们相继进行了对标题的词频统计和综合标题和文本的词频统计,并针对这三个矩阵的统计结果进行了三次贝叶斯分类。
此处需要说明的是,我们将训练集中随机选出的80%数据用于分类器的训练,剩余20%用于测试训练的结果。
## 3.4 朴素贝叶斯分类
朴素贝叶斯方法是基于贝叶斯定理的一组有监督学习算法,即“简单”地假设每对特征之间相互独立。 给定一个类别![](https://www.writebug.com/myres/static/uploads/2022/7/29/e295bcd2a22a123dee5352b8d390d1b0.writebug)和一个从![](https://www.writebug.com/myres/static/uploads/2022/7/29/2eba973a6ef6df3ab00519afd02f7423.writebug)到![](https://www.writebug.com/myres/static/uploads/2022/7/29/33f0933b8d3373d81973ddc78fcbea66.writebug)的相关的特征向量, 贝叶斯定理阐述了以下关系:
![](https://www.writebug.com/myres/static/uploads/2022/7/29/6b13233e40d440a1e624ac5b154698bb.writebug)
使用简单(naive)的假设-每对特征之间都相互独立:
![](https://www.writebug.com/myres/static/uploads/2022/7/29/b780b739cd034db6d2430fd12601d4e1.writebug)
对于所有的 i都成立,这个关系式可以简化为
![](https://www.writebug.com/myres/static/uploads/2022/7/29/b033f92087c77f4ee9de891c5ea44c13.writebug)
由于在给定的输入中![](https://www.writebug.c