幸せ戦闘力を計測するAWS×LINE Bot で作ってみた
はじめに
開発に至るまでの経緯
実際に作ろうか否かの話は今年、2021年4月にありました。
ことの発端はこちらの記事です。
作ろうと思いましたが当時はLINE Bot の知見がなく作るにもどこから作れば良いか分かりませんでした。
ですが、今年はCloudTech と LINE Developers とのコラボイベントを2回開催して
その中でLINE Botの作り方をおおむね理解できたのでそれじゃあ挑戦してみようという風になったわけです。
ちなみに今回のLINE Botは実際に友達の結婚式があるということもあり
タイミングも良かったので作ってみたということもあります。(むしろ、これが主な要因?)
何を作ったか - 2行で説明
Amazon Rekognition(AWSのサービス)で表情を分析して
表情から幸せ度合いを測定するLINE Botを作りました。
完成品の動作
戦闘力の度合い
れい先生 >>>>>>>>>>>> 超えられない壁 >>>>>>>>>>>> 山田 > 犬 > 猫
ちなみに顔と認識されない画像については顔を認識できないので「顔がありません!」と表示します。
具体的な作り方と利用サービスの説明は以下
Amazon Rekognitionとは
機械学習を使用して画像と動画の分析を自動化する
要するに機械的に画像や動画を分析して分析結果を返すというスグレモノ
今回はこのAmazon Rekognitionの機能のうち表情判定を利用
さっそく作ってみる
LINE のアカウントで MessagingAPI の Bot を作成
ログイン
LINE Developer Console にログインします。
「LINE アカウントにログイン」をクリック
LINE のユーザ ID とパスワードを入力して「ログイン」をクリック
※既にログイン済みの方は以下のように表示されます。例
プロバイダの作成
ログインに成功しましたら「プロバイダ」を作成します。
作成をクリック
新規のプロバイダ名には「cloud_tech」と入力して作成をクリック
作成が完了すると以下の画面に遷移するので「Messaging API 」をクリック
新規チャネルの作成
プロバイダの管理画面から「Messaging API 」をクリック 後はチャネルを作成します。
チャネルは以下のように設定します。
設定項目 | 値 |
---|---|
チャネルの種類 | Messaging API |
プロバイダー | cloud_tech |
チャネル名 | marriage-bot |
チャネルの説明 | ハピネススカウター!! |
大業種 | ウェブサービス |
小業種 | ウェブサービス(その他) |
規約同意にチェックを入れて「作成」をクリック
作成内容を聞かれるので確認して「OK」をクリック
情報利用に関する同意について聞かれるので「同意する」をクリック
※「同意する」をクリック後にサーバエラーが出る場合がありましたが、私の場合はチャネル名に「LINE」という文字を入れていた為エラーが出てしまいました。他の名前を入力することで解決しました。
チャネルが完成すると画面遷移して以下の画面が表示されます。
「チャネルアクセストークン」をコピー
外部から LINE を操作する為の「チャネルアクセストークン」を発行します。
「Messaging API 設定」をクリック
発行ボタンをクリック
長い文字列が表示されるので長い文字列のすぐ右にあるコピーボタンをクリック
チャネルアクセストークンをメモ帳に貼り付け
応答メッセージと挨拶メッセージをオフにする
Messaging API には友達追加時やメッセージを送ったときにメッセージを返信するという機能があります。
この機能は今回利用しないのでオフにします。
「Messaging API 設定」から「編集」をクリック
するとLINE Official Account Manager の画面に遷移
デフォルトでは以下のようにオンになっていますので
それぞれオフにしましょう。
オフにできましたらLINE Official Account Manager の画面 の画面を閉じます。
LINE Developers の画面で画面を更新して応答メッセージとあいさつメッセージが無効になっていることを確認しましょう。
ここまでで一旦、LINE側の準備は完了です。API GatewayでAPIのエンドポイントを作成した後に
LINE Bot の設定にWebhookの設定を行う必要がある為、LINE Developersの画面は閉じないでおきましょう。
AWS の構成
構成図
少々複雑に見えるかもしれませんが以下の構成図が今回のLINE Botの構成です。
事前準備
コマンドを実行して必要なファイルをローカルにコピーします。
git clone https://github.com/ymd65536/happiness_scouter.git
cd marriage-bot
python -m pip install LINE-bot-sdk -t .
cd ..
cd reko_api
python -m pip install LINE-bot-sdk -t .
圧縮に成功したらmarriage-bot.zip
として保存します。
reko_api フォルダを圧縮します。こちらも全選択で圧縮して保存します。圧縮後の名前はreko_api.zip
となるようにしてください。
圧縮時にフォルダの階層を二重にしないところがポイントです。
NGな例
reko_api.zip
|- reko_api
|- reko_api
|- lambda_function.py
画像を受信する機能を構成する
受信用Lambda - S3バケットの作成
バケット名が marry-bot-image
となるようにS3バケットを作成する。
S3のバケット名は全世界でユニークである必要がある為、オリジナルの名前を付けるようにしてください。
なお、このバケット名は受信用Lambdaの作成時に環境変数に入れて利用しますのでどこかに記録しておいてください。
AWSマネジメントコンソールからS3 マネジメントコンソール を開きます。バケット作成をクリック
以下のように設定します。
最後に作成をクリック
受信用Lambda - DynamoDBテーブルの作成
LINE からメッセージを保存するテーブルの名前がLineMessages
となるようにDynamoDBでテーブルを作成します。
DynamoDB テーブルに以下のようなKey-Value 形式のデータが入る想定です。
※自身のユーザIDなど機密情報が含まれている為、一部伏せています。
{
"image_id": "15197815743669",
"user_id": "<画像送り主のユーザID>",
"destination": "<Destination>",
"events": [
{
"mode": "active",
"replyToken": "<reply token>",
"source": {
"type": "user",
"userId": "<画像送り主のユーザID>"
},
"type": "message",
"message": {
"type": "image",
"contentProvider": {
"type": "line"
},
"id": "15197815743669"
},
"timestamp": 1638707995302
}
]
}
AWSマネジメントコンソールからAmazon DynamoDB マネジメントコンソールを開きます。
テーブルの作成をクリック
以下のように設定してください。
パーティションキー:image_id
ソートキー:user_id
ここはデフォルト設定で問題ありません。
キー:bot
バリュー:db
受信用Lambda - IAMポリシーの作成
以下のポリシーを満たすIAMポリシー、marriage-bot-iam
を作成する為
AWSマネジメントコンソールからIAM マネジメントコンソールを開きます。
今回利用するポリシーは主に3つです。
- S3 PutObject
- CloudWatch logs (PutLogEvents)
- DynamoDB PutItem
Lambdaの関数名はmarriage-bot
としました。
※XXXXXXXXXXX はご自身のAWSアカウントIDに置き換えてください。
ちなみにDynamoDBのテーブル名はLineMessages
としています。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::marry-bot-image/*"
},
{
"Effect": "Allow",
"Action": "logs:CreateLogGroup",
"Resource": "arn:aws:logs:ap-northeast-1:XXXXXXXXXXX:*"
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": [
"arn:aws:logs:ap-northeast-1:XXXXXXXXXXX:log-group:/aws/lambda/marriage-bot:*"
]
},
{
"Effect": "Allow",
"Action": "dynamodb:PutItem",
"Resource":"arn:aws:dynamodb:ap-northeast-1:XXXXXXXXXXX:table/LineMessages"
}
]
}
ポリシーをクリック
ポリシーを作成をクリック
既に記載されているJSONを削除して作成したIAMポリシーをコピペします。
コピペが終わり、エラーが無ければ次のステップへ
キーとバリューを入力します。
キー:bot
値:iam
受信用Lambda - IAMロールの作成
続いてIAMポリシーからIAMロールを定義する。
IAM マネジメントコンソールからロールをクリック
ロールを作成をクリック
AWSサービスを指定して一般的なユースケースからLambda を選択
次のステップをクリック
先ほど作成したIAMポリシーにチェック
次へをクリック
受信用Lambdaの作成
Lambda のダッシュボードから関数の作成をクリック
既存のロールmarriage-bot-role
を利用したLambda関数marriage-bot
を作成します。
基本的な情報は以下のように設定してください。
項目 | 値 |
---|---|
関数名 | marriage-bot |
ランタイム | Python3.9 |
アーキテクチャ | x86 |
実行ロール | 既存のロールを使用する |
既存のロール | marriage-bot-role |
詳細設定にある二つのチェックボックスが外れていることを確認して関数の作成をクリックします。
事前準備で作成したzipファイルをアップロードします。
アップロード元をクリックしてmarriage-bot.zip
を指定後
保存をクリックしてアップロードします。
次にLambda内で利用する環境変数を定義します。
設定から環境変数をクリック
編集をクリック
このLambda 関数で定義する環境変数
変数名 | 値 |
---|---|
S3_BUCKET_NAME | marry-bot-image |
LINE_CHANNEL_ACCESS_TOKEN | LINE Developers Console からコピーしたトークン |
DYNAMODB_TABLE_NAME | LineMessages |
最後にタイムアウト時間が15秒となるようにLambdaの一般設定からタイムアウト秒を設定します。
API Gateway の作成
Lambda関数marriage-bot
をWeb APIとして利用できるよう
APIエンドポイントURLを作成します。
AWS マネジメント コンソールからAPI Gateway を開き
APIタイプからプライベートではないほうのREST APIを構築します。
構築をクリック
プロトコルの選択して新しいAPIを作成します。
新しいAPIおよび名前と説明は以下のように設定してください。
API名:marriage
説明:貴様の幸せ戦闘力を数えろ!
エンドポイントタイプ:リージョン
Messaging APIのWebhook から利用できるようにエンドポイントを作成します。
まずはメソッドを作成する為にアクションからメソッドの作成をクリック
プルダウンからPOSTを選択
POSTリクエスト時に起動するLambda関数がmarriage-bot になるように設定します。
POSTリクエストの設定は以下のように設定してください。
項目 | 値 |
---|---|
統合タイプ | Lambda関数 |
Lambdaプロキシの利用 | チェックを入れる |
Lambdaリージョン | ap-northeast-1 |
Lambda関数 | marriage-bot |
デフォルトタイムアウトの使用 | チェックを入れる |
保存をクリックするとLambdaに権限を追加するか聞かれるのでOKをクリック
次にAPI GatewayのエンドポイントURLをMessagingAPIで利用できるようにAPIをデプロイします。
デプロイされるステージ名を新しいステージ名に設定します。
他の項目は以下のように設定してください。
項目 | 値 |
---|---|
ステージ名 | bot |
ステージの説明 | 貴様の幸せ戦闘力を数えろ |
デプロイメントの説明 | ハピネススカウター |
設定が終わりましたらデプロイをクリック
画面が遷移してURLの呼び出しが現れますので最後にをURLをコピーしてメモしておきます。
API GatewayのURLをLINE の Webhookに登録
先ほどコピーしたAPI Gateway で作成したエンドポイントURLをMessagingAPIのWebhookにコピーします。
LINE Developers Console に戻ってWebhook を設定します。編集をクリック
API Gateway で作成したエンドポイントURL を貼り付けて更新をクリック
画面上に反映されましたら検証をクリックして疎通を確認します。
問題無ければ、成功というダイアログが表示されます。OKをクリック
画像処理の結果を返す機能を構成する
返信用DynamoDBテーブルの作成
Amazon Rekognition のデータを保存できるようにDynamoDBでテーブル、RekoEmotions
を作成します。
DynamoDB テーブルに以下のようなKey-Value 形式のデータが入ります。
※自身のユーザIDなど機密情報が含まれている為、一部伏せています。
{
"object_id": "<image_id>_<画像送り主のユーザID>.jpg",
"SAD": "38.500",
"HAPPY": "549466.500",
"DISGUSTED": "66.000",
"CONFUSED": "132.000",
"CALM": "22.000",
"user_name": "Kento.Yamada",
"ANGRY": "55.000",
"FEAR": "104.500",
"SURPRISED": "110.000"
}
AWSマネジメントコンソールからAmazon DynamoDB マネジメントコンソールを開きます。テーブルの作成をクリック
以下のように設定してください。
テーブル名:LineMessages
パーティションキー:image_id
ソートキー:空白のままでOK
設定:デフォルト設定
返信用LambdaのIAMポリシーの作成
以下のポリシーを満たすIAMポリシー、reko-api-iam
を作成する為
AWSマネジメントコンソールからIAM マネジメントコンソールを開きます。
利用ポリシーは主に3つ
- S3 GetObject
- CloudWatch logs (PutLogEvents)
- DynamoDB PutItem
- Amazon Rekognition
Lambdaの関数名はreko_api
としました。
※XXXXXXXXXXX はご自身のAWSアカウントIDに置き換えてください。
※S3バケット名はmarry-bot-image
としていますが、世界で一意である必要がある為、ご自身の環境で読み替えてください。
DynamoDBのテーブル名はRekoEmotions
としています。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "dynamodb:PutItem",
"Resource": "arn:aws:dynamodb:ap-northeast-1:XXXXXXXXXXX:table/RekoEmotions"
},
{
"Sid": "GetImagesMetadata",
"Effect": "Allow",
"Action": [
"s3:GetObject"
],
"Resource": "arn:aws:s3:::marry-bot-image/*"
},
{
"Effect": "Allow",
"Action": [
"rekognition:DetectFaces"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": "logs:CreateLogGroup",
"Resource": "arn:aws:logs:ap-northeast-1:XXXXXXXXXXX:*"
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": [
"arn:aws:logs:ap-northeast-1:XXXXXXXXXXX:log-group:/aws/lambda/reko_api:*"
]
}
]
}
既に記載されているJSONを削除して作成したIAMポリシーをコピペします。
コピペが終わり、エラーが無ければ次のステップへ
ポリシーの確認画面で名前と説明を入力してポリシーの作成をクリック
返信用LambdaのIAMロールの作成
続いてIAMポリシーからIAMロール、reko-api-role
を定義する。
IAM マネジメントコンソールからロールをクリックしてロールを作成をクリック
AWSサービスを指定して一般的なユースケースからLambda を選択
次のステップをクリック
検索ボックスでポリシーを検索
先ほど作成したIAMポリシーにチェック
次のステップをクリック
返信用Lambdaの作成
Lambda のダッシュボードから関数の作成をクリック
既存のロールreko-api-role
を利用したLambda関数reko_api
を作成します。
基本的な情報は以下のように設定してください。
項目 | 値 |
---|---|
関数名 | reko_api |
ランタイム | Python3.9 |
アーキテクチャ | x86 |
実行ロール | 既存のロールを使用する |
既存のロール | reko-api-role |
詳細設定にある二つのチェックボックスが外れていることを確認して関数の作成をクリックします。
事前準備で作成したzipファイルをアップロードします。
アップロード元をクリックしてreko_api.zip
を指定後
保存をクリックしてアップロードします。
次にLambda内で利用する環境変数を定義します。
設定から環境変数をクリック
次にLambda内で利用する環境変数を定義します。
設定から環境変数をクリック後、編集をクリック
変数名 | 値 |
---|---|
S3_BUCKET_NAME | marry-bot-image |
LINE_CHANNEL_ACCESS_TOKEN | LINE Developers Console からコピーしたトークン |
DYNAMODB_TABLE_NAME | LineMessages |
環境変数の追加をクリックして3つの環境変数を定義します。
変数名 | 値 |
---|---|
IMAGE_URL | 幸せ戦闘力が50万を超えたときに表示する画像 |
LINE_CHANNEL_ACCESS_TOKEN | LINE Developers Console からコピーしたトークン |
DYNAMODB_TABLE_NAME | RekoEmotions |
最後にタイムアウト時間が15秒となるようにLambdaの一般設定からタイムアウト秒を設定します。
一般設定をクリック後、編集をクリック
S3イベントを設定
返信用LambdaにはS3のバケットに画像がPUTされたら発火するようにトリガーをセットします。
関数の概要が表示されるので関数の概要をクリックしてトリガーを追加をクリック
バケット名、イベントタイプ、プレフィックス、サフィックスを以下のように設定してください。
項目 | 値 |
---|---|
バケット名 | marrige-bucket |
イベントタイプ | PUT |
プレフィックス | 空白のまま |
サフィックス | 空白のまま |
最後に追加をクリック
返信時の流れ - ざっと
- LINEを経由して特定のS3バケットに画像がPUTされる
- ユーザID、オブジェクトID、LINEのメッセージをDynamoDBに保存
- 返信用Lambda が発火
- S3バケットに入った画像のメタ情報を取り出す
- Amazon Rekognition 起動
- 画像処理を実行
- 処理結果をJSONで取得
- データを加工
- FlexMessageで返信
- 処理結果をDynamoDBに保存
反省点
受信用DynamoDBのパーティションの切り方
パーティションを切る時にimage_idでパーティションを切ってしまうと
ソートキーの意味がなくなってしまうので受信用DynamoDBのソートキーとパーティションキーは逆にすべきだった。
返信用DynamoDBのパーティションの切り方
Rekognition の結果をどう格納するかというところで
最初はEmotions キーに表情分析の結果を配列として格納していましたが
それではPartiQLで分析できないということ。
※要は分析できるようにテーブルを作らなかったというところが良くない。
データ分析ができるようにデータを作る!!これ大事!!
イベントの活用方法
今回はユーザIDを画像の名前に付加してそれをS3のPUTイベント発生時に取得するようにしていましたが
参考にさせていただいた記事ではおそらくDynamoDBのイベントを使っているモノと思われるので
今回の記事と参考記事では若干、作りが異なると思われる。
Lambdaイベントを使う時はスクリプトの実行順序を入念に検討する必要がある。
Bot作成時のトラブルシューティング方法
結論を言うと、CloudWatch の ログを読むことです。
だいたいの答えはここにあります。
Amazon Rekognition の結果を分析してみる
Amazon Rekognition は 表情分析の結果だけなく他にもいろんな情報を返します。
具体的には以下
{
"FaceDetails": [
{
"BoundingBox": {
"Width": 0.55982905626297,
"Height": 0.31907957792282104,
"Left": 0.19411040842533112,
"Top": 0.155109241604805
},
"AgeRange": {
"Low": 20,
"High": 32
},
"Smile": {
"Value": false,
"Confidence": 98.34297943115234
},
"Eyeglasses": {
"Value": false,
"Confidence": 65.72138977050781
},
"Sunglasses": {
"Value": false,
"Confidence": 96.26079559326172
},
"Gender": {
"Value": "Female",
"Confidence": 98.86897277832031
},
"Beard": {
"Value": false,
"Confidence": 99.22696685791016
},
"Mustache": {
"Value": false,
"Confidence": 99.65571594238281
},
"EyesOpen": {
"Value": true,
"Confidence": 96.83961486816406
},
"MouthOpen": {
"Value": false,
"Confidence": 89.64883422851562
},
"Emotions": [
{
"Type": "CALM",
"Confidence": 85.87602233886719
},
{
"Type": "SAD",
"Confidence": 11.985572814941406
},
{
"Type": "CONFUSED",
"Confidence": 1.33014976978302
},
{
"Type": "HAPPY",
"Confidence": 0.22139669954776764
},
{
"Type": "ANGRY",
"Confidence": 0.21962696313858032
},
{
"Type": "SURPRISED",
"Confidence": 0.1779804825782776
},
{
"Type": "DISGUSTED",
"Confidence": 0.11067485809326172
},
{
"Type": "FEAR",
"Confidence": 0.07857893407344818
}
],
"Landmarks": [
{
"Type": "eyeLeft",
"X": 0.3114166259765625,
"Y": 0.27229952812194824
},
{
"Type": "eyeRight",
"X": 0.556735634803772,
"Y": 0.2768763303756714
},
{
"Type": "mouthLeft",
"X": 0.3393491804599762,
"Y": 0.395893394947052
},
{
"Type": "mouthRight",
"X": 0.5452344417572021,
"Y": 0.4002780616283417
},
{
"Type": "nose",
"X": 0.3942665755748749,
"Y": 0.35237061977386475
},
{
"Type": "leftEyeBrowLeft",
"X": 0.23418769240379333,
"Y": 0.2390945702791214
},
{
"Type": "leftEyeBrowRight",
"X": 0.34563449025154114,
"Y": 0.24140697717666626
},
{
"Type": "leftEyeBrowUp",
"X": 0.28236690163612366,
"Y": 0.2317887395620346
},
{
"Type": "rightEyeBrowLeft",
"X": 0.48571792244911194,
"Y": 0.24332554638385773
},
{
"Type": "rightEyeBrowRight",
"X": 0.659654438495636,
"Y": 0.2459377497434616
},
{
"Type": "rightEyeBrowUp",
"X": 0.5644543766975403,
"Y": 0.23580995202064514
},
{
"Type": "leftEyeLeft",
"X": 0.27321746945381165,
"Y": 0.26966771483421326
},
{
"Type": "leftEyeRight",
"X": 0.36017027497291565,
"Y": 0.2745400667190552
},
{
"Type": "leftEyeUp",
"X": 0.30802878737449646,
"Y": 0.26683565974235535
},
{
"Type": "leftEyeDown",
"X": 0.3124621510505676,
"Y": 0.27796489000320435
},
{
"Type": "rightEyeLeft",
"X": 0.5081146359443665,
"Y": 0.27715158462524414
},
{
"Type": "rightEyeRight",
"X": 0.6056190133094788,
"Y": 0.27561256289482117
},
{
"Type": "rightEyeUp",
"X": 0.5542343258857727,
"Y": 0.2711951732635498
},
{
"Type": "rightEyeDown",
"X": 0.5555209517478943,
"Y": 0.28240805864334106
},
{
"Type": "noseLeft",
"X": 0.374962717294693,
"Y": 0.3577878475189209
},
{
"Type": "noseRight",
"X": 0.46588602662086487,
"Y": 0.35922765731811523
},
{
"Type": "mouthUp",
"X": 0.4184502959251404,
"Y": 0.3886415660381317
},
{
"Type": "mouthDown",
"X": 0.426589697599411,
"Y": 0.4241403341293335
},
{
"Type": "leftPupil",
"X": 0.3114166259765625,
"Y": 0.27229952812194824
},
{
"Type": "rightPupil",
"X": 0.556735634803772,
"Y": 0.2768763303756714
},
{
"Type": "upperJawlineLeft",
"X": 0.23471041023731232,
"Y": 0.2555982172489166
},
{
"Type": "midJawlineLeft",
"X": 0.2832850217819214,
"Y": 0.39067912101745605
},
{
"Type": "chinBottom",
"X": 0.4491232633590698,
"Y": 0.48228609561920166
},
{
"Type": "midJawlineRight",
"X": 0.7167062759399414,
"Y": 0.3968362808227539
},
{
"Type": "upperJawlineRight",
"X": 0.7680227160453796,
"Y": 0.26324328780174255
}
],
"Pose": {
"Roll": -0.2124393731355667,
"Yaw": -12.579103469848633,
"Pitch": -5.298882961273193
},
"Quality": {
"Brightness": 94.21043395996094,
"Sharpness": 94.08262634277344
},
"Confidence": 99.99595642089844
}
],
"ResponseMetadata": {
"RequestId": "3ae31d19-fc05-4d9d-84ae-b0d7dede9752",
"HTTPStatusCode": 200,
"HTTPHeaders": {
"x-amzn-requestid": "3ae31d19-fc05-4d9d-84ae-b0d7dede9752",
"content-type": "application/x-amz-json-1.1",
"content-length": "3357",
"date": "Thu, 16 Dec 2021 14:51:12 GMT"
},
"RetryAttempts": 0
}
}
上記のように
推定年齢、笑顔かどうか、メガネ着用有無、サングラス着用有無、見た目上の性別、ひげと口ひげ、目や口が開いているかなど様々なデータを取ることができます。
ただし、顔からわかることでしか判断をしない為、正確でないこともあります。
例えば、ジェンダーレスモデルは見かけ上の性別と異なるケースが多いが為に判断を誤ることがあります。
今回は実在するジェンダーレスモデルを分析してみましたが、女性と認知されました。
人は見かけによらずというのはAWSというか機械も例外ではないということですね。
※あれ、そうすると男性と判定された一般男性の私も誤認された可能性があるのかも。
独り言
最初の印象が全てなどと語る人がいる。確かに第一印象が全てというのはあるかもしれない。
しかし、それは捉え方によって変わるモノだと思う。
例えば、幸せなニュースだと言われていても他の人にとっては不幸なニュースに聞こえるかもしれないし憤りを感じる人だっている。
それはニュースを見た時に何に注目して何を考えて何を思うのかで変わるのだと思います。
人種、性別、門地、価値観、イデオロギー 人の数だけ見方がある。
千差万別の見方があるということは千差万別の印象があるものと考えています。
また、多くの人に愛された著名人の不倫や自殺などもそうですが、我々が普段見ている彼ら彼女らは本当の姿ではないかもしれないです。
印象や見せかけではなく本質を見極められる人間になりたいものです。