【ゲーム日記】ELDEN RING #3
前回「忌み王モーゴット」にボコボコにされたので、レベル上げ兼探索しつつ、リベンジをした。
今回の記事では、①ラダーン祭り→②永遠の都ノクローン→③産まれ直し→④「忌み王モーゴット」へのリベンジ、といった流れ。
ステータス・装備
「忌み王モーゴット」にボコボコにされ、色々と探索したためLV.75→LV.85になった。
今回「名刀月隠」を使うため、生まれ変わりをして知力特化へ変更。
攻略の流れ
前述の通り「忌み王モーゴット」にボコボコにされてから、①ラダーン祭り→②永遠の都ノクローン→③産まれ直し→④「忌み王モーゴット」へのリベンジ、の順で進めた。
地図上の動き
ラニのイベントを進めるため、ケークリッドの「赤獅子城」から始まり、目的地「永遠の都ノクローン」に到達。その後、産まれ直しをしてから王都ローデイルへ。
①ラダーン祭り
ラニの指示で「ノクローン」を目指し、前々回「シーフラ河」へ行ったが、結局「ノクローン」には辿り着けなかった…
セルブス・セレンに話を聞くと「星砕きのラダーン」を倒すことで、「ノクローン」に行けるらしい。そこで、「星砕きのラダーン」のいる「赤獅子城」へ突撃。
「赤獅子城」では、「ラダーン祭り」としてNPCが集まっており、NPCと協力して「星砕きのラダーン」を討伐した!
ボス「星砕きのラダーン」
- 戦い方:馬に乗りながら、NPC(やられても時間経過で復活)を召喚しヘイトがこちらに向いていない時に攻撃するHit &Away戦法。
- 感想:10回ぐらい死んだ。最初の遠距離攻撃から始まり、近距離では双剣にボコボコされ、後半の初見殺しの隕石攻撃にも見事にやられた。ただ、NPCをひたすら召喚して、ヘイト誘導でゴリ押せばどうにかなった。(正直、正当法がよく分からない…)
②永遠の都ノクローン
「星砕きのラダーン」を倒すと、隕石が落ち「ノクローン」へ続く巨大な穴が出現。隕石が落ちるムービーもカッコいい。
「ノクローン」は、前回の「シーフラ河」同様、景色が良く、屋根を伝って進んでいく感じも良かった。進んでいくと、かの有名な「写し見の雫」、そしてラニからのお使い「ノクローンで秘宝:指殺しの刃」をゲットできる。
「ノクローンで秘宝:指殺しの刃」をラニに届けると、ラニがどこかへ行ってしまう。
ボス「写し身」
- 戦い方:普通の対人戦
- 感想:報酬として「写し見の雫」貰えると思っていたので、倒してから「あれ?」となっていた。
ボス「祖霊の王」
- 戦い方:「写し身の雫」を召喚して、「血の斬撃」でゴリ押し。
- 感想:途中回復されるが、「血の斬撃」でゴリ押しできた。「写し身の雫」強い!
③産まれ直し
レベルも上がり、厨二武器「名刀月隠」を装備できるようになったが、かっこいいけど、火力が出ない。調べてみると、知力が低いと火力が伸びないらしい。
そこで、魔術学院レアルカリアの「満月の女王レナラ」に「産まれ直し」してもらうことにした。「産まれ直し」した結果、知力型へ変更し、「名刀月隠」の火力上昇+魔術が使えるようになった。
④「忌み王モーゴット」へリベンジ
「助っ人NPC:メリナ」と「写し身の雫」にヘイトが向いている間、「魔術:輝石の大つぶて」で遠距離から攻撃する簡単なお仕事。びっくりするほど難易度が下がり、達成感がない…
ボス「忌み王モーゴット」
- 戦い方:「助っ人NPC:メリナ」と「写し身の雫」にヘイトが向いている間、「魔術:輝石の大つぶて」で遠距離から攻撃。
- 感想:近距離で戦っていた時は、30回ぐらいやられたのに、遠距離から魔術戦法に切り替えた途端にすぐ倒せた。プレイヤースキルに応じて、戦術を変えて難易度を変更出来るので、かなりいいゲームデザインだと思う。達成感ないけど…
次回のゲーム日記
以下のような項目に挑戦したい!
- 王都ローデイルから先のストーリー
- ラニイベント進める
- ひたすら探索(これが一番楽しい!)
【ゲーム日記】ELDEN RING #2
前回、「最初の王ゴッドフレイ」にボコボコにされたので、そのリベンジをした。しかし、次の「忌み王モーゴット」にもボコボコにされて、レベル上げ兼探索した。
今回の記事では、①「最初の王ゴッドフレイ」へのリベンジ→②「忌み王モーゴット」にボコボコ→③古遺跡断崖→④日陰城、といった流れで進める。
ステータス・装備
「忌み王モーゴット」にボコボコにされ、色々と探索したためLV.70→LV.75になった。現在、「名刀月隠」を使うため、知力にステ振り中。
武器は、変わらず打刀+10で「戦灰:血の斬撃」。
攻略の流れ
前述の通り「最初の王ゴッドフレイ」にボコボコにされてから、①「最初の王ゴッドフレイ」へのリベンジ→②「忌み王モーゴット」にボコボコ→③古遺跡断崖→④日陰城、の順で進めた。
地図上の動き
王都ローデイルから始まり、アルター高原の未開の領域を開拓をした。結論、アルター高原から移動してない…
①「最初の王ゴッドフレイ」へのリベンジ
「最初の王ゴッドフレイ」本当に強すぎる…リアルな話30回ぐらいやられた。
ボス「最初の王ゴッドフレイ」
- 戦い方:自分ができる選択肢「血の斬撃」「回復」「回避」を意識して、極力無駄な隙を生まないようにした。以下のようなイメージ。あと「霊クラゲ」も召喚したが、あまり意味はなかったかも…
- 「血の斬撃」:敵の大振りの攻撃後のみ
- 「回復」:敵が後ろに下がってからの地ならし攻撃の時のみ
- 「回避」:それ以外(YouTubeが参考になる)
- 感想:アクションゲームなら当然だが、自分ができる選択肢を誤ると、そこを皮切りにからやられてしますので、隙を生まないように意識した。
②「忌み王モーゴット」にボコボコ
「最初の王ゴッドフレイ」から少し進んだところで出会える「忌み王モーゴット」。最初のボス「忌み鬼マルギット」の親戚?みたいなボス。ムービーはかっこいいが、めちゃくちゃ強い。
ボス「忌み王モーゴット」
- 戦い方:?
- 感想:「メリナ」と遺灰にヘイトが向いてる間しか攻撃できない…槍投げるデレイ、本当にやめて…半分削った後の後半戦よく分からない…
③古遺跡断崖
「忌み王モーゴット」にボコボコにされ、レベル上げ兼探索で、アルター高原の未開の領域を開拓した。アルター高原に進むもう一つのルートである古遺跡断崖に挑戦した。レベルが比較的高かったので、そこまで苦労せず突破できた。
ボス「溶岩土竜マカール」
- 戦い方:「霊クラゲ」を召喚して、後ろから「血の斬撃」でひたすら攻撃。(ワンパターンだな…)
- 感想:一回死んだが、レベルの暴力で無事倒せた。
④日陰城
アルター高原で行ったことないエリアに進んだところ、毒沼にそびえる「日陰城」に辿り着いた。毒沼に建っているだけあって、城内の敵は毒系の敵ばかり、状態異常対策を全くしてないので、通常のモブにもやられた…特に、次の写真の強モブ、急に始まるラッシュパンチがキツい…3回ぐらい殺された…
ボス「鉄茨のエレメール」
数多のモブを乗り越え、聖杯瓶が無くなったところで、待ってましたボス戦。
- 戦い方:「民兵のスケルトン」を召喚、スケルトンにヘイト向いてる間に「血の斬撃」で攻撃してヘイト誘導で、スケルトンが倒されないように努めた。この敵も隙を見せると、殺されるので、Hit&Awayを徹底した。
- 感想:5回ぐらいやられた…突進攻撃と血で操作する剣がメチャクチャかっこいいが、何回も殺された。有効な回避方法が分からなかったが、レベルの暴力で突破できた!
次回のゲーム日記
以下のような項目に挑戦したい!
- ボス「忌み王モーゴット」討伐(勝てるかな???)
- ラニイベント進める
- ひたすら探索(これが一番楽しい!)
【ゲーム日記】ELDEN RING #1
2022年2月25日にフロム・ソフトウェアから発売された「ELDEN RING」のゲーム日記#1。#1と書いてるが、もう既に40時間ぐらい遊んでおり、今更感しかないが個人的なゲーム日記を記載。
アルター高原・王都城壁前の「竜のツーリガード」にボコボコにされて、レベル上げ兼探索で、①カーリアの城→②シーフラ河→③大壺の騎士→④竜のツリーガードのリベンジ→⑤王都ローデイル、といった流れで進めた。
ステータス・装備
「竜のツリーガード」のボコボコにされ、色々と探索したためLV.60→LV.70になった。「竜のツールガード」の適正レベルLV.50らしい…
今まで、生命力・筋力・技量しか上げてなかったが、手に入れた武器が全然使えないため、知力・神秘にステ振り中。
武器は、打刀+10で「戦灰:血の斬撃」。
侍の初期装備だが、出血+「戦灰:血の斬撃」が優秀すぎて、なんとか乗り越えられている。
攻略の流れ
前述の通り「竜のツーリガード」にボコボコにされて、①カーリアの城→②シーフラ河→③大壺の騎士→④竜のツリーガードのリベンジ→⑤王都ローデイルの順で進めた。
①カーリアの城
手のモンスターが怖すぎる…しかも、そこそこ強い。ただ、Lv.60あったので、道中のモンスターには、レベルの暴力で基本的にはそこまで苦労しなかった。
ボス「親衛騎士ローレッタ」
②シーフラ河
「カーリアの城」の裏手にある「ラニの魔術師塔」の「ラニ」に指示されるまま、「半狼ブレイヴ」に会うため「シーフラ河」へ行った。地下は広大で、天井が星のようにキレイ!毎回思うことだが、地下まで作り込まれており、エルデンリングの作り込みに感動!
ただ、地下が広大過ぎて、ボス「祖霊」と戦うための祭壇探しが大変だった…
ボス「竜人兵」
- 戦い方:馬に乗っている状態で、後ろから攻撃
- 感想:3回ぐらい死んだが、いつも巨人と同じやり方で倒せた
ボス「祖霊」
③大壺の騎士
シーフラ河にある昇降機を使うと、めちゃくちゃでかい大壺が登場。話しかけると、「大壺の騎士」の召喚サインが表示され、そのまま戦闘。
大壺の騎士
あまりにも勝てなかったので、ググったところ、非常に有効な戦法が紹介されていた。
- 戦い方:必殺「しゃがみ」戦法
- 感想:3人連続対決は、かなり厳しい。毎回3人目でやられ、心が折れた。そこで、ググったところ、以下のYouTubeを発見!紹介されていた「しゃがみ」戦法を使うと、めちゃくちゃ余裕で倒せた笑(動画、感謝です!)
④竜のツリーガードのリベンジ
前回やられ苦手意識があったが、どうにか倒せた。「竜のツリーガード」のHPが半分近くなると、雷を纏い、雷攻撃が追加されて回避が難しくなった。
ボス「竜のツリーガード」
- 戦い方:馬に乗りながら、色気を出さずHit&Awayを徹底
- 感想:やっぱり強い。「今、攻撃行けるかな?」なんて色気を出すとボコボコにされるので、そんな色気は出さずHit&Awayを徹底したところ、どうにかなった!基本は大事だな…
⑤王都ローデイル
「竜のツリーガード」を乗り越え、「王都ローデイル」に到達。
第1印象は、めちゃくちゃ街がキレイ!!!ただ、そこら辺のモブが強く、結構ボコボコにされた…
そして、ボス「最初の王ゴッドフレイ」と遭遇したが、ボコボコにされた。次回は、ボス「最初の王ゴッドフレイ」討伐ですな!
ボス「最初の王ゴッドフレイ」
- 戦い方:?
- 感想:ボスの攻撃が全然避けられない。微妙なデレイ、本当にやめて欲しい。あと、回避してると、攻撃するタイミングがない…
次回のゲーム日記
以下のような項目に挑戦したい!
- ボス「最初の王ゴッドフレイ」討伐(勝てるかな???)
- ラニイベント進める
- ひたすら探索(これが一番楽しい!)
【Python】iPhoneの画像(JPGファイル)を撮影日時でリネーム
iPhoneの画像ファイルは、4桁の連番で命名されているため、 ファイル名だけで管理することは難しく、稀に重複が発生する。
そこで、画像ファイルのメタデータである撮影日時をPythonで取得し、リネームすることで、画像ファイルの管理をスムーズにすることを目指す。
背景
iPhoneの画像ファイルの命名規則
iPhoneの画像ファイルは、以下のように4桁の連番で命名されている。 また、命名されたファイル名が「IMG_9999.JPG」まで行くと「IMG_0001.JPG」に戻るため、稀にファイル名が重複する。
参考
iPhoneで写真ファイルの番号が「9999」を超えたら「0001」になった!(iOS7)
JPGのメタデータ(Exif)
JPGやPNGなどの特定の画像ファイルは、Exif(Exchangeable image file formatの略)と呼ばれる画像ファイルフォーマットでメタデータを管理している。 メタデータとしては、撮影日時、位置情報(ジオタグ)、撮影方向、撮影機器のメーカー名などがある。
参考
Exchangeable image file format - Wikipedia
本記事の目的
iPhoneの画像ファイルを、以下のように撮影日時でリネームし、画像ファイルの管理をスムーズにすることを目指す。
iPhoneの画像を撮影日時でリネーム
事前準備
Pythonにおける画像ファイルの処理では、定番のPillowを用いる。
pip install Pillow
JPGのメタデータ(Exif)の取得方法
以下のソースコードのように、撮影日時や撮影機器などのメタデータを取得することができる。
メタデータを取得する際には、Exifのキーが必要である。 ちなみに、Exifのキーの一覧は、以下のリンク先に記載されている。
Exiv2 - Image metadata library and tools
from PIL import Image import PIL.ExifTags as ExifTags file = "/path/to/images/IMG_0001.JPG" im = Image.open(file) # Exifのメタデータを辞書型で取得する exif_dict = { ExifTags.TAGS[k]: v for k, v in im._getexif().items() if k in ExifTags.TAGS } # 撮影日時 print(exif_dict["DateTimeOriginal"]) # 撮影機器メーカー名とモデル名 print(exif_dict["Make"]) print(exif_dict["Model"])
参考
- Exiv2 - Image metadata library and tools
- ゼロからはじめるPython(42) Pythonで写真に埋め込まれているGPS情報から撮影場所を調べよう | TECH+
iPhoneの画像を撮影日時でリネーム
前節のメタデータ(Exif)の取得方法を用いて、 以下のように所定のフォルダに保存された画像ファイルを一括でリネームできる。
from PIL import Image import PIL.ExifTags as ExifTags from pathlib import Path import datetime # 画像ファイルから辞書型でメタデータを取得する def get_exif_of_image(file): im = Image.open(file) exif_dict = { ExifTags.TAGS[k]: v for k, v in im._getexif().items() if k in ExifTags.TAGS } return exif_dict for filename in Path("/path/to/images").glob("IMG_*.JPG"): exif_dict = get_exif_of_image(filename) if "DateTimeOriginal" in exif_dict: #撮影日時に基づく新規ファイル名を準備 file_dateTime = datetime.datetime.strptime(exif_dict["DateTimeOriginal"], "%Y:%m:%d %H:%M:%S") file_dateTime = file_dateTime.strftime("IMG_%Y-%m-%d_%H-%M-%S.JPG") new_name = Path(filename).with_name(file_dateTime) #リネーム filename.rename(new_name)
参考
【論文メモ】Louvain法
Louvain法について、提案論文(下記リンク)を元に調べてみました。
Louvain法は、ネットワーク内のコミュニティ(密に結合しているノードの集合)を抽出する手法であり、従来の手法に比べ高速で抽出することができます。 また、アルゴリズムもとてもシンプルで、プログラムへの実装も容易にできます。
※私はグラフ理論が専門ではないので、間違いがある可能性も多分にあります。 参考にして頂く際には、ご注意下さい。
概要
近年、SNSやWebの流行を背景にグラフデータ(ネットワーク)への関心が高まっています。 グラフデータの活用方法として、グラフデータからコミュニティ(密に結合しているノードの集合)を抽出するという方法があります。 しかし、SNSやWebの発達に伴いグラフデータの規模が年々拡大しており、従来のコミュニティ抽出手法では、常識的な時間で計算が完了できないことが増えています。
本稿では、以下の2点により計算量を抑え、従来の手法に比べ高速にコミュニティ抽出できる手法を提案します。
- 最適化の計算を局所的に行う
- コミュニティごとにノードを集約
様々な規模のグラフデータにおいて、既存手法との比較実験を行いました。 その結果、いずれのグラフデータでも、品質が高いコミュニティを高速で抽出することできました。
背景知識
グラフとネットワーク
グラフとは、下画像のようにノード(頂点)とノード同士を繋ぐエッジ(辺)で構成されたものを指します。特に、エッジの結びつき(重み、コスト)が一律ではなく、エッジによって異なるグラフをネットワーク(重み付きグラフ)と呼びます。SNSの場合、ノードがユーザー、エッジがユーザー同士の関係性を表します。
参考URL: グラフ理論 - Wikipedia
コミュニティ
下図のように、密に結合しているノードの集合をコミュニティと呼びます。 ただし、コミュニティ同士は疎な結合をしていることが多いです。 コミュニティは、ノード同士の関係性を基にノードを分類(クラスタリング)した結果を表します。 SNSの場合、コミュニティに着目することで、密なユーザー同士を抽出することができるようになります。
モジュラリティ
モジュラリティは、wikiにおいて以下のように説明されています。
モジュラリティ(英: Modularity)は、コンピューターネットワークや、ソーシャルネットワークなどのネットワークやグラフの解析に用いられる効果関数。ネットワークから、モジュールやコミュニティへの分割の「質」を定量化するものである。
高いモジュラリティを持つような高レベルな分割は、モジュール内部でのノード間の密なネットワークを持つ反面、異なるモジュール間で疎なネットワークを持つ。
つまり、モジュラリティは、抽出されたコミュニティの質を評価する指標です。 モジュラリティが高いグラフは、コミュニティ内が密で、コミュニティ同士が疎な関係になります。逆に、モジュラリティが低いグラフは、コミュニティ内が疎で、コミュニティ同士が密な関係になります。
モジュラリティは、以下の式で表されます。 ただし、数式内で使用される記号は下表の通りです。
記号 | 意味 | 数式 |
---|---|---|
ノードとノードのエッジの重み | ー | |
ノードが所属するコミュニティ | ー | |
ノードに結合しているエッジの重みの合計 | ||
全てのエッジの重みの総合計 | ||
クロネッカーのデルタ | (省略) |
課題
上記のモジュラリティは、最適化する目的関数として用いられます。 しかし、大規模なネットワークを扱う場合、モジュラリティの計算が困難となるので、近似的な計算が必要となります。
既存の近似手法1には、以下の2つの問題点があります
- シミュレーテッドアニーリングと比較して、モジュラリティの値が大幅に低い傾向があります。
- 生成されたコミュニティは、ノードの大部分を含むスーパーコミュニティになる傾向があります。 このスーパーコミュニティの影響により、計算速度が遅くなり、100万以上のノードを持つネットワークには適用できません。
Louvain法(提案手法)
アルゴリズム
Louvain法がコミュニティを抽出する流れは、下図で表されます。
Louvain法のアルゴリズムは、大きく2つのフェイズに分かれます。
一つ目のフェイズではモジュラリティの最適化(手順2)を行い、二つ目のフェイズではコミュニティの集約を行います。
また、2つのフェイズを合わせて「パス」と呼びます。
手順1) 初期値の設定
各ノードごとに個別のコミュニティを設定します。
手順2) モジュラリティの最適化
ノードをランダムに選択し、《終了条件》を満たすまで以下の手順2-1), 手順2-2)の操作を行います。
《終了条件》全てのノードにおいて、コミュニティを変化によるモジュラリティの変化量がを満たす場合。
つまり、モジュラリティが極大値をとり、モジュラリティがこれ以上改善できない時です。
※同じノードであったとしても複数回操作する可能性があります
手順2-1) 選択されたノードに隣接した全てのコミュニティにおいて、モジュラリティの変化量を計算する。 このモジュラリティの変化量は、ノードが元々所属するコミュニティから隣接したコミュニティへ移動することにより生ずるモジュラリティの変化量のことを指します。
ここでは、移動前のコミュニティを、移動後のコミュニティをとした時、移動に伴うモジュラリティの変化量を次の式で表すことができます。
この時、右辺の第一項を、第二項をと置いた場合、 を次式のようになります。 また、も符号を反転させた同様な式で表すことができます。
ただし、数式内で使用される記号は下表の通りです。
(コミュニティにはノードは含まれません)
記号 | 意味 | 数式 |
---|---|---|
ノードと結合しているノードのうち コミュニティに所属するノードとのエッジの重みの合計 |
||
コミュニティに所属するノード同士のエッジの重みの合計 | ||
コミュニティに所属するノードと 結合のあるノードとのエッジの重みの合計 |
手順2-2) 隣接するコミュニティのの最大値ををおきます。 この時、下表のようにの最大値によってノードが所属するコミュニティを変化させます。
ただし、はの最大値をとるコミュニティを指します。
条件 | 意味 | ノードが所属する コミュニティ |
---|---|---|
ノードをからに移動させた方が モジュラリティが増加する |
||
ノードをから移動させない方が モジュラリティが高い |
手順3) コミュニティごとの集約
手順3) では、手順2) によって抽出したコミュニティごとに集約し新たなグラフを構築します。
このグラフの構築が完了次第、手順2) に戻ります。
具体的なグラフの構築方法は、それぞれのコミュニティのノードを単一のノードに集約します。 その際、集約後のノード同士のエッジの重みと集約後のノード内のエッジの重みは次のように定義します。
この時、上図のようにコミュニティとを考えます。 また、集約後のノードもそれぞれノードa、ノードbとおきます。
集約後のノード同士のエッジの重み
コミュニティとのエッジは、集約後のノードa,bのエッジとなり、エッジの重みは次の式で表せます。
集約後のノード内のエッジの重み
コミュニティ内のエッジは、集約後のノードaのセルフループ(自己閉路)となり、エッジの重みは次の式で表せます。
Louvain法の特徴
Louvain法は、以下のような特徴があります。
- 各手順が直感的で、実装が容易です。
- アルゴリズムが非常に高速です。
- アルゴリズムを繰り返すことでコミュニティ数が大幅に減少するため、実行時間のほとんどが最初のパス(反復作業)に集中します。
- アルゴリズムのマルチレベルの性質のおかげで、モジュラリティの resolution limit problem(分解制限問題?,*1)を回避できるようになります。
- アルゴリズムが停止して得られた最終的なコミュニティだけではなく、中間的なコミュニティにも意味がある可能性があります。
*1 resolution limit problem:ネットワークが巨大になることでノード同士が相対的に疎になること(ヌルモデルの仮説を保てない)により、小規模なコミュニティを抽出できない問題。詳細は以下のリンクを参照して下さい。
参考URL: Modularity (networks) - Wikipedia
実験
様々なグラフにおいて、Louvain法を既存手法と比較する実験を行います。 今回利用するグラフは、下表の通りです。 (グラフの詳細は、元論文等を確認して下さい。)
名称 | 説明 | ノード | リンク |
---|---|---|---|
Karate | 小規模なソーシャルネットワーク | 34 | 77 |
Arxiv | 科学論文とそれを引用する論文のネットワーク | 9k | 24k |
Internet | インターネットのサブネットワーク | 70k | 351k |
Web nd.edu | nd.eduドメインのサブネットワーク | 325k | 1M |
Phone | 携帯電話の利用客のネットワーク(ウェイトは電話回数) | 2.6M | 6.3M |
Web uk-2005 | .ukドメインのサブネットワーク | 39M | 783M |
Web WebBase 2001 | Stanford WebBase crawlerによって得られたネットワーク | 118M | 1B |
今回比較する既存手法は、以下の3つ手法です。
実験結果は、下表の通りです。
表の2つの数値は、(モジュラリティ)/(実行時間)を表します。
ただし、実行時間が24時間を超えた場合、"-"と表記します。
いずれのグラフでも、モジュラリティ・実行時間の両方の観点において、Louvain法が最良な結果を得られました。 特に、Web uk-2005、Web WebBase 2001などの巨大なネットワークに対しても適用できるのは、Louvain法の優れている点です。
名称 | CNM | PL | WT | Louvain法 |
---|---|---|---|---|
Karate | .38/0s | .42/0s | .42/0s | .42/0s |
Arxiv | .772/3.6s | .757/3.3s | .761/0.7s | .813/0s |
Internet | .692/799s | .729/575s | .667/62s | .781/1s |
Web nd.edu | .927/5034s | .895/6666s | .898/248s | .935/3s |
Phone | -/- | -/- | .56/464s | .769/134s |
Web uk-2005 | -/- | -/- | -/- | .979/738s |
Web WebBase 2001 | -/- | -/- | -/- | .984/152nm |
まとめ
本記事では、Louvain法について、提案論文を元に調べました。
Louvain法は、既存手法に比べ、品質が高いコミュニティを高速で抽出することができ、巨大なネットワークに対しても適用可能です。
SNSやWebの発達に伴いグラフデータの規模が年々拡大することが予測できるため、Louvain法への関心がますます高まると思います。
【Python】DICOM画像(DCM)をJPG画像へ変換
DICOM画像は、医療用の画像フォーマットです。 DICOM画像の特徴は、通常の画像フォーマットと比較して高階調であり、一般的に使用される画像ビューアでは表示できないケースも多いです。 本記事では、DICOM画像を使用頻度が高いJPG画像へ変換することを試みます。 また、変換する際に必要となるウィンドウ処理に関しても記載します。
※私は医療 or 画像処理の専門ではないので、間違いがある可能性も多分にあります。 参考にして頂く際には、ご注意下さい。
DICOM画像
DICOM画像とは
wikiでは、DICOM画像を次のように説明しています。
DICOM(ダイコム)とは、CTやMRI、CRなどで撮影した医用画像のフォーマットと、それらを扱う医用画像機器間の通信プロトコルを定義した標準規格である。 (引用元:DICOM - Wikipedia)
また、DICOM画像は画像データだけではなく、患者の情報(名前・性別・身長など)や画像の撮影状況などのメタ情報を保持しています。 メタ情報の詳細は、下リンクが参考になると思います。
https://www.liberworks.co.jp/407/dicom.html
DICOM画像は、他の画像フォーマットと比較して『①高階調』・『②通常のビューアーでは表示できない』の2つがあります。
①高階調
高階調な画像とは、画素値(各ピクセルの色の濃淡や明るさを表す値)が幅広いレンジの画像のことを指します。 DICOM画像では、一般的な階調表現である8bitを超える10~16bitであることが多いです。
②通常のビューアーでは表示できない
通常のビューアーでは、DICOM画像を表示できないケースが多いです。
サンプルとして使用するDICOM画像
下記リンクより取得できる『CT_JPG_IR6a.dcm』を使用します。
DICOM画像を表示するためのソースコード
次のソースコード は、『DICOM画像を扱う前の事前準備』を実施後に実行にして下さい。
from matplotlib import pyplot as plt import pydicom dcm_sample = pydicom.dcmread("CT_JPG_IR6a.dcm") plt.imshow(dcm_sample.pixel_array) #カラー(未処理) plt.imshow(dcm_sample.pixel_array, cmap = 'gray') #グレースケール plt.show()
PythonでDICOM画像を扱う前の事前準備
PythonでDICOM画像を扱う前にpydicom
をインストールする必要があります。
また、JPEG・JPEG-LS・JPEG2000を解凍する必要がある場合は、gdcm
をインストールして下さい。
pydicom
をインストール
pip install pydicom
gdcm
をインストール
conda install gdcm -c conda-forge
参考URL
DICOM画像をJPG画像へ変換する方法
DICOM画像のメタ情報にWindowCenter・WindowWidthが存在する場合は、ウィニング処理をした方が適切です。 理由としては、撮影時に重要視した対象(※)を鮮明に表現できるからです。
※恐らくWindowCenter・WindowWidthの値は、画像撮影時に設定されるものだと思っているので、上のように記述しました。 しかし、WindowCenter・WindowWidthの値を設定する正確なタイミングを把握できていないため、あくまで推察です。
ちなみに、WindowCenter・WindowWidthの有無を確認するソースコードは次の通りです。
WindowCenter・WindowWidthの有無に依り、5行目の結果が変化します。
存在する場合はTrue
、存在しない場合はFalse
となります。
from matplotlib import pyplot as plt import pydicom dcm_sample = pydicom.dcmread("CT_JPG_IR6a.dcm") print(('WindowCenter' in dcm_sample) and ('WindowWidth' in dcm_sample))
WindowCenter・WindowWidthがない場合
次のソースコード を用いると、DICOM画像をJPG画像(下図)に変換できます。
import pydicom import cv2 dcm_sample = pydicom.dcmread("CT_JPG_IR6a.dcm") dcm_img = dcm_sample.pixel_array cv2.imwrite("CT_NoWindow.jpg", dcm_img)
WindowCenter・WindowWidthがある場合
DICOM画像をJPG画像(下図)に変換する際に、ウィニング処理を考慮した場合のソースコード は、次のようになります。 ウィニング処理に関しては、次の節をご確認下さい。
import pydicom import cv2 dcm_sample = pydicom.dcmread("CT_JPG_IR6a.dcm") dcm_wc = dcm_sample.WindowCenter dcm_ww = dcm_sample.WindowWidth dcm_img = dcm_sample.pixel_array #ウィンドウ処理 window_max = dcm_wc + dcm_ww/2 window_min = dcm_wc - dcm_ww/2 dcm_img = 255*(dcm_img - window_min)/(window_max - window_min) dcm_img[dcm_img > 255] = 255 dcm_img[dcm_img < 0] = 0 cv2.imwrite("CT_Window.jpg", dcm_img)
参考URL
医療情報学研究室: Pyゼミ1.02 DICOMからJPEGなどへの変換
ウィンドウ処理
ウィンドウ処理とは
ウィンドウ処理とは、下図のように幅広いレンジの画素値(各ピクセルの色の濃淡や明るさを表す値)を持つ画像において、特定の範囲の画素値(Window Center ± 0.5*Window Width)を一般的な階調表現 (例えば 8 bit)に変換する処理のことを指します。 ウィンドウ処理をすることで、特定の範囲の画素値を鮮明に表現できるようになります。
ウィンドウ処理(数式)とは
変換前の画像(高階調)のピクセルの画素値をx
とし、特定の範囲の画素値に関する情報であるWindow Center、Window Widthをそれぞれwc
、ww
とおきます。
また、変換後の画像の階調をn
bit 、変換後のピクセルの画素値をy
とします。
この時、ウィンドウ処理は、次のような数式で表現できます。
ウィンドウ処理の効果
上記のDICOM画像が、ウィンドウ処理の有無で、どのように変化するかを比較すると次のようになります。 ウィンドウ処理ある場合の方が、画像が鮮明になり分かりやすくなります。
参考URL
まとめ
本記事では、医療用の画像フォーマットとして利用されるDICOM画像を、使用頻度が高いJPG画像へ変換する方法を記載しました。 加えて、階調の変換する際に必要となるウィンドウ処理についても記載しました。
【Python】面グラフ・層グラフを描画する方法
Pythonのmatplotlibを使った、面グラフ(Area Graph)・層グラフ(Stacked Area Charts)を描画する方法を調べてみました。 面グラフとして有名な積み上げ面グラフ、積み上げ100%面グラフ の特徴を比較した後、それぞれを描画するソースコードを記載します。 加えて、モノクロ印刷時にグラフを見やすくするハッチング(グラフの面ごとの模様・柄を設定)の方法も記載します。
使用データ
政府統計の総合窓口e-Statから取得できる統計名「成果物卸売市場調査 長期累年」を使用します。具体的に使用するデータ項目は、次の通りです。
面グラフ・層グラフとは
本記事では、面グラフ(Area Graph)・層グラフ(Stacked Area Charts)のうち積み上げ面グラフ、積み上げ100%面グラフを対象とします。
上記のデータを面グラフで表現すると、次のようになります。 ちなみに、描画にはExcelを使用しました。
それぞれの特徴をまとめると、下表のようになります。いずれのグラフもデメリットは存在しますが、双方を組み合わせることでお互いのデメリットを補うことができます。
本題から脱線しますが、たけのこの卸売量は極端に少ないですね笑 高級品として扱われる意味が分かります。
項目 | 積み上げ面グラフ | 積み上げ100%面グラフ |
---|---|---|
図 | 左図 | 右図 |
表現する対象 | 変化量の構成 | 構成比率の変化 |
メリット | 全体、構成要素ごとの変化量が分かりすい | 構成比率・変化の要因が分かりやすい |
デメリット | 全体が変化した要因が分かりにくい | 変化量が分からない |
Pythonによる面グラフの描画方法
ここでは、Pythonによる面グラフの描画方法をまとめています。
内容としては、上で登場した積み上げ面グラフ、積み上げ100%面グラフと積み上げ面グラフ(ハッチング)です。 ハッチングとは、面グラフの面に模様・柄を設定するもので、モノクロ印刷時にとても見やすいです。(弊社はカラー印刷に制限があるので。。。)
積み上げ面グラフ
具体的なソースコードと積み上げ面グラフは、次の通りです。 また、グラフの画質や日本語表記などのグラフの整形方法の詳細は、参考URLをご確認下さい。
import numpy as np import pandas as pd import matplotlib.pyplot as plt import matplotlib.ticker as ticker import japanize_matplotlib df = pd.read_excel('/野菜の卸売数量.xlsx') df = df.set_index('YEAR', drop=True) yasai_list = list(df.columns) plt.stackplot(df.index, df[yasai_list].values.T, labels=yasai_list) #グラフの整形 plt.gca().get_xaxis().set_major_locator(ticker.MaxNLocator(integer=True)) plt.legend(loc = 'upper right', bbox_to_anchor=(0.3, 0, 1, 1),title="野菜") plt.title('野菜の卸売数量[t]') plt.savefig('/野菜の卸売数量.png', dpi=200, bbox_inches='tight')
参考URL
- matplotlib よく使うグラフまとめ(折れ線、積み上げ面グラフ) - Qiita
- matplotlibで軸の値が小数になったりオフセット表現になったりするのを止める方法 - minus9d's diary
- 【超簡単】たったの2ステップで matplotlib の日本語表記を対応させる方法 | YOLO – 人工知能の導入録
- チラシ裏のラクガキ: Matplotlibの高解像度画像保存
積み上げ100%面グラフ
積み上げ100%面グラフは、積み上げ面グラフと異なり、描画する前に数量を割合に変換(11行目)します。 逆に11行目以外は、積み上げ面グラフと同じソースコードです。
import numpy as np import pandas as pd import matplotlib.pyplot as plt import matplotlib.ticker as ticker import japanize_matplotlib df = pd.read_excel('/野菜の卸売数量.xlsx') df = df.set_index('YEAR', drop=True) yasai_list = list(df.columns) df = df.apply(lambda x:x/sum(x),axis=1) #ここを追加 plt.stackplot(df.index, df[yasai_list].values.T, labels=yasai_list) #グラフの整形 plt.gca().get_xaxis().set_major_locator(ticker.MaxNLocator(integer=True)) plt.legend(loc = 'upper right', bbox_to_anchor=(0.3, 0, 1, 1),title="野菜") plt.title('野菜の卸売数量[t]') plt.savefig('/野菜の卸売数量.png', dpi=200, bbox_inches='tight')
参考URL
積み上げ面グラフ(ハッチング)
ハッチング(hatch)とは、面グラフの面に模様・柄を設定するもので、モノクロ印刷時にとても有効です。 上記の積み上げ面グラフと比較すると、変更点が分かりやすいと思います。
import numpy as np import pandas as pd import matplotlib.pyplot as plt import matplotlib.ticker as ticker import japanize_matplotlib df = pd.read_excel('/野菜の卸売数量.xlsx') df = df.set_index('YEAR', drop=True) yasai_list = list(df.columns) hatch_list = ['xx', '\\', '//', '||', '--', '..', '++'] fig, ax = plt.subplots() stacks = ax.stackplot(df.index, df[yasai_list].values.T, labels=yasai_list) for (stack, hatch) in zip(stacks, hatch_list): stack.set_hatch(hatch) #グラフの整形 plt.gca().get_xaxis().set_major_locator(ticker.MaxNLocator(integer=True)) plt.legend(loc = 'upper right', bbox_to_anchor = (0.3, 0, 1, 1),title="野菜") plt.title('野菜の卸売数量[t]') plt.savefig('/野菜の卸売数量.png', dpi=200, bbox_inches='tight')
参考URL
- Python matplotlibで棒グラフ(ハッチングと2軸グラフの凡例) - Qiita
- python - Matplotlib: stackplot with different hatches - Stack Overflow
まとめ
Pythonのmatplotlibを使った、面グラフ(Area Graph)・層グラフ(Stacked Area Charts)を描画する方法を調べました。 面グラフとして有名な積み上げ面グラフ、積み上げ100%面グラフ の特徴を比較した後、それぞれを描画するソースコードをまとめました。 加えて、モノクロ印刷時にグラフを見やすくするハッチング(グラフの面ごとの模様・柄を設定)の方法もまとめました。