分享好友 编程语言首页 频道列表

一个关于创建一个可以用 Ruby 做 UMAP 的 gem 的故事

ruby专题  2023-03-08 10:580

RubyでUMAPをできるgemを作った話RubyでUMAPをできるgemを作った話
RubyでUMAPをできるgemを作った話

介绍

统一流形逼近和投影 (UMAP) 是一种通过降维的可视化方法,通常与 t-SNE 一起使用。

用 Ruby 语言执行机器学习时,瘤胃我认为有很多情况下你使用 gem 调用。瘤胃有t-SNE但不是UMAP。

这一次,它是一个 C++ 库乌马普红宝石绑定我创造了它,所以我会在我忘记之前记录它。

让我们在没有 Ruby 库的情况下创建一个绑定

Ruby 语言在数据分析领域是一种相对次要的语言,因此通常没有库可以实现您想做的事情。在这种情况下,有一种方法可以找到 C 语言或 Rust 语言等库并创建 Ruby 绑定。 GitHub 搜索允许您按语言搜索代码。使用它来查找 C 语言库。 GitHub 允许你标记你的项目,所以检查目标标记也是有效的。但是,UMAP 似乎很难实现,我找不到实现UMAP 的C 语言库。相反,我找到了一个在 C++ 中实现 UMAP 的库。那是乌马普是。

Umappp - UMAP 的 C++ 实现

乌马普是由 Aaron Lun 实现的 C++ 库。 R的uwot它似乎是参考开发的虽然尚未测量,但可以预期高性能,因为它是用 C++ 实现并使用 OpenMP。

从 Ruby 语言调用 C++ 函数

使用 C++ 的扩展库在 R 语言中很常见,但使用 C++ 的扩展库在 Ruby 语言中的使用并不广泛。最近,Rust 开始流行起来,我偶尔会看到有人用 Rust 做 Ruby 扩展,但我没有看到很多新的 C++ 扩展库。

但是在 Ruby 中创建 C++ 绑定比您想象的要容易。我没有使用 C++ 的经验,但我能够从 Ruby 调用 C++。

在 C++ 中编写 Ruby 扩展有两种方法。一,另一个是扩展程序是。这次Numo::NArray和 C++numo.hpp我用大米是因为我想用。

我将 Umappp 和 Umappp 依赖的所有 C++ 文件放在 Vendor 目录中,并将其作为 Gem 分发,以便我可以在运行时编译 C++。我不知道怎么写extconf.rb,所以我根据其他项目进行了调整。

Rice - 用于 C++ 扩展的 Ruby 接口

是一个用 Ruby 编写 C++ 扩展的库,由 Paul Brannan、Charlie Savage 和 Jason Roelofs 开发。通过使用 Rice,您可以从 C++ 代码中定义 Ruby 模块和方法,如下所示。

#include <rice/rice.hpp>
#include <rice/stl.hpp>

using namespace Rice;

Hash umappp_default_parameters(Object self)
{
  Hash d;
//<中略>
  return d;
}

//<中略>

extern "C" void Init_umappp()
{
  Module rb_mUmappp =
      define_module("Umappp")
          .define_singleton_method("umappp_run", &umappp_run)
          .define_singleton_method("umappp_default_parameters", &umappp_default_parameters);
}

在 Ruby 中运行 UMAP

针对著名的 iris 数据集和 MNIST 数据库运行 UMAP。

鸢尾花数据集

该数据集测量三种鸢尾花的萼片长度和宽度以及花瓣长度和宽度。

RubyでUMAPをできるgemを作った話
图片来源:https://machinelearninghd.com/iris-dataset-uci-machine-learning-repository-project/

红宝石代码:

require "umappp"
require "datasets-numo-narray"
require "gr/plot"

iris = Datasets::LIBSVM.new("iris").to_narray
d = iris[true, 1..-1]
l = iris[true, 0]

r = Umappp.run(d)
x = r[true, 0]
y = r[true, 1]
s = [2000] * l.size

GR.scatter(
  x, y, s, l,
  title: "iris",
  colormap: 16,
  colorbar: true
)
gets

RubyでUMAPをできるgemを作った話

簇被清楚地分开。这里,标签 0 (setosa) 是浅蓝色,标签 1 (versicolor) 是淡紫色,标签 2 (virginica) 是洋红色。 setosa 组与其他组明显分开,但 versicolor 和 virginica 部分重叠。

(旁白)表格数据的GUI显示

在 Ruby 中,很难在 CUI 中查看大型表数据。在这样的时候红琥珀一个名为的数据框和一个用于其GUI显示的自制工具红琥珀观也可用于在 GUI 中显示表格数据。

# irisデータセットをテーブルとして表示する
iris = Datasets::LIBSVM.new("iris")
dataframe = RedAmber::DataFrame.new(iris).view
# 結果をテーブルとして表示する
RedAmber::DataFrame.new(x: x.to_a, y: y.to_a, l: l.to_a).view

