ikeの日記

しがない研究者の雑記。

あるデータサイエンティストが解雇された話

George Floydさんの死がきっかけとなり、最近のアメリカでは人種問題に関連した議論や抗議活動が盛んに行われている。
そんな中、あるデータサイエンティストが解雇される事件が起きた。

事の経緯はこんな感じだ。
彼はデータコンサルティング会社に勤務するデータサイエンティストで、民主党系の選挙キャンペーンへのかかわりで知られる人物である。
彼は最近政治学のトップジャーナルに発表された論文の内容を紹介するツイートをした。
大雑把にまとめると、この論文はマイノリティによる抗議活動がメディアの報道を通じて政治家や有権者に正の影響を与えられる (抗議活動の目的達成につながる) こと、しかし抗議活動が暴徒化した場合には逆効果になりうることを、1960~70年代の公民権運動をケースに丁寧に実証したものである。
ところが彼のツイートは人種差別的であるという批判を浴びてしまい、結果として彼は勤務していた会社を解雇されてしまった。

このニュースを知り、いろいろと考えることがあった。大してまとまっていないが、以下に2つ思うことを書いておこうと思う。

まず、政治信条に反する事実/科学的知見に接したとき人はそれを受け入れるのが非常に難しい、ということをこの件は強く示してしまっている。
彼が紹介した論文は抗議活動の可能性や戦略の重要性を実証的に指摘するものであり、問題のツイートはその結果の一部を紹介しただけである。
しかし、抗議活動を支持する人の一部からはトーンポリーシングをしていると見られてしまったうえ、科学的知見を売りにしているはずの会社から解雇されることにまでなってしまった。
学術的研究にあたっては政治信条よりも科学的な厳密さや手続きが重要なことは当然だが、研究以外のシチュエーションでは、特に政治信条を強く持っているほど、後者を優先させることは困難になってしまう。

そして上記に関連するが、この件は政治に関する科学的コミュニケーションの難しさも示している。
彼が当該論文を違う形で紹介した場合 (別の言葉を使って紹介する、より詳細に紹介する、など) に異なる結果になったかはわからない。
ただ政治学を専攻している身として、特に政治学者以外にどのように研究結果を紹介するべきかについて真面目に考えないといけないと感じさせられた出来事だった。

Stay-at-Home & 国勢調査

前回の投稿に続いて最近のできごと。

Stay-at-Home

コロナウイルスの拡がりにより、うちの大学も3月11日に授業が当面の間オンラインで行われるようになり、3月30日には居住している州で外出禁止の州知事令 (Stay-at-Home Order)が出された。

私の観測範囲では在宅勤務や外出禁止による生産性低下やメンタルヘルスへの影響がしばしば指摘されている(気がする)。
自分はもともと必需品の買い物とたまに大学に行く以外にはほとんど外出していなかったため、幸いなことに(?)生活への変化はあまりない。

今回の騒動で自分が困ったことを挙げると
(1) 自分の近所でも買い占めが起こり、様々な商品が品薄(というより品切れ)になっている。特に驚いたのが、生肉が非常に品薄になっていること。買い占めてどうするわけ…?
(2) 人と話す機会が完全になくなった。英語が下手になるどころか、声の出し方を忘れかけている 笑。
(3) 参加を予定した学会が2つキャンセルされてしまったこと。いずれもネットワーキングや旅行を兼ねていたので、非常に残念。
(4) おそらく日本にしばらく帰省できないだろうこと。
といった感じだろうか。

自分も感染するんじゃないか、とか人種差別や治安が悪化するんじゃないか、とか不安はあるが、健康に気をつけつつ引きこもり生活をできるだけ楽しもうと思う。

国勢調査

今年は10年に一度の国勢調査イヤー、ということでアメリカの国勢調査に初めて回答した。
回答はオンラインででき、回答者の識別は事前に郵送されてきたIDを入力するだけなので非常に簡単だった。

しかし驚いたのは質問項目の少なさ。聞かれたのは
・世帯構成
・持ち家か否か
・性別
・年齢
・ヒスパニックか否か
・人種
だけだった。
教育程度や職種、国籍といったその他の情報はAmerican Community Surveyで聞いているからいい、ということなのかもしれないが、政策決定の基礎情報になりそうな変数の多くがサンプル調査に委ねられている、というのは不思議な気がする。
国勢調査も回収率が100%でないから…、という事情もあるのかもしれない。

他国の国勢調査事情を知ることができたいい経験だった。

最近のできごと

最近あったことのまとめ。

