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

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

Avatar for bob3bob3 bob3bob3
February 24, 2024

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

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

Avatar for bob3bob3

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!