京橋のバイオインフォマティシャンの日常

南国のビーチパラソルの下で、Rプログラムを打ってる日常を求めて、、Daily Life of Bioinformatician in Kyobashi of Osaka

【R言語パッケージ作成のマスターガイド】GPT4にR言語のパッケージ開発の手順を聞いてみた件

はじめに

R言語は、データサイエンスと統計解析の世界で重宝される、強力なプログラミング言語及びその開発実行環境です。その魅力の1つは、ユーザー自身でパッケージを作成し、それをRコミュニティと共有できるという点にあります。パッケージとは、特定の問題解決のための関数やデータセット、ドキュメントを1つにまとめたもので、他のユーザーが同じ課題に遭遇した際に、そのパッケージを利用することで即座に解決策を見つけることができます。

R言語でのパッケージ開発と共有には、Rの歩みそのものであり、これまでにかなりの歴史と蓄積があります。

パッケージ作成の初心者にとっては、そのプロセスが難しそうに思えるかもしれませんが、R言語のパッケージ作成は、一連の明確な手順に従うことで進めることができます。また、Rパッケージ作成時の多くの面倒な作業は、GPT4を通じて実施あるいは一部を補完でき、パッケージ作成の障壁を著しく下げられます。

この記事では、chatGPT / GPT4モデル*1の指南に基づき、R言語のパッケージ作成の基本的な手順を初心者向けに解説します。また、パッケージ設計の際のベストプラクティスや、パッケージ開発を助けるツールについても紹介します。

Rのパッケージを作成し、それをCRAN(「シーラン」あるいは「クラン」と読む)や他のリポジトリに公開するための、全体の道筋が掴めることでしょう。パッケージ作成の経験は、あなたのR言語のスキルを次のレベルに引き上げるための大きな一歩となります。

それでは、R言語のパッケージ作成の旅を始めましょう!

初心者でも分かりやすいように、R言語のパッケージ開発の手順を聞いてみた

今回の実行環境では、GPT4を選択して、Show Me DiagramsWebPilot(使われなかった)、Wolfram(使われなかった)をプラグインとして設定しました。

まずは、Rパッケージ開発の手順と、開発をサポートするパッケージがあれば提案してもらうようにchatGPTに質問しました。

Rパッケージ開発について、パッケージのセットアップ、関数の追加、ドキュメンテーション作成、データの追加、テストの追加、パッケージのビルドとチェック、インストール、そしてCRANへの公開という手順となります。

また、これらのプロセスを支援、効率化するためのパッケージとして、devtools、roxygen2、testthat、usethisなどがあります。

さらに、個別の項目を尋ねれれば、詳しく答えてくれるけども、ここでは省略します。興味があればさらに問答してみてください。

パッケージの構築デザインを考える際の注意点は???

パッケージの構築デザインについての注意点について訊いてみました。

Rパッケージの作成では、はっきりとした目的を持つこと、シンプルで一貫性のある設計を心がけることが大切とのことです。

また、各関数の説明を書き、テストを行い、必要なパッケージを最小限にすることも重要です。バージョン管理を行い、Rのコミュニティと協力することで、使いやすく、保守しやすい、高品質なパッケージを作成できるとのことです。

CRANにパッケージを投稿・登録する際に、留意点は???

次に、CRANにパッケージを投稿・登録する際の注意点を訊いてみました。

RパッケージをCRANに投稿する際は、パッケージのチェック、適切なライセンスの選択、バージョン番号の更新、パッケージの詳細な説明の記述、CRANのポリシーの確認、そしてさまざまなプラットフォームとRのバージョンでのテストが必要です。

これらを適切に行うことで、パッケージの投稿と登録がスムーズに進みます。

CRAN以外にRパッケージを投稿できるリポジトリは???

続いて、CRAN以外のリポジトリについて追加で訊いてみた。

CRAN以外にも、Bioconductor、GitHub、R-Forge、R-universe、ROpenSciなど、さまざまなリポジトリに投稿できます。

これらは、それぞれ特定の分野に特化したパッケージを集めたり、パッケージの開発と共有を支援したりしています。ただし、各リポジトリは独自の投稿ガイドラインと要件を持っているため、パッケージを投稿する前にそれらを確認する必要があるとのことです。

BioconductorやROpenSciはコードレビューがかなり厳しくしっかりしていて、それらにパッケージが通れば、一流のRパッケージ開発者です。

中級者から上級者になるには???

そして、上級者レベルになるために、何が大事かも訊いてみました。

Rパッケージ開発で上級者になるためには、コードの効率性を上げる、パッケージの拡張性を確保する、高度なテストを行う、パフォーマンスを最適化する、ユーザーインターフェースを改善する、そしてRのコミュニティと協力して、スキルを磨くことで、より高品質で使いやすいパッケージを開発することができるとのことです。

つまりは、Rパッケージ開発は、上級者になるパスの通過点ということです。

CRANのパッケージ開発の手順をstep by stepで図示してもらうと・・・

Show Me Diagramsプラグインを使って、ここまでの説明を図示してもらうことにしました。

やや冗長になってしまったので、パッケージ開発の全体ではなく、CRAN投稿前までのステップのみを詳しく図示してもらった。

Rパッケージを設計段階も含めて図示すると・・・

Rパッケージを設計段階も含めて、ステップを図示してもらった。

まとめ

Rパッケージ作成の基本的な手順について、GPTで得られた知見を解説しました。

これで、少しでも、パッケージ作成の一連の手順を理解いただけたのではないでしょうか。

さらに、詳しく知りたい場合には、補足のプロンプトを使って、GPT4と壁打ちしてみるのも良いと思います。

プロンプトのまとめ

今回使用した、プロンプトを以下の通り、まとめました。ご参考までに。

今回の実行環境では、GPT4を選択して、Show Me Diagramsをプラグインとして設定しました。

(プロンプト1)
CRAN用のR言語のパッケージ開発を予定しています。
初心者でもわかりやすいように、パッケージ開発の手順を示してください。
また、パッケージ開発をサポートするパッケージ群があれば提案してください。

(プロンプト2)
R言語のパッケージの構築デザインを考える際に注意点はありますか?

(プロンプト3)
CRANにパッケージを投稿・登録する際に、留意点はありますか?

(プロンプト4)
CRAN以外にRパッケージを投稿できるリポジトリはありますか?
ROpenSciはどうでしょうか?

(プロンプト5)
R言語のパッケージ開発についての基本的な手順を教えてもらいました。
中級者から上級者になるに従って、どの点をより改善させるべきでしょうか?

(プロンプト6)
以上をまとめて、CRANのパッケージ開発の手順をstep by stepで図示してください。

(プロンプト7)
パッケージ開発の全体ではなく、CRAN投稿前までのステップを詳しく図示してください。図には適切な言語を選択してください。

(プロンプト8)
R言語のパッケージを設計段階も含めて、ステップを図示してください。

*1:GPT4とプラグインを使用するには、OpenAIのサブスク(月20ドルかかります)に加入する必要があります。

LLMを使って、R関数の実行プロセスをダイアグラムで可視化してみた件

はじめに

2023年3月、OpenAI社が公開したGPT4のLLM(Large Language Models、大規模言語モデル)モデルの登場以降、プログラミングの世界はこれまでにないスピードで進化し、劇的な変化を遂げています。現世の私たちは、日々のニュースに感嘆し、新たなインスピレーションを受けています。まるで、スーパーマリオがスター状態になっているかのように、走馬灯が現実となり、日々が新たな発見で満たされています。これは、過去10年間で飛躍的に進化を続けてきた、データサイエンス、深層学習・AIのムーブメントが一旦の終着点を迎えたようにも感じます。

前置きはさておき、これは始まりに過ぎず、GPT4モデル、およびそのプラグイン機能の利用によって、コーディングや実行関数の作成だけに留まらず、コード自体の分析や可視化も可能になってきています。

これらの技術は、開発者やユーザーがコードやその動作を深く理解し、直感的かつ効率的に作業を進め、深い洞察を得る強力なツールとなるかもしれません。

この記事では、R言語の関数の実行プロセスや動作を可視化する方法について概説します。具体的には、自作関数であるchat4RというR関数の実行プロセスを対象にして、GPT4のプラグインの1つである、Show Me Diagramsを使用して、実行フローをダイアグラムで表現します。

また、GPT4とプラグインを使用するには、OpenAIのサブスク(月20ドルかかります)に加入する必要があります。

chat4R 関数の詳細とその可視化

chat4R関数は、OpenAI社が提供するGPT APIを使用して、テキストを生成するための自作関数です。この関数は、ユーザーからの入力(content)、APIキー(api_key)、モデル名(Model)などを引数として受け取ります。

以下に、この関数の定義を示します。

chat4R <- function(content,
            api_key = Sys.getenv("OPENAI_API_KEY"),
            Model = "gpt-3.5-turbo-16k",
            temperature = 1,
            simple=TRUE,
            fromJSON_parsed=FALSE) {

#パラメータを定義します
#詳細は以下のURLを参照してください: https://platform.openai.com/docs/guides/chat
api_url <- "https://api.openai.com/v1/chat/completions"
n <- 1
top_p <- 1

#APIリクエストのヘッダーを設定します
headers <- httr::add_headers(Content-Type = "application/json",
Authorization = paste("Bearer", api_key))

#APIリクエストのボディを定義します
body <- list(model = Model,
messages = list(list(role = "user", content = content)),
temperature = temperature, top_p = top_p, n = n)

#OpenAIサーバーにPOSTリクエストを送信します
response <- httr::POST(url = api_url,
body = jsonlite::toJSON(body, auto_unbox = TRUE),
encode = "json", config = headers)

#レスポンス内容を抽出し、返します
if(simple){
return(data.frame(httr::content(response, "parsed"))$choices.message.content)
}else{

if(fromJSON_parsed){
raw_content <- httr::content(response, "raw")
char_content <- rawToChar(raw_content)
parsed_data <- jsonlite::fromJSON(char_content)
return(parsed_data)
}else{
return(data.frame(httr::content(response, "parsed")))
}
}
}

R関数にroxygen2形式の説明を付与する

R関数の可読性を高めるために、引数の説明や実行内容のコメントを付与することが有効です。 GPT4モデルを活用してプロンプトを工夫すれば、roxygen2形式でのドキュメンテーションを関数に付与することが可能で、さらに関数内のコメントの翻訳もできます。

R関数の定義の際に、私はこの機能をよく使っています。GPT4モデルでは、その精度は驚くほど高いです。

例えば、以下のようなプロンプトでLLM実行します。

出力された、テキスト結果は以下の通りです。 今回使用したプロンプトの英文と和文は補足に記載しています。 ほぼ完璧な仕上がりです。

#' Generate text using OpenAI's API
#'
#' This function sends a request to OpenAI's API to generate text based on the provided content and parameters.
#'
#' @title chat4R
#' @description Generate text using OpenAI's API
#' @param content The initial text that the model responds to.
#' @param api_key The API key for OpenAI. Defaults to the value of the environment variable "OPENAI_API_KEY".
#' @param Model The ID of the model to use, such as "gpt-3.5-turbo-16k".
#' @param temperature Controls the randomness of the generated text. A value close to 0 produces more deterministic output, while a higher value (up to 2) produces more random output.
#' @param simple If TRUE, returns the generated text without newline characters. If FALSE, returns the full response from the API.
#' @param fromJSON_parsed If TRUE, parses the raw content of the response into a list. If FALSE, returns the parsed content of the response as a data frame.
#' @importFrom httr POST add_headers content
#' @importFrom jsonlite toJSON fromJSON
#' @return The generated text or the full response from the API, depending on the value of `simple` and `fromJSON_parsed`.
#' @export
#' @author Satoshi Kume
#' @examples
#' \dontrun{
#'   Sys.setenv(OPENAI_API_KEY = "Your API key")
#'
#'   content <- "Translate the following English text to French: '{}'"
#'
#'   chat4R(content, api_key)
#' }
chat4R <- function(content,
                   api_key = Sys.getenv("OPENAI_API_KEY"),
                   Model = "gpt-3.5-turbo-16k",
                   temperature = 1,
                   simple=TRUE,
                   fromJSON_parsed=FALSE) {

  # Define parameters
  # For more details, refer to: https://platform.openai.com/docs/guides/chat
  api_url <- "https://api.openai.com/v1/chat/completions"
  n <- 1
  top_p <- 1

  # Configure headers for the API request
  headers <- httr::add_headers(`Content-Type` = "application/json",
                      `Authorization` = paste("Bearer", api_key))

  # Define the body of the API request
  body <- list(model = Model,
               messages = list(list(role = "user", content = content)),
               temperature = temperature, top_p = top_p, n = n)

  # Send a POST request to the OpenAI server
  response <- httr::POST(url = api_url,
                         body = jsonlite::toJSON(body, auto_unbox = TRUE),
                         encode = "json", config = headers)

  # Extract and return the response content
  if(simple){
   return(data.frame(httr::content(response, "parsed"))$choices.message.content)
  }else{

  if(fromJSON_parsed){
  raw_content <- httr::content(response, "raw")
  char_content <- rawToChar(raw_content)
  parsed_data <- jsonlite::fromJSON(char_content)
  return(parsed_data)
  }else{
  return(data.frame(httr::content(response, "parsed")))
  }
  }
  }