NBA

先日NBAの試合を初めて現地観戦してきた。
見たのはWizards対Grizzliesで、この日は八村と渡邊雄太の初対決だった。
試合はWizardsが第1クオーターからリードしていたが、第4クオーターでグリズリーズが逆転する、そこそこ劇的(?)な展開だった。
個人的には八村や渡邊よりもGrizzliesのMorantという選手が最も印象に残った (今年の新人王の有力候補らしい)。

f:id:ike_og:20200227131620j:plain
↑2人が練習中に話した後の様子 (話している最中の写真は撮り逃した…)

f:id:ike_og:20200227132223j:plain
↑試合があったCapital One ArenaはChina Townにあるので、中国語表記もある。

シャワーが壊れた

非常に古いアパートに住んでいるため、たまに不都合が生じることがあるが、先日シャワーの蛇口が壊れてしまった。
修理が来るまでの間は、運動もしないのにジムに(お金払って…)登録し、そこのシャワーを使うはめになった。
修理は不動産屋経由で依頼するのだが、最初はメールで頼んだが案の定(?)返事がなく、やはりアメリカ、電話をかけてようやく修理をしてもらえた。

アメリカに留学してきたものの大学以外でアメリカ人と話す機会は今までほとんどなかったのだが、修理に来たplumberのお兄さんと政治の話をしてしまった。
(彼はトランプは嫌だがバイデンは年寄りすぎ、ブティジェッジは若すぎ、だからサンダースに投票する(え?)、とのこと)
シャワーが壊れたのは嫌だったが、こちらはよい経験だった。

博論

がなかなかうまくいかない。
自分が興味があることをやるのはもちろんのことだが、ジョブマーケットを考えると、専門が近い人だけでなくやや遠い人にも「なるほど」「面白い」と思われる研究にしたいが、結構難しい。
なんとなくこれでいけるかな、という感じはしているので、頑張ろうと思う。

Bradley-Terryモデルを使ったJリーグデータの分析

先日ツイッタープレミアリーグのデータのBradley-Terryモデルを使った分析を見つけて、自分もやってみたくなった。
こんなことをやっている場合ではないが、同様の分析を2019年シーズンのJリーグのデータを用いてやってみてしまった…ので、ブログにまとめておこうと思う。

Bradley-Terryモデルとは?

Bradley-Terryモデルは、一対比較データから各観測の潜在的な能力を推定するモデルである。サッカーでいえば、各チームの潜在的な強さを試合結果(勝敗データ)から推定するために使われる。

データの収集

以下のRコードを使ってJリーグの公式サイトから2019年シーズンの試合結果を取得する。 ここではリーグ戦のみならずルヴァンカップ及び天皇杯のデータも含めることで、J1からJ3までの全チームの強さを比較できるようにした。

# Load packages
pacman::p_load(BradleyTerry2, dplyr, ggplot2, rvest)

# Scrape match data
dat <- rep(NA, 5)
month <- c("02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12")
for (i in month){ # loop over month
  url <- paste0("https://www.jleague.jp/match/search/?category%5B%5D=j1&category%5B%5D=leaguecup&category%5B%5D=j2&category%5B%5D=j3&category%5B%5D=emperor&year=2019&month%5B%5D=", i)
  web <- read_html(url)
  team_left <- web %>% html_nodes(css = "td[class='clubName leftside']") %>% html_text()
  team_left <- gsub("[[:space:]]", "", team_left)
  team_right <- web %>% html_nodes(css = "td[class='clubName rightside']") %>% html_text()
  team_right <- gsub("[[:space:]]", "", team_right)
  score_left <- web %>% html_nodes(css = "td[class='point leftside']") %>% html_text()
  score_left <- as.numeric(score_left)
  score_right <- web %>% html_nodes(css = "td[class='point rightside']") %>% html_text()
  score_right <- as.numeric(score_right)
  tmp <- cbind(team_left, team_right, score_left, score_right, 
               rep(i, length(team_left)))
  dat <- rbind.data.frame(dat, tmp)
  Sys.sleep(2)
}
dat <- dat[-1,]
# Data cleaning
colnames(dat)[5] <- "month"
dat$score_left <- as.numeric(as.character(dat$score_left))
dat$score_right <- as.numeric(as.character(dat$score_right))
## code match results (ties as 0.5)
dat$team_left_win <- ifelse(dat$score_left > dat$score_right, 1, 
                            ifelse(dat$score_left == dat$score_right, 0.5, 0))
dat$team_right_win <- 1 - dat$team_left_win
## drop cup games with non-league teams
dat <- dat %>% group_by(team_left) %>% mutate(team_left_n = n()) %>% ungroup()
dat <- dat %>% group_by(team_right) %>% mutate(team_right_n = n()) %>% ungroup()
dat <- dat %>% dplyr::filter(team_left_n > 5 & team_right_n > 5)
## convert team names to factor class
dat$team_left <- factor(as.character(dat$team_left))
dat$team_right <- factor(as.character(dat$team_right))

上記により、J1-J3のチーム同士による計1184試合の結果を取得することができる。
データを集めた後、パッケージの仕様に合わせてデータを整理しておく。

モデルの推定

モデルの推定にはRのBradleyTerry2パッケージを使う。最尤法を使っているので、今回のようにそれほど大きくないデータセットであれば推定は瞬時に終わる。

out <- BTm(outcome = cbind(team_left_win, team_right_win), 
           player1 = team_left, player2 = team_right, id = "team",
           formula = ~ team, data = dat, br = TRUE)

簡単!1
ちなみにBradleyTerry2パッケージを使うと潜在スコアのモデリングもできる。
今回の例であれば、勝敗の確率はチームの潜在的な強さのみならず試合会場(ホームかアウェイか)にも左右されうると考えられる。
ただし、天皇杯などどちらがホームかが判別できない試合がデータに含まれているため、ここでは最もシンプルな方法で分析をした。

結果の図示

モデルにより推定された各チームの潜在的な強さをプロットしてみる。

# Summarize estimation results
res <- BTabilities(out)
res <- as.data.frame(res)
res$lower <- res$ability + qnorm(0.025) * res$s.e. # 95% conf. intervals
res$upper <- res$ability + qnorm(0.975) * res$s.e.
res <- res[order(res$ability, decreasing = TRUE),] # sort teams
# Visualize
png("fig_jleague.png", width = 500, height = 1000)
par(mar = c(3, 4, 3, 2), mgp = c(2, 0.5, 0), family = "HiraKakuProN-W3")
plot(NULL, NULL, type = "n", xlim = c(-2.2, 4.0), ylim = c(1, 58),
     xlab = "Ability Estimates", ylab = "", main = "J League (2019 season)",
     axes = FALSE)
axis(1, tck = -0.01, cex.axis = 0.8)
axis(2, at = c(1:58), labels = rownames(res), las = 2, tck = -0.01,
     cex.axis = 0.8)
abline(v = 0, col = 8, lty = 2)
points(res$ability, c(1:58), pch = 20)
segments(res$lower, c(1:58), res$upper, c(1:58))
dev.off()

f:id:ike_og:20200207164417p:plain

出力された図を見てみると、信頼区間が非常に大きいことがわかる。
これは先に引用したツイートでも触れられているが、推定に使われたデータ数が1チームあたり30-40ゲームしかないためであると考えられる。2
ただ、推定誤差は大きいものの、潜在スコアの順序は割と直感にあっているように見える。
各リーグ内の順序は概ねリーグ戦の順位と相関している。また、おそらく多くの人が思っていた通り、柏レイソルはJ1下位チームよりも強く、FC岐阜J3の上位チームよりも弱い、という結果になっている。3


という感じでものすごく簡単に再現することができた。
Bradley-Terryモデルはパッケージを使ってしまえば簡単に推定できる一方、興味深い知見を得られるなぁという感想を持った。
政治学だと一対比較データはあまり見ないが、機会があればぜひ使ってみたいと思う。


  1. パッケージのデフォルトで、セレッソ大阪U23の潜在スコアが0に固定されている。

  2. J3チームの信頼区間が狭くなっている理由はよくわからないが…。

  3. 柏レイソルルヴァンカップ天皇杯などリーグ間をつなぐ試合(bridge observation)でそこまでパフォーマンスがよくなかったが、リーグ戦での勢いをこれらの試合でも見せられていれば、潜在スコアはもっと高く出たのかもしれない。

分析コードの望ましい(?)書き方

今学期から、某政治学トップジャーナルのRAとして働いている。
主な仕事は、採択されたペーパーで報告されている統計分析の結果が再現(reproduce)できるかを確認することである。1
そのため他人が書いたRやStataのコードを見る機会が多いが、再現性や可読性の高いコードの書き方について、いろいろと学ぶところが多い。
そこで、これまでに得た教訓を以下にまとめておこうと思う。

1. 途中で変数やオブジェクトを削除しない

データの前処理をしたり異なる種類の複数の分析をする際、分析ファイル内で変数やオブジェクトを削除してしまうケースをよく見るが、これはできるだけやめた方がいい。
後から元の変数の情報や前に行った分析の結果を参照できなくなってしまい、大変不便である。

2. ペーパーで報告されている全ての数値情報に関するコードを公開する

当たり前のように聞こえるかもしれないが、例えば記述統計に関するコードが欠けているなど、ペーパーの結果すべてに関するコードが公開されていないケースが非常に多い。
再現性の確認は分析者の義務であり、第三者にそのために追加的なコーディングをさせるようなことがあってはいけない。

3. Readmeファイルやデータのコードブックなどの添付文書もできるだけ公開する

これらがないと、ある場合と比べコードの可読性は格段に下がる。
特に複数のデータセットやコードファイルが存在する際は、Readmeファイルがあると非常に便利である。
また変数が多いような場合は、それぞれが何を示すのかがわかるよう、コードブックも公開すべきである。

4. どの図表に関するコードかを必ず明記する

統計モデルを推定したり図を出力したりした場合は、ペーパーのどの図表に該当するのかを必ずコメントで明記すべきである。
この情報がないと第三者はコードを理解するのが難しくなり、可読性が著しく低下する。

5. 図の縦横比はコードで指定する

ペーパーに載っている図とソフトウェアが出力する図とで縦横比が異なっているケースが非常に多い。
縦横比が違うと図が伝える印象が著しく変わってしまうので、分析者は自らが望ましいと思うアスペクト比をコード内で指定し、出力された通りの図をペーパーに載せるべきである。

6. 疑似乱数を発生させる際は必ず初期値を設定する

当たり前のように思えるかもしれないが、実際には守られていないケースが多い。
初期値が設定されていないと、結果が本当に再現できるのか、第三者は判別できなくなってしまう。
モンテカルロシミュレーションを行う際などは、この点を忘れてはいけない。

7. どのアドオンやパッケージを用いているのかがわかるようにする

これは特にStataユーザーに起こりがちな問題。
統計分析を行うにあたって、アドオンにより提供されているコマンドに頼ることが多い。
そのことに全く問題はないが、その際、コードの実行にどのアドオンが必要なのか、分析者は必ず明示すべきである。
この情報がないと、第三者はコードエラーへの対処法を自ら探さねばならなくなってしまう。

8. バージョン情報を必ず記載する

統計ソフトやそのパッケージ/アドオンのバージョンが違うと、利用できる関数や得られる結果が異なることが多い。
再現性を高めるため、分析者は使用したソフトウェアやパッケージ/アドオンのバージョンをペーパーに記載すべきである。


以上、自分が重要だと思った点を挙げてみた。
網羅的でも体系的でもないが、何かの役に立てば。


  1. ここでいう再現性(reproducibility)とは「同じデータ・方法を用いて報告されている通りの分析結果が得られること」を指しており、「異なるデータや方法を用いても結果が再現できること」(replicability)とは異なる。

走るチームは勝てる? - Jリーグのトラッキングデータの簡単な分析

最近Rを使ったデータ分析入門のレクチャーをする機会があったので、せっかくなのでブログにも書いてみようと思う。

リサーチクエスチョン

サッカーの話をすると、しばしば「走るチームは強い」という言説を聞く気がする。
相手がボールを持った時素早くプレスをかければ走行距離は増えるのでこれは正しそうにも思えるが、ただ単に走ればいいというわけでもないだろう。

そこで、Jリーグのトラッキングデータを使って、実際に「走るチームは強い」のかを見てみたいと思う。

データ収集

残念ながら走行距離及びスプリントの回数について既存のデータセットを知らないので、Jリーグの公式サイトからJ1各チームの試合毎のトラッキングデータを集めることにする。
今回は2019年シーズンの、25節 (直近の週末)までのデータを分析に使うことにする。
以下がそのために使うRのコード。

# Load packages
require(cowplot)
require(dplyr)
require(ggplot2)
require(lfe)
require(RCurl)
require(XML)

# Scrape match data
j1.dat <- rep(NA, 7)
for (i in 1:25){ # Loop over weeks
  # List of matches in the week
  u <- paste0("https://www.jleague.jp/match/section/j1/", i, "/")
  tmp <- htmlParse(getURL(u), encoding = "UTF-8")
  links <- unlist(xpathApply(tmp, "//a[contains(@href, 'trackingdata')]", xmlGetAttr, "href"))
  links.short <- gsub("/trackingdata", "", links)
  for (j in 1:length(links)){ # Loop over matches
    # Teams, scores, and results
    u <- paste0("https://www.jleague.jp", links[j])
    tmp <- htmlParse(getURL(u), encoding = "UTF-8")
    team <- unlist(xpathApply(tmp, "//p[contains(@class, 'leagAccTeam')]/a/span[contains(@class, 'embL')]", xmlValue))
    home <- c(1, 0)
    gf <- c(unlist(xpathApply(tmp, "//div[@class = 'leagLeftScore']", xmlValue)),
            unlist(xpathApply(tmp, "//div[@class = 'leagRightScore']", xmlValue)))
    gf <- as.numeric(gf)
    ga <- c(unlist(xpathApply(tmp, "//div[@class = 'leagRightScore']", xmlValue)),
            unlist(xpathApply(tmp, "//div[@class = 'leagLeftScore']", xmlValue)))
    ga <- as.numeric(ga)
    # Tracking data
    u <- paste0("https://www.jleague.jp", links.short[j], "ajax_trackingdata/")
    tmp <- htmlParse(getURL(u), encoding = "UTF-8")
    tracking <- unlist(xpathApply(tmp, "//td[@class = 'total_km']", xmlValue))
    tracking <- gsub("[^[:digit:]|^[:punct:]]", "", tracking)
    distance <- tracking[1:2]
    sprint <- tracking[3:4]
    # Storing information
    week <- rep(i, 2)
    tmp.dat <- cbind.data.frame(week, team, home, gf, ga, distance, sprint)
    j1.dat <- rbind.data.frame(j1.dat, tmp.dat)
  }
  cat("Finished collecting information on week", i, "matches... \n")
  Sys.sleep(1)
}
j1.dat <- j1.dat[-1,]

あまり効率のよいコードではないが、それは目をつぶって下さい m(__)m
以上のコードでチーム \times節単位のパネルデータを収集することができる。

データの前処理

収集したデータは即座に分析に使えるわけではない。そこでデータが分析に使えるようにクリーニングする必要がある。
ここでは、1) チーム名を英語でも表記する、2) 勝ち点の情報を含める、3) 公式データの欠損に対応する、1 4) データを並べ替える、という作業を行う。

# Data preprocessing
## team names in English
teams <- data.frame(team.ja = unique(j1.dat$team),
                    team.en = c("Cerezo Osaka", "Vissel Kobe", "Vegalta Sendai",
                                "Urawa Red Diamonds", "Kawasaki Frontale", "FC Tokyo",
                                "Sanfrecce Hiroshima", "Shimizu S-Pulse", "Sagan Tosu",
                                "Nagoya Grampus", "Kashima Antlers", "Oita Trinita",
                                "Jubilo Iwata", "Matsumoto Yamaga", "Gamba Osaka",
                                "Yokohama F. Marinos", "Shonan Bellmare", "Consadole Sapporo"))
j1.dat <- merge(j1.dat, teams, by.x = "team", by.y = "team.ja")
## results & points
j1.dat$res <- ifelse(j1.dat$gf > j1.dat$ga, "W", ifelse(j1.dat$gf == j1.dat$ga, "D", "L"))
j1.dat$point <- ifelse(j1.dat$res == "W", 3, ifelse(j1.dat$res == "D", 1, 0))
j1.dat <- j1.dat %>% group_by(team) %>% mutate(point.total = sum(point)) %>% ungroup()
### adjusting the points for data missingness
j1.dat$point.total[j1.dat$team.en == "Shimizu S-Pulse"] 
  <- j1.dat$point.total[j1.dat$team.en == "Shimizu S-Pulse"] + 3
## sorting data
j1.dat <- j1.dat[order(j1.dat$point.total, j1.dat$week, decreasing = TRUE),]

データの可視化

統計的な分析を行う前にまずデータを可視化することで、分析に関する重要な情報が得られることが多い。
ここでは、チーム毎に走行距離及びスプリント回数を集計し、それが25節時点の順位と関係しているかを見てみることにする。

まず、データを可視化するためのRのコードが↓

# Visualization
j1.dat$distance <- as.numeric(as.character(j1.dat$distance))
j1.dat$sprint <- as.numeric(as.character(j1.dat$sprint))
j1.dat$team.en <- factor(j1.dat$team.en, levels = rev(as.character(unique(j1.dat$team.en))))
g1 <- ggplot(data = j1.dat) + 
  geom_boxplot(aes(x = team.en, y = distance)) + 
  xlab("") + ylab("") + ggtitle("Running Diatance by Team") + theme_bw() + coord_flip()
g2 <- ggplot(data = j1.dat) + 
   geom_boxplot(aes(x = team.en, y = sprint)) + 
   xlab("") + ylab("") + ggtitle("# of Sprints by Team") + theme_bw() + coord_flip()
plot_grid(g1, g2, align = "h")

そして出力された図が↓ f:id:ike_og:20190902131047p:plain

図を見ると、少なくともチーム単位で分析をする限り、特に勝敗と勝ち点との間に関係はないようだ。
チーム単位で分析をする限り、走行距離やスプリント回数の分布はむしろチームの戦略や特色を反映しているように思われる。

統計分析

デモンストレーションはデータの可視化までだったので、これはオマケ。
データ発生過程が今ひとつ分からないが、チームカラーや季節などによる時系列なトレンドをコントロールした上で走行距離やスプリント回数の勝敗への影響が知りたいので、ひとまず固定効果を含んだモデルを推定する。
従属変数は0/1のダミー変数だが、固定効果を含めたいため線形確率モデルを使う。
また、距離や回数に関しては自然対数をとった。

分析のコード及び結果は↓

# Analysis
j1.dat$win <- as.numeric(j1.dat$res == "W")
out <- felm(win ~ log(distance) + log(sprint) + home | team + week | 0 | 0, data = j1.dat)
summary(out)

Call:
   felm(formula = win ~ log(distance) + log(sprint) + home | team +      week | 0 | 0, data = j1.dat) 

Residuals:
    Min      1Q  Median      3Q     Max 
-0.7323 -0.3594 -0.1941  0.4741  0.9173 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)   
log(distance)  2.29639    0.80680   2.846  0.00465 **
log(sprint)   -0.02526    0.19050  -0.133  0.89456   
home           0.06280    0.04570   1.374  0.17014   
---
Signif. codes:  0***0.001**0.01*0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.4813 on 403 degrees of freedom
Multiple R-squared(full model): 0.1131   Adjusted R-squared: 0.01627 
Multiple R-squared(proj model): 0.02818   Adjusted R-squared: -0.07793 
F-statistic(full model):1.168 on 44 and 403 DF, p-value: 0.2221 
F-statistic(proj model): 3.895 on 3 and 403 DF, p-value: 0.009167 

簡単な分析ではあるが、少なくとも走行距離に関してはある程度勝敗に影響がありそうだということがわかる。

以上非常に大雑把な分析だったが、個人的にはやっていてとても楽しかった。
公式データを使うだけでもまだ色々できそうだったので、暇にまた遊んでみようと思う。


  1. なぜか第18節の清水-神戸戦だけは公式サイトからトラッキングデータが取得できなかったため、勝ち点のみ事後的に調整した。

小切手は面倒くさい

日本ではあまり使われないがアメリカで頻繁に使われるものの1つとして小切手があげられる。
最近これでちょっと面倒なことがあった。

以前は家賃を小切手で払わなければいけなかったので、銀行からpersonal checkという、自分の名前と住所が書かれた (要は自分専用の)小切手を買っていた。
もっとも家賃以外はすべて銀行引き落としやクレジットカードによる決済が可能だったので、小切手は家賃の支払いのためだけに準備していた。
しかし今は家賃が銀行引き落としになったので、昨年引っ越して以降はpersonal checkを購入していなかった。

ところが、先日どうしても小切手で支払わなければいけないものがあった。
当初は銀行に行けば小切手くらい簡単に入手できるだろう、と思っていたが、実際は非常に面倒くさかった。
まず、自分が使っている銀行には(a) personal checkと(b) casher's checkの2種類しかない。
前者は自分で名宛人と支払額を記入できるが、最低1綴り42枚を購入しなければならず、(自分専用なので)結構値段が張る。また、注文してから1~2週間待つ必要がある。
一方casher's checkは銀行の窓口で名宛人と支払額をしていしてその都度発行してもらうものだが、なんと手数料が$15(!)もかかる。
今回の場合、普段は小切手を使わないのでcasher's checkを選択したのだが、たった$20の支払いのためにほぼ同額手数料を払うはめになってしまった。

小切手の性質を考えればいろいろと面倒なことが多いのはわかるのだが、それにもかかわらずアメリカでは小切手を使わなければならないケースが(頻繁ではないとはいえ)あるのが不思議でならない。
その点、日本ではほとんどの場合現金かクレジットカードのどちらかで支払いを済ませることのできるので便利だと感じる。