區塊鏈研究實驗室|用Java構建基於Twitter的比特幣情感分析器

買賣虛擬貨幣

比特幣建立於2009年,仍然是一個相當年輕的專案。但其市場價格非常不穩定。此外,比特幣對大眾效應更為敏感,比如像2017年底那樣大眾為佔據的FOMO感覺一樣。在大眾的興奮情緒推動下,比特幣價格曾高達到2萬美元的歷史高點。能夠衡量圍繞比特幣的這種型別的情緒,可以很好地表明未來幾個小時內等待比特幣價格的因素。一個好的解決方案是分析像Twitter這樣的社交網路上圍繞比特幣的活動。在本文中,我將教您如何建立一個Java程式,從Twitter上檢索的tweets中分析關於比特幣的所有大眾情緒。

比特幣情緒分析器規範您將學習開發的比特幣情緒分析器在執行過程中將執行以下操作:1. 在Twitter上檢索包含關鍵字bitcoin的推文2. 分析每條檢索到的推文,以及檢測與之相關的大眾情緒3. 在Twitter上顯示以下5種比特幣情緒各自的百分比:非常消極,消極,中立,積極,非常積極該程式將在每次執行後結束,由於Twitter是使用其免費的開發人員API設定的配額,將不會連續執行此分析。

建立Java專案第一步是建立一個Java專案。我們將使用Maven作為依賴關係管理器。在依賴性方面,我們將具有以下程式碼庫:

Twitter4J是Twitter API的非官方Java客戶端

Stanford CoreNLP是一個用於自然語言處理的開源庫Twitter4J將允許我們以一種簡單的方式從Twitter中檢索tweets的推文樣本。Stanford CoreNLP程式碼庫將使我們能夠檢測與每個相關推文相關的情緒。這為我們的專案提供了以下POM:

<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.ssaurel</groupId><artifactId>bitcoinsentiment</artifactId><version>0.0.1-SNAPSHOT</version><packaging>jar</packaging><name>bitcoinsentiment</name><url>http://maven.apache.org</url><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>edu.stanford.nlp</groupId><artifactId>stanford-corenlp</artifactId><version>3.9.2</version></dependency><dependency><groupId>edu.stanford.nlp</groupId><artifactId>stanford-corenlp</artifactId><version>3.9.2</version><classifier>models</classifier></dependency><dependency><groupId>org.twitter4j</groupId><artifactId>twitter4j-core</artifactId><version>[4.0,)</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-simple</artifactId><version>1.6.1</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>3.8.1</version><scope>test</scope></dependency></dependencies></project>

建立一個Twitter應用程式使用Twitter API需要建立開發者帳戶。它是免費的,但會有一定呼叫次數和配額限制使用。作為我們用於展示目的的專案的一部分,這是完全足夠的。使用Twitter API所需的開發者帳戶的建立在此處完成:開發者地址https://developer.twitter.com/建立此帳戶後,您將轉到下一頁:

您將需要建立一個新的應用程式。我選擇將我的應用程式命名為“ Bitcoin_Sentiment_Analyzer”。在建立此應用程式期間,您將必須填寫有關它的一定數量的資訊。最後,您將到達“Keys and tokens””螢幕,在該螢幕上,您將找到使您在呼叫Twitter API來檢索與比特幣相關的推文時正確進行身份驗證的資訊:

檢索推文現在已經建立了與比特幣情緒分析器關聯的Twitter應用程式,我們將能夠繼續檢索程式中的推文。為此,我們將依靠Twitter4J程式碼庫。Twitter4J具有TwitterFactory和Twitter類作為其入口點。TwitterFactory類將包含與Twitter API的連線資訊的Configuration物件例項作為輸入:

使用者API公鑰

使用者API金鑰

訪問Token

訪問Token金鑰然後,我將透過呼叫其getInstance方法從TwitterFactory檢索Twitter物件例項的例項。有了這個物件,我們將能夠在Twitter API上啟動查詢。我們將使用其搜尋方法來檢索符合特定條件的推文。在Query物件中對查詢建模,該物件以與您要透過Twitter API執行的查詢相對應的字串作為輸入。對於比特幣情緒分析器,我想檢索包含關鍵字bitcoin的推文,而不是轉發,連結,答案或圖片。該查詢用以下字串表示:

bitcoin-filter:retweets-filter:links-filter:replies-filter:imagesQuery類的setCount方法允許您定義要檢索的結果數。如果使用免費的開發人員API,則此數量限制為100個結果。最後,仍然需要透過從Twitter物件例項的search方法傳遞該查詢來執行此查詢 返回一個QueryResult物件,將其保留在其上以呼叫getTweets方法以檢索Status物件的列表。每個Status物件代表一條推文。最終可以透過後一個物件的getText方法訪問其文字內容。所有這些提供了以下searchTweets方法:

publicstaticList<Status>searchTweets(Stringkeyword){List<Status>tweets=Collections.emptyList();ConfigurationBuildercb=newConfigurationBuilder();cb.setDebugEnabled(true).setOAuthConsumerKey("YOUR_CONSUMER_KEY").setOAuthConsumerSecret("YOUR_CONSUMER_SECRET").setOAuthAccessToken("YOUR_ACCESS_TOKEN").setOAuthAccessTokenSecret("YOUR_ACCESS_TOKEN_SECRET");TwitterFactorytf=newTwitterFactory(cb.build());Twittertwitter=tf.getInstance();Queryquery=newQuery(keyword+"-filter:retweets-filter:links-filter:replies-filter:images");query.setCount(100);query.setLocale("en");query.setLang("en");;try{QueryResultqueryResult=twitter.search(query);tweets=queryResult.getTweets();}catch(TwitterExceptione){}returntweets;}

分析一條推文的情緒分析下一步是分析一條推文的情緒分析。Google,Amazon或Microsoft提供解決方案。但是也有非常好的免費和開源解決方案,例如Stanford CoreNLP程式碼庫。Stanford CoreNLP程式碼庫完全滿足我們的需求,這是我們的比特幣情緒分析器程式的一部分。StanfordCoreNLP類是API的入口點。我們透過傳遞屬性的例項作為例項來例項化此物件,在其中定義了將在文字分析期間使用的不同註釋器。然後,我呼叫StanfordCoreNLP物件的處理方法以開始文字分析。作為結果回報,我得到一個Annotation物件,將在該物件上迭代以獲得關聯的CoreMap物件。對於這些物件中的每一個,我都檢索一個Tree物件,該物件是透過將SentimentAnnotatedTree類作為輸入呼叫get方法而獲得的。最後,仍然需要透過傳遞Tree的此例項作為輸入來呼叫RNNCoreAnnotations類的靜態方法getPredictedClass。返回值對應於此分析文字的總體情緒。文字的總體情感是透過保留文字最長部分的情感來計算的。為作為輸入傳遞的文字計算的情感表示為一個整數,其值的範圍可以從0到4(含0和4)。為了便於以後對文字的情緒進行操作,我定義了TypeSentiment列舉,將每個值與以該列舉的形式定義的關聯感覺相關聯。所有這些都給出以下程式碼:

enumTypeSentiment{VERY_NEGATIVE(0),NEGATIVE(1),NEUTRAL(2),POSITIVE(3),VERY_POSITIVE(4);intindex;privateTypeSentiment(intindex){this.index=index;}publicstaticTypeSentimentfromIndex(intindex){for(TypeSentimenttypeSentiment:values()){if(typeSentiment.index==index){returntypeSentiment;}}returnTypeSentiment.NEUTRAL;}}publicstaticTypeSentimentanalyzeSentiment(Stringtext){Propertiesprops=newProperties();props.setProperty("annotators","tokenize,ssplit,parse,sentiment");StanfordCoreNLPpipeline=newStanfordCoreNLP(props);intmainSentiment=0;if(text!=null&&text.length()>0){intlongest=0;Annotationannotation=pipeline.process(text);for(CoreMapsentence:annotation.get(CoreAnnotations.SentencesAnnotation.class)){Treetree=sentence.get(SentimentCoreAnnotations.SentimentAnnotatedTree.class);intsentiment=RNNCoreAnnotations.getPredictedClass(tree);StringpartText=sentence.toString();if(partText.length()>longest){mainSentiment=sentiment;longest=partText.length();}}}returnTypeSentiment.fromIndex(mainSentiment);}

彙編程式的不同部分現在我們可以檢索與給定關鍵字相對應的推文。然後我們能夠分析其每個推文,以獲得與之相關的推文情緒。剩下的就是將所有這些彙編到BitcoinSentimentAnalyzer類的主要方法中。首先我定義一個HashMap,它將儲存在分析的tweets中發現每個情感的次數。然後使用關鍵字“ bitcoin”作為輸入來呼叫searchTweets方法。下一步是迭代由searchTweets方法返回的列表中包含的Status物件。對於每條推文,我都檢索關聯的文字並呼叫analysisSentiment方法以TypeSentiment例項的形式計算關聯的情感。每次返回情感時,我們都會在HashMap中增加計數器。在分析了所有檢索到的推文之後,我們可以顯示關於比特幣的每種觀點的百分比,以在Twitter上給出當前觀點的分佈。以下是完整的程式碼:

packagecom.ssaurel.bitcoinsentiment;importjava.util.Collections;importjava.util.HashMap;importjava.util.List;importjava.util.Map.Entry;importjava.util.Properties;importedu.stanford.nlp.ling.CoreAnnotations;importedu.stanford.nlp.neural.rnn.RNNCoreAnnotations;importedu.stanford.nlp.pipeline.Annotation;importedu.stanford.nlp.pipeline.StanfordCoreNLP;importedu.stanford.nlp.sentiment.SentimentCoreAnnotations;importedu.stanford.nlp.trees.Tree;importedu.stanford.nlp.util.CoreMap;importtwitter4j.Query;importtwitter4j.QueryResult;importtwitter4j.Status;importtwitter4j.Twitter;importtwitter4j.TwitterException;importtwitter4j.TwitterFactory;importtwitter4j.conf.ConfigurationBuilder;publicclassBitcoinSentimentAnalyzer{enumTypeSentiment{VERY_NEGATIVE(0),NEGATIVE(1),NEUTRAL(2),POSITIVE(3),VERY_POSITIVE(4);intindex;privateTypeSentiment(intindex){this.index=index;}publicstaticTypeSentimentfromIndex(intindex){for(TypeSentimenttypeSentiment:values()){if(typeSentiment.index==index){returntypeSentiment;}}returnTypeSentiment.NEUTRAL;}}publicstaticList<Status>searchTweets(Stringkeyword){List<Status>tweets=Collections.emptyList();ConfigurationBuildercb=newConfigurationBuilder();cb.setDebugEnabled(true).setOAuthConsumerKey("UiLHCETjD1SLKb4EL6ixm90Mv").setOAuthConsumerSecret("fDAqCfMQ6Azj1BbvXqS3f9HoPNM6BIGSV7jw3SUBu8TAaPPnBx").setOAuthAccessToken("58410144-m5F3nXtyZGNXFZzofNhYp3SQdNMrbfDLgZSvFMdOq").setOAuthAccessTokenSecret("PxlJJ3dRMlMiUf7rFAqEo4n0yLbiC6FC4hyvKF7ISBgdW");TwitterFactorytf=newTwitterFactory(cb.build());Twittertwitter=tf.getInstance();Queryquery=newQuery(keyword+"-filter:retweets-filter:links-filter:replies-filter:images");query.setCount(100);query.setLocale("en");query.setLang("en");;try{QueryResultqueryResult=twitter.search(query);tweets=queryResult.getTweets();}catch(TwitterExceptione){}returntweets;}publicstaticTypeSentimentanalyzeSentiment(Stringtext){Propertiesprops=newProperties();props.setProperty("annotators","tokenize,ssplit,parse,sentiment");StanfordCoreNLPpipeline=newStanfordCoreNLP(props);intmainSentiment=0;if(text!=null&&text.length()>0){intlongest=0;Annotationannotation=pipeline.process(text);for(CoreMapsentence:annotation.get(CoreAnnotations.SentencesAnnotation.class)){Treetree=sentence.get(SentimentCoreAnnotations.SentimentAnnotatedTree.class);intsentiment=RNNCoreAnnotations.getPredictedClass(tree);StringpartText=sentence.toString();if(partText.length()>longest){mainSentiment=sentiment;longest=partText.length();}}}returnTypeSentiment.fromIndex(mainSentiment);}publicstaticvoidmain(String[]args){HashMap<TypeSentiment,Integer>sentiments=newHashMap<BitcoinSentimentAnalyzer.TypeSentiment,Integer>();List<Status>list=searchTweets("bitcoin");for(Statusstatus:list){Stringtext=status.getText();TypeSentimentsentiment=analyzeSentiment(text);Integervalue=sentiments.get(sentiment);if(value==null){value=0;}value++;sentiments.put(sentiment,value);}intsize=list.size();System.out.println("SentimentsaboutBitcoinon"+size+"tweets");for(Entry<TypeSentiment,Integer>entry:sentiments.entrySet()){System.out.println(entry.getKey()+"=>"+(entry.getValue()*100)/size+"%");}}}

執行比特幣情緒分析器本文的最佳之處在於,我們將把剛剛構建的比特幣情緒分析器程式付諸實踐。執行該程式後,經過幾秒鐘的分析,我得到以下結果:

在Twitter API返回的推文示例中,人們對比特幣的普遍看法如下:1. 2%非常負面的推文2. 72%的負面推文3. 12%的中立推文4. 14%的正面推文我們的比特幣情緒分析清楚地表明,目前Twitter上的總體情緒對比特幣相當負面。

更進一步我們的比特幣情緒分析儀功能完善,為進一步分析比特幣情緒提供了良好的基礎。因此,您可以連續執行此分析,以使其與可透過Coindesk的比特幣價格指數API檢索的比特幣價格相關。因此,如果Twitter上有關比特幣的普遍情緒與價格的變化直接相關,則可以由此推斷。該程式可以幫助您改善對比特幣未來價格的預測。對於此類程式,您將需要切換到Twitter的付費開發人員API,以實時獲取有關比特幣的推文。

免責聲明:

  1. 本文版權歸原作者所有,僅代表作者本人觀點,不代表鏈報觀點或立場。
  2. 如發現文章、圖片等侵權行爲,侵權責任將由作者本人承擔。
  3. 鏈報僅提供相關項目信息,不構成任何投資建議

推荐阅读

;