Wie man Python oder Julia von Ruby aus aufruft (experimentelle Implementierung)

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.

Eine kurze Einführung in die Bedienung des virtuellen Moduls mit REPL

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

Wie man Python oder Julia von Ruby aus aufruft (experimentelle Implementierung)
MessagePack-Aufruf von Ruby to Python-Methoden (oder Python to Ruby-Methoden) mithilfe von RPC
[Python] So rufen Sie eine Funktion von c aus Python auf (ctypes edition)
Rufen Sie Matlab von Python zur Optimierung auf
Rufen Sie popcount von Ruby / Python / C # auf
So greifen Sie über Python auf Wikipedia zu
So rufen Sie PyTorch in Julia an
Offline in Echtzeit, wie man ein Implementierungsbeispiel für E11 Ruby und Python schreibt
So aktualisieren Sie Google Sheets von Python
Zugriff auf RDS von Lambda (Python)
Wie man Spaß am Programmieren mit Minecraft hat (Ruby, Python)
So öffnen Sie einen Webbrowser über Python
[Python] Konvertieren von DICOM in PNG oder CSV
[Python] Lesen von Daten aus CIFAR-10 und CIFAR-100
So generieren Sie ein Python-Objekt aus JSON
Eine einfache Möglichkeit, Java von Python aus aufzurufen
So installieren Sie Python
Änderungen von Python 3.0 zu Python 3.5
Änderungen von Python 2 zu Python 3.0
Python aus oder importieren
[Python] So entfernen Sie doppelte Werte aus der Liste
So kratzen Sie Bilddaten von Flickr mit Python
So messen Sie die Verarbeitungszeit mit Python oder Java
So laden Sie Dateien von Selenium of Python in Chrome herunter
Führen Sie die Python-Funktion von Powershell aus (wie Sie Argumente übergeben).
python, php, ruby Konvertieren von Dezimalzahlen in n
Umgang mit JSON in Ruby, Python, JavaScript, PHP
Ein Mechanismus zum Aufrufen von Ruby-Methoden aus Python, der in 200 Zeilen ausgeführt werden kann
Rufen Sie C-Sprachfunktionen von Python auf, um mehrdimensionale Arrays auszutauschen
Rufen Sie CPLEX von Python aus auf (DO cplex)
Post von Python nach Slack
So installieren Sie Python [Windows]
python3: Verwendung der Flasche (2)
Offline-Echtzeit zum Schreiben eines E14 Python-Implementierungsbeispiels
Flirte von PHP nach Python
So schneiden Sie ein Block-Multiple-Array aus einem Multiple-Array in Python
So führen Sie ein Python-Programm in einem Shell-Skript aus
Verwendung der Methode __call__ in der Python-Klasse
Verliere nicht gegen Ruby! Wie man Python (Django) auf Heroku ausführt
So rufen Sie eine Funktion auf
So aktualisieren Sie Pythons Tkinter auf 8.6
So starten Sie AWS Batch über die Python-Client-App
Herstellen einer Verbindung zu verschiedenen DBs über Python (PEP 249) und SQL Alchemy
Anaconda aktualisiert von 4.2.0 auf 4.3.0 (python3.5 aktualisiert auf python3.6)
Wie benutzt man Python Argparse?
Wie man aus einer Wahrscheinlichkeitsdichtefunktion in Python tastet
[Python] Verwendung von checkio
[Python / Ruby] Mit Code verstehen Wie man Daten aus dem Internet abruft und in CSV schreibt
Wechseln Sie von Python2.7 zu Python3.6 (centos7)
So führen Sie Notepad ++ Python aus
Stellen Sie von Python aus eine Verbindung zu SQLite her
So ändern Sie die Python-Version
[Python] Wie man Skalar beurteilt
[Python] Verwendung von input ()
Wie benutzt man Python Lambda?
[Python] Verwendung von virtualenv
python3: Verwendung der Flasche (3)
python3: Wie man eine Flasche benutzt
Gehen Sie zur Sprache, um Teil 8 zu sehen und sich daran zu erinnern. Rufen Sie die GO-Sprache von Python aus auf