Clojureと関数プログラミング

ウェブ技術 デジタルトランスフォーメーション技術 人工知能技術 機械学習 自然言語処理技術 推論技術 セマンティックウェブ技術 深層学習技術 強化学習技術 オンライン学習 チャットボットと質疑応答技術 ユーザーインターフェース技術 知識情報処理技術 プログラミング スパースモデリング 確率的生成モデル サポートベクトルマシン 本ブログのナビ

Clojureと関数プログラミングについて

Clojureは、Rich Hickeyにより作られ2007年に登場した比較的新しい言語である。新しいとは言っても、言語自体は1958年に登場したLISP言語の方言の一つであり、またJVMの上で動作してレガシーなプログラミング言語であるJAVAのコードをそのまま利用できるという古い顔と新しい顔を併せ持つ言語となっている。

Clojureの特徴の一つとして関数型言語であるというものがある。これはpythonやjavascript等の通常の言語が手続きを書き並べていく言語であるのに対して、関数という機能ブロックで全てのプログラムを構成するというプログラミング言語の歴史の中では最新のトレンドに部類されるものとなる。

プログラミング言語の開発の視点の一つに再利用性の向上がある。関数型言語の前に一世を風靡したオブジェクト指向型言語もそのような観点で開発されたものだが、関数というブロックで構成するというアイデアは更なる再利用性の向上を実現している。

また、REPLと呼ばれるコードを書きながらその都度関数を評価していくしくみは、作成時のバグを低減し、コード生成の効率化をもたらす。更に、LISPの持つ「データ=コード」という特徴は、プログラムの自動生成を含めた人工知能技術を実現する可能性を持つ。

本ブログでは以下に示すように、概要から環境の立ち上げ、言語の詳細とWebアプリケーション機械学習人工知能技術への応用について述べている。

概要

  • Code as Dataの概要とアルゴリズム及び実装例について

“Code as Data”は、プログラムのコード自体をデータとして扱う考え方やアプローチを指し、プログラムをデータ構造として操作し、分析、変換、処理することを可能にする方法となる。通常、プログラムはある入力を受け取り、それに対して特定の手順やアルゴリズムを実行し、結果を出力する。一方で、”Code as Data”では、プログラム自体がデータとして扱われ、他のプログラムによって操作される。これにより、プログラムをより柔軟に、動的に、抽象的に扱うことが可能となる。

技術トピック

プログラミングを行うためには、それぞれの言語に合わせた開発環境を作る必要がある。ここでは、本ブログに述べているPython、Clojure、C、Java、R、LISP、Prolog、Javascript、PHPそれぞのケースでの具体的な開発環境の立ち上げについて述べている。個々の言語では、開発を容易にするためのプラットフォームが準備されており、それらを用いると容易な環境設定が可能となるが、ここでは最もシンプルなケースでのものを中心に述べている。

ClojureでのSublimetext4とVS codeをそれぞれ使った開発環境の立ち上げについて述べる。

まずBootとはとして、Bootのgit pageより「Bootは、ClojureビルドフレームワークとアドホックClojureスクリプト評価器です。Bootは、プロジェクトのコンテキストで実行されるClojureで書かれたスクリプトからClojureプロジェクトを構築するために必要なすべてのツールを含む実行時環境を提供します」

Leiningenも開発ツールとしては優れたものだが、特にwebページシステム開発のような複雑なアプリケーションでは設定が複雑になり例えばLeningenのprojectファイルが非常に冗長なものとなる。これに対して、Bootでは、”build.bootというファイルを作成し、使用するライブラリやタスクを書く、Ruby の Gemfile や NodeJS の package.json のような役割をするファイルとなる。

Clojureを始めるための環境設定(JVM、テキストエディタ(Spacemacs)、コンパイラ/ラリブラリ管理ツール(leiningen))について述べる。

replの利用と最初のシンプルな関数プログラミング

各種データ構造とEDNについて

プログラミングを行う際にファイルの入出力機能は最も基本的で必須なものとなる。またファイルの入出力機能は、手続き的な命令となるため、各言語ごとに実現の仕方も異なってくる。以下に様々な言語でのファイル入出力の具体的な実装について述べる。

プログラミング言語の中でも基本機能は、”プログラミング言語の歴史“でも述べた「構造化言語」の3つの機能である(1)順次進行、(2)条件分岐、(3)繰り返しの中の一つの要素となる。ここではこの内繰り返しと分岐に対して様々な言語での実装を示す。

型システムの観点で見ると、Clojureは、静的な型システムと動的な型システムの両方を備えたLisp系のプログラミング言語であるということが言える。これはベースとなるJavaが持つ静的型付け言語という特性と、LISP言語体系が持つ動的な型システムでの、型宣言を行わない柔軟なコーディングに対応しているという特性を兼ね備えていることから、コードの信頼性を高め、同時にコードの柔軟性を維持することができるものとなっている。

Clojure specは、Clojureに含まれるライブラリの一つで、関数の引数や戻り値、データ構造などの様々な要素に対して、仕様を定義することができ、更にデータの検証と変換も行うことができるツールとなる。

写経の際に役に立つライブラリの自動管理システムancient

map関数を使った全文検索ライクなデータ抽出

プログラムの基本構文となる条件分岐としての関数型言語的アプローチであるcondp、matchについて

JavascriptとClojureでの非同期処理の実際

非同期処理のベースとなるClojureを用いた関数型言語ての状態管理について

Clojureを使った関数型言語でのオブジェクト指向型アプローチ

ポリモーフィズムとはプログラミング言語の型システムを表す言葉で、プログラミング言語の各要素(定数変数オブジェクト関数メソッドなど)についてそれらが複数の型に属することを許すという性質を指す。ポリモルフィズム、多態性、多相性、多様性とも呼ばれる。対義語はモノモーフィズム (Monomorphism)で、単態性、単相性で、プログラミング言語の各要素が唯一つの型に属するという性質を指す。

今回はClojureを使った関数型言語でのポリモーフィズムとモノモーフィズムについて述べる。

clojureでのオブジェクトのハンドリング関数としてのdeftypeとdefrecordについて

Clojureを使ったmutableなデータハンドリングとしてのロカール変数のdestructuringによる扱い

C、Java、Javascript、Python、Clojureでの繰り返し処理の比較

各種データソートアルゴリズムとClojure

いくつかのビジネスアプリケーションは、ネットワークトラフィックのような外部刺激に非同期で反応する必要になる場合がある。例えば、IOTアプリケーションのようなstreaming dataを受け取って処理するものや株式市場における企業の株価や情報をを追跡するためのアプリケーションなどとなる。

通常のコンピューターのシーケンシャル/同期的な処理でこれらを実行しようとすると、入力するデータの量が増えてきた場合、非同期なデータ間の同期をとるオーバーヘッドがボトルネックとなり実効的な速度でのアプリケーション困難になる。

今回はサーバーサイドのバックエンド処理の言語で非同期処理を行い、それらを実際のアプリケーションを想定した実装として組み上げる

お手軽にデスクトップアプリとしてUIを作成場合に利用できるClojureのライブラリーとしてseesawがある。これはJavaのグラフィカルライブラリであるSwingをClojureで利用できるようにしたものとなる。

Clojure Quilは、Clojureプログラミング言語で書かれた2Dグラフィックスおよびアニメーションを作成するためのライブラリとなる。Quilは、ProcessingというJavaベースの2DグラフィックスライブラリのClojureラッパーで、Quilを使用すると、Clojureで記述されたプログラムを使用して、2Dグラフィックスおよびアニメーションを作成することができる。

Clojureのカンファレンスの一つであるClojure/Conj2018にてCODE GOES IN, ART COMES OUT“というジェネレーティブアートに関する講演を見た。

ジェネレーティブアートとはwikiによると

「コンピュータソフトウェアのアルゴリズムや数学的/機械的/無作為的自律過程によってアルゴリズム的に生成・合成・構築される芸術作品を指す。コンピュータの計算の自由度と計算速度を活かし、自然科学で得られた理論を実行することで、人工と自然の中間のような、統一感を持った有機的な表現を行わせる作品が多い。

ジェネレーティブアートは、創作方法として自然科学的なシステムを主体として用いた芸術である。前提として、自律的に動作する機構を設計して作品制作を行わなければならない点が、他の芸術分野との違いであると言える。システムによる作品は、複雑系や情報理論といった科学理論を実行することがある。

数学はこの世界にある法則やパータンを抽象化して形にするものだと思っている。機械学習や人工知能の中で数学が重要な位置を占めるのも、コンピューターの計算するという機能に即しているというだけでなく、この法則やパターンの抽象化という機能が大きく寄与しているものだと思う。さらに数学は、様々な視点や発想を工夫してそれらパターンや法則を見つけるという”自由な発想”や”感じる力”が必要とされる分野でもある。このような観点で見ると、様々な直感や発想で人の心を揺さぶるパターンを作り上げる”音楽”も、数学と共通していると考えることができる。

ブルースは、現代のポピュラーミュージックのルーツの一つであり、重要な役割を果たすジャンルの一つとなる。ここではブルースの歴史とClojureによる自動生成について述べている。

一般的に、IoTデバイスはセンサーやアクチュエータを備えた小型のデバイスであり、ワイヤレス通信を使用してセンサーデータを収集し、アクチュエータを制御する形態となる。ワイヤレスでのIoT制御にはさまざまな通信プロトコルや技術が使用される。ここでは、このワイヤレス技術を用いたIoTを様々な言語で実装した例について述べている。

他言語との連携

Clojureは、ベースとなっているLISPの持つマクロシステムのような強力なDSL(domain-specific language:ドメイン固有言語)機能を継承し、様々な言語との連携が可能となっている。これらにより、機械学習に強いPyhtonでの学習ライブラリと、統計処理に強いRのライブラリ、推論技術の為の言語であるProlog等を融合したAIソリューションを組むことが可能となり、さらにwebアプリケーションのデファクトであるJavascriptや、基幹システムの構築に多く用いられているJavaやPHP等のライブラリと組み合わせてシステムを構築できる利点がある。

以下のそれぞれの言語との連携の詳細について述べる。

機械学習の領域では、PythonRのような豊富なライブラリーを持つ環境が利用されててほぼデファクトとなっているが、これに対して初期(2007年〜2017年頃)のClojureでは、CやPython、R等と繋げるしくみも開発されていたが、相手先のライブラリを自由に扱えるレベルではなく、最新のアルゴリズムを駆使することにハードルがあった。

これに対して近年(2018年〜)、libPython-cljのようなPython環境と相互に運用可能なフレームワークが現れたり、またJavaやCのライブラリを活用した数学的フレームワークfastmathや、深層学習のフレームワークCortexDeep Diamond等が開発されたりすることで、機械学習へのアプローチが積極的に検討され、Clojureの機械学習のコミュニティとして有名なscicloj.ml等で活発に議論されるようになった。

近年システム構築する際にwebフレームワークは重要な位置を占めている。このwebフレームワークのフロントエンドの開発に用いられる言語としては、Javascript(あるいはそれらの派生言語であるAltJavascript)とそれらを使ったフレームワーク(React、View等)がデファクトとなっている。

Clojureには、それらJavascript/フレームワークとClojureの連携のフレームワーク(Clojurescript)が開発されており、今回はそれらについて述べたいと思う。さらに近年高速なJVMであるGraalVMを介してJavaとJavascriptの相互運用が可能となっており、それを介してClojureとJavascriptの連携も可能との記事もあるが今回は割愛する。

今回はRとの連携について述べる。ClojureからRのライブラリへアクセスするツールは複数あり、以下のリンクにまとめられている。それぞれのツールの観点としては(a)提供されるAPIと構文解析、(b)使用されるRバックエンドの種類(JRI+REngine / Rserve+REngine / Opencpu / シェルからRを実行等)、(c) Rの「データフレーム」や「行列」と同等のものとしてClojureの概念が使われているか、もしそうなら、どのような概念なのか、がある。

これらの中で比較的安定して利用できるClojisrについて述べる。

ClojureはJVMの上で動くLispであり、様々なレベルでJavaと連携することができ、Javaの資産をフルで活用することができる。

Prologは、Lispと並ぶシンボリック人工知能プログラミング用の2つの古典言語の1つとなる。言語の特徴としては宣言型言語であることで、この「宣言型プログラミング言語」とは、対象の定義 =「何(What)を得たいか」を宣言してプログラムを構成し、逆に一般的な手続き型言語が持つ、それを得る過程・手続き・アルゴリズム =「どうやって(How)得るか」を記述しない[1][2]ものとなる。ClojureでのProlog機能の実現は論理プログラミング言語であるminiKanrenをベースとしたClojureでの論理プログラミング関数であるcore.logicを用いて実現される。

Webアプリケーション

データベース技術とは、データを効率的に管理・保存・取得・処理するための技術のことを指し、情報システムやアプリケーションにおけるデータの永続化や操作を支援し、データの正確性、一貫性、可用性、安全性を確保することを目的としたものとなる。

以下にこれらのデータベースを実際に扱うための各種言語による実装について述べる。

ここでは”サーバー技術“で述べているサーバーを各種プログラミング言語で活用する事例について述べる。ここでのサーバー技術とは、ネットワーク上でクライアントからのリクエストを受け取り、要求された処理を実行してレスポンスを返すサーバーシステムの設計・構築・運用などに関する技術のことを指す。

サーバー技術は、WebアプリケーションやAPIサーバー、データベースサーバー、メールサーバーなど、さまざまなシステムやサービスで使用されており、プログラミング言語やフレームワークに応じて、サーバー技術の実装方法やベストプラクティスが異なる。

Webクローリングは、Web上の情報を自動的に収集する技術となる。ここでは、それらの概要と応用例およびPythonとClojureを用いた具体的な実装について述べる。

ClojureでのRingを用いたサーバーの立ち上げについて

前回に立ち上げたClojureでのサーバーにcompojureを用いたルーティングを導入

ウェブアプリケーションを構築するためにClojureでpostgresqlを立ち上げる

Clojureでサーバーとデータベースを統合する

ClojureでSQLやSPARQL等のクエリを自動で生成する際に利用するformat関数について

Clojureで高速kvDBであるRedisを利用する実装について

PlantUML は、オープンソースの様々なデータモデルを自動で描画可能なツールとなり、AT&T研究所が提供しているオープンソースの描画ツールであるgraphvizをベースとしている。以下に示すような様々なダイアグラムを素早く作成するためのコンポーネントとなる。

