20210604のPythonに関する記事は26件です。

残人生のためのプログラミング 第-3回

早速プログラムの紹介だ!! 今回紹介するのはこいつだ!!TaskNotify.py!! 前回からの変更点はtaskLoad関数の追加と,csv中のisRoutine列を使って期限日の自動更新機能の実装だ!! datetimeやdateオブジェクトの更新にはtimedeltaオブジェクトを使う必要があるから覚えておいてくれよな!! TaskNotify.py import requests import datetime import pandas as pd class Task: def __init__(self, name, date): self.name = name self.date = date self.sentence = "{}まで残り{}日\n".format(name, abs(self.date-today).days) def loadTasks(path_csv): csv_tasks = pd.read_csv(path_csv) list_tasks =[] for row in csv_tasks.itertuples(): date = datetime.datetime.strptime(row.deadline, '%Y年%m月%d日').date() if row.isRoutine and (date < today): date += datetime.timedelta(days=row.isRoutine) list_tasks.append(Task(row.name, date)) return list_tasks def createSend(tasks): sentences = "\n" for s in tasks: print(s.date) if s.date >= today: sentences += s.sentence return sentences if __name__ == '__main__': today = datetime.date.today() list_tasks = loadTasks("tasks.csv") send_dict = {'message': createSend(list_tasks)} TOKEN = 'hoge' url = 'https://notify-api.line.me/api/notify' TOKEN_dict = {'Authorization': 'Bearer ' + TOKEN} requests.post(url, headers=TOKEN_dict, data=send_dict) tasks.csv name,deadline,isRoutine,priority Qiitaの記事を投稿する,2021年6月3日,1,low 課題を提出する,2021年6月9日,,high Toeicの試験,2021年6月20日,,high コインランドリー,2021年6月3日,4,mid 次回 第-4回は!! タスクの登録・削除部分を実装していきます.とりあえずはtkinterとかでGUIとして実装しようかなって感じです.
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

CLIP/DALL-E、Aleph2Image、big-sleepを用いたテキストからの画像生成と、生成画像のテキストによる説明に関する試行

きっかけと概要 textとimageの適切な橋渡し、CLIP技術が公開された。imageの加減算ができるように。 CLIPにより、textが備える概念が適切にimageへと転移できているならば、imageからtextへの変換、imageのtextによる説明も、より適切にできているのではないか、と興味を持った。 もしこれができるのであれば、自らの興味の一つである「文章を読まず概要理解する」につながる可能性があるのかもしれない。かもしれない。 環境 基本的に Windows10 Python 3.7 tensorflow == 2.4.1 torch == 1.7.1+cpu DALL-E == 0.1 のnon-CUDA環境を用いるが、 現実的な処理速度を得るにはまたはCUDA必須である場合には、次の環境とした。 Google Colab(Pro) Python 3.7.10 CUDA Version: 11.2 tensorflow == 2.5.0 torch == 1.8.1+cu101 *CLIPを使用するには1.7.1とする必要がある 参考。というかほとんど ・openai/CLIP https://github.com/openai/CLIP https://openai.com/blog/clip/ CLIP (Contrastive Language-Image Pre-Training) is a neural network trained on a variety of (image, text) pairs. *non-CUDA可 ・openai/DALL-E https://github.com/openai/DALL-E https://openai.com/blog/dall-e/ This is the official PyTorch package for the discrete VAE used for DALL·E. *non-CUDA可 ・Thoughts on DeepDaze, BigSleep, and Aleph2Image https://rynmurdock.github.io/2021/02/26/Aleph2Image.html Aleph2Image uses the VQ-VAE discrete decoder from DALL-E. *non-CUDA可 ・lucidrains/big-sleep https://github.com/lucidrains/big-sleep A simple command line tool for text to image generation, using OpenAI's CLIP and a BigGAN. *non-CUDA不可 試行 入力テキスト 例えば、 input_text = """human in the loop"""   text-to-image:テキストからの画像生成 次を用いてテキストから画像生成。 Aleph2Image https://colab.research.google.com/drive/1oA1fZP7N1uPBxwbGIvOEXbTsq2ORa9vb?usp=sharing big-sleep https://colab.research.google.com/drive/1NCceX2mbiKOSlAd_o7IU7nA9UskKN5WR?usp=sharing 例えば、   image-to-text:生成画像のテキストによる説明(現状は単語による説明) CLIPのGithubにあるサンプルコードZero-Shot Predictionを改変。 CIFAR-100 datasetの100分類(語彙)を、NGSL単語の約2800語彙に拡張。 #CLIPのインストール import subprocess CUDA_version = [s for s in subprocess.check_output(["nvcc", "--version"]).decode("UTF-8").split(", ") if s.startswith("release")][0].split(" ")[-1] print("CUDA version:", CUDA_version) if CUDA_version == "10.0": torch_version_suffix = "+cu100" elif CUDA_version == "10.1": torch_version_suffix = "+cu101" elif CUDA_version == "10.2": torch_version_suffix = "" else: torch_version_suffix = "+cu110" !pip install torch==1.7.1{torch_version_suffix} torchvision==0.8.2{torch_version_suffix} -f https://download.pytorch.org/whl/torch_stable.html ftfy regex #Google colab使用時、ランタイムの再起動が必要かもしれない。 ! git clone https://github.com/openai/CLIP.git %cd /content/CLIP/ import os import clip import torch import matplotlib.pyplot as plt from PIL import Image import numpy as np # Load the model device = "cuda" if torch.cuda.is_available() else "cpu" print(device) model, preprocess = clip.load('ViT-B/32', device) #画像入力 image = Image.open("/content/3.png").convert("RGB") plt.imshow(np.array(image)) image_input = preprocess(image).unsqueeze(0).to(device) #カテゴリをNGSLに変更 !wget -P /content/ http://www.newgeneralservicelist.org/s/NGSL-101-by-band-qq9o.xlsx import pandas as pd df_ngsl1 = pd.read_excel('/content/NGSL-101-by-band-qq9o.xlsx', header=None, sheet_name=[0,1,2]) ngsl_catlist = [] for i in range(3): ngsl_catlist += df_ngsl1[i].iloc[:,0].values.tolist() ngsl_catlist += []#任意の語彙追加 text_inputs = torch.cat([clip.tokenize(f"a image of {c}") for c in ngsl_catlist]).to(device)#表現を変更 # Calculate features with torch.no_grad(): image_features = model.encode_image(image_input) text_features = model.encode_text(text_inputs) # Pick the top 5 most similar labels for the image image_features /= image_features.norm(dim=-1, keepdim=True) text_features /= text_features.norm(dim=-1, keepdim=True) print(image_features.shape, text_features.shape) similarity = (100.0 * image_features @ text_features.T).softmax(dim=-1) values, indices = similarity[0].topk(20) # Print the result print("\nTop predictions:\n") for value, index in zip(values, indices): print(f"{ngsl_catlist[index]:>16s}: {100 * value.item():.2f}%") 例えば、 input_text = """human in the loop""" ・・・意味深・・・   気を取り直して他の例、 input_text = '''Clip art of a man in a red car''' 画像から赤い車に乗るヒトと読み取れなくもない。説明語彙はred, carで正しい。   さらに他の例、 input_text = '''寺''' 説明語彙に'temple','寺'を追加している。 どのように判断すべきか悩みどころ。画像から寺と読み取れなくもない。説明語彙は日本語の'寺'で正しい。ただし、templeの説明は弱い。全体的には寺を説明する単語が並んでいるように見える。   さらに他の例、 input_text = '''an illustration of a baby daikon radish in a tutu walking a dog''' 説明語彙に入力テキスト語彙を追加。 なんだろうかこのコソ泥感   コメント (上記例はわかりやすい例とは言えないが別途試したところ)、入力テキストと生成画像から示されるテキスト(単語)は類似していると感じる。非常に面白い。 画像からテキスト(単語)を予想できるか=文章を読まず概要理解することができるか、に関しては、どうだろうかと。受け手の認知と統合する過程が現状はどこにもないからそりゃそうだとも言える。 そのまま使用する場合には、用途は限定的だろうと感じる。学習データがwebの画像とキャプションであり語彙も制限されているので、おのずから限界はあるだろう。(例えば、膵臓がんの画像から膵臓がんを示すテキストが示されることはないだろう。適切な画像が十分にweb上には無いであろうから。また、膵臓がんと入力して画像を生成させても、生成画像から膵臓がんを示すテキストが示されることはないだろう。) image-to-textにつき、現状はtextではなくwordsであるわけだが、textに・・・しようかどうしようか。単語間の関係は画像を見れば予想(妄想)できるわけで、画像と単語が同時に提供されている範囲であれば、textに変換する意味はあまり・・・ 追加 image-to-textにつき、語彙を増やせばより適切な説明が得られうる。入力テキストに固有名詞を用いたなら、説明語彙にもその固有名詞を加えてみる、と面白い。(単に入力テキストをリストに変換し語彙リストに加えるだけ。) CLIPを用いることにより、ローカルフォルダ内の画像をすべてベクトルに変換しておき高度な画像検索を行う、なども可能となる。イラストに限定した検索、線画に限定した検索、シチュエーションを限定した検索もでき、かなり面白い。 http://cedro3.com/ai/clip-search/ text = 'fireworks' text = 'Blue colored fireworks'
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Spotipyで英語名アーティストを日本語検索

はじめに 皆さんはSpotifyという音楽ストリーミングサービスを利用したことがありますか? 私はどれが良いか良く分からなかったのでとりあえずSpotifyを契約している節があります。 そんなSpotifyですが、実はAPIが用意されているという豪華仕様なんですよね。 今回AndroidアプリでSpotifyを再生する用事があったため、PythonからSpotify APIへリクエストを送るSpotipyモジュールを使おうと思ったのですが、1つ躓いた事があったので備忘録として残しておきます。 参考 Spotify APIと戯れる Spotify APIで楽曲情報やアーティスト情報を取得してみた ありがとうございました。 Spotipyの基本的な使い方について 既にSpotipyの使い方は様々な人がアップしているため、ここでは説明しません。 こちらの方の記事が非常にわかりやすくオススメです。↓ Spotify APIで楽曲情報やアーティスト情報を取得してみた 本題:英語名アーティストを日本語検索するには? さて、問題はここからです。 様々な記事を参考にしましたが、英語名称のアーティストを日本語名で検索する方法はわかりませんでした。 どういう意味? 例えばバンドリというゲームに「Morfonica」というバンドが登場するのですが、このバンドの楽曲もSpotifyに存在します。 このMorfonicaは「モルフォニカ」と発音し、Spotifyで検索をかけると「Morfonica」「モルフォニカ」の両者で同じ結果が返ってきます。 英語でも・・・ ひらがなでも・・・ カタカナでも・・・ 同じ結果が返ってきます。 しかしこれをSpotipyでやろうとすると・・・ from spotipy import Spotify from spotipy.oauth2 import SpotifyClientCredentials import pprint credentials = SpotifyClientCredentials( client_id = '', client_secret = '' ) sp = Spotify(auth_manager=credentials, language='ja') name = 'モルフォニカ' result = sp.search(q='artist:' + name, type='artist') pprint.pprint(result['artists']) 結果はこの通り ちなみにname=Morfonicaでリクエストすると・・・ 結果が長いので一部しかお見せできませんが、明らかに取得できることがわかると思います。 日本語検索するには? こうします↓ from spotipy import Spotify from spotipy.oauth2 import SpotifyClientCredentials import pprint credentials = SpotifyClientCredentials( client_id = '', client_secret = '' ) sp = Spotify(auth_manager=credentials, language='ja') name = 'モルフォニカ' result = sp.search(q=name, type='artist') pprint.pprint(result['artists']) 結果はご覧の通りです 何をしたのか 検索ワードで問題(と言う程問題でもないですが)のコードはqueryに「artist:」という文言が入っていました。 なぜかこれが英語→日本語検索できない原因だったようで、これを省いてあげるだけでどちらでも検索結果が返ってくるようになりました。 余談ですが このSpotipyで取得してきたjsonデータの中に「uri」という項目がありますが、これをkotlinやらjavaやらで書いたAndroidアプリでごちゃごちゃしてあげると、Spotifyアプリを開いてアーティストを表示させることができます。 これについてはまた今度・・・
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Seabornでグラフを描画したときにxlabelにすべての要素が入ってしまうときに確認すること

はじめに データ分析でEDAをするとMatplotlibやSeabornは欠かせないです。 可視化をするときには必須のライブラリですが、思い通りにいかないことが多々あります。 今回は、箱ひげ図やSwarmなどのグラフを描画したときにxlabelが変になっていたので、その解決方法について説明します。 問題 以下のデータフレームがあります。 このデータフレームの都道府県が北海道の行をすべて抽出して、x=都道府県名、y=取引価格(総額)_log、hue=改装の項目(改装済、未改装)に対して行います。 箱ひげ図やswarmplotなどで描画をすると以下のようになります。 boxplot.py # 抽出 df = df[df["都道府県名"]=="北海道"] # 箱ひげ図 import seaborn as sns sns.boxplot(x='都道府県名', y='取引価格(総額)_log', hue="改装", data=df[:100]) plt.show() swarmplot.py # 抽出 df = df[df["都道府県名"]=="北海道"] # swarmplot import seaborn as sns sns.boxplot(x='都道府県名', y='取引価格(総額)_log', hue="改装", data=df[:100]) plt.show() データ数が多いため100行だけ可視化しています。 するとxlabelが北海道のはずだけのはずが、全都道府県表示されていました。 解決方法 原因は都道府県名のカラム型がcategory型であることでした。 LightGBMの前処理の最後にカテゴリ型にしていました。 ですので、この処理をなくしてobject形にするとうまく表示されます。 おわりに まさかのところに原因が潜んでいました。 同じところで悩まされる人が早くこの記事で解決できることを願っています。 参考記事 Pandasのgroupbyがうまく機能していないので教えていただきたいです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Pandasのgroupbyでないはずの要素もまとまられてしまいNaNになってしまう

はじめに Pandasのgroupbyはとても難しく初心者の壁だと思っています。 私も本格的にさわり初めて日が浅く、どこが原因なのかよくわからない or どうやってアルゴリズムを組めば効率的に実現できるのかと模索する日々です。 時間がかかったものに関してはQiitaに記事としてまとめていますのでご覧ください。 今回は、groupbyで想定していない動きになり困っていたのですが、質問サイトに投稿したところデバックをしていくうちに真相にたどり着いたのでまとめたいと思います。デバックしていなかったら解決に至っていなかった危害します。(よかった) 私と同じようなことになった方がすぐに解決できればと思います。 問題 以下のようなDataFrameがあります。 このデータフレームに対して、 「都道府県名が北海道の行だけを抽出して、市区町村名でgroupbyして、市区町村ごとの面積の平均値をだす」という操作を行いました。 df[df["都道府県名"]=="北海道"].groupby('市区町村名').mean() すると、以下の結果が返ってきました。 北海道にはあきる市や鹿児島市などはもちろんありません。 また、元のデータフレームは47都道府県、618種類の市区町村があります。 うまく抽出ができていないのかと確認したところすべて北海道、市区町村の数は18個になっていました。 ここでデバックしていて、Categoriesになぜかすべての市区町村名が入っています。おそらくこれが原因なのですが、よくわからずという状態でした。 しかし、このデバックが解決への道となるのでした。 解決方法 原因はこの市区町村名のデータ型がcategory型だったことでした。 実は、LightGBMを動かしており、以下のような処理を前処理として行っていました。 この処理が原因となっていました。 ですので、この処理をしないことで無事、groupbyが成功しました。 また、どうしてもCategory型で行いたい場合はこのような方法で実現できます。 data.groupby(['都道府県名', '市区町村名'], observed=True).mean() observed=Trueで実現可能です。 おわりに DataFrame関係はわからないことばかりですが、同じような問題を例題として用意し、teratailやstack over flowなどで質問してみるとスマートな回答が返ってくることが多いです。 サービスはどんどん活用していくべきだと思います。 参考サイト Pandasのgroupbyがうまく機能していないので教えていただきたいです。 Pandas groupby with categories with redundant nan
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Pythonのloggingで出力したログ内容を変数に格納する

概要 Pythonのloggingでログ出力する際、出力したログ内容を変数に格納したい。一度ファイルに書き出してから読み込んでもよいが、直接変数に格納するに越したことはないだろう。 実装例 logging.configなし もっとも単純な実装方法は、組み込みのStreamHandlerをインスタンス化するときにStringIOを渡すこと。 sample.py import io import logging # 文字列バッファ str_io = io.StringIO() # ロガー logger = logging.getLogger('sample') logger.setLevel(logging.INFO) # 組み込みのStreamHandlerにStringIOを渡す handler = logging.StreamHandler(str_io) handler.setFormatter(logging.Formatter('%(asctime)s %(name)s %(levelname)s %(message)s')) # ログ出力(この時点ではバッファに書き込まれるだけ) logger.info('info') # ログ内容を変数に格納 log_text = str_io.getvalue() # 表示 print('log : ' + log_text) 上記の例でlogging.config.dictConfigを使う場合は、StreamHandlerのstreamに"est://__main__.str_io"を設定する。ただ、さすがに変数名を設定ファイルに直接記載するのは憚られるので、StringIOを出力対象とする独自Handlerを定義した方がよいだろう。 logging.configあり StreamHandlerを継承した独自Handlerを定義する。StringIOインスタンスの配置場所や参照方法はお好みで。 my_util.py import io from logging import StreamHandler class StringHandler(StreamHandler): """ログ出力を変数に格納する独自Handler""" str_io = io.StringIO() def __init__(self): StreamHandler.__init__(self, StringHandler.str_io) sample2.py import io from logging import getLogger, config from my_util import StringHandler # ログ設定 config.dictConfig({ 'version': 1, 'formatters': { 'simple': { 'format': '%(asctime)s %(name)s %(levelname)s %(message)s' } }, 'handlers': { 'string': { 'class': 'my_util.StringHandler', 'formatter': 'simple' } }, 'loggers': { 'sample': { 'level': 'INFO', 'handlers': ['string'] } } }) # ロガー logger = getLogger('sample') # ログ出力(この時点ではバッファに書き込まれるだけ) logger.info('info') # ログ内容を変数に格納 log_text = StringHandler.str_io.getvalue() # 表示 print('log : ' + log_text)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

StyleGAN2で生成できるものが増えてきたのでメモ

StyleGAN2の学習済みモデルがまた増えてたので, 面白いことが出来そうなモデルをメモ 絵画・浮世絵の画像生成に使ったコード: https://colab.research.google.com/drive/1D_5zvi-ny3ChQ0vG2cKPngeTawoSzhmT?usp=sharing 絵画 浮世絵 面白かったこと 絵画のモデルはFFHQの学習済みモデルから転移学習を行なっているらしく、潜在変数空間の分布が転移学習前のものに似ている. なので、以前のモデルで生成していた画像に対応する潜在変数を与えることで似たような顔画像の絵画を生成できる. 左がFFHQで学習済みのモデルで、右が転移学習で絵画を生成できるモデル Image2StyleGANを使って特定の画像の再現もできるけど、絵画のデータにはメガネをかけているものは少ない(もしかしたらない?)ので、メガネを再現しようとすると失敗する 左がFFHQで学習済みのモデルで、右が転移学習で絵画を生成できるモデル
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

dynamodb のアイテムを CSV にして S3 に吐き出してみた。Lambda で。

ssm.describe_instance_information() で取得したインスタンスID、プラットフォーム名、プラットフォームバージョンが格納されている DynamoDB のテーブルをCSVに吐き出す。 lambda-python3.8 import json import csv import boto3 def export_s3(): # lambda 上に展開する一次ファイルの定義。 /tmp/配下が使えるよ。 local_path = "/tmp/platform.csv" # s3 に保存するファイルの定義。/xxx/plaform.csv のような感じでディレクトリ指定可能 s3_path = "platform.csv" # 吐き出す先の S3 バケットの指定 bucket_name = "jiro-platform" # DynamoDB のテーブル名。今回は事前に作ってある想定。 table_name = 'platform-information' # DynamoDB のクライアントを定義 ddb_client = boto3.client('dynamodb') # scan にて DynamoDB テーブルの中身(Item)を get_data に一旦投入 get_data = ddb_client.scan( TableName=table_name ) # CSV における列を定義。ここでは3列。インスタンスID、プラットフォーム名、プラットフォームバージョン fieldnames = ['instanceid', "platform_name", "platform_version"] # lambda の /tmp 領域に 一時的な csvファイルを作成・オープンし、get_data から1行ずつ読み出しては csvファイルに書き出し。をfor 文で回す。 with open(local_path, 'w') as f: writer = csv.DictWriter(f, fieldnames = fieldnames) writer.writeheader() for data in get_data['Items']: instanceid = data['instanceid']['S'] platform_name = data['platform_name']['S'] platform_version = data['platform_version']['S'] writer.writerow({"instanceid":instanceid, "platform_name":platform_name, "platform_version": platform_version}) # s3 クライアント、s3バケット定義 s3 = boto3.resource('s3') bucket = s3.Bucket(bucket_name) # /tmp内のローカルファイルを s3 にアップロード bucket.upload_file(local_path, s3_path)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

