Ich mache ein Juwel namens "virtual_module", das Python- und Julia-Pakete von Ruby aus aufrufen kann. Im folgenden Beispiel schreiben wir in Ruby bis zum Lesen der Manpage einiger Befehle als Dokument, rufen Python auf und überlassen den von doc2vec zu verarbeitenden Teil gensim.
doc2vec.rb
require 'natto'
manpages={}
natto = Natto::MeCab.new
%w"ps ls cat cd top df du touch mkdir".each do |cmd|
list = []
natto.parse(`man #{cmd} | col -bx | cat`) do |n|
list << n.surface
end
manpages[cmd] = list
end
require 'virtual_module'
py = VirtualModule.new(:methods=><<EOS, :python=>["gensim"])
class LabeledListSentence(object):
def __init__(self, words_list, label_list):
self.words_list = words_list
self.label_list = label_list
def __iter__(self):
for i, words in enumerate(self.words_list):
yield gensim.models.doc2vec.LabeledSentence(words, [self.label_list[i]])
EOS
model = py.gensim.models.doc2vec.Doc2Vec(py.LabeledListSentence(manpages.values, manpages.keys), min_count:0)
p model.docvecs.most_similar(["ps"]) # [["top", 0.5594387054443359], ["cat", 0.46929454803466797], ["df", 0.3900265693664551], ["mkdir", 0.38811227679252625], ["du", 0.23663029074668884], ["ls", 0.15436093509197235], ["cd", -0.1965409815311432], ["touch", -0.38958919048309326]]
Ich habe dies verwendet, um eine Funktion zum Extrahieren verwandter Artikel mit doc2vec, die auf Ruby ausgeführt wird, zu meinem Blog (erstellt von Sinatra) hinzuzufügen, aber es war ein wenig praktisch. Ich weiß nicht, wie viele Menschen außer mir glücklich sein können, aber (obwohl es ziemlich unpraktisch ist) Sie können auch Scicit-Learn verwenden. Gehen.
Zusätzlich zu doc2vec sind Beispiele für die Verwendung von scicit-learn in Personal blog zusammengefasst. -from-ruby /) Also, wenn Sie interessiert sind, schauen Sie es sich bitte an.
Hier werde ich REPL verwenden, um zu schreiben, wie das virtuelle Modul intern funktioniert. Es wird davon ausgegangen, dass Folgendes bereits auf Ihrem System installiert ist:
--virtual_module
gem (v0.3.0 oder höher)
Starten Sie zuerst irb.
debussy:~ remore$ irb -r virtual_module
irb(main):001:0> po = VirtualModule.new(:python=>["sklearn"=>"datasets"])
=> #<Module:0x007fb7e1aee818>
Durch Aufrufen von "VirtualModule # new" wird ein Python- (oder Julia-) Prozess hinter den Kulissen gestartet. Wenn der Hintergrundjob erfolgreich gestartet wurde, gibt VirtualModule eine neue Modulinstanz zurück. Von nun an werden wir über diese Modulinstanz mit dem Hintergrund kommunizieren (≒ diese Instanz verhält sich wie ein Proxy). Der Einfachheit halber nennen wir dies ein Proxy-Objekt.
irb(main):002:0> py.int(2.3)
=> 2
irb(main):003:0> po.unknown_method(2.3)
RuntimeError: An error occurred while executing the command in python process: ,name 'unknown_method' is not defined
Das Verhalten des Proxy-Objekts ist sehr einfach. Im obigen Beispiel empfängt das Proxy-Objekt einen Methodenaufruf namens "int (2.3)" und leitet ihn unverändert an den Hintergrundjob weiter (zu diesem Zeitpunkt wird msgpack zum Konvertieren des Werts verwendet). Infolgedessen wird der Fixnum-Typwert "2" an das Terminal ausgegeben, das vom Hintergrundjob zurückgegeben wird. Da bei der Datenkonvertierung nur msgpack verwendet wird, entsprechen die Werte, die ineinander konvertiert werden können, auch den msgpack-Spezifikationen. Wenn auf der Hintergrundjobseite eine undefinierte Methode aufgerufen wird, wie im Beispiel po.unknown_method (2.3)
, wird ein Fehler angezeigt. Grundsätzlich ist das Obige der gesamte Betrieb des virtuellen Moduls.
Ich denke, dass es einige Stellen gibt, an denen dies allein keinen Sinn ergibt, deshalb werde ich etwas mehr hinzufügen.
irb(main):004:0> po.datasets
=> #<Module:0x007ffd0906c030>
irb(main):005:0> po.datasets.load_iris(:_)
=> #<Module:0x007ffd09074500>
irb(main):006:0> po.datasets.load_iris(:_).vclass
=> "<class 'sklearn.datasets.base.Bunch'>"
irb(main):007:0> po.datasets.load_iris(:_).data[1].to_a
=> [4.9, 3.0, 1.4, 0.2]
In diesem Beispiel sehen Sie, wie es funktioniert, wenn Werte verwendet werden, die von msgpack nicht konvertiert werden können. In diesem Beispiel gibt das Proxy-Objekt (hier die lokale Variable po
) zuerst ein neues Proxy-Objekt (# <Module: 0x007ffd0906c030>
) als Antwort auf den Aufruf der Methode # datasets
zurück, danach jedoch #load_iris (: _)
gibt auch ein anderes Proxy-Objekt zurück (# <Modul: 0x007ffd09074500>
). Da Datasets in Python Modultypobjekte sind und load_iris (: _) eine Instanz der Klasse "sklearn.datasets.base.Bunch" ist, kann keines von beiden über msgpack konvertiert werden, daher ist dies die Modulinstanz Wurde generiert. Bei Aufrufen, die von mspgack auf diese Weise nicht konvertiert werden können, wird der tatsächliche Wert nicht an VirtualModule übergeben, und es wird nur ein Zeiger auf diesen Wert übergeben.
irb(main):008:0> po.datasets.vclass
=> "<type 'module'>"
irb(main):009:0> iris = po.datasets.load_iris(:_)
=> #<Module:0x007ffd09057568>
irb(main):010:0> iris.target.vclass
=> "<type 'numpy.ndarray'>"
irb(main):011:0> iris.target.vmethods
=> ["T", "__abs__", "__add__", "__and__", "__array__", "__array_finalize__", "__array_interface__", "__array_prepare__", "__array_priority__", "__array_struct__", "__array_wrap__", "__class__", "__contains__", "__copy__", "__deepcopy__", "__delattr__", "__delitem__", "__delslice__", "__div__", "__divmod__", "__doc__", "__eq__", "__float__", "__floordiv__", "__format__", "__ge__", "__getattribute__", "__getitem__", "__getslice__", "__gt__", "__hash__", "__hex__", "__iadd__", "__iand__", "__idiv__", "__ifloordiv__", "__ilshift__", "__imod__", "__imul__", "__index__", "__init__", "__int__", "__invert__", "__ior__", "__ipow__", "__irshift__", "__isub__", "__iter__", "__itruediv__", "__ixor__", "__le__", "__len__", "__long__", "__lshift__", "__lt__", "__mod__", "__mul__", "__ne__", "__neg__", "__new__", "__nonzero__", "__oct__", "__or__", "__pos__", "__pow__", "__radd__", "__rand__", "__rdiv__", "__rdivmod__", "__reduce__", "__reduce_ex__", "__repr__", "__rfloordiv__", "__rlshift__", "__rmod__", "__rmul__", "__ror__", "__rpow__", "__rrshift__", "__rshift__", "__rsub__", "__rtruediv__", "__rxor__", "__setattr__", "__setitem__", "__setslice__", "__setstate__", "__sizeof__", "__str__", "__sub__", "__subclasshook__", "__truediv__", "__xor__", "all", "any", "argmax", "argmin", "argpartition", "argsort", "astype", "base", "byteswap", "choose", "clip", "compress", "conj", "conjugate", "copy", "ctypes", "cumprod", "cumsum", "data", "diagonal", "dot", "dtype", "dump", "dumps", "fill", "flags", "flat", "flatten", "getfield", "imag", "item", "itemset", "itemsize", "max", "mean", "min", "nbytes", "ndim", "newbyteorder", "nonzero", "partition", "prod", "ptp", "put", "ravel", "real", "repeat", "reshape", "resize", "round", "searchsorted", "setfield", "setflags", "shape", "size", "sort", "squeeze", "std", "strides", "sum", "swapaxes", "take", "tobytes", "tofile", "tolist", "tostring", "trace", "transpose", "var", "view"]
irb(main):012:0> iris.target.to_a
=> [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]
In Ruby können Sie Informationen zu verschiedenen Zuständen eines Objekts mit den Methoden "Object # class" und "Object #" abrufen. VirtualModule folgt jedoch mit ähnlichen Methoden ("# vclass" und "# vmethods"). ) Ist vorbereitet. Wie Sie sich vorstellen können, besucht
# vclass den Hintergrundjob und gibt den Typ dieses Werts zurück, und
# vmethods` gibt die für dieses Objekt verfügbaren Methoden zurück.
Das ist alles für die bisherige Erklärung, aber wenn jemand mehr Beispiele sehen möchte, habe ich einige andere Beispiele auf GitHub Sie können in / tree / master / example darauf verweisen. Es ist eine experimentelle Implementierung, daher denke ich, dass es an vielen Orten schwierig ist, sie zu verwenden, aber wenn jemand sie verwenden möchte, würde ich mich freuen, wenn Sie mir sagen könnten, was Sie darüber denken.
Recommended Posts