Rで何かをしたり、読書をするブログ

政府統計の総合窓口のデータや、OECDやUCIやのデータを使って、Rの練習をしています。ときどき、読書記録も載せています。

読書記録 - 「【音声アプリ対応】 英検3級 文で覚える単熟語 4訂版」 (旺文社英検書)

リスニングアプリ「英語の友」に対応しているので、スマホで音声を聞くことができます。音声ファイルをダウンロードできるので、PCで音声を聞くこともできます。

英検を受けるために購入したのではなくて、英文と日本語の文章が並んであるものが欲しかったので購入しました。

とても簡単な英語なので、すらすら読めました。

私の知らないアメリカのトピック記事がいろいろあって、雑学が増えました、例えば、CANUSA大会(カナダとアメリカのスポーツ大会)とか、リンゴにMacIntoshという品種があって、アップルのパソコン、マッキントッシュはこのリンゴの名前から名付けられたとかなどです。

 

読書記録 - 「中華料理と日本人 帝国主義から懐かしの味への100年史」 岩間 一弘 著 (中公新書)

料理(食事)は人間の営みの基本的なことですから、文化や歴史、社会情勢などと密接に結びついています。

この本は、肉まん、ジンギスカン料理、餃子、ウーロン茶、シュウマイ、ラーメン、麻婆豆腐、中国野菜などが、いつ、どのようにして日本に入って、広まってきたのかを文化や歴史、社会情勢を背景にして書いてあります。

これらの中華料理の多くが、明治以降の日本の満洲国や、台湾統治時代に日本に伝わってきたようです。またしく、サブタイトルの「帝国主義から」そのものです。

私は、ジンギスカン料理が、モンゴル、チンギス・ハーンとは全く関係がなく、北京で食べられていた羊肉のあぶり焼きがルーツであることを初めて知りました。

この本は多くの中村屋、崎陽軒など多くの具体的なお店の名前が出てきて、そのお店がどのように、肉まんを売っていたかとか、シウマイを売っていたかなどが書かれていて面白かったです。

また、日本の中華料理のように、植民地の地元の料理を懐かしく食べるという意味では、でイギリスのカレー料理同じようということが書かれてありました。

はじめにも書きましたが、ある一つ料理の背景にはいろいろなことが隠れているというのが興味深かったです。

私は肉まん、シウマイ、餃子、麻婆豆腐など大好きですが、こんどからは食べるときに、日本の帝国主義時代の頃などを思い出しながら食べるだろうな、と思いました。

 

読書記録 - 「ルビンの壺が割れた」 宿野 かほる 著 (新潮文庫)

友達から貰った本です。

30年前に結婚式に現れなかった婚約者の女性をフェイスブックで偶然に見かけた男性が、その女性にメールします。

そして、その女性をメールを返信します。

そのメールのやりとりをそのまま小説にしてありました。とても薄い本なので、1日で読み終わりました。

二人は大学の劇団の先輩(男性)と後輩(女性)という関係でした。はじめのうちは、その当時のことをやりとりしています。だんだんと、二人が付き合うようになったことなどをやり取りしていきます。そして、読者は、「女性がどうして結婚式に現れず、そのまま消息不明になったのかな」、という疑問を抱きつつ読んでいく、という構成です。

二人のメールのやりとりを読んでいく、という構成なのでとても読みやすかったです。出版当時は、最後の文章が衝撃的だと話題になったようですが、私は最後の文章はなかったほうがいいと思いました。

私もやりとりが途絶えてしまった人が何人かいますが、もしも自分がSNSで偶然にその人をみかけたら、この本の男性のようにメールするのかな、しないのかなと考えました。

 

UCI Machine Learning Repository の Seoul Bike Sharing Demand のデータの分析3 - Elastic-Net Regression による予測

www.crosshyou.info

の続きです。今回は、glmnetパッケージを使って、Elastic-Net Regression で bike を予測してみます。まず、glmnetパッケージを読み込みます。

glmnet はマトリックス型オブジェクトが必要なので、make() で生成します。

cv.glmnet() でモデルを生成します。

plot() でグラフを描くと、lambda を X軸、MSEをY軸、グラフの上部に使用している変数の数を表示したグラフになります。

このグラフは、いろいろな複雑さのモデルを試して、どれが一番よく当たるかを比べるためのものです。
左の縦線は「シンプルで安定したモデル」、右の縦線は「最も当たるモデル」を示しています。

左の縦線は、s = "lambda.1se", 右の縦線は、s = "lambda.min" のときのモデルです。

s = "lambda.1se" のモデルの係数をみてみます。

windやdewなどは不要な変数だとElastic-Net Regressionでは判断したのですね。

RMSEを計算します。

RMSEは7.5でした。

前回計算したRMSEと並べて表示します。