*这是一个正在进行的工作,所以这只是一个你可以做这样的事情的故事。

RubyでUMAPをできるgemを作った話

MNIST 数据库

接下来,让我们降低 MNIST 的维度,这是一个手写数字的图像数据集。

RubyでUMAPをできるgemを作った話

红宝石代码:

require "umappp"
require "datasets"
require "gr/plot"
require "etc"

mnist = Datasets::MNIST.new

pixels = []
labels = []
mnist.each_with_index do |r, _i|
  pixels << r.pixels
  labels << r.label
end

puts "start umap"
nproc = Etc.nprocessors
n = nproc > 4 ? nproc - 1 : nproc
d = Umappp.run(pixels, num_threads: n, a: 1.8956, b: 0.8006)
puts "end umap"

x = d[true, 0]
y = d[true, 1]
s = [500] * x.size

GR.scatter(x, y, s, labels, colormap: 0)

gets

在安装了OpenMP的环境下,如果你用htop命令监控CPU使用率,你会发现中间有很多核被用于计算。簇被非常整齐地分开。

RubyでUMAPをできるgemを作った話

如果我们比较 GR.rb 颜色图中的标签,我们会得到:这是,官方 UMAP 结果几乎一样,可以看到UMAP可以正确执行。 5-3-8 和 4-9-7 似乎很相似。手写字符 4 和 9 之间的相似之处是直观的,实际上是最接近的。我有把 1 写成 7 的习惯,但似乎没有多少人这样做。

RubyでUMAPをできるgemを作った話

我将尝试 3D 显示。在这里,指定ndim: 3。 GR.rb有GIF动画输出功能,用起来吧。

require "umappp"
require "datasets" # red-datasets https://github.com/red-data-tools/red-datasets
require "gr/plot"  # GR.rb https://github.com/red-data-tools/GR.rb
require "etc"

mnist = Datasets::MNIST.new

pixels = []
labels = []
mnist.each_with_index do |r, _i|
  pixels << r.pixels
  labels << r.label
end

puts "start umap"
nproc = Etc.nprocessors
n = nproc > 4 ? nproc - 1 : nproc
d = Umappp.run(pixels, ndim: 3, num_threads: n, a: 1.8956, b: 0.8006)
puts "end umap"

x = d[true, 0]
y = d[true, 1]
z = d[true, 2]

GR.beginprint("mnist.gif")
30.times do |i|
  GR.scatter3(x, y, z, labels, title: "mnist", colormap: 0, backgroundcolor: 1, rotation: i * 3)
end
GR.endprint

RubyでUMAPをできるgemを作った話

不幸的是,GR.rb 只是按顺序调用polymarker3d,所以一些应该在后面的点在前面,而一些应该在前面的点在后面。但我认为气氛是传播的。有趣的是,保持了与 2D 的位置关系的一致性。

作为一个反思点,在使用 GR.rb 的可视化中,无法知道哪组颜色对应于哪个数字(无法显示颜色条之类的东西),所以我认为有必要改进这一点。。

写这篇文章的人数学不好,根本不了解UMAP的具体机制。所以我不能说UMAP有什么好处,但我觉得用UMAP检查你关心的数据如果它工作得这么快,会很方便。我的印象是结果出来的速度比 t-SNE 快得多。此外,我觉得 UMAP 结果的可重复性比我预期的要高。

综上所述

通过从 Ruby 调用 C++,可以从 Ruby 使用 UMAP。据我所知,这是第一个可以在 Ruby 中执行 UMAP 的库,包括绑定。这样一来,可以用 Ruby 完成的另一件事增加了。

[公关]
对于那些想要在 Ruby 中创建数据分析工具的人红色数据工具有一个社区叫基本上我是自己开发的,但是如果你在实现上有什么问题,或者你有想法想实现但是不知道怎么做,我们或许可以和你协商,所以请drop经过。

这就是本文的内容。


原创声明:本文系作者授权爱码网发表,未经许可,不得转载;

原文地址:https://www.likecs.com/show-308629283.html

查看更多关于【ruby专题】的文章

展开全文
相关推荐
反对 0
举报 0
评论 0
图文资讯
热门推荐
优选好物
更多热点专题
更多推荐文章
[ruby on rails] 跟我学之(6)显示指定数据
根据《[ruby on rails] 跟我学之路由映射》,我们知道,可以访问 GET    /posts/:id(.:format) 来显示具体的对象。 修改 app/controllers/posts_controller.rb的show这个action。这里有个难题,如果获取url里面的参数?可以通过params内置变量进行访问

0评论2023-03-16300

[ruby on rails] 跟我学之(10)数据输入验证
这里简单加上几个验证,非空,最小长度,唯一修改app/models/post.rb文件,如下:class PostActiveRecord::Base#attr_accessible :title, :contentvalidates :title, :context, :presence = truevalidates :title, :length = { :minimum =2}validates :title,

0评论2023-03-16870

