mirror of
https://github.com/node-red/node-red-nodes.git
synced 2023-10-10 13:36:58 +02:00
add multilang sentiment node as separate node
This commit is contained in:
parent
c691b4eaa1
commit
c1ac48d6a6
13
analysis/mlsentiment/LICENSE
Normal file
13
analysis/mlsentiment/LICENSE
Normal file
@ -0,0 +1,13 @@
|
||||
Copyright 2019 JS Foundation and other contributors, https://js.foundation/
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
33
analysis/mlsentiment/README.md
Normal file
33
analysis/mlsentiment/README.md
Normal file
@ -0,0 +1,33 @@
|
||||
node-red-node-multilang-sentiment
|
||||
=================================
|
||||
|
||||
A <a href="http://nodered.org" target="new">Node-RED</a> node that scores incoming words
|
||||
using the AFINN-165 wordlist and attaches a sentiment.score property to the msg.
|
||||
|
||||
This is similar to the default sentiment node but supports many more languages at the cost of using more disk space. (approx 11MB)
|
||||
|
||||
Install
|
||||
-------
|
||||
|
||||
Either use the Menu - Manage palette - Install option in the editor or run the following command in your Node-RED user directory - typically `~/.node-red`
|
||||
|
||||
npm install node-red-node-multilang-sentiment
|
||||
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
Uses the AFINN-165 wordlist to attempt to assign scores to words in text.
|
||||
|
||||
Attaches `msg.sentiment` to the msg and within that `msg.sentiment.score` holds the score.
|
||||
|
||||
Supports multiple languages. These can be preselected in the node configuration. You can also set it so that `msg.lang` can be used to set the language dynamically if required. The cldr language codes supported are:
|
||||
|
||||
af, am, ar, az, be, bg, bn, bs, ca, ceb, co, cs, cy, da, de, el, en, eo, es, et, eu, fa, fi,
|
||||
fr, fy, ga, gd, gl, gu, ha, haw, hi, hmn, hr, ht, hu, hy, id, ig, is, it, iw, ja, jw, ka, kk, km, kn, ko, ku, ky, la, lb, lo, lt,
|
||||
lv, mg, mi, mk, ml, mn, mr, ms, mt, my, ne, nl, no, ny, pa, pl, ps, pt, ro, ru, sd, si, sk, sl, sm, sn, so, sq, sr, st, su, sv,
|
||||
sw, ta, te, tg, th, tl, tr, uk, ur, uz, vi, xh, yi, yo, zh, zh-tw, zu
|
||||
|
||||
A score greater than zero is positive and less than zero is negative. The score typically ranges from -5 to +5, but can go higher and lower.
|
||||
|
||||
See the <a href="https://github.com/marcellobarile/multilang-sentiment/blob/develop/README.md" target="_blank">Multilang Sentiment docs here</a>.</p>
|
8
analysis/mlsentiment/locales/en-US/mlsentiment.json
Normal file
8
analysis/mlsentiment/locales/en-US/mlsentiment.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"mlsentiment": {
|
||||
"sentiment": "sentiment",
|
||||
"label": {
|
||||
"language": "Language"
|
||||
}
|
||||
}
|
||||
}
|
20
analysis/mlsentiment/locales/ja/mlsentiment.html
Normal file
20
analysis/mlsentiment/locales/ja/mlsentiment.html
Normal file
@ -0,0 +1,20 @@
|
||||
|
||||
<script type="text/x-red" data-help-name="mlsentiment">
|
||||
<p>指定したプロパティ(デフォルトは<code>payload</code>)を分析し、<code>sentiment</code>オブジェクトを追加します。</p>
|
||||
<h3>出力</h3>
|
||||
<dl class="message-properties">
|
||||
<dt>sentiment <span class="property-type">オブジェクト</span></dt>
|
||||
<dd>AFINN-111による感情分析の結果</dd>
|
||||
<dt>sentiment.score <span class="property-type">数値</span></dt>
|
||||
<dd>感情分析スコア</dd>
|
||||
</dl>
|
||||
<h3>入力</h3>
|
||||
<dl class="message-properties">
|
||||
<dt>overrides <span class="property-type">オブジェクト</span></dt>
|
||||
<dd>単語スコアの上書きをするためのオブジェクト - <code>{ word:score,... }</code></dd>
|
||||
</dl>
|
||||
<h3>詳細</h3>
|
||||
<p>ゼロ以上のスコアはポジティブ、ゼロ以下はネガティブを意味します。</p>
|
||||
<p>スコアの範囲は通常-5から+5ですが、より大きかったり小さかったりすることもあります。</p>
|
||||
<p>詳細は<a href="https://github.com/marcellobarile/multilang-sentiment/blob/develop/README.md" target="_blank">the Multilang-Sentiment docs here</a>を参照してください。</p>
|
||||
</script>
|
8
analysis/mlsentiment/locales/ja/mlsentiment.json
Normal file
8
analysis/mlsentiment/locales/ja/mlsentiment.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"mlsentiment": {
|
||||
"sentiment": "sentiment",
|
||||
"label": {
|
||||
"language": "言語"
|
||||
}
|
||||
}
|
||||
}
|
176
analysis/mlsentiment/mlsentiment.html
Normal file
176
analysis/mlsentiment/mlsentiment.html
Normal file
@ -0,0 +1,176 @@
|
||||
|
||||
<script type="text/x-red" data-template-name="mlsentiment">
|
||||
<div class="form-row">
|
||||
<label for="node-input-lang"><i class="fa fa-language"></i> <span data-i18n="mlsentiment.label.language"></span></label>
|
||||
<select type="text" id="node-input-lang" style="width:70%;">
|
||||
<option value="">set by msg.lang</option>
|
||||
<option value="af">Afrikaans</option>
|
||||
<option value="sq">Albanian</option>
|
||||
<option value="am">Amharic</option>
|
||||
<option value="ar">Arabic</option>
|
||||
<option value="hy">Armenian</option>
|
||||
<option value="az">Azerbaijani</option>
|
||||
<option value="bn">Bangla</option>
|
||||
<option value="eu">Basque</option>
|
||||
<option value="be">Belarusian</option>
|
||||
<option value="bs">Bosnian</option>
|
||||
<option value="bg">Bulgarian</option>
|
||||
<option value="my">Burmese</option>
|
||||
<option value="ca">Catalan</option>
|
||||
<option value="ceb">Cebuano</option>
|
||||
<option value="zh">Chinese</option>
|
||||
<option value="zh-tw">Chinese (Taiwanese)</option>
|
||||
<option value="co">Corsican</option>
|
||||
<option value="hr">Croatian</option>
|
||||
<option value="cs">Czech</option>
|
||||
<option value="da">Danish</option>
|
||||
<option value="nl">Dutch</option>
|
||||
<option value="en">English</option>
|
||||
<option value="eo">Esperanto</option>
|
||||
<option value="et">Estonian</option>
|
||||
<option value="fi">Finnish</option>
|
||||
<option value="fr">French</option>
|
||||
<option value="fy">Frisian</option>
|
||||
<option value="gl">Galician</option>
|
||||
<option value="ka">Georgian</option>
|
||||
<option value="de">German</option>
|
||||
<option value="el">Greek</option>
|
||||
<option value="gu">Gujarati</option>
|
||||
<option value="ht">Haitian Creole</option>
|
||||
<option value="ha">Hausa</option>
|
||||
<option value="haw">Hawaiian</option>
|
||||
<option value="hi">Hindi</option>
|
||||
<option value="hmn">Hmong</option>
|
||||
<option value="hu">Hungarian</option>
|
||||
<option value="is">Icelandic</option>
|
||||
<option value="ig">Igbo</option>
|
||||
<option value="id">Indonesian</option>
|
||||
<option value="ga">Irish</option>
|
||||
<option value="it">Italian</option>
|
||||
<option value="ja">Japanese</option>
|
||||
<option value="kn">Kannada</option>
|
||||
<option value="kk">Kazakh</option>
|
||||
<option value="km">Khmer</option>
|
||||
<option value="ko">Korean</option>
|
||||
<option value="ku">Kurdish</option>
|
||||
<option value="ky">Kyrgyz</option>
|
||||
<option value="lo">Lao</option>
|
||||
<option value="la">Latin</option>
|
||||
<option value="lv">Latvian</option>
|
||||
<option value="lt">Lithuanian</option>
|
||||
<option value="lb">Luxembourgish</option>
|
||||
<option value="mk">Macedonian</option>
|
||||
<option value="mg">Malagasy</option>
|
||||
<option value="ms">Malay</option>
|
||||
<option value="ml">Malayalam</option>
|
||||
<option value="mt">Maltese</option>
|
||||
<option value="mi">Maori</option>
|
||||
<option value="mr">Marathi</option>
|
||||
<option value="mn">Mongolian</option>
|
||||
<option value="ne">Nepali</option>
|
||||
<option value="no">Norwegian</option>
|
||||
<option value="ny">Nyanja</option>
|
||||
<option value="ps">Pashto</option>
|
||||
<option value="fa">Persian</option>
|
||||
<option value="pl">Polish</option>
|
||||
<option value="pt">Portuguese</option>
|
||||
<option value="pa">Punjabi</option>
|
||||
<option value="ro">Romanian</option>
|
||||
<option value="ru">Russian</option>
|
||||
<option value="sm">Samoan</option>
|
||||
<option value="gd">Scottish Gaelic</option>
|
||||
<option value="sr">Serbian</option>
|
||||
<option value="sn">Shona</option>
|
||||
<option value="sd">Sindhi</option>
|
||||
<option value="si">Sinhala</option>
|
||||
<option value="sk">Slovak</option>
|
||||
<option value="sl">Slovenian</option>
|
||||
<option value="so">Somali</option>
|
||||
<option value="st">Southern Sotho</option>
|
||||
<option value="es">Spanish</option>
|
||||
<option value="su">Sundanese</option>
|
||||
<option value="sw">Swahili</option>
|
||||
<option value="sv">Swedish</option>
|
||||
<option value="tl">Tagalog</option>
|
||||
<option value="tg">Tajik</option>
|
||||
<option value="ta">Tamil</option>
|
||||
<option value="te">Telugu</option>
|
||||
<option value="th">Thai</option>
|
||||
<option value="tr">Turkish</option>
|
||||
<option value="uk">Ukrainian</option>
|
||||
<option value="ur">Urdu</option>
|
||||
<option value="uz">Uzbek</option>
|
||||
<option value="vi">Vietnamese</option>
|
||||
<option value="cy">Welsh</option>
|
||||
<option value="xh">Xhosa</option>
|
||||
<option value="yi">Yiddish</option>
|
||||
<option value="yo">Yoruba</option>
|
||||
<option value="zu">Zulu</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-property"><i class="fa fa-ellipsis-h"></i> <span data-i18n="node-red:common.label.property"></span></label>
|
||||
<input type="text" id="node-input-property" style="width:70%;"/>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="node-red:common.label.name"></span></label>
|
||||
<input type="text" id="node-input-name" data-i18n="[placeholder]node-red:common.label.name">
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/x-red" data-help-name="mlsentiment">
|
||||
<p>Analyses the chosen property, default <code>payload</code>, and adds a <code>sentiment</code> object.</p>
|
||||
<h3>Outputs</h3>
|
||||
<dl class="message-properties">
|
||||
<dt>sentiment <span class="property-type">object</span></dt>
|
||||
<dd>contains the resulting AFINN-111 sentiment.</dd>
|
||||
<dt>sentiment.score <span class="property-type">number</span></dt>
|
||||
<dd>the sentiment score.</dd>
|
||||
</dl>
|
||||
<h3>Inputs</h3>
|
||||
<dl class="message-properties">
|
||||
<dt>words <span class="property-type">object</span></dt>
|
||||
<dd>an object of words and scores to override or add words can be supplied - <code>{ word:score,... }</code>.</dd>
|
||||
</dl>
|
||||
<dl class="message-properties">
|
||||
<dt>lang <span class="property-type">string</span></dt>
|
||||
<dd>Two letter cldr code to specify the language to use - from the list below</dd>
|
||||
</dl>
|
||||
<h3>Details</h3>
|
||||
<p>A score greater than zero is positive and less than zero is negative.</p>
|
||||
<p>The score typically ranges from -5 to +5, but can go higher and lower.</p>
|
||||
<p>See <a href="https://github.com/marcellobarile/multilang-sentiment/blob/develop/README.md" target="_blank">the Sentiment docs here</a>.</p>
|
||||
<p>The node can also be configured to let the language be specified by setting <code>msg.lang</code> to one of the codes below</p>
|
||||
<p>The language codes supported are - af, am, ar, az, be, bg, bn, bs, ca, ceb, co, cs, cy, da, de, el, en, eo, es, et, eu, fa, fi,
|
||||
fr, fy, ga, gd, gl, gu, ha, haw, hi, hmn, hr, ht, hu, hy, id, ig, is, it, iw, ja, jw, ka, kk, km, kn, ko, ku, ky, la, lb, lo, lt,
|
||||
lv, mg, mi, mk, ml, mn, mr, ms, mt, my, ne, nl, no, ny, pa, pl, ps, pt, ro, ru, sd, si, sk, sl, sm, sn, so, sq, sr, st, su, sv,
|
||||
sw, ta, te, tg, th, tl, tr, uk, ur, uz, vi, xh, yi, yo, zh, zh-tw, zu</p>
|
||||
</script>
|
||||
|
||||
<script type="text/javascript">
|
||||
RED.nodes.registerType('mlsentiment',{
|
||||
category: 'analysis-function',
|
||||
color:"#E6E0F8",
|
||||
defaults: {
|
||||
name: {value:""},
|
||||
property: {value:"payload",required:true},
|
||||
lang: {value:"en"}
|
||||
},
|
||||
inputs:1,
|
||||
outputs:1,
|
||||
icon: "arrow-in.png",
|
||||
paletteLabel: "multilang sentiment",
|
||||
label: function() {
|
||||
return this.name||"multilang sentiment";
|
||||
},
|
||||
labelStyle: function() {
|
||||
return this.name?"node_label_italic":"";
|
||||
},
|
||||
oneditprepare: function() {
|
||||
if (this.property === undefined) {
|
||||
$("#node-input-property").val("payload");
|
||||
}
|
||||
$("#node-input-property").typedInput({default:'msg',types:['msg']});
|
||||
}
|
||||
});
|
||||
</script>
|
28
analysis/mlsentiment/mlsentiment.js
Normal file
28
analysis/mlsentiment/mlsentiment.js
Normal file
@ -0,0 +1,28 @@
|
||||
|
||||
module.exports = function(RED) {
|
||||
"use strict";
|
||||
var multilangsentiment = require('multilang-sentiment');
|
||||
|
||||
function MultiLangSentimentNode(n) {
|
||||
RED.nodes.createNode(this,n);
|
||||
this.lang = n.lang;
|
||||
this.property = n.property||"payload";
|
||||
var node = this;
|
||||
|
||||
this.on("input", function(msg) {
|
||||
var value = RED.util.getMessageProperty(msg,node.property);
|
||||
if (value !== undefined) {
|
||||
if (msg.hasOwnProperty("overrides")) {
|
||||
msg.extras = msg.overrides;
|
||||
delete msg.overrides;
|
||||
}
|
||||
multilangsentiment(value, node.lang || msg.lang || 'en', {words: msg.extras || null}, function (err, result) {
|
||||
msg.sentiment = result;
|
||||
node.send(msg);
|
||||
});
|
||||
}
|
||||
else { node.send(msg); } // If no matching property - just pass it on.
|
||||
});
|
||||
}
|
||||
RED.nodes.registerType("mlsentiment",MultiLangSentimentNode);
|
||||
}
|
24
analysis/mlsentiment/package.json
Normal file
24
analysis/mlsentiment/package.json
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"name" : "node-red-node-multilang-sentiment",
|
||||
"version" : "0.1.0",
|
||||
"description" : "A Node-RED node that uses the AFINN-165 wordlists for sentiment analysis of words translated into multiple languages including emojis.",
|
||||
"dependencies" : {
|
||||
"multilang-sentiment" : "^1.2.0"
|
||||
},
|
||||
"repository" : {
|
||||
"type":"git",
|
||||
"url":"https://github.com/node-red/node-red-nodes/tree/master/analysis/sentiment"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"keywords": [ "node-red", "sentiment", "anaylsis", "AFINN" ],
|
||||
"node-red" : {
|
||||
"nodes" : {
|
||||
"mlsentiment": "mlsentiment.js"
|
||||
}
|
||||
},
|
||||
"author": {
|
||||
"name": "Dave Conway-Jones",
|
||||
"email": "ceejay@vnet.ibm.com",
|
||||
"url": "http://nodered.org"
|
||||
}
|
||||
}
|
@ -79,28 +79,6 @@ describe('sentiment Node', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('should add a positive score for good words (in French)', function(done) {
|
||||
var flow = [{id:"jn1",type:"sentiment",wires:[["jn2"]],lang:"fr"},
|
||||
{id:"jn2", type:"helper"}];
|
||||
helper.load(sentimentNode, flow, function() {
|
||||
var jn1 = helper.getNode("jn1");
|
||||
var jn2 = helper.getNode("jn2");
|
||||
jn2.on("input", function(msg) {
|
||||
try {
|
||||
msg.should.have.property('sentiment');
|
||||
msg.sentiment.should.have.property('score');
|
||||
msg.sentiment.score.should.be.a.Number();
|
||||
msg.sentiment.score.should.be.above(5);
|
||||
done();
|
||||
} catch(err) {
|
||||
done(err);
|
||||
}
|
||||
});
|
||||
var testString = 'bon, belle, don du ciel, brillant';
|
||||
jn1.receive({payload:testString});
|
||||
});
|
||||
});
|
||||
|
||||
it('should add a positive score for good words - alternative property', function(done) {
|
||||
var flow = [{id:"jn1",type:"sentiment",property:"foo",wires:[["jn2"]]},
|
||||
{id:"jn2", type:"helper"}];
|
||||
|
Loading…
Reference in New Issue
Block a user