当前位置:   article > 正文

用python调用百度AI进行情感分析探索与股票之间的关系_股票评论数据采集与情感分析的分析方法

股票评论数据采集与情感分析的分析方法

听闻有人在Twitter上分析股民的情绪来炒股,盈利不少。就来试试看。

具体过程:

一、数据采集

通过采集东方财富上某只股票一段时间内股票的评论,这里以恒生电子为例。我自己编写了爬虫代码。如下:

  1. import re,requests,codecs,time,random
  2. from lxml import html
  3. #proxies={"http" : "123.53.86.133:61234"}
  4. proxies=None
  5. headers = {
  6. 'Host': 'guba.eastmoney.com',
  7. 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.221 Safari/537.36 SE 2.X MetaSr 1.0'}
  8. def get_url(page):
  9. stocknum=600570
  10. url='http://guba.eastmoney.com/list,'+str(stocknum)+'_'+str(page)+'.html'
  11. try:
  12. text=requests.get(url,headers=headers,proxies=proxies,timeout=20)
  13. requests.adapters.DEFAULT_RETRIES = 5
  14. s = requests.session()
  15. s.keep_alive = False
  16. text=html.fromstring(text.text)
  17. urls=text.xpath('//div[@id="articlelistnew"]/div[@class="articleh"]/span[3]/a/@href')
  18. except Exception as e:
  19. print(e)
  20. time.sleep(random.random() + random.randint(0, 3))
  21. urls=''
  22. return urls
  23. def get_comments(urls):
  24. for newurl in urls:
  25. newurl1='http://guba.eastmoney.com'+newurl
  26. try:
  27. text1=requests.get(newurl1,headers=headers,proxies=proxies,timeout=20)
  28. requests.adapters.DEFAULT_RETRIES = 5
  29. s = requests.session()
  30. s.keep_alive = False
  31. text1=html.fromstring(text1.text)
  32. times1=text1.xpath('//div[@class="zwli clearfix"]/div[3]/div/div[2]/text()')
  33. times='!'.join(re.sub(re.compile('发表于| '),'',x)[:10] for x in times1).split('!')
  34. #times=list(map(lambda x:re.sub(re.compile('发表于| '),'',x)[:10],times))
  35. comments1=text1.xpath('//div[@class="zwli clearfix"]/div[3]/div/div[3]/text()')
  36. comments='!'.join(w.strip() for w in comments1).split('!')
  37. dic=dict(zip(times,comments))
  38. save_to_file(dic)
  39. except:
  40. print('error!!!!')
  41. time.sleep(random.random()+random.randint(0,3))
  42. #print(dic)
  43. #if times and comments:
  44. #dic.append({'time':times,'comment':comments})
  45. #return dic
  46. def save_to_file(dic):
  47. if dic:
  48. #dic=dic
  49. print(dic)
  50. #df=pd.DataFrame([dic]).T
  51. #df.to_excel('eastnoney.xlsx')
  52. for i,j in dic.items():
  53. output='{}\t{}\n'.format(i,j)
  54. f=codecs.open('eastmoney.xls','a+','utf-8')
  55. f.write(output)
  56. f.close()
  57. for page in range(2,1257):
  58. print('正在爬取第{}页'.format(page))
  59. urls=get_url(page)
  60. dic=get_comments(urls)

我爬取了2017年8月-2018年3月份恒生电子股吧股民个评论,具体如下:

看看大家都在讨论啥,词云的代码可以参考python生成词云,中间一排的绿绿绿绿。看来大家不看好啊。。。。。

接下来是获取对应时间段恒生电子的历史股票数据,我找了很久,终于找了一个不错的接口传送门,直接复制到Excel就可以了。

接下来,用python画出K线图,这部分代码参考了画K线图

  1. from pandas import DataFrame, Series
  2. import pandas as pd; import numpy as np
  3. import matplotlib.pyplot as plt
  4. from matplotlib import dates as mdates
  5. from matplotlib import ticker as mticker
  6. from matplotlib.finance import candlestick_ohlc
  7. from matplotlib.dates import DateFormatter, WeekdayLocator, DayLocator, MONDAY,YEARLY
  8. from matplotlib.dates import MonthLocator,MONTHLY
  9. import datetime
  10. import pylab
  11. MA1 = 10#移动平均线的日期间隔
  12. MA2 = 50
  13. #'股票代码,名称,收盘价,最高价,最低价,开盘价,前收盘,涨跌额,涨跌幅,换手率,成交量,成交金额,总市值,流通市值
  14. startdate = datetime.date(2017,8,1)
  15. enddate = datetime.date(2018, 3, 26)
  16. data=pd.DataFrame(pd.read_excel('eastmoney.xlsx',sheet_name=1,index_col='日期'))#读取数据、设置日期为index
  17. data=data.sort_index()#按日期升序排列
  18. #抽取需要的列组成新的表
  19. stdata=pd.DataFrame({'DateTime':data.index,'Open':data.开盘价,'High':data.最高价,'Close':data.收盘价,'Low':data.最低价})
  20. stdata['DateTime'] = mdates.date2num(stdata['DateTime'].astype(datetime.date))#把日期转化成天数,从公元0年开始算
  21. #stdata=stdata.set_index('DateTime')
  22. #stdata.drop(data.columns[6:],axis=1,inplace=True),stdata['Volume']=data.涨跌幅,del stdata['名称']
  23. def main():
  24. daysreshape = stdata.reset_index()
  25. daysreshape = daysreshape.reindex(columns=['DateTime', 'Open', 'High', 'Low', 'Close'])
  26. Av1 = pd.rolling_mean(daysreshape.Close.values, MA1)
  27. Av2 = pd.rolling_mean(daysreshape.Close.values, MA2)
  28. SP = len(daysreshape.DateTime.values[MA2 - 1:])
  29. fig = plt.figure(facecolor='#07000d', figsize=(15, 10))
  30. ax1 = plt.subplot2grid((6, 4), (1, 0), rowspan=4, colspan=4, axisbg='#07000d')
  31. candlestick_ohlc(ax1, daysreshape.values[-SP:], width=.6, colorup='#ff1717', colordown='#53c156')
  32. Label1 = str(MA1) + ' SMA'
  33. Label2 = str(MA2) + ' SMA'
  34. ax1.plot(daysreshape.DateTime.values[-SP:], Av1[-SP:], '#e1edf9', label=Label1, linewidth=1.5)
  35. ax1.plot(daysreshape.DateTime.values[-SP:], Av2[-SP:], '#4ee6fd', label=Label2, linewidth=1.5)
  36. ax1.grid(True, color='w')
  37. ax1.xaxis.set_major_locator(mticker.MaxNLocator(10))
  38. ax1.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))
  39. ax1.yaxis.label.set_color("w")
  40. ax1.spines['bottom'].set_color("#5998ff")
  41. ax1.spines['top'].set_color("#5998ff")
  42. ax1.spines['left'].set_color("#5998ff")
  43. ax1.spines['right'].set_color("#5998ff")
  44. ax1.tick_params(axis='y', colors='w')
  45. plt.gca().yaxis.set_major_locator(mticker.MaxNLocator(prune='upper'))
  46. ax1.tick_params(axis='x', colors='w')
  47. plt.ylabel('Stock price and Volume')
  48. plt.show()
  49. if __name__ == "__main__":
  50. main()