Elastic-Net Regression は lm() 関数の Linear Regression に正則化(Regularization)を追加したものなので、同じくらいのRMSEです。

今回は以上です。

はじから読むには、

www.crosshyou.info

です。

今回のコードは、以下になります。

#
# glmnetパッケージを読み込む
library(glmnet)
#
# マトリックス型オブジェクトを作成
train_X <- df[train, ] |> select(-bike) |> makeX()
test_X <- df[-train, ] |> select(-bike) |> makeX()
train_Y <- df$bike[train]
test_Y <- df$bike[-train]
#
# Elastic-Net Regression
set.seed(1)
glmnet_mod <- cv.glmnet(train_X, train_Y, alpha = 0.5,
                        family = "gaussian", type.measure = "mse")
#
# cv.glmnetオブジェクトのグラフ
plot(glmnet_mod)
#
# 係数の確認
coef(glmnet_mod, s = "lambda.1se")
#
# RMSEの計算
RMSE_glmnet <- 
  sqrt(mean*1
RMSE_glmnet
#
# 3つのRMSEの比較
tibble(
  model = c("avg", "lm", "glmnet"),
  RMSE = c(RMSE_avg, RMSE_lm, RMSE_glmnet)
)
#

(冒頭の画像は、Bing Image Creator で生成しました。プロンプトは、Photograph of natural wild grass fields, full of white clover flowers, blue sky, closeup of a pink iris flower. です。)

 

*1:predict(glmnet_mod, newx = test_X, s = "lambda.1se") -
  test_Y)^2

UCI Machie Learning Repository の Seoul Bike Sharing Demand のデータの分析2 - 平均値と線形回帰モデルでの予測

www.crosshyou.info

の続きです。このデータセットは、レンタルサイクルの需要があるかを予測するモデルを作るためのものです。まず、トレーニング用データ、テスト用のデータにわけるためのインデックスを作成します。

まずは、一番単純な平均値でどのくらいの予測精度があるかを確認しておきます。

23.4ぐらいです。トレーディング用のデータの平均がこれぐらいだから、予測値もこの値にしてしまえ、という単純な考えです。

テスト用のデータで、RMSEを計算します。

12.5ぐらいになりました。平均すると12.5ぐらい予測値(この場合は平均値ですが)と実際のテスト用のデータのbikeの値が違っている、ということです。

ここから、いろいろなモデルで、この12.5よりも小さいRMSEを目指していこう、ということです。

線形回帰モデルから始めます。

lm()関数でモデルの学習をします。

summary()関数で、どんな係数のモデルになったかみてみます。

Multiple R-squared: 0.6532 とあります。つまりこのモデルで、bikeの変動の65%くらいは説明できる、ということですね。

テスト用のデータのRMSEを計算します。

7.4と平均値のRMSEからは、だいぶ小さくなりました。平均値RMSEから比べると41%も減少しました。

最後に、テスト用のデータのbikeと線形回帰モデルが予測した値の散布図を描いてみます。

予測値は、マイナスの値もありますね。bikeはマイナスにならないことは明らかですから、実務では、予測値がマイナスになったら、それは0に置き換えることでしょう。

なので、再度、マイナスの予測値は0として、RMSEを計算してみます。

7.35が7.26と少し小さくなりました。

今回は以上です。

次回は、

www.crosshyou.info

です。

 

初めから読むには、

www.crosshyou.info

です。

今回のコードは以下になります。

#
# トレーニング用データ、テスト用のデータにわけるためのインデックスを作成
set.seed(1)
train <- sample(1:nrow(df), 0.25 * nrow(df), replace = FALSE)
#
# トレーディング用のデータのbikeの平均値
avg_train <- mean(df$bike[train])
avg_train
#
# テスト用のデータのRMSE
RMSE_avg <- sqrt(mean*1
RMSE_avg
#
# 線形回帰モデル
lm_mod <- lm(bike ~ ., data = df, subset = train)
#
# モデルの確認
summary(lm_mod)
#
# テスト用のデータのRMSE
RMSE_lm <- 
  sqrt(mean*2
RMSE_lm
#
# 平均値RMSEとの比較
(RMSE_lm / RMSE_avg - 1) * 100
#
# 実際のbikeとモデルの予測値の散布図
plot(df$bike[-train],
     predict(lm_mod, newdata = df[-train, ]),
     xlab = "実際のbike",
     ylab = "線形回帰モデルの予測値"
     )
abline(0, 1, col = "red")
#
# 予測値でマイナスになったら0に置換したRMSE
lm_pred <- predict(lm_mod, newdata = df[-train, ])
lm_pred <- ifelse(lm_pred < 0, 0, lm_pred)
RMSE_lm2 <- sqrt(mean*3
RMSE_lm2
#

(冒頭の画像は、Bing Image Creator で生成しました。プロンプトは、Photograph of natural seaside coast, green forest, blue ocean, blue sky, green grasses, close up of yellow pansy flowers, there is not any human-made objects. です。)

 

*1:avg_train - df$bike[-train])^2

*2:predict(lm_mod, newdata = df[-train, ]) - df$bike[-train])^2

*3:lm_pred - df$bike[-train])^2

