いささか旧聞ですが「ライトノベルのタイトルが長文化しているのではないか?」という話題がありました
Web小説投稿サイトである小説家になろうは、最近作品がいくつも書籍化されて話題になっています
Web小説もライトノベルからも大きな影響を受けていると考えられるので、同様にタイトルの文字数の増加が起きているのではないかと思って調べてみました
データの収集方法
小説家になろうでは以下のようなAPIが公開されていて、本文などを除いた一部の情報については簡単に取得することができます
例えば次のURLにアクセスするとその下のような結果が帰ってきます
--- - allcount: 194835 - title: 異世界迷宮で奴隷ハーレムを - title: '無職転生 - 異世界行ったら本気だす -' - title: 理想のヒモ生活 - title: こちら討伐クエスト斡旋窓口 - title: > この世界がゲームだと俺だけが知っている
これを利用して各年ごとの作品のデータを取得したいのですが、一つ大きな問題があります。
このAPIでは検索条件に最初の投稿日時を含めることができません
日時関係で指定できるのは最終更新日時だけです
しょうがないので近似的にデータを集めました。
具体的には各年ごとに、最終更新日時がその年の範囲に含まれる作品の中から人気順に取り出してきたもの最大2000件をAPIでとってきて全体のデータセットとしました
データセットの詳細
APIを使って収集した結果、17557件のデータが得られました
それぞれの作品についてタイトルと最初の投稿日時を取得しました。
最初の投稿年ごとのデータ数は以下のようになっています
このグラフを見ると、2004、2005、2013年が相対的に少ないデータしか集められていないことがわかります。
なので、これらの年についての分析結果は少し信頼性が低いかもしれません
タイトルの文字数の分析
例として2012年のタイトルの長さの分布を示します
タイトルの文字数についてはサブタイトルやカッコの有無などは考慮せず、その全体の文字を数えました
10文字弱あたりにピークがある、右に裾の長い分布であることがわかります
それぞれの年の分布を比較するために、文字数を1-5, 6-10, 11-15, 16-20, 21- の5区分に分けて、年ごとにその割合を調べてみました
以下のグラフを見ると、1-5文字のタイトルが減って、16文字以上のタイトルが増え続けているのがよくわかると思います
またそれぞれの年のタイトルの文字数の平均値は次のように年々増え続けています
以上の結果を見ると、小説家になろうの作品タイトルも長文化傾向にあるといえるでしょう
このままのペースで増え続けたらすごいことになりますね
長文タイトルトップ5
タイトルの長さ上位5件を以下に例示しておきます
- 82文字 『グズな国じゃの! ここではだね、同じ場所にとどまるだけで、もう必死で走らなきゃいけないんだよ。そしてどっかよそに行くつもりなら、せめてその倍の速さで走らないとね! 』
- 73文字 『AETERNA~It is an amrit and it is those who recover about invulnerability~』
- 72文字 『トラックが突っ込んできて高校生男子が死ぬが自称神の老人が出てきて「自分のミスで云々」で異世界に送ってくれることになるという斬新な展開から始まる話』
- 67文字 『剣、魔法、そしてアサルトライフル ~~転生させくれるんなら、もうちょいチートにしてくれたっていいだろォがァァァァァァァァァァ!!!~~』
- 66文字 『a person with preternatural power in the magic world~~超能力者魔法の世界へ~~』
ソースコードと収集したデータ
作品名と初投稿日時のデータを収集するスクリプトです
import urllib2 import gzip import json import StringIO import urllib class NarouAPIWrapper(object): def __init__(self, URL='http://api.syosetu.com/novelapi/api/', **default_parameter): self.URL = URL self.default_parameter = default_parameter.copy() def isGzipEnabled(self, parameter): return 'gzip' in parameter and 1 <= parameter['gzip'] <= 5 def decompressGzipString(self, string): strIO = StringIO.StringIO(string) return gzip.GzipFile(fileobj=strIO).read() def encodeQuery(self, parameter): return urllib.urlencode({k: v.encode('utf-8') if isinstance(v, unicode) else v for k, v in parameter.iteritems()}) def requestAPI(self, urlencoded_query): res = urllib2.urlopen(self.URL + '?' + urlencoded_query) return res.read() def get(self, **parameter): temp_parameter = self.default_parameter.copy() temp_parameter.update(parameter) query = self.encodeQuery(temp_parameter) result = self.requestAPI(query) if self.isGzipEnabled(temp_parameter): result = self.decompressGzipString(result) return result if __name__ == "__main__": import datetime import time import collections import numpy date = collections.Counter() length = collections.defaultdict(list) t = NarouAPIWrapper(gzip=5, out='json', lim=200, order='favnovelcnt', of='t-gf') titles = [] for year in xrange(2004, 2014): for i in xrange(10): time.sleep(1) start = int(time.mktime(datetime.datetime(year, 1, 1, 0, 0, 0).timetuple())) end = int(time.mktime(datetime.datetime(year, 12, 31, 23, 59, 59).timetuple())) js = json.loads(t.get(st=1 + i * 200, lastup='{}-{}'.format(start, end))) for item in js: if u'title' in item: print item['title'].encode('utf-8', 'ignore'), item['general_firstup'].encode('utf-8', 'ignore')