[脚本_Ruby]Windows安装配置Ruby On Rails
感觉Java学的差不多了,想接触下Ruby On Rails,看看它比Java WEB高效到哪里了,在Ubuntu12.10上弄了两天总是报错提示没有指向的文件sqlite3,不管怎么安装sqlite3都不行,到最后没办法只有跑到WIN7平台下试试,以下就是我搭建Ruby On Rails的过程:    

0评论2023-02-10507

Prawn:Ruby生成PDF更简捷的选择
在InfoQ上看到《Prawn:使用Ruby生成PDF更简捷》,其说到的Prawn可以更加快捷的在Ruby中生成PDF文件。因为之前使用过很多版本的PDF生成类库都不尽如人意,有的太复杂,有的太慢,于是对这个做了测试。1、安装安装很简单,直接使用gem install prawn即可安装完

0评论2023-02-10471

Ruby On Rails:InstanRails
参考数据:对于Ruby On Rails 不是粉清楚的朋友可以参考以下的连结信息,该连结网站都提供不错的Ruby On Rails 信息。Ruby: 一个纯OO的脚本语言..Ruby on Rails: 快速建置Web的MVC架构的Framework说明:整合环境: Instant Rails 是在Windows环境中,整合了Ruby,

0评论2023-02-10701

进入Ruby on Rails世界
一、ruby和rails简介  ruby是一种面向对象的动态脚本语言。它的语法很灵活,而且提供了丰富的类库。因此,用ruby编写程序的效率是非常高的。  虽然ruby很早就出现了(1993年诞生于日本),但由于ruby一直缺乏英语文档,而且当时的ruby在web开发上并不怎么

0评论2023-02-10479

ruby : nil?, empty? and blank?的选择
article = nilarticle.nil?# = trueempty? checks if an element - like a string or an array f.e. - is empty:# Array[].empty? #= true# String"".empty? #= trueRails adds the method blank? to the Object class:An object is blank if it‘s false, em

0评论2023-02-09424

Ruby环境的安装(In Ubuntu 7.10)
今天开始学习Ruby。准备的图书呢,就是《Programming Ruby - 2nd》。为了准备一个实验的环境,于是要给我的Ubuntu上安装Ruby的环境。    1、安装解释器:sudo apt-get install ruby    2、安装一个即时执行工具irb:      由于第一部安装的结果只

0评论2023-02-09335

ruby使用IO类读写文件 ruby读取文件内容
path="test.txt"port=open(path)beginport.each_line{|line|p line.to_s}ensureport.closeendSTDOUT"i love you \n"port=open('test.txt')s=port.statp s.ftypep s.devp s.inop s.modep s.nlinkbegina=port.readlinesa=port.each{|e| p e}ensu

0评论2023-02-09410

Ruby1.9.2 开发环境安装备忘
在Windows下安装Ruby环境http://rubyinstaller.org/ 下载安装包和Devkit开发工具包Ruby的安装就不用说了。双击 Next.记得 Add to PATH Devkit 安装 把下载的压缩文件解压缩到如devkit文件夹中,例如:Ruby安装位置:D:\Ruby\Devkit安装位置:D:\Ruby\devkit 

0评论2023-02-09870

Python vs Ruby: 谁是最好的 web 开发语言?
Python 和 Ruby 都是目前用来开发 websites、web-based apps 和 web services 的流行编程语言之一。 这两种语言在许多方面有相似之处。它们都是高级的面向对象的编程语言,都是交互式脚本语言、都提供标准库且支持持久化。但是,Python 和 Ruby 的解决方法却

0评论2023-02-09819

Ruby require_gem
   gem 是ruby 的包管理系统,类似于ubuntu 的 apt-get.命令安装包:gem install your-package移除包:  gem uninstall your-package查询:     gem query –ln your-wanted (本地)             gem query –rn your-wanted (网上资源) 程序

0评论2023-02-09778

ruby 赋值语句解析
a = [1,2,3,4]-----------------------------------------------b,c = a      = b=1,c=2当右边只有一个数组,ruby自动将右边的数组拆分,然后赋值给左边的变量-----------------------------------------------b,*c = a    =b=1 ,c=[2,3,4]当左边变量

0评论2023-02-09341

Ruby on rails开发从头来(五十四)- ActiveRecord基础(指定关联关系)
Rails支持三种表间关联关系,一对一,一对多,多对多,你需要在Model中加入声明来标识这些关联:has_one,has_many,belongs_to,has_and_belongs_to_many。一对一关联关系可能存在于象订单和发票这样的关系,一个订单只能有一个发票,在Rails中,我们这样指

0评论2023-02-09873

Ruby的require
require一般用来加载其它的类,如: #Ruby代码  :require 'dbi'  require "rexml/document"但是上面加载的是标准类库里面的文件,当然也可以是已安装的gems文件,但是如果是自己在本地写的文件,就不能直接用require了,而应该这样:#E7.4-1.rb Modul

0评论2023-02-09601

更多推荐