Je crée un joyau appelé virtual_module
qui peut appeler les packages Python et Julia de Ruby. Dans l'exemple ci-dessous, la partie de lecture de la page de manuel de certaines commandes en tant que document est écrite en Ruby, et la partie à traiter par doc2vec est appelée Python et laissée à 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]]
J'ai utilisé ceci pour ajouter une fonction pour extraire des articles liés à l'aide de doc2vec qui fonctionne sur Ruby sur mon blog (créé par Sinatra), mais c'était un peu pratique. Je ne sais pas combien de personnes seront heureuses à part moi, mais (bien que ce soit assez gênant) vous pourrez également utiliser scikit-learn. Aller.
En plus de doc2vec, des exemples d'utilisation de scicit-learn sont résumés dans Personal blog -from-ruby /) Donc, si vous êtes intéressé, veuillez le vérifier.
Ici, j'utiliserai REPL pour écrire comment le module virtuel fonctionne en interne. On suppose que les éléments suivants sont déjà installés sur votre système:
virtual_module
(v0.3.0 ou supérieure)Tout d'abord, lancez irb.
debussy:~ remore$ irb -r virtual_module
irb(main):001:0> po = VirtualModule.new(:python=>["sklearn"=>"datasets"])
=> #<Module:0x007fb7e1aee818>
L'appel de «VirtualModule # new» lance un processus Python (ou Julia) dans les coulisses. Lorsque le lancement du travail en arrière-plan a réussi, VirtualModule renvoie une nouvelle instance de Module. Désormais, nous communiquerons avec l'arrière-plan via cette instance de Module (≒ cette instance se comporte comme un proxy). Pour plus de commodité, nous appellerons cela un objet proxy.
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
Le comportement de l'objet proxy est très simple. Dans l'exemple ci-dessus, l'objet proxy reçoit un appel de méthode appelé ʻint (2.3) ʻet le transmet au travail d'arrière-plan tel quel (à ce moment, msgpack est utilisé pour convertir la valeur). En conséquence, la valeur de type Fixnum «2» est sortie vers le terminal, qui est renvoyée par le travail en arrière-plan. Puisque la conversion de données n'utilise que msgpack, les valeurs qui peuvent être converties les unes aux autres sont également conformes aux spécifications de msgpack. Si une méthode non définie est appelée du côté du travail d'arrière-plan, comme dans l'exemple po.unknown_method (2.3)
, une erreur sera affichée. Fondamentalement, ce qui précède est tout le fonctionnement du module virtuel.
Je pense qu'il y a des endroits que je ne peux pas m'empêcher d'ajouter un peu plus.
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]
Consultez cet exemple pour voir comment cela fonctionne lorsque des valeurs qui ne peuvent pas être réellement converties par msgpack sont utilisées. Dans cet exemple, l'objet proxy (la variable locale po
ici) retourne d'abord un nouvel objet proxy (# <Module: 0x007ffd0906c030>
) en réponse à l'appel de la méthode # datasets
, mais après cela #load_iris (: _)
renvoie également un autre objet proxy (# <Module: 0x007ffd09074500>
). Étant donné que les ensembles de données sont des objets de type module sur Python, et load_iris (: _) est une instance de la classe `` 'sklearn.datasets.base.Bunch' ', aucun ne peut être converti via msgpack, donc l'instance Module est A été généré. Pour les appels qui ne peuvent pas être convertis par mspgack de cette manière, la valeur réelle n'est pas transmise à VirtualModule et seul un pointeur vers cette valeur est passé.
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]
Dans Ruby, vous pouvez obtenir des informations sur différents états d'un objet avec ʻObject # class et ʻObject # methods
, mais VirtualModule suit cela avec des méthodes similaires (# vclass
et # vmethods
. `) Est prêt. Comme vous pouvez l'imaginer, «# vclass» visite le travail d'arrière-plan et renvoie le type de cette valeur, et «# vmethods» renvoie les méthodes disponibles pour cet objet.
C'est tout pour l'explication jusqu'à présent, mais si quelqu'un veut voir plus d'exemples, j'ai quelques autres exemples sur GitHub Vous pouvez vous y référer dans / tree / master / example). C'est une implémentation expérimentale, donc je pense que c'est difficile à utiliser dans de nombreux endroits, mais si quelqu'un veut l'utiliser, je serais heureux si vous pouviez me dire ce que vous en pensez.
Recommended Posts