Twitter的比特幣情感分析器怎樣來構(gòu)建
比特幣創(chuàng)建于2009年,仍然是一個相當(dāng)年輕的項目。但其市場價格非常不穩(wěn)定。此外,比特幣對大眾效應(yīng)更為敏感,比如像2017年底那樣大眾為占據(jù)的FOMO感覺一樣。在大眾的興奮情緒推動下,比特幣價格曾高達(dá)到2萬美元的歷史高點。
能夠衡量圍繞比特幣的這種類型的情緒,可以很好地表明未來幾個小時內(nèi)等待比特幣價格的因素。一個好的解決方案是分析像Twitter這樣的社交網(wǎng)絡(luò)上圍繞比特幣的活動。在本文中,我將教您如何創(chuàng)建一個Java程序,從Twitter上檢索的tweets中分析關(guān)于比特幣的所有大眾情緒。
比特幣情緒分析器規(guī)范
您將學(xué)習(xí)開發(fā)的比特幣情緒分析器在執(zhí)行過程中將執(zhí)行以下操作:
1. 在Twitter上檢索包含關(guān)鍵字bitcoin的推文
2. 分析每條檢索到的推文,以及檢測與之相關(guān)的大眾情緒
3. 在Twitter上顯示以下5種比特幣情緒各自的百分比:非常消極,消極,中立,積極,非常積極
該程序?qū)⒃诿看螆?zhí)行后結(jié)束,由于Twitter是使用其免費(fèi)的開發(fā)人員API設(shè)置的配額,將不會連續(xù)執(zhí)行此分析。
創(chuàng)建Java項目
第一步是創(chuàng)建一個Java項目。我們將使用Maven作為依賴關(guān)系管理器。
在依賴性方面,我們將具有以下代碼庫:
1. Twitter4J是Twitter API的非官方Java客戶端
2. Stanford CoreNLP是一個用于自然語言處理的開源庫
Twitter4J將允許我們以一種簡單的方式從Twitter中檢索tweets的推文樣本。Stanford CoreNLP代碼庫將使我們能夠檢測與每個相關(guān)推文相關(guān)的情緒。
這為我們的項目提供了以下POM:
《?xml version=“1.0” encoding=“UTF-8”?》
《project xmlns=“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.0 http://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》
創(chuàng)建一個Twitter應(yīng)用程序
使用Twitter API需要創(chuàng)建開發(fā)者帳戶。它是免費(fèi)的,但會有一定調(diào)用次數(shù)和配額限制使用。作為我們用于展示目的的項目的一部分,這是完全足夠的。使用Twitter API所需的開發(fā)者帳戶的創(chuàng)建在此處完成:
開發(fā)者地址https://developer.twitter.com/
創(chuàng)建此帳戶后,您將轉(zhuǎn)到下一頁:
您將需要創(chuàng)建一個新的應(yīng)用程序。我選擇將我的應(yīng)用程序命名為“ Bitcoin_Sentiment_Analyzer”。在創(chuàng)建此應(yīng)用程序期間,您將必須填寫有關(guān)它的一定數(shù)量的信息。最后,您將到達(dá)“Keys and tokens””屏幕,在該屏幕上,您將找到使您在調(diào)用Twitter API來檢索與比特幣相關(guān)的推文時正確進(jìn)行身份驗證的信息:
檢索推文
現(xiàn)在已經(jīng)創(chuàng)建了與比特幣情緒分析器關(guān)聯(lián)的Twitter應(yīng)用程序,我們將能夠繼續(xù)檢索程序中的推文。為此,我們將依靠Twitter4J代碼庫。
Twitter4J具有TwitterFactory和Twitter類作為其入口點。
TwitterFactory類將包含與Twitter API的連接信息的Configuration對象實例作為輸入:
· 使用者API公鑰
· 使用者API密鑰
· 訪問Token
· 訪問Token密鑰
然后,我將通過調(diào)用其getInstance方法從TwitterFactory檢索Twitter對象實例的實例。有了這個對象,我們將能夠在Twitter API上啟動查詢。我們將使用其搜索方法來檢索符合特定條件的推文。
在Query對象中對查詢建模,該對象以與您要通過Twitter API執(zhí)行的查詢相對應(yīng)的字符串作為輸入。對于比特幣情緒分析器,我想檢索包含關(guān)鍵字bitcoin的推文,而不是轉(zhuǎn)發(fā),鏈接,答案或圖片。
該查詢用以下字符串表示:
bitcoin -filter:retweets -filter:links -filter:replies -filter:images
Query類的setCount方法允許您定義要檢索的結(jié)果數(shù)。如果使用免費(fèi)的開發(fā)人員API,則此數(shù)量限制為100個結(jié)果。
最后,仍然需要通過從Twitter對象實例的search方法傳遞該查詢來執(zhí)行此查詢 返回一個QueryResult對象,將其保留在其上以調(diào)用getTweets方法以檢索Status對象的列表。每個Status對象代表一條推文。最終可以通過后一個對象的getText方法訪問其文本內(nèi)容。
所有這些提供了以下searchTweets方法:
public static List 《 Status 》 searchTweets(String keyword) {
List 《 Status 》 tweets = Collections.emptyList();
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setDebugEnabled(true).setOAuthConsumerKey(“YOUR_CONSUMER_KEY”)
.setOAuthConsumerSecret(“YOUR_CONSUMER_SECRET”)
.setOAuthAccessToken(“YOUR_ACCESS_TOKEN”)
.setOAuthAccessTokenSecret(“YOUR_ACCESS_TOKEN_SECRET”);
TwitterFactory tf = new TwitterFactory(cb.build());
Twitter twitter = tf.getInstance();
Query query = new Query(keyword + “ -filter:retweets -filter:links -filter:replies -filter:images”);
query.setCount(100);
query.setLocale(“en”);
query.setLang(“en”);;
try {
QueryResult queryResult = twitter.search(query);
tweets = queryResult.getTweets();
} catch (TwitterException e) {}
return tweets;
}
分析一條推文的情緒分析
下一步是分析一條推文的情緒分析。Google,Amazon或Microsoft提供解決方案。但是也有非常好的免費(fèi)和開源解決方案,例如Stanford CoreNLP代碼庫。
Stanford CoreNLP代碼庫完全滿足我們的需求,這是我們的比特幣情緒分析器程序的一部分。
StanfordCoreNLP類是API的入口點。我們通過傳遞屬性的實例作為實例來實例化此對象,在其中定義了將在文本分析期間使用的不同注釋器。
然后,我調(diào)用StanfordCoreNLP對象的處理方法以開始文本分析。作為結(jié)果回報,我得到一個Annotation對象,將在該對象上迭代以獲得關(guān)聯(lián)的CoreMap對象。對于這些對象中的每一個,我都檢索一個Tree對象,該對象是通過將SentimentAnnotatedTree類作為輸入調(diào)用get方法而獲得的。
最后,仍然需要通過傳遞Tree的此實例作為輸入來調(diào)用RNNCoreAnnotations類的靜態(tài)方法getPredictedClass。返回值對應(yīng)于此分析文本的總體情緒。文本的總體情感是通過保留文本最長部分的情感來計算的。
為作為輸入傳遞的文本計算的情感表示為一個整數(shù),其值的范圍可以從0到4(含0和4)。
為了便于以后對文本的情緒進(jìn)行操作,我定義了TypeSentiment枚舉,將每個值與以該枚舉的形式定義的關(guān)聯(lián)感覺相關(guān)聯(lián)。
所有這些都給出以下代碼:
enum TypeSentiment {
VERY_NEGATIVE(0), NEGATIVE(1), NEUTRAL(2), POSITIVE(3), VERY_POSITIVE(4);
int index;
private TypeSentiment(int index) {
this.index = index;
}
public static TypeSentiment fromIndex(int index) {
for (TypeSentiment typeSentiment: values()) {
if (typeSentiment.index == index) {
return typeSentiment;
}
}
return TypeSentiment.NEUTRAL;
}
}
public static TypeSentiment analyzeSentiment(String text) {
Properties props = new Properties();
props.setProperty(“annotators”, “tokenize, ssplit, parse, sentiment”);
StanfordCoreNLP pipeline = new StanfordCoreNLP(props);
int mainSentiment = 0;
if (text != null && text.length() 》 0) {
int longest = 0;
Annotation annotation = pipeline.process(text);
for (CoreMap sentence: annotation.get(CoreAnnotations.SentencesAnnotation.class)) {
Tree tree = sentence.get(SentimentCoreAnnotations.SentimentAnnotatedTree.class);
int sentiment = RNNCoreAnnotations.getPredictedClass(tree);
String partText = sentence.toString();
if (partText.length() 》 longest) {
mainSentiment = sentiment;
longest = partText.length();
}
}
}
return TypeSentiment.fromIndex(mainSentiment);
}
匯編程序的不同部分
現(xiàn)在我們可以檢索與給定關(guān)鍵字相對應(yīng)的推文。然后我們能夠分析其每個推文,以獲得與之相關(guān)的推文情緒。剩下的就是將所有這些匯編到BitcoinSentimentAnalyzer類的主要方法中。
首先我定義一個HashMap,它將存儲在分析的tweets中發(fā)現(xiàn)每個情感的次數(shù)。然后使用關(guān)鍵字“ bitcoin”作為輸入來調(diào)用searchTweets方法。
下一步是迭代由searchTweets方法返回的列表中包含的Status對象。對于每條推文,我都檢索關(guān)聯(lián)的文本并調(diào)用analysisSentiment方法以TypeSentiment實例的形式計算關(guān)聯(lián)的情感。
每次返回情感時,我們都會在HashMap中增加計數(shù)器。在分析了所有檢索到的推文之后,我們可以顯示關(guān)于比特幣的每種觀點的百分比,以在Twitter上給出當(dāng)前觀點的分布。
以下是完整的代碼:
package com.ssaurel.bitcoinsentiment;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
import java.util.Properties;
import edu.stanford.nlp.ling.CoreAnnotations;
import edu.stanford.nlp.neural.rnn.RNNCoreAnnotations;
import edu.stanford.nlp.pipeline.Annotation;
import edu.stanford.nlp.pipeline.StanfordCoreNLP;
import edu.stanford.nlp.sentiment.SentimentCoreAnnotations;
import edu.stanford.nlp.trees.Tree;
import edu.stanford.nlp.util.CoreMap;
import twitter4j.Query;
import twitter4j.QueryResult;
import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.conf.ConfigurationBuilder;
public class BitcoinSentimentAnalyzer {
enum TypeSentiment {
VERY_NEGATIVE(0), NEGATIVE(1), NEUTRAL(2), POSITIVE(3), VERY_POSITIVE(4);
int index;
private TypeSentiment(int index) {
this.index = index;
}
public static TypeSentiment fromIndex(int index) {
for (TypeSentiment typeSentiment: values()) {
if (typeSentiment.index == index) {
return typeSentiment;
}
}
return TypeSentiment.NEUTRAL;
}
}
public static List 《 Status 》 searchTweets(String keyword) {
List 《 Status 》 tweets = Collections.emptyList();
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setDebugEnabled(true).setOAuthConsumerKey(“UiLHCETjD1SLKb4EL6ixm90Mv”)
.setOAuthConsumerSecret(“fDAqCfMQ6Azj1BbvXqS3f9HoPNM6BIGSV7jw3SUBu8TAaPPnBx”)
.setOAuthAccessToken(“58410144-m5F3nXtyZGNXFZzofNhYp3SQdNMrbfDLgZSvFMdOq”)
.setOAuthAccessTokenSecret(“PxlJJ3dRMlMiUf7rFAqEo4n0yLbiC6FC4hyvKF7ISBgdW”);
TwitterFactory tf = new TwitterFactory(cb.build());
Twitter twitter = tf.getInstance();
Query query = new Query(keyword + “ -filter:retweets -filter:links -filter:replies -filter:images”);
query.setCount(100);
query.setLocale(“en”);
query.setLang(“en”);;
try {
QueryResult queryResult = twitter.search(query);
tweets = queryResult.getTweets();
} catch (TwitterException e) {}
return tweets;
}
public static TypeSentiment analyzeSentiment(String text) {
Properties props = new Properties();
props.setProperty(“annotators”, “tokenize, ssplit, parse, sentiment”);
StanfordCoreNLP pipeline = new StanfordCoreNLP(props);
int mainSentiment = 0;
if (text != null && text.length() 》 0) {
int longest = 0;
Annotation annotation = pipeline.process(text);
for (CoreMap sentence: annotation.get(CoreAnnotations.SentencesAnnotation.class)) {
Tree tree = sentence.get(SentimentCoreAnnotations.SentimentAnnotatedTree.class);
int sentiment = RNNCoreAnnotations.getPredictedClass(tree);
String partText = sentence.toString();
if (partText.length() 》 longest) {
mainSentiment = sentiment;
longest = partText.length();
}
}
}
return TypeSentiment.fromIndex(mainSentiment);
}
public static void main(String[] args) {
HashMap 《 TypeSentiment, Integer 》 sentiments = new HashMap 《 BitcoinSentimentAnalyzer.TypeSentiment, Integer 》 ();
List 《 Status 》 list = searchTweets(“bitcoin”);
for (Status status: list) {
String text = status.getText();
TypeSentiment sentiment = analyzeSentiment(text);
Integer value = sentiments.get(sentiment);
if (value == null) {
value = 0;
}
value++;
sentiments.put(sentiment, value);
}
int size = list.size();
System.out.println(“Sentiments about Bitcoin on ” + size + “ tweets”);
for (Entry 《 TypeSentiment, Integer 》 entry: sentiments.entrySet()) {
System.out.println(entry.getKey() + “ =》 ” + (entry.getValue() * 100) / size + “ %”);
}
}
}
運(yùn)行比特幣情緒分析器
本文的最佳之處在于,我們將把剛剛構(gòu)建的比特幣情緒分析器程序付諸實踐。執(zhí)行該程序后,經(jīng)過幾秒鐘的分析,我得到以下結(jié)果:
在Twitter API返回的推文示例中,人們對比特幣的普遍看法如下:
1. 2%非常負(fù)面的推文
2. 72%的負(fù)面推文
3. 12%的中立推文
4. 14%的正面推文
我們的比特幣情緒分析清楚地表明,目前Twitter上的總體情緒對比特幣相當(dāng)負(fù)面。
更進(jìn)一步
我們的比特幣情緒分析儀功能完善,為進(jìn)一步分析比特幣情緒提供了良好的基礎(chǔ)。因此,您可以連續(xù)執(zhí)行此分析,以使其與可通過Coindesk的比特幣價格指數(shù)API檢索的比特幣價格相關(guān)。
因此,如果Twitter上有關(guān)比特幣的普遍情緒與價格的變化直接相關(guān),則可以由此推斷。該程序可以幫助您改善對比特幣未來價格的預(yù)測。對于此類程序,您將需要切換到Twitter的付費(fèi)開發(fā)人員API,以實時獲取有關(guān)比特幣的推文。