Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
T
Text-sentiment-analysis
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
202205008011
Text-sentiment-analysis
Commits
48b809b2
Commit
48b809b2
authored
Sep 28, 2022
by
202205008011
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Upload New File
parent
21f4cacd
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
348 additions
and
0 deletions
+348
-0
starter_code.ipynb
+348
-0
No files found.
starter_code.ipynb
0 → 100644
View file @
48b809b2
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 情感分析项目"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"本项目的目标是基于用户提供的评论,通过算法自动去判断其评论是正面的还是负面的情感。比如给定一个用户的评论:\n",
"- 评论1: “我特别喜欢这个电器,我已经用了3个月,一点问题都没有!”\n",
"- 评论2: “我从这家淘宝店卖的东西不到一周就开始坏掉了,强烈建议不要买,真实浪费钱”\n",
"\n",
"对于这两个评论,第一个明显是正面的,第二个是负面的。 我们希望搭建一个AI算法能够自动帮我们识别出评论是正面还是负面。\n",
"\n",
"情感分析的应用场景非常丰富,也是NLP技术在不同场景中落地的典范。比如对于一个证券领域,作为股民,其实比较关注舆论的变化,这个时候如果能有一个AI算法自动给网络上的舆论做正负面判断,然后把所有相关的结论再整合,这样我们可以根据这些大众的舆论,辅助做买卖的决策。 另外,在电商领域评论无处不在,而且评论已经成为影响用户购买决策的非常重要的因素,所以如果AI系统能够自动分析其情感,则后续可以做很多有意思的应用。 "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"情感分析是文本处理领域经典的问题。整个系统一般会包括几个模块:\n",
"- 数据的抓取: 通过爬虫的技术去网络抓取相关文本数据\n",
"- 数据的清洗/预处理:在本文中一般需要去掉无用的信息,比如各种标签(HTML标签),标点符号,停用词等等\n",
"- 把文本信息转换成向量: 这也成为特征工程,文本本身是不能作为模型的输入,只有数字(比如向量)才能成为模型的输入。所以进入模型之前,任何的信号都需要转换成模型可识别的数字信号(数字,向量,矩阵,张量...)\n",
"- 选择合适的模型以及合适的评估方法。 对于情感分析来说,这是二分类问题(或者三分类:正面,负面,中性),所以需要采用分类算法比如逻辑回归,朴素贝叶斯,神经网络,SVM等等。另外,我们需要选择合适的评估方法,比如对于一个应用,我们是关注准确率呢,还是关注召回率呢? "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"在本次项目中,我们已经给定了训练数据和测试数据,它们分别是 ``train.positive.txt``, ``train.negative.txt``, ``test_combined.txt``. 请注意训练数据和测试数据的格式不一样,详情请见文件内容。 整个项目你需要完成以下步骤:\n",
"\n",
"数据的读取以及清洗: 从给定的.txt中读取内容,并做一些数据清洗,这里需要做几个工作: \n",
"- (1) 文本的读取,需要把字符串内容读进来。 \n",
"- (2)去掉无用的字符比如标点符号,多余的空格,换行符等 \n",
"- (3) 把文本转换成``TF-IDF``向量: 这部分直接可以利用sklearn提供的``TfidfVectorizer``类来做。\n",
"- (4) 利用逻辑回归等模型来做分类,并通过交叉验证选择最合适的超参数\n",
"\n",
"项目中需要用到的数据:\n",
"- ``train.positive.txt``, ``train.negative.txt``, ``test_combined.txt``: 训练和测试数据\n",
"- ``stopwords.txt``: 停用词库\n",
"\n",
"\n",
"你需要完成的部分为标记为`TODO`的部分。 \n",
"\n",
"另外,提交作业时候的注意点:\n",
"> 1. 不要试图去创建另外一个.ipynb文件,所有的程序需要在`starter_code.ipynb`里面实现。很多的模块已经帮你写好,不要试图去修改已经定义好的函数以及名字。 当然,自己可以按需求来创建新的函数。但一定要按照给定的框架来写程序,不然判作业的时候会出现很多问题。 \n",
"> 2. 作业可以讨论,但请自己完成。让我们一起遵守贪心学院的`honor code`。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 1. File Reading: 文本读取 "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def process_file():\n",
" \"\"\"\n",
" 读取训练数据和测试数据,并对它们做一些预处理\n",
" \"\"\" \n",
" train_pos_file = \"data/train_positive.txt\"\n",
" train_neg_file = \"data/train_negative.txt\"\n",
" test_comb_file = \"data/test_combined.txt\"\n",
" \n",
" # TODO: 读取文件部分,把具体的内容写入到变量里面\n",
" train_comments = []\n",
" train_labels = []\n",
" test_comments = []\n",
" test_labels = []"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 2. Explorary Analysis: 做一些简单的可视化分析"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# 训练数据和测试数据大小\n",
"print (len(train_comments), len(test_comments))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"> 这里有一个假设想验证。我觉得,如果一个评论是负面的,则用户留言时可能会长一些,因为对于负面的评论,用户很可能会把一些细节写得很清楚。但对于正面的评论,用户可能就只写“非常好”,这样的短句。我们想验证这个假设。 为了验证这个假设,打算画两个直方图,分别对正面的评论和负面的评论。 具体的做法是:1. 把正面和负面评论分别收集,之后分别对正面和负面评论画一个直方图。 2. 直方图的X轴是评论的长度,所以从是小到大的顺序。然后Y轴是对于每一个长度,出现了多少个正面或者负面的评论。 通过两个直方图的比较,即可以看出``评论``是否是一个靠谱的特征。\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# TODO: 对于训练数据中的正负样本,分别画出一个histogram, histogram的x抽是每一个样本中字符串的长度,y轴是拥有这个长度的样本的百分比。\n",
"# 并说出样本长度是否对情感有相关性 (需要先用到结巴分词)\n",
"# 参考:https://baike.baidu.com/item/%E7%9B%B4%E6%96%B9%E5%9B%BE/1103834?fr=aladdin\n",
"# 画饼状图参考: https://pythonspot.com/matplotlib-histogram/ \n",
"# https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.pyplot.hist.html\n",
"\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"// TODO: 情感跟评论长度是否有相关性?\n",
"\n",
"// 你的答案.....\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 3. 文本预处理\n",
"> 在此部分需要做文本预处理方面的工作。 分为几大块:\n",
"- ``去掉特殊符号`` 比如#$.... 这部分的代码已经给出,不需要自己写\n",
"- ``把数字转换成特殊单词`` 把数字转换成 \" NUM \", 这部分需要写。 注意:NUM前面和后面加一个空格,这样可以保证之后分词时被分掉。\n",
"- ``分词并过滤掉停用词`` 停用词库已经提供,需要读取停用词库,并按照此停用词库做过滤。 停用词库使用给定的文件:``stopwords.txt`` "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def clean_symbols(text):\n",
" \"\"\"\n",
" 对特殊符号做一些处理,此部分已写好。如果不满意也可以自行改写,不记录分数。\n",
" \"\"\"\n",
" text = re.sub('[!!]+', \"!\", text)\n",
" text = re.sub('[??]+', \"?\", text)\n",
" text = re.sub(\"[a-zA-Z#$%&\\'()*+,-./:;:<=>@,。★、…【】《》“”‘’[\\\\]^_`{|}~]+\", \" OOV \", text)\n",
" return re.sub(\"\\s+\", \" \", text) \n",
"\n",
"\n",
"# TODO:对于train_comments, test_comments进行字符串的处理,几个考虑的点:\n",
"# 1. 去掉特殊符号\n",
"# 2. 把数字转换成特殊字符或者单词\n",
"# 3. 分词并做停用词过滤\n",
"# 4. ... (或者其他)\n",
"#\n",
"# 需要注意的点是,由于评论数据本身很短,如果去掉的太多,很可能字符串长度变成0\n",
"# 预处理部分,可以自行选择合适的方.\n",
"\n",
"\n",
"train_comments_cleaned = [] \n",
"test_comments_cleaned = []"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# 打印一下看看\n",
"print (train_comments_cleaned[0], test_comments_cleaned[0])\n",
"print (train_comments_cleaned[1], test_comments_cleaned[1])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 4. 把文本转换成向量\n",
"> 预处理好文本之后,我们就需要把它转换成向量形式,这里我们使用tf-idf的方法。 sklearn自带此功能,直接调用即可。输入就是若干个文本,输出就是每个文本的tf-idf向量。详细的使用说明可以在这里找到: 参考:https://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.text.TfidfVectorizer.html 这里需要特别注意的一点是:对于训练数据调用fit_transform, 也就是训练的过程。 但对于测试数据,不能再做训练,而是直接使用已经训练好的object做transform操作。思考一下为什么要这么做?\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# TODO: 利用tf-idf从文本中提取特征,写到数组里面. \n",
"# 参考:https://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.text.TfidfVectorizer.html\n",
"\n",
"X_train = # 训练数据的特征\n",
"y_train = # 训练数据的label\n",
"X_test = # 测试数据的特征\n",
"y_test = # 测试数据的label\n",
"\n",
"print (np.shape(X_train), np.shape(X_test), np.shape(y_train), np.shape(y_test))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 5. 通过交叉验证来训练模型\n",
"> 接下来需要建模了! 这里我们分别使用逻辑回归,朴素贝叶斯和SVM来训练。针对于每一个方法我们使用交叉验证(gridsearchCV), 并选出最好的参数组合,然后最后在测试数据上做验证。 这部分已经在第二次作业中讲过。"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from sklearn.linear_model import LogisticRegression\n",
"# TODO: 利用逻辑回归来训练模型\n",
"# 1. 评估方式: F1-score\n",
"# 2. 超参数(hyperparater)的选择利用grid search https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.GridSearchCV.html\n",
"# 3. 打印出在测试数据中的最好的结果(precision, recall, f1-score, 需要分别打印出正负样本,以及综合的)\n",
"# 请注意:做交叉验证时绝对不能用测试数据。 测试数据只能用来最后的”一次性“检验。\n",
"# 逻辑回归的使用方法请参考:http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html\n",
"# 对于逻辑回归,经常调整的超参数为: C\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from sklearn.naive_bayes import MultinomialNB\n",
"# TODO: 利用朴素贝叶斯来训练模型\n",
"# 1. 评估方式: F1-score\n",
"# 2. 超参数(hyperparater)的选择利用grid search https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.GridSearchCV.html\n",
"# 3. 打印出在测试数据中的最好的结果(precision, recall, f1-score, 需要分别打印出正负样本,以及综合的)\n",
"# 请注意:做交叉验证时绝对不能用测试数据。 测试数据只能用来最后的”一次性“检验。\n",
"# 朴素贝叶斯的使用方法请参考:https://scikit-learn.org/stable/modules/generated/sklearn.naive_bayes.MultinomialNB.html#sklearn.naive_bayes.MultinomialNB\n",
"# 对于朴素贝叶斯,一般不太需要超参数的调节。但如果想调参,也可以参考上面的链接,有几个参数是可以调节的。 \n",
"\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from sklearn import svm\n",
"# TODO: 利用SVM来训练模型\n",
"# 1. 评估方式: F1-score\n",
"# 2. 超参数(hyperparater)的选择利用grid search https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.GridSearchCV.html\n",
"# 3. 打印出在测试数据中的最好的结果(precision, recall, f1-score, 需要分别打印出正负样本,以及综合的)\n",
"# 请注意:做交叉验证时绝对不能用测试数据。 测试数据只能用来最后的”一次性“检验。\n",
"# SVM的使用方法请参考:http://scikit-learn.org/stable/modules/generated/sklearn.svm.SVC.html\n",
"# 对于SVM模型,经常调整的超参数为:C, gamma, kernel。 这里的参数C跟逻辑回归是一样的, gamma和kernel是针对于SVM的参数\n",
"# 在这里先不要考虑他们的含义(或者通过官方文档试图理解一下), 在课程最后的部分会讲到这些内容。 \n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"> 对于超参数的调整,我们经常使用gridsearch,这也是工业界最常用的方法,但它的缺点是需要大量的计算,所以近年来这方面的研究也成为了重点。 其中一个比较经典的成果为Bayesian Optimization(利用贝叶斯的思路去寻找最好的超参数)。Ryan P. Adams主导的Bayesian Optimization利用高斯过程作为后验概率(posteior distribution)来寻找最优解。 https://papers.nips.cc/paper/4522-practical-bayesian-optimization-of-machine-learning-algorithms.pdf 在下面的练习中,我们尝试使用Bayesian Optimization工具来去寻找最优的超参数。参考工具:https://github.com/fmfn/BayesianOptimization 感兴趣的朋友可以去研究一下。 "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 6. 思考题 \n",
"1. 对于情感分析来说,有一个问题也很重要,比如一个句子里出现了 “我不太兴奋”, “不是很满意”。 在这种情况,因为句子中出现了一些积极的词汇很可能被算法识别成正面的,但由于前面有一个“不”这种关键词,所以否定+肯定=否定,算法中这种情况也需要考虑。另外,否定+否定=肯定, 这种情况也一样。 \n",
"2. 另外一个问题是aspect-based sentiment analysis, 这个指的是做情感分析的时候,我们既想了解情感,也想了解特定的方面。 举个例子: “这部手机的电池性能不错,但摄像不够清晰啊!”, 分析完之后可以得到的结论是: “电池:正面, 摄像:负面”, 也就是针对于一个产品的每一个性能做判定,这种问题我们叫做aspect-based sentiment analysis,也是传统情感分析的延伸。\n",
"\n",
">``Q``: 对于如上两个问题,有什么解决方案? 大概列一下能想到的处理方案。 用简介的文字来描述即可。 "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"// 你的答案在这里.......\n",
"\n",
"\n",
"\n",
"\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 7. 其他领域(仅供参考)\n",
"跟情感分析类似的领域有叫affective computing, 也就是用来识别情绪(emotion recognition)。但情感和情绪又不太一样,情绪指的是高兴,低落,失落,兴奋这些人的情绪。我们知道真正的人工智能是需要读懂人类的情绪的。而且情绪识别有很多场景,比如服务机器人根据不同的情绪来跟用户交流; 无人驾驶里通过识别用户的情绪(摄像头或者声音或者传感器)来保证安全驾驶; IOT领域里设备也需要读懂我们的情绪; 微博里通过文本读懂每个人发文时的情绪。 \n",
"\n",
"总体来讲,情绪识别跟情感识别所用到的技术是类似的,感兴趣的小伙伴,也可以关注一下这个领域。 如果想发论文,强烈建议选择情绪方面的,不建议选择情感分析,因为问题太老了。情绪分析是近几年才开始受关注的领域。 "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.1"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment