Skip to content

Instantly share code, notes, and snippets.

@kenwebb
Last active March 22, 2017 10:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kenwebb/5c0cd0c62961c93255ba0277191fb18d to your computer and use it in GitHub Desktop.
Save kenwebb/5c0cd0c62961c93255ba0277191fb18d to your computer and use it in GitHub Desktop.
Dictator Series - Prototype 01
<?xml version="1.0" encoding="UTF-8"?>
<!--Xholon Workbook http://www.primordion.com/Xholon/gwt/ MIT License, Copyright (C) Ken Webb, Wed Mar 22 2017 06:19:15 GMT-0400 (EDT)-->
<XholonWorkbook>
<Notes><![CDATA[
Xholon
------
Title: Dictator Series - Prototype 01
Description:
Url: http://www.primordion.com/Xholon/gwt/
InternalName: 5c0cd0c62961c93255ba0277191fb18d
Keywords:
My Notes
--------
March 15, 2017
see my print notebook for March 15, 2017
Politician has a thought, composes it into a Tweet or NewsItem, and sends that to a NewsDistributor.
Citizens access the Tweet or NewsItem, internalize the sentiment that causes a behavior and an action.
I could have different personality types, instead of just Citizen.
Each one would react in different ways to a sentiment analysis.
To create more Citizen nodes, paste the following as last child of a CaseStudy:
<Citizen><CitizenBehavior/></Citizen>
References
----------
(1) http://www.cnn.com/interactive/2017/politics/trump-tweets/
I could get tweets from this page
//*[@id="cnnint-tweets"]/div[56]
(2) https://en.wikiquote.org/wiki/Benito_Mussolini
Emotion/Sentiment software
--------------------------
() http://varianceexplained.org/r/trump-tweets/
We’ll work with the NRC Word-Emotion Association lexicon, available from the tidytext package, which associates words with 10 sentiments: positive, negative, anger, anticipation, disgust, fear, joy, sadness, surprise, and trust.
() https://cran.r-project.org/web/packages/tidytext/
() http://saifmohammad.com/WebPages/NRC-Emotion-Lexicon.htm
NRC Word-Emotion Association Lexicon (aka EmoLex)
The NRC Emotion Lexicon is a list of English words and their associations with eight basic emotions (anger, fear, anticipation, trust, surprise, sadness, joy, and disgust) and two sentiments (negative and positive). The annotations were manually done by crowdsourcing.
() https://github.com/juliasilge/tidytext/blob/master/data/sentiments.rda
I used RStudio to inspect this file, after downloading it. I wrote it out as standard CSV:
load("~/Downloads/sentiments.rda")
View(sentiments)
write.csv(sentiments, file = "~/Downloads/sentiments.csv")
KSW - How do I measure the sentiment of the entire tweet, based on the sentiment of each individual word?
score -1 for each negative emotion and score +1 for each positive; sum all the values to get a score for the tweet
KSW - or maybe pass all emotion words from a tweet to Citizen nodes; let each word/sentiment stimulate it's own behavior
() https://www.jstatsoft.org/article/view/v059i10
tidy data principles; interesting
() https://cloud.google.com/natural-language/
Sentiment Analysis
Understand the overall sentiment expressed in a block of text.
KSW - I tried this using the first tweet. The result was a score and magnitude that extended from very low to very high, so it's useless.
() google: sentiment analysis javascript
most software is for Node.js
() http://www.gtlambert.com/blog/sentiment-analysis-sentimoodjs
Client Side Sentiment Analysis with Sentimood.js, 06 Jul 2016
I recently found myself wanting to use sentiment analysis on the client side, and so went searching for a browser-based sentiment analysis package.
There isn't too much out there, but I did come across an excellent browser-based package called Sentimood.js.
According to the GitHub readme.md file, it is effectively the same as the NodeJS sentimental package, but edited/translated for browser-side use.
) https://github.com/soops/sentimood
A minimal sentiment analyzer based on @thinkroth's "Sentimental" and written in CoffeeScript
) https://github.com/thinkroth/Sentimental
Sentiment analysis tool for node.js based on the AFINN-111 wordlist.
() http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6010
AFINN is a list of English words rated for valence with an integer
between minus five (negative) and plus five (positive). The words have
been manually labeled by Finn Årup Nielsen in 2009-2011. The file
is tab-separated. There are two versions:
AFINN-111: Newest version with 2477 words and phrases.
) https://github.com/thisandagain/sentiment
AFINN-based sentiment analysis for Node.js.
() https://en.wikipedia.org/wiki/Sentiment_analysis
() https://en.wikipedia.org/wiki/Topic_model
In machine learning and natural language processing, a topic model is a type of statistical model for discovering the abstract "topics" that occur in a collection of documents. Topic modeling is a frequently used text-mining tool for discovery of hidden semantic structures in a text body.
() http://www.apperceptual.com/
Peter Turney, one of the authors of NRC Word-Emotion Association lexicon
]]></Notes>
<_-.XholonClass>
<PoliticalSystem/>
<CaseStudy/>
<Person>
<Citizen/>
<Politician/> <!-- ex: Trump, Mussolini -->
</Person>
<PersonBehavior superClass="Script">
<CitizenBehavior/>
<PoliticianBehavior/>
</PersonBehavior>
<PoliticalStatement superClass="Attribute_String">
<Tweet/> <!-- ex: from Trump -->
<NewsItem/> <!-- ex: from Mussolini -->
</PoliticalStatement>
<NewsDistributor>
<Twitter/>
<Newspaper/>
</NewsDistributor>
<!-- others -->
<TwitterApi/> <!-- access to a library that can obtain tweets from Twitter -->
<SentimoodAnalyzer/> <!-- TESTING access to the Sentimood library that can provide a sentiment term given a chunk of text such as a Tweet -->
<SentiEmoLexAnalyzer/> <!-- TESTING access to the SentiEmoLex library that can provide a sentiment term given a chunk of text such as a Tweet -->
<Behaviors/>
<EmoSpace>
<Neutral/> <!-- starting point -->
<!-- emotions and sentiments from EmoLex
{anger:0,fear:0,anticipation:0,trust:0,surprise:0,sadness:0,joy:0,disgust:0,negative:0,positive:0} -->
<Anger/>
<Fear/>
<Anticipation/>
<Trust/>
<Surprise/>
<Sadness/>
<Joy/>
<Disgust/>
<Negative/>
<Positive/>
</EmoSpace>
<EmotionalUniverse/>
</_-.XholonClass>
<xholonClassDetails>
<Citizen><Color>rgba(255,0,0,1.0)</Color></Citizen>
<CitizenBehavior><DefaultContent><![CDATA[
var me, meParent, newsDist, readingNow, firstTime = true, emoLex, emoMult, beh = {
postConfigure: function() {
me = this.cnode;
meParent = me.parent();
newsDist = meParent.xpath("../NewsDistributor");
if (newsDist) {
readingNow = newsDist.first();
var emoSpace = meParent.xpath("ancestor::PoliticalSystem/EmotionalUniverse/Neutral");
emoSpace.append(meParent.remove());
emoLex = {anger:0,fear:0,anticipation:0,trust:0,surprise:0,sadness:0,joy:0,disgust:0,negative:0,positive:0,total:0};
// emotional multiplier (emoMult) is a way of specifying the Citizen's innate personality
emoMult = {};
emoMult.anger = $wnd.Math.random();
emoMult.fear = $wnd.Math.random();
emoMult.anticipation = $wnd.Math.random();
emoMult.trust = $wnd.Math.random();
emoMult.surprise = $wnd.Math.random();
emoMult.sadness = $wnd.Math.random();
emoMult.joy = $wnd.Math.random();
emoMult.disgust = $wnd.Math.random();
emoMult.negative = $wnd.Math.random();
emoMult.positive = $wnd.Math.random();
//emoMult = {anger:1,fear:1,anticipation:0,trust:0,surprise:0,sadness:0,joy:0,disgust:0,negative:0,positive:0}; // fearful and angry personality
//emoMult = {anger:0,fear:0,anticipation:0,trust:0,surprise:0,sadness:0,joy:0,disgust:0,negative:1,positive:1}; // switch between neg and pos
//emoMult = {anger:0,fear:0,anticipation:0,trust:0,surprise:0,sadness:0,joy:0,disgust:0,negative:0,positive:0}; // no personality
//emoMult = {anger:1,fear:1,anticipation:1,trust:1,surprise:1,sadness:1,joy:1,disgust:1,negative:1,positive:1}; // receptive to any input
//emoMult = {anger:0,fear:0,anticipation:1,trust:1,surprise:1,sadness:0,joy:1,disgust:0,negative:0,positive:1}; // positive personality
$wnd.console.log(emoMult);
var behaviors = meParent.xpath("ancestor::PoliticalSystem/Behaviors");
behaviors.append(me.remove());
}
},
act: function() {
//me.println(me.name());
if (firstTime) {
firstTime = false;
return;
}
if (readingNow) {
var el = readingNow.emoLex;
me.println(me.name() + " is reading: " + readingNow.text() + " " + $wnd.JSON.stringify(el));
if (el) {
this.updateEmoLex(el, "anger");
this.updateEmoLex(el, "fear");
this.updateEmoLex(el, "anticipation");
this.updateEmoLex(el, "trust");
this.updateEmoLex(el, "surprise");
this.updateEmoLex(el, "sadness");
this.updateEmoLex(el, "joy");
this.updateEmoLex(el, "disgust");
this.updateEmoLex(el, "negative");
this.updateEmoLex(el, "positive");
}
me.println(" ==> " + $wnd.JSON.stringify(emoLex));
this.updateEmoSpace();
readingNow = readingNow.next();
}
},
updateEmoLex: function(el, elItemName) {
var elVal = el[elItemName] * emoMult[elItemName];
emoLex[elItemName] += elVal;
emoLex["total"] += elVal;
},
updateEmoSpace: function() {
//var rnum = $wnd.Math.ceil($wnd.Math.random() * emoLex.total);
var rnum = $wnd.Math.random() * emoLex.total;
me.println(" rnum=" + rnum);
var namesArr = ["anger","fear","anticipation","trust","surprise","sadness","joy","disgust","negative","positive"];
var count = 0;
for (var i = 0; i < namesArr.length; i++) {
count += emoLex[namesArr[i]];
if (count > rnum) {
var nodeName = namesArr[i];
nodeName = nodeName.charAt(0).toUpperCase() + nodeName.substring(1);
var emoSpace = meParent.xpath("../../" + nodeName);
me.println(emoSpace);
emoSpace.append(meParent.remove());
return;
}
}
}
}
//# sourceURL=Citizen.js
]]></DefaultContent></CitizenBehavior>
<PoliticianBehavior><DefaultContent><![CDATA[
var me, meParent, newsDist, nls, beh = {
postConfigure: function() {
me = this.cnode;
meParent = me.parent();
newsDist = meParent.xpath("../NewsDistributor");
//me.println(meParent.name() + " has a " + me.xhc().name());
//me.println(newsDist);
nls = $wnd.xh.service("NaturalLanguageService-SentiEmoLex");
},
act: function() {
//me.println(me.name());
var node = meParent.first();
if (node && (node.xhc().name() == "Attribute_String")) {
//me.println(node.text());
newsDistTag = newsDist.first().xhc().name(); // get the name of the DUMMY tweet or newsItem
const SIG_ANALYZE_SENTIMENT_REQ = -3896;
var respMsg = nls.call(SIG_ANALYZE_SENTIMENT_REQ, node.text(), me);
//me.println(text + ": " + resp.data[0].sentiment);
$wnd.console.log(respMsg.data);
var statement = "<" + newsDistTag + ">" + node.text() + "</" + newsDistTag + ">";
//me.println(statement);
newsDist.append(statement);
newsDist.last().emoLex = respMsg.data; //$wnd.JSON.stringify(respMsg.data);
node.remove();
}
}
}
//# sourceURL=Politician.js
]]></DefaultContent></PoliticianBehavior>
</xholonClassDetails>
<PoliticalSystem>
<Behaviors/>
<!-- this subtree should come before the CaseStudy subtrees -->
<EmotionalUniverse>
<Neutral/>
<Anger/>
<Fear/>
<Anticipation/>
<Trust/>
<Surprise/>
<Sadness/>
<Joy/>
<Disgust/>
<Negative/>
<Positive/>
</EmotionalUniverse>
<CaseStudy roleName="USA 2017">
<Politician roleName="Trump">
<Attribute_String>Based on the incredibly inaccurate coverage and reporting of the record setting Trump campaign, we are hereby revoking the press credentials of the phony and dishonest Washington Post.</Attribute_String>
<Attribute_String>Here's another thing I just thought of.</Attribute_String> <!-- KSW wrote this -->
<Attribute_String>CEO's most optimistic since 2009. It will only get better as we continue to slash unnecessary regulations and when we begin our big tax cut!</Attribute_String>
<Attribute_String>ObamaCare is imploding. It is a disaster and 2017 will be the worst year yet, by far! Republicans will come together and save the day.</Attribute_String>
<Attribute_String>It is amazing how rude much of the media is to my very hard working representatives. Be nice, you will do much better!</Attribute_String>
<Attribute_String>We are making great progress with healthcare. ObamaCare is imploding and will only get worse. Republicans coming together to get job done!</Attribute_String>
<Attribute_String>Despite what you hear in the press, healthcare is coming along great. We are talking to many groups and it will end in a beautiful picture!</Attribute_String>
<Attribute_String>Don't let the FAKE NEWS tell you that there is big infighting in the Trump Admin. We are getting along great, and getting major things done!</Attribute_String>
<Attribute_String>Terrible! Just found out that Obama had my "wires tapped" in Trump Tower just before the victory. Nothing found. This is McCarthyism!</Attribute_String>
<Attribute_String/>
<PoliticianBehavior/>
</Politician>
<Twitter>
<Tweet>T DUMMY</Tweet>
</Twitter>
<Citizen><CitizenBehavior/></Citizen>
<!-- the following 4 do not get created -->
<!--<Citizen><CitizenBehavior/></Citizen>
<Citizen><CitizenBehavior/></Citizen>
<Citizen><CitizenBehavior/></Citizen>
<Citizen><CitizenBehavior/></Citizen>-->
</CaseStudy>
<CaseStudy roleName="Italy 192x">
<Politician roleName="Mussolini">
<Attribute_String>I know how to yell and strut.</Attribute_String> <!-- KSW wrote this -->
<Attribute_String>The truth is that men are tired of liberty.</Attribute_String>
<Attribute_String>Blood alone moves the wheels of history.</Attribute_String>
<Attribute_String>We go to battle against the plutocratic and reactionary democracies of the west…</Attribute_String>
<Attribute_String>We declare war against socialism, not because it is socialism, but because it has opposed nationalism....</Attribute_String>
<Attribute_String>This is what we propose now to the Treasury: either the property owners expropriate themselves, or we summon the masses of war veterans to march against these obstacles and overthrow them.
</Attribute_String>
<Attribute_String>We want an extraordinary heavy taxation, with a progressive character, on capital, that will represent an authentic partial expropriation of all wealth</Attribute_String>
<Attribute_String>Three cheers for the war. Three cheers for Italy's war and three cheers for war in general. Peace is hence absurd or rather a pause in war.</Attribute_String>
<Attribute_String>I declare that henceforth capital and labor shall have equal rights and duties as brothers in the fascist family.</Attribute_String>
<Attribute_String>Our program is simple: we wish to govern Italy. They ask us for programs but there are already too many. It is not programs that are wanting for the salvation of Italy but men and will power.
</Attribute_String>
<Attribute_String>Liberty is a duty, not a right.</Attribute_String>
<Attribute_String>Democracy is beautiful in theory; in practice it is a fallacy. You in America will see that some day.</Attribute_String>
<Attribute_String>Socialism has to remain a terrifying and a majestic thing. If we follow this line, we shall be able to face our enemies.</Attribute_String>
<Attribute_String>The law of socialism is that of the desert: a tooth for a tooth, an eye for an eye. Socialism is a rude and bitter truth, which was born in the conflict of opposing forces and in violence. Socialism is war, and woe to those who are cowardly in war. They will be defeated.</Attribute_String>
<Attribute_String>Let us have a dagger between our teeth, a bomb in our hands and an infinite scorn in our hearts.</Attribute_String>
<Attribute_String>[Marx was] the magnificent philosopher of working class violence.</Attribute_String>
<Attribute_String>All within the state, nothing outside the state, nothing against the state.</Attribute_String>
<Attribute_String>Fascism was not the protector of any one class, but a supreme regulator of the relations between all citizens of a state.</Attribute_String>
<Attribute_String>The citizen in the Fascist State is no longer a selfish individual who has the anti-social right of rebelling against any law of the Collectivity.</Attribute_String>
<Attribute_String/>
<Attribute_String/>
<Attribute_String/>
<Attribute_String/>
<PoliticianBehavior/>
</Politician>
<Newspaper>
<NewsItem>M DUMMY</NewsItem>
</Newspaper>
<Citizen>
<CitizenBehavior/>
</Citizen>
</CaseStudy>
<!-- these are for testing -->
<!--<SentimoodAnalyzer/>
<SentiEmoLexAnalyzer/>-->
<!-- TODO Animate EmotionalUniverse -->
<Animate duration="2" selection="#xhanim" tweenScript="xhSvgTween_exp" xpath="PoliticalSystem/EmotionalUniverse" cssStyle=".d3cpnode circle {stroke-width: 0px;}" efParams="{&quot;selection&quot;:&quot;#xhanim&quot;,&quot;shouldIncludeDecorations&quot;:true,&quot;useIcons&quot;:false,&quot;shape&quot;:&quot;circle&quot;, &quot;iconPos&quot;:&quot;outside&quot;,&quot;sort&quot;:&quot;disable&quot;,&quot;width&quot;:600,&quot;height&quot;:600,&quot;mode&quot;:&quot;tween&quot;,&quot;labelContainers&quot;:true,&quot;includeId&quot;:true,&quot;shape&quot;:&quot;circle&quot;,&quot;supportTouch&quot;:true,&quot;maxChars&quot;:3}"/>
</PoliticalSystem>
<SentimoodAnalyzerbehavior implName="org.primordion.xholon.base.Behavior_gwtjs"><![CDATA[
var me, nls, count, beh = {
postConfigure: function() {
me = this.cnode.parent();
nls = $wnd.xh.service("NaturalLanguageService-Sentimood");
count = 1;
},
act: function() {
switch (count) {
case 1: this.doIt("We had a good time."); break;
case 2: this.doIt("I had a bad time."); break;
case 3: this.doIt("The good the bad and the ugly."); break;
case 4: this.doIt("Based on the incredibly inaccurate coverage and reporting of the record setting Trump campaign, we are hereby revoking the press credentials of the phony and dishonest Washington Post."); break;
case 5: this.doIt("Let us have a dagger between our teeth, a bomb in our hands and an infinite scorn in our hearts."); break;
default: break;
}
count++;
},
doIt: function(text) {
const SIG_ANALYZE_SENTIMENT_REQ = -3896;
var resp = nls.call(SIG_ANALYZE_SENTIMENT_REQ, text, me);
me.println(text + ": " + resp.data.score);
}
}
]]></SentimoodAnalyzerbehavior>
<SentiEmoLexAnalyzerbehavior implName="org.primordion.xholon.base.Behavior_gwtjs"><![CDATA[
var me, nls, count, beh = {
postConfigure: function() {
me = this.cnode.parent();
nls = $wnd.xh.service("NaturalLanguageService-SentiEmoLex");
count = 1;
},
act: function() {
switch (count) {
case 1: this.doIt("We had a good time."); break;
case 2: this.doIt("I had a bad time"); break;
case 3: this.doIt("The good the bad and the ugly."); break;
case 4: this.doIt("Based on the incredibly inaccurate coverage and reporting of the record setting Trump campaign, we are hereby revoking the press credentials of the phony and dishonest Washington Post."); break;
case 5: this.doIt("Let us have a dagger between our teeth, a bomb in our hands and an infinite scorn in our hearts."); break;
default: break;
}
count++;
},
doIt: function(text) {
const SIG_ANALYZE_SENTIMENT_REQ = -3896;
var respMsg = nls.call(SIG_ANALYZE_SENTIMENT_REQ, text, me);
//me.println(text + ": " + resp.data[0].sentiment);
$wnd.console.log(respMsg.data);
me.println(text + ": " + $wnd.JSON.stringify(respMsg.data));
}
}
]]></SentiEmoLexAnalyzerbehavior>
<SvgClient><Attribute_String roleName="svgUri"><![CDATA[data:image/svg+xml,
<svg width="100" height="50" xmlns="http://www.w3.org/2000/svg">
<g>
<title>USA 2017</title>
<rect id="PoliticalSystem/CaseStudy" fill="#98FB98" height="50" width="50" x="25" y="0"/>
<g>
<title>Mussolini</title>
<rect id="PoliticalSystem/CaseStudy[2]/Politician" fill="#6AB06A" height="50" width="10" x="80" y="0"/>
</g>
</g>
</svg>
]]></Attribute_String><Attribute_String roleName="setup">${MODELNAME_DEFAULT},${SVGURI_DEFAULT}</Attribute_String></SvgClient>
</XholonWorkbook>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment