AIを使ってアンパンマンの正体を探る

AI

アンパンマンは何者?

日本国民であれば誰もが知っているであろうあの人気キャラクター。

しかし、年齢などその素性はよくわかりませんね。

今回はそんな彼の正体を暴いてみました。

どうやって?

今回の調査にあたってNTTグループが開発している自然言語処理技術である、 COTOHA API を利用しました。COTOHA APIの ユーザ属性推定(β) では文章から年代や職業などの属性を分析することができます。このAPIをりようすることでアンパンマンの真の姿が見えてきそうです。

また、アンパンマンの名言を集めたこちらのサイトから、アンパンマンの発言をランダムに10件集め解析対象の文章としました。

名言リスト

  1. あきらめるもんか!最後まで頑張るんだ
  2. みんなが僕に勇気を、優しさをくれる
  3. 僕の強さは、僕だけのものじゃないんだよ
  4. みんなは僕が守る!守るために戦うんだ!!
  5. ドーリィちゃん、君は僕の中で生きているんだ。ずっとずーっと、一緒に
  6. 大丈夫だよ。みんなの胸に“こころの星”の光がある限り、この世界は輝き続ける
  7. 泣いている人、困っている人、お腹がすいた人、みんな僕の顔を食べると、ニコッと笑顔になるんだ。その笑顔を見るとね、嬉しくて僕も自然に笑顔になる。そしてね、ここ(胸)がとってもあたたかくなるんだ
  8. 高価な物でも心がこもっていないと貰った人は淋しいですもんね
  9. 困っている人を助けた時に、こころがあたたかくなって、そのときわかったんだ。僕が何のために生まれてきたのか、何をして生きていくか、何が僕の幸せかって
  10. 心で聴くんです。ジャムおじさんが言っていました。心で見て、心で聴けば、見えない本当のことがみえてくるんだって

やってみる

ソースコード

今回利用したクエリはこちらを参考にしています。


# reference https://qiita.com/gossy5454/items/83072418fb0c5f3e269f
import os
import urllib.request
import json
import configparser
import codecs
# COTOHA API操作用クラス
class CotohaApi:
    # 初期化
    def __init__(self, client_id, client_secret, developer_api_base_url, access_token_publish_url):
        self.client_id = client_id
        self.client_secret = client_secret
        self.developer_api_base_url = developer_api_base_url
        self.access_token_publish_url = access_token_publish_url
        self.getAccessToken()
    # アクセストークン取得
    def getAccessToken(self):
        # アクセストークン取得URL指定
        url = self.access_token_publish_url
        # ヘッダ指定
        headers={
            "Content-Type": "application/json;charset=UTF-8"
        }
        # リクエストボディ指定
        data = {
            "grantType": "client_credentials",
            "clientId": self.client_id,
            "clientSecret": self.client_secret
        }
        # リクエストボディ指定をJSONにエンコード
        data = json.dumps(data).encode()
        # リクエスト生成
        req = urllib.request.Request(url, data, headers)
        # リクエストを送信し、レスポンスを受信
        res = urllib.request.urlopen(req)
        # レスポンスボディ取得
        res_body = res.read()
        # レスポンスボディをJSONからデコード
        res_body = json.loads(res_body)
        # レスポンスボディからアクセストークンを取得
        self.access_token = res_body["access_token"]
    # ユーザ属性推定API
    def userAttribute(self, document):
        # ユーザ属性推定API URL指定
        url = self.developer_api_base_url + "nlp/beta/user_attribute"
        # ヘッダ指定
        headers={
            "Authorization": "Bearer " + self.access_token,
            "Content-Type": "application/json;charset=UTF-8",
        }
        # リクエストボディ指定
        data = {
            "document": document
        }
        # リクエストボディ指定をJSONにエンコード
        data = json.dumps(data).encode()
        # リクエスト生成
        req = urllib.request.Request(url, data, headers)
        # リクエストを送信し、レスポンスを受信
        try:
            res = urllib.request.urlopen(req)
        # リクエストでエラーが発生した場合の処理
        except urllib.request.HTTPError as e:
            # ステータスコードが401 Unauthorizedならアクセストークンを取得し直して再リクエスト
            if e.code == 401:
                print ("get access token")
                self.access_token = getAccessToken(self.client_id, self.client_secret)
                headers["Authorization"] = "Bearer " + self.access_token
                req = urllib.request.Request(url, data, headers)
                res = urllib.request.urlopen(req)
            # 401以外のエラーなら原因を表示
            else:
                print ("<Error> " + e.reason)
        # レスポンスボディ取得
        res_body = res.read()
        # レスポンスボディをJSONからデコード
        res_body = json.loads(res_body)
        # レスポンスボディから解析結果を取得
        return res_body
if __name__ == '__main__':
    # ソースファイルの場所取得
    APP_ROOT = os.path.dirname(os.path.abspath( __file__)) + "/"
    # 設定値取得
    config = configparser.ConfigParser()
    config.read(APP_ROOT + "config.ini")
    CLIENT_ID = config.get("COTOHA API", "Developer Client id")
    CLIENT_SECRET = config.get("COTOHA API", "Developer Client secret")
    DEVELOPER_API_BASE_URL = config.get("COTOHA API", "Developer API Base URL")
    ACCESS_TOKEN_PUBLISH_URL = config.get("COTOHA API", "Access Token Publish URL")
    # COTOHA APIインスタンス生成
    cotoha_api = CotohaApi(CLIENT_ID, CLIENT_SECRET, DEVELOPER_API_BASE_URL, ACCESS_TOKEN_PUBLISH_URL)
    # 解析対象文
    sentence = "みんなが僕に勇気を、優しさをくれる"
    # API実行
    result = cotoha_api.userAttribute(sentence)
    # 出力結果を見やすく整形
    result_formated = json.dumps(result, indent=4, separators=(',', ': '))
    print (codecs.decode(result_formated, 'unicode-escape'))

レスポンス

以下のようなレスポンスが返ってきます。詳細は公式のAPIリファレンスをご参考ください。

今回はこの中からage、hobby、location、occupationを集計することにしました。

{
  "result" : {
    "age" : "40-49歳",
    "civilstatus" : "既婚",
    "earnings" : "不明",
    "gender" : "不明",
    "habit" : [ "ALCOHOL" ],
    "hobby" : [ "ANIMAL", "COOKING", "FISHING", "FORTUNE", "GAMBLE", "GRUME", "GYM", "INTERNET", "MOVIE", "PAINT", "SHOPPING", "STUDY" ],
    "kind_of_business" : "不明",
    "kind_of_occupation" : "不明",
    "location" : "不明",
    "moving" : [ "RAILWAY" ],
    "occupation" : "会社員",
    "position" : "不明"
  },
  "status" : 0,
  "message" : "OK"
}

結果

文章ごとの結果

1. あきらめるもんか!最後まで頑張るんだ

{
    "result": {
        "age": "20-29歳",
        "civilstatus": "未婚",
        "earnings": "-1M",
        "hobby": [
            "GOURMET",
            "INTERNET",
            "TRAVEL"
        ],
        "location": "関東",
        "occupation": "会社員"
    },
    "status": 0,
    "message": "OK"
}

2. みんなが僕に勇気を、優しさをくれる

{
    "result": {
        "age": "20-29歳",
        "earnings": "-1M",
        "gender": "男性",
        "hobby": [
            "INTERNET",
            "MOVIE",
            "MUSIC"
        ],
        "location": "関東",
        "moving": [
            "RAILWAY"
        ],
        "occupation": "会社員"
    },
    "status": 0,
    "message": "OK"
}

3. 僕の強さは、僕だけのものじゃないんだよ

{
    "result": {
        "age": "20-29歳",
        "civilstatus": "既婚",
        "earnings": "-1M",
        "gender": "男性",
        "hobby": [
            "TVGAME"
        ],
        "location": "関東",
        "moving": [
            "RAILWAY",
            "WALKING"
        ],
        "occupation": "会社員"
    },
    "status": 0,
    "message": "OK"
}

4. みんなは僕が守る!守るために戦うんだ!!

④みんなは僕が守る!守るために戦うんだ!!
{
    "result": {
        "age": "40-49歳",
        "civilstatus": "未婚",
        "earnings": "-1M",
        "gender": "男性",
        "hobby": [
            "GOURMET",
            "INTERNET",
            "TRAVEL"
        ],
        "location": "関東",
        "occupation": "会社員"
    },
    "status": 0,
    "message": "OK"
}

5. ドーリィちゃん、君は僕の中で生きているんだ。ずっとずーっと、一緒に

{
    "result": {
        "age": "40-49歳",
        "civilstatus": "未婚",
        "earnings": "-1M",
        "gender": "男性",
        "hobby": [
            "INTERNET",
            "MOVIE"
        ],
        "location": "関東",
        "moving": [
            "WALKING"
        ],
        "occupation": "会社員"
    },
    "status": 0,
    "message": "OK"
}

6. 大丈夫だよ。みんなの胸に“こころの星”の光がある限り、この世界は輝き続ける