学生証と顔認証で本人確認してみる [2] 〜Face APIにユーザーを覚えさせよう〜

先ほどぶりです。たてしきと申します。 本人確認しようってやつの続きです(雑) お品書き ・学生証と顔認証で本人確認してみる [1] 〜MS Azure、Face APIの利用準備をしよう〜 ・学生証と顔認証で本人確認してみる [2] 〜Face APIにユーザーを覚えさせよう〜 ←いまここ! ・学生証と顔認証で本人確認してみる [3] 〜Node-REDを使ってシステムを構築しよう〜 New! ・学生証と顔認証で本人確認してみる [4] 〜実際に使ってみよう〜 (仮) (執筆中) 学習のお時間 AIを使う上で欠かせないものといえば、やっぱり学習ですよね。 というわけでFace APIを学習させていきましょう。 Face APIの準備 1. PersonGroupを作成する "PersonGroup"、つまり人物のグループを作ってその中に"PersonGroup Person"、つまりユーザーを、その中に顔情報を記録していくわけです。 Cognitive Services APIs Reference - PersonGroup - Createより、グループを作成します。緑色のやつです。 Hostに関しては前回の通り。 Query parameters - personGroupIdにはPersonGroupの名前を入力します。英小文字、数字ぐらいしか使えないみたいです(例ではauthlist)。 Headersもいつも通りに入力してください。 今度はbodyを編集します。 nameの欄には表示される名前を入力します。ほとんど使いませんが。(例では大学の学生リスト) userDataは今回はまだ使わないので消してあげてください。 recognitionModelはrecognition_04に変更してあげてください。最新版のほうがいいです。 「Send」を押すと作成できます。 2. Personを追加する ユーザーを作成します。黄色のやつです。 Cognitive Services APIs Reference - PersonGroup Person - Createから作成します。 Query parameters - personGroupIdには先ほど作成したグループのID(ここではauthlist)を入力します。 body部分のuserDataはまたしてもいらないので消してあげてください。 nameにユーザーの名前(ここではTestuser01)を入力します。 「Send」を押すと、返り値にpersonIdというものが入ってます。 return { "personId": "aa0dadea-a031-45c9-a759-1a5a3fe93cfe" } これがユーザーを識別するUUIDになるのでどこかに保存しておきます。 3. PersistedFaceを登録する 顔写真を登録します。オレンジ色っぽいやつです。今回は班のメンバーの写真を登録しました。 もちろん枚数が多い方が精度が高くなりますが、実用化するわけでもないので僕の写真はとりあえず100枚準備しました。 Cognitive Services APIs Reference - PersonGroup Person - Add Faceからも登録できますが、圧倒的に時間がかかります。 というわけで、サクッとPythonでコードでも書いて自動化しましょう。 main.py import requests, glob, os, time resourceId = "tsukuru-system-faceapi" # リソースID personGroup = "authlist" # さっき作ったグループID personId = "aa0dadea-a031-45c9-a759-1a5a3fe93cfe" # さっきのpersonId detectionModel = "detection_03" # 最新モデル subKey = "********************" # サブスクキー accessCount = 0 # アクセス制限用カウンタ def main(): imageList = glob.glob(".\\images\\"+personId+"\\image_*.jpg") # 保存フォルダから画像を選択 (環境によって書き換えてください) for image in imageList: print("Reading "+os.path.basename(image)+" ... ", end="") # デバッグ binData = open(image, "rb").read() # バイナリで読み込む print("OK. Uploading ... ", end="") # デバッグ response = requests.post( "https://"+resourceId+".cognitiveservices.azure.com/face/v1.0/persongroups/"+personGroup+"/persons/"+personId+"/personFaces?detectionModel="+detectionModel, headers={"Content-Type": "application/octet-stream", "Ocp-Apim-Subscription-Key": subKey}, data=binData ) # 顔情報を登録する op = str(response.status_code)+" OK" if (response.status_code == requests.codes.ok) else str(response.status_code)+" Failed" print(op) # デバッグ print(response.json) # デバッグ accessCount += 1 # アクセスカウント (アクセス制限対策) if accessCount >= 20: time.sleep(60) # 1分待機 accessCount = 0 # カウンタをリセット if __name__ == "__main__": main() py main.pyで実行です。あとは登録が終わるまで待つ。 4. トレーニングする いよいよ学習させます。Cognitive Services APIs Reference - PersonGroup - Trainから指示します。 Query parameters - personGroupIdにはグループのID(ここではauthlist)を入力します。 「202 Accepted」となれば学習が開始されてます。 Cognitive Services APIs Reference - PersonGroup - Get Training Statusから学習状況を確認できます。 100枚程度なら1秒程度で学習できました。おそろしく速い学習、オレでなきゃ見逃しちゃうね お疲れさまでした 学習まで完了しました。次はNode-REDを用いつつ、顔認証テストとシステム構築を行っていきます。 前: 学生証と顔認証で本人確認してみる [1] 〜MS Azure、Face APIの利用準備をしよう〜 次: 学生証と顔認証で本人確認してみる [3] 〜Node-REDを使ってシステムを構築しよう〜 (仮) (執筆中)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

unittestで動的にmock responseを帰る

はじめに unittest.mockのpatchメソッドではmockのresponseを送信することはみなん知っていると思いますが、しかし、請求URLなどより動的にmock responseを作ることはどう実現できるでしょうか?この記事ではそれを実現するための方法を紹介します。 return_valueとside_effect 簡単にまとめる、こんな感じ: モックを呼び出したときに(毎回同じ)返り値を返してほしい場合はreturn_value属性を設定する。 モックを呼び出すたびに異なる返り値を返してほしい場合はside_effect属性に渡す。 今回は可変な返り値を返してほしいのでside_effect属性を利用します。 コード例 import json from unittest.mock import patch from requests import Response def mocked_request_get(*args, **kwargs): response_content = None request_url = kwargs.get('url') if request_url == 'aurl': response_content = json.dumps('a response') elif request_url == 'burl': response_content = json.dumps('b response') elif request_url == 'curl': response_content = json.dumps('c response') response = Response() response.status_code = 200 response.content = str.encode(response_content) return response @patch('requests.get', side_effect=mocked_requests_get) ここに注意すべきなのはkwargs.get('url')のところ請求requestによりコードを変わる必要があります。以上のようなmocked_request_getで請求requestより違うresponseを作成し、patchメソッドのside_effect属性を利用して、mockのresponseを作ることができます。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWSとMicrosoft Azureにおける機械学習モデルのサービング技術の概要

初版: 2021年6月4日 著者: 橋本恭佑、柿田将幸, 株式会社 日立製作所 はじめに 近年、機械学習をはじめとするAI技術を活用したデータ分析が注目を集めており、AIを活用する案件が増加しています。 機械学習モデルを活用したシステムを構築する案件では、まずPoC(Proof of Concept)で機械学習モデルの有用性を確認し、その成果をもとに本番用のシステムを開発するケースが多いです。機械学習モデルをシステムに組み込み、サービスとして公開する一連の技術はサービング技術と呼ばれており、システム構築と運用を担う技術者にとって重要な技術です。 特に、機械学習サービスの負荷が大きく変動する場合は、負荷に合わせて柔軟にリソースを増減可能なパブリッククラウド上でのサービングが有効といえます。 本連載では、オンプレミス環境で作成した機械学習モデルをパブリッククラウド(AWSおよびMicrosoft Azure)でサービングする技術について、実際に検証した手順を交えながら解説します。 投稿一覧 AWSとMicrosoft Azureにおける機械学習モデルのサービング技術の概要・・・本投稿 Amazon SageMakerとAzure MLにおける機械学習モデルのサービング技術比較: AWS/Azureが提供するコンテナイメージを利用する場合・・・近日公開 Amazon SageMakerとAzure MLにおける機械学習モデルのサービング技術比較: 自作コンテナイメージを利用する場合・・・近日公開 AWS FargateとAzure Container Instanceにおける機械学習モデルのサービング技術比較・・・近日公開 パブリッククラウドにおける機械学習モデルのサービングパターン パブリッククラウドにおける機械学習モデルのサービング パブリッククラウドにおける機械学習モデルのサービングに必要なコンポーネントとサービングの手順の概要を図1に示します。 パブリッククラウド上で機械学習モデルをサービングする際は、前処理、モデル、後処理、およびそれらの実行に必要なライブラリ群を、 パブリッククラウドのコンテナ基盤上にまとめてコンテナとしてデプロイします。 AWSやMicrosoft Azureが提供する機械学習プラットフォームであるAmazon SageMakerやAzure Machine Learning(以下、Azure ML)では、 各々の機械学習プラットフォーム上で機械学習モデルを学習させて、同じパブリッククラウドのコンテナ基盤上へサービングする機能を提供しています1。 図1 パブリッククラウドにおける機械学習モデルのサービングに必要なコンポーネントとサービングの手順の概要 オンプレミス環境で作成した機械学習モデルのサービングパターン Amazon SageMakerやAzure MLを利用してサービングする場合は、SageMakerやAzure ML上で利用可能なコンテナイメージを用意します。 AWSやMicrosoft Azureは、SageMakerやAzure MLで利用可能な、機械学習の用途ごとに必要なライブラリが含まれるコンテナイメージを提供しています。 機械学習モデルの用途に沿ったコンテナイメージを選択し、モデルや前処理・モデル・後処理を呼び出す推論コードを追加することで、オンプレミス環境で作成した機械学習モデルをコンテナ基盤上にデプロイできます。 一方で、AWSやMicrosoft Azureが提供するコンテナイメージに、必要なライブラリが不足している場合や、オンプレミス環境で利用したライブラリとバージョンが異なる場合もあります。 これらの場合、次の2つのパターンのいずれかを行う必要があります。 パターン1: パブリッククラウドが提供するコンテナイメージをコンテナ基盤にデプロイするときに、ライブラリの追加またはバージョン変更して、前処理・モデル・後処理を追加する パターン2: パブリッククラウドが提供するコンテナイメージを利用せず、オンプレミス環境で必要なライブラリを含んだコンテナイメージを作成して、コンテナ基盤へデプロイするときに、前処理・モデル・後処理を追加する 一方で、Amazon SageMakerやAzure MLを利用しない場合は、AWS FargateやAzure Container Instance (Azure CI)といったコンテナ実行サービスを利用して、次のパターン3を行うことも考えられます。 パターン3: オンプレミス環境でライブラリ・前処理・モデル・後処理を含んだコンテナイメージを作成し、コンテナ基盤へデプロイする パターン1、パターン2、パターン3の比較を表1に示します。パターン毎に、オンプレミス環境で用意するものの多さと、パブリッククラウド環境で必要な手順の多さが異なります。 本連載では、パターン1からパターン3を実際にパブリッククラウドで試し、パブリッククラウド毎にどのパターンが可能であるかを確認します。さらに、複数のパブリッククラウドで可能なパターンについては、実際に試した結果を踏まえて、どのパブリッククラウドのサービスを使うべきか、指針を示します。 表1 サービングパターンの比較 パターン サービングに利用するクラウドサービス ベースとなるコンテナイメージ 必要ライブラリの追加方法 前処理・モデル・後処理の追加方法 1 機械学習プラットフォーム(Amazon SageMaker/Azure ML) パブリッククラウドが提供 コンテナイメージのデプロイ後に追加 コンテナイメージをデプロイするときに追加 2 機械学習プラットフォーム(Amazon SageMaker/Azure ML) オンプレミス環境で作成 コンテナイメージの作成時に追加 コンテナイメージをデプロイするときに追加 3 コンテナ実行基盤(Amazon Fargate/Azure CI) オンプレミス環境で作成 コンテナイメージの作成時に追加 コンテナイメージの作成時に追加 サービング検証のシナリオ パターン1からパターン3の実現可能性と各パターンの選定の指針を検討するために、今回設定した検証シナリオを説明します。 今回の投稿では機械学習モデルの学習に用いたソースコードと、前処理、推論、後処理を行うソースコードを紹介し、次回以降の投稿で実際にパブリッククラウドでサービングした結果を紹介します。 検証シナリオ: MNISTデータセットを用いた手書き文字画像の認識 本連載における検証シナリオでは、オンプレミス環境で学習させた手書き文字認識(MNIST)の機械学習モデルをパブリッククラウドでサービングします。 MNISTは28×28ピクセルの手書き画像で、ピクセル値は0から255までの整数です。MNISTのデータセットを学習用データセットと推論用データセットに分割し、学習用データセットを用いて作成した機械学習モデル(joblibファイル)に、JPEGファイルの手書き画像データを入力させて推論結果を出力します。 まず、機械学習モデルの前処理、学習、後処理、推論を実行する環境を用意します。表2に本検証シナリオに用いたpythonライブラリのバージョンを示します。 表2: 今回の検証シナリオに用いたpythonライブラリのバージョン ソフトウェア バージョン python 3.7.6 numpy 1.18.1 scikit-learn 0.22.1 pillow 7.0.0 joblib 1.0.0 flask 1.1.2 手書き文字認識モデルの学習 下記に学習用のソースコード(train.py)を示します。 train.py import numpy as np from sklearn import model_selection, svm, metrics from sklearn.neural_network import MLPClassifier import joblib # MNISTデータセット(mnist.npz)を学習用データセットと推論用データセットに分割する # X_train is 60000 rows of 28x28 values --> reshaped in 60000 x 784 RESHAPED = 784 NB_CLASSES = 10 x_train = x_train.reshape(60000, RESHAPED) x_test = x_test.reshape(10000, RESHAPED) x_train = x_train.astype('float32') x_test = x_test.astype('float32') # 学習 clf = MLPClassifier(hidden_layer_sizes=(128,), solver='adam', max_iter=20, verbose=10, random_state=0) clf.fit(x_train, y_train) # 推論用データセットを利用して精度を検証 print('accuracy_score: %.3f' % clf.score(x_test, y_test)) # joblibファイルとして機械学習モデルをエクスポート joblib.dump(clf, "./model.joblib") 手書き文字認識モデルによる推論 次に、推論用のソースコード(api_server.py)を示します。 api_server.py import argparse import os import sys import numpy as np from PIL import Image import joblib import flask app = flask.Flask(__name__) @app.route("/") def hello_world(): return 'Flask Hello world' @app.route("/predict", methods=["POST"]) def predict(): model = joblib.load(os.path.join(“/root/serving/”, "model.joblib")) response = {"Content-Type": "application/json", "number": None} RESHAPED = 784 if flask.request.method == "POST": if flask.request.files["file"]: image_number = np.array( Image.open(flask.request.files["file"]).convert('L')) array = [image_number.reshape(RESHAPED)] print('type(array): {0}, array: {1}'.format(type(array), array)) prediction = model.predict(array) response["number"] = str(prediction[0]) return flask.jsonify(response) if __name__ == '__main__': app.run(debug=True, host='0.0.0.0') 上記のソースコード(api_server.py)を実行すると、前処理、推論、後処理を行うサーバプログラムが起動します。 $ python api_server.py * Serving Flask app "api_server" (lazy loading) * Environment: production WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Debug mode: on * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit) * Restarting with stat * Debugger is active! * Debugger PIN: 180-690-578 手書き文字認識サービスの利用 上記のソースコード(api_server.py)を実行して、手書き数字のJPEGファイルを送信します。今回利用した手書き数字のJPEGファイルを図2に示します。 図2 今回利用した手書き数字の画像ファイル(左がx_test_30.jpeg, 右がx_test_60.jpeg) 図2に示した画像ファイルをサーバへ入力した場合の出力を下記に示します。 $ curl -F file=@x_test_30.jpeg localhost:5000/predict { "Content-Type": "application/json", "number": "3" } $ curl -F file=@x_test_60.jpeg localhost:5000/predict { "Content-Type": "application/json", "number": "6" } 実行環境の選定 パターン1からパターン3をAWSおよびMicrosoft Azureで実現する際のサービス一覧を表3に示します。パターン1とパターン2については、Amazon SageMakerと Azure Machine Learningで対応します。また、パターン3についてはAWSではAWS Fargate、Microsoft AzureではAzure Container Instanceが対応します。 表3 オンプレミス環境で学習させた機械学習モデルをAWSおよびMicrosoft Azure上でサービングする際のサービス一覧(2021年2月現在) パターン 概要 AWS Microsoft Azure 1 AWS/Azureが提供するコンテナイメージを利用(デプロイ時にライブラリと前処理・モデル・後処理を追加) Amazon SageMaker Azure Machine Learning 2 自作コンテナイメージを利用(コンテナイメージ作成時にライブラリを追加し、デプロイ時に前処理・モデル・後処理を追加) Amazon SageMaker Azure Machine Learning 3 自作コンテナイメージを利用(コンテナイメージ作成時にライブラリと前処理・モデル・後処理を追加) AWS Fargate Azure Container Instance おわりに 次回以降の投稿で、表3に示した各パターンをAWSおよびMicrosoft Azureで実現する技術を紹介します。また実際にサービングしてわかった注意点や使いどころを紹介します。 Amazon SageMakerまたはAzure ML上で作成した機械学習モデルをサービングする技術については、AWSやMicrosoft Azureが提供するドキュメントや、こちらの投稿をご覧ください。 ↩
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Python演算処理】行列演算の基本③パスカルの三角形から二次形式へ

【Python演算処理】パスカルの三角形と二項定理または二項展開 この投稿で紹介した乗法公式(式の展開公式)に登場するに乗算式を行列の二次形式で表現すると、それぞれこうなります。 【Python演算処理】行列演算の基本①基本的四則演算と積(Product) import sympy as sp a,b = sp.symbols('a,b') #Rows x=sp.Matrix([[a,b]]) #Columns y=sp.Matrix([[a],[b]]) a=sp.Matrix([[1,1],[1,1]]) sp.init_printing() display(x) display(a) display(y) display(sp.simplify(x*a*y)) print(sp.latex(x)+sp.latex(a)+sp.latex(y)+"="+sp.latex(sp.simplify(x*a*y))) \left[\begin{matrix}a & b\end{matrix}\right]\left[\begin{matrix}1 & 1\\1 & 1\end{matrix}\right]\left[\begin{matrix}a\\b\end{matrix}\right]=\left[\begin{matrix}\left(a + b\right)^{2}\end{matrix}\right] import sympy as sp a,b = sp.symbols('a,b') #Rows x=sp.Matrix([[a,b]]) #Columns y=sp.Matrix([[a],[b]]) a=sp.Matrix([[1,-1],[-1,1]]) sp.init_printing() display(x) display(a) display(y) display(sp.simplify(x*a*y)) print(sp.latex(x)+sp.latex(a)+sp.latex(y)+"="+sp.latex(sp.simplify(x*a*y))) \left[\begin{matrix}a & b\end{matrix}\right]\left[\begin{matrix}1 & -1\\-1 & 1\end{matrix}\right]\left[\begin{matrix}a\\b\end{matrix}\right]=\left[\begin{matrix}\left(a - b\right)^{2}\end{matrix}\right] import sympy as sp a,b = sp.symbols('a,b') #Rows x=sp.Matrix([[a,b]]) #Columns y=sp.Matrix([[a],[b]]) a=sp.Matrix([[-1,1],[1,-1]]) sp.init_printing() display(x) display(a) display(y) display(sp.simplify(x*a*y)) print(sp.latex(x)+sp.latex(a)+sp.latex(y)+"="+sp.latex(sp.simplify(x*a*y))) \left[\begin{matrix}a & b\end{matrix}\right]\left[\begin{matrix}-1 & 1\\1 & -1\end{matrix}\right]\left[\begin{matrix}a\\b\end{matrix}\right]=\left[\begin{matrix}- \left(a - b\right)^{2}\end{matrix}\right] import sympy as sp a,b = sp.symbols('a,b') #Rows x=sp.Matrix([[a,b]]) #Columns y=sp.Matrix([[a],[b]]) a=sp.Matrix([[-1,-1],[-1,-1]]) sp.init_printing() display(x) display(a) display(y) display(sp.simplify(x*a*y)) print(sp.latex(x)+sp.latex(a)+sp.latex(y)+"="+sp.latex(sp.simplify(x*a*y))) \left[\begin{matrix}a & b\end{matrix}\right]\left[\begin{matrix}-1 & -1\\-1 & -1\end{matrix}\right]\left[\begin{matrix}a\\b\end{matrix}\right]=\left[\begin{matrix}- \left(a + b\right)^{2}\end{matrix}\right] ここで二次形式行列と二次方程式を結ぶ為に使った「全ての成分が1か-1の行列」をアダマール行列(Hadamard Matrix)という。アダマール行列の定義と性質 しばしば「全ての成分が1か-1のアダマール行列」はスカラーと混同されるが、その背景にはもっと深淵なレベルの数理が横たわっている様にも窺える。【Python演算処理】行列演算の基本①基本的四則演算と積 行列から対角角成分のみを抜き出すとこんな感じ。 対角行列 - Wikipedia import sympy as sp a,b = sp.symbols('a,b') #Rows x=sp.Matrix([[a,b]]) #Columns y=sp.Matrix([[a],[b]]) a=sp.Matrix([[1,0],[0,1]]) sp.init_printing() display(x) display(a) display(y) display(sp.simplify(x*a*y)) print(sp.latex(x)+sp.latex(a)+sp.latex(y)+"="+sp.latex(sp.simplify(x*a*y))) \left[\begin{matrix}a & b\end{matrix}\right]\left[\begin{matrix}1 & 0\\0 & 1\end{matrix}\right]\left[\begin{matrix}a\\b\end{matrix}\right]=\left[\begin{matrix}a^{2} + b^{2}\end{matrix}\right] 行列から非対角成分のみを抜き出すとこんな感じ。 交代行列 - Wikipedia import sympy as sp a,b = sp.symbols('a,b') #Rows x=sp.Matrix([[a,b]]) #Columns y=sp.Matrix([[a],[b]]) a=sp.Matrix([[0,1],[1,0]]) sp.init_printing() display(x) display(a) display(y) display(sp.simplify(x*a*y)) print(sp.latex(x)+sp.latex(a)+sp.latex(y)+"="+sp.latex(sp.simplify(x*a*y))) \left[\begin{matrix}a & b\end{matrix}\right]\left[\begin{matrix}0 & 1\\1 & 0\end{matrix}\right]\left[\begin{matrix}a\\b\end{matrix}\right]=\left[\begin{matrix}2 a b\end{matrix}\right] さて、これらの直感的に思いつく初歩的行列操作にはそれぞれ数理的に一体どんな説明がつくのでしょうか? 行列操作の基礎①二次形式 まずは二次形式そのものの概念について理解を深めましょう。 二次形式の意味,微分,標準形など 二次形式とは,二次の項のみからなる多項式の事。対称行列A、変数を縦に並べた列ベクトルx、転置記号Tを用いて$x^TAx$なるコンパクトな形で書けます。 import sympy as sp x1,x2 = sp.symbols('x1,x2') a=sp.Matrix([[x1],[x2]]) b=a.transpose() sp.init_printing() display(a) display(b) print(sp.latex(a)+"^T="+sp.latex(b)) \left[\begin{matrix}x_{1}\\x_{2}\end{matrix}\right]^T=\left[\begin{matrix}x_{1} & x_{2}\end{matrix}\right] 二次形式における表現 import sympy as sp a11,a12,a21,a22,x1,x2 = sp.symbols('a11,a12,a21,a22,x1,x2') a=sp.Matrix([[a11,a12],[a21,a22]]) y=sp.Matrix([[x1],[x2]]) x=y.transpose() sp.init_printing() display(x) display(a) display(y) display(x*a*y) print(sp.latex(x)+sp.latex(a)+sp.latex(y)+"="+sp.latex(x*a*y)) \left[\begin{matrix}x_{1} & x_{2}\end{matrix}\right]\left[\begin{matrix}a_{11} & a_{12}\\a_{21} & a_{22}\end{matrix}\right]\left[\begin{matrix}x_{1}\\x_{2}\end{matrix}\right]=\left[\begin{matrix}x_{1} \left(a_{11} x_{1} + a_{21} x_{2}\right) + x_{2} \left(a_{12} x_{1} + a_{22} x_{2}\right)\end{matrix}\right] 結果が$3x_1^2-2x_1x_2+3x_2^2$となる代入。 import sympy as sp a11,a12,a21,a22,x1,x2 = sp.symbols('a11,a12,a21,a22,x1,x2') a=sp.Matrix([[a11,a12],[a21,a22]]) y=sp.Matrix([[x1],[x2]]) x=y.transpose() b=a.subs([(a11,3),(a12,-1),(a21,-1),(a22,4)]) sp.init_printing() display(x) display(b) display(y) display(x*b*y) print(sp.latex(x)+sp.latex(b)+sp.latex(y)+"="+sp.latex(x*b*y)) \left[\begin{matrix}x_{1} & x_{2}\end{matrix}\right]\left[\begin{matrix}3 & -1\\-1 & 4\end{matrix}\right]\left[\begin{matrix}x_{1}\\x_{2}\end{matrix}\right]=\left[\begin{matrix}x_{1} \left(3 x_{1} - x_{2}\right) + x_{2} \left(- x_{1} + 4 x_{2}\right)\end{matrix}\right] シグマ形式における表現 x^TAx=\sum_{i=1}^{n}\sum_{j=1}^{n}A_{ij}x_{i}x_{j} import sympy as sp a11,a12,a21,a22,x1,x2= sp.symbols('a11,a12,a21,a22,x1,x2') i,j,n=sp.symbols('i,j,n', integer = True) Org=sp.Matrix([[a11,a12],[a21,a22]]) Var=sp.Matrix([[x1*x1,x1*x2],[x1*x2,x2*x2]]) Trg=sp.summation(sp.summation(Org[i,j]*Var[i,j],(j,0,1)),(i,0,1) ) sp.init_printing() display(Org) display(Var) display(Trg) print("x^TAx="+sp.latex(Trg)) x^TAx=a_{11} x_{1}^{2} + a_{12} x_{1} x_{2} + a_{21} x_{1} x_{2} + a_{22} x_{2}^{2} 結果が$3x_1^2-2x_1x_2+3x_2^2$となる代入。 import sympy as sp a11,a12,a21,a22,x1,x2= sp.symbols('a11,a12,a21,a22,x1,x2') i,j,n=sp.symbols('i,j,n', integer = True) Org0=sp.Matrix([[a11,a12],[a21,a22]]) Org=Org0.subs([(a11,3),(a12,-1),(a21,-1),(a22,4)]) Var=sp.Matrix([[x1*x1,x1*x2],[x1*x2,x2*x2]]) Trg=sp.summation(sp.summation(Org[i,j]*Var[i,j],(j,0,1)),(i,0,1) ) sp.init_printing() display(Org) display(Var) display(Trg) print("x^TAx="+sp.latex(Trg)) x^TAx=3 x_{1}^{2} - 2 x_{1} x_{2} + 4 x_{2}^{2} ところで上で$x_1^2+2X_1X_2+X_2^2$に対応する二次形式行列から(マスキング概念の援用で)強引に対角角成分のみを抽出したら$x_1^2+X_2^2$だけが残りました。この様な操作を対角化(Diagonalization)といい、計算の正しい全体像は以下となります。 対角化 - Wikipedia 対角行列 - Wikipedia import sympy as sp a11,a12,a21,a22= sp.symbols('a11,a12,a21,a22') x=sp.Matrix([[a11,a12],[a21,a22]]) x1=x.det() y1=x.eigenvals() y2=x.eigenvects() y3=x.diagonalize() sp.init_printing() display(x) display(x1) display(y1) display(y2) display(y3) print(sp.latex(x)+"行列式"+sp.latex(x1) +"→"+"固有値"+sp.latex(y1) +"固有ベクトル"+sp.latex(y2) +"→対角化"+ sp.latex(y3)) \left[\begin{matrix}a_{11} & a_{12}\\a_{21} & a_{22}\end{matrix}\right]行列式a_{11} a_{22} - a_{12} a_{21} \\ →固有値\left\{ \frac{a_{11}}{2} + \frac{a_{22}}{2} - \frac{\sqrt{a_{11}^{2} - 2 a_{11} a_{22} + 4 a_{12} a_{21} + a_{22}^{2}}}{2} : 1, \ \frac{a_{11}}{2} + \frac{a_{22}}{2} + \frac{\sqrt{a_{11}^{2} - 2 a_{11} a_{22} + 4 a_{12} a_{21} + a_{22}^{2}}}{2} : 1\right\} \\ 固有ベクトル\left[ \left( \frac{a_{11}}{2} + \frac{a_{22}}{2} - \frac{\sqrt{a_{11}^{2} - 2 a_{11} a_{22} + 4 a_{12} a_{21} + a_{22}^{2}}}{2}, \ 1, \ \left[ \left[\begin{matrix}- \frac{2 a_{12}}{a_{11} - a_{22} + \sqrt{a_{11}^{2} - 2 a_{11} a_{22} + 4 a_{12} a_{21} + a_{22}^{2}}}\\1\end{matrix}\right]\right]\right), \ \left( \frac{a_{11}}{2} + \frac{a_{22}}{2} + \frac{\sqrt{a_{11}^{2} - 2 a_{11} a_{22} + 4 a_{12} a_{21} + a_{22}^{2}}}{2}, \ 1, \ \left[ \left[\begin{matrix}- \frac{2 a_{12}}{a_{11} - a_{22} - \sqrt{a_{11}^{2} - 2 a_{11} a_{22} + 4 a_{12} a_{21} + a_{22}^{2}}}\\1\end{matrix}\right]\right]\right)\right] \\ →対角化\left( \left[\begin{matrix}- \frac{2 a_{12}}{a_{11} - a_{22} + \sqrt{a_{11}^{2} - 2 a_{11} a_{22} + 4 a_{12} a_{21} + a_{22}^{2}}} & \frac{2 a_{12}}{- a_{11} + a_{22} + \sqrt{a_{11}^{2} - 2 a_{11} a_{22} + 4 a_{12} a_{21} + a_{22}^{2}}}\\1 & 1\end{matrix}\right], \ \left[\begin{matrix}\frac{a_{11}}{2} + \frac{a_{22}}{2} - \frac{\sqrt{a_{11}^{2} - 2 a_{11} a_{22} + 4 a_{12} a_{21} + a_{22}^{2}}}{2} & 0\\0 & \frac{a_{11}}{2} + \frac{a_{22}}{2} + \frac{\sqrt{a_{11}^{2} - 2 a_{11} a_{22} + 4 a_{12} a_{21} + a_{22}^{2}}}{2}\end{matrix}\right]\right) 式自体は複雑だが計算自体はコンピューターに任せてしまうものとする。ここで重要なのは「対角化の計算結果は固有ベクトル(列ベクトル=縦ベクトル)を行で連ねた(横に並べた)変換行列と、その変換結果としての固有値を対角線上に並べた対角行列のセットで示される」なる全体イメージの獲得(この考え方の延長線上にジョルダン標準形への変換が現れる)。 Sympyの出力を見る限り、省略はされているものの、一応以下の場合を自明解として含むっぽい? \begin{bmatrix}1 & 0\\0 & 1\end{bmatrix} それでは具体的に以下の行列を代入した結果を求めていきましょう。 \begin{bmatrix}1 & 1\\1 & 1\end{bmatrix} import sympy as sp x=sp.Matrix([[1,1],[1,1]]) y1=x.eigenvals() y2=x.eigenvects() y3=x.diagonalize() sp.init_printing() display(x) display(y1) display(y2) display(y3) print(sp.latex(x)+"→"+"固有値"+sp.latex(y1)+"固有ベクトル"+sp.latex(y2)+"→対角化"+ sp.latex(y3)) \left[\begin{matrix}1 & 1\\1 & 1\end{matrix}\right]行列式0 \\ →固有値\left\{ 0 : 1, \ 2 : 1\right\} \\ 固有ベクトル\left[ \left( 0, \ 1, \ \left[ \left[\begin{matrix}-1\\1\end{matrix}\right]\right]\right), \ \left( 2, \ 1, \ \left[ \left[\begin{matrix}1\\1\end{matrix}\right]\right]\right)\right] \\ →対角化\left( \left[\begin{matrix}-1 & 1\\1 & 1\end{matrix}\right], \ \left[\begin{matrix}0 & 0\\0 & 2\end{matrix}\right]\right) 行列式の結果が0なのに答えが算出されている。ある種の極限解っぽい? どうやらこの辺りに、ずっと悩んできた「偶数系と奇数系の分離」問題の回答も潜んでいるのかもしれない? 偶数系(スカラー)から奇数系への変換行列?:\begin{bmatrix}-1 & 1\\1 & 1\end{bmatrix}\\ その結果現れる奇数系行列?:\begin{bmatrix}0 & 0\\0 & 2\end{bmatrix} それ以外の行列の代入結果 Pythonで線形代数!固有値と固有ベクトルを求める \begin{bmatrix}3 & 0\\1 & 2\end{bmatrix} import sympy as sp a11,a12,a21,a22= sp.symbols('a11,a12,a21,a22') x0=sp.Matrix([[a11,a12],[a21,a22]]) x=x0.subs([(a11,3),(a12,0),(a21,1),(a22,2)]) x1=x.det() y1=x.eigenvals() y2=x.eigenvects() y3=x.diagonalize() sp.init_printing() display(x) display(x1) display(y1) display(y2) display(y3) print(sp.latex(x)+"行列式"+sp.latex(x1) +"→"+"固有値"+sp.latex(y1) +"固有ベクトル"+sp.latex(y2) +"→対角化"+ sp.latex(y3)) \left[\begin{matrix}3 & 0\\1 & 2\end{matrix}\right]行列式6 \\ →固有値\left\{ 2 : 1, \ 3 : 1\right\} \\ 固有ベクトル\left[ \left( 2, \ 1, \ \left[ \left[\begin{matrix}0\\1\end{matrix}\right]\right]\right), \ \left( 3, \ 1, \ \left[ \left[\begin{matrix}1\\1\end{matrix}\right]\right]\right)\right]→ \\ 対角化\left( \left[\begin{matrix}0 & 1\\1 & 1\end{matrix}\right], \ \left[\begin{matrix}2 & 0\\0 & 3\end{matrix}\right]\right) 二次形式の意味,微分,標準形など \begin{bmatrix}3 & -1\\-1 & 3\end{bmatrix} import sympy as sp a11,a12,a21,a22= sp.symbols('a11,a12,a21,a22') x0=sp.Matrix([[a11,a12],[a21,a22]]) x=x0.subs([(a11,3),(a12,-1),(a21,-1),(a22,3)]) x1=x.det() y1=x.eigenvals() y2=x.eigenvects() y3=x.diagonalize() sp.init_printing() display(x) display(x1) display(y1) display(y2) display(y3) print(sp.latex(x)+"行列式"+sp.latex(x1) +"→"+"固有値"+sp.latex(y1) +"固有ベクトル"+sp.latex(y2) +"→対角化"+ sp.latex(y3)) \left[\begin{matrix}3 & -1\\-1 & 3\end{matrix}\right]行列式8 \\ →固有値\left\{ 2 : 1, \ 4 : 1\right\} \\ 固有ベクトル\left[ \left( 2, \ 1, \ \left[ \left[\begin{matrix}1\\1\end{matrix}\right]\right]\right), \ \left( 4, \ 1, \ \left[ \left[\begin{matrix}-1\\1\end{matrix}\right]\right]\right)\right] \\ →対角化\left( \left[\begin{matrix}1 & -1\\1 & 1\end{matrix}\right], \ \left[\begin{matrix}2 & 0\\0 & 4\end{matrix}\right]\right) 二次形式$3x^2−2xy+3y^2$を以下の様に変数変換します。 \begin{bmatrix}X\\Y\end{bmatrix}=\frac{1}{\sqrt{2}}\begin{bmatrix}1 & 1\\1 & -1\end{bmatrix}\begin{bmatrix}x\\y\end{bmatrix} すると以下の様にクロスタームがないきれいな二次形式に変換されます。 3x^2−2xy+3y^2 \\ =2(\frac{x}{\sqrt{2}}+\frac{y}{\sqrt{2}})^2+4(\frac{x}{\sqrt{2}}+\frac{y}{\sqrt{2}})^2 \\ =2X^2+4Y^2 平方完成の多変数バージョンです。この様に一般に二次形式$x^TAx$を標準形になおすことは,対称行列Aの対角化に対応します。 対称行列の固有値と固有ベクトルの性質の証明 \begin{bmatrix}5 & 2\\2 & 2\end{bmatrix} import sympy as sp a11,a12,a21,a22= sp.symbols('a11,a12,a21,a22') x0=sp.Matrix([[a11,a12],[a21,a22]]) x=x0.subs([(a11,5),(a12,2),(a21,2),(a22,2)]) x1=x.det() y1=x.eigenvals() y2=x.eigenvects() y3=x.diagonalize() sp.init_printing() display(x) display(x1) display(y1) display(y2) display(y3) print(sp.latex(x)+"行列式"+sp.latex(x1) +"→"+"固有値"+sp.latex(y1) +"固有ベクトル"+sp.latex(y2) +"→対角化"+ sp.latex(y3)) \left[\begin{matrix}5 & 2\\2 & 2\end{matrix}\right]行列式6 \\ →固有値\left\{ 1 : 1, \ 6 : 1\right\} \\ 固有ベクトル\left[ \left( 1, \ 1, \ \left[ \left[\begin{matrix}- \frac{1}{2}\\1\end{matrix}\right]\right]\right), \ \left( 6, \ 1, \ \left[ \left[\begin{matrix}2\\1\end{matrix}\right]\right]\right)\right] \\ →対角化\left( \left[\begin{matrix}-1 & 2\\2 & 1\end{matrix}\right], \ \left[\begin{matrix}1 & 0\\0 & 6\end{matrix}\right]\right) 固有方程式は$\lambda^2-7\lambda+6=0$なので,固有値は$\lambda=1,6$。 $\lambda=1$に対応する固有ベクトル \begin{bmatrix}1\\-2\end{bmatrix} $\lambda=6$に対応する固有ベクトル \begin{bmatrix}2\\1\end{bmatrix} 固有値は実数で,二本の固有ベクトルは直交する! かくしてここに直交行列(Orthogonal Matrix)の概念が乱入してくる訳です。 直交行列 - Wikipedia 固有値,固有ベクトルの定義と具体的な計算方法 \begin{bmatrix}3&1\\2&2\end{bmatrix} import sympy as sp a11,a12,a21,a22= sp.symbols('a11,a12,a21,a22') x0=sp.Matrix([[a11,a12],[a21,a22]]) x=x0.subs([(a11,3),(a12,1),(a21,2),(a22,2)]) x1=x.det() y1=x.eigenvals() y2=x.eigenvects() y3=x.diagonalize() sp.init_printing() display(x) display(x1) display(y1) display(y2) display(y3) print(sp.latex(x)+"行列式"+sp.latex(x1) +"→"+"固有値"+sp.latex(y1) +"固有ベクトル"+sp.latex(y2) +"→対角化"+ sp.latex(y3)) \left[\begin{matrix}3 & 1\\2 & 2\end{matrix}\right]行列式4 \\ →固有値\left\{ 1 : 1, \ 4 : 1\right\} \\ 固有ベクトル\left[ \left( 1, \ 1, \ \left[ \left[\begin{matrix}- \frac{1}{2}\\1\end{matrix}\right]\right]\right), \ \left( 4, \ 1, \ \left[ \left[\begin{matrix}1\\1\end{matrix}\right]\right]\right)\right] \\ →対角化\left( \left[\begin{matrix}-1 & 1\\2 & 1\end{matrix}\right], \ \left[\begin{matrix}1 & 0\\0 & 4\end{matrix}\right]\right) 以下の式より出発する。 A-\lambda I=\begin{bmatrix} 3-\lambda & 1\\ 2 & 2-\lambda \end{bmatrix} これより特性方程式は$(3-\lambda)(2-\lambda)-2=0$。これを解くと$\lambda=1, 4$となり固有値が求まる。 ・ $\lambda=1$に対応する固有ベクトルは以下の解である。 (A-I)\overrightarrow{x}=\begin{bmatrix} 2&1\\ 2&1\end{bmatrix}\overrightarrow{x}=0 よってその固有ベクトルは以下の定数倍と求まる。 \begin{bmatrix}1\\-2\end{bmatrix} $\lambda=4λ=4$に対応する固有ベクトルは以下の解である。 (A-4I)\overrightarrow{x}=\begin{bmatrix} -1&1\\ 2&-2\end{bmatrix} よってその固有ベクトルは以下の定数倍と求まる。 \begin{bmatrix}1\\1\end{bmatrix} なお固有ベクトルで重要なのは向きのみ(長さは自由に決めれる)なので$k\overrightarrow{x}(k\neq 0)$もまたその$\overrightarrow{x}$の固有値$\lambda$に対応する固有ベクトルとなる。実際、Sympyの計算には随所に「約分」が見て取れる。 三次以上でも同様です。三次の場合,特性方程式が三次方程式になる&固有ベクトルを三本求めるために三回連立方程式を解かないといけないのでかなりめんどうですが、各種試験では平気で出題されるのでできるようにしておきましょう。 上記の手順だけでは不十分な場合(AA が対角化できない場合)も稀に登場します。しかし,実際工学的に登場する行列はほとんどが対角化できる&対角化できない場合を厳密に議論するのはけっこうめんどうなので省略します。特性方程式が重解を持たない場合は問題なしです! 特に重要なのは「対称行列の固有値と固有ベクトルは全て実数でかつ直交する(すなわち直交行列となる)」なる定理っぽい(棒読み)。 ところどころ「Sympyの計算結果」と「説明」の第一列目の向きが反転している様に見えるのだけど、気のせい? 学部1年で習う線形代数の一つの目標は固有値の概念を理解することだと思います。 なるほど、いつの間にかそんな領域まで踏み込んでいたんですね。 Python(SymPy)で学ぶ行列の固有値とJordan標準形 \begin{bmatrix}1&2\\3&2\end{bmatrix} import sympy as sp a11,a12,a21,a22= sp.symbols('a11,a12,a21,a22') x0=sp.Matrix([[a11,a12],[a21,a22]]) x=x0.subs([(a11,1),(a12,2),(a21,3),(a22,2)]) x1=x.det() y1=x.eigenvals() y2=x.eigenvects() y3=x.diagonalize() sp.init_printing() display(x) display(x1) display(y1) display(y2) display(y3) print(sp.latex(x)+"行列式"+sp.latex(x1) +"→"+"固有値"+sp.latex(y1) +"固有ベクトル"+sp.latex(y2) +"→対角化"+ sp.latex(y3)) \left[\begin{matrix}1 & 2\\3 & 2\end{matrix}\right]行列式-4 \\ →固有値\left\{ -1 : 1, \ 4 : 1\right\} \\ 固有ベクトル\left[ \left( -1, \ 1, \ \left[ \left[\begin{matrix}-1\\1\end{matrix}\right]\right]\right), \ \left( 4, \ 1, \ \left[ \left[\begin{matrix}\frac{2}{3}\\1\end{matrix}\right]\right]\right)\right] \\ →対角化\left( \left[\begin{matrix}-1 & 2\\1 & 3\end{matrix}\right], \ \left[\begin{matrix}-1 & 0\\0 & 4\end{matrix}\right]\right) この様にn次正方行列に対し、線型独立な固有ベクトルがn個ある場合には行列を対角化することができますが、一般には線形独立な固有ベクトルの個数はnより小さくなります。 \begin{bmatrix}1&-2\\2&5\end{bmatrix} import sympy as sp a11,a12,a21,a22= sp.symbols('a11,a12,a21,a22') x0=sp.Matrix([[a11,a12],[a21,a22]]) x=x0.subs([(a11,1),(a12,2),(a21,-2),(a22,5)]) x1=x.det() y1=x.eigenvals() y2=x.eigenvects() sp.init_printing() display(x) display(x1) display(y1) display(y2) print(sp.latex(x)+"行列式"+sp.latex(x1) +"→"+"固有値"+sp.latex(y1) +"固有ベクトル"+sp.latex(y2)) \left[\begin{matrix}1 & 2\\-2 & 5\end{matrix}\right]行列式9 \\ →固有値\left\{ 3 : 2\right\} \\ 固有ベクトル\left[ \left( 3, \ 2, \ \left[ \left[\begin{matrix}1\\1\end{matrix}\right]\right]\right)\right] 例えばこの行列は固有値3(縮重度は2)を持ちますが、固有ベクトルが(定数倍の自由度を除いて)ただ一つしかないので正則行列が作れず、行列を対角化することができません。そういう場合も適切な変換行列を用いてジョルダン標準形に変形する事が出来ます。 import sympy as sp a11,a12,a21,a22= sp.symbols('a11,a12,a21,a22') x0=sp.Matrix([[a11,a12],[a21,a22]]) x=x0.subs([(a11,1),(a12,2),(a21,-2),(a22,5)]) q=x.jordan_form() Q=sp.Matrix([[-2,1],[-2,0]]) J=Q.inv()*x*Q sp.init_printing() display(x) print(sp.latex(x)) display(q) print(sp.latex(q)) display(Q) print(sp.latex(Q)) display(J) print(sp.latex(J)) \left[\begin{matrix}1 & 2\\-2 & 5\end{matrix}\right]→\left( \left[\begin{matrix}-2 & 1\\-2 & 0\end{matrix}\right], \ \left[\begin{matrix}3 & 1\\0 & 3\end{matrix}\right]\right) \\ J=\left[\begin{matrix}-2 & 1\\-2 & 0\end{matrix}\right]^{-1}\left[\begin{matrix}1 & 2\\-2 & 5\end{matrix}\right]\left[\begin{matrix}-2 & 1\\-2 & 0\end{matrix}\right]=\left[\begin{matrix}3 & 1\\0 & 3\end{matrix}\right] Jordan標準形と呼ばれる形をした行列を考えることのメリットの一つとして、その累乗が対角化可能な行列同様に簡単に求められる事が挙げられます。 行列のn乗の求め方と例題 まずは正方数列Aを対角化する、すなわち$D=P^{-1}AP$,$A=P^{-1}DP$となる変換行列Pと対角行列Dの固有対を求める。 \begin{bmatrix}3&1\\2&2\end{bmatrix} import sympy as sp a11,a12,a21,a22= sp.symbols('a11,a12,a21,a22') x0=sp.Matrix([[a11,a12],[a21,a22]]) x=x0.subs([(a11,3),(a12,1),(a21,2),(a22,2)]) x1=x.det() y1=x.eigenvals() y2=x.eigenvects() y3=x.diagonalize() sp.init_printing() display(x) display(x1) display(y1) display(y2) display(y3) print(sp.latex(x)+"行列式"+sp.latex(x1) +"→"+"固有値"+sp.latex(y1) +"固有ベクトル"+sp.latex(y2) +"→対角行化"+ sp.latex(y3)) \left[\begin{matrix}3 & 1\\2 & 2\end{matrix}\right]行列式4 \\ →固有値\left\{ 1 : 1, \ 4 : 1\right\} \\ 固有ベクトル\left[ \left( 1, \ 1, \ \left[ \left[\begin{matrix}- \frac{1}{2}\\1\end{matrix}\right]\right]\right), \ \left( 4, \ 1, \ \left[ \left[\begin{matrix}1\\1\end{matrix}\right]\right]\right)\right] \\ →対角行列化\left( \left[\begin{matrix}-1 & 1\\2 & 1\end{matrix}\right], \ \left[\begin{matrix}1 & 0\\0 & 4\end{matrix}\right]\right) n乗の計算が大幅に省力化されるが、$A^n=P^{-1}D^nP$を求めると同じ結果となる。 import sympy as sp a11,a12,a21,a22= sp.symbols('a11,a12,a21,a22') n=sp.symbols('n', integer = True) A=sp.Matrix([[3,1],[2,2]]) D=sp.Matrix([[1,0],[0,4]]) P=sp.Matrix([[-1,1],[2,1]]) Pr=P.inv() sp.init_printing() display(Pr*D*P) print("D=P^{-1}AP="+sp.latex(Pr)+sp.latex(A)+sp.latex(P)+"="+sp.latex(D)) display(Pr*A*P) print("A=P^{-1}DP="+sp.latex(Pr)+sp.latex(D)+sp.latex(P)+"="+sp.latex(A)) display(P) display(Pr) display(A**n) print("A^n="+sp.latex(A**n)) display(P*D**n*Pr) print("A^n=P^{-1}D^nP="+sp.latex(Pr)+sp.latex(D**n)+sp.latex(Pr)+"="+sp.latex(P*D**n*Pr)) D=P^{-1}AP=\left[\begin{matrix}- \frac{1}{3} & \frac{1}{3}\\\frac{2}{3} & \frac{1}{3}\end{matrix}\right]\left[\begin{matrix}3 & 1\\2 & 2\end{matrix}\right]\left[\begin{matrix}-1 & 1\\2 & 1\end{matrix}\right]=\left[\begin{matrix}1 & 0\\0 & 4\end{matrix}\right] \\ A=P^{-1}DP=\left[\begin{matrix}- \frac{1}{3} & \frac{1}{3}\\\frac{2}{3} & \frac{1}{3}\end{matrix}\right]\left[\begin{matrix}1 & 0\\0 & 4\end{matrix}\right]\left[\begin{matrix}-1 & 1\\2 & 1\end{matrix}\right]=\left[\begin{matrix}3 & 1\\2 & 2\end{matrix}\right] \\ A^n=\left[\begin{matrix}\frac{2 \cdot 4^{n}}{3} + \frac{1}{3} & \frac{4^{n}}{3} - \frac{1}{3}\\\frac{2 \cdot 4^{n}}{3} - \frac{2}{3} & \frac{4^{n}}{3} + \frac{2}{3}\end{matrix}\right]\\ A^n=P^{-1}D^nP=\left[\begin{matrix}- \frac{1}{3} & \frac{1}{3}\\\frac{2}{3} & \frac{1}{3}\end{matrix}\right]\left[\begin{matrix}1 & 0\\0 & 4^{n}\end{matrix}\right]\left[\begin{matrix}- \frac{1}{3} & \frac{1}{3}\\\frac{2}{3} & \frac{1}{3}\end{matrix}\right]=\left[\begin{matrix}\frac{2 \cdot 4^{n}}{3} + \frac{1}{3} & \frac{4^{n}}{3} - \frac{1}{3}\\\frac{2 \cdot 4^{n}}{3} - \frac{2}{3} & \frac{4^{n}}{3} + \frac{2}{3}\end{matrix}\right] 対角化出来ない正方数列Aの場合は$J=Q^{-1}JQ$,$J=Q^{-1}JQ$となる変換行列Qとジョルダン標準形Jの対を求めると同様にn乗の計算が省力化される。 対角化可能な正方行列と異なり$J=Q^{-1}AQ$のみが成立し$A=P^{-1}JP$は成立しない点に注意。 \begin{bmatrix}1&-2\\2&5\end{bmatrix} import sympy as sp a11,a12,a21,a22= sp.symbols('a11,a12,a21,a22') x=sp.Matrix([[a11,a12],[a21,a22]]) A=x.subs([(a11,1),(a12,2),(a21,-2),(a22,5)]) q=A.jordan_form() Q=sp.Matrix([[-2,1],[-2,0]]) Qr=Q.inv() J=sp.Matrix([[3,1],[0,3]]) sp.init_printing() display(q) print(sp.latex(A)+"→"+sp.latex(q)) display(A) display(Qr*A*Q) print("J=Q^{-1}AQ="+sp.latex(Qr)+sp.latex(A)+sp.latex(Q)+"="+sp.latex(Qr*A*Q)) display(Q) display(Pr) display(A**n) print("A^n="+sp.latex(A**n)) display(J**n) print("J^n="+sp.latex(J**n)) \left[\begin{matrix}1 & 2\\-2 & 5\end{matrix}\right]→\left( \left[\begin{matrix}-2 & 1\\-2 & 0\end{matrix}\right], \ \left[\begin{matrix}3 & 1\\0 & 3\end{matrix}\right]\right) // J=Q^{-1}AQ=\left[\begin{matrix}0 & - \frac{1}{2}\\1 & -1\end{matrix}\right]\left[\begin{matrix}1 & 2\\-2 & 5\end{matrix}\right]\left[\begin{matrix}-2 & 1\\-2 & 0\end{matrix}\right]=\left[\begin{matrix}3 & 1\\0 & 3\end{matrix}\right] \\ A^n=\left[\begin{matrix}3^{n} - 2 \cdot 3^{n - 1} n & 2 \cdot 3^{n - 1} n\\- 2 \cdot 3^{n - 1} n & 3^{n} + 2 \cdot 3^{n - 1} n\end{matrix}\right] \\ J^n=\left[\begin{matrix}3^{n} & 3^{n - 1} n\\0 & 3^{n}\end{matrix}\right] そしてどうやらジョルダン標準形への変換は固有空間から広義固有空間への拡大に対応する様なんです?(棒読み) 今こそJordan標準形と向き合う ベクトル空間上の線形写像は行列によって表現することができる。特に線形変換は線形写像であるから、これも行列によって表現可能である。 行列というのは線形変換をある基底に対して表現したものに過ぎず、基底の取り方によって姿を変え得る。唯一不変なのはその背後にある線形変換Tであり、線形変換を通して行列の振る舞いを考えることがJordan標準形の理解へと繋がる。 Jordan標準形になっていないn次正方行列Bを考える。Bをあるベクトル空間V上の線形変換Tの表現行列であると考えると、これは基底として広義固有ベクトル以外のものを選んだ場合であると解釈できる。これをJordan標準形に変形する事は、基底を広義固有ベクトルに取り替えることを意味する。 結局、線形変換の基底として広義固有ベクトルを選んだ場合の表現行列こそが、Jordan標準形の正体なのである。 おそらくジョルダン標準形への変換では$J=Q^{-1}AQ$のみが成立し$A=P^{-1}JP$は成立しない事と関わってくるのでしょうが、現時点では私の理解可能な範囲を超えています。 それと${}_nC_n=1$が現れるか右端に到達するまで計算を続けるジョルダン細胞(Jordan Block)のn乗の計算方法に何となくパスカルの三角形との関連性が見て取れる気もしますが、この辺りも現時点では私の理解可能な範囲を超えています。 行列のn乗の求め方と例題 ジョルダン標準形の意味と求め方 ジョルダン細胞のn乗 [物理のかぎしっぽ] ジョルダン細胞とn乗の計算 - 新米夫婦のふたりごと 行列操作の基礎②二次形式の微分 二次形式の意味,微分,標準形など 二次形式$x^TAxの微分(勾配ベクトル)は2Axとなります。ちなみに勾配ベクトル(Gradient)$\nabla f$とは各変数での微分を並べたベクトルのことです。勾配ベクトルの意味と例題 $3x_1^2-2x_1x_2+4x_2^2$の場合 $x_1$で偏微分すると$6x_1-2x_2$。 $x_2$で偏微分すると$-2x_1+8x_2$。 import sympy as sp x1,x2 = sp.symbols('x1,x2') #元関数 f=3*x1**2-2*x1*x2+4*x2**2 #x1について偏微分 g=sp.diff(f,x1,1) #x2について偏微分 h=sp.diff(f,x2,1) #画面表示 sp.init_printing() display(f) print(sp.latex(f)) display(g) print(sp.latex(g)) display(h) print(sp.latex(h)) 3 x_{1}^{2} - 2 x_{1} x_{2} + 4 x_{2}^{2}\frac{dy}{dx_1}=6 x_{1} - 2 x_{2}\\ 3 x_{1}^{2} - 2 x_{1} x_{2} + 4 x_{2}^{2}\frac{dy}{dx_2}=- 2 x_{1} + 8 x_{2} よって勾配ベクトルは以下。 \begin{bmatrix}6x_1-2x_2\\-2x_1+8x_2\end{bmatrix} ところでこの二次方程式に対応する対称行列は以下でした。 \begin{bmatrix}3&-1\\-1&4\end{bmatrix} よって以下が成立します。 2Ax=2\begin{bmatrix}3&-1\\-1&4\end{bmatrix} \begin{bmatrix}X_1\\x_2\end{bmatrix} 具体例で確認しましたが,一般の二次形式の微分が$2Ax$になることも,成分計算で証明できます。 ちなみに,1変数の場合は「$ax^2$の微分が$2ax$になる」高校数学の微分公式となります。【数理考古学】冪乗算(Exponentiation)の微積分 行列操作の基礎③二次形式と行列のトレース 二次形式の意味,微分,標準形など 二次形式は行列のトレースを用いて$x^{T}Ax=tr(Axx^T)$の形で表現する事も出来ます。統計とかでときどき使う公式です。 import sympy as sp a11,a12,a21,a22= sp.symbols('a11,a12,a21,a22') x1,x2= sp.symbols('x1,x2') A=sp.Matrix([[a11,a12],[a21,a22]]) X=sp.Matrix([[x1],[x2]]) XT=X.transpose() Trg=A*X*XT display(A) print("A="+sp.latex(A)) display(X) display(XT) print("X^T="+sp.latex(X)+"^T="+ sp.latex(XT)) display(Trg) print("tr(AXX^T)=tr("+sp.latex(Trg)+")="+ sp.latex(Trg.trace())) A=\left[\begin{matrix}a_{11} & a_{12}\\a_{21} & a_{22}\end{matrix}\right] \\ X^T=\left[\begin{matrix}x_{1}\\x_{2}\end{matrix}\right]^T=\left[\begin{matrix}x_{1} & x_{2}\end{matrix}\right] \\ tr(AXX^T)=tr(\left[\begin{matrix}x_{1} \left(a_{11} x_{1} + a_{12} x_{2}\right) & x_{2} \left(a_{11} x_{1} + a_{12} x_{2}\right)\\x_{1} \left(a_{21} x_{1} + a_{22} x_{2}\right) & x_{2} \left(a_{21} x_{1} + a_{22} x_{2}\right)\end{matrix}\right])=x_{1} \left(a_{11} x_{1} + a_{12} x_{2}\right) + x_{2} \left(a_{21} x_{1} + a_{22} x_{2}\right) 統計分野でも行列計算は重要な役割を果たしているのですね。 書評『統計のための行列代数』 詳し内容についての勉強はこれからです。 行列のトレースのいろんな性質とその証明 トレースは正方行列に対して定まる実数で、行列式と並ぶ重要な量ですが行列式と違ってその定義は非常に単純(対角要素の和)です! それが行列Aの固有値の和になっているのも重要な特徴の一つです。 Aの固有値を\lambda_1,\cdots,\lambda_nとおく。 \\ \mathrm{tr}\:A=\displaystyle\sum_{i=1}^n\lambda_i 実際に計算してみましょう。 これを「非常に単純」と断言する「高校数学の美しい物語」管理人って鬼過ぎじゃなくて? まぁ「足したら確かに同じ」なんですが…(積分定数が存在する事による)不定積分の「不定性」が定積分では消えてしまうのと同じトリックを感じずにはいられません!! 【数理考古学】冪乗算(Exponentiation)の微積分 \begin{bmatrix}2&4\\-1&3\end{bmatrix} import sympy as sp a11,a12,a21,a22= sp.symbols('a11,a12,a21,a22') x=sp.Matrix([[a11,a12],[a21,a22]]) A=x.subs([(a11,2),(a12,4),(a21,-1),(a22,3)]) T=A.trace() e=A.eigenvals() sp.init_printing() display(A) display(T) print("tr("+sp.latex(A)+")="+sp.latex(T)) display(e) print("固有値"+sp.latex(e)) tr(\left[\begin{matrix}2 & 4\\-1 & 3\end{matrix}\right])=5 \\ 固有値\left\{ \frac{5}{2} - \frac{\sqrt{15} i}{2} : 1, \ \frac{5}{2} + \frac{\sqrt{15} i}{2} : 1\right\} \\ (\frac{5}{2} - \frac{\sqrt{15} i}{2})+(\frac{5}{2} + \frac{\sqrt{15} i}{2} )=5 その基本的性質 1. tr(r*A)=r*tr(A) \\ 2. tr(A+B)=tr(A)+tr(B) \\ 3. tr(A^T)=tr(A) \\ 4.tr(AB^T)=sum_{i=1}^n\sum_{j=1}^na_{ij}b_{ij} \\ 5.tr(AB)=tr(BA) 1〜3いずれもトレースの定義より明らかです。 1と2はトレースの線形性を表しています。 3は対角要素が転置によって影響を受けない事に対応します。 4.5は,積ABのトレースの話です。 4の右辺は行列Aと行列Bの内積であり,しばしばお目にかかります。サイズ2の場合について実際に計算してみましょう。 import sympy as sp a11,a12,a21,a22= sp.symbols('a11,a12,a21,a22') b11,b12,b21,b22= sp.symbols('b11,b12,b21,b22') i,j=sp.symbols('i,j', integer = True) A=sp.Matrix([[a11,a12],[a21,a22]]) B=sp.Matrix([[b11,b12],[b21,b22]]) BT=B.transpose() ABT=A*BT Trg=sp.summation(sp.summation(A[i,j]*B[i,j],(j,0,1)),(i,0,1) ) display(A) print("A="+sp.latex(A)) display(B) display(BT) print("B^T="+sp.latex(B)+"^T→"+ sp.latex(BT)) display(ABT) print("AB^T="+sp.latex(ABT)) display(ABT.trace()) display(Trg) print("tr(AB^T)=\sum_{i=1}^n\sum_{j=1}^na_{ij}b_{ij}="+sp.latex(Trg)) A=\left[\begin{matrix}a_{11} & a_{12}\\a_{21} & a_{22}\end{matrix}\right] \\ B^T=\left[\begin{matrix}b_{11} & b_{12}\\b_{21} & b_{22}\end{matrix}\right]^T→\left[\begin{matrix}b_{11} & b_{21}\\b_{12} & b_{22}\end{matrix}\right] \\ AB^T=\left[\begin{matrix}a_{11} b_{11} + a_{12} b_{12} & a_{11} b_{21} + a_{12} b_{22}\\a_{21} b_{11} + a_{22} b_{12} & a_{21} b_{21} + a_{22} b_{22}\end{matrix}\right] \\ tr(AB^T)=\sum_{i=1}^n\sum_{j=1}^na_{ij}b_{ij}=a_{11} b_{11} + a_{12} b_{12} + a_{21} b_{21} + a_{22} b_{22} 5はトレースの交換法則で、4から証明できます。これも重要です! 4よりtr(AB)=\sum_{i=1}^n\sum_{j=1}^na_{ij}b_{ji}=\sum_{i=1}^n\sum_{j=1}^nb_{ij}a_{ji}=tr(BA) 注:3つの積についてtr(ABC)=tr(CAB)=tr(BCA)は成立しますが,tr(ABC)=tr(ACB)などは成立するとは限りません。 行列操作の基礎④対称行列と反対称行列 対称行列と反対称行列の性質・分解公式 証明はこちらのサイトでご確認ください。 まずは転置操作による分類から出発します。 import sympy as sp a,b,c,d = sp.symbols('a, b,c,d') x=sp.Matrix([[a,b],[c,d]]) y=x.transpose() sp.init_printing() display(x) display(y) print(sp.latex(x)+"^T="+sp.latex(y)) \left[\begin{matrix}a & b\\c & d\end{matrix}\right]^T=\left[\begin{matrix}a & c\\b & d\end{matrix}\right] 正方行列Aが対称行列である事は転置すなわち$A^T=A$と表現される。 逆を言えば転置しても成分が同じ正方行列が対称行列である。 import sympy as sp a,b,c,d = sp.symbols('a, b,c,d') x=sp.Matrix([[a,b],[c,d]]) X=x.subs([(a,1),(b,0),(c,-0),(d,-1)]) y=x.transpose() Y=X.transpose() Z=X.inv() sp.init_printing() display(X) display(Y) display(Z) print(sp.latex(X)+"^T="+sp.latex(Y)) print(sp.latex(X)+"^{-1}="+sp.latex(Z)) \left[\begin{matrix}1 & 0\\0 & -1\end{matrix}\right]^T=\left[\begin{matrix}1 & 0\\0 & -1\end{matrix}\right]\\ \left[\begin{matrix}1 & 0\\0 & -1\end{matrix}\right]^{-1}=\left[\begin{matrix}1 & 0\\0 & -1\end{matrix}\right] この場合、同時に逆行列でもありますが… 正方行列Aが反対称行列である事は転置すなわち$A^T=-A$によって示される。 逆を言えば転置によって-1倍される正方行列が反対称行列である。 import sympy as sp a,b,c,d = sp.symbols('a, b,c,d') x=sp.Matrix([[a,b],[c,d]]) X=x.subs([(a,0),(b,1),(c,-1),(d,0)]) y=x.transpose() Y=X.transpose() Z=X.inv() sp.init_printing() display(X) display(Y) display(-Y) print(sp.latex(X)+"^T="+sp.latex(Y)) print(sp.latex(X)+"*-1="+sp.latex(-Y)) \left[\begin{matrix}0 & 1\\-1 & 0\end{matrix}\right]^T=\left[\begin{matrix}0 & -1\\1 & 0\end{matrix}\right] \\ \left[\begin{matrix}0 & 1\\-1 & 0\end{matrix}\right]*-1=\left[\begin{matrix}0 & 1\\-1 & 0\end{matrix}\right] そして… 反対称行列の対角成分は0である(二乗して0になる数が0しかない)。 対称行列かつ反対称行列である行列は零行列に限る(実際には、しばしばスカラーと混同される「全ての成分が同じ値で埋め尽くされたアダマール行列およびそのスカラー倍」も含まれる気もする?)。 また任意の正方行列?は以下の式によって対称行列と反対称行列の和に分解する事が可能であり、かつそれが両者の和に分解する唯一の方法である。 A=\frac{A+A^T}{2}+\frac{A-A^T}{2} import sympy as sp a,b,c,d = sp.symbols('a, b,c,d') x=sp.Matrix([[a,b],[c,d]]) X=x.subs([(a,1),(b,0),(c,-0),(d,1)]) Y=x.subs([(a,0),(b,1),(c,1),(d,0)]) sp.init_printing() display(X) display(Y) display(X+Y) print(sp.latex(X)+"+"+sp.latex(Y)+"="+sp.latex(X+Y)) \left[\begin{matrix}1 & 0\\0 & 1\end{matrix}\right]+\left[\begin{matrix}0 & 1\\1 & 0\end{matrix}\right]=\left[\begin{matrix}1 & 1\\1 & 1\end{matrix}\right] 指数関数におけるcosh(x)(カテナリー)とsinh(x)(双曲線関数)の分離、およびその発展形として登場した三角関数におけるCos(θ)とSin(θ)の分離に際しても活用された登場した概念ですね。 行列・関数・多項式に共通する有名な性質 【初心者向け】指数・対数関数の発見とそれ以降の発展について。 e^{x}=\frac{e^{x}+e^{-x}}{2}+\frac{e^{x}-e^{-x}}{2} 【数理考古学】群論とシミュレーション原理④群導出演算としてのオイラーの公式(Eulerien Formula) e^{iθ}=\cos(θ)+\sin(θ)i=\frac{e^{θi}+e^{-θi}}{2}+\frac{e^{θi}-e^{-θi}}{2i} $A^T=-A$となる交代行列(alternating matrix, antisymmetric matrix, skew symmetric matrix=反対称行列,歪対称行列)」は、さらに以下の特徴も備えます。 交代行列の定義と性質 実交代行列の固有値は全て実部が0となる。 実対称行列の固有値は,必ず実数である事は別記事で紹介しています。 対称行列の固有値と固有ベクトルの性質の証明 実交代行列にも同様に,固有値に面白い性質があります。実交代行列の固有値は全て実部が0となるのです。実数であることと,虚部が0であることは同値ですから,実対称行列の性質は「固有値の虚部が0である」とも言い換えられます。 もう一つ,交代行列に関する定理を紹介します。交代行列が固有値λを持つとき,-λも固有値になるのです。共役複素数について「実数係数多項式=0という方程式に関してzが解なら$\overline{z}$も解である」という話がありましたが、なんだかそれに似ていますね。 共役複素数の覚えておくべき性質 import sympy as sp a11,a12,a21,a22= sp.symbols('a11,a12,a21,a22') x0=sp.Matrix([[a11,a12],[a21,a22]]) x=x0.subs([(a11,0),(a12,-1),(a21,1),(a22,0)]) x1=x.det() y1=x.eigenvals() y2=x.eigenvects() y3=x.diagonalize() sp.init_printing() display(x) display(x1) display(y1) display(y2) display(y3) print(sp.latex(x)+"行列式"+sp.latex(x1)) print("→"+"固有値"+sp.latex(y1)) print("固有ベクトル"+sp.latex(y2)) print("→対角化"+ sp.latex(y3)) \left[\begin{matrix}0 & -1\\1 & 0\end{matrix}\right]行列式1 \\ →固有値\left\{ - i : 1, \ i : 1\right\} \\ 固有ベクトル\left[ \left( - i, \ 1, \ \left[ \left[\begin{matrix}- i\\1\end{matrix}\right]\right]\right), \ \left( i, \ 1, \ \left[ \left[\begin{matrix}i\\1\end{matrix}\right]\right]\right)\right] \\ →対角化\left( \left[\begin{matrix}- i & i\\1 & 1\end{matrix}\right], \ \left[\begin{matrix}- i & 0\\0 & i\end{matrix}\right]\right) 確かに交代行列の固有値には虚部しかなく、しかも±対で現れてますね。 行列操作の基礎⑤直交行列 ところで冒頭と「対称行列と反対称行列の和に分解」に登場した以下の2行列、転置の結果がそれ自身であり(対称行列の特徴)、かつ逆行列(反対称行列)だったりします。 import sympy as sp a,b,c,d = sp.symbols('a, b,c,d') x=sp.Matrix([[a,b],[c,d]]) X=x.subs([(a,1),(b,0),(c,-0),(d,1)]) y=x.transpose() Y=X.transpose() Z=X.inv() sp.init_printing() display(X) display(Y) display(Z) print(sp.latex(X)+"^T="+sp.latex(Y)) print(sp.latex(X)+"^{-1}="+sp.latex(Z)) \left[\begin{matrix}1 & 0\\0 & 1\end{matrix}\right]^T=\left[\begin{matrix}1 & 0\\0 & 1\end{matrix}\right] \\ \left[\begin{matrix}1 & 0\\0 & 1\end{matrix}\right]^{-1}=\left[\begin{matrix}1 & 0\\0 & 1\end{matrix}\right] import sympy as sp a,b,c,d = sp.symbols('a, b,c,d') x=sp.Matrix([[a,b],[c,d]]) X=x.subs([(a,0),(b,1),(c,1),(d,0)]) y=x.transpose() Y=X.transpose() Z=X.inv() sp.init_printing() display(X) display(Y) display(Z) print(sp.latex(X)+"^T="+sp.latex(Y)) print(sp.latex(X)+"^{-1}="+sp.latex(Z)) \left[\begin{matrix}0 & 1\\1 & 0\end{matrix}\right]^T=\left[\begin{matrix}0 & 1\\1 & 0\end{matrix}\right] \\ \left[\begin{matrix}0 & 1\\1 & 0\end{matrix}\right]^{-1}=\left[\begin{matrix}0 & 1\\1 & 0\end{matrix}\right] 要するにこれらは直交行列(Orthogonal Matrix)なのですね。 直交行列の5つの定義と性質の証明 1.$U^T=U^{-1}$ 2.Uのn本の行ベクトルが正規直交基底をなす 3.Uのn本の列ベクトルが正規直交基底をなす 4.任意の$x\in \mathbb{R}^n$に対して∥Ux∥=∥x∥ 5.任意の$x,y\in\mathbb{R}^n$に対してUx⋅Uy=x⋅y 2.3における「正規直交」とは,全てのベクトルの長さが1で異なる二本のベクトルの内積が 0であることを意味します。 基底 (線型代数学) - Wikipedia 4は「変換でベクトルのノルム(長さ)が変わらない(等長性)」,5は「変換で二つのベクトルの内積が変わらない」ことを表しています。 その性質 直交行列の行列式は1または-1である。 直交行列の逆行列もまた直交行列である。 対称行列は直交行列で対角化できる。 import sympy as sp a11,a12,a21,a22= sp.symbols('a11,a12,a21,a22') x0=sp.Matrix([[a11,a12],[a21,a22]]) X1=x0.subs([(a11,1),(a12,0),(a21,0),(a22,1)]) X1Det=X1.det() X1Eval=X1.eigenvals() X1Evec=X1.eigenvects() X1Dig=X1.diagonalize() X2=x0.subs([(a11,0),(a12,1),(a21,1),(a22,0)]) X2Det=X2.det() X2Eval=X2.eigenvals() X2Evec=X2.eigenvects() X2Dig=X2.diagonalize() sp.init_printing() display(X1) display(X1Det) display(X1Eval) display(X1Evec) display(X1Evec) display(X1Dig) print(sp.latex(X1)+"行列式"+sp.latex(X1Det)) print("→"+"固有値"+sp.latex(X1Eval)) print("固有ベクトル"+sp.latex(X1Evec)) print("→対角化"+ sp.latex(X1Dig)) display(X2) display(X2Det) display(X2Eval) display(X2Evec) display(X2Evec) display(X2Dig) print(sp.latex(X2)+"行列式"+sp.latex(X2Det)) print("→"+"固有値"+sp.latex(X2Eval)) print("固有ベクトル"+sp.latex(X2Evec)) print("→対角化"+ sp.latex(X2Dig)) 対角成分 \left[\begin{matrix}1 & 0\\0 & 1\end{matrix}\right]行列式1 \\ →固有値\left\{ 1 : 2\right\} \\ 固有ベクトル\left[ \left( 1, \ 2, \ \left[ \left[\begin{matrix}1\\0\end{matrix}\right], \ \left[\begin{matrix}0\\1\end{matrix}\right]\right]\right)\right] \\ →対角化\left( \left[\begin{matrix}1 & 0\\0 & 1\end{matrix}\right], \ \left[\begin{matrix}1 & 0\\0 & 1\end{matrix}\right]\right) 反対角成分 \left[\begin{matrix}0 & 1\\1 & 0\end{matrix}\right]行列式-1 \\ →固有値\left\{ -1 : 1, \ 1 : 1\right\} \\ 固有ベクトル\left[ \left( -1, \ 1, \ \left[ \left[\begin{matrix}-1\\1\end{matrix}\right]\right]\right), \ \left( 1, \ 1, \ \left[ \left[\begin{matrix}1\\1\end{matrix}\right]\right]\right)\right] \\ →対角化\left( \left[\begin{matrix}-1 & 1\\1 & 1\end{matrix}\right], \ \left[\begin{matrix}-1 & 0\\0 & 1\end{matrix}\right]\right) ところでWikipediaに気になる記述があるのです。 直交行列 - Wikipedia n次直交行列全体の集合をn次直交群といいO(n)と書く。行列式の値が1となる直交行列全体の集合を特殊直交群(Special Orthogonal Matrix)といいSO(n) と書く。 え? もしかして群論は特殊でない(長さが1でない)直交群も想定してるというの? 三次形式? 二次形式の意味,微分,標準形など 複素数の二次形式を考えるときはエルミート行列が登場します。三次形式というものも一応あるみたいです。 ここから先は完全に「パスカルの三角形」の世界から離れてしまいます。 import sympy as sp a,b,c = sp.symbols('a,b,c') #Rows x=sp.Matrix([[a,b,c]]) #Columns y=sp.Matrix([[a],[b],[c]]) a=sp.Matrix([[1,1,1],[1,1,1],[1,1,1]]) sp.init_printing() display(x) display(a) display(y) display(sp.simplify(x*a*y)) print(sp.latex(x)+sp.latex(a)+sp.latex(y)+"="+sp.latex(sp.simplify(x*a*y))) \left[\begin{matrix}a & b & c\end{matrix}\right]\left[\begin{matrix}1 & 1 & 1\\1 & 1 & 1\\1 & 1 & 1\end{matrix}\right]\left[\begin{matrix}a\\b\\c\end{matrix}\right]=\left[\begin{matrix}\left(a + b + c\right)^{2}\end{matrix}\right] そんな感じで以下続報…
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AtCoder Beginner Contest D - 2017 - like Number の Python コード

