ラーメン屋は何曜日に休みが多いのかAPIを利用して調べた

きっかけはツイート

ラーメン屋は何曜日に休みのお店が多いのかを調べてみようと思ったきっかけは、フォロワーのツイートだった。調べることは好きだけど、これまでは人力で調べてばかりだった。Pythonを勉強してから、ずっとウェブスクレイピングやWeb APIに興味があったので、折角なので挑戦してみた。

ラーメン屋は月曜日が休みが多い

HOT PEPPERぐるなびAPIを提供しているので、そこからラーメン店の情報を取得し、定休日を集計した。

データは2019年2月21日に取得し、HOT PEPPERからは2212件、ぐるなびからは4767件の店舗情報が集められた。これを元に、定休日を集計した。データはJSON形式で、定休日もキーとして割り振られているので、抽出は簡単だった。

HOT PEPPERぐるなびともに、年中無休がもっと多く全体の30%から40%を占めている。曜日としては、月曜日が休みの店が多くHOT PEPPERでは15%、ぐるなびでは11%であった。次いで、火曜、水曜、日曜が10%前後である。金土休みの店はほとんどなく、0.5%程度である。それを除けば、木曜休みが5%と、他の曜日に比べて半分程度であった。
無休と曜日別の定休日はそれぞれのサービスで似たような傾向にあったが、その他は異なる結果になった。それぞれのサービスに登録する店舗の傾向を反映しているのだろう。たとえば、不定休の店はHOT PEPPERでは6%だが、ぐるなびでは14%と倍近い違いがある。一方で、HOT PEPPERでは祝日前が定休日の店舗が2%程度なのに、ぐるなびには殆どなかった。

f:id:lastline:20190222121019p:plain
HOT PEPPER ラーメン屋 定休日

f:id:lastline:20190222121057p:plain
ぐるなび ラーメン屋 定休日

曜日別でも割合を算出した。何曜日に休みが多いのかは、こちらの方が適当だろう。月曜日が定休日の店が25%から30%で、火曜、水曜、日曜が大体20%くらいとなる。月曜休みの未成は多いが、突出して多いわけではない。火、水、日はHOT PEPPERぐるなびとでばらつきがあったので、月曜日の次に多い曜日を特定するのは難しい。一方で、木曜日は10%と下がる。金土は稼ぎ時のためか、定休日のお店は1%くらいである。むしろ、数%でも存在していることが意外であった。
日曜日が休みの店舗はオフィス街などにあるのだろう。平日に休む場合は、月曜日が多く、次いで火曜日と水曜日となる。月曜日が休みなのは多客日の後に休みたい心理的な面と、日曜に市場が開いていないため食材調達上の問題もありそうだ。木曜日が定休の店が少ないのは、金曜日の仕込みなどがあるからだろうか。

f:id:lastline:20190222121128p:plain
HOT PEPPER ラーメン店 曜日別定休日

f:id:lastline:20190222121202p:plain
ぐるなび ラーメン屋 曜日別定休日

他の業態の飲食店と比較すべきだが、今回は本筋ではないのでやらない。恐らく、他の飲食店でも似たような傾向になるだろう。

Pythonによる定休日の集計方法

HOT PEPPERぐるなびAPIを利用し、Pythonにてラーメン店の情報を取得しJSONとして保存した。そのデータから定休日の情報を抜き出し、集計を行った。
取得したJSONデータから直接定休日を集計した方が手順は省けるが、定休日以外の統計処理を見据えて店舗情報を保存することにした。

APIの叩き方は経験が無かったので少々戸惑ったけども、一度取得できれば試行錯誤は用意だった。むしろ、JSONデータや定休日を集計しCSV形式で保存したデータが文字化けしまくって四苦八苦した。

HOT PEPPERぐるなびAPI仕様の所感

食べログAPIがあると便利そうだと思ってググったら、残念ながらかなり前に廃止されていることを知った。そこで、食べログAPI提供終了していたので代わりのAPIを探した(一覧) - エンジニアステップ を参考に、HOT PEPPERぐるなびAPIを使うことにした。それぞれに一長一短がある。

HOT PEPPER はメールアドレスのみでAPIキー取得でき、お試しにはもってこいだ。検索できる店舗数に上限がないのも扱いやすい。また、店舗のジャンルコードとして「ラーメン店」を指定できるため、今回の用途と相性もよい。ただし、ぐるなびと比較すると登録店舗数が圧倒的に少ない。
データ形式XMLがデフォルトだが、JSONJSONPも選択できる。

ぐるなびは、APIを取得するために氏名などを入力する必要があるため、お試しで使う身としてはちょっと敷居が高い。一方で、自身でサービスを立ち上げる際にはぐるなびの方が案内がしっかりしており信頼感が高い。データはJSON形式で出力される。

業態コードとして「ラーメン」が用意されているものの、それを指定して叩いても居酒屋のようなラーメン専門店以外もひっかかる。特定の業態を抽出するには工夫が必要となる。
一方でテストツールをウェブから利用でき、お試しで結果を得やすい。また登録店舗数が圧倒的に多い。たとえば、ラーメン店で検索するとHOT PEPPERでは2,600店しかヒットしないが、ぐるなびだとその10倍の26,000店もヒットする。統計を取りたいならぐるなびの方に分があるだろう。ただし、取得上限が1,000件までのため、必要な情報を網羅的に得るのにも工夫が必要となる。

PythonAPIを叩いてみれば

Python の requests を用いて API を叩き、JSON形式で店舗情報を取得した。先にも述べたが、ラーメン店を絞り込むのにやや工夫が必要である。

HOT PEPPER はラーメン店のジャンルコードが G013 と指定されており、絞りこみが楽である。約2,600店がヒットした。取得上限はないが1ページ当たり100店舗までしか表示できないので、26回叩いて全店舗の情報をJSONとして出力した。

ぐるなびにもラーメン店の業態コードがあるものの、それだけではラーメン店以外もヒットする。お好み焼きやしゃぶしゃぶ店なども引っかかるため、ぐるなびの分類方法は難がありすぎに思う。対処は比較的簡単で、フリーワードに「ラーメン」を入れることでほぼラーメン店のみに絞れた。
ぐるなびでは約26,000件ものラーメン店がヒットした。取得上限が1,000件なので、それ以上の店舗情報を得るには叩き方に工夫が必要となる。今回は、都道府県毎に取得した。
東京には3,000店舗以上、都市圏では1,000店舗以上のラーメン店が登録されている。 1,000件以上ある都道府県では上限の1,000件を取得するように設定した。ぐるなびの掲載順に取得すると、ラーメン店以外は検索結果の後ろの方に表示される。上位1,000件を取得した方が、ラーメン店以外を除外しやすい。

APIの叩き方に少々手間取ったが、それ以上に四苦八苦したのがJSONデータの保存である。エンコードUTF-8を指定しているのに、なぜか日本語がASCIIで描き込まれ uXXXXなどど保存される。それを回避するには、open() ではなく codecs.open() で開き、dumps() の引数に ensure_ascii=False と指定する必要があった。

# HOT PEPPER のラーメン店情報をJSON形式で取得する
import requests
import json
import codecs
 
# APIキーの指定
apikey = ”{個々人のAPIKEYを入力する}”
 
# APIのURL
api = 'http://webservice.recruit.co.jp/hotpepper/gourmet/v1/?key={key}&order=3&genre={genre}&count={count}&start={start}&format=json'
 
# APIにリクエストを送信して店舗数を取得する
url = api.format(key=apikey, count=1, start=1, genre='G013')
response = requests.get(url)
response.raise_for_status()
data = json.loads(response.text)
count_range = data['results']["results_available"]
 
# ラーメン店の検索結果をJSON形式で取得する
ramen_json = []
 
# 100件ごとにAPIにリクエストを送信して店舗情報を取得する
for i in range(0, count_range, 100):
    url = api.format(key=apikey, count=100, start=i, genre='G013')
 
    response = requests.get(url)
    response.raise_for_status()
 
    data = json.loads(response.text)
    data = data['results']['shop']
    ramen_json += data
 
# 取得したラーメン店のJSONデータを保存
with codecs.open('ramen_hot.json', 'w', 'utf-8') as obj:
    dump = json.dumps(ramen_json, indent=4, ensure_ascii=False)
    obj.write(dump)
# ぐるなびのラーメン店情報をJSON形式で取得する
import requests
import json
import codecs
 
# APIキーの指定
apikey = ”{個々人のAPIKEYを入力する}”
 
# APIのURL
api = 'https://api.gnavi.co.jp/RestSearchAPI/v3/?keyid={key}&category_s={categoly}&freeword={freeword}&offset={start}&hit_per_page={count}&pref={pref_code}'
 
# 業態コードとフリーワードの指定
w_ramen = '%e3%83%a9%e3%83%bc%e3%83%a1%e3%83%b3' # ラーメン
c_ramen = 'RSFST08008' # ラーメン
 
# 都道府県毎に店舗情報を取得する
for num in range(1, 48):
    num = str(num).zfill(2)
    pref_num = 'PREF' + num
 
    # APIにリクエストを送信して店舗数を取得する
    url = api.format(key=apikey, count=1, start=1, freeword=w_ramen, categoly=c_ramen, pref_code=pref_num)
    response = requests.get(url)
    response.raise_for_status()
    data = json.loads(response.text)
    count_range = data['total_hit_count']
 
    # 上限が1000件なので、1000を超える場合は count_range を1000に書き換える
    if count_range > 1000:
        count_range = 1000
 
    # ラーメン店の検索結果をJSON形式で取得する
    ramen_json = []
 
    # 100件ごとにAPIにリクエストを送信して店舗情報を取得する
    for i in range(1, count_range, 100):
        url = api.format(key=apikey, count=100, start=i, freeword=w_ramen, categoly=c_ramen, pref_code=pref_num)
 
        # 実際にAPIにリクエストを送信して結果を取得する
        response = requests.get(url)
        response.raise_for_status()
 
        data = json.loads(response.text)
        data = data['rest']
        ramen_json += data
 
    # 取得したラーメン店のJSONデータを保存
    with codecs.open('ramen_guru' + pref_num + '.json', 'w', 'utf-8') as obj:
        dump = json.dumps(ramen_json, indent=4, ensure_ascii=False)
        obj.write(dump)
定休日を抽出する

HOT PEPPERぐるなびともに定休日がそれぞれ close や holiday としてキー登録されているので定休日の抽出は非常に簡単だ。
また、ラーメン専門店を抽出できているかを確認するため、店舗業態も抽出した。都道府県毎の傾向を見ようと思い都道府県も抽出したが、今回はそこまでやらなかった。
ぐるなびの定休日情報は細かく書かれており、たとえば「毎週月曜日、*元日は休み」など備考が含まれている。今回は定期的な休業日を知りたかったので備考を省くように処理した。
ちなみに、ぐるなびの店舗形態を確認すると「こだわりラーメン」に分類されているラーメン店があった。気になって調べてみると、北海道を拠点する山岡家が用いている業態名称である。チェーン店なのにこだわりラーメンと銘打つのは強気すぎないか。

結果を、1列目に都道府県、2列目に店舗業態、3列目に定休日となるCSVファイルとして保存した。
ぐるなび都道府県毎にCSVファイルを出力した後に結合したファイルを作成した。
ちなみに、CSVファイルを結合する時にもエンコードの問題が発生。結合したファイルを出力する際に encoding='utf-8' と指定しているにも拘わらず、なぜかJIS形式で保存されるため、UTF-8で開こうとして文字化けした。結合するファイルを開く際に、engine='python' と指定することで文字化けを回避した。

# HOT PEPPERとぐるなびの店舗データから定休日を抽出しCSVとして出力
import os
import glob
import json
import codecs
import csv
 
def holiday_pickup_hot(path):
    # HOT PEPPERのJSONデータを処理する関数
    # 指定したpath内のJSONファイルを取得
    # 地域、店舗ジャンル、定休日を抽出
    # CSV形式で保存
 
    # フォルダ中のパスを取得
    All_Files = glob.glob('{}*.json'.format(path))
 
    for file in All_Files:
        #JSON ファイルを開く
        with codecs.open(file, 'r', 'utf-8') as obj:
            df = json.load(obj)
 
        # 地域、店舗ジャンル、定休日を抽出する
        ramen_csv = []
        for i in range(len(df)):
            holiday_list = []
            area = df[i]['large_area']['name']
            genre =  df[i]['genre']['name']
            holiday = df[i]['close']
            holiday_list = [area, genre, holiday]
            ramen_csv.append(holiday_list)
 
        # 抽出した地域、店舗ジャンル、定休日のデータをCSV形式で保存
        name = file.rstrip('.json')
        with open(name + '_holiday.csv', 'w') as obj:
            writer = csv.writer(obj, lineterminator='\n')
            writer.writerows(ramen_csv)
 
def holiday_pickup_guru(path):
    # ぐるなびのJSONデータを処理する関数
    # 指定したpath内のJSONファイルを取得
    # 地域、店舗ジャンル、定休日を抽出
    # CSV形式で保存
 
    # フォルダ中のパスを取得
    All_Files = glob.glob('{}*.json'.format(path))
 
    for file in All_Files:
        #JSON ファイルを開く
        with codecs.open(file, 'r', 'utf-8') as obj:
            df = json.load(obj)
 
        # 地域、店舗ジャンル、定休日を抽出する
        ramen_csv = []
        for i in range(len(df)):
            holiday_list = []
            area = df[i]['category']
            genre =  df[i]['code']['prefname']
            holiday = repr(df[i]['holiday']) #repr()
            holiday = holiday.split(r'\n')
            holiday = holiday[0].split("'")
            holiday_list = [area, genre, holiday[1]]
            ramen_csv.append(holiday_list)
 
        # 取得した地域、店舗ジャンル、定休日のデータをCSV形式で保存
        name = file.rstrip('.json')
        with open(name + '_holiday.csv', 'w') as obj:
            writer = csv.writer(obj, lineterminator='\n')
            writer.writerows(ramen_csv)
 
 
holiday_pickup_hot(path='./ramen_hot/')
holiday_pickup_guru(path='./ramen_guru/')
# フォルダ内にあるCSVファイルを結合し出力
import os
import glob
import csv
import pandas as pd
 
# フォルダ中のパスを取得
DATA_PATH = "./ramen_guru/"
All_Files = glob.glob('{}*.csv'.format(DATA_PATH))
 
# フォルダ中の全csvをマージ
list = []
for file in All_Files:
    list.append(pd.read_csv(file, engine='python', header=None))
 
df = pd.concat(list, sort=False)
 
# 結合しcsvを出力
df.to_csv('ramen_guruPREF01to47_holiday.csv', encoding='utf-8')
定休日を集計する

EXCELでもできそうだが、折角なのでPythonを使って集計した。CSVファイルの3列目を読み込み、定休日をキーとする辞書形式でカウントした。定休日と頻出数のセットとしたリストを作り、それをソートした後に、結果をCSVファイルとした出力した。
曜日は意図通りに集計されるが、「無」、「無休」などは別々に集計される。また、週に二日以上定休日がある場合も、異なるキーとなる。そのため、出力されたデータを手動で再集計した。集計方法には工夫の余地があるものの、結果としては大きな差異はないと思われる。

ぐるなびは定休日が記載されていない店舗が多かった。約20,000店舗の情報を取得したが、その内約16,000件は定休日の情報が「記載無し」であった。これは「null」や「nan」の意味での「記載無し」である。定休日がなく年中無休なのか、そもそも情報が記載されていないのか判断できない。「記載無し」の店舗は省き、残った4,000店舗から定休日を集計した。

# CSVファイル内の指定した列にある単語の出現数をカウントする
import pandas as pd
 
def counter(file_name, read_column):
    # CSVファイルの指定した列の単語の出現数をカウントする関数
    # file_name でCSVファイルを指定
    # read_column で列を指定
 
    df =  pd.read_csv(file_name, engine='python', header=None)
    data = df.iloc[:, read_column]
 
    # 単語を辞書のキーとしてカウントする
    words = {}
    for word in data:
        words[word] = words.get(word, 0) + 1
 
    # 単語と出現数をタプルとしてリスト化しソートする
    dic = [(v,k) for k,v in words.items()]
    dic.sort()
    dic.reverse()
 
    # 結果をCSV形式で保存
    # utf-8 を指定しない
    with open(file_name.strip('.csv') + '_count.csv', 'w') as obj:
        for count, word in dic:
            obj.write(str(count) + ',' + str(word) + '\n')
 
counter(file_name='ramen_holiday_hot.csv', read_column=2)
counter(file_name='ramen_guruPREF01to47_en.csv', read_column=2)

APIを叩いて集計してみた感想

ブログに内容をまとめるのに、コードを書いて結果を得るまでと同じくらいの労力がかかってしまった。

APIそのものは簡単に取り扱えるので、欲しい情報を絞り込むのに検索力が必要に感じた。データを取得でにさえすれば、集計自体も難しくない。エンコードには苦しめられたが……。
最終的に人力で集計した部分もあるが、今回はそこを自動化するのに労力かかりそうだったので、自動化するメリーはないだろう。より多くのデータを集計するならより自動化をすべきだろう。自然言語系の処理は面倒そうだ。

コードを他人に見せることを意識すると、コメントやプログラミングのロジックなどを他の人が読んでもわかりやすいようにしようと自然に思えたので、勉強に向いてるなと感じた。

みんなもゲームのRTA見よう!

YouTubeニコニコ動画でゲームのRTAを見ています。2019年に入り、ゼルダの伝説のブレスオブザワイルドのRTAが30分を切り、スーパーマリオオデッセイのRTAは1時間を切りそうな状況が続いています。共に、1時間弱で楽しめるコンテンツなので見所を紹介していきます。

とうとう30分を切ったブレスオブザワイルド

  • Amiiboあり
    • rasenurns
    • 29m 46s
  • Amiibo 無し
    • sketodara01417
    • 31m 01s 160ms

2019年1月2日、ついにゼルダの伝説ブレスオブザワイルドのRTAAmiibo有りで30分を切りました。2018年の3月に40分台を切ってから実に9ヶ月後の達成です。Amiiboなしも30分台が目前となっています。

ブレスオブザワイルドというか、ゼルダの伝説RTAにはバグ技(glitch)がつきものです。時のオカリナは様々なバグやそれを実行するためのセットアップが多く、そのためRTAのレギュレーションも細かく分かれています。一例として 【RTA】ゼルダの伝説時のオカリナ All Dungeons(オールダンジョン)in 1:18:46【Part1】 - ニコニコ動画 を紹介します。
ブレスオブザワイルドでは、着地時のダメージをキャンセルするバグ技や、シールドによる小ジャンプなどが駆使されてきました。ビタロックで停止させたオブジェクトで移動する「stasis launch」はバグ技というか、仕様でしょう。そのオブジェクトにぶつかってパラセールのスピードをかせぐのはバグ技になりますが。
30分台までの’RTAとしては、【RTA】ゼルダの伝説 ブレスオブザワイルド Any% 40:58 Part1【字幕解説】 - ニコニコ動画 が解説もわかりやすくおすすめです。

ブレスオブザワイルドのRTAにおける30分切りには、2018年後半に発見された二つのバグ技が大きく貢献しています。

一つは、2018年8月末に発見された、縦サーフィンで壁を抜ける「Shield Skew Clip」。壁をすり抜けることで、はじまり塔を起動することなく、祠に侵入できるようになりました。これにより、回生の祠からの脱出、はじまりの塔の起動や、そこまでのイベントを諸々すっ飛ばせます。以前は、回生の祠でゼルダ姫がリンクに語りかけるシーンがそれなりの尺であったため、セリフ読み上げの速いドイツ語でのプレイが推奨されてきました。現在は、ゼルダ姫が語りかけるシーンが減少したため、ドイツ語以外でのタイムロスの影響は軽微になっています。ただし、ロードの関係から Wii U 版の方が早く、RTA勢は Wii U 版でプレイしています。

もう一つが、2018年10月に発見された、敵に吹っ飛ばしもらって超高速で移動する「Bullet time Bounce(BtB)」。これにより、従来から利用されてきた「stasis launch」よりも速く移動できるようになりました。あまりも超高速で移動するため、オブジェクトのロードが間に合いません。使用できる場所は限られますが、祠の扉がロードされる前に侵入する、なんてことも可能です。「BtB」によるぶっ飛びでも、はじまりの大地ではパラセールを取得していないため落下時のダメージをキャンセルする技も健在です。

現在の世界記録保持者であるrasenurns氏は「Shield Skew Clip」と「BtB」の精度を高めることで30分切りを達成しました。ガノン戦はあまり得意ではないようで、その辺が最適化されると28分台も可能かも知れません。ただし「Shield Skew Clip」と「BtB」しっかりとキメないとガノン戦すら辿り着けないため、そんな簡単な話ではありませんけど。

Amiiboを使うと攻撃力アップ食材を入手できたり、金属の箱を呼び出せるため、使用しない場合よりもおよそ30秒ほど早いと言われています。現在のsketodara01417氏によるAmiiboなしの記録は、ギリギリ31分を切れませんでしたが、31分切りは可能でしょう。また、rasenurns氏と比較すると「BtB」による祠間の移動に若干のロスがあるため、恐らくAmiiboなしでも30分は切れそうです。

さらなる更新は、新たなバグ技が登場しないと無理でしょう。ブレスオブザワイルドが発売された当初から、パラセール取得前にはじまりの台地を抜け出す方法が模索されていますが、ガノン討伐につなげられる抜け道は見出されていません。パラセールを手に入れない限り、はじまりの台地以外には地面判定が出現しないようで、仮にガノンまで辿り着けても討伐はできません。最近のゲームにおいて、メモリ書き換え等のバグ技が発見される可能性は非常に低いです。リンクのさらなる高速移動、あるいは敵に大ダメージを与える方法などが発見されないかぎり、大幅な更新はないでしょう。

スーパーマリオオデッセイにおける1時間の壁

スーパーマリオオデッセイのRTAは1時間切り目前です。現在の世界記録保持者である、Chaospringle氏が1時間0分台に突入してから徐々に記録が縮められていますが、なかなか超えられない状況が続いています。最適な動きを続けられれば1時間切りも可能でしょうが、20秒以上の更新には、新たなルートの発見が必須でしょう。1時間00分台への到達は「壁抜け」が大きく貢献しています。壁抜けによる新ルートの発見も模索されているので、1時間切りは新規ルートによってなされるでしょう。

1時間1分台までは、NicroVeda氏が記録を更新しづけていましたが、壁抜けを利用した新ルートになってからは振るっていないようです。現在のルートではChaospringle氏が1時間切りに一番近いプレイヤーではないでしょうか。

マリオオデッセイは、ステージ毎に所定の数のムーンを集めることで、次のステージへ進めます。最終面に到達するために必要なムーンの総数も決まっています。つまり、ステージをすっ飛ばすことはできないため、大幅な更新はなさそうです。
RTAとしては、短時間で取得できるムーンを効率的なルートで集める必要があります。テンポ良くムーンが取得されていく様はRTAの見所です。基本的には、マップをぐるっと一周してワープ無しでスタート地点に戻ってくるのが最適なルートとなります。ただし、特定のイベントをこなすとスタート地点に戻ってくることもあるので、そちらを利用した方が早いステージもあります。
特定のムーンは取得時にムービーが流れるため避けて通りたいところですが、ゲーム進行に必須なケースがほとんどです。ただし、「最初のムーン」など幾つかのムーンを取得せずに進めるようになりました。

その他のRTA動画とか。

普段は、ニコニコ動画の解説付きRTA動画を見ています。多くのRTAは極まりすぎているので、プレイ済みのゲームであっても、予備知識がないと見所がさっぱりわからないのですよね。その点で、解説動画はうれしいです。

【ロマサガ2 RTA 37:46】SFC実機サブフレームリセット技利用【VOICEROID実況】 - ニコニコ動画 などは、解説を見てもロマサガ2RTAおよび、サブフレームリセットを含むバグ技に精通していないとさっぱりですね。
バグ技を駆使するとある種の儀式めいてきます。最終的に「お祈り」が必要となるのも儀式めいてきます。【バグありRTA】METALMAX2 20:54.00 - ニコニコ動画 などは儀式がすぎます。RTA中に他のゲームのRTA動画を流すってどうなの。バグの詳細は 【TAS】メタルマックス2 3:05【更新】 - ニコニコ動画 なども参考にすると、なんとなく理解できるかと思いますが、それでも意味不明です。
ちなみに、祈祷力に関しては 【ゆっくり】バーニングファイトRTA デューク 19分51秒39 【更新】 - ニコニコ動画 がおすすめ。バーニングファイトに関してはRTA動画ではありませんが、【ゆっくり】バーニングファイト ダフィーバグ考察 - ニコニコ動画 はもっと評価されるべき。

栗城さんの死に対してNHKが無自覚すぎる

2019年1月14日にNHKで、2018年5月21日にエベレストで亡くなった栗城史多さんの追悼番組をやっていたが、NHKがあまりにも無自覚で、ひどい構成であった。

番組では、インターネット上の匿名の批判や期待するファンの声によって、栗城さんが追い込まれたのではないか、と締めくくっていた。そこには、NHKを含むメディアやスポンサーの視点が感じられなかった。NHKは彼をしばし好意的かつ無批判に取り上げてきた。そして、今回の番組でも彼に近しい立場での映像がまとめあげられている。つまり、NHKも彼の支援者である。インターネットの声が彼を追い詰めたのならば、NHKも共犯者であろう。しかし、番組においてNHKはずっと傍観者の立場であり続け、メディアやスポンサーへの内省はまったくみられなかった。

栗城さんの最期の挑戦は無謀というより他にない。エベレストの北壁ルートは非常に難易度が高いとされる。それなのに、さらに難易度の高い単独無酸素に挑んでいた。しかも栗城さんは2012年のシシャパンマ挑戦の際に指に凍傷を追い、翌年の2013年にはその影響で9指を切断している。これを無謀といわず、なんというのか。

栗城さんの登山レベルに関しては、登山ライターである森山憲一氏の文春の記事が的確だろう。森山氏は栗城さんに直接会って、彼の挑戦が如何に無謀かを説いたそうだが、物別れに終わっている。

2010年のインタビューから読み解くと、栗城さんは挑戦が無謀であると説かれるほど燃えるタイプであったようだ。最初の挑戦となるマッキンリーも、山岳部の先輩から何度も諭されている。運良くマッキンリーの登頂に成功したことで、栗城さんは無理だとされる挑戦に打ち勝てるイメージを自分の内にも外にも確立していったように思われる。

2007年頃から、ヒマラヤへの挑戦を目指している。ちょうどその頃、電波少年などで知られる土屋プロデューサーが栗城さんを見出した。ニートでも引きこもりでもないのに、「ニートアルピニスト、初めてのヒマラヤ」なる企画名をつけたのは土屋プロデューサーである。この企画を経ることで、栗城さんは全国的に名が知られるようになった。この企画においてチョ・オユーに登頂したことで、支援者やスポンサーが得られやすくなったであろう。


栗城さんが単独無酸素に拘った理由は、彼の掲げる「冒険の共有」にあるのかもしれない。エベレストであっても、十分な支援を受けてのノーマルルートの登頂は可能であっただろう。ただし、ノーマルルートを目指す人は非常に多い。絵面としては「挑戦感」が薄くなってしまう。誰でも登れる感は、栗城さん自身も支援者も望むものではないだろう。「無酸素」に拘ったのも、実況するためだったのだろうと思われる。指を失ったのも「冒険の共有」のためにカメラを操作するために手袋を外したからだとも言われている。「冒険の共有」のための演出が、彼を無謀な挑戦に向けていたように思われる。

先の森山氏の記事にもあるように2015年以降はその「冒険の共有」もうまく行っていなかったようだ。NHKの番組で流れた、亡くなる直前の栗城さんが、キャンプ地でスタッフに激昂している映像は、彼自身が追い詰められている様に見えた。
栗城さんは指を失った2012年からしばらく挑戦をしていない。2015年に挑戦を再開してからは、森山氏が指摘するようにアンコントロールな状態にあったように思われる。このような状態に至ったのはNHKが指摘するようにインターネットにおける批判も一因だろう。先に挙げたように、栗城さんは批判されればされるほど、無理な挑戦を目指すタイプであるし、支援者やスポンサーはそのような彼に期待をしていた。また「冒険の共有」を標榜する以上、インターネットからの応援も、番組が指摘するように、栗城さんを追い詰めたとも想像できる。
番組は、インターネットの批判者が、あるいはファンが彼を追い詰めたという論調であった。しかし、彼を物理的にかつ金銭的に支援するスポンサーがいなければ、彼は挑戦を続けられない。彼自身が、テレビ的な誇張により無謀とされる困難に挑戦することで自身をプロデュースしていたし、そして周囲もそれを求めていた。そのような彼を後押したのはメディアである。特に、NHKは彼を何度か特集している。これにより、支援者やスポンサーが得やすくなった側面はあるだろう。そのようなNHKが自己を内省することなく、栗城さんの死はインターネットの闇であるかのような構成の番組を放映することが信じられない。


森山氏のように、彼に直接忠告する人はいたが、その声は彼には届かなかったし、むしろ彼を奮い立たせるだけだったのかもしれない。指を失って再挑戦してからは、引くに引けない状況になっていたように思える。
多くの支援者の協力を受けて、単独無酸素でない道もあったのではないかと思う。「冒険の共有」としては、その方が正しいとも思える。しかし、彼が確立していった挑戦者というスタイルが、それを許さなかったのだろう。
インターネットの声が彼を追い詰めたとするならば、メディアや支援者、そしてスポンサーも彼を死に追いやって点を明言するべきであったと思う。

追記 2019年1月17日

ブックマークのコメントにて紹介されていた、かつて栗城さんに同行しドキュメンタリーを制作した方のブログを紹介しておく。
自分の「夢」を人に語るな | チェ・キタラの「隅っこまで照らすな!」

2018年に買って満足したものと残念だったものを3点ずつ

2018年に買って良かったものは、間違いなく Pixel3 XL と Surface GO Advanced LTE なのですが、感想は散々書いたので、詳しくはリンク先をご覧下さい。日傘も良い買い物でした。ただ、失ってしまったので、夏に向けて新しいのを物色するつもりです。

折角なので、レビューを書こうと思って忘れていたものを、満足したもの残念だったもの交えて紹介したいと思います。

買って満足したもの3点

エレコム カメラバッグ ボディバッグ off toco

ガジェットが増えてしまったので、小さいけれども色々入るバッグを探していました。
メインの収納部位には、財布にモバイルバッテリーなどが納められますし、背面にはスマホやUSBケーブル、側面にクレジットカードなどと色々収納できて便利です。

ちょっと残念なのは金具の塗装が直ぐに剥がれてしまったこと。安い塗装をするくらいなら、何も塗らない方がよかったと思います。

Bluetooth Switch コントローラー DinoFire

スプラトゥーン2は Switch の Proコンでプレイしていたのですが、左スティックの調子がすぐに悪くなります。何度か分解修理したのですが、とうとう反応がイマイチになってしまいました。スティックを倒しても動かない、あるいは触っていないのに勝手にキャラが動くなどは対人ゲームでは致命的です。
新しい Proコンを買うにも、恐らく同じ現象が再発するでしょう。安くはない買い物なのでちゅうちょしていました。そこで、非純正品に手を出してみました。
Amazon でいくつかレビューを読み、またアナログスティックが下側にあるコントローラーに決めました。RZ と LZ の遊びが大きすぎるのですが、スプラトゥーン2の場合は連射系のブキでなければ問題ないと感じました。勝率にも変化がないので、いい買い物だったと思います。

Ticwatch E

レビューを書こうと思って忘れていました。ASUS の ZenWatch3 を使用していたのですが、バッテリーが一日持たなくなってきたので購入しました。
Ticwatch E のバッテリーはまぁそこそこに。むしろ、本体が軽いことのの方がメリットが大きかったです。
Wear OS もそれなりに熟れてきました。以前のバージョンは左右にスワイプすると盤面が変更されるという、非常に使い勝手の悪いものでしたが、現在は左にスワイプするとアシスタントが、右にスワイプするとアクティビティが表示されるようになり利便性が向上しました。

SKAGEN の Falster 2 のデザインが気になってはいるのですが、Qualcomm Wear 2100 と最新でないため躊躇しています。Fossil Sport は Wear 3100 なのですが最新チップのためだけに購入するほどではないなと。

残念だったもの3点

AMORNO の左右分離型ワイヤレスイヤホン

完全分離型のワイヤレスイヤホンが欲しくて購入したのですが、2時間程度しか連続再生できないのは耐えられませんでした。また、接触不良のため充電ケースにイヤホンを入れても充電されない不良品に当たったのも心証が悪いです。クレームを入れたら新し商品を送ってきたので、実働時間が倍にはなったのですが、結局 AVIOT TE-D01b に出資してしまいました。

Nintendo Switch対応ワイヤレスイヤホンアダプター「GENKI」

GENKI: Bluetooth Audio for the Nintendo Switch by Human Things — Kickstarter
GENKI
Nintendo Switch をワイヤレスイヤホンで利用したかったので、出資しましたがやはり遅延が気になりました。40 ms の遅れはスプラトゥーンでは致命的でした。
ただし、Nintendo Switch 意外にも利用できるので使い道を見出してあげたい・・・・・・。

スマートリモコン Home Mate

就寝時のエアコンの温度調整などを細かく設定したかったので購入したのですが、設定が反映されないことがままありました。そもそも、エアコンのリモコンが Home Mate に微妙に対応していないので、逐一設定する必要があり面倒です。外出先からエアコンを操作できたりと便利ではあるのですが、家電同士の通信規格が揃ってからの方が便利そうで、ちょっと買う時期がが早かったかなぁとも。
勢いで購入してしまったので、もう少々下調べするべきでした。

AIのおかげで長くつき合えそうなPixel3 XL

Pixel3 XL を使用して一ヶ月が経過したので、改めてレビューでも。メモリ関係以外は非常に満足しています。

Google Payはやっぱり便利ですが、未だに改札口で反応させることができないことがあります。慣れの問題だとは思うのですが、丁度良い位置と角度で読み取り機に当てるのが難しく感じます。

電池の持ちは正直良く分かりません。職場でも家でも使っていないときはワイヤレス充電器に立てかけているので、大体いつも100%に近いのです。外出時もモバイルバッテリーを持っていきますし、有線での充電速度も速いので今のところ電池がなくて困ったことはないです。

メモリ4GBはやはり足りないのでは

最初に大きな不満点を述べるならば、メモリ周りが貧弱なことでしょう。稀に良くスタックします。以前使用していた、HUAWEI P9 ではあまりなかったので残念です。しない時は全然安定しているが故の「稀に良くある」。このスタックは Essential Phone でも稀に頻発するので Android 9 そのものに不具合があるのでしょう。つまり、メモリが 4GB 以上あっても解決しない可能性も考えられます。今後のアップデートに期待したい。

メモリが4GBしかないせいか、Pokemon GO をプレイ中にカメラを立ち上げて、Pokemon GO に戻ると、アプリケーションがほぼ間違いなく再起動されます。これは二台持ちしている Essential Phone で Pokemon GO をプレイして、Pixel3 XL で写真を撮れば解決する問題ではあるのですが、ここにもメモリ不足が見えて残念です。

ただし、メモリが増えたから解決する問題でもないのかもしれません。なにしろ、カメラの処理にハードウェアもソフトウェアも全振りしてるようなので、増えた分だけカメラの処理に喰われそうです。

カメラの満足度が非常に高い

f:id:lastline:20190109152249j:plain

カメラに全振りしてるだけあって、カメラの満足度が非常に高いです。電源カメラを二度押しすればカメラをさっと起動できるで、気軽に写真撮影ができます。ちなみに、長押しすると電源を切るか再起動、もしくはスクリーンショットを撮影できます。また、Google フォトに無制限でアップロードできるので、容量を気にせず撮影できるのも気楽です。

f:id:lastline:20190109152132j:plain
f:id:lastline:20190109152111j:plain
丸の内にある国際展示場の天井を撮影しましたが、結構細かいディティールまで再現されており、2倍程度ならデジタルスームでも劣化も少ないです。

f:id:lastline:20190109151911j:plain
f:id:lastline:20190109151935j:plain

シングルカメラなのにポートレートモードが抜群です。ポートレートモードで撮影しておけば、それなりのスナップ写真が撮れてしまいます。忘年会で写真を撮りまくっていましたが、薄暗い居酒屋でもいい感じの写真になりました。また、人物以外にも適用できるのも使い勝手がいいです。ただし、ソフトウェアによる処理なので、複雑なものに対しては、おかしなボケ具合になります。たとえば、くまもんのランタンの写真では、配線が消えてしまっています。ボケの不具合は iPhone XS でも Mate 20 Pro でも発生するので、現在のスマートフォンの限界でしょう。


f:id:lastline:20190109152501j:plain
f:id:lastline:20190109152516j:plain
夜景モードも素晴らしく、手持ちでも問題なく撮影できます。年末年始はイルミネーションがあちこちにあるので、大活躍でした。スマートフォンの手持ちで、光の筋が写り込むのは、正直ずるいと思います。恐ろしいのが、星空を撮影できる点で、肉眼では見えづらい等級の星の光まで取り込んでいました。

Dxomark は iPhone XR と同じ 101 でしたが、このスコアは夜景モードを加味していません。実際の所は iPhone XR よりは高いんじゃないかなぁと信じたい。

残念なのは、逆光時にレンズ由来の白いゴーストが映り込むシチュエーションが多いことです。逆光自体には強いのですが、夜景モードだとそのゴーストがより強調されるケースがあります。

AIはなにかと役に立つ

Pixel3 では様々なシチュエーションで AI が動いていますが、結構痒いところに手が届く働きをみせてくれます。顕著に気がつくのは、アプリの履歴を表示したとき。アプリの履歴と共に画面下部に AI がお勧めするアプリを挙げてくれるのですが、これが結構当たっています。ホーム画面には必要最低限のアプリのみを配置すれば十分です。

Google アシスタントもさらに使い勝手が良くなりました。特に、本体をギュッと握って起動できるアクティブセンスが便利です。「OK Google」と呼びかけることでも反応しますが、やはり物理的に起動できた方が確実性が高いです。特に、片手で操作したい際に Pixel3 XL を握ってアシスタントを起動し音声で操作できるのが便利です。ただし、若干日本語に最適化されいません。Pixel3 のライトを点灯したい場合は「懐中電灯 を オン」と命令しなければなりません。「ライト」だと、アシスタントと連動する筈のルームライトの制御だと認識しているようです。

検索バーが下に配置されているので、すぐさま検索が可能です。アシスタントの「最近」の項目から検索履歴なども網羅的に閲覧できるのも、使い勝手が良いです。検索しまくっているとフィードに反映され、ニュースや話題を勝手に収集してくれるので、さらに捗るというサイクルが生じます。

検索とGoogleアシスタントの使い分けができるのが地味に便利です。Googleレンズを起動したり、音声で検索したりする場合はギュッと握ればいいですし、テキストベースならば検索バーをタップするだけです。

Pixel Stand のめざましディスプレイですっきり目覚める

Pixel Stand を購入しましたが、満足度が高いです。Pixel Stand ならではの機能がいくつかありますが、「めざましディスプレイ」が特に気に入っています。アラームが鳴る前に Pixel3 の画面がサンライトイエローに光るので、朝日を浴びたような心地で目覚めることができます。

Pixel3 本体を Stand に置くと自動で「マナーモード」に切り替わるようにも設定できますが、この「マナーモード」は日本で一般的に浸透した通知音をならさない「マナーモード」ではなく、ほぼ全ての通知をオフにする機能なので使っていません。代わりに就寝時にはアンビエントモードに切り替えるようにしています。これなら、枕元で時間をチェックできますし、まぶしくもありません。旅先の宿でも利用したい機能です。

ところで、Pixel Stand の設定を変える方法が少々分かりづらいです。Stand を利用していないときは、「設定」の「接続済みの端末」から「以前接続されていたデバイス」から変更できます。少々、深いところにあるので見つけづらいです。

その他の満足したところ

フロントデュアルスピーカーの音も大きく音質も良いので満足しています。YouTubeニコニコ動画を見るときなどに重宝しています。画面の大きな、XL にして良かったと思える瞬間です。

顔認証は画面を見だけで認証されるので楽なのです、冬はマスクをすることが多いので、その他の認証の方が役に立つころがあります。また、ずっと背面指紋認証の端末をつかってきたので、こちらの方が慣れています。個人的には、机の上に置いて使うのでなければ背面の方が便利だと思います。また、背面指紋認証で通知を呼び出せるのも地味に助かります。

Bluetoothの接続が良くなったのはうれしい限りです。HUAWEI は強力なバッテリーセーバーが動いているのですが、そのせいか Bluetooth の接続が安定しません。知らない間にスマートウォッチとの接続が切れていたり、Pokemon GO plus との接続がうまくいかなかったりしていました。Pixel3 では快適に利用できています。

AIのおかげで長く付き合えそう

Pixel3 と Mate 20 Pro で悩んだ末、Pixel3 にしましたが、Essential Phone で体験した Android 9 の挙動が気に入ったからってのは大きいです。

カメラ以外にも、Googleアシスタントやスマートバッテリーなど、AIのおかげで利便性がどんどん高まっていくのが、Pixel3 の一番いいところだと思います。
Google フォトで収集されたデータが、画像検索やGoogleレンズに使われていると考えると、Google Homeのおかでてアシスタントの性能がグングンあがりそうです。Googleアカウントにどっぷり使っている人なら、特にお勧めのスマートフォンです。
英語版ではすでに公開されている電話の自動対応も早く日本語に対応して欲しいですね。