{
    "result": {
        "age": "20-29歳",
        "earnings": "-1M",
        "hobby": [
            "INTERNET",
            "TRAVEL"
        ],
        "location": "関東",
        "moving": [
            "WALKING"
        ],
        "occupation": "会社員"
    },
    "status": 0,
    "message": "OK"
}

7. 泣いている人、困っている人、お腹がすいた人、みんな僕の顔を食べると、ニコッと笑顔になるんだ。その笑顔を見るとね、嬉しくて僕も自然に笑顔になる。そしてね、ここ(胸)がとってもあたたかくなるんだ

{
    "result": {
        "age": "20-29歳",
        "civilstatus": "未婚",
        "gender": "男性",
        "hobby": [
            "ANIMAL",
            "CAMERA",
            "COOKING",
            "FORTUNE",
            "GAMBLE",
            "GYM",
            "IDOL",
            "INTERNET",
            "SMARTPHONE_GAME",
            "MOVIE",
            "TVCOMMEDY"
        ],
        "kind_of_occupation": "研究開発職",
        "location": "近畿",
        "moving": [
            "RAILWAY",
            "WALKING"
        ],
        "occupation": "会社員"
    },
    "status": 0,
    "message": "OK"
}

8. 高価な物でも心がこもっていないと貰った人は淋しいですもんね

{
    "result": {
        "age": "40-49歳",
        "earnings": "-1M",
        "hobby": [
            "INTERNET",
            "MOVIE",
            "SHOPPING"
        ],
        "location": "関東",
        "occupation": "会社員"
    },
    "status": 0,
    "message": "OK"
}

9. 困っている人を助けた時に、こころがあたたかくなって、そのときわかったんだ。僕が何のために生まれてきたのか、何をして生きていくか、何が僕の幸せかって

{
    "result": {
        "age": "20-29歳",
        "civilstatus": "未婚",
        "earnings": "3M-5M",
        "gender": "男性",
        "hobby": [
            "INTERNET",
            "MOVIE"
        ],
        "location": "近畿",
        "moving": [
            "WALKING"
        ],
        "occupation": "会社員"
    },
    "status": 0,
    "message": "OK"
}

10. 心で聴くんです。ジャムおじさんが言っていました。心で見て、心で聴けば、見えない本当のことがみえてくるんだって

{
    "result": {
        "age": "40-49歳",
        "civilstatus": "既婚",
        "hobby": [
            "COOKING"
        ],
        "location": "関東",
        "occupation": "会社員"
    },
    "status": 0,
    "message": "OK"
}

集計

大項目小項目出現回数
年齢20代6回
40代4回
職業会社員10回
出身地関東8回
近畿2回
趣味料理2回
グルメ2回
映画5回
インターネット8回
旅行3回
買い物1回
動物1回
映画1回
占い1回
ギャンブル1回
ジム1回
アイドル1回
テレビコメディ1回
スマホゲーム1回

趣味はインターネットや映画が多く、意外とインドア派なんですね。パトロールは仕事ですから、仕事終わったらネットサーフィンとかネットフリックスを見ているのかもしれません。

まとめ

アンパンマンは20代で関東出身のパン工場勤務の会社員、趣味はインターネット


年齢は20代が多かったですが、40代も見られました。30代はありませんでした。

どのようにして年齢を判断しているのでしょうか?文章中のワードによって年齢を判断している可能性はあります。

また、location(出身地)は方言を使うとその地方になりそうですね。

職業はどのように判断するのでしょうか?今回はすべて会社員でした。謎です。

次回は、若者言葉や方言を使って、意図したとおりの結果になるか試したいです。

広告

フリーランスエンジニアを目指すあなたに!

サポートが充実したコミュニティと仕事をご用意【Freeto】

・これからフリーランスに転向したいと考えている方
・フリーランスとして働いているが報酬や仕事内容に満足していない方
・自分の実力をより発揮できる仕事がしたい方

一人では解決できないこともあるのではないでしょうか。
安定した仕事から将来のキャリアプランまで、
フリーランスの方の一生涯をサポートしていきます。

フリーランス同士のコミュニティの場、Freetoはこちら

アフェリエイトを始めたいあなたに!

A8.netなら!

◇スマートフォンやPCから簡単に広告が掲載可能

◇もちろん会員登録は無料。その後も費用はかかりません!

◇欲しい商品がお得に購入できるセルフバックの利用ができる

◇有名ブランドから高額報酬がもらえる広告を掲載
登録はこちら 

FXに興味があるあなたに!

◆◇DMM FXは国内口座数第1位!!!◇◆
※2019年1月末時点。ファイナンス・マグネイト社調べ(2019年1月口座数調査報告書)
口座開設キャンペーン!【20,000円キャッシュバック】

口座開設はこちら

コメント

タイトルとURLをコピーしました