перевод кода Python для генерации цепей Маркова в lua - PullRequest
0 голосов
/ 04 января 2019

как проект для начинающих, я пытаюсь перевести этот код Python в код Lua https://eli.thegreenplace.net/2018/elegant-python-code-for-a-markov-chain-text-generator/. У меня проблемы с переводом питонов "random.choices" правильно. Сама матрица Маркова должна работать. Я был бы благодарен за любую помощь в создании цепочки markov с этим кодом lua. это вывод марковской матрицы для марковского заказа 3 и этот ввод "1111111111111110000006000000000006600".

600 0   1
111 1   12
111 0   1
060 0   1
660 0   1
006 6   1
006 0   1
100 0   1
000 6   2
000 0   11
110 0   1
066 0   1

с этой информацией мне нужно рассчитать следующий шаг, но я не знаю, как это сделать с lua. для последовательности 600 0 следует с 100%, для последовательности 111 1 следует с 12/13, а 0 с 1/13, для последовательности 060 следует 0 с 100% и т. д.

вот мой код Луа:

math.randomseed(os.time()- os.clock() * 1000);
-- make dictionary;
function defaultdict(default_value_factory);
local t = {};
local metatable = {};
metatable.__index = function(t, key);
if not rawget(t, key) then;
rawset(t, key, default_value_factory(key));
end;
return rawget(t, key);
end;
return setmetatable(t, metatable);
end;
;
;
-- make markov matrix;
STATE_LEN = 3;
model = defaultdict(function() return {} end)
data = "1111111111111110000006000000000006600";
print("datasize: ", #data)
print('Learning model...')
for i = 1, (#data - STATE_LEN) do;
state = data:sub(i, i + STATE_LEN-1);
print("state: ", state)    
local next = data:sub(i + STATE_LEN, i + STATE_LEN);
print("next: ", next);
model[state][next] = (model[state][next] or 0)+1;
end;
;
;
-- make markov chain;
print('Sampling...');
;
-- make key list;
local keyset={};
local n=0;
for k,v in pairs(model) do;
n=n+1;
keyset[n]=k;
end;
-- make random key;
local randomKey = keyset[math.random(#keyset)];
print("RandomKey: ", randomKey)
state = randomKey;
;
-- make table from random key;
local str = state;
local stateTable = {};
for i = 1, #str do;
stateTable[i] = str:sub(i, i);
end;
;
out = stateTable;
print ("random key as table: ", table.unpack(stateTable));
;
-- make value list;
local valueset={};
local n=0;
for key, value in pairs(model) do;
for k, v in pairs(value) do;
n=n+1;
valueset[n]=v;
end;
end;
;
print("Keys: ", table.unpack(keyset));
print("Vals: ", table.unpack(valueset));
;
for key, value in pairs(model) do;
for k, v in pairs(value) do;
print(key, k, v);
end;
end;
;
;
-- make markov chain;
for i = 1, 400 do;
table.insert(out, #out + 1, math.random(10)); 
state = string.sub(state, 2, #state) .. out[#out];
end;
-- print markov chain;
print(table.concat(out));
;

1 Ответ

0 голосов
/ 06 января 2019

я думаю, что понял это сам. я не знаю, должен ли я удалить свой вопрос, так или иначе, вот код и мой ответ:

-- LUA MARKOV GENERATOR;
;
local markovOrder = 3;
local markovChainLength = 16;
local randomStart = 0;
local markovInputList = {1, 1, 2, 1 , 1 , 2, 2, 1, 2, 6, 6, 2, 1, 6, 6, 1, 2, 6, 6, 6, 1, 1, 6, 6, 1, 2, 2, 2, 1};
;
math.randomseed(os.time()- os.clock() * 1000);
;
print("LUA MARKOV GENERATOR");
print("Markov Order: ", math.floor(markovOrder));
;
-- make dictionary;
;
local function defaultdict(default_value_factory);
;
local t = {};
local metatable = {};
metatable.__index = function(t, key);
if not rawget(t, key) then;
rawset(t, key, default_value_factory(key));
end;
return rawget(t, key);
end;
return setmetatable(t, metatable);
end;
;
-- make markov matrix;
;
local model = defaultdict(function() return {} end);
local data = {};
for i = 1, #markovInputList do;
data[i] = markovInputList[i];
end;
print("Data Size: ", #markovInputList);
for i = 1, markovOrder do;
table.insert(data, data[i]);
end;
for i = 1, #data - markovOrder do;
local state = table.concat({table.unpack(data, i, i + markovOrder - 1)}, "-");
local next = table.unpack(data, i + markovOrder, i + markovOrder);
model[state][next] = (model[state][next] or 0)+1;
end;
;
-- make tables from dict;
;
local keyTbl = {};
local nexTbl = {};
local prbTbl = {};
for key, value in pairs(model) do;
for k, v in pairs(value) do;
table.insert(keyTbl, key);
table.insert(nexTbl, k);
table.insert(prbTbl, v);
end;
end;
;
print("Key: ", table.unpack(keyTbl));
print("Nex: ", table.unpack(nexTbl));
print("Prb: ", table.unpack(prbTbl));
;
print("Make a Markov Chain...");
;
-- make start key;
;
local startKey = {};
if randomStart == 1 then;
local randomKey = math.random(#keyTbl);
startKey = randomKey;
else;
startKey = 1;
end;
;
local markovString = keyTbl[startKey];
local out = {};
for match in string.gmatch(keyTbl[startKey], "[^-]+") do;
table.insert(out, match);
end;
;
-- make markov chain;
;
for i = 1, markovChainLength do;
;
-- weighted random choices;
;
local choices = {};
local weights = {};
for j = 1, #keyTbl do;
if markovString == keyTbl[j] then;
table.insert(choices, nexTbl[j]);
table.insert(weights, prbTbl[j]);
end;
end;
;
-- print ("choices:", table.unpack(choices));
-- print ("weights:", table.unpack(weights));
;
local totalWeight = 0;
for _, weight in pairs(weights) do;
totalWeight = totalWeight + weight;
end;
rand = math.random() * totalWeight;
local choice = nil;
for i, weight in pairs(weights) do;
if rand < weight then;
choice = choices[i];
break;
else;
rand = rand - weight;
end;
end;
;
table.insert(out, choice);
local lastStep = {table.unpack(out, #out - (markovOrder-1), #out)};
markovString = table.concat(lastStep, "-");
end;
;
print ("Markov Chain: ", table.unpack(out, markovOrder + 1, #out));
;
...