当前位置:   article > 正文

微博评论情感分析-百度自然语言处理API使用教程_contentalldf = self.get_comment_ori(self.textpath)

contentalldf = self.get_comment_ori(self.textpath) commentcontent = contenta

最近在做微博的评论情感分析,本来想用Tensorflow的RNN来实现,但网上一直找不到好的训练集,在CSDN上买的几万条的微博情感标注集效果也不好,模型对训练集的准确率很高,但放到实际预测中效果很差。

在暂时没有时间自己做标注的情况下,只能先考虑一些现有的工具了,之前用过百度AI的自然语言处理,凑合能用,个人感觉他们的训练集应该量是比较大的,能适应的场景比较多。实际使用后还没有发现很离谱的打标打错的情况,所以记录一下供大家参考,使用的是Python3.6+Requests库。

准备工作

首先要先在百度AI控制台申请一下应用。

创建应用

创建应用后保存自己的API key和Secret key,要用到这两个字段去获取AccessToken,然后再用AccessToken访问API。

应用管理

获取AccessToken

虽然百度API的技术文档里有介绍,但用的是python2.7版本的,而且是urllib库。转换成Requests库更方便,代码如下:

  1. # 获取AccessToken类
  2. class GetAccessToken:
  3. def __init__(self):
  4. # 【修改点1】输入自己在百度AI控制台申请应用后获得的AK和SK
  5. self.AK = ''
  6. self.SK = ''
  7. self.token_url = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id='+self.AK+'&client_secret='+self.SK
  8. self.headers = {'Content-Type':'application/json; charset=UTF-8'}
  9. def get_access_token(self):
  10. r = requests.get(self.token_url,headers = self.headers)
  11. if r.text:
  12. tokenkey = json.loads(r.text)['access_token']
  13. print('get token success')
  14. return tokenkey
  15. else:
  16. print('get token fail')
  17. return ''

将之前申请的API key和Secret key填入字段即可获得AccessToken。

调用API接口