累積和の問題 結構昔の問題です。今更ながら、累積和の勉強の為に解いてみました。 コード like2017.py Q = int(input()) lr = [list(map(int, input().split())) for _ in range(Q)] N = 10 ** 5 prime = [1] * (N + 1) prime[0] = prime[1] = 0 # 素数テーブルの作成 (エラトステネスのふるい) for i in range(2, N + 1): if prime[i]: for j in range(i * i, N + 1, i): prime[j] = 0 # 2017 like number の累積和テーブルの作成 like2017 = [0] * (N + 1) for n in range(1, N + 1): if prime[n] == 0: # n がそもそも素数でなかったから前の値で更新 like2017[n] = like2017[n - 1] continue query = (n + 1) // 2 # n は素数なので奇数であり、n + 1 は必ず 2 で割り切れる数となっている if prime[query] == 1: # (n + 1) // 2 も素数だから、1 を足した値で更新 like2017[n] = like2017[n - 1] + 1 else: # n は素数だったけど、(n + 1) // 2 が素数でなかったから前の値で更新 like2017[n] = like2017[n - 1] for l, r in lr: print(like2017[r] - like2017[l - 1]) 参考 ABC084D - 2017-like Number 累積和を何も考えずに書けるようにする!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Signateの第10回_Beginner限定コンペの振り返り