読書記録 - 「文書の書き方」 辰濃 和夫 著 (岩波新書)

1994年3月に出版された本で、私が買ったのは、2024年12月発行の第50版でした。

「文は心である」ということが繰り返し繰り返し書かれています。

技術的なことの前に、書きたいことが心に入っているか、心から書きたいか、などが大切と言っています。

福沢諭吉や北村薫、その他たくさんの人の文章が見本として掲載されていますので、それを読むだけでも面白かったです。特に、「吾輩は猫である。」「山椒魚は悲しんだ」「メロスは激怒した」など有名な小説のはじめの一文だけを並べてあったところなどは、とても面白かったです。

著者は、1975年から1988年まで、朝日新聞の天声人語を担当していたそうです。天声人語を書く人は、朝日新聞の中で、抜群に文章の上手な人だ、ということをどこかの文章で読んだことがありますが、本当にそうだと思いました。

文章を書く時は、この本に書いてあることに気を付けて、とくに「文は心である」ということを意識して書こうと思いました。

 

 

UCI Machine Learning RepositoryのSeoul Bike Sharing Demandのデータの分析1 - Rにデータを取り込む

今回からしばらくは、UCI Machine Learning RepositoryのSeoul Bike Sharing Demandのデータを分析してみたいと思います。

Seoul Bike Sharing Demand [Dataset]. (2020). UCI Machine Learning Repository. https://doi.org/10.24432/C5F62R.

レンタルサイクルの貸出数を予測するモデルを作る、というタスクです。

ダウンロードしたExcel CSVファイルはこんな感じでした。

2行目に、私が変数名を挿入しました。

これをRで分析します。

まず、Tidyverseパッケージを読み込みます。

read_csv()関数でファイルを読み込みます。skip = 1 として2行目から読み込みます。

glimpse()関数で、データが読み込まれていることを確認します。

上手く読み込まれました。

na.omit()関数でNAのある行を念のため削除します。

dateが文字列型のままなので、dmy()関数で日付型に変換します。

dateが<date>となっていて、日付型になっていることが確認できます。

season, hol, funcを文字列型からファクター型に変換します。

summary()関数でサマリーをみてみます。

seasonは、春、夏、秋、冬の4つですね。holは休日か休日でないか、funcはyesかnoかです。

holとfuncは0, 1のダミー変数にしておきます。

今回のタスクは、bikeを予測することなので、bikeの分布を確認しておきましょう。

右の裾野が広い分布ですね。

対数変換した分布をみてみます。

今度は左の裾野が広い分布になりました。

sqrt()関数で平方根にしてみます。

平方根にした分布が一番、左右対称に近いですね。

ということで、bikeを平方根に変換しておきます。

今回は以上です。

次回は、

www.crosshyou.info

です。

 

今回のコードは以下になります。

#
# tidyverseの読み込み
library(tidyverse)
#
# CSVファイルの読み込み
df_raw <- read_csv("SeoulBikeData.csv",
                   skip = 1)
#
# データの確認
glimpse(df_raw)
#
# NAの削除
df <- na.omit(df_raw)
#
# dateを日付型に変換
df <- df |> mutate(
  date = dmy(date)
)
df
#
# season, hol, funcをファクター型にする
df <- df |> 
  mutate(
    across(season:func, as.factor)
  )
#
# サマリー
summary(df)
#
# hol, funcをダミー変数に
df <- df |> 
  mutate(
    hol = if_else(hol == "Holiday", 1, 0),
    func = if_else(func == "Yes", 1, 0)
  )
#
#
# bikeが目的変数なので、分布を確認
ggplot(df, aes(x = bike)) +
  geom_histogram(fill = "white", color = "black") +
  theme_minimal()
#
# bike + 1の対数変換ヒストグラム
df |> 
  mutate(bike = log(bike + 1)) |> 
  ggplot(aes(x = bike)) +
  geom_histogram(fill = "white", color = "black") +
  theme_minimal()
#
# sqrt(bike)のヒストグラム
df |> 
  mutate(bike = sqrt(bike)) |> 
  ggplot(aes(x = bike)) +
  geom_histogram(fill = "white", color = "black") +
  theme_minimal()
#
# bikeをsqrt()で平方根変換
df$bike <- sqrt(df$bike)
#

 

 

(冒頭の画像は、Bing Image Creator で生成しました。プロンプトは、Photograph of very long wide view of natural forest, a river is running in the middle of the forest. Blue sky, a close up of red rose flowers. です。)