由于是穷人,只能使用普通权限,QPS限制为5,也就是最多这个接口每秒能处理5次请求,超过就会返回错误。但实际的请求速度还是跟网速和电脑配置有关,比如设置了每个0.1秒请求一次,但实际发送请求时有时候是0.1S发送,有时候是0.3S发送,但如果连续多次0.1S发送请求就会报错,因此在调用时考虑每次出现错误就增加一点等待时间,而一段时间没有报错就减少一点等待时间,保持自己能最大化利用免费接口的请求量(这就是穷人的心机吗...)。代码解释见注释,直接使用需修改两个地方1.更改待分析文本所在文件夹地址;2.根据自己文本的格式,修改读取文件的方式

  1. # 调用API类
  2. class SentimentBaidu:
  3. def __init__(self,tp):
  4. # 调用自己需要使用的API,这里使用情感分析API作为示例,其他接口查询百度AI说明文档后替换 + 前的URL
  5. self.HOST = 'https://aip.baidubce.com/rpc/2.0/nlp/v1/sentiment_classify' + '?charset=UTF-8&access_token='
  6. self.headers = {'Content-Type': 'application/json','Connection': 'close'}
  7. self.textpath = tp
  8. self.commentcomment = []
  9. self.count = 0
  10. # 速度设置,对应百度AI的QPS限制,由于request发送请求的速度跟网速、设备性能有关,所以虽然限制是5QPS,但可以把请求的间隔写短点,这里采用的是最快0.06s
  11. self.speedlimit = 0.06
  12. # 初始速度,后续实际请求速度程序自动根据错误调整
  13. self.sleepdt = 0.08
  14. self.errorwaittime = 0.5
  15. self.qpserror = 0
  16. self.qpserrorindex = 0
  17. self.errorallcount = 0
  18. # 调用百度API获得情感分析结果方法
  19. def get_content_sentiments(self,text,at):
  20. raw = {'text': text}
  21. data = json.dumps(raw).encode('gbk')
  22. url = self.HOST+at
  23. try:
  24. if self.count - self.qpserrorindex > 500:
  25. if self.sleepdt > self.speedlimit:
  26. self.sleepdt -= 0.001
  27. print('speed up, current speed:',
  28. self.sleepdt)
  29. self.qpserrorindex = self.count
  30. time.sleep(self.sleepdt)
  31. r = requests.post(url=url, data=data, headers=self.headers)
  32. if 'error_code' in r.text:
  33. error = r.json()['error_code']
  34. print('error_code',error)
  35. if error == 18:
  36. self.errorallcount += 1
  37. self.qpserror += 1
  38. self.qpserrorindex = self.count
  39. self.sleepdt += 0.001
  40. print('current qps error count = ', self.qpserror, 'speed down, current speed:', self.sleepdt, self.errorallcount)
  41. time.sleep(self.errorwaittime)
  42. content = r.json()
  43. except Exception as e:
  44. self.errorallcount += 1
  45. time.sleep(self.errorwaittime)
  46. return
  47. try:
  48. if content['items']:
  49. contentposprob = content['items'][0]['positive_prob']
  50. contentnegprob = content['items'][0]['negative_prob']
  51. contentconfi = content['items'][0]['confidence']
  52. contentsenti = content['items'][0]['sentiment']
  53. temp = [contentposprob,contentnegprob,contentconfi,contentsenti]
  54. return temp
  55. except KeyError as e:
  56. self.errorallcount += 1
  57. print('error reason:',content)
  58. time.sleep(self.errorwaittime)
  59. return
  60. # 使用pandas读取所有待分析文本
  61. def get_comment_ori(self,fp):
  62. fpath = fp
  63. fpl = os.listdir(fpath)
  64. contentall = []
  65. for file in fpl:
  66. fd = fpath + '/' + file
  67. print('reading',fd)
  68. temp = pd.read_csv(fd)
  69. contentall.append(temp)
  70. contentalldf = pd.concat(contentall, ignore_index=True, sort=False)
  71. print('comment get:',contentalldf.shape[0])
  72. return contentalldf
  73. # 主程序
  74. def run(self):
  75. requests.adapters.DEFAULT_RETRIES = 5
  76. ATclass = GetAccessToken()
  77. AT = ATclass.get_access_token()
  78. print('progress start current speed = ', self.sleepdt)
  79. # 【修改点3】以下4行为获取文本,可选择自己常用的方式,将所有文本待分析文本放到一个iterator中,这里使用的pandas读取文本
  80. contentalldf = self.get_comment_ori(self.textpath)
  81. commentcontent = contentalldf['commentContent']
  82. commentcontent = pd.DataFrame(commentcontent)
  83. commentcontent.columns = ['comment']
  84. # 如果在调用接口前想先对文本符号、表情等信息进行清理,可调用clean_comment函数,通过pandas的apply快速处理所有文本
  85. # commentcontent['comment'] = commentcontent['comment'].apply(self.clean_comment)
  86. for comment in commentcontent['comment']:
  87. if comment:
  88. self.count += 1
  89. if self.count % 100 == 0:
  90. print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())),'正在处理第{0}条评论'.format(self.count))
  91. commentsenti = self.get_content_sentiments(comment,AT)
  92. if commentsenti is not None:
  93. commentbatch = [comment]+commentsenti
  94. self.commentcomment.append(commentbatch)
  95. if self.count % 100 == 0:
  96. commentsentidf = pd.DataFrame(self.commentcomment,
  97. columns=['comment', 'contentposprob', 'contentnegprob',
  98. 'contentconfi', 'contentsenti'])
  99. fpath = self.textpath + '/cpbaidu.csv'
  100. if os.path.exists(fpath):
  101. commentsentidf.to_csv(fpath, mode='a', encoding='utf-8-sig', index=False, header=False)
  102. else:
  103. commentsentidf.to_csv(fpath, encoding='utf-8-sig', index=False)
  104. # print('write to path',fpath,'write num:',commentsentidf.shape[0])
  105. self.commentcomment = []
  106. print('finished progress')
  107. # 文本清理方法,可选是否剔除文本内的符号、空格、emoji的剔除
  108. def clean_comment(self,text):
  109. emoji = re.compile(u'['
  110. u'\U0001F300-\U0001F64F'
  111. u'\U0001F680-\U0001F6FF'
  112. u'\u2600-\u2B55]+',
  113. re.UNICODE)
  114. text = re.sub("[\s+\.\!\/_,$%^*(+\"\']+|[+——!,。?、~@#¥%……&*()::]+", "", text)
  115. text = re.sub(emoji,'',text)
  116. return text
  117. if __name__=='__main__':
  118. tp = '' # 【修改点2】修改为自己的文本存储的文件夹位置
  119. runner = SentimentBaidu(tp)
  120. runner.run()

调用效果

实际效果打标结果只能说勉强能用,而且由于之前没有做停用词去除,所以很多微博名字也被放到文本中进行分析了,所以最好在将文本提交API之前先对文本进行清理,去掉停用词和符号等内容,另外如果纯表情的微博回复调用接口会直接报空,也可以提前清除。打标结果如下,后面字段分别为,积极概率,消极概率,判断信心,情感分类(0消极 1中性 2积极)

打标效果

 

完整项目见:https://github.com/pandasgb/SentimentAnalysisWithBaiduAI

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/359497
推荐阅读
相关标签
  

闽ICP备14008679号