はじめに データ分析の勉強のために参戦したSIGNATEの第10回_Beginner限定コンペが先日終了したので、振り返るために初めて記事を書くことにしました。文章は拙いと思われますが、よろしければ読んでみてください。 分析環境 結果 コンペ内容 取り組み内容 今回の反省点 良かった点 分析環境 Google Colaboratory 結果 最終順位は2位(178人中)。使用モデルはLGBM(fold-out)。 コンペティション内容について 概要 タスク携帯電話のスペックから携帯電話価格帯を分類する多クラス分類 データ学習データ:1200、テストデータ:800のテーブルデータ 評価指標F1macro 取り組みの大まかな流れ EDA説明変数はすべて量的変数とされていたためカテゴリ変数になりうるものはカテゴリ変数化。 shape、info、describe、headで全体の把握。 ヒストグラム、散布図、箱ひげ図、バイオリンプロットで全体の分布の把握。 カテゴリ変数は全体、クラス毎に相対度数確認。 最後にtargetとの相関関係を確認。 特徴量作成相関係数が極端に低い変数の削除。 カテゴリ変数を確認時、クラスごとに最頻の組み合わせがあったため「{}_{}_{}」という形でカテゴリ変数作成。 学習データ、テストデータを一度合わせて量的変数、カテゴリ変数でクラスターを作成。 カテゴリ変数をtarget encodingで数値化(https://towardsdatascience.com/target-encoding-for-multi-class-classification-c9a7bcb1a53(multilabel化)の方法と通常の方法)。 学習と予測ロジスティック回帰、K近傍法、サポートベクターマシン、決定木、ランダムフォレスト、XGBoost、LightGBMでモデル構築(fold-out、crossvalidation)。 上記のモデルのアンサンブルの実施(バギング、スタッキング) 今回の反省点 githubを使用しなかった上、ファイルも一つで作業を行っていたため、無駄な動作が多くなってしまった。 CVでtarget encodingする方法で躓いてしまったため、fold-outで強引に進めてしまった。 Pytorchを理解していなかったため、TabNetは試すことができなかった。 良かった点 上記に書いてないことも含めていろいろ試すことができた。 TabNetは使用するまでの把握ができなかったが、論文やYoutubeの解説動画を見て学ぶことができた。 今後について 今回うまく行かなかったところを勉強し、使用できるようにする。 Gitについて勉強する。 kaggleのコンペに参加してみる。 最後に 最後まで読んでいただきありがとうございました。次回の投稿時にはもう少し読みやすいようにしたいです。思考の文章化もできればなと思っています 参考 Kaggleで勝つデータ分析の技術(https://gihyo.jp/book/2019/978-4-297-10843-4) 前処理大全(https://gihyo.jp/book/2018/978-4-7741-9647-3) mechanisms-of-action-moa-tutorial(https://www.kaggle.com/sinamhd9/mechanisms-of-action-moa-tutorial) Target Encoding For Multi-Class Classification(https://towardsdatascience.com/target-encoding-for-multi-class-classification-c9a7bcb1a53)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Anaconda「zshでコマンドプロンプトが効かない」

現在、pythonを勉強しようとしております。 本日はmacでAnnacondaをインストール後、zshでcondaコマンドが効かない現象が起きたのでメモとして残しておきます。 zshでcondaコマンドが効かない なぜこの現象が起きたのかを見たところ、Anacondaをインストールした同時にパスを通す記述がされるのは~/.bash_profileだったことが原因なようでした。 ターミナル % conda info zsh: command not found: conda ターミナル % which python /usr/bin/python #macのデフォルトのpythonのパス % python --version Python 2.7.16 #インストールしたのはpython 3.~なはず。。。 自分:「え!ダウンロードしたじゃん!condaコマンド使えるでしょ!おかしいよ!」 zshさん:「....そんなコマンドないし、読み込むパスないもん。」 とりあえずbash_profileの中身を移して解決 ターミナル % less ~/.bash_profile # >>> conda initialize >>> # !! Contents within this block are managed by 'conda init' !! ~(略)~ # <<< conda initialize <<< 上記の中にある/Users/Owner/opt/anaconda3/bin/pythonまでをコピーしてzshファイルに記述する。 ターミナル % vi ~/.zshrc iボタンを押してインサートモードにしてから ↓をペースト /Users/Owner/opt/anaconda3/bin/python escボタンを押し、:wqを入力する。 % source ~/.zshrc 一応ターミナルを再起動 実行後 % which python /Users/Owner/opt/anaconda3/bin/python % python --version Python 3.8.5 こちらで一旦解決できました。 問題点などあれば、コメントいただけますと幸いです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

WIP: Django勉強メモ2

Djangoのツボとコツが絶対に分かる本を学習時の単なるメモ書き2 blog 立ち上げ 以下のコマンドを実行 $ django-admin startproject blogproject $ cd blogproject $ python3 manage.py startapp blogpost blogproject/urls.pyを修正(blogpostのurls.pyを使用するように変更) urls.py urlpatterns = [ XXXX, path('', include('blogpost.urls')), ] blogproject/setting.pyでappを認識させる & htmlファイルが入る場所も限定 setting.py INSTALLED_APPS = [ 'blogpost.apps.BlogpostConfig', TEMPLATES = [ {'DIRS': [os.path.join(BASE_DIR, 'template')] }] blogpostのurls.pyを作成 modelについて データベース関連 setting.pyのDATABASESにデータベースの設定は記載(デフォルトはsqlite3) models.pyに作成するテーブルの情報を記入 models.py class <table_name>(models.Model): <column_name> = models.<type> 以下の2つのコマンドでデータベースに設定を反映 - makemigrations: models.pyから設定用ファイルを作成 - $ python3 manage.py makemigrations (<app名>) - migrations/ というディレクトリが作成される - migrate: 上で作成した設定用ファイルをdatabaseに反映させる - $ python3 manage.py makemigrate $ python3 manage.py createsuperuser: superuserの作成 適当にsu1とかで設定 admin.pyに作成したテーブルについて書くことでadminで確認できるようになる admin.py from .models import <table_name> admin.site.register(<table_name>) CRUDについて CRUDとそのViewとの対応 C: Create -> CreateView R: Read -> ListView, DetailView U: Update -> UpdateView D: Delete -> DeleteView 一覧画面 モデルを作る urls.py: urlpatternsにBlogList (views.pyで定義)を追加 views.py: BlogListを定義 (BlogModelをmodelに使用, list.htmlを使用) models.py: BlogModelを定義 -> makemigratioin, migrate admin.pyに登録 htmlを作る templatesディレクトリを作成 (blogproject直下) templatesにlist.htmlファイルを作成 テンプレート {% %}: 処理(テンプレートタグ) {{ }}: data (テンプレート変数) 詳細画面 urls.pyのurlpatternsに追加 /detail/<int:pk>/ として各データにアクセスする migrations/のidがprimary_key=Trueとなっているのでそれが使われる bootstrapの活用 https://getbootstrap.jp/docs/5.0/getting-started/introduction/
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

モデル契約書ver1.0 秘密保持契約書(新素材)の前文に、日本語NLPライブラリGiNZAを当てはめてみました。

この記事について 「研究開発型スタートアップと事業会社のオープンイノベーション促進のためのモデル契約書ver1.0」の改訂に向けた、GitHub(ギットハブ)を用いた意見募集 (https://github.com/meti-oi-startups/METI-JPO-Model-Contract) のモデル契約書ver1.0 秘密保持契約書(新素材)の前文に、日本語NLPライブラリGiNZAにより、形態素解析を行ってみました。 前提 windows10 pyhton3.8.10 Visual Studio Code 実行 Ginzaの環境構築については、下の記事を参考にしました。 日本語NLPライブラリGiNZAのすゝめ https://qiita.com/poyo46/items/7a4965455a8a2b2d2971 対象テキストを変えただけです。 日本語NLPライブラリGiNZAのすゝめ ソースコードをGitHubで見る https://github.com/poyo46/ginza-examples/blob/master/examples/token_information.py 結果 i text lemma_ reading_form pos_ tag_ inflection ent_type_ 0 X x X NOUN 名詞-普通名詞-一般 1 社 社 シャ NOUN 名詞-普通名詞-助数詞可能 2 ( ( キゴウ PUNCT 補助記号- 括弧開 3 以下 以下 イカ NOUN 名詞-普通名詞-一般 4 「 「 キゴウ PUNCT 補助記号- 括弧開 5 甲 甲 コウ NOUN 名詞-普通名詞-一般 6 」 」 キゴウ PUNCT 補助記号- 括弧閉 7 と と ト ADP 助詞-格助詞 8 いう いう イウ VERB 動詞-一般 五段-ワア行 終止形-一般 9 。 。 。 PUNCT 補助記号-句点 10 ) ) キゴウ PUNCT 補助記号-括弧閉 11 と と ト ADP 助詞-格助詞 12 Y y Y PROPN 名詞-固有名詞-一般 13 社 社 シャ NOUN 名詞-普通名 詞-助数詞可能 14 ( ( キゴウ PUNCT 補助記号-括弧開 15 以下 以下 イカ NOUN 名詞-普 通名詞-一般 16 「 「 キゴウ PUNCT 補助記号-括弧開 17 乙 乙 オツ NOUN 名詞-普通名 詞-一般 18 」 」 キゴウ PUNCT 補助記号-括弧閉 19 と と ト ADP 助詞-格助詞 20 いう いう イウ VERB 動詞-一 般 五段-ワア行 終止形-一般 21 。 。 。 PUNCT 補助記号-句点 22 ) ) キゴウ PUNCT 補助記号- 括弧閉 23 と と ト ADP 助詞-格助詞 24 は は ハ ADP 助詞-係助詞 25 、 、 、 PUNCT 補助記号-読点 26 甲 甲 コウ NOUN 名詞-普通名 詞-一般 27 が が ガ ADP 助詞-格助詞 28 開発 開発 カイハツ VERB 名詞-普通名詞-サ変可能 29 し する シ AUX 動詞-非自立可能 サ行変格 連用形-一般 30 た た タ AUX 助動詞 助動詞-タ 連体形-一般 31 放熱 放熱 ホウネツ NOUN 名詞-普通名詞-サ変可能 32 特性 特性 トクセイ NOUN 名詞-普通名詞-一般 33 を を ヲ ADP 助詞-格助詞 34 有する 有する ユウスル VERB 動詞-一般 サ行変格 連体形-一般 35 新規 新規 シンキ ADJ 形状詞-一般 36 素材 素材 ソザイ NOUN 名詞- 普通名詞-一般 37 α α アルファー NOUN 記号-文 字 38 を を ヲ ADP 助詞-格助詞 39 自動車 自動車 ジドウシャ NOUN 名詞-普通名詞-一般 40 用 用 ヨウ NOUN 接尾辞-名詞的-一般 41 ヘッドライト ヘッドライト ヘッドライト NOUN 名詞-普通名詞-一般 42 カバー カバー カバー NOUN 名詞-普通名詞-サ変可能 43 に に ニ ADP 助詞-格助詞 44 用い 用いる モチイ VERB 動詞-一般 上一段-ア行 連用形-一般 45 た た タ AUX 助動詞 助動詞-タ 連体形-一般 46 新製品 新製品 シンセイヒン NOUN 名詞-普通名詞-一般 47 の の ノ ADP 助詞-格助詞 48 開発 開発 カイハツ NOUN 名詞-普通名詞-サ変可能 49 を を ヲ ADP 助詞-格助詞 50 行う 行う オコナウ VERB 動詞-一般 五段-ワア行 終止形-一般 51 か か カ PART 助詞-終助詞 52 否 否 イナ NOUN 名詞-普通名詞-一般 53 か か カ ADP 助詞-副助詞 54 を を ヲ ADP 助詞-格助詞 55 甲乙 甲乙 コウオツ NOUN 名詞-普通名詞-一般 56 共同 共同 キョウドウ NOUN 名詞-普通名詞-サ変可能 57 で で デ ADP 助詞-格助詞 58 検討 検討 ケントウ VERB 名詞-普通名詞-サ変可能 59 する する スル AUX 動詞-非自立可能 サ行変格 終止形-一般 60 に に ニ ADP 助詞-格助詞 61 当たり 当たる アタリ VERB 動詞-一般 五段-ラ行 連用形-一般 62 ( ( キゴウ PUNCT 補助記号-括弧開 63 以下 以下 イカ NOUN 名詞-普通名詞-一般 64 「 「 キゴウ PUNCT 補助記号-括弧開 65 本 本 ホン NOUN 接頭辞 66 目的 目的 モクテキ NOUN 名詞-普通名詞-一般 67 」 」 キゴウ PUNCT 補助記号-括弧閉 68 と と ト ADP 助詞-格助詞 69 いう いう イウ VERB 動詞-一般 五段-ワア行 終止形-一般 70 。 。 。 PUNCT 補助記号-句点 71 ) ) キゴウ PUNCT 補助記号-括弧閉 72 、 、 、 PUNCT 補助記号-読点 73 甲 甲 コウ NOUN 名詞-普通名詞-一般 74 また また マタ CCONJ 接続詞 75 は は ハ ADP 助詞-係助詞 76 乙 乙 オツ NOUN 名詞-普通名詞-一般 77 が が ガ ADP 助詞-格助詞 78 相手方 相手方 アイテガタ NOUN 名詞-普通名詞-一般 79 に に ニ ADP 助詞-格助詞 80 開示 開示 カイジ NOUN 名詞-普通名詞-サ変可能 81 等 等 トウ NOUN 接尾辞-名詞的-一般 82 する する スル AUX 動詞-非自立可能 サ行変格 連体形-一般 83 秘密 秘密 ヒミツ NOUN 名詞-普通名詞-形状詞可能 84 情報 情報 ジョウホウ NOUN 名詞-普通名詞-一般 85 の の ノ ADP 助詞-格助詞 86 取扱い 取扱い トリアツカイ NOUN 名詞-普通名詞-一般 87 に に ニ ADP 助詞-格助詞 88 つい つく ツイ VERB 動詞-一般 五段-カ行 連用形-イ音便 89 て て テ SCONJ 助詞-接続助詞 90 、 、 、 PUNCT 補助記号-読点 91 以下 以下 イカ NOUN 名詞-普通名詞-一般 92 の の ノ ADP 助詞-格助詞 93 とおり とおり トオリ NOUN 名詞-普通名詞-助数詞可能 94 の の ノ ADP 助詞-格助詞 95 秘密保持契約 秘密保持契約 ヒミツホジケイヤク NOUN 名詞-普通名詞-一般 96 ( ( キゴウ PUNCT 補助記号-括弧開 97 以下 以下 イカ NOUN 名詞-普通名詞-一般 98 「 「 キゴウ PUNCT 補助記号-括弧開 99 本 本 ホン NOUN 接頭辞 100 契約 契約 ケイヤク NOUN 名 詞-普通名詞-サ変可能 101 」 」 キゴウ PUNCT 補助記号-括弧閉 102 と と ト ADP 助詞-格助詞 103 いう いう イウ VERB 動詞-一般 五段-ワア行 終止形-一般 104 。 。 。 PUNCT 補助記号-句点 105 ) ) キゴウ PUNCT 補助記号-括弧閉 106 を を ヲ ADP 助詞-格助詞 107 締結 締結 テイケツ VERB 名詞-普通名詞-サ変可能 108 する する スル AUX 動詞-非自立可能 サ行変格 終止形-一般 109 。 。 。 PUNCT 補助記号-句 点
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【tweepy】TwitterAPIキーを取得してPythonでCLIからツイートできるようにする

はじめに  何回か趣味でTwitterのAPIキーを取得して遊んだけど一貫して書いてある記事が意外と無かったのでまとめてみる。 APIキーの申請  Twitter APIを使うにはAPIキーを取得する必要がある(ここが一番の関門)。  まずは申請したいアカウントでログインをする。複数垢ある人はTwitter Web Appで該当アカウントでログインした状態にしておけばOK(このページで紹介する方法ではこのアカウントからツイートすることになる)。APIを取得することでbotのような振る舞いができるようになるが今まで通りスマホ版のアプリを使ったりというのは可能。新しく作ってもいいし普段使ってるアカウントでも良し。  その状態で下記リンクにアクセス↓  すると下のような申請用のページに行くはず↓  よっぽどのことがない限りは「Hobbyist」を選択すれば大丈夫。その後目的を選択するように言われますがこれはどれを選択しても問題ないはず。  そして[Get started]をクリックして次のページへ。  するとアカウントの基本情報とかが表示されるので一応チェックを。あと本人確認のために電話番号でのアカウント認証もしておく必要がある。 そして下に進むといくつか入力する項目があるのでそれぞれ入力。どれもメモみたいなもので重大な意味を持たないので気楽に。 What would you like us to call you? →このAPI自体の名前みたいなもの。あとで変更はできないがあまり意味はないので自分でわかりやすい名前をつければOK(ツイートソースラベルとは無関係) What country do you live in? What's your current coding skill level? Get the latest Twitter API news? →これはそれぞれ当てはまるのを選べばOK  [next]を押して次のページへ。  ここからがAPIキーの申請に必要な内容。  まずは収集したTwitterデータ,APIをどのように使用するかのプランを書いてくれと。詳細に書くほど早く承認されるよと。「英語かよ。だる」と思うだろうけど実はこれ日本語でもいけた。日本語で200文字書けばOK。  「特定のハッシュタグを含むツイートを収集します。」「フォロワーの増減を記録します。」とかだと弱くて絶対通らない。  「〇〇についてのブログを書いていて,その宣伝の自動投稿や扱うコンテンツの分析に利用します。」とか「大学の〇〇についての授業で〇〇をすることになり,そのために利用したいです。」とか,"遊びじゃなくてこういうしっかりした目的のために使うんだよ"アピールをしたほうがいいんだと思う。2アカウント分申請通したけど一発で通ったことないので当てにならん()  これ以降はAPIの使用内容に当てはまる項目にチェックを入れてそれについての説明を書いていく。もちろんこっちも日本語でおk  Twitterデータの分析をするかどうか。使う場合はどのようにするかプランを書けと。まあこれは書いておいたほうがよさそう。これも"ビジョンが見えてるアピール"をしたほうがいいので,使用するツールとか関数とか書いてそれっぽいこと(嘘っぱちじゃバレるけど)を書く。  自分の場合は「Pythonのtweepyのsearch関数を使って特定のハッシュタグを含むツイートを取得し,pandasやcsvを使ってそのデータをCSV形式で記録し,そのカテゴリで今ホットなコンテンツが何なのかの分析を行います。」とか書いた気がする。正直盛っても問題無し。申請内容に応じてAPIキーの権限が抑えられるとかはないはず。  次,ツイート,いいね,RT,Follow,DMを機械的に行うかどうか。とりあえずこの記事ではツイートをゴールにしたいのでこれも書いておきますか。さっきの使い回しでブログ書くていで「ブログを投稿した時に自動で宣伝の投稿をできるようにする」とか「提供する情報の需要に合致しそうなアカウントを自動フォローするとか」(これだとスパム認定される?),やっぱりとにかく具体的に,やること決まってるよアピールを。正解が分からないので当てにしないで  残りの項目は別に書かなくていいんじゃないかなと思う。チェック入れたら書かなきゃいけないし通っちゃえばこっちのもんなので...  というわけで他のところはNoにして[next]  次のページも内容合ってたら[next]。次も利用規約なので下までスクロールして同意のチェック入れて[submit application]で申請完了。多分確認のためのメールが届くので開いて[confirm your email]をクリックすると正式に審査が始まる。  早いとその日中,遅くても2〜3日でメールに反応が来るはず。一発で通ったことないと言ったけどチャンスは一回じゃないから大丈夫。内容が不十分だとTwitterから「申請する上でこの辺もうちょい詳しく教えてくれ」みたいなメールが来る。  聞かれた項目について落ち着いて(日本語で)返信すればOK。ちなみにさっきの申請文を英語で頑張って書くとこのレスポンスも長文英語で来る。日本語で書くと画像のように日本語で来るっぽい。  さっき一発で通ったことないって言ったけど正確には二発でも通ってません。1回目のメールに返信したらしばらくしてもう一回メールきました。めんどくs...  今回は太字の部分があったのでそこを重点的に返信。  粘ってメールの返信をちゃんとすればこんな感じで受理のお知らせが来る。おめでとう。  これでTwitter Developer Portalにアクセスできるようになる。 Appの作成  まずProject&Appsから[Create App]でAppを作成する。  ここに入力したApp nameはツイートした際のツイートソースラベルになるので自分の設定したい名前を入力する。ツイートしたクライアントを示す部分になるのですでに使われてるものは使えない。日本語もいけるのでオリジナリティーのあるものならそうそう被らないはず。  次のページでAPI Key,API Secret Key,Bearer Tokenが表示されるのでローカル環境にコピーしておく。外部に漏らさない,無くさないこと。あとで使いやすいようにconfig.pyみたいな名前で下のようにPythonファイルとして保存しておくことをお勧めします。この記事ではそういう進め方でいきます。 config.py #例 API_KEY = "ここにAPI Keyをペースト" API_SECRET_KEY = "ここにAPI Secret Keyをペースト" BEARER_TOKEN = "ここにBearer Tokenをペースト" [App settings]でAppが作成される。デフォルトで権限がRead Onlyになってるので変更する。 Read and Writeに変更して[Save]。DMも使いたければそっちでも。  次に認証関連の設定  Enable 3-legged OAuthにチェックを入れる。Request email adress from usersはチェック無しでOK。  Callback URLsとかWebsite URLはOAuth認証の時に使うけどツイートするだけならいらないので存在するURL(自分のブログとか,https://twitter.comとか)を入れておけばOK。  あとはOptionalなので特に入力せずに[save]  これで設定は完了なので[Keys and Tokens]に移動してAccess Token and Secretを[Generate]してさっきと同じようにconfig.pyなどに保存しておく。 こんな感じ config.py API_KEY = "ここにConsumer Keyを入力" API_SECRET_KEY = "ここにAPI Secret Keyを入力" BEARER_TOKEN = "ここにBearer Tokenを入力" ACCESS_TOKEN = "ここにAccess Tokenを入力" ACCESS_TOKEN_SECRET = "ここにAccess Token Secretを入力" これでTwitter側の設定は終わり。 ツイートの投稿  pipやconda installでtweepyライブラリをインストールしてください。tweepyにはTwitter APIをPythonで扱うための機能が豊富に入ってるので大体これだけで済む。(筆者はanaconda環境でやったのでconda install -c conda-forge tweepyで入れました。)  tweepyのinstallが済んだらconfig.pyと下記のpost_tweet.pyを同じ階層においてpost_tweet.pyを実行。入力した内容が投稿されてるはず。 post_tweet.py import tweepy from config import * auth = tweepy.OAuthHandler(API_KEY, API_SECRET_KEY) auth.set_access_token(ACCESS_TOKEN, ACCESS_TOKEN_SECRET) api = tweepy.API(auth) tweet = input('ツイートを入力してください>> ') api.update_status(tweet)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【tweepy】TwitterAPIキーを取得してPythonでCLIからツイートできるようにする その①

はじめに  何回か趣味でTwitterのAPIキーを取得して遊んだけど一貫して書いてある記事が意外と無かったのでまとめてみる。 APIキーの申請  Twitter APIを使うにはAPIキーを取得する必要がある(ここが一番の関門)。  まずは申請したいアカウントでログインをする。複数垢ある人はTwitter Web Appで該当アカウントでログインした状態にしておけばOK(このページで紹介する方法ではこのアカウントからツイートすることになる)。APIを取得することでbotのような振る舞いができるようになるが今まで通りスマホ版のアプリを使ったりというのは可能。新しく作ってもいいし普段使ってるアカウントでも良し。  その状態で下記リンクにアクセス↓  すると下のような申請用のページに行くはず↓  よっぽどのことがない限りは「Hobbyist」を選択すれば大丈夫。その後目的を選択するように言われますがこれはどれを選択しても問題ないはず。  そして[Get started]をクリックして次のページへ。  するとアカウントの基本情報とかが表示されるので一応チェックを。あと本人確認のために電話番号でのアカウント認証もしておく必要がある。 そして下に進むといくつか入力する項目があるのでそれぞれ入力。どれもメモみたいなもので重大な意味を持たないので気楽に。 What would you like us to call you? →このAPI自体の名前みたいなもの。あとで変更はできないがあまり意味はないので自分でわかりやすい名前をつければOK(ツイートソースラベルとは無関係) What country do you live in? What's your current coding skill level? Get the latest Twitter API news? →これはそれぞれ当てはまるのを選べばOK  [next]を押して次のページへ。  ここからがAPIキーの申請に必要な内容。  まずは収集したTwitterデータ,APIをどのように使用するかのプランを書いてくれと。詳細に書くほど早く承認されるよと。「英語かよ。だる」と思うだろうけど実はこれ日本語でもいけた。日本語で200文字書けばOK。  「特定のハッシュタグを含むツイートを収集します。」「フォロワーの増減を記録します。」とかだと弱くて絶対通らない。  「〇〇についてのブログを書いていて,その宣伝の自動投稿や扱うコンテンツの分析に利用します。」とか「大学の〇〇についての授業で〇〇をすることになり,そのために利用したいです。」とか,"遊びじゃなくてこういうしっかりした目的のために使うんだよ"アピールをしたほうがいいんだと思う。2アカウント分申請通したけど一発で通ったことないので当てにならん()  これ以降はAPIの使用内容に当てはまる項目にチェックを入れてそれについての説明を書いていく。もちろんこっちも日本語でおk  Twitterデータの分析をするかどうか。使う場合はどのようにするかプランを書けと。まあこれは書いておいたほうがよさそう。これも"ビジョンが見えてるアピール"をしたほうがいいので,使用するツールとか関数とか書いてそれっぽいこと(嘘っぱちじゃバレるけど)を書く。  自分の場合は「Pythonのtweepyのsearch関数を使って特定のハッシュタグを含むツイートを取得し,pandasやcsvを使ってそのデータをCSV形式で記録し,そのカテゴリで今ホットなコンテンツが何なのかの分析を行います。」とか書いた気がする。正直盛っても問題無し。申請内容に応じてAPIキーの権限が抑えられるとかはないはず。  次,ツイート,いいね,RT,Follow,DMを機械的に行うかどうか。とりあえずこの記事ではツイートをゴールにしたいのでこれも書いておきますか。さっきの使い回しでブログ書くていで「ブログを投稿した時に自動で宣伝の投稿をできるようにする」とか「提供する情報の需要に合致しそうなアカウントを自動フォローするとか」(これだとスパム認定される?),やっぱりとにかく具体的に,やること決まってるよアピールを。正解が分からないので当てにしないで  残りの項目は別に書かなくていいんじゃないかなと思う。チェック入れたら書かなきゃいけないし通っちゃえばこっちのもんなので...  というわけで他のところはNoにして[next]  次のページも内容合ってたら[next]。次も利用規約なので下までスクロールして同意のチェック入れて[submit application]で申請完了。多分確認のためのメールが届くので開いて[confirm your email]をクリックすると正式に審査が始まる。  早いとその日中,遅くても2〜3日でメールに反応が来るはず。一発で通ったことないと言ったけどチャンスは一回じゃないから大丈夫。内容が不十分だとTwitterから「申請する上でこの辺もうちょい詳しく教えてくれ」みたいなメールが来る。  聞かれた項目について落ち着いて(日本語で)返信すればOK。ちなみにさっきの申請文を英語で頑張って書くとこのレスポンスも長文英語で来る。日本語で書くと画像のように日本語で来るっぽい。  さっき一発で通ったことないって言ったけど正確には二発でも通ってません。1回目のメールに返信したらしばらくしてもう一回メールきました。めんどくs...  今回は太字の部分があったのでそこを重点的に返信。  粘ってメールの返信をちゃんとすればこんな感じで受理のお知らせが来る。おめでとう。  これでTwitter Developer Portalにアクセスできるようになる。 Appの作成  まずProject&Appsから[Create App]でAppを作成する。  ここに入力したApp nameはツイートした際のツイートソースラベルになるので自分の設定したい名前を入力する。ツイートしたクライアントを示す部分になるのですでに使われてるものは使えない。日本語もいけるのでオリジナリティーのあるものならそうそう被らないはず。  次のページでAPI Key,API Secret Key,Bearer Tokenが表示されるのでローカル環境にコピーしておく。外部に漏らさない,無くさないこと。あとで使いやすいようにconfig.pyみたいな名前で下のようにPythonファイルとして保存しておくことをお勧めします。この記事ではそういう進め方でいきます。 config.py #例 API_KEY = "ここにAPI Keyをペースト" API_SECRET_KEY = "ここにAPI Secret Keyをペースト" BEARER_TOKEN = "ここにBearer Tokenをペースト" [App settings]でAppが作成される。デフォルトで権限がRead Onlyになってるので変更する。 Read and Writeに変更して[Save]。DMも使いたければそっちでも。  次に認証関連の設定  Enable 3-legged OAuthにチェックを入れる。Request email adress from usersはチェック無しでOK。  Callback URLsとかWebsite URLはOAuth認証の時に使うけどツイートするだけならいらないので存在するURL(自分のブログとか,https://twitter.comとか)を入れておけばOK。  あとはOptionalなので特に入力せずに[save]  これで設定は完了なので[Keys and Tokens]に移動してAccess Token and Secretを[Generate]してさっきと同じようにconfig.pyなどに保存しておく。 これでTwitter側の設定は終わり。 ツイートするところまで一つにまとめようと思ったけど思ったより長くなったので続きは別で描きます。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

FlaskでWeb上に文字を表示させるまで

はじめに プログラミング初心者の私ですが、まず始めの一歩目としてFlaskを使ってみました。 まず今回は最も簡単なWeb上に文字を表示させるまでの説明です。 Flaskとは FlaskとはPythonのWebアプリケーションフレームワークの一種です。比較的小規模で簡単なWebアプリケーションを作るのに適しています。また搭載されている機能が少なくシンプルなためプログラミング初心者の学習にも広く利用されています。 Flaskをインストールする Pythonのパッケージ管理ツールである「pip」を使ってインストールします。ターミナルに以下のコードを入力します。(pythonを起動していない状態) pip install Flask スクリプトを記述 とりあえず定番のHello Worldを表示させるため、以下のコードを保存します。 hello.py #Flaskモジュールのインポート from flask import Flask #Flaskインスタンスの生成 app = Flask(__name__) #URLが'/'のリクエストを受けた場合の処理 @app.route('/') def hello_world(): return 'Hello World!' 「@app.route('/')」部分はデコレーターと呼ばれ、関数やメソッドの前に記述し、その関数がどういう性質のものかを設定する働きがあります。 実行 Macの場合は以下のように実行。 export FLASK_APP=Hello.py flask run windowsの場合は、以下のように実行。 set FLASK_APP=Hello.py flask run ブラウザを立ち上げ、http://localhost:5000 にアクセスし、「Hello World!」が表示されていれば無事成功です。 参考:https://flask.palletsprojects.com/en/0.12.x/quickstart/
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

PythonでHTML生成、WEBサーバ起動、ブラウザ参照を自動で実行

はじめに Pythonであるシステムに画面を組み込む話があったのだが、テスト時にシステム全体をインストールしたくなかったので、単体で画面を表示するドライバを作ってみた。 環境 python 3.6 ソース こんな感じ。 import argparse import http.server import socketserver import webbrowser import threading def main(): PORT = 8009 Handler = http.server.SimpleHTTPRequestHandler socketserver.TCPServer.allow_reuse_address = True server = socketserver.TCPServer(("", PORT), Handler) server_thread = threading.Thread(target=server.serve_forever) server_thread.daemon = True server_thread.start() print("Web server running in thread:", server_thread.name) webbrowser.open("http://localhost:{0}/html/test.html".format(PORT)) import time from datetime import datetime try: while(True): time.sleep(10000) except KeyboardInterrupt: print("closing") #server.shutdown() server.socket.close() import sys sys.exit() if __name__ == "__main__": main() 解説 コマンドを実行すると、WEBサーバを立ち上げ、ブラウザを開き、プログラムの直下のhtmlフォルダの下のtest.htmlを表示する。 WEBサーバを立ち上げた後にブラウザを開けるよう、WEBサーバはスレッドで立ち上げている。 途中でCtr-Cによりキャンセルできるようにしている。 VisualStudioのLive Serverでいいじゃんという話もあるが、これだとPythonしかない環境に配布を行うことができる。 参考 pythonでWebサーバを書いてみる Python で Ctrl-C をキャッチする
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Python 多項式回帰を実装する

多項式回帰とは 与えられた各点を通るような直線を単回帰では1次式(直線)で近似するが、多項式回帰では2次以上の曲線で近似する。 n次の近似多項式を以下のようにおく。 $y = \beta_0 + \beta_1 x + \cdots + \beta_n x^n$ 点 $(x_1, y_1), (x_2, y_2), \cdots, (x_m, y_m)$ に対して、誤差 $\varepsilon_i$ を考慮し $y_{i}=\beta_{0}+\beta_{1}x_{i}+\beta_{2}x_{i}^{2}+\cdots +\beta_{n}x_{i}^{n}+\varepsilon_{i}\ (i=1,2,\dots ,m)$ とする。 誤差ベクトル \varepsilon = \begin{pmatrix} \varepsilon_{1}\\ \varepsilon_{2}\\ \varepsilon_{3}\\ \vdots \\ \varepsilon_{m} \end{pmatrix} の大きさが最小となる $(\beta_0,\ \cdots,\ \beta_n)$ を求めたい。これは以下の事実がある。 y=\begin{pmatrix} y_{1} \\ y_{2} \\ y_{3} \\ \vdots \\ y_{m} \end{pmatrix}, X = \begin{pmatrix} 1&x_{1}&x_{1}^{2}&\dots &x_{1}^{n}\\ 1&x_{2}&x_{2}^{2}&\dots &x_{2}^{n}\\ 1&x_{3}&x_{3}^{2}&\dots &x_{3}^{n}\\ \vdots &\vdots &\vdots &\ddots &\vdots \\ 1&x_{m}&x_{m}^{2}&\dots &x_{m}^{n} \end{pmatrix}, \beta = \begin{pmatrix} \beta_{0}\\ \beta_{1}\\ \beta_{2}\\ \vdots \\ \beta _{n} \end{pmatrix}, \varepsilon = \begin{pmatrix} \varepsilon_{1}\\ \varepsilon_{2}\\ \varepsilon_{3}\\ \vdots \\ \varepsilon_{m} \end{pmatrix} $y=X\beta + \varepsilon$ の $\varepsilon$ が最小となる $\beta$ は、$\beta = (X^TX)^{-1}X^Ty$ である。 実装 import numpy as np import matplotlib.pyplot as plt plt.figure(figsize=(12, 10)) def pol_reg(x_input, y_input, deg): l = [] for x in x_input: tmp = [] for j in range(0, deg + 1): tmp.append(x ** j) l.append(tmp) X = np.array(l, dtype=float) Y = X.T @ X Y_inv = np.linalg.inv(Y) Z = Y_inv @ X.T m = [] for y in y_input: m.append([y]) M = np.array(m) coef = Z @ M x_axis = np.linspace(x_input[0], x_input[-1], 100) y_axis = [] for z in x_axis: val = 0 for i in range(len(coef)): val += coef[i][0] * z ** i y_axis.append(val) plt.scatter(x_input, y_input, color='red', label='sample') plt.plot(x_axis, y_axis) plt.legend(loc='upper left', fontsize=18) if __name__ == "__main__": x_input = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] y_input = [3, 9, 7, -9, -10, -2, -10, -3, 8, 20] pol_reg(x_input, y_input, 8) 参考記事
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

文系の非エンジニアが半年間データ分析を勉強したお話です。

はじめに Qiita初投稿の(@danish55)です。現在、車販売会社の販売促進部署に勤めております。 現在、自己研鑽の為にアイデミー様にてデータ分析・機械学習を学んでおります。 学習のアウトプットとして本記事を投稿させて頂きます。 未熟者ゆえ至らぬ点が多々有るかと存じますが、暖かくご指摘頂けましたら幸いです。 本記事の概要 この記事では、文系の非エンジニアの私が勉強を始めたきっかけや何処で学習が詰まってしまったのかなどを書いていきます。 ● この記事を読んで欲しい方 文系・非エンジニアでデータ分析が有るが、どんな勉強するのか全く分からない方 ● この記事で扱わないこと 実際のプログラミング方法などはこの記事では取り扱いません。 勉強を始めたきっかけ 私が勤めている会社で外部の方と共同で仕事する機会が有りました。その際に外部の方々がデータ分析を用いてターゲティングを行っていました。そこで私と外部の方々との力の差を感じてしまいました。その差を埋めるべく、データ分析の学習を始めました。 アイデミーでの学習の振り返り ● 1ヶ月目 Python入門・Numpy・Pandas・Matplotlibの講座を学習しました。チューターの方にこの辺りの基礎的な講座に関しては完璧にするというよりはどんどん先に進めていき、後から復習する感じで良いと言われました。アイデミー様では、アウトプットとして添削課題というものが有ります。これらの講座の添削課題は少し悩みましたが、文系の非エンジニアの私でもまだまだついていけるレベルでした。 ● 2ヶ月目 データクレンジング・データハンドリング・機械学習概論の講座を学習しました。この辺りでデータ分析の業務内容が私の想像していたものと乖離していることに気づきました。私の想像していたデータ分析は華やかなでデータさえあればすぐに出来るというイメージでした。しかし実際には地道な下準備が8割程度を占めています。この気付きからモチベーションが低下してしまいました。但し、学習自体は、まだついていけていました。 ● 3ヶ月目 教師あり学習(回帰)・教師あり学習(分類)・教師なし学習の講座を学習しました。この辺りから本格的な機械学習が始まりました。ここでも私の想像していたものと実際との乖離が有りました。私の想像していた機械学習は、とても複雑で難しくコードも大量に必要というものでした。しかし実際には、機械学習用のライブラリをインポートするのでゼロからモデル作成する必要は全く有りません。私の感想としては「え?こんなにコード少ないの?」という感じでした。この気付きからモチベーションが少し上がりました。但し学習の難易度がこの辺りから上がりだし、ついていけなくなり始めました。なぜならば機械学習の多くの方法が一気に出てきて頭が混乱してしまったためです。 ● 4ヶ月目 時系列分析・機械学習におけるデータ前処理・ディープラーニング基礎の講座を学習しました。この辺りから難易度が更に上がり、完全についていけなくなりました。そして勉強のやり方を切り替えました。それは覚えることの放棄して理解に徹することです。時系列分析・ディープラーニングといった難解な部分を理解しようと取り組みました。 ● 5ヶ月目 株価予測・タイタニック号の講座を勉強しました。難易度も高いです。自力で解くというよりは、流れを体感するという感じで学習しました。特にタイタニック号の講座では、Kaggleの使い方を学習できます。Kaggleについては、今後も、取り組むつもりなのでどんな機能があるのかなど色々サイト内をさわってみました。 ● 6ヶ月目 現在です。正直、自力でデータ分析を満足に行うことは、今の私では厳しいかと思います。 しかし、受講した結果、中身が一切分からなかったデータ分析が薄っすらですが理解出来たかと思います。 受講が終わってからも引き続きデータ分析は学んでいきたいと思います。 今後の活用 今の会社でデータ分析を用いて市場調査を行いたいと考えております。 元々、今の会社にデータ分析を取り入れたいと思い、学習を始めました。 なぜならば、今の会社では感覚で施策を考案しているからです。 定量的な根拠を持った施策を行えるように市場調査を行いたいと考えております。 おわりに 文系で非エンジニアの自分がデータ分析を学ぶのは多くのハードルが有りました。特に微分や行列といった数学的知識の部分は頭の中が「?」で埋め尽くされていました。 半年という期間では、私の頭では薄っすら理解するのがやっとというレベルでした。 しかし、私はこれからも引き続きデータ分析を勉強していくつもりです。 もしこの記事を見られて、勉強してみたいと思われた方がいらっしゃいましたら一緒に頑張っていきましょう。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

コロナ前後で伸びた企業を分析してみた【世界編】

はじめに どうも、将来乗りたい車はTesla、 プラチナ☆みゆきです。 本記事は前回記事の世界編である。 今回も前回と同様に世界の時価総額の高い企業を順に300社抽出して、yahoo-finance-api2を用いてコロナ前後の株価の成長率を算出していく。 分析手順 companiesmarketcap.comから企業シンボルの取得 yahoo-finance-api2を利用してコロナ前後の株価を取得 コロナ前後で伸びた企業の事業調査 1. companiesmarketcap.comから企業シンボルの取得 世界中の企業の時価総額が網羅されたサイトとしてcompaniesmarketcap.comを選出した。 前回は企業コードであったが、今回はティッカーシンボルを抽出していく(例:Apple.inc → AAPL) 時価総額の高い順位300社のティッカーシンボル・企業名・在籍国名を取得するcodeは以下となる。 search_symbol.py import re import requests from bs4 import BeautifulSoup as bs def main(url): # requestsによってhtmlソースを取得 res = requests.get(url) soup = bs(res.text, 'html.parser') # codeのtagを抽出 code_soup = soup.find_all(class_="company-code") code_list = [] for code in code_soup: code_list.append(code.text) # 企業名のtagを抽出 company_soup = soup.find_all(class_="company-name") company_list = [] for company in company_soup: company_list.append(company.text) # 国名のtagを抽出 country_soup = soup.find_all(class_="responsive-hidden") country_list = [] for country in country_soup: country_list.append(country.text) return code_list, company_list, country_list total_code_list = [] total_company_list = [] total_country_list = [] for i in range(1,4): url = "https://companiesmarketcap.com/page/" + str(i) code_list, company_list, country_list = main(url) total_code_list.extend(code_list) total_company_list.extend(company_list) total_country_list.extend(country_list) # エスケープ文字の除去 for i in range(len(total_company_list)): total_company_list[i] = re.sub('\W', '', total_company_list[i]) # 欠損値の除去 total_company_list.pop(115) total_code_list.pop(115) total_country_list = [s for s in total_country_list if '\n' not in s] total_country_list.pop(115) 2. yahoo-finance-api2を利用してコロナ前後の株価を取得 1で取得した企業リストをもとにyahoo-finance-api2で以下の3つの変数を算出していき結果をcsvとして保存する。 コロナ前の株価 = 2019年6月1日~2019年12月31日までの終値の平均 コロナ後の株価 = 2020年11月1日~2021年4月30日までの終値の平均 株価成長率 = コロナ後の株価 / コロナ前の株価 yahoo_finance_world.py import pprint import sys import pandas as pd import matplotlib.pyplot as plt import datetime as dt from yahoo_finance_api2 import share from yahoo_finance_api2.exceptions import YahooFinanceError from search_symbol import total_code_list, total_company_list, total_country_list def main(code, company, country): my_share = share.Share(code) symbol_data = None try: symbol_data = my_share.get_historical(share.PERIOD_TYPE_YEAR, 2, share.FREQUENCY_TYPE_DAY, 1) df = pd.DataFrame(symbol_data.values(), index=symbol_data.keys()).T df.timestamp = pd.to_datetime(df.timestamp, unit='ms') df.index = pd.DatetimeIndex(df.timestamp, name='timestamp') except YahooFinanceError as e: print(e.message) sys.exit(1) after_covid19 = df[(df.index >= dt.datetime(2020,11,1)) & (df.index <= dt.datetime(2021,4,30))] after_covid19 = round(after_covid19.close.mean()) before_covid19 = df[(df.index >= dt.datetime(2019,6,1)) & (df.index <= dt.datetime(2019,12,31))] before_covid19 = round(before_covid19.close.mean()) ratio = round(after_covid19 / before_covid19, 2) print("code: {}. company: {}. country: {}".format(code, company, country)) print(before_covid19, after_covid19, ratio) stock_df.loc[i] = [code, company, country, before_covid19, after_covid19, ratio] stock_df = pd.DataFrame(columns=['シンボル', '企業名', '国名', 'コロナ前平均', 'コロナ後平均', '成長率']) for i in range(len(total_code_list)): try: main(total_code_list[i], total_company_list[i], total_country_list[i]) except Exception as e: print(e) stock_df.to_csv("stock_world.csv", encoding='utf_8_sig', index=False) print(stock_df) 完成したcsvファイルがこちらである。 一応codeもこのリポジトリに格納している。 ※上場している証券取引所が企業によってバラバラなので、株価成長率を標準的な尺度としては語れないかもしれない点には注意が必要である。 3. コロナ前後で伸びた企業の事業調査 前回のように企業ごとに決算資料を確認して財務指標のYoYを算出するのは少々骨が折れるので今回はランキングの発表と各企業の概説をしていく。 その代わりに、ランクイン企業の紹介数を増やしたいと思う。 コロナ前後で世界のどんな企業が伸びたかを知るだけでも後学になると思われる。 上位30位:TokyoElectron(Japan) 株価成長率:2.13 業界:半導体製造装置業界 企業HP 日本勢として最初で最後のランクインとなったのは我らが東京エレクトロンである。 同社は5Gモバイルの普及とデータセンター投資に牽引され業績を伸ばしている。 上位28位タイ:WuliangyeYibin(China) 株価成長率:2.2 業界:飲料業界 企業HP 発音の仕方がわからないのだが28位タイには中国のスピリッツメーカーがランクインした。 中国はコロナ後に家飲みの頻度でも上がったのだろうか。 上位28位タイ:ASML(Netherlands) 株価成長率:2.2 業界:半導体製造装置業界 企業HP 同じく28位にランクインしたのはオランダの半導体製造装置メーカーASMLである。 ASMLと聞いてASMRと誤解したのは私だけではないはず。 上位26位タイ:PayPal(USA) 株価成長率:2.23 業界:オンライン決済業界 企業HP 言わずもがな世界最大のオンライン決済サービス企業がランクイン。 上位26位タイ:Apple(USA) 株価成長率:2.23 業界:ITプラットフォーム業界 企業HP Appleである。 同社は2020年11月17日にM1チップを発売したりと株式市場でもひときわ注目を集めているようだ。 最近では7種類のカラーバリエーションがあるiMacも発売されている。 上位24位タイ:Mindray(China) 株価成長率:2.3 業界:医療機器業界 企業HP 同率24位にランクインしたのは中国の医療業界からMindrayである。 同社は患者のモニタリング・体外診断・医療画像システムをサービスとしており、中国だけでなくヨーロッパにも進出している。 上位24位タイ:LamResearch(USA) 株価成長率:2.3 業界:半導体製造装置業界 企業HP 同じく24位にランクインしたのはアメリカの半導体製造装置企業LamResearchである。 上位23位:TSMC(Taiwan) 株価成長率:2.45 業界:半導体受託製造(ファウンドリ)業界 企業HP 23位にランクインしたのはまたしても半導体業界から台湾のTSMCである。 同社は受託製造企業としてアップル、クアルコム、AMD、アマゾンといった米国の名だたる大企業から発注を受けている。 垂直統合型の生産体制から水平分業型の生産体制に変化した今、ハイテク企業のデバイスは自国だけでは決して賄えないことに注意したい。 上位22位:AMD(USA) 株価成長率:2.53 業界:半導体業界 企業HP 22位にランクインしたのはICチップでお馴染みのAMDである。 AMD製のチップはパソコンだけではなくTeslaの自動車にも組み込まれている。 また、同社はCPUだけではなくGPUも製造している。 上位21位:WuXiAppTec(China) 株価成長率:2.65 業界:製薬業界 企業HP 中国の製薬・バイオ医薬品・医療機器企業である。 遺伝子絡みのバイオテクノロジーは近い未来に活況するので注目しておきたい。 上位20位:LGChem(S. Korea) 株価成長率:2.67 業界:化学業界 企業HP 韓国最大の化学メーカー。 同社は創業当初は化粧品製造企業として誕生したが2017年には世界で第10位の化学会社に生まれ変わった。 樹脂からはじまりディスプレイやリチウムイオン電池まで幅広く製造している。 上位19位:FreeportMcMoRan(USA) 株価成長率:2.73 業界:非鉄金属業界 企業HP 19位には少し変わった業界からのランクイン。 同社は世界最大のモリブデン生産者であり、銅の最大生産者の1社でもある。 上位18位:MercadoLibre(Argentina) 株価成長率:2.76 業界:EC業界 企業HP ラテンアメリカ版のAmazonとでも言おうか、アルゼンチンのEC企業がランクイン。 同社は2016年時点でラテンアメリカを中心に1億7千万人のユーザを保有している。 同社のショッピングサイトはこちら 上位17位:JingdongMall(China) 株価成長率:2.81 業界:EC業界 企業HP 中国の巨大EC企業である。 同じく中国のEC企業といえばAlibaba社であるが、Alibabaが商品を自社でエンドユーザに提供しないのに対し、同社は自社で商品をエンドユーザに提供する点が差異となっている。 商品の買い付けから果ては物流まで自前で行う一気通貫のビジネスモデルであり、バックにはTencentがついている。 上位16位:NVIDIA(USA) 株価成長率:2.98 業界:半導体業界(GPU) 企業HP 16位にランクインしたのは言わずと知れたGPU企業NVIDIA。 同社はGPUの開発はもちろんディープラーニングのオープンソース開発なども行っている。 上位15位:Adyen(Netherlands) 株価成長率:3.04 業界:オンライン決済業界 企業HP こちらはオランダのオンライン決済企業である。Uberやebay、Spotifyなどの大企業も利用している。 上位14位:ChinaTourismGroupDutyFree(China) 株価成長率:3.06 業界:小売業界 企業HP 中国最大の免税店である同社が14位にランクイン。 上位層としては、異色の業界である。 上位13位:Square(USA) 株価成長率:3.42 業界:決済業界 企業HP オフライン・オンラインどちらも扱っている決済企業である。 POSレジ、在庫管理、顧客管理、勤怠管理を1つのサービスでまかなうことができ、アカウント1つで自分のサイトをオンライン決済に対応させることができる。 シンプルなデザインのデバイスも特徴的である。 上位12位:Shopify(Canada) 株価成長率:3.43 業界:EC業界 企業HP 区分上はEC業界としたが、実際は普通のECとは随分と違っている。なぜならShopifyはC向けのサービスであり、エンドユーザが手軽にショップオーナーになれるサービスだからである。 日本でもBASEという類似のサービスが登場している。 Shopifyはサブスクリプション制でありベーシックプランで月額3000円ほどかかるが、BASEは基本利用料は無料で決済手数料と売上手数料だけの課金だというからすごい。 上位11位:Snap(USA) 株価成長率:3.6 業界:SNS業界 企業HP 動画系SNSであるSnapchatを運営する同社がランクイン。 日本ではあまり浸透していないイメージでる。類似のサービス・機能としてInstagramのストーリーが存在する。 上位10位:WuXiBiologics(China) 株価成長率:3.71 業界:製薬業界 企業HP 中国の製薬業界である。 アジアやヨーロッパ、北米に製造施設を有する。 上位9位:BYD(China) 株価成長率:3.94 業界:自動車業界 企業HP 中国の自動車メーカーがランクイン。 同社はEV(電気自動車)に力を入れており、新エネルギー車(NEV)が売りである。 上のロゴは2007年のもので現在は変わってしまっているがどう見てもBMWのようにしか見えない。 上位8位:Meituan(China) 株価成長率:4.2 業界:ITプラットフォーム業界 企業HP 上の画像はギグエコノミーを代表するような画像ではあるが同社はUber Eatsのようなフードデリバリーだけを運営する企業ではない。提供するサービスが多すぎて一言では説明できないのだが、Uber EatsとPayPayとExpediaを合体させたようなプラットフォームを提供している。 幅広いO2O(Offline to Online)、具体的には配達から決済、旅行予約等のサービス展開しているのだ。 上位7位:CATL(China) 株価成長率:4.26 業界:自動車バッテリー業界 企業HP 主に電気自動車用にリチウムイオン電池を製造する中国の企業である。多くの電気自動車メーカーが同社のバッテリーを使用している。 上位6位:Zoom(USA) 株価成長率:4.65 業界:オンラインコミュニケーション業界 企業HP コロナ禍で人類全員が使いだしたんじゃないかいうほど普及したZoom。同社は元Ciscoのエンジニア、エリック・ユアン氏によって2011年に設立され、瞬く間に2017年にユニコーン企業へと変貌を遂げた。高い株価成長率から見ても世界中でコロナ禍が一番追い風になった企業であるといえるだろう。 上位5位:Pinduoduo(China) 株価成長率:5.1 業界:EC業界 企業HP 5位にランクインしたのは中国のC向けECアプリ企業。 同社は農作物を中心としたECプラットフォームであるが、他のECとは決定的に違う点がチーム購入と言われる仕組みである。 チーム購入というのは、買いたい商品をSNSで共有してチームメンバーを増やすことによって商品価格を下げられる仕組みのことである。 この仕組みは売り手にも買い手にもメリットがある画期的な仕組みである。 このモデルは次世代型のECとしてソーシャルEコマースとも呼ばれている。 チーム購入について分かりづらい方は公式HPの動画を見てイメージを掴んでもらうと良いかもしれない。 チーム購入機能こそないものの、日本で類似するサービスとしてletが挙げられる。 上位4位:SeaGarena(Singapore) 株価成長率:6.64 業界:オンラインゲーム業界 企業HP 4位にはシンガポールのオンラインゲーム企業がランクインした。 同社はゲームタイトルの配信プラットフォームとしてだけではなく、eスポーツの大会なども主催している。 シンガポールはカジノ文化との相性も良かったのかもしれないが、この兆しを見ると日本のeスポーツ熱も過熱する日が近いように思われる。 上位3位:Moderna(USA) 株価成長率:8.56 業界:製薬業界 企業HP ファイザーの次に日本に輸入されたm-RNAワクチンを製造する同社が堂々と3位にランクイン。 日本においては緊急事態宣言の効力も限界に近づいてきているのでワクチン投与の体制が整うを期待するばかりだ。 上位2位:Tesla(USA) 株価成長率:12.57 業界:自動車業界 企業HP 2位にランクインしたのは電気自動車専売自動車メーカーTeslaである。 株価成長率12.57倍という10倍以上の脅威の成長率を誇った。 Tesla車はEV車両であったり、運転支援機能であったり、タッチパネル操作であったり、GPUが搭載されていたりともはや従来の自動車の尺度では考えてはいけない代物である。 これは自動車ではない別の乗り物であり、まさに走るコンピューターといったところである。 モデル3なら500万円程度で新車が買えるのでいつか買ってみたいものだ。 上位1位:NIO(China) 株価成長率:12.57 業界:自動車業界 企業HP 株価成長率1位を樹立したのは中国版Teslaとも名高い中国のEVメーカーNIOである。 同社は2014年の設立以来爆速で成長しており、EV車両の開発や自動運転技術の発展に注力している。 また、2020年からはじめたBaaS(Battery as a Service)の成功も大きい。 BaaSとはその名の通りリチウムイオンバッテリーのサブスクリプションであり、EVの購入時にバッテリーを購入せずにその後サブスクリプション費用として支払うモデルである。 これはビジネス的にもテクノロジー的にも革新的なモデルであるとも言われている。 上位2社の投資熱は単に過熱しているだけかもしれないが、今後のEV・自動運転の技術革新を助けてくれるに違いない。 日本でも高速道路なら自動運転できる日も近いことを願うばかりだ。 総括 今回の調査の結果から、EV業界やEC業界、製薬業界、半導体業界がコロナショック後に伸びている企業であることがわかった。 また、世界経済は相変わらず米中の2強であった。上位30社の所在する国の登場数を以下にまとめる。 国名 登場数 USA 11 China 11 Netherlands 2 Taiwan 1 Singapore 1 S. Korea 1 Japan 1 Canada 1 Argentina 1 果たして今後日本から世界を驚かすユニコーン企業は登場するのか、今後の展開に期待したい。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

初心者がAIアプリ開発講座を終えて

はじめに 私は汎用系のサーバ保守を仕事としているSEですが 開発経験は全くなく、SEとして開発言語に触れていないことに 後ろめたさを感じていたため今回アイデミーのAIアプリ講座を受けることにしました。 ※技術的に詳しいブログは山ほどあると思うので所感をメインに書きたいと思います。 本記事の概要 全くの初心者がAIアプリ開発講座を受けての率直な感想 当初想定していた到達点とのギャップ 作成した成果物と反省点 今後の課題 1.全くの初心者がAIアプリ開発講座を受けての率直な感想   講座自体は非常にためになるものであって受けて損はないというのが正直な感想です。 しっかり言語の入門から始まりますし、段階を踏んでステップアップしていくのが 自分でも体感できていました。ただし注意しなくてはいけないことは、、、、 絶対に受け身になってはいけないこと!! これは非常に重要だと感じました。というのも特に初心者の方はいわゆる業界用語に 慣れていないため、講座で飛び交う用語がよくわからないと思います。 特に機械学習分野では不明な用語は自分で調べながら講座を受けるスタイルを 徹底して受けないとよくわからないまま進んでしまうので要注意だと感じます。 そしてお金に余裕がある方はぜひ6ヶ月コースをお勧めします! 私は昼間働きながら受講しましたが3ヶ月ではなかなか厳しく感じました。 2.当初想定していた到達点とのギャップ   受講前は受けきれば1人前!!と思っていましたが 現実はそう甘くないなと感じました。 そして受講後にどれだけ自分で触っていけるかが重要だと思います。 というのも感覚をあけて受講すると前回の単元の内容を忘れてしまい また復習から始めないといけないんですよね。するとスケジュールが どんどん遅れていき、結果ギリギリになってしまいます。 とにかく毎日触る! 習うより慣れろが開発には必要なことだと痛感しました。 結論として受講後も趣味でAIアプリを作成するか 同じ技術を必要とする仕事に就くことをおすすめします。 3.作成した成果物と反省点   私はファッションアイテムを画像で識別するアプリを作成しました。 いわゆるFashion Mnist?と呼んで差支えないと思いますが あまり時間がなくて精度の高いものを作れませんでした。。。。 仕組みとしては単純です。 スニーカーやシャツの画像を分類するニューラルネットワークモデルを訓練させ TensorFlowを使ってモデルを構築しました。 データセットは以下を使用 keras.datasetsを使ってデータをロードさせました。 fashion_mnist = keras.datasets.fashion_mnist (train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data() 訓練させる前にピクセル値が0から255に収まるようにデータを前処理しました。 ピクセル値の確認 plt.figure() plt.imshow(train_images[0]) plt.colorbar() plt.grid(False) plt.show() 0と1の範囲にスケール train_images = train_images / 255.0 test_images = test_images / 255.0 あとは層をセットアップしてモデルをコンパイルして訓練してと続いて行きますが 全部書くとゴチャゴチャになりそうなので気になればコメント下さい。 ※もう少し精度の高いものが出来たら乗せようかなと思います。 個人的な反省点はモデルの精度もそうですが 時間があれば見栄えももっとこだわりたかった!! 個人的に服のデザインとかもやっていてAdobe系のソフト使えるので 見栄えもこだわりたいですね。美しいwebデザインで精度の高いAIを実装したかった。 これが最大の反省点です。 ただ諦めていません。受講期間が終わっても合間縫っていろいろ試したいと思いました。 4.今後の課題 モデルの構築とその評価が課題かなと個人的には感じています。 というのもまだ調べながら作業しないとどんなモデルが最適か すぐに選択・想像ができないからです。 そこが当初想定していた到達目標でしたが 今後はそこに到達できるようにこの講座を活かしていきたいと思います。 最後に 開発未経験の私が開発の雰囲気とさらに今熱いAI分野を学習できたことは 非常に良かったと思います。 ぜひ受講を検討されている方がいればまずは飛び込んで見てほしいなと思います。 ※長年開発アレルギーでしたが仕組みを知るだけで世界が変わりました。 乱文ですが最後まで読んで頂きありがとうございました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

身近な音に関する50クラス分類データセット「ECS-50」を学習含めて3分クッキング

自然音に関する50カテゴリの音声データセットであるECS-50を用いて畳み込みによる学習を行った。 全カテゴリは以下の通り。 犬の鳴き声や風の音、人の笑い声、マウスのクリック音、花火など様々なジャンルの音声がある。 以下のコードを google colab にコピペして、GPUで実行すると約3分で終わる。 まずは、データの事前加工を行う。ダウンロードに1分、サウンドスペクトログラム化に40秒かかる。 import zipfile import glob import requests import librosa import librosa.display import numpy as np import matplotlib.pyplot as plt import itertools from sklearn.preprocessing import OneHotEncoder from sklearn.model_selection import train_test_split def sound_download(): # urlからデータをダウンロードする download_url = "https://github.com/karoldvl/ESC-50/archive/master.zip" filename = "master.zip" content_ = requests.get(download_url).content with open(filename, 'wb') as f: # wb でバイト型を書き込める f.write(content_) # 解凍すると master ディレクトリが現れる with zipfile.ZipFile('master.zip') as existing_zip: existing_zip.extractall('master') def sound_preprocess(path): # 音声の読み込み y, sr = librosa.load(path, sr=None) # メルスペクトログラム(人間の聴覚に適したスペクトログラム) S = librosa.feature.melspectrogram(y=y, sr=sr) S_dB = librosa.power_to_db(S, ref=np.max) return S_dB # 音声データのダウンロードと解凍(1分かかる) sound_download() # recordingsに入っている数字の音声データ2000個をサウンドスペクトログラムとして取り出す path_list = glob.glob("master/ESC-50-master/audio/*") # ラベルでまとまるようにソート path_list = sorted(path_list, key=lambda x: int(x.split('-')[-1].replace('.wav', ''))) # サウンドスペクトログラムを取得 dB_list = [sound_preprocess(path) for path in path_list] # スペクトログラムを3つ表示 for i in range(3): librosa.display.specshow(dB_list[i], sr=sr, x_axis='time', y_axis='mel') plt.colorbar() plt.show() # Conv2Dを適用できるように最後に軸を追加 X.shape = (2000, 128, 431, 1) X = np.array(dB_list) X = X[:, :, :, np.newaxis] # ディレクトリ内はラベル1からラベル50まで40個ずつ並んでいる _y = [[i] * 40 for i in range(50)] y = list(itertools.chain.from_iterable(_y)) y = np.array(y) # [0, 0, ..., 1, 1, ... ... 9, 9] # ラベルのone hot encodeを行う enc = OneHotEncoder(sparse=False) y = enc.fit_transform(y[:, np.newaxis]) # データの分割 X_train, X_test, y_train, y_test = train_test_split(X, y) 次に、モデルの学習を行う。 from keras.layers import Input, Dense, Conv2D, Activation, Dropout, BatchNormalization, Flatten, MaxPool2D from keras.models import Model # (データサイズ、時系列、隠れ層)の順 inputs = Input(shape=X.shape[1:]) x = inputs x = Conv2D(32, (4, 4), strides=2)(x) x = BatchNormalization()(x) x = Activation('relu')(x) x = MaxPool2D()(x) x = Dropout(0.5)(x) x = Conv2D(64, (4, 4), strides=2)(x) x = BatchNormalization()(x) x = Activation('relu')(x) x = MaxPool2D()(x) x = Dropout(0.5)(x) x = Conv2D(128, (4, 4), strides=2)(x) x = BatchNormalization()(x) x = Activation('relu')(x) x = MaxPool2D()(x) x = Dropout(0.5)(x) x = Flatten()(x) x = Dense(256, activation='relu')(x) x = Dense(50)(x) x = Activation('softmax')(x) model = Model(inputs, x) model.summary() model.compile(loss='categorical_crossentropy', optimizer="adam", metrics=['accuracy']) # GPUを使うと早い model.fit(X_train, y_train, batch_size=32, epochs=150, validation_data=(X_test, y_test)) pd.DataFrame(model.history.history).loc[:, ['accuracy', 'val_accuracy']].plot(ylim=(0, 1)) 学習エポックとaccuracyのグラフはこのようになった。GPUを用いると150エポックでも1分20秒で学習できた。 データは波形 or サウンドスペクトログラムから、モデルはLSTM or 1次元畳み込み or 2次元畳み込みから組み合わせて試すと、サウンドスペクトログラムと2次元畳み込みを用いた場合が60〜70%と、群を抜いて一番精度が高かった。他のパターンは10%〜40%の精度だった。2000のデータで50クラス分類ということと、精度上位の論文ではかなり複雑なモデルにしていたことを踏まえれば、健闘したほうだと思う。 次はデータ拡張をして精度が上がるかを試してみたい。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む