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

   2023-03-08 学习力0
核心提示:介绍统一流形逼近和投影 (UMAP) 是一种通过降维的可视化方法,通常与 t-SNE 一起使用。用 Ruby 语言执行机器学习时,瘤胃我认为有很多情况下你使用 gem 调用。瘤胃有t-SNE但不是UMAP。这一次,它是一个 C++ 库乌马普的红宝石绑定我创造了它,所以我会在我忘记

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

 
反对 0举报 0 评论 0
 

免责声明:本文仅代表作者个人观点,与乐学笔记(本网)无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
    本网站有部分内容均转载自其它媒体,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责,若因作品内容、知识产权、版权和其他问题,请及时提供相关证明等材料并与我们留言联系,本网站将在规定时间内给予删除等相关处理.

  • [ruby on rails] 跟我学之(6)显示指定数据
    根据《[ruby on rails] 跟我学之路由映射》,我们知道,可以访问 GET    /posts/:id(.:format) 来显示具体的对象。 修改 app/controllers/posts_controller.rb的show这个action。这里有个难题,如果获取url里面的参数?可以通过params内置变量进行访问
    03-16
  • [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,
    03-16
  • 我尝试使用 Ruby 和 mittsu 库制作 3D 战斗动作游戏
    我尝试使用 Ruby 和 mittsu 库制作 3D 战斗动作
    概述这篇文章是关于我偶然发现的 hitbox 的回忆录。2022 夏季鲁比训练营创造了这个游戏。我的游戏仓库这里是。我们作为一个团队开发,有 4 名成员第一次见面,并第一次使用 Git 和 Github 进行开发。使用的技术是Ruby,三通图书馆是。我主要负责碰撞检测,所
    03-16
  • 我只是想在我的 Mac 上将 Ruby 和 Rails 更新到终端中的最新版本。 .
    我只是想在我的 Mac 上将 Ruby 和 Rails 更新到
    介绍自从我尝试创建一个简单的应用程序以来已经有很长时间了,并且我尝试在创建它之前将 Ruby 和 Rails 更新到最新版本,但是我意外卡住了,所以我将它作为备忘录留下。作为版本升级1. 更新 Homebrew 和 rbenv2. 红宝石更新3. Rails 更新这就是它的感觉。让我
    03-16
  • ruby写爬虫 ruby python
    ruby写爬虫 ruby python
    http://www.javaeye.com/topic/545160爬虫性能比较http://www.rubyrailways.com/data-extraction-for-web-20-screen-scraping-in-rubyrails/srcapihttp://huacnlee.com/blog/ruby-scrapi-collect-koubei  2009年4月22日 星期三用ruby写的一个网络爬虫程序前
    03-08
  • 让我们制作一个应用程序,当您在表格①中输入名称时输出 PDF 戳记(使用 Ruby on Rails 创建 PDF 文件)
    让我们制作一个应用程序,当您在表格①中输入名
    介绍你好!我的名字是荣查本。这次在Ruby on Rails中实现PDF转换的时候,用到了一个叫Prawn的gem,所以总结了一下。您可以通过阅读本文创建フォームに名前を入力するとPDF化された印鑑を出力するアプリ。即使是我,一个初学者也可以做到,所以实现方法很简单
    03-08
  • [脚本_Ruby]Windows安装配置Ruby On Rails
    感觉Java学的差不多了,想接触下Ruby On Rails,看看它比Java WEB高效到哪里了,在Ubuntu12.10上弄了两天总是报错提示没有指向的文件sqlite3,不管怎么安装sqlite3都不行,到最后没办法只有跑到WIN7平台下试试,以下就是我搭建Ruby On Rails的过程:    
    02-10
  • Prawn:Ruby生成PDF更简捷的选择
    在InfoQ上看到《Prawn:使用Ruby生成PDF更简捷》,其说到的Prawn可以更加快捷的在Ruby中生成PDF文件。因为之前使用过很多版本的PDF生成类库都不尽如人意,有的太复杂,有的太慢,于是对这个做了测试。1、安装安装很简单,直接使用gem install prawn即可安装完
    02-10
  • Ruby On Rails:InstanRails
    参考数据:对于Ruby On Rails 不是粉清楚的朋友可以参考以下的连结信息,该连结网站都提供不错的Ruby On Rails 信息。Ruby: 一个纯OO的脚本语言..Ruby on Rails: 快速建置Web的MVC架构的Framework说明:整合环境: Instant Rails 是在Windows环境中,整合了Ruby,
    02-10
  • 进入Ruby on Rails世界
    一、ruby和rails简介  ruby是一种面向对象的动态脚本语言。它的语法很灵活,而且提供了丰富的类库。因此,用ruby编写程序的效率是非常高的。  虽然ruby很早就出现了(1993年诞生于日本),但由于ruby一直缺乏英语文档,而且当时的ruby在web开发上并不怎么
    02-10
点击排行