看看运行的效果,好像还挺不错的。

接下来,要对爬下来的股票的评论进行情感分析,这里调用百度AI的情感分析。

  1. import pandas as pd
  2. import datetime
  3. from aip import AipNlp
  4. import codecs
  5. startdate = datetime.date(2017, 8, 1).strftime('%Y-%m-%d')
  6. enddate = datetime.date(2018, 3, 27).strftime('%Y-%m-%d')
  7. APP_ID = '你的id'
  8. API_KEY = '你的key'
  9. SECRET_KEY = '你的key'
  10. client = AipNlp(APP_ID, API_KEY, SECRET_KEY)
  11. def get_sentiments(text,dates):
  12. try:
  13. sitems=client.sentimentClassify(text)['items'][0]#情感分析
  14. positive=sitems['positive_prob']#积极概率
  15. confidence=sitems['confidence']#置信度
  16. sentiment=sitems['sentiment']#0表示消极,1表示中性,2表示积极
  17. #tagitems = client.commentTag(text, {'type': 9}) # 评论观点
  18. #propertys=tagitems['prop']#属性
  19. #adj=tagitems['adj']#描述词
  20. output='{}\t{}\t{}\t{}\n'.format(dates,positive,confidence,sentiment)
  21. f=codecs.open('sentiment.xls','a+','utf-8')
  22. f.write(output)
  23. f.close()
  24. print('Done')
  25. except Exception as e:
  26. print(e)
  27. def get_content():
  28. data=pd.DataFrame(pd.read_excel('eastmoney.xlsx',sheet_name=0))
  29. data.columns=['Dates','viewpoints']#重设表头
  30. data=data.sort_values(by=['Dates'])#按日期排列
  31. vdata=data[data.Dates>=startdate]#提取对应日期的数据
  32. newvdata=vdata.groupby('Dates').agg(lambda x:list(x))#按日期分组,把同一天的评论并到一起
  33. return newvdata
  34. viewdata=get_content()
  35. for i in range(viewdata.shape[0]):
  36. print('正在处理第{}条,还剩{}条'.format(i,viewdata.shape[0]-1))
  37. dates=viewdata.index[i]
  38. for view in viewdata.viewpoints[i]:
  39. print(view)
  40. get_sentiments(view,dates)
 

