Skip to content

Commit a2ba565

Browse files
committed
Testing, licensing, packaging etc
1 parent bfded96 commit a2ba565

10 files changed

Lines changed: 112 additions & 20 deletions

File tree

.npmignore

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
6+
# Runtime data
7+
pids
8+
*.pid
9+
*.seed
10+
11+
# Directory for instrumented libs generated by jscoverage/JSCover
12+
lib-cov
13+
14+
# Coverage directory used by tools like istanbul
15+
coverage
16+
17+
# nyc test coverage
18+
.nyc_output
19+
20+
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
21+
.grunt
22+
23+
# node-waf configuration
24+
.lock-wscript
25+
26+
# Compiled binary addons (http://nodejs.org/api/addons.html)
27+
build/Release
28+
29+
# Dependency directories
30+
node_modules
31+
jspm_packages
32+
33+
# Optional npm cache directory
34+
.npm
35+
36+
# Optional REPL history
37+
.node_repl_history

Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
test:
2+
./node_modules/.bin/mocha --reporter spec
3+
4+
.PHONY: test

README.md

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,27 @@
11
# dracula-sentiment-node
2-
node.js/Javascript implementation of Dracula - adapted to do deep sentiment analysis using character embeddings.
2+
A quick way to get "good enough" sentiment analysis into your applications, this package uses character and word-level embeddings and LSTM networks to decide if a given text is either "positive" or "negative".
3+
4+
## Installation
5+
6+
npm install dracula-sentiment --save
7+
8+
## Usage
9+
10+
var dracula = require('dracula-sentiment');
11+
var text = "xoxo cant wait";
12+
console.log(text, dracula.analyze(text));
13+
14+
For best results, remove any non-ascii characters by converting them to their closest equivalents via `unidecode` or something similar.
15+
16+
## Testing
17+
18+
npm test
19+
20+
Tests aren't very extensive at present.
21+
22+
## Contributing
23+
24+
If you encounter any sentences where the classifiction is obviously wrong, open an issue and we'll work out a way to extend Dracula's training data so that it doesn't happen. Contributions to clean up the code and improve its style and performance are certainly welcome!
25+
26+
## Release
27+
* 1.0.0 Original release

dracula.embeddings.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@ function draculaGetEmbeddings(word, length) {
1919
}
2020

2121
for (var i = ret.length; i < length; i++) {
22-
ret.push(new Array(32).fill(0));
22+
var r = [];
23+
// Change from browser version: ES6 is messy
24+
for (var i = 0; i < 32; i++) r.push(0);
25+
ret.push(r);
2326
}
2427

2528
return ret;

dracula.js

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,18 @@ function dracula(content, visualize) {
3434
}
3535

3636
var lstmOutput = lstmOutput1;
37-
3837
// Mean-pooling
3938
var meanOutput = [];
4039
for (var i = 0; i < lstmOutput.length; i++) {
4140
if (lengths[i] == 0) break;
42-
var cur = new Array(32).fill(0);
43-
var max = new Array(32).fill(-Number.MAX_VALUE);
44-
var min = new Array(32).fill(Number.MAX_VALUE);
41+
var cur = [];
42+
var min = [];
43+
var max = [];
44+
for (var j = 0; j < 32; j++) {
45+
cur.push(0);
46+
max.push(-Number.MAX_VALUE);
47+
min.push(Number.MAX_VALUE);
48+
}
4549
for (var j = 0; j < lengths[i]; j++) {
4650
cur = numeric.add(cur, lstmOutput[i][j]);
4751
max = numeric.max(max, lstmOutput[i][j]);
@@ -65,7 +69,10 @@ function dracula(content, visualize) {
6569
visualize2DActivation(lstmWords, "lstm-words-"+i, "Word-level LSTM")
6670
}
6771

68-
var finalPool = new Array(96).fill(0);
72+
var finalPool = [];
73+
for (var i = 0; i < 96; i++) {
74+
finalPool.push(0);
75+
}
6976
for (var i = 0; i < lstmWords.length; i++) {
7077
finalPool = numeric.add(finalPool, lstmWords[i]);
7178
}
@@ -80,6 +87,6 @@ function dracula(content, visualize) {
8087
if (visualize) {
8188
visualize2DActivation(probs, "probs-plot", "Softmax");
8289
}
83-
return determineLabels(probs);
90+
output = determineLabels(probs);
8491
return output.join(', ');
8592
}

dracula.lstm.js

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ function draculaLSTM(values, prefix, backwards, dims) {
55
// Basically a 2D version of what's in nn_lstm.py
66

77
prefix = 'draculaParams_'+prefix;
8-
var U = window[prefix+'_U'];
9-
var W = window[prefix+'_W'];
10-
var b = window[prefix+'_b'];
8+
var U = eval(prefix+'_U');
9+
var W = eval(prefix+'_W');
10+
var b = eval(prefix+'_b');
1111

1212
var sigmoid = function(t) {
1313
return numeric.div(1,
@@ -41,8 +41,11 @@ function draculaLSTM(values, prefix, backwards, dims) {
4141
stateBelow[i] = numeric.add(stateBelow[i], b)
4242
}
4343

44-
var h_ = new Array(dims).fill(0);
45-
var c_ = new Array(dims).fill(0);
44+
var h_ = [];
45+
var c_ = [];
46+
for (var i = 0; i < dims; i++) {
47+
h_.push(0); c_.push(0);
48+
}
4649
var ret = [];
4750

4851
var tokens = [];

dracula.softmax.js

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,18 @@
11
function draculaSoftmax(values) {
22

33
// TODO: need to check if this U is the same as the one exported
4-
// var act = numeric.dot(values, draculaParams_U);
54
var act = [];
65
for (var i = 0; i < values.length; i++) {
76
var tmp = numeric.dot(values[i], draculaParams_U);
87
tmp = numeric.add(tmp, draculaParams_b);
98
act.push(tmp);
109
}
1110

12-
//var exp = numeric.exp(act);
1311
var exp = [];
1412
for (var i = 0; i < act.length; i++) {
15-
//var ex = numeric.exp(act[i] - Math.max(...act[i]))
1613
var ex = numeric.exp(act[i]);
1714
ex = numeric.div(ex, numeric.sum(ex))
1815
exp.push(ex);
19-
// exp[i] = numeric.div(exp[i], numeric.sum(exp[i]));
2016
}
2117
return exp;
2218
}
@@ -36,9 +32,9 @@ function determineLabels(exp) {
3632
}
3733
}
3834
if (argMax == 0) {
39-
ret.push("This tweet might be negative.");
35+
ret.push("negative");
4036
} else if (argMax == 2) {
41-
ret.push("This tweet may possibly be positive.");
37+
ret.push("positive");
4238
} else {
4339
ret.push("Something weird's going on here: the argMax is not working "
4440
+" correctly");

index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,14 @@ var fs = require('fs');
1414
// similar to the browser version as possible.
1515
var numeric = require('numeric');
1616
eval(fs.readFileSync('dracula.params.js')+'');
17+
eval(fs.readFileSync('dracula.embeddings.js')+'');
1718
eval(fs.readFileSync('dracula.lstm.js')+'');
1819
eval(fs.readFileSync('dracula.softmax.js')+'');
1920
eval(fs.readFileSync('dracula.tokenize.js')+'');
2021
eval(fs.readFileSync('dracula.js')+'');
2122

2223
module.exports = {
23-
analyse: function(string) {
24+
analyze: function(string) {
2425
return dracula(string, false);
2526
}
2627
}

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,8 @@
3030
"devDependencies": {
3131
"chai": "^3.5.0",
3232
"mocha": "^2.5.3"
33+
},
34+
"scripts": {
35+
"test": "make test"
3336
}
3437
}

test/index.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
var should = require('chai').should(),
2+
dracula = require('../index'),
3+
analyze = dracula.analyze;
4+
5+
describe('#analyze', function() {
6+
it('Should think "terror" is bad news', function() {
7+
analyze("terror").should.equal("negative");
8+
});
9+
10+
it('Should think "puppies" are good news', function() {
11+
analyze('puppies').should.equal("positive");
12+
});
13+
});

0 commit comments

Comments
 (0)