Upgrade to Pro — share decks privately, control downloads, hide ads and more …

『データ可視化学入門』をPythonからRに翻訳した話(増強版)

bob3bob3
February 24, 2024

 『データ可視化学入門』をPythonからRに翻訳した話(増強版)

「『データ可視化学入門』をPythonからRに翻訳した話(増強版)」です。

bob3bob3

February 24, 2024
Tweet

More Decks by bob3bob3

Other Decks in Programming

Transcript

  1. 『データ可視化学入門』 『指標・特徴量の設計から始めるデータ可視化学 入門 データを洞察につなげる技術』 
 • 2023年12月発売
 • 発売前から周囲での前評判が良かったので 買ってみた。
 •

    単なるハウツー本ではなくて、「分布をどう捉 えるか」「どう指標化するか。指標化で何が 失われるか」といった分析プロセスを踏まえ た視点で書かれているのが良い。 
 • 加えて、ほとんどの可視化例について Pythonのコードが公開されているので、すぐ に試せる。

  2. どうやって翻訳したか • 文明の利器 LLM を使わない手はない。
 • 今回は Copilot (旧Bing Chat)

    を使いました。中身はChatGPT4のはず。
 • PythonのコードをCopilotに与えて「R言語で書き直してください」とお願いするだけ。
 • そのまま使える完璧なコードが出てくることは多くないが、それでもかなりの工数を 削減できた。

  3. 翻訳例(1) Pythonの原文 import matplotlib.pyplot as plt # matplotlibのpyplotをpltとしてインポート import pandas

    as pd # pandasをpdとしてインポート import seaborn as sns # seabornをsnsとしてインポート import japanize_matplotlib # matplotlibで日本語を表示可能にする # データを辞書形式で提供 data = { 'year': list(range(1990, 2023)), # 年(1990年から2022年まで) 'population': [1.23611, 1.24101, 1.24567, 1.24938, 1.25265, 1.2557, 1.25859, 1.26157, 1.26472, 1.26667, 1.26926, 1.27316, 1.27486, 1.27694, 1.27787, 1.27768, 1.27901, 1.28033, 1.28084, 1.28032, 1.28057, 1.27834, 1.27593, 1.27414, 1.27237, 1.27095, 1.27042, 1.26919, 1.26749, 1.26555, 1.26146, 1.25502, 1.24947] # 人口(億人単位) } df = pd.DataFrame(data) # pandasデータフレームにデータを変換 plt.figure(figsize=(5, 3)) # グラフのサイズを指定 sns.lineplot(x='year', y='population', data=df, marker='o', linestyle='-') # 折れ線グラフの描画 plt.xlabel("西暦") # x軸のラベル plt.ylabel("日本の総人口 [億人]") # y軸のラベル plt.grid(True) # グリッドを表示 plt.tight_layout() # レイアウトの調整 plt.show() # グラフの表示
  4. 翻訳例(1) Copilot # 必要なパッケージのインポート library(ggplot2) library(gridExtra) # データの作成 year <-

    seq(1990, 2022) # 年(1990年から2022年まで) population <- c(1.23611, 1.24101, 1.24567, 1.24938, 1.25265, 1.2557, 1.25859, 1.26157, 1.26472, 1.26667, 1.26926, 1.27316, 1.27486, 1.27694, 1.27787, 1.27768, 1.27901, 1.28033, 1.28084, 1.28032, 1.28057, 1.27834, 1.27593, 1.27414, 1.27237, 1.27095, 1.27042, 1.26919, 1.26749, 1.26555, 1.26146, 1.25502, 1.24947) # 人口(億人単位) # データフレームに変換 df <- data.frame(year, population) # グラフの作成 p <- ggplot(df, aes(x=year, y=population)) + geom_line() + geom_point() + labs(x="西暦", y="日本の総人口 [億人]") + theme_bw() + theme(panel.grid.major = element_line(colour = "grey80")) # グラフの表示 print(p) 不要なgridExtraパッケージをなぜ か呼び出してる。 折れ線に色を付けて欲しかったけど、デ フォルトの色指定なので仕方ないのかな ……
  5. 翻訳例(2) Pythonの原文 import seaborn as sns # グラフ作成のためのSeaborn import matplotlib.pyplot

    as plt # グラフ描画のためのMatplotlib import japanize_matplotlib # Matplotlibで日本語を使用可能にする from scipy import stats # 統計解析のためSciPyを読み込み plt.rcParams["font.size"] = 16 # フォントサイズの設定 penguins = sns.load_dataset("penguins") # データセットの読み込み lm = sns.lmplot(x='bill_length_mm', y='body_mass_g', hue='species', data=penguins, scatter_kws={'alpha': 0.3}, legend=False) # 回帰直線を描画 plt.xlabel('くちばしの長さ [mm]') # x軸ラベル plt.ylabel('体重 [g]') # y軸ラベル plt.show() # グラフの表示
  6. 翻訳例(2) Copilot library(ggplot2) library(palmerpenguins) # データセットの読み込み data("penguins") # 回帰直線を描画 ggplot(penguins,

    aes(x = bill_length_mm, y = body_mass_g, color = species)) + geom_point(alpha = 0.3) + geom_smooth(method = "lm", se = FALSE) + labs(x = "くちばしの長さ [mm]", y = "体重 [g]") + theme(legend.position = "none") # 凡例を削除 信頼区間はTRUEであって欲しい
  7. 翻訳例(3) Pythonの原文 # ペンギンの種類ごとに回帰分析 from scipy import stats # 統計解析のためSciPyを読み込み

    penguins = sns.load_dataset("penguins") # データセットの読み込み for species in penguins.species.unique(): if species is not None: # Exclude NaN species_data = penguins[penguins.species == species].dropna() # NaNを除外 slope, intercept, r_value, p_value, std_err = stats.linregress( species_data['bill_length_mm'], species_data['body_mass_g'] ) # 線形回帰分析 # 相関係数とp値の出力 print(f"For {species}:\n r value is: {r_value}\n p_value is: {p_value}")
  8. 翻訳例(3) Copilot # 必要なパッケージのインストールと読み込み if (!require(palmerpenguins)) install.packages('palmerpenguins') library(palmerpenguins) if (!require(ggplot2))

    install.packages('ggplot2') library(ggplot2) # データセットの読み込み data("penguins", package = "palmerpenguins") # 種ごとに線形回帰分析を行う for (species in unique(penguins$species)) { species_data <- subset(penguins, species == species) species_data <- na.omit(species_data) # NaNを除外 # 線形回帰分析 fit <- lm(bill_length_mm ~ body_mass_g, data = species_data) # 相関係数とp値の出力 cat(paste("For", species, ":\n r value is:", summary(fit)$r.squared, "\n p_value is:", summary(fit)$coefficients[2,4], "\n")) } ggplot2は要らないのに… for文かぁ、原文がfor文だから仕方な いけど、Rらしくapply族かpurrr::map 族で書いて欲しいな。
  9. 翻訳例(3) Copilot 「apply族を使ってください」 # 必要なパッケージのインストールと読み込み if (!require(palmerpenguins)) install.packages('palmerpenguins') library(palmerpenguins) if

    (!require(ggplot2)) install.packages('ggplot2') library(ggplot2) # データセットの読み込み data("penguins", package = "palmerpenguins") # 種ごとにデータを分割 split_data <- split(penguins, penguins$species) # 各データフレームに対して線形回帰分析を適用 results <- lapply(split_data, function(df) { df <- na.omit(df) # NaNを除外 fit <- lm(bill_length_mm ~ body_mass_g, data = df) # 線形回帰分析 list(r_value = summary(fit)$r.squared, p_value = summary(fit)$coefficients[2,4]) }) # 結果の出力 for (species in names(results)) { cat(paste("For", species, ":\n r value is:", results[[species]]$r_value, "\n p_value is:", results[[species]]$p_value, "\n")) } 明示して依頼すれば apply族で書いて くれる。 ここはfor文が残ってる。
  10. 翻訳例(3) Copilot 「purrrパッケージのmap族を使ってください」 # 必要なパッケージのインストールと読み込み if (!require(palmerpenguins)) install.packages('palmerpenguins') library(palmerpenguins) if

    (!require(ggplot2)) install.packages('ggplot2') library(ggplot2) if (!require(purrr)) install.packages('purrr') library(purrr) # データセットの読み込み data("penguins", package = "palmerpenguins") # 種ごとにデータを分割 split_data <- split(penguins, penguins$species) # 各データフレームに対して線形回帰分析を適用 results <- map(split_data, function(df) { df <- na.omit(df) # NaNを除外 fit <- lm(bill_length_mm ~ body_mass_g, data = df) # 線形回帰分析 list(r_value = summary(fit)$r.squared, p_value = summary(fit)$coefficients[2,4]) }) # 結果の出力 map2(names(results), results, function(species, res) { cat(paste("For", species, ":\n r value is:", res$r_value, "\n p_value is:", res$p_value, "\n")) }) 明示して依頼すれば purrr::map族で書 いてくれる。 ここもmap族になってる。
  11. まとめ • 他言語からRへ翻訳するのにChatGPTはなかなか役に立つ。
 ◦ 下訳として使うことでだいぶ工数を減らせる。
 ◦ 時々、個性を出そうとしてくるのがむしろ人間っぽい。
 ◦ 使いたいパッケージや関数を明示すると意図したように書いてくれることが多い。
 ▪

    例えば、原文のfor文に対して「purrrパッケージのmap関数を使ってください」などと指示 する。
 ◦ Copilot(旧BingChat)で十分。
 ▪ ただし、Edgeは💩なのでご注意を。ポータルが最悪。
 ◦ GoogleのGeminiも悪くなさそう。
 
 • Enjoy!