R関数のダイアグラムを作成する

R関数の実行プロセスを可視化するために、GPT4のプラグインの1つである、Show Me Diagramsというツールを使用します。 このツールは、Mermaid、PlantUML、D2などの図表言語を使用して、チャット上でダイアグラムを作成することができます。

ChatGPTのプラグイン設定

ChatGPTは、プラグインを使用して機能を拡張することができます。

Show Me Diagramsというプラグインは、図表言語を使用してダイアグラムを作成できます。

今回は、R関数の実行プロセスを視覚的に表現するのに使用しますが、それだけの用途に止まりません。

使い方は、GPT4を選択して、Show Me Diagramsのプラグイン機能をONにするだけです。

chat4R関数の実行プロセスをMermaidで表現したダイアグラム

以下に、chat4R関数の実行プロセスをMermaidで表現したダイアグラムを示します。

今回、実行したプロンプトは以下の通りです。 ここで使用したプロンプトの英文と和文は補足に記載しています。

次が実行結果です。

また、「PlantUMLで作図して」といえば、結果が切り替わります。

このダイアグラムでは、chat4R関数がどのように動作するかを視覚的に表現しています。ユーザーが関数を呼び出すところから始まり、関数内でパラメータとヘッダーが定義され、APIにPOSTリクエストが送信され、最終的にレスポンスがユーザーに返されるまでの一連のプロセスが描かれています。

つまりは、R関数がどのように動作し、どのようにデータが処理されるのかを理解することができます。

まとめ

関数の実行プロセスを理解したり、他人に説明する際に、即座にそのプロセスを視覚的に表現できれば、非常に有用と思われます。

このツールを活用して、Rコーディングの効率と理解を向上させましょう。

補足: R関数の可視化で使用したプロンプト(命令分)

今回、R関数の可視化で使用した、プロンプト(命令分)を下記に記載します。

現状、英語文でプロンプトを与える方が、テキスト生成の速度、精度共に良いとされています。

プロンプトのあとに、実際のR関数をコピペして与えます。

今回の実行時には、chat4R関数のコードを与えています。

英語版プロンプト

Please use Show Me Diagrams to create a diagram that represents the execution process of R functions, and make sure that the prompt used in the diagram is well thought out. 
To create sequence diagrams, please use a diagramming language such as Mermaid or PlantUML. 
Your answer should be detailed and comprehensive.  
The R functions are as follows.

日本語版プロンプト

Show Me Diagramsを使用してR関数の実行プロセスを表す図を作成し、その中で使用するプロンプトをよく考えて作成してください。
シーケンス図を作成するには、Mermaid や PlantUML などの図解言語を使用してください。
回答は詳細かつ包括的でなければなりません。 R 関数は以下の通りです。

補足: R関数にroxygen2形式の説明を付与するプロンプト(命令分)

R関数の可読性を高めるために、roxygen2形式の説明を付与するのにしようした、プロンプト(命令分)を下記に記載します。

パッケージ開発を鑑みて、説明文は英語に訳すようにしています。

今回の実行時には、chat4R関数のコードを与えています。

英語版プロンプト1

function: roxygen2
author: Your name
Language: English

You are an experienced and knowledgeable R programmer who is being asked to provide a comprehensive definition of a specific R language function.
Your definition should be in the {function} format, and should include specific elements such as @title, @description, @param, @importFrom, @return, @export, @author {author}, and @examples.
It is important that you ensure that the function name you define is also defined in @export.
Additionally, you should translate any comments in the function (starting with #) into English, ensuring that the content of the comments is consistent and correct throughout the function.
If you notice any mistakes or areas for improvement in the R script, you should correct them according to these instructions.
If there is a risk of errors occurring during text generation, you should make any necessary modifications to prevent these errors.
Once you have completed the definition, please provide it as the final product.
Do not omit the output of the code.

英語版プロンプト2

function: roxygen2
author: Your name
Language: English

As an experienced and knowledgeable R programmer, you have been tasked with providing a comprehensive definition of a specific R language function.
Your definition should follow the {function} format and must include specific elements such as @title, @description, @param, @importFrom, @return, @export, @author {author}, and @examples.
It is crucial that you ensure that the function name you define is also defined in @export.
Moreover, you must translate any comments in the function (starting with #) into English, and ensure that the content of the comments is consistent and accurate throughout the function.
If you encounter any errors or areas for improvement in the R script, you must correct them following these instructions.
In case there is a risk of errors occurring during text generation, you should make the necessary modifications to prevent these errors.
Once you have completed the definition, please submit it as the final product.
Do not omit the output of the code.

日本語版プロンプト

関数: roxygen2
著者: 貴方の名前
説明で使用する言語: 英語

貴方は、熟練した気の利いたRプログラマーです。
以下のR言語の関数を{関数}形式で定義してください。
@title、@description、@param、@importFrom、@return、@export、@author {著者}、@examplesを定義してください。
定義した関数名を@exportに定義してください。
関数中のコメント部分(#以降)の日本語は英語にしてください。
英語でのコメントの内容は関数全体で齟齬がないように、最も適したコメントに修正してください。
Rスクリプトの間違い、および改善点を指摘し、それら指摘に従いスクリプトを修正してください。
また、テキスト生成時にエラーが起こりそうになった場合、エラーが起こらないように柔軟に出力を修正してください。
以上の結果を最終的な成果物として出力してください。出力は日本語で答えてください。

【2023年6月版】ChatGPTの現状理解と今月のLLM情報

BioPackathon 2023 #6: ChatGPTとLarge Language Models(LLM)の現状と最新情報

6月14日に、研究会でトークしたスライドです。

speakerdeck.com

はじめに

BioPackathon 2023 #6の概要です。ChatGPTとLLMの最新情報についての議論が行われました。その中で、iOS版ChatGPTアプリのリリース、ウェブ情報の取得とプラグイン、ChatGPTの限界、日本初のChatGPTプラグイン「食べログ」、プロンプトエンジニアリング、そしてMagic社の開発についてトークしました。

ChatGPTとは?

ChatGPTは、OpenAIが2022年11月に公開したAIチャットボットで、大量のテキストを学習したAIモデルです。現在の最新版はGPT-4です。LLMの登場によって、"自然言語"をプロンプト(指示文)としてAIに命令できるようになりました。

iOS版ChatGPTアプリのリリース

iOS版のChatGPTアプリがリリースされました。ただ、偽アプリが多数リリースされているため、必ずOpenAI公式からApp storeにアクセスすることが重要です。

ウェブ情報の取得とプラグイン

β版ですが、プラグイン機能が使えるようになりました。

ウェブ情報の取得については、全てのウェブ情報にアクセスできるわけではなく、アクセス可能なウェブサイトに制限があります。また、Webブラウジング機能は、プラグインの「WebPilot」についも言及しました。

現在、Plugin storeでは、400近くのプラグインが公開されています。プロンプトの自動修正・最適化ができる「Prompt Perfect」、数学や科学、作図などの様々なタスクを実行可能な「Wolfram」について紹介しました。

ChatGPTの限界

ChatGPTが苦手なこととして、モデルの学習データが2021年までであること、記事になっていない情報あるいはアクセスが難しい情報(会員サイト、地域ネタ、データベースなど)に弱いことが挙げられます。

日本初のChatGPTプラグイン: 食べログ

日本初のChatGPTプラグインとして「食べログ」プラグインがリリースされました。

自然言語(プロンプト)を入力すると、GPTでクエリを作成し、「食べログ」APIを介してDBを検索し、検索結果のメタデータを取得し、その情報をもとにGPTでさらに文書を生成しているようです。

プロンプトエンジニアリング

プロンプトエンジニアリングについても議論しました。

プロンプトエンジニアリングは、大規模言語モデルを効率的に使用するためのプロンプトを開発および最適化する新しい学問分野で、これが流行りそうであるとの議論をしました。

Magic社の開発

Magic社は、プログラミングに特化した、 LTM-1というLLMモデルを開発・リリースしたようです。