处理完大概是这样的效果。

接着,我们画出曲线图处理。

  1. import pandas as pd
  2. from datetime import datetime
  3. from pylab import *
  4. import matplotlib.dates as mdates
  5. import dateutil, pylab, random
  6. from pylab import *
  7. import matplotlib.pyplot as plt
  8. data=pd.DataFrame(pd.read_excel('sentiment.xlsx'))
  9. data.columns=['date','positive','confidence','sentiments']
  10. newdata=data.groupby('date').agg(lambda x:list(x))## 相同日期的聚一起
  11. times=[]
  12. sentiment=[]
  13. for i in range(1,newdata.shape[0]):
  14. p=newdata.positive[i]
  15. d=newdata.index[i]
  16. sum=0
  17. for z in p:
  18. sum+=z
  19. average=sum/len(p)
  20. times.append(d)
  21. sentiment.append(average)
  22. pylab.plot_date(pylab.date2num(times), sentiment, linestyle='-')
  23. xtext = xlabel('time')
  24. ytext = ylabel('sentiments')
  25. ttext = title('sentiments')
  26. grid(True)
  27. setp(ttext, size='large', color='r')
  28. show()

 

画出来是这个样子的。

好像看不出来,那么,画一张图看看呢。股票的价格取每天的均价。

  1. import pandas as pd
  2. import matplotlib.pyplot as plt
  3. data1=pd.read_excel('sentiment.xlsx',sheet_name=0)
  4. data1=data1.fillna(method='pad')#因为周末没开盘,所以用周五的价格填充,保证画图连续性
  5. #newdata=pd.merge(data1,data2,how='left',left_on='date',right_on='日期')
  6. x=data1.date
  7. y1=data1.pos
  8. y2=data1.price
  9. fig = plt.figure()
  10. ax1 = fig.add_subplot(111)
  11. ax1.plot(x, y1)
  12. ax1.set_ylabel('sitiment')
  13. ax1.set_title("Sentiment")
  14. ax1.legend(loc='upper right')
  15. ax2 = ax1.twinx()#设置双y轴
  16. ax2.plot(x, y2, 'r')
  17. ax2.set_ylabel('stock price')
  18. ax2.set_xlabel('date')
  19. ax2.legend(loc='upper left')
  20. plt.show()

看得出有轻微的关系,但是没那么明显。

总结一下可能的原因:

1.可能是百度的情感分析不是很准,比如我试了‘今天天气不错,但是我并不开心’,给我积极的概率是0.8,显然不是很正确。

2.采集的评论没有过滤,或者信息量不是很大,需要更新采集数据源。

3.可能真的并没有那么大的关联。

 

 

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/498413
推荐阅读
相关标签
  

闽ICP备14008679号