plantUMLの利用の仕方には様々な方法がある。(1)Jarファイルの利用、(2)Macでのbrewの利用、(3)Webサービス、(4)アプリケーションに仕込む方法

      マイクロサービス

      ここでは、一般的なパターンとプラクティスを学び、プログラミング言語Clojureを使用して適用する方法を紹介する。アーキテクチャ設計とRESTful通信の基本的な概念を学び、開発時および運用時のスケールに対応した管理可能なコードを提供するパターンを紹介する。また、これらの概念とパターンをClojureでどのように実践するかについても例示している。

      PedestalはAPIファーストのClojureフレームワークで、動的な性質を持つ信頼性の高い並行サービスを構築するためのライブラリ群を提供するデータ駆動型の拡張可能なフレームワークであり、コンポーネント間の結合を減らすためにプロトコルを使って実装されている。

      今回は、マイクロサービスに用いられるデータベースである次世代データベースDatomicについて述べる。Datomicはマイクロサーピスのようなデータ指向アプリケーション(データ指向アプリケーションとは、データの量や複雑さ、変化が課題となるアプリケーション)向けのデータを確実に保存し、取得する為の、基盤となるデータベースとなる。DatomicはClojureで書かれたライブラリであり、AWSで提供されているクラウドサービスでもある。

      「Microservice with Clojure」より。今回はマイクロサービスシステム運用監視の為のElasticStashの活用について述べる。ここで述べた監視システムはマイクロサービスシステム以外にも広く適用可能となる。ElasticStashを用いた検索エンジンへの活用は”検索ツールElasticsearch -立ち上げ手順“等に詳細述べているのでそちらも参照のこと。

      機械学習/自然言語処理

      勾配法は機械学習や最適化アルゴリズムで広く使用される手法の一つであり、そのの主な目的は、関数の最小値(または最大値)を見つけるために、反復的にパラメータを更新していくことになる。機械学習では、通常、コスト関数(損失関数とも呼ばれる)を最小化することが目標で、例えば、回帰や分類問題において、予測値と実際の値の誤差を表すコスト関数が定義され、このコスト関数が最小となるパラメータの値を見つけるのに役立つ。

      ここでは、この勾配法に関して様々なアルゴリズムと各種言語による実装例について述べている。

      LightGBMは、Microsoftが開発したGradient Boosting Machine(GBM)のフレームワークであり、大規模なデータセットに対して高速かつ高精度なモデルを構築できるように設計されている機械学習のツールとなる。ここではpyhton、R、Clojureでの実装について述べる。

      一般化線形モデル(Generalized Linear Model, GLM)は、統計モデリングや機械学習の手法の一つであり、応答変数(目的変数)と説明変数(特徴量)の間の関係を確率的にモデリングするために使用されるものとなる。ここでは、この一般化線型モデルの概要と各種言語(python、R、Clojure)による実装について述べる。

      粒子群最適化(Particle Swarm Optimization、PSO)は、鳥や魚の群れの行動をモデル化し、自然界の群れの動きに着想を得たもので、進化計算アルゴリズムの一種であり、複数の個体が群れを形成し、最適解を探索する手法となる。PSOは、局所解に陥りやすい遺伝的アルゴリズムよりも、より広範な探索空間を探索できることが特徴となる。また、他の進化計算アルゴリズムよりも計算時間が短く、高速に最適解を見つけることができることがある。PSOは、機械学習や最適化問題の解決に広く用いられており、多数の研究や実用例が報告されている。

          一般的な統計解析では、標本を要約統計量という観点からどのように記述するか、また、そこからどのように母集団のパラメータを推測できるかについて考える。このような分析は、一般的な母集団と特に標本について何かを教えてくれるが、個々の要素について非常に正確な記述をすることはできない。これは、データを平均と標準偏差という2つの統計量に還元することで、多くの情報が失われてしまうからである。

          さらに踏み込んで、2つ以上の変数間の関係を確立したり、ある変数から別の変数を予測したりしたいこともよくある。そこでは、相関と回帰の研究を行うことになる。相関は、2つ以上の変数間の関係の強さと方向性に関係する。回帰は、この関係の性質を決定し、そこから予測を行うことができる。

          線形回帰は、初歩的な機械学習アルゴリズムとなる。データのサンプルが与えられると、モデルは線形方程式を学習し、新しい未知のデータについて予測を行うことができるようになる。そのために、Clojureの統計ライブラリであるIncanterを用いて、オリンピック選手の身長と体重の関係を、Incanter を使ってどのように行列を操作できるかについて述べる。

          2つの変数に相関関係があることを知ることは有用だが、それだけでは、”Clojure/Incanterを用いた統計解析と相関評価“でも述べたデータを用いて、身長からオリンピック水泳選手の体重を予測することはできないし、その逆もまた然りとなる。相関関係の確立では関係の強さと符号を測定したが、傾きは測定していない。予測を行うためには、一方の変数が1単位変化したときに、もう一方の変数がどの程度の変化率になるかを知ることが必要となる。
          そこで必要となるのが、独立変数と呼ばれる一方の変数の具体的な値と、従属変数と呼ばれるもう一方の変数の期待値を関連付ける方程式となる。例えば、身長から体重を予測する一次方程式であれば、身長が独立変数、体重が従属変数になる。

          この方程式で表される直線を回帰直線という。この言葉は、19世紀の英国の博学者フランシス・ガルトン卿によって紹介されたもので、19世紀、彼は弟子のカール・ピアソン(相関係数を定義)と共に直線関係を研究する様々な方法を開発し、これらを総称して回帰手法と呼ぶようになった。

          前回”Clojureを用いた回帰分析(1) 単回帰モデル”では、1つの独立変数で回帰直線を構築する方法について述べた。しかし現実の問題を考える際に、複数の独立変数でモデルを構築することが望ましい場合も多い。この問題は重回帰問題と呼ばれる。各独立変数には、それ自身の係数が必要になる。そこでそれぞれの係数をアルファベットで表すよりも、新しい変数β(「ベータ」と発音)を指定して、すべての係数を保持することにする。

          今回は、より大量のデータに適した方法で、回帰や分類のの分析を適用していくことについて述べる。今回扱うのは、10万レコードという比較的控えめなデータセットとなる。これはビッグデータではないが(100MBで、1台のマシンのメモリに快適に収まる)、大規模データ処理の一般的な手法を示すには十分な大きさとなる。この章では、Hadoop(分散計算のための一般的なフレームワーク)をケーススタディとして、並列処理によってアルゴリズムを非常に大きなデータ量に拡張する方法に焦点を当て述べる。

          Hadoopの特徴は、HDFS(Hadoop Distributed File System)と呼ばれる分散ファイル制御モジュールとMapReduceと呼ばれる分散データ処理基盤を特徴として持つ。ここではClojureが提供するHadoopと連携する2つのライブラリ、TesserとParkourを取り上げ、MapReduceの仕組みについて具体的な実装を元に述べる

          バッチ型勾配降下の各反復処理にかかる時間の長さは、データのサイズとコンピュータのプロセッサの数によって決まる。いくつかのデータの塊を並列に処理するとはいえ、データセットは大きく、プロセッサは有限である。計算を並列に行うことで高速化を実現するが、データセットのサイズが2倍になれば、実行時間も2倍になる。

          Hadoopは、1台のマシンの能力を超える作業を並列化することを目的とした、過去10年間に登場したいくつかのシステムのうちの1つとなる。Hadoopは、複数のプロセッサでコードを実行するのではなく、多くのサーバーで計算を実行することを目的としている。実際、Hadoopのクラスターは何千台ものサーバーで構成されることもある。

          “Clojureを用いたシンプルな推薦アルゴリズムの実装(2)”で述べた全項目のペアワイズド・ディファレンスはコンパイルすることに時間のかかる作業となる。アイテムベースの推薦技術の利点のひとつは、項目間の一対の差分が時間の経過とともに比較的安定することである。差分行列は定期的に計算されればよい。これは、これまで見てきたように10個のアイテムを評価したユーザが、さらに1個のアイテムを評価した場合、そのユーザが評価した11個のアイテムの差分を調整するだけでよいこととなる。
          しかし、アイテムベースレコメンダーの実行時間は、保存するアイテムの数によって変化し、アイテム数に比例して実行時間が長くなる。
          ユーザ数がアイテム数に比べて少ない場合、ユーザベースのレコメンダーを実装する方が効率的な場合がある。例えば、コンテンツアグリゲーションサイトでは、アイテム数がユーザー数を桁違いに上回る可能性があり、ユーザーベース・レコメンダーの良い候補になる。
          ClojureとMahoutを用いたラージスケールのクラスタリング“で述べたMahoutライブラリには、ユーザーベースレコメンダーを含む様々なレコメンダーを作成するためのツールが含まれている。今回はこれらについて述べてみる。

          Sparkプロジェクトは、低レイテンシーでのジョブ実行を重視したクラスタコンピューティングのフレームワークで、2009年にUC BerkleyのAMP Labから生まれた比較的新しいプロジェクトとなる。SparkはHadoopと共存可能だが(Hadoop Distributed File System(HDFS)に格納されたファイルに接続するなど)、計算の多くをメモリ上に保持することでジョブ実行時間の大幅な高速化を目指している。

          今回はClojureライブラリであるSparklingを使ってSparkジョブを実行するために必要なキーコンセプトについて説明する。

          グラフを視覚的な意味ではなく、数学的な意味で扱った場合について考える。グラフとは、単に辺で結ばれた頂点の集合であり、この抽象化の単純さは、グラフがどこにでもあることを意味する。グラフは、ウェブのハイパーリンク構造、インターネットの物理構造、道路、通信、社会的ネットワークなど、さまざまな構造の有効なモデルとなる。

          これらのグラフデータの為のアルゴリズムに対して、以前”グラフデータの基本的アルゴリズム(DFS、BFS、ニ部グラフ判定、最短路問題、最小全域木)”や”高度なグラフアルゴリズム(強連結成分分解、DAG、2-SAT、LCA)”等でC++を使った実装について述べた。今回はClojure/loomを使った活用について述べる。

          GraphXは、Sparkと連携して動作するように設計された分散グラフ処理ライブラリとなる。 “Apache SparkとMLlibによる大規模な機械学習“で述べたしたMLlibライブラリのように、GraphXはSparkのRDDの上に構築された一連の抽象化機能を提供する。グラフの頂点と辺をRDDとして表現することで、GraphXは非常に大きなグラフをスケーラブルに処理することができる。

          グラフ並列システムは、表現できる計算の種類を制限し、グラフを分割・分散する技術を導入することで、高度なグラフアルゴリズムを一般的なデータ並列システムより数桁速く効率的に実行することが可能となる。

          Pregel APIは、カスタムで反復的なグラフ並列計算を表現するための、GraphXの主要な抽象化機能となる。この名前は、Googleが2010年に発表した大規模グラフ処理を実行するための社内システムにちなんで付けられた。また、”Clojureを用いたネットワーク解析(1) 幅優先/深さ優先探索・最短経路探索・最小スパニング木・サブグラフと連結成分“でも述べたグラフのオイラー路(グラフの全ての辺を通る路)の問題で有名なケーニヒスベルクの橋がかかっている川の名前でもある。

          GoogleのPregel論文は、グラフ並列計算に対する「頂点のように考える」アプローチを普及させたものとなる。Pregelのモデルは、基本的に、スーパーステップと呼ばれる一連のステップに編成されたグラフの頂点間のメッセージパッシングを使用する。各スーパーステップの最初に、Pregelは各頂点上でユーザー指定の関数を実行し、前のスーパーステップでその頂点に送られたすべてのメッセージを受け渡す。頂点関数は、これらのメッセージのそれぞれを処理し、他の頂点に順番にメッセージを送信する機会を持つ。また、頂点は計算を「停止させる投票」をすることができ、すべての頂点が停止に投票すると、計算が終了する。

          前回”Clojureを用いたGraphX Pregelでのネットワーク解析“で分析したコミュニティのうち、何が最も大きなコミュニティを結びつけているのかを明らかにすることができるかどうかについて述べる。そのためには、さまざまな方法が考えられる。ツイートそのものにアクセスできれば、クラスタリングで行うようなテキスト分析を行って、これらのグループの間で特定の単語や特定の言語がより頻繁に使用されているかどうかを確認することもできる。

          ここでは、ネットワーク分析について述べる。そこでは、グラフの構造を使って、各コミュニティで最も影響力のあるアカウントを特定する。これは例えば、最も影響力のあるアカウントのトップ10のリストは、そのフォロワーに何が共鳴しているかを示す指標になる。

          ゲーム理論とは、競争や協力など、相互に影響を与えあう複数の意思決定者(プレーヤー)が存在する場合に、彼らの戦略とその結果を数学的にモデル化することで、最適な戦略を決定するための理論となる。これは主に経済学や社会科学、政治学などの分野で用いられている。

          ゲーム理論のアルゴリズムとしては、ミニマックス法、モンテカルロ木探索、深層学習、強化学習等様々な手法が用いられている。ここでは、R、Python、Clojureでの実装例について述べる。

          Clojureを用いた自然言語処理ツール(OpemNLP、kuromoji、Juman、KNP)を用いた形態素解析等の処理の実際

          サポートベクトルマシンのライブラリであるliblinearのClojureラッパーを用いた文の分類について

          ClojureによるK-meansを用いた教師なし学習について

          自然言語処理や検索で用いるClojureによるtfidfの実装

          自然言語処理のクレンジングで用いるClojureでのstopword除去の実装

          自然言語処理での単語等の構造化に用いるone-hot-vectorとcategory vectorについて

          ガウス過程は関数形をランダムに出力する箱(確率過程)のようなものであり、例えばサイコロが1,2,3,4,5,6の自然数を生成する過程がサイコロのゆがみに依存するのと考えた場合、ガウス過程もパラメータ(この例ではサイコロの歪み具合)次第で関数の出現の様子(サイコロの目が出る確率を表した関数)が変化すると考える。

          ガウス過程回帰は、データ間の相関係数を用いて解析することから、カーネル法を用いたアルゴリズムが用いられたり、ベイズ解析的手法と組み合わせたMCMCを用いたアルゴリズム等が適用される。これらの解析に用いられるツールとして、MatlabやPython、R、Clojure等様々な言語でのオープンソースがある。今回はClojureでのアプローチについて述べる。

          ベイズ最適化(bayesian optimization)は、少数標本と最低限の過程に基づいて確率的な予測を行うことのできる、ガウス回帰過程の特徴をフル活用した応用技術となる。

          具体的な例としては、医療や化学/材料研究等の実験計画において、実験を行いながら逐次的に次に行うべき実験パラメータの最適な組み合わせを抽出したり、機械学習におけるハイパーパラメータの学習/評価のサイクルを回しながら逐次的に最適化を行ったり、製造業での部品のすり合わせによる機能の最適化に用いられたりと広範囲に利用できる技術となる。

          以前ベイズモデル等の確率的生成モデルで述べたStanやBUSGS等は、確率的プログラミング(Probabilistic Programming:PP)とも呼ばれる。PPは確率モデルを何らかの形で指定し、それらのモデルの推論が自動的に実行されるプログラミングパラダイムとなる。それらの目的は確率モデリングと汎用プログラミングを統合して、株価の予測、映画の推奨、コンピュータの診断、サイバー侵入の検出、画像検出など、さまざまな不確実な情報に対して、様々なAI技術と組み合わせたシステムを構築することにある。

          今回は、この確率的プログラミングへのClojureでのアプローチについて述べる。

          CRP (Chinese resturant process) は,ある特定のデータ生成過程を記述する確率過程である.数学的には,このデータ生成過程は,各ステップで,可能な整数の集合から新しい整数をサンプリングし,その特定の整数がこれまでにサンプリングされた回数に比例する確率で,これまで見たことのない新しい整数をサンプリングする一定の確率で,その整数をサンプリングするものとなる。

          今回はこのCRPのClojureの確率的プログラミングのフレームワークであるAnglicanを用いた実装と混合ガウスモデルとの組み合わせについて述べる。

          今回は時系列データについて説明する。時系列とは、ある量の定期的な観測値を、その測定時間に従って並べたデータ系列のこととなる。時系列の将来の値を予測するためには、将来の値がある程度、過去の値に基づいていることが必要となる。今回はClojureを用いたAR、MA、ARMAモデルの実装について述べる。

          今回は状態空間モデルの応用の一つであるカルマンフィルターのClojureでの実装について述べる。カルマンフィルターは離散的な誤差のある観測から、時々刻々と時間変化する量(例えばある物体の位置と速度)を推定するために用いられる無限インパルス応答フィルターであり、その使いやすさからレーダーやコンピュータービジョンなど幅広い工学分野で利用されている技術となる。具体的な利用例としては、機器内蔵の加速度計やGPSからの誤差のある情報を統合して、時々刻々変化する自動車の位置を推定したり、人工衛星やロケットの制御などにも用いられている。

          カルマンフィルターは以前述べた隠れマルコフモデル(hidden markov model)と類似した隠れ状態とそれらから生成される観測データを持つ状態空間モデルで、状態は連続であり、状態変数の変化はガウス分布に従う雑音を用いて統計的に記述されるものとなる。

            異常検知とは、システムを代表するいくつかの選択された特徴量について、与えられた値の集合が、通常観測される特徴量の値と予想外に異なっているかどうかを判断する機械学習手法となる。異常検知の応用例としては、製造業における構造的・操作的欠陥の検出、ネットワーク侵入検知システム、システム監視、医療診断などがある。異常検知は機械学習問題の応用形態で二値分類の拡張版となる。

            異常検知のアプローチとして、学習データから構築される確率分布モデルを用いて異常を検知することが考えられる。異常を検出するために使用できるもう一つの方法は、近接ベースのアプローチとなる。このアプローチでは、サンプルデータ中の残りの値に対する観測値のセットの近接性、つまり近さを決定するものとなる。

            また、与えられた観測値の集合が異常であるかどうかは、その周辺のデータの密度に基づいて判断することもできる。このアプローチは、密度ベースの異常検出アプローチと呼ばれる。与えられた入力値の集合は、与えられた値の周辺のデータが低い場合、異常として分類される。

            隠れマルコフモデルとは、確率モデルの一つであり、観測されない(隠れた)状態を持つマルコフ過程となる。状態が直接観測可能なマルコフ過程と異なり、観測されたデータの情報を使って、その裏側にある「隠れた」状態を推測するものとなる。今回はこれに対するビタビアルゴリズムと確率的生成モデルによるClojureでの実装について述べる。

            推薦システムは、あるアイテムに対するユーザーの好みや嗜好を予測しようとする情報システムとなる。推薦システムは、ユーザーに有用な情報を提供することを目的とした情報フィルタリングシステムでとなる。推薦システムは、ユーザーの行動履歴を利用したり、他のユーザーが気に入ったものを推薦したりする。この2つのアプローチが、推薦システムで用いられる2種類のアルゴリズム(コンテンツベースフィルタリングと協調フィルタリング)の基礎となっている。

            今回は、k-meansアルゴリズムを用いたテキスト文書のクラスタリングに用いられる、テキスト文書間の類似性の尺度を使った推薦システムについて述べる。それらの中では、類似性の概念を使って、ユーザーが好きそうなアイテムを提案する形となる。

            ここではまず基本的な推薦システムの種類を説明し、最も単純なものの一つをClojureで実装する。そして、次回でMahoutを使った、様々な種類の推薦を作成する方法について述べる。

            強化学習やオンライン学習等で小規模な深層学習をアルゴリズムの中に導入することを念頭に起き、(かつニューラルネットのアルゴリズムの原理的な理解を含めて)Clojureでのニューラルネットの実装について述べる。ベースの実装はqitaでの”Clojureで0からのニューラルネット構築と隠れ層の観察“を用いて加筆を加えたものとした。

            Hierarchical Temporal Memory (HTM) は、新皮質の構造的・アルゴリズム的性質 を捉えることを目指した機械学習技術となる。HTMは現在のスマートフォンの原型となるハンドヘルドコンピュータ(palm、Treo)を考案したジェフ・ホーキンスが唱えた「自己連想記憶」理論(考える脳、考えるコンピューター)をベースにしたニューラルネットライクなパターン認織アルゴリズムとなる。

            グラフを視覚的な意味ではなく、数学的な意味で扱った場合について考える。グラフとは、単に辺で結ばれた頂点の集合であり、この抽象化の単純さは、グラフがどこにでもあることを意味する。グラフは、ウェブのハイパーリンク構造、インターネットの物理構造、道路、通信、社会的ネットワークなど、さまざまな構造の有効なモデルとなる。

            これらのグラフデータの為のアルゴリズムに対して、以前”グラフデータの基本的アルゴリズム(DFS、BFS、ニ部グラフ判定、最短路問題、最小全域木)”や”高度なグラフアルゴリズム(強連結成分分解、DAG、2-SAT、LCA)”等でC++を使った実装について述べた。今回はClojure/loomを使った活用について述べる。

            ベイズ推定のような複雑な複率分布の積分計算を解析的に行うことは困難であり、マルコフ連鎖モンテカルロ(Markov Chain Monte Carlo;MCMC)法がよく用いられる。これは基本的な乱択アルゴリズムの一種で、最も単純なモンテカルロ法は、パラメータの候補として乱数を発生し、その乱数に対応する確率(積分)を計算するものだが、このような総当たり的な手法では、パラメータの数が増えると爆発的に計算量が増え効率的でないのに対して、完全にランダムではなく、ひとつ前の乱数を元に少しずつ確率の大きな値を探索(マルコフ確率場の探索)しつつ次の乱数次の乱数を発生するアルゴリズムとなる。

            以前、Rstanについては紹介したが、PythonでのMCMCの実装としてはPystan、PyMC3がある。また、Rstanは2020年から更新されておらず、StanチームもCmdStanを奨励しているらしいことから、今回はCmdStanのrのラッパーであるCmdStanrと同様にCmdStanのシンプルなラッパーであるclj-stanについて述べてみたいと思う。

            その他AI技術

            ケースベース推論は、過去の問題解決の経験や事例を参照し、類似の問題に対して適切な解決策を見つける手法となる。ここでは、このケース推論技術の概要と課題及び様々な実装について述べている。

            CLIPSにインスパイアーされて作られたClojureのライブラリとしてclara ruleやrete4framesがある。それぞれを用いた簡単なサンプルプログラムを示す。

            ClojureのエキスパートシステムであるClara Rulesの基本的な実装について

            ClojureのエキスパートシステムであるClara Rulesの応用実装について

            論理プログラミング言語であるminiKanrenをベースとしたClojureでの論理プログラミング関数であるcore.logicについて

            チャットボットフレームワークのClojureとJavascriptによる構築と各種AI機能の統合(自然言語処理、SVM、BERT、Transformer、ナレッジグラフ、データベース、エキスパートシステム)

            コメント

            1. […] 前回までで、Clojureを使うための環境を設定したので、今回はClojure自身の導入と設定まで述べてみたい。 […]

            2. […] 次回は具体的な言語の一例として、現在に蘇ったLISP言語であるClojureについて述べてみたい。 […]

            3. […] 前述の密結合する関数を疎結合にする手段として、Clojureの実現手段としてはSTM(software transaction Memory)を使う方法がある。たとえばatomを使うケースだと […]

            4. […] Racket, Clojure,Haskell, Python, JavaScript, Scala, Ruby, OCaml, and […]

            5. […] 2002年にマイクロソフト社が関数型言語F#を発表し、2003年にはオブジェクト指向機能と関数型を併せ持つScalaが登場した。この他にもJavaやJavascript等の既存の言語にも関数的な機能が盛り込まれ始めた。また、Clojureも2007年に登場し、2000年代は関数型言語が見直される時代となった。 […]

            6. […] Clojureを使った自然言語処理について述べてみたい。 […]

            7. […] これらをClojureで実装したものはHolger Schauer氏の以下のものがある。 […]

            8. […] 前回に続いて、Clojureでのexpert systemであるclara-ruluesについて。Claraでは、defqueryとquery関数を用いて外部への推論結果の外部への出力を行う。以下にサンプルを示す […]

            9. […] Clojureのプログラムの中で単純にソートをしたい場合は以下のような形で行える。 […]

            10. […] Clojureではシーケンスを続ける形の表現となり以下のようになる。 […]

            11. […] 以前紹介したClojureを使ったプログラミングを選択しているのは、LISPがこれらの数学的な理論の裏付けのある言語であるからと言う理由もある。人工知能のゴールの一つであるプログラムの自動生成を考える際に、「シンタックス」側のアプローチはLISPを使うことでの実現手段がイメージできるが、それに密接に関係する「セマンティクス」のアプローチは未だ十分にイメージできていない。今後もそれらに関しては考えていければと思う。 […]

            12. […] ClojureScriptは、プログラミング言語のClojureからJavaScriptに変換するコンパイラーで、Clojureの持つ動的型付けや汎用の関数型言語で、変更不可な(immutable)データ構造に対応する特徴を持つ。ClojureScriptはLisp系のプログラミング言語なので、コードはデータとして扱われ、マクロが使えるのでメタプログラミングが可能となる。ほかのLisp系言語とは違いClojureは変更不可の(immutable)データ構造に対応しており、副作用の管理がしやすくなっている。List特有の括弧の使い方をはじめ、他の言語に比べて取っ付きにくく見える構文だが、構文の簡潔さと抽象化能力により、高度な抽象化が必要な場面に強力なツールとなる。ClojureScriptはコードの最適化にGoogle Closureを使用しているため、既存のJavaScriptライブラリーと互換性がある。 […]

            13. […] 自然言語処理で不必要な単語を除くstopword除去のClojureでの実装について。 […]

            14. […] たとえばClojureではこれをcore.asyncというライブラリで実現する。これは並列処理がが得意なGo-langのコンセプトを用いたgoマクロによってgo-blockを作り、そのブロック内のみで非同期動作を実現するという形を取る。またブロック間でのデータをやり取りするデータとしてチャネル(channel)を使う。 […]

            15. […] AI、ML、DX等に活用可能な関数型プログラミングClojure | Deus Ex Machina より: 2021年9月24日 3:16 AM […]

            16. […] 前回は、Clojureの特徴であるREPLとimmutableなデータについて述べた。今回はデータ構造について述べる。 […]

            17. […] 自然言語処理の機械学習で利用される。one-hot-vectorとcategory vectorのClojureでの実装。(形態素解析やCSVの入出力以外は極力外部のライブラリを使わない形で実装。 […]

            18. […] Clojureを使う上で重要なデータのDestrucurtingについてまとめる。サンプルコードは「Destructuring in Clojure」を参照した。まずベクトルデータからのデータの分割は以下となる。 […]

            19. […] Clojureでのクラスのハンドリングの関数として、defrecordとdefTypeがある。deftypeに関してはmutableな変数を扱う使い方がある。以下にまとめる。まずはdefinterfaceを用いたパターン。 […]

            20. […] これを具体的にClojureのコードで見ていく。まずモノモーフィズムなコードとしては以下のようになる。 […]

            21. […] ClojurScriptを構成したり、Java等のOOPプラットフォームとの連携を考えたり、また前述のCralaでもClojureでのクラスの操作の理解が必要となる。 […]

            22. […] 先述のCLIPSにインスパイアーされて作られたClojureのライブラリとしてclara ruleやrete4fmanesやがある。まずclara ruleについて、サンプルコードは以下となる。 […]

            23. […] 国内外で出版されているClojureの参考図書についてまとめた。機械学習の参考図書に関しては別途まとめる。 […]

            24. […] Clojureでの機械学習の参考図書は以下のようになる。残念ながら日本語でのものは発行されていない。Clojure全般の参考図書に関しては別途述べる。 […]

            25. […] サーバーサイドでの動的処理を抽象化するのが、サーバーサイドフレームワークとなる。サーバーサイドでは、PHP/Ruby/Python/Perl/Clojureのようなスクリプト言語で、Webアプリケーションの処理に必要な、HTML生成のためのテンプレート機能、データベースアクセスをする機能、安全性を高めるための入力チェック機能等様々な機能が抽象化されて準備されている。このフレームワークを使うことでユーザーはWebアプリケーションの仕組みを知らなくても、これらの抽象化された機能を使うだけでWebアプリケーションを開発できるようになる。 […]

            26. […] スペクトラムクラスタリングの実行は上記をコード化するか、python(sklean)やR、Clojure等の様々なプラットフォーム上のライブラリを利用して行うものとなる。 […]

            27. […] 人工知能技術サマリー 機械学習技術サマリー トピックモデルサマリー オントロジー技術サマリー Clojureサマリー Pythonサマリー […]

            28. […] 初心者のための関数型プログラミングClojure、環境設定 | Deus Ex Machina より: 2021年7月15日 6:33 AM […]

            29. […] AI、ML、DX等に活用可能な関数型プログラミングClojure | Deus Ex Machina より: 2021年7月17日 6:34 AM […]

            30. […] AI、ML、DX等に活用可能な関数型プログラミングClojure | Deus Ex Machina より: 2021年7月15日 6:55 AM […]

            31. […] AI、ML、DX等に活用可能な関数型プログラミングClojure | Deus Ex Machina より: 2021年7月15日 6:56 AM […]

            32. […] Clojure.  人工知能   life […]

            33. […] <Clojureと関数型プログラミング> […]

            34. […] 関係データ学習 Clojure デジタルトランスフォーメーション技術 人工知能技術 […]

            35. […] 関係データ学習 Clojure デジタルトランスフォーメーション技術 人工知能技術 […]

            36. […] サポートベクトルマシン スパースモデリング 人工知能技術 Clojure デジタルトランスフォーメーション技術 一般的な機械学習とデータ分析 […]

            37. […] 関係データ学習 Clojure デジタルトランスフォーメーション技術 人工知能技術 […]

            38. […] Clojure デジタルトランスフォーメーション技術 人工知能技術 […]

            39. […] 人工知能技術 機械学習技術 デジタルトランスフォーメーション Clojure Python PHP Prolog Javascript JavaとScalaとKoltlin プログラミング技術概要 […]

            40. […] ICT技術 ストリームデータの処理と機械学習 ICTインフラ技術 Clojure Python […]

            41. […] Clojure デジタルトランスフォーメーション技術 人工知能技術 […]

            42. […] Clojure デジタルトランスフォーメーション技術 人工知能技術 […]

            43. […] Clojure デジタルトランスフォーメーション技術 人工知能技術 […]

            44. […] Clojure デジタルトランスフォーメーション技術 人工知能技術 […]

            45. […] 異常検知と変化検知技術 時系列データ解析 Python R言語  Java Clojure […]

            タイトルとURLをコピーしました