blob: 27673604263f53652f5d0c3e73e5649381be1ab6 [file] [log] [blame]
Marc Kupietzdc22b982015-10-09 09:19:34 +02001#!/usr/local/bin/perl
2use Inline C;
3use Mojolicious::Lite;
4
5init_net($ARGV[1]);
6
7helper print_neighbours => sub { shift; print_neighbours(@_) };
8
9get '/' => sub {
10 my $c = shift;
11 my $word=$c->param('word');
12 $c->render(template=>"index", word=>$word);
13};
14
15app->start;
16
17exit;
18
19__END__
20
21__C__
22#include <stdio.h>
23#include <string.h>
24#include <math.h>
25#include <malloc.h>
26#include <stdlib.h> //strlen
27
28#define max_size 2000
29#define max_w 50
30#define N 75
31
32//the thread function
33void *connection_handler(void *);
34
35char *bestw[N];
36char file_name[max_size], st[100][max_size];
37float dist, len, bestd[N], vec[max_size];
38long long words, size, a, b, c, d, cn, bi[100];
39char ch;
40float *M;
41char *vocab;
42char *stringBuffer;
43
44int init_net(char *file_name) {
45 FILE *f;
46
47 stringBuffer = malloc(64000);
48 f = fopen(file_name, "rb");
49 if (f == NULL) {
50 printf("Input file %s not found\n", file_name);
51 return -1;
52 }
53 fscanf(f, "%lld", &words);
54 fscanf(f, "%lld", &size);
55 vocab = (char *)malloc((long long)words * max_w * sizeof(char));
56 for (a = 0; a < N; a++) bestw[a] = (char *)malloc(max_size * sizeof(char));
57 M = (float *)malloc((long long)words * (long long)size * sizeof(float));
58 if (M == NULL) {
59 printf("Cannot allocate memory: %lld MB %lld %lld\n", (long long)words * size * sizeof(float) / 1048576, words, size);
60 return -1;
61 }
62 for (b = 0; b < words; b++) {
63 a = 0;
64 while (1) {
65 vocab[b * max_w + a] = fgetc(f);
66 if (feof(f) || (vocab[b * max_w + a] == ' ')) break;
67 if ((a < max_w) && (vocab[b * max_w + a] != '\n')) a++;
68 }
69 vocab[b * max_w + a] = 0;
70 for (a = 0; a < size; a++) fread(&M[a + b * size], sizeof(float), 1, f);
71 len = 0;
72 for (a = 0; a < size; a++) len += M[a + b * size] * M[a + b * size];
73 len = sqrt(len);
74 for (a = 0; a < size; a++) M[a + b * size] /= len;
75 }
76 fclose(f);
77 return 0;
78}
79
80char *print_neighbours(char *st1) {
81 FILE *out=stdout;
82 *stringBuffer=0;
83
84 for (a = 0; a < N; a++) bestd[a] = 0;
85 for (a = 0; a < N; a++) bestw[a][0] = 0;
86 a = 0;
87 cn = 0;
88 b = 0;
89 c = 0;
90 while (1) {
91 st[cn][b] = st1[c];
92 b++;
93 c++;
94 st[cn][b] = 0;
95 if (st1[c] == 0) break;
96 if (st1[c] == ' ') {
97 cn++;
98 b = 0;
99 c++;
100 }
101 }
102 cn++;
103 for (a = 0; a < cn; a++) {
104 for (b = 0; b < words; b++) if (!strcmp(&vocab[b * max_w], st[a])) break;
105 if (b == words) b = -1;
106 bi[a] = b;
107 sprintf(stringBuffer, "\n<pre>Word: \"%s\" Position in vocabulary: %lld</pre>\n", st[a], bi[a]);
108 if (b == -1) {
109 sprintf(stringBuffer+strlen(stringBuffer), "Out of dictionary word!\n");
110 break;
111 }
112 }
113 if (b == -1) return stringBuffer;
114 sprintf(stringBuffer+strlen(stringBuffer), "\n<table><tr><th>Word</th><th>Cosine distance</th></tr>\n");
115 for (a = 0; a < size; a++) vec[a] = 0;
116 for (b = 0; b < cn; b++) {
117 if (bi[b] == -1) continue;
118 for (a = 0; a < size; a++) vec[a] += M[a + bi[b] * size];
119 }
120 len = 0;
121 for (a = 0; a < size; a++) len += vec[a] * vec[a];
122 len = sqrt(len);
123 for (a = 0; a < size; a++) vec[a] /= len;
124 for (a = 0; a < N; a++) bestd[a] = -1;
125 for (a = 0; a < N; a++) bestw[a][0] = 0;
126 for (c = 0; c < words; c++) {
127 a = 0;
128 for (b = 0; b < cn; b++) if (bi[b] == c) a = 1;
129 if (a == 1) continue;
130 dist = 0;
131 for (a = 0; a < size; a++) dist += vec[a] * M[a + c * size];
132 for (a = 0; a < N; a++) {
133 if (dist > bestd[a]) {
134 for (d = N - 1; d > a; d--) {
135 bestd[d] = bestd[d - 1];
136 strcpy(bestw[d], bestw[d - 1]);
137 }
138 bestd[a] = dist;
139 strcpy(bestw[a], &vocab[c * max_w]);
140 break;
141 }
142 }
143 }
144 for (a = 0; a < N; a++) sprintf(stringBuffer+strlen(stringBuffer), "<tr><td>%s</td><td align=\"right\">%f</td></tr>\n", bestw[a], bestd[a]);
145 sprintf(stringBuffer+strlen(stringBuffer), "</table>\n");
146 return stringBuffer;
147}
148
149__DATA__
150
151@@ index.html.ep
152<!DOCTYPE html>
153<html>
154<head><title>word2vec</title></head>
155<body>
156 <form action="<%=url_for('/')->to_abs%>" method="GET">
157 Word: <input type="text" name="word">
158 <input type="submit" value="Show neighbours">
159 </form>
160 <br>
161 <%== print_neighbours($word) %>
162</body>
163</html>
164