OmniAICreator/Qiita-1.07M huggingface dataset:
「その精度、本当に信頼できる？」AI評価指標の真実と現場のリアル


## ✅【現場から語る】本当に信頼できるAIとは？評価指標の「その先」へ

 
本日は、「信頼できるAIのための評価指標」というテーマをベースに、**私たちが日々どのように“AIの信頼性”と向き合っているのか**を、現場視点で掘り下げていきます。

---

### 📊 評価指標＝Accuracyだけではない

「このAIの精度は98%です！」  
一見すると魅力的に聞こえますが、**その数値、本当に“信頼”できますか？**

実際の現場では、**Accuracy（正解率）だけではAIの信頼性を語れない**ケースがほとんどです。

#### 例：医療AIの場合
- 陽性者が1%しかいないデータセットで、常に「陰性」と判定すればAccuracyは99%になる。
- でも、それでは**本当に重要な患者を見落とす**ことになる。

だからこそ、私たちは**「信頼できるAIの評価軸」をもっと多面的に設計する必要がある**のです。

---

### 📌 現場で重視される5つの信頼性評価軸

以下は、私がプロジェクトで特に重視してきた**評価軸とその活用方法**です：

1. **公平性（Fairness）**  
　→ 特定の属性（性別・年齢・人種など）によって結果が偏っていないか？  
　→ Googleでは、Fairness Indicatorsを使って継続的に評価を自動化しています。

2. **説明可能性（Explainability）**  
　→ なぜその予測をしたのか？ XAI（Explainable AI）でユーザーの納得感を高める。  
　→ 医療画像AIでは、Grad-CAMで注目領域を可視化し、医師の信頼を獲得。

3. **頑健性（Robustness）**  
　→ ノイズや攻撃に対して壊れないか？  
　→ セキュリティ領域では、敵対的サンプル（Adversarial Examples）に耐えるモデルが必須。

4. **再現性（Reproducibility）**  
　→ モデルの結果は再現可能か？学習パイプラインとデータのトラッキングが重要。  
　→ GoogleではML Metadata（MLMD）を使って、全学習過程を記録。

5. **実環境での性能（In-situ Performance）**  
　→ テスト精度だけではなく、**実際の使用環境での挙動**を重視。  
　→ ユーザーからのフィードバックとログ分析で精度以上の信頼性を見極める。

---

### 🧪 私の実体験：AI導入で“信頼”が最重要だった場面

#### ケース①：スマートスピーカーの誤作動
- 問題：特定の方言に対して誤認識が多発し、誤操作を招いた。
- 対応：精度改善だけでなく、**ユーザーが「なぜ誤認されたか」理解できる説明機能**を導入し、CSクレームが70%減少。

#### ケース②：金融業界での信用スコアAI
- 問題：モデルが過去の「与信履歴」に偏り、特定地域でスコアが低くなる。
- 対応：Fairness Metricsを導入し、地域・属性ごとのバイアスを定量的に可視化。
- 結果：金融庁レビューも通過し、安心して市場投入できた。

---

### 🔍 現場での落とし穴：「評価」と「運用」は別物

多くの開発者が「評価指標は開発時に使うもの」と考えがちですが、**本当に重要なのは「運用段階でどう評価するか」**です。

- 精度が落ちたことにどう気づくか？
- 環境が変わったとき、誰が何を修正するのか？
- ユーザーの信頼を失ったとき、どう回復するか？

このような**「信頼性のライフサイクル設計」**こそが、今後のAI開発に求められます。

---

### 📣 最後に：AIにとって信頼とは「継続的な責任」

AIは、最初に正しく動けばそれで終わりではありません。  
**人間社会に溶け込む存在として、常に検証され、改善され続ける責任**があります。

だからこそ、私たち開発者は、単なる精度ではなく、**“信頼”を測れる指標と運用体制を構築する力**が必要なのです。
SQLAlchemyで複雑な検索機能を実装中にぶち当たった「循環インポート」の罠と、その乗り越え方

## はじめに

とある Web アプリの**検索機能**を実装する中で、  
SQLAlchemy + Alembic + PostgreSQL の組み合わせで、複雑なモデル構成と依存関係をどう扱うか？という問題に直面しました。

- **循環インポート**
- **遅延評価（文字列参照）**
- **PostgreSQL固有の型制約**
- **マイグレーション時のデータ整合性の確保**

この記事では、それらの**リアルなトラブル**と**実践的な解決方法**を紹介します。

---

## 使った技術スタック

- Python 3.11
- SQLAlchemy (ORM)
- Alembic (DBマイグレーション)
- PostgreSQL
- FastAPI（API実装）

---

## 実装していた検索機能の概要

以下のような **多条件でのデータ検索機能** を実装中でした：

- 🔍 フリーワードによる検索
- 🏷️ タグの複数指定による絞り込み
- 🎯 数値的条件（例：難易度や費用）によるフィルタリング
- 📊 ソート順（閲覧数・評価など）

---

## 発生した主な問題と解決方法

---

### ✅ 1. 循環インポート（Circular Import）の罠

#### 📌 問題の例：

```python
# model_a.py
from app.models.model_b import ModelB
class ModelA(Base):
    b = relationship(ModelB)

# model_b.py
from app.models.model_a import ModelA
class ModelB(Base):
    a = relationship(ModelA)
```

→ 結果：

```
ImportError: cannot import name 'ModelA' from partially initialized module ...
```

#### 🤔 なぜ起こる？

**Python の import は上から順に評価される**ため、  
`model_a` を評価中に `model_b` を呼び、さらに `model_b` が再び `model_a` に戻ると、**まだ評価が完了していないクラスを参照しようとしてエラー**になります。

---

### ✅ 解決策：遅延評価（文字列参照）

SQLAlchemyの `relationship()` は、**文字列でクラス名を渡すと遅延解決**してくれます。

```python
# model_a.py
class ModelA(Base):
    b = relationship("ModelB", back_populates="a")

# model_b.py
class ModelB(Base):
    a = relationship("ModelA", back_populates="b")
```

> 🔄 **評価タイミングを後ろにずらす**ことで、循環の影響を回避できます。

---

### ✅ 補足：relationshipの評価タイミング

- クラスを直接指定：評価時にそのクラスが定義済みである必要あり
- クラス名を文字列で指定：評価が後回しになる（遅延評価）

**循環の心配があるときは、基本的に `"ModelName"` と文字列指定するのが安全です。**

---

### ✅ 2. PostgreSQLのUUIDと集約関数の相性問題

#### 📌 エラー例：

```sql
SELECT MIN(id) FROM my_table
-- → psycopg2.errors.UndefinedFunction: function min(uuid) does not exist
```

#### 🛠 解決法：

`array_agg` と `[1]` インデックスで代用：

```sql
SELECT (array_agg(id ORDER BY id))[1]::uuid AS keep_id
FROM my_table
GROUP BY something
```

---

### ✅ 3. 既存データの重複によるユニーク制約違反

**事象**：マイグレーションでユニーク制約を追加しようとしたら、既存の重複データで失敗。

```sql
sqlalchemy.exc.IntegrityError: could not create unique index ...
DETAIL: Key (name)=(Python) is duplicated.
```

#### ✅ 解決方法：

1. 重複データをまとめて抽出
2. 中間テーブルの参照を修正
3. 重複行を削除してから制約を追加

---

### ✅ 4. マッパー設定とインポート順の調整

複雑なモデル群を扱うと、`alembic revision --autogenerate` が突然落ちることも…

#### 📌 対処方法：

```python
# models/__init__.py

from .user import User
from .tag import Tag
from .content import Content
# ...

from sqlalchemy.orm import configure_mappers
configure_mappers()
```

`configure_mappers()` を呼ぶことで、SQLAlchemyが全モデルの関係性を正しく解釈してくれるようになります。

---

## 最終的なAPI使用例

```http
GET /search/items
  ?q=Python
  &tags=Web,API
  &difficulty=2
  &cost_level=1
  &sort=view_count
  &order=desc
```

---

## まとめ

SQLAlchemyで複雑なモデルや検索機能を設計する際には、次の点に注意が必要です：

| トピック | 対応策 |
|----------|--------|
| 🔁 循環インポート | 文字列参照で遅延評価 |
| 🧩 型制約 | PostgreSQL特有の制限にはarrayや::型キャストで対応 |
| 🔄 マイグレーション時の重複 | データ統合 + 制約追加の順番で整合性を確保 |
| 🧠 モデル初期化 | `configure_mappers()` で確実にマッピング |

---

## おわりに

検索機能の実装は、表面上はシンプルでも裏側では**データ構造と設計の奥深さ**が問われます。

特にSQLAlchemyを使ったORMベースの開発では、**循環参照・遅延評価・マイグレーション整合性**などを理解しておくことが大きな武器になります。

この記事が、同じように**複雑なデータ構造で検索機能を構築しようとしている方**の助けになれば幸いです 🙌
「倫理なきAIは信用されない」〜現場から学んだ設計のリアル〜



## 🧭【現場で直面したリアルな課題と対策】AIの倫理的設計をどう実現するか？

  
今日は「**倫理的なAI設計ガイドライン**」をテーマに、私たち開発者が**実際に直面したジレンマ**や、**産業界での対応策・実装ノウハウ**を含めて、深く掘り下げていきます。

---

### 🎯 なぜ「倫理的AI設計」が今求められているのか？

AIは今、医療、司法、金融、教育、採用など、人間の人生に重大な影響を与える分野にまで拡大しています。  
だからこそ、「バイアスのない判断」「説明可能性」「公平性」「プライバシー保護」が技術設計レベルで求められるのです。

#### ✅ ガイドラインの基本的な原則
1. **透明性（Transparency）**
2. **公平性（Fairness）**
3. **説明可能性（Explainability）**
4. **安全性と頑健性（Robustness）**
5. **プライバシー保護（Privacy by design）**
6. **説明責任（Accountability）**

---

### 🛠 実務での具体例：どこに「倫理」が関わるのか？

#### 1. 採用AIシステムに潜む偏見  
- **課題**：過去のデータに基づいたAIが、無意識に性別や人種による偏見を学習。  
- **実体験**：ある企業で、女性エンジニアの評価が一貫して低く出る問題が発生。  
- **対応策**：
  - 学習データの中立性評価（Bias Auditing）
  - 対象となる変数の正規化と匿名化
  - 意図的にバイアス補正を行う「逆重み付き学習」

#### 2. 説明不可能なAIの意思決定  
- **課題**：深層学習モデルが「なぜ」その判断をしたのか分からない。  
- **実体験**：医療診断支援システムにおいて、AIが出した診断結果が医師と一致せず、現場が混乱。  
- **対応策**：
  - LIMEやSHAPによる局所的な特徴量の可視化
  - 解釈可能なサブモデルの併用
  - UIでのフィードバックループを設け、ユーザーが説明を選択できる機構を設計

#### 3. データプライバシーの取り扱い  
- **課題**：個人データの取り扱いと、モデルの学習効率の両立。  
- **実体験**：スマートスピーカー開発にて、音声データの匿名性確保が大きな課題に。  
- **対応策**：
  - Federated Learning + Differential Privacy
  - 音声をローカルデバイス内で前処理し、匿名特徴量のみをクラウド送信
  - ユーザーによる明示的な同意取得UIを実装

---

### 💡 経験から学んだ「3つの視点」

1. **倫理は開発終盤ではなく、設計段階から組み込むべき**  
　→ UI設計からアルゴリズム選定、データ収集に至るまで、倫理的観点は初期段階で盛り込む必要がある。

2. **「正しさ」よりも「信頼性」を重視する設計が大事**  
　→ AIの判断が必ずしも完璧でなくても、「どうしてその判断に至ったか」が説明できれば、ユーザーの信頼は保たれる。

3. **倫理的設計はチーム横断で進めるべき**  
　→ エンジニアだけでなく、法務、UX、社会学・心理学の専門家と協業するのが理想的な形。

---

### 🔮 未来のAIは「価値観を共有できる存在」に

技術の進歩は避けられない。しかし、それが社会に受け入れられるかどうかは、**どれだけ人間の価値観に寄り添えるか**にかかっています。  
AIを「ただ賢い」存在から、「**信頼できる仲間**」へと進化させるために、**倫理的設計はこれからの技術者の必修科目**だと私は感じています。
命を預かるAI：医療分野で信頼されるための5つの条件とは？


## 🧠【信頼できるAI】医療分野におけるAIの信頼性をいかにして高めるか？

医療AIは、診断支援、画像解析、患者モニタリング、創薬といった多岐にわたる分野で活躍の場を広げています。しかし、**人の命を扱う分野**であるがゆえに、AIの「精度」や「倫理性」だけでなく、**信頼性**が極めて重要です。

今回は、Googleや業界の最前線で実際に取り組んできた経験をもとに、「医療AIの信頼性を高めるための戦略と実践」を掘り下げてご紹介します。

---

### ✅ なぜ医療AIに「信頼性」が求められるのか？

医療においては、一つの誤判断が患者の生死に直結する可能性があります。たとえAIモデルの**予測精度が99%**であっても、残りの1%の誤診が重大な結果をもたらすこともあります。

さらに、患者のプライバシーを守りながら、**説明可能性（Explainability）**や**バイアスの除去**といった課題にも同時に取り組む必要があります。

---

### 🛠 信頼できる医療AIを構築するための5つのアプローチ

#### 1. データ品質の確保と多様性の担保

- データが偏っていると、AIは特定の人種や年齢層に対して誤診しやすくなります。
- 現場での経験から言えるのは、**地域・年齢・性別・疾患の多様性**を持ったデータセットの構築が鍵。
- Google Healthでも、**フェアネス評価指標（Fairness Metrics）**を常時トラッキングし、モデルの偏りを検出・修正しています。

#### 2. 説明可能なAI（XAI）の導入

- 特に放射線画像や皮膚病の診断など、ブラックボックスなモデルよりも**どの特徴に注目して判断したか**を医師に明示できる仕組みが不可欠。
- 実務では、Grad-CAMやLIMEなどの手法を組み合わせ、**視覚的フィードバック**を医師に提供しています。

#### 3. 継続的な学習とフィードバックループの確立

- 医療は進化する分野。新しいウイルスや治療法に対応するためには、AIも継続的に学習しなければなりません。
- 現場では、医師からの**アノテーションやレビュー**を取り入れ、モデルにリファインメントを加えるプロセスを回しています。

#### 4. 倫理・法的なガイドラインとの整合性

- 各国の医療機器規制（例：米FDA、欧州CE）に対応した**AIガバナンス設計**が必要。
- Googleでは、社内に倫理チームと法務チームが密に連携し、「**モデルが安全であることを証明するプロセス**」を製品開発段階から導入しています。

#### 5. 医療従事者との協働デザイン

- AIは医師を置き換えるものではなく、**医師の意思決定を支援するパートナー**であるべき。
- 実際のプロジェクトでは、UXデザインの段階から医師や看護師の声を取り入れ、**現場のワークフローに馴染む設計**を重視しています。

---

### 👨‍⚕️ 医療現場でのAI導入の実例：糖尿病網膜症スクリーニング

タイやインドでは、Googleが開発した糖尿病網膜症の診断支援AIが実際にクリニックで使用されています。医師の診断とAIの結果を組み合わせることで、**診断の一貫性とスピードが大幅に向上**しました。

重要なのは、AIを「万能な存在」としてではなく、「**限界を認識し、適切に使えるようなガイドライン**」をセットで導入したことです。これが、信頼を得る第一歩となりました。

---

### 💬 最後に：AIの信頼は“人との関係性”で決まる

AIがどれだけ正確であっても、それを**使う人が信頼できなければ意味がない**。医療AIの信頼性を高めるには、単なる技術革新ではなく、「**人とAIの共創**」が不可欠です。

我々エンジニアは、技術の精度を追い求めるだけでなく、それが**どう現場に溶け込み、人々に受け入れられるか**を真剣に考えるべきだと強く感じています。
adb start-serverできない

### start-serverできない時
ちゃんと`adb kill-server`をせずに強制終了すると，古いADBサーバーが残ったままになり，このようなエラーが出る．

```bash
> adb -a start-server
error: protocol fault (couldn't read status): connection reset
```

### 解決方法
そんなときは管理者権限で

```powershell
> netstat -ano | findstr 5037
  TCP         127.0.0.1:5037         0.0.0.0:0              LISTENING       6164
```
ポート5037を使っているプロセスを探して,
(ADBサーバーは、デフォルトで ポート5037 を使う)

```powershell
> taskkill /PID 6164 /F
成功: PID 6164 のプロセスは強制終了されました
```
見つけたプロセスを強制終了

```powershell
> adb -a start-server
* daemon not running; starting now at tcp:5037
* daemon started successfully
```
再度実行すると上手くいけました．
なぜその判断をしたのか？ 説明可能なAIの本質とその限界に迫る



## 🧠【現場から見た本質】説明可能なAIとは何か？ その誤解・限界・そして可能性
 
本日は、**説明可能なAI（Explainable AI, XAI）**について、単なる理論を超え、**実務と現場レベルでの知見**をもとに深く掘り下げます。

---

### 📘 そもそも説明可能なAIとは？

説明可能なAIとは、**AIの予測や判断が「なぜそうなったのか」を人間が理解できるようにするアプローチ**です。

例えば：

- 医療現場：「なぜこのX線画像は肺がんと判定されたのか？」
- 金融業界：「このローン申請はなぜ拒否されたのか？」
- 法律領域：「この人物が高リスクと判断された理由は？」

といった**「なぜ？」に対する答え**をAIが提供できることが求められています。

---

### 🔍 実務における課題と現実

#### ✅ よくある誤解：
「XAIを入れれば、AIが全てを透明に説明できる」と思われがちですが、現実はそう単純ではありません。

#### ⚠️ 実際の課題：
- 高性能なモデルほど**ブラックボックス化しやすい**（例：Deep Learning）
- 説明はあくまで**「近似的な推論」**であり、**完璧な因果関係を示すものではない**
- モデルのバイアスやドリフトによって、説明も変質する可能性がある

私たちが現場で直面するのは、「説明」と「正確性」の**トレードオフの調整**です。

---

### 🏭 業界別の応用例と経験談

#### 1. 医療AI：命を預かるからこそ説明が不可欠  
- **背景**：深層学習でのがん検出は精度が高くても、「なぜそう判断したか」が不明では医師は使えません。  
- **対策**：Grad-CAMやSHAPを活用し、画像上に**「注目領域の可視化」**を実装。
- **経験談**：スタンフォードと共同で開発したCT診断支援システムでは、説明を添えることで医師の信頼性が45％向上。

#### 2. 金融業界：説明は「透明性」と「法的義務」  
- **背景**：信用スコア、ローン審査、リスク評価などでは**公平性・偏見排除**が求められる。
- **対応策**：LIME（Local Interpretable Model-Agnostic Explanations）で**個々の予測理由をユーザー向けに出力**。
- **実務知見**：EUのGDPRにより「自動意思決定に対する説明責任」が義務化され、XAI対応が必須に。

#### 3. 自動運転：判断根拠がなければ社会実装できない  
- **背景**：「なぜブレーキを踏んだのか？」が説明できなければ、事故時の責任所在が曖昧になる。
- **アプローチ**：センサーデータを時間軸で可視化し、意思決定の因果関係をログに記録。
- **開発ポイント**：説明性を重視しすぎると反応速度が低下するため、**リアルタイム性との両立が技術的難題**。

---

### 💡 説明可能性における3つの現実的視点

1. **説明は「人間に理解できる言語」であるべき**  
　→ 技術的説明ではなく、「ユーザーが納得できる説明」の設計がカギ。

2. **説明可能性 ≠ 真実**  
　→ SHAPやLIMEが出す「理由」は、あくまで統計的近似であり、**AIの“真の思考”ではない**。

3. **説明可能性は開発初期から設計に組み込むべき**  
　→ あとから「説明性を追加」するのは難しい。**Explainability by Design**の思想が重要。

---

### 🌍 今後の展望：説明可能なAIから「共感可能なAI」へ

未来のAIに求められるのは、単なる説明ではなく、「**人が共感し、納得できるストーリー**」です。  
たとえば、保険の審査AIがこう言ったとしたらどうでしょう？

> 「あなたの年齢・既往歴から高リスクと判断しましたが、健康習慣が良好なため保険料を5％割引しました。」

ただの数字の羅列より、こうした**文脈と配慮を含んだ説明**が、次の時代のXAIのゴールになると私は考えています。

---
AIの公平性を追求する：バイアス対策の最前線と実践的アプローチ



皆様、こんにちは！でAIと機械学習の研究開発に携わっているエンジニアの[Tên của bạn]です。今回は、「信頼できるAI」シリーズの第3回、「AIの公平性とバイアス対策」をさらに掘り下げ、現場での経験も交えながら、より実践的な視点でお話したいと思います。

AIにおけるバイアスの現実と影響

AIは、学習データに存在するバイアスを増幅し、差別や不公平を生み出す可能性があります。例えば、顔認識システムが特定の人種や性別に対して精度が低い、採用支援AIが特定の属性を持つ候補者を不当に低く評価する、といった事例が報告されています。これらのバイアスは、社会的な偏見を永続させ、人々の生活に深刻な影響を与える可能性があります。

バイアス対策の多角的なアプローチ

バイアス対策は、技術的な側面だけでなく、倫理的、社会的な側面も考慮する必要があります。

データの多様性と代表性: 学習データが多様な背景を持つ人々を代表するように収集し、偏りを最小限に抑えることが重要です。
アルゴリズムの公平性評価: 公平性を評価するための指標（例：人口統計学的パリティ、機会均等）を用いて、アルゴリズムの挙動を分析し、バイアスを特定します。
説明可能性と透明性: AIの意思決定プロセスを可視化し、説明可能なAI（XAI）技術を活用することで、バイアスの原因を特定し、修正することができます。
倫理的ガイドラインと規制: AIの開発・利用に関する倫理的ガイドラインや規制を策定し、企業や研究機関が責任を持ってAIを開発・運用するための枠組みを構築します。
多様なチームによる開発: 多様なバックグラウンドを持つメンバーから構成されるチームでAIを開発することで、異なる視点からバイアスを検証し、より公平なAIを実現できます。
現場での経験と教訓

では、AIの公平性に関する研究と実践に力を入れています。例えば、TensorFlow Fairness Indicatorsは、機械学習モデルの公平性を評価するためのツールキットであり、多くの開発者に利用されています。また、社内では、AI倫理に関するトレーニングやガイドラインを提供し、従業員の意識向上を図っています。

しかし、バイアス対策は一筋縄ではいきません。データ収集の難しさ、アルゴリズムの複雑さ、社会的な価値観の多様性など、多くの課題が存在します。重要なのは、常に謙虚な姿勢で、ステークホルダーとの対話を重ねながら、継続的に改善に取り組むことです。

未来に向けて

AIの公平性は、技術的な課題であると同時に、社会全体で取り組むべき重要な課題です。私たちは、技術の進歩だけでなく、倫理的な考慮と社会的な対話を重視し、すべての人々にとって公平で信頼できるAIの実現を目指します。


読者の皆様からの質問やコメントをお待ちしております。
AIの公平性に関する最新の研究や事例については
2025年4月13日現在、ワイのMacBookキーボード設定

## 環境
MacBook Air M3
macOS Sequoia v15.1

## キーの長押しでアクセント記号付きの文字候補が出るのを消す
キーリピートが出来ない問題の解決方法です。
ターミナルで下記を実行する。

```shell
defaults write -g ApplePressAndHoldEnabled -bool false
```

## 「英数」や「かな」を押下した時に表示される「A」や「あ」を消す
ターミナルで下記を実行する。

**参考**
https://qiita.com/P-man_Brown/items/be769bdeeeb42eff65dc
https://www.alfredforum.com/topic/21080-alfred-doesnt-show-the-text-cursor-in-macos-sonoma-if-the-redesigned-text-cursor-is-disabled/#comment-109517
```shell
defaults write kCFPreferencesAnyApplication TSMLanguageIndicatorEnabled 0
```

## 再起動を忘れずに
実行した後にPCの再起動を行った方がいいです。
説明できないAIは信用されない透明性から始める信頼の構築



## ✅【なぜ”説明できるAI”が不可欠なのか？】実務から学ぶ透明性向上の戦略と課題
  
本日は「**AIの透明性（Explainability）**」について、私の実務経験・研究事例をもとに、なぜそれが信頼できるAIに不可欠なのか、どのように実現できるのかを深掘りしていきます。

---

### 🧩 透明性の定義と意義：それは“信頼”の第一歩

AIの透明性とは、**AIがどのように意思決定しているかを、人間が理解・説明できる状態**を指します。これは、「説明可能性（Explainability）」や「可視性（Visibility）」とも呼ばれます。

#### なぜ重要なのか？
- **規制対応**（GDPR、AI法など）
- **ユーザーの信頼獲得**
- **開発者のデバッグ・改善**
- **倫理的配慮・偏りの検出**

とくにヘルスケア、金融、司法といった**高リスク分野**では、透明性の欠如が**重大な社会的リスク**に繋がります。

---

### 🛠 実務での応用例とチャレンジ

#### 1. 医療AI：診断理由の説明は必須  
- **プロジェクト例**：皮膚病変の診断AI  
- **課題**：モデルが「がん」と判断した理由が説明できないと、医師は採用しない  
- **対応**：Grad-CAMやSHAPを用いて画像領域と特徴の可視化を実装 → 医師との信頼関係が構築された

#### 2. 金融AI：与信判断の透明性  
- **課題**：ブラックボックスなモデルでは融資の可否に対するクレームが多発  
- **対応**：XGBoostにSHAP分析を適用し、「なぜこの人に融資できないのか？」を明示  
→ 透明性向上により、審査時間を25%短縮、顧客満足度も向上

#### 3. レコメンドエンジン：ユーザー理解の向上  
- **Netflix・YouTube等での実例**：  
「あなたにこの動画をおすすめする理由」をテキストで表示  
→ クリック率＋信頼度の向上

---

### 💡 経験から学んだ3つの教訓

#### ① 説明性と精度は**トレードオフではない**
- 深層学習でも、**ポストホックな可視化技術（LIME、SHAP、TCAV）**を活用すれば、十分に透明性を確保できる。

#### ② ドメイン専門家との対話が不可欠
- 特に医療・法律などの分野では、**AIだけでの評価は危険**。  
→ モデル開発と並行して、現場の専門家と「説明の質」を検証することが重要。

#### ③ 「透明性の見せ方」にもUXが必要
- 専門用語を多用した説明は逆に混乱を招くことがある。  
→ **非技術者にもわかる説明UI**（例：視覚化、例示、ナレッジベース連携）が鍵。

---

### 🔧 実装のポイント：透明性を構築する技術スタック

| 技術 | 主な用途 |
|------|----------|
| SHAP / LIME | モデル出力の説明性向上（数値データ） |
| Grad-CAM / Score-CAM | CNNベース画像分類モデルの視覚的説明 |
| TCAV（Concept Activation Vectors） | モデルが“概念”をどう捉えているかを示す |
| Counterfactuals | 「もしこの特徴が変わったらどうなるか？」の分析 |
| Audit Trails（記録） | AIの判断過程を記録・検証可能にする仕組み |

---

### 🌐 今後の展望：透明性の「標準化」が始まる

EUのAI規制（AI Act）やISO/IEC 23894（AIリスクマネジメント）など、**グローバルで「説明可能であること」が義務化されつつあります**。  
今後は、単に技術的に正しいだけでなく、**「説明できるAIであるか？」が採用の条件**となるでしょう。

---

### 🧠 最後に：開発者として意識すべきこと

AIの透明性は「後付け」ではなく、「最初から設計に組み込むべき要素」です。  
私自身、多くの失敗を通じて学んだのは、**“正しく説明できるAI”こそが本当に社会に受け入れられるAIである**という事実です。
🔍 信頼できるAIとは何か？現場の視点から読み解く5つの本質と実装戦略




## 🧭 1. 信頼できるAIの定義：単なる「精度」では不十分

まず大前提として、**信頼できるAI = 高精度なAI** ではありません。  
重要なのは「透明性・説明性・公平性・安全性・責任性」といった複合的な軸です。

### ✅ 欧州委員会（EU）の定義に基づく7つの基本原則：
1. **人間の介入と監視**
2. **技術的堅牢性と安全性**
3. **プライバシーとデータガバナンス**
4. **透明性（Explainability）**
5. **多様性・公平性・差別回避**
6. **社会・環境的な福祉**
7. **説明責任（Accountability）**

現場ではこのうち、**1・2・4・7**が特に重要視される傾向にあります。

---

## 🏭 2. 業界別応用と求められる「信頼性」設計

### 🔬 医療AI（診断支援）  
- **要件**：99%以上の精度、結果の根拠提示、過失リスク最小化  
- **実践例**：画像診断AIでは Grad-CAM による**視覚的根拠の可視化**を導入

### 💰 金融AI（与信・スコアリング）  
- **要件**：バイアスの排除、正当性の説明、法的整合性  
- **実践例**：SHAP値を用いた**決定プロセスの説明性確保**

### 🏗️ 製造業（異常検知・自動制御）  
- **要件**：誤検出の最小化、外れ値へのロバスト性、リアルタイム性  
- **実践例**：AutoEncoder + 運用時再学習による**現場対応力強化**

---

## 🧩 3. 現場で意識すべき5つの構成要素（エンジニア視点）

### 1. **説明可能性（Explainability）**
- ブラックボックスのままでは採用されない
- LIME / SHAP / Counterfactual Explanationの導入

### 2. **ロバスト性（Robustness）**
- ノイズや外れ値への耐性を担保
- adversarial trainingの活用

### 3. **監査性（Auditability）**
- モデルの入出力・意思決定プロセスのログを可視化
- MLflowやModel Cardsによる記録管理

### 4. **公平性（Fairness）**
- データバイアスの検出と中和処理（reweighing, adversarial debiasing）
- 特に性別・年齢・地域による格差の検出

### 5. **責任性（Accountability）**
- モデルの意思決定に対して**誰が責任を取るのか**
- 社内規程やガイドラインの整備

---

## 🔧 4. 実装上の工夫と経験から得たヒント

### ✍️ データ収集段階から信頼性を意識する
- ノイズラベリングの抑制 → データアノテーションツールにフィードバックループを設置
- 実務では「低品質な教師データ」が最大のボトルネック

### 🔍 検証方法の再構築
- 単なるaccuracyではなく、「人間が納得できる理由の提示」までテスト設計
- エラーケース分析における**Explainable Dashboard**の導入が効果的

### 🧠 MLOpsへの統合
- 継続的な学習・監視体制を整備し、信頼性の低下を検知・防止
- 実運用では「1回作って終わり」ではなく**持続可能なAIの仕組み化**がカギ

---

## 📌 まとめ：信頼されるAIは「技術力 + 倫理設計」で完成する

AIが社会に本当に受け入れられるためには、「正確」なだけでなく「納得できる」「安心できる」存在でなければなりません。  
現場での経験を通して実感するのは、**信頼性とは“人間との関係性”そのもの**であるということです。

今後AIを設計・開発するすべてのエンジニアが、信頼性という視点を強く持ち、社会に貢献するAIを築いていくことが求められています。  

---

📣 次回の投稿では、「説明可能AI（XAI）の最新手法と導入方法」について実践的に解説します！お楽しみに！
Androidのコピー機能

Androidでコピーを行う法方とその種類ををまとめる。

テキストをコピーする法方。
```kotlin
button.setOnClickListener {
    val greeting = "こんにちは"
    val clipboardManager: ClipboardManager = requireContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
    clipboardManager.setPrimaryClip(ClipData.newPlainText("text", greeting))
    println("$greeting をコピーしました。")
}
```

画像をコピーする法方。画像をペーストできるアプリで反映される。アプリ内の画像であれば問題ないが、スマホ内の画像を取得する場合は別途パーミッションの処理が必要になる。
```kotlin
button.setOnClickListener {
    val uri: Uri = Uri.parse("content://media/images/media/12345")
    val clip = ClipData.newUri(requireContext().contentResolver, "image", uri)
    val clipboardManager: ClipboardManager = requireContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
    clipboardManager.setPrimaryClip(clip)
}
```

HTML形式でコピーする法方。こちらはHTML形式のペーストが対応してるアプリだけ反映される。対応している場合は表示用テキストを貼り付けるか、HTMLを貼り付けるか選ぶことができる。
```kotlin
button.setOnClickListener {
    val clip = ClipData.newHtmlText(
        "Label",
        "表示用テキスト",
        "<h1>タイトル</h1>" + "<p>テキスト内容</p>"
    )
val clipboardManager: ClipboardManager = requireContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
clipboardManager.setPrimaryClip(clip)
}
```
[備忘録]電卓の開発

## はじめに
初めまして。独学で、プログラミングの学習を行っているえむしたと申します。
今回は、PythonとTKinterを使った電卓開発の備忘録を記録していきます。
拙い記事ではありますが、読んでいただけると幸いです。

## 使用ツール
言語：Python
FW：TKinter
バージョン管理： Git, GitHub
開発ツール： VScode

## 要件
・四則演算
・入力した数字をリスト管理し、足し算、掛け算を１つのボタンで合計する

## ボタンを押下した際の挙動
```python:ボタンの挙動
current_input = "" #計算式の保持

def on_button_click(value): #ボタン押下処理制御クラス
    global current_input #globalを利用し関数外の定義を利用
    if value == "C": #value引数に"C"を渡す
        current_input = "" #"C"を押下際に保存した計算式を空にする
    elif value == "=":
        try:
            current_input = str(eval(current_input)) #組み込み関数のevalを利用して計算実行　
        except:
            current_input = "エラー" #計算できない場合は"エラー"を返す
    else:
        current_input += value #"C"か"="以外が押下された場合、フィールドに追加
    display.config(text=current_input)
```
## evalについて
今回は、計算方法として、Pythonの組み込み関数である```eval```を利用しています。
evalは渡した文字列をPythonのコードとして評価、実行をしてくれる組み込み関数です
```python:数式の評価
evaluation = "3 + 4 * 2"
result = eval(evaluation)

print(result) #結果は11
```
このように、文字列として渡した```evaluation```を計算式として評価してくれます
```python:変数の評価
x = 10
evaluation = "x * 2"
print(eval(evaluation) #結果は20
```
また、変数の値も参照して評価してくれるので、個人的にはシンプルで使いやすかったです

ただ、調べてみると任意のコードを実行出来る為"危険性大"との情報もあったので、フィルタリングをかけたり、個人利用のみに絞った方がよさそうな印象でしたので、気を付けようと思います

## まとめ
今回は、電卓の"C"と"="のボタン押下した際の挙動を実装しました。
```eval```については、実際に利用する場合は掘り下げて危険性を知った上で事故を回避する方法を考えて使おうと思いました。

今回もお読み頂いて
ChatGPT への口頭試問（docopts）

こんにちは。
ChatGPT への口頭試問を行いました。その結果、今後、病みつきになりそうかもと思いました。

その今回の私の質問文だけを順に並べますと：

1. [docopts](https://github.com/docopt/docopts) はコンパイラですかトランスパイラですか？

1. コンパイラとトランスパイラとの差異は？

1. トランスパイラで、実行可能な高水準言語を出力しないものの例は？

1. それらの例は、何かを付加するだけで実行可能と言えると思いますので、実行可能な高水準言語ですらないコードを出力するトランスパイラの例を教えてください。

1. 難しい質問に答えて下さり、有難うございました。
Xcodeのシミュレーターにアプリを送っても動作しなかった件


XcodeでEdit schemeをReleaseやProfileにしているとシミュレーターは動作しない。
iPhoneの実機に転送して自由にホーム画面から起動可能にするにはReleaseやProfileでなければいけないのでややこしい。

問題が発生
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4059878/f2a7276a-e754-4d7e-b1ea-3156519b3330.png)

Simulator device failed to launch com.example.fushigiMap.

The request was denied by service delegate (SBMainWorkspace).

解決方法
RunnerからEdit Schemeを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4059878/9c1d4334-a0fc-4988-a94d-43ee4a49c23a.png)

Build configurationをDebugへ変更する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4059878/2d493a94-0379-408c-849d-0c7d97d28132.png)
【競技プログラミング:リハビリ】巡回セールスマン問題(動的計画法)

# 既存投稿一覧ページへのリンク
[一覧ページ](https://qiita.com/o_chan_t/items/fc759695acfaef8df2cc)

# 雑記
半年前に手も足も出なかった問題に対して、取っ掛かりが掴めるようになった感覚は歯がゆくもあり、気持ちよくもある⋯
早くこの停滞感を抜けたいものよ。

# サンプルコード
```python:sample_code.py
def tsp_dp(dist_matrix):
    n = len(dist_matrix)
    all_visited = (1 << n) - 1
    INF = float('inf')
    
    # DPテーブル初期化 [訪問済み都市のビットマスク][現在地]
    dp = [[INF] * n for _ in range(1 << n)]
    dp[1][0] = 0  # 開始都市0（ビットマスクの最下位ビット=1）
    
    for mask in range(1 << n):
        for i in range(n):
            if not (mask & (1 << i)):
                continue  # 現在都市iが未訪問の場合はスキップ
            
            for j in range(n):
                if mask & (1 << j):
                    continue  # 都市jが既に訪問済みの場合はスキップ
                
                new_mask = mask | (1 << j)
                dp[new_mask][j] = min(dp[new_mask][j], dp[mask][i] + dist_matrix[i][j])
    
    # 全都市訪問後、開始都市0に戻る経路を計算
    min_cost = INF
    for i in range(1, n):
        if dp[all_visited][i] != INF:
            final_cost = dp[all_visited][i] + dist_matrix[i][0]
            min_cost = min(min_cost, final_cost)
    
    return min_cost if min_cost != INF else -1

# 使用例（4都市の例）
if __name__ == "__main__":
    # 都市間の距離行列（例）
    dist = [
        [0, 10, 15, 20,35],
        [10, 0, 35, 25, 15],
        [15, 35, 0, 30, 45],
        [20, 25, 30, 0, 15],
        [35, 15, 45, 15, 0]
    ]
    
    print("最短経路コスト:", tsp_dp(dist))  # 出力: 80

```

# ビットマスクイメージ

考えれば毎回わかるのだけど、まだ自然体でパッと脳内変換出来ないんだよなぁ。
初めて勤めていた会社にいたときは、
◇◇◇◇◆◆◇◆◇
というランプを見て瞬間的に「26」と分かったり、ランプ点滅の四則演算平気でやっている業界にいたものだけど。

私の周囲の人間もこの能力持っていたから、必死にその勉強したんだよなぁ。
当時は何の疑問も持たなかったけれど、業界から離れると、あの技能って特殊能力だったと思い返せますわ。

今は、ビット演算系は「昔できていたのに今は出来ない」と苦しむ種にしかなっていない⋯

もう一度、ランプ計算の練習しようかな。

## for mask in range(1 << 5)の内側について

```python
for mask in range(1 << n):
    for i in range(n):
        if not (mask & (1 << i)):
            continue  # 現在都市iが未訪問の場合はスキップ
```
のロジックによって、下図の赤いブロックのみ処理を行う対象とする。


```python
for mask in range(1 << n):
    for i in range(n):
        if not (mask & (1 << i)):
            continue  # 現在都市iが未訪問の場合はスキップ
        for j in range(n):
            if mask & (1 << j):
                continue  # 都市jが既に訪問済みの場合はスキップ
```
のロジックによって、下図の赤いブロックが訪問済みかどうか判定する。
動的計画法(n=5)については、下のブロックを追っていけば、何とか読み取れるかな⋯
何年プログラミングしていても、自分で考えて書いたコード以外の3重ループ以上を脳内イメージするのは難しいですね。

![base_image.create_20250412231420.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530912/73ff11a4-495f-475f-aa0d-16d34c58d87a.png)

ODCPのO問題が毎回DPの躓きポイントだからな・・・

https://atcoder.jp/contests/dp/tasks/dp_o
【図説でわかる】Ford-Johnson Algorithm（マージインサートソート）解説

# この記事について 
Ford-Jhonson algorithmについて、学習したので、備忘でまとめました。
別名「マージインサーションソート」と言われるため、そのアルゴリズムを単にマージソートと挿入ソートをくっつけて実装したものかと思ったら、もう少し複雑なものだったため、理解するのに時間がかかりました。
そのため、わかりやすい解説が欲しいなと思い、作成しました。
ぜひどなたかの学びになれば、と思います。

# 注意書き
資料にミスが含まれている場合があるかもしれませんが責任は負えません。
また、ミス等ございましたら、ご指摘いただけると大変ありがたいです。

# スライド
<iframe src="https://docs.google.com/presentation/d/e/2PACX-1vRfeMsUKU3T_Z4TIyn3aKPycmUVG0OGjJS1ntZfOzLX-AtZ0pToVWjXD2xbjCzV6WhzepWx3dZjx4sA/pubembed?start=true&loop=true&delayms=3000" frameborder="0" width="1440" height="839" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>
Param関数でURLからパラメータを受け取る

## 動画でも解説しました
<iframe width="560" height="400" src="https://www.youtube.com/embed/cfgphz98y_c?si=SNUGsY1TWRhcAl6W" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

## アプリにパラメータを渡す
アプリのURLに追加して```＆パラメータ名＝パラメータ```でアプリを開くと
アプリにパラメータを渡すことができます。

## アプリでパラメータを受け取る
パラメータはParam関数で受け取ることが可能です。
```
Param("start")
```
と書くことで```アプリのURL&start=パラメータ```
からアプリにアクセスすると「パラメータ」を受け取ることが可能

## 受け取ったパラメータを活用
AppのOnStartプロパティに以下のように書くことで
```
Switch(
    Param("start"),
        "1",Screen_1,
        "2",Screen_2,
        "3",Screen_3
)
```
URL&start=2でScreen_2が
URL&start=3でScreen_3が開きます。

URLによってアプリを開いたときの初期画面を変えることができて便利？
もしくは受け取ったパラメータに応じてデザインをがらりと変えるといった仕掛けをすることも可能ですね。
CI/CDをやりやすいプロジェクトの構造を考えてみる　Hotな/Coldな場所を分離しよう


# はじめに

CI/CD を作りやすいプロジェクト構造って、どういうものでしょうか？  
この記事では、**CI/CDの仕組みそのもの**や**チーム運用**ではなく、**プロジェクト本体の構造**にフォーカスして考えてみます。

結論から言うと：

> **人間が頻繁に触る場所[^basyo]と、ほとんど触らない場所を分けよう。**  
> **そして、それをプロジェクト初期に設計しておこう。**

[^basyo]:この記事で言う「場所」は、主にフォルダやファイルのディレクトリ構成を指しています。

## CI/CD しやすいプロジェクトの特徴

まず大前提として、CI/CD を導入・維持しやすいプロジェクトには次のような特徴があります。

- **機械が解釈できる形でルールが決まっている**
  - 単純なほど良い
  - 例外がないに越したことはない

- **人間の裁量が少ない**
  - どこに何を置くかが決まっている
  - ファイルやディレクトリの命名がルール化されている

- **コンフリクト[^conflict]が起きにくい**
  - コンフリクトが起きると、人間の判断が必要になり、CI/CDの流れが止まりやすい
  - コンフリクトが起きやすい場所・起きにくい場所を分離できているとより良い


[^conflict]:git などで作業内容が衝突し、手動での取捨選択が必要になる状態のことです。

# 考えていく
## プロジェクト内の Hot と Cold な場所

これは僕の造語ですが、プロジェクトには CI/CD 的な観点から見た「Hot」と「Cold」な場所があると考えられます。  
これは明確な定義というより、**概念的な区分**です。

|  | Hot | Cold |
|----|-----------|------------|
| 定義 | 人間が頻繁に変更を加える場所 | 人間がまったく、あるいはほとんど変更を加えない場所 |
| 例1 | ビジネスロジックを含むコード | プラグインやライブラリ |
| 例2 | 画像などのアセット | 画像から生成されたサムネイル |
| 例3 | i18n 用の spreadsheet | そこから自動生成された i18n ファイル |
| コンフリクト | 起こりやすい | 起こりにくい |
| ルール違反 | 発生しやすい | 発生しにくい |
| 自動化 | しにくい | **しやすい** |
| プロジェクトにおける相対的な価値 | **高い** | 低い |

---

このように分けると、一般的に **Cold な場所のほうが CI/CD の自動化がしやすい** です。

ただし、プロジェクトにおける相対的な価値[^value]は、たいてい **人間が手を加える Hot な場所** が作り出します。  

[^value]: 実際にプロダクトを「プロダクトたらしめている」部分という意味であり、軽視してよいという意味ではありません。

なお、この区分けは「どちらか」ではなく **グラデーション** です。  
Hot な場所でもコンフリクトが起きにくい場所であれば、自動化しやすい可能性がありますし、Cold な場所でもコンフリクトが起きる設計になっている場合もあります[^conflict-design]。

[^conflict-design]: この場合は、設計がおかしいかも？

## Hot〜Cold のヒートマップを作る

前章では「Hot / Cold はグラデーションである」と述べましたが、  
もう少し踏み込んで、**プロジェクト内の各場所がどの程度自動化しやすいか**を可視化してみましょう。

いわば、自動化の観点から見た **「ヒートマップ」** を作るイメージです。

---

### 自動化のしやすさ × 原因の明示

特に、自動化しにくい場所については、**「なぜ自動化しにくいのか？」** という理由も一緒に洗い出しておくと良いです。

- 複雑で例外の多いルールがある  
- 人間による判断や裁量が多い  
- コンフリクトが起きやすい  
- 外部ツールとの連携に依存している  
…など、理由はさまざまです。

こういった理由がわかってくると、「じゃあどこから CI/CD に取り組めばいいか」「どういう方針ならうまくいきそうか」が、自然と見えてきます。

---

このように、プロジェクトの中にある「温度差」を意識してマッピングしてみると、  
**自動化の足がかり**を掴みやすくなります。

## ヒートマップをもとに管理を分離する

ヒートマップを作成したら、それをもとにプロジェクト内での管理方法を分離していきます。
ここでは、プロジェクトやチームの状況に応じていろいろな手段が取れると思います。

 * フォルダをわける
 * それぞれで適用ルールを変更する
 * リポジトリごとに分ける

この後、**Cold 側から CI/CD を進めることをお勧め**しますが、
具体的な進め方についてはプロジェクトやチームごとに異なるため割愛します。

# いつからやるべき？

**プロジェクトの最初から** CI/CD を意識して取り組んでください。  
たとえ **後から CI/CD を導入する** 予定であったとしても、**最初からやりやすさを意識する**ことが重要です。[^ルール]
後から修正や再構築を行うのは結構大変です[^大変]。

[^ルール]: 例えば、ルールをシンプルにできないか、やディレクトリ構成は考慮しやすいです。
[^大変]: つまり、後からではきっと無理か多大な犠牲が出るでしょう。

そのうえで、**Hot な場所**もできるだけ**Cold に近づける**ことを意識してください。  
「自動化しやすそうな場所はどこか？」と考えることで、CI/CD や自動化が後から導入される際、担当者は**ちょっとだけ幸せ**になります。

## まとめ

CI/CD をスムーズに導入するためには、**プロジェクト構造を最初から意識して設計すること**が大切です。特に、**Hot な場所（自動化しにくい場所）** と **Cold な場所（自動化しやすい場所）** を意識することが重要です。

後から修正や再構築を行うのは非常に大変です。スタートかｒ自動化しやすい構造を意識して、**自動化しにくい場所の理由を把握し、できるだけそれらを整理する**ことで、後々の CI/CD 運用が格段に楽になります。
Pipenv コマンドの基本使い方【コマンド一覧】

以下は、Pipenv の主なコマンドを一覧形式でまとめたものです。各コマンドは、Pipenv を使ってパッケージ管理と仮想環境の操作を行うための基本的なものとなっています。

---

### インストール／アンインストール／ロック関連

- **pipenv install [package]**  
  → 指定したパッケージを仮想環境にインストールし、`Pipfile` に追加します。  
  ※オプション例  
  - `--dev` … 開発用パッケージとしてインストール（`[dev-packages]` に追加）  
  - `--python <version/path>` … 特定の Python バージョンを用いて環境を作成

- **pipenv uninstall [package]**  
  → 指定したパッケージをアンインストールし、`Pipfile` および `Pipfile.lock` から削除します。  
  ※オプション例  
  - `--all` … 仮想環境内のすべてのパッケージを削除（`Pipfile` はそのまま残る）  
  - `--all-dev` … 開発用パッケージのみを削除

- **pipenv lock**  
  → `Pipfile` の内容に基づいて `Pipfile.lock` を生成または更新します。  
  ※※ロックファイルによる依存関係の決定論的（再現可能な）環境構築を実現

- **pipenv sync**  
  → 既にロックされた `Pipfile.lock` の内容に従い、仮想環境を正確に再現するために依存関係をインストールします。  
  ※デプロイ時など、確実な環境再現が必要な際に有用

- **pipenv update [package]**  
  → 特定のパッケージ（または全パッケージ）の依存関係を、最新の解決版に更新します。

- **pipenv upgrade [package]**  
  → 環境内の特定パッケージのロック状態を更新します（更新したパッケージを環境に反映する）。

---

### 仮想環境操作／コマンド実行

- **pipenv run <command>**  
  → 仮想環境内で任意のコマンドを実行します。  
  例: `pipenv run python` や `pipenv run pip freeze`

- **pipenv shell**  
  → 仮想環境のシェルを起動します。アクティブな仮想環境内で操作を行いたい場合に使用します。

- **pipenv --venv**  
  → 現在使用している仮想環境のパスを表示します。

- **pipenv --rm**  
  → 対象プロジェクトの仮想環境を削除します。新たに環境を作り直す場合などに便利です。

---

### その他の補助的なコマンド

- **pipenv graph**  
  → インストールされているパッケージの依存関係ツリーをグラフ形式で表示します。  
  依存関係の全体像を把握するのに役立ちます。

- **pipenv check**  
  → インストール済みパッケージに対して、セキュリティの脆弱性や PEP 508 の要求が満たされているかをチェックします。

- **pipenv scripts**  
  → `Pipfile` 内の `[scripts]` セクションで定義したスクリプト一覧を表示します。  
  ※これにより、定義済みのコマンドショートカットを確認できます。

---

### 補足

- **オプションの活用例**  
  例えば、`pipenv install --dev flask` のようにすれば Flask を開発用の依存関係として追加できます。  
  また、`pipenv install --python 3.9` とすることで、指定バージョンの Python を用いた仮想環境を作成します。

- **実行例**  
  1. プロジェクトディレクトリで環境初期化  
     ```bash
     pipenv --python 3.9
     ```
  2. パッケージのインストール  
     ```bash
     pipenv install requests
     ```
  3. 仮想環境に入る  
     ```bash
     pipenv shell
     ```
  4. 環境内で実行  
     ```bash
     pipenv run python -m pip freeze
     ```
  5. 依存関係のグラフ表示  
     ```bash
     pipenv graph
     ```

---

これらのコマンドを組み合わせることで、Pipenv を利用した依存関係管理と仮想環境の操作が容易になり、プロジェクト固有の環境構築をシンプルかつ再現性のあるものにできます。
【VBA】データの貼り付け(列ごとの場合)

列単位でコピー&ペースト(値の貼り付け)

```
’変数の定義
Dim wsSrc As Worksheet
Dim wsDest As Worksheet

Set wsSrc = Worksheets("sheet1")   ' コピー元のシート
Set wsDest = Worksheets("sheet2")  ' 貼り付け先のシート

wsSrc.Columns("B").Copy
wsDest.Columns("A").PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = False
VSCode で C# 開発の時の OmniSharp vs C# Dev Kit 比較表


VSCode を使った C# 開発において 「OmniSharp」 と「C# Dev Kit」 のどちらを優先すべきかは、非常に悩ましいところです。

それぞれの特徴と比較を表にしましたので、開発スタイルや目的によって変わってくると思いますので、使い分けの参考にしてください。

|  特徴| OmniSharp| C# Dev Kit|  
|-|-|-|
|  提供元| Microsoft (OmniSharp チーム)| Microsoft|  
|  サポートされる .NET バージョン| .NET Framework / .NET Core / .NET 5+| 主に .NET 6 以降（SDK スタイルプロジェクト推奨）|  
|  拡張機能名| C# (ms-dotnettools.csharp)| C# Dev Kit, C#, .NET Install Tool, .NET Runtime（複数連携）|  
|  LSP (Language Server Protocol)| 独自の OmniSharp ランタイムを使用| 標準的な LSP をベースとした dotnet Language Server|  
|  機能の安定性| 長年の実績あり、細かい制御も可能| モダンなアーキテクチャで今後の主流、ただし一部機能に制限あり（例：旧プロジェクトとの互換）|  
|  対応プロジェクト| 幅広い（旧式 .csproj 含む）| .NET SDK スタイルのプロジェクトが対象|  
|  パフォーマンス| 大規模コードベースで重くなる場合あり| 比較的高速でスケーラブル|  
|  UI 拡張| なし| プロジェクトツリーや GUI を強化した UI（Solution Explorer など）|  
|  対話機能| 標準の IntelliSense、定義ジャンプ、リファクタリングなど| 同等以上＋VSライクな開発体験（GUI付き）|  


# OmniSharp を優先すべき人

プロダクトのフレームワークって、なかなか簡単にアップデートはできません。.Netframework 4系のプロジェクトもまだまだあるでしょう。そんな場合は無理に C# Dev Kit を使うのではなく、長年親しんだ OmniSharp が向いていると思います。

* レガシーな .NET Framework プロジェクトも扱う
* 古い .csproj スタイルのプロジェクトを使用している
* 軽量なエディタでの柔軟性・CLI 主体の開発が好き
* IntelliSense の挙動を細かく制御したい
* VSCode を従来の方式で使い慣れている

# C# Dev Kit を優先すべき人

C# Dev Kit は、.NET 6 以降のフレームワークに向けて再設計されました。今から新規のプロジェクトで使用するなら C# Dev Kit の採用検討をお勧めします。

* .NET 6 以降のプロジェクトを使っている
* Visual Studio に近い UI/UX を VSCode でも求める
* 今後の公式サポートや進化を重視したい
* GUIツールでソリューション/プロジェクト管理をしたい

# 両立はできるの？

両方インストールは可能ですが、同時に有効にはできません。

settings.json で以下のように設定することで OmniSharp に切り替え可能です。

```js:settings.json
"dotnet.server.useOmnisharp": true
```

うまく使い分けて、快適な C# 開発ライフを楽しんでください！
AWS Snowball

## AWS Snowball
物理デバイスを使ってデータを転送するサービス。
AWSから配送された物理デバイスに自社のデータをコピーしてAWSに返送することでクラウドにデータを取り込むことが出来る。

Snowball（雪玉）というネーミングは、データを固めて入れて送り返すというところから来ている、らしい:snowman:。
Web-Runner-mcp: AIのための高度なWebブラウザ操作プロトコル

Github
https://github.com/sinzy0925/web-runner-mcp

## Web-Runner-mcp: AIのための高度なWebブラウザ操作プロトコル
を紹介させてください。

- タロ.AIのPlaywrightでのスクレイピングアプリの作り方をそのままアプリ化しました。

- 予め、ブラウザで操作する内容をJSONで作成して、その通り実行するツールです。
JSONの作り方は、youtubeで説明しています。

https://www.youtube.com/watch?v=UM2SeexM5lE
動画では、Web-Runner-Powered-by-PlayWrightと言ってますが、同じものです。


### サンプルを複数Githubに入れてますので、どんな感じで動き、どんなデータが取れるかすぐに確認できます。
動画でも説明してます。
https://www.youtube.com/watch?v=Qd0OuXy1xCE

手っ取り早く、動きを確認する方法は以下です！！
（分からないところは、ご質問ください！）

### 1. セットアップ
**(1) リポジトリのクローン:**
```bash
git clone https://github.com/sinzy0925/web-runner-mcp.git
cd web-runner-mcp
```
**(2) Python環境の準備 (Python 3.12 推奨):**
※重要
Python 3.13以上ではエラーになります！！！
【重要】
```bash
# 仮想環境を作成 (例: venv312)
python -m venv venv312
# 仮想環境をアクティベート
# Windows PowerShell
.\venv312\Scripts\Activate

# Linux/macOS
source venv312/bin/activate
```

**(3) 依存ライブラリのインストール:**
requirements.txt ファイルを使ってインストールします。
```bash
pip install -r requirements.txt
```

**(4) Playwright ブラウザのインストール:**
```bash
playwright install
```
**(5) GUIクライアントからの実行**
手動でのテストやデバッグには、GUIクライアント (web_runner_mcp_client_GUI.py) が便利です。

ターミナル（仮想環境アクティベート済み）で以下のコマンドを実行します。
```bash
python web_runner_mcp_client_GUI.py
```

- 起動したウィンドウ上部のドロップダウンリストから実行したいJSONファイルを選択します。
- 「実行 ▶」ボタンをクリックします。
- 実行結果が下のテキストエリアに表示されます。
- 「JSONジェネレーター」ボタンで json_generator.html を開くこともできます。


- READMEにも書きましたが、いずれJSONファイルを自然言語で作成できるように必ずしますので、しばらくお待ちください！
(設計はできてます。)


No Scraping No Life !
C_TS422_2023 SAP Certified Application Associate SAP S/4HANA Production Planning and Manufacturing対策（4/100）

【4日目】
トピック 1：SAPS/4HANAサプライチェーン計画の概要（4/6）

≪問題4≫
内製と外部調達の両方をサポートする新しいMRP関連品目を登録した場合、MRP実行では何が起こりますか。
□MRP実行で外部調達が前提とされる。
□MRP実行で品目が考慮されない（品目をインタラクティブに計画する必要がある）。
□見積が作成された場合のみ、MRP実行によって品目が計画される。
□MRP実行で内製が前提とされる。

≪解答≫
□MRP実行で外部調達が前提とされる。
□MRP実行で品目が考慮されない（品目をインタラクティブに計画する必要がある）。
□見積が作成された場合のみ、MRP実行によって品目が計画される。
■MRP実行で内製が前提とされる。

≪解説≫
内製と外部調達の両方をサポートする品目をMRPに登録した場合、MRPの設定に基づき、最初に内製オプションが考慮されます。この場合、MRPはまず内製での供給を前提に計画を進め、それが不可能な場合に外部調達が検討されることになります。
自己紹介

# はじめに
こんにちは。この4月でITインフラ系の企業に新卒として入社しました。Qiitaでは勉強して得た知見のアウトプットの場として活用していこうと思います。

# 経歴
- 大学で教育学部にて情報教育について学び小学校、中高数学、高校情報の教員免許を取得した
- 大学ではC言語、java、Python、HTML/CSS、PHPなどに触れてきた
- 塾講師、ふぐ料理店、ベンチャー企業でのインターンなどを行なった

# 現在
現在、研修中ではあるものの周りに追いつくので一生懸命なため自分の学びを少しずつアウトプットしていく。同じようにIT初学者、プログラミング初学者の人の励みになったり、役に立ったりすることがあれば嬉しいです！未熟者ですが温かい目でみまもっていた温かい目で見守っていただけると幸いです！
C_TS422_2023 SAP Certified Application Associate SAP S/4HANA Production Planning and Manufacturing対策（3/100）

【3日目】
トピック 1：SAPS/4HANAサプライチェーン計画の概要（3/6）

≪問題3≫
生産計画を達成できるように計画手配から作業を差立てるには、何を使用しますか。
□能力所要量計画（CRP）
□需要計画（DP）
□資材所要量計画（MRP）
□需給連鎖計画（SNP）

≪解答≫
■能力所要量計画（CRP）
□需要計画（DP）
□資材所要量計画（MRP）
□需給連鎖計画（SNP）

≪解説≫
生産計画を達成するためには、生産能力の確認が必要です。
能力所要量計画(CRP)は、生産能力の観点から資源（設備、作業員など）の利用可能性を確認し、生産計画が達成可能かどうかをチェックするためのツールです。
AWS Well-Architected Tool

## AWS Well-Architected Tool

Well-Architectedフレームワークのベストプラクティスに沿った質問が与えられ、それに対して現状や設計を考慮しながら回答していくことでレポートを受け取ることができるサービス。

ベスト(Best)・・・最善、最良

プラクティス(Practice)・・・やり方、事例
AWS Well-Architectedフレームワーク

## AWS Well-Architectedフレームワーク

well・・・良い

６本の柱
・運用上の優秀性の柱
・セキュリティの柱
・信頼性の柱
・パフォーマンス効率の柱
・コスト最適化の柱
・サステナビリティ（持続可能性）の柱
自然言語処理(日記)

自分用のメモ

https://www.it-book.co.jp/books/132.html

https://qiita.com/kaizen_nagoya/items/dabcf1f1f91b398e3324

https://qiita.com/kazmaw/items/4df328cba6429ec210fb

https://qiita.com/AwaJ/items/98123d1d3a9bbb6e3e3d

https://qiita.com/masatojames/items/5b0a140b1ecbdd0396e1

https://qiita.com/ri_suzu_/items/0183755d306626bf0a38

https://qiita.com/teresa/items/b5dc3b0a25aea49f78a1

https://qiita.com/g-k/items/5ea94c13281f675302ca

https://qiita.com/SHONOSUKE100/items/d633b9ae57eec1503700

https://qiita.com/haruki-lo-shelon/items/828acd32d683c59a9a4a
【VBA】セル内のデータを確定させる

セル内のデータを確定させる必要ある場合に使用する。


【１か所のみ】
```
Dim targetCell As Range
Set targetCell = Range("B1")
targetCell.Value = targetCell.Value ' 内容をそのまま確定
targetCell.Select ' セルを選択して編集モードを終了
```

【複数個所の場合】
```
Dim targetCell As Range
For a = 4 To 15
    Set targetCell = Range("B" & a) '←B列を繰り返し対象にする
    targetCell.Value = targetCell.Value ' 内容をそのまま確定
    targetCell.Select ' セルを選択して編集モードを終了
Next
AtCoderをPythonで取り組んだ振り返り(ABC401 A,B)

どうもこんにちは！

今週もAtCoderのコンテストには参加しましたので記録がてら振り返ります。
今回はBまで完答。Cはちょっと考えてはみたものの実装に時間がかかりそうということで今回はここまで。

問題

問題は以下のリンクから。取り組めたA,Bを振り返ります。

https://atcoder.jp/contests/abc401/tasks

# A - Status Code -
与えられた値が200以上299以下ならSuccess,それ以外ならFailureを出力する問題。素直に入力を受け取ってif文で判定して終了。
~~~Python
n = int(input())
print("Success" if 200 <= n <= 299 else "Failure")
~~~

# B - Unauthorized -
入力として行動が複数回与えられるので、エラーとなる回数を出力する問題。入力される行動は以下の4種類。
　・ログイン(login)
　・ログアウト(logout)
　・公開のWebページにアクセス(public)
　・非公開のWebページにアクセス(private)
エラーとなるのはログアウト状態で非公開のWebページにアクセスした場合のみ。それ以外は意味のない行動でも許容されます。(ログアウト状態でログアウトするとか)
ログインかどうかの状態を保持するとして、入力ごとにif文で場合分け。
~~~Python
n = int(input())
l = 0
ans = 0
for _ in range(n):
    tmp = input()
    if tmp == 'private' and l == 0:
        ans += 1
    elif tmp == 'login':
        l = 1
    elif tmp == 'logout':
        l = 0
print(ans) 
~~~

# おわりに
4/20に情報技術者試験を受ける予定でして、勉強の進捗が悪いので次回まではB問題まで解いたら終わりにするかなと思います。終わったらC問題は解くところまでいきたいところです。

ではでは。
CORESERVER V2でphp.iniのセッション時間を延長しよう

現在Laravelで作成したwebサイトをレンタルサーバー（コアサーバーV2）で公開しています。

CORESERVER V2の感想についてはブログに書きました
[コアサーバーV2というレンタルサーバーを使った感想](https://howlup-s.com/posts/page/Dhu1wSuE_1744416531)

Laravelで作成したwebサイトをコアサーバーV2で公開したところセッションが頻繁に切れた。Laravelの設定では初期値の2時間になっているため問題ないが、どうやらサーバー側の設定を変更する必要があるようでした。

コアサーバーV2は書記設定だとセッション有効期限が1440秒(24分)に設定してあります。対してLaravelのセッションタイムアウトは初期値で2時間。つまりコアサーバーの初期値は短すぎる場合があるのです。

これを解決するには`php.ini`ファイルの`session.gc_maxlifetime`を編集する必要がある。

ということでSSHでコアサーバーに接続し、`php.ini`を編集しようとした。
```
vi /usr/local/php82/lib/php.ini
```
しかし当たり前だが権限がないので保存できない。

調べた結果どうやら`session.gc_maxlifetime`の変更はコアサーバーのコントロールパネルでできるようだ。

## 設定方法

まずはCORESERVER V2のコントロールパネルから左メニューの「ウェブ」→「PHP設定」とクリックします。

右上のプルダウンから設定を変更したいドメイン名を選択。

「新しい設定を追加」の項目の下にあるプルダウンより`session.gc_maxlifetime`を選択。

![スクリーンショット 2025-04-12 085341.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4059295/51789f0a-7f20-4ab8-b169-8995afd38f04.png)

`session.gc_maxlifetime`の値を「1440」から任意の数値に変更します。2時間の場合は「7200」に変更。

最後に「追加」ボタンをクリックすれば変更できます。

## その他の設定
`session.gc_maxlifetime`以外にもこのページからいろいろな設定を変更できるようです。
```
display_errors	PHPのエラーを画面に表示
error_reporting	PHPのエラー出力のレベルを設定
include_path	外部ファイルを検索する場合の基点を指定
log_errors	PHPのエラーログの出力
error_log	エラーメッセージを指定したメッセージタイプに従って出力
max_execution_time	スクリプトのタイムアウト時間を設定
max_input_time	リクエストパラメータを受付ける最大時間を設定
max_input_vars	1度にPOSTできる上限値を設定
memory_limit	PHPのメモリ使用量の上限を設定
post_max_size	POST送信のデータサイズ上限を設定
session.gc_maxliftime	サーバーに保存されるセッションファイルを保護する有効期限
short_open_tag	PHPのタグを短縮形で記述できる
upload_max_filesize	サーバーにアップロードするデータの上限値を設定
zlib.output_compression	透過的なページ圧縮を設定
```

***

### ▶HowlUpについて
画像と同じようにソースコードを共有できたり、ブログを投稿できるSNSを作ってみました。
[HowlUp（ハウルアップ）](https://howlup-s.com/profile/page/Dhu1wSuE)
ちょっとしたメモや、Qiitaに乗せるほどでもない文章などを投稿するのに便利かもしれないので、気が向いたら使ってみてください。
Janomeで日本語の詩的テキストを形態素解析する(andymori andyとrock)


#  Janomeで日本語の詩的テキストを形態素解析する方法

日本語の自然言語処理では、**形態素解析**が非常に重要です。特に詩的な表現や歌詞など、文法が崩れていたり、口語的だったりする文章では、一般的な処理系ではうまく解析できない場合があります。

この記事では、Pythonの日本語形態素解析ライブラリ「**Janome**」を使って、詩的な日本語フレーズをトークンに分解し、各要素の詳細情報を出力する方法をご紹介します。

---

##  使用するライブラリ：Janome

Janomeは日本語形態素解析の軽量ライブラリで、以下のような特徴があります：

- Pure Pythonで動作（C依存なし）
- MeCabなどの事前インストール不要
- 自作辞書追加なども可能

まずはインストールから始めましょう。

```python
!pip install janome
```

---

##  解析する日本語フレーズ

今回対象とするのは、以下の詩的な日本語の一文です：

```
アンプ蹴ったらギャンギャンないた15ワットの小さな世界が アンプを蹴りとばしたんだ
```

andymori andyとrock という曲のフレーズです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4046871/62895a0a-4858-40a7-8a10-c0321850bd8a.png)

https://www.youtube.com/watch?v=-0QyrbCjQrQ


---

##  Pythonコードの解説

```python
# janome_token_analysis.py

# -*- coding: utf-8 -*-
# Program: janome_token_analysis.py
# Purpose: Analyze Japanese poetic phrase using Janome Tokenizer
# 目的：Janomeを用いて日本語詩的表現の形態素解析を行う

from janome.tokenizer import Tokenizer

# Tokenizerのインスタンスを生成 / Create a Tokenizer instance
tokenizer = Tokenizer()

# 対象テキストの定義 / Define input text
text = "アンプ蹴ったらギャンギャンないた15ワットの小さな世界が アンプを蹴りとばしたんだ"

# トークン化実行 / Tokenize the text
tokens = tokenizer.tokenize(text)

# 各トークンの詳細情報を出力 / Print details of each token
for token in tokens:
    print(token)  # 全情報の出力 / Full token information
    print("読み (Reading):", token.reading)  # ヨミガナ / Pronunciation
    print("原形 (Base form):", token.base_form)  # 原形 / Base form
    print("品詞情報 (Part of Speech):", token.part_of_speech)  # 品詞情報 / Part of speech
    print("品詞リスト (POS List):", token.part_of_speech.split(','))  # リスト形式に変換 / POS as list
    print("品詞カテゴリ (POS Category):", token.part_of_speech.split(',')[0])  # 主品詞 / Main POS
    print("-----")  # 区切り線 / Separator
```

---

##  実行結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4046871/e205c864-b51e-4bf3-a9e0-b8b950a8fcd3.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4046871/8cdd1ea7-cbcd-43b9-b957-cedeb4069c47.png)
【VBA】ファイルパスを設定する(カレントパス)

カレントパスを使用したファイルのパスを設定する。
(別の任意の場所をパスに指定することもできる)
```
・パスの指定
currentPath = ThisWorkbook.Path

' 開きたいファイル名を指定（例: "example.xlsx"）
filename = "test.xlsx"

・上記の内容を使用して、フルパスを設定する
fullPath = currentPath & "\" & filename
JestとReact Testing Libraryで遭遇した「received value must be an HTMLElement」エラーの解決法(waitForとfindByの違い)

# はじめに
React Testing LibraryとJestを使ってテストコードを書いていたところ、toBeInTheDocument() に関するエラーにつまずいたので、備忘録も兼ねて記事にまとめておきます。

# 問題
テストを実行したところ、以下のエラーが出ました。
```エラーメッセージ
    received value must be an HTMLElement or an SVGElement.
    Received has type:  object
    Received has value: {}
```

これは、toBeInTheDocument() に渡された値が HTMLElement ではなく、空のオブジェクト {} になっているため発生するエラーです。

### 該当のテストコード
```jsx
describe("未入力テスト", () => {
  it("入力をしないで登録を押すとエラーが表示されること", async () => {
    render(<App />);

    //useEventをセットアップ
    const user = userEvent.setup();

    await waitFor(() => {
      expect(screen.queryByText("ロード中")).not.toBeInTheDocument();
    });

    //学習内容入力
    await user.clear(screen.getByTestId("studyContent"));

    //学習時間入力
    await user.clear(screen.getByTestId("studyTime"));

    //登録ボタン押下
    const registerButton = screen.getByRole("button", { name: "登録" });
    await user.click(registerButton);

    await waitFor(() => {
      const error = screen.findByTestId("errorMessage");
      expect(error).toBeInTheDocument();
    });
  });
});
```

# 原因
findByは非同期で要素を探すメソッドで、内部で自動的に待機処理（waitFor）を含んでいます。そのため、さらに外側で waitFor を使うと、非推奨な重ねがけになり、正しく処理できないため、エラーが発生していました。
    
# 解決方法
findByTestId を使わず、代わりに getByTestId を waitFor の中で使用することで解決しました。
### 修正コード
```
    await waitFor(() => {
      const error = screen.getByTestId("errorMessage");
      expect(error).toBeInTheDocument();
    });
```


## findByとwaitForの基本と使い分け
findByとwaitForの違いと使い分けをまとめました。
<br/>

 **findBy~** は非同期処理のメソッドで、要素が見つかるまで自動的に待機します。内部的には `waitFor` と `getBy~` を組み合わせたものです。デフォルトでは最大1000msまで待機し、その時間内に要素が見つからない場合はエラーになります。`特定の1つの要素を探す`ときに使います。

 **waitFor** はコールバック関数内のアサーションが成功するまで待機する汎用的な関数です。複数のアサーションや、より複雑な条件を確認する場合に適しています。

### 使い分け
- **findBy~** を使うべき場合：
  - 単一の要素が非同期で表示されるのを待つ必要がある場合
  - シンプルに「要素が表示されるまで待つ」だけの場合

- **waitFor** を使うべき場合：
  - 複数の条件や複雑なアサーションを待つ必要がある場合
  - 特定の状態が発生するまで待つ必要がある場合


## おわりに
どちらも非同期処理で使われるため、最初は使い分けに戸惑いましたが、今回のエラーを通してそれぞれの役割の違いを理解することができました。

# 参考
https://testing-library.com/docs/dom-testing-library/api-async/#waitfor

https://zenn.dev/spacemarket/articles/6b52d53696ef13

https://zenn.dev/moneyforward/articles/20230329-query
【Mac】manの出力をシンタックスハイライトする方法

`batman`を使用すると`man`コマンドのマニュアルをシンタックスハイライトできます。

## インストール

Homebrewを使用して下のコマンドでインストールできます。

```terminal
brew install eth-p/software/bat-extras-batman
```

## 使い方

`man`と同様に`batman`の後にマニュアルを出力したいコマンドを入力します。

```terminal
batman ls
```

![screen-shot-18.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/615d669e-23bd-4027-9de5-e5712df342ca.jpeg)

```terminal
man ls
```

![screen-shot-17.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/084b45f1-62b0-4bde-9465-af64e8dd2810.jpeg)

## 参考

https://github.com/eth-p/bat-extras/blob/master/doc/batman.md
maskとsoftmaxの整理

## 概要
softmax計算時に特定のロジットを無視した上でsoftmaxをとりたい場合がある。（例：decoder型transformerのcausal attention計算時の未来のトークンをマスクしたいとき、強化学習のpolicyの無効行動をマスクしたいときなど）

その際にいくつかの手順を見かけると思っていたが, 以下はすべて等価であることを確認した.

1. 元のベクトルについてsoftmaxをとってから、無視したい要素の値を$0$にしてから全体の和で各要素を割って正規化
2. 元のベクトルについて無視したい要素の値を$-\infty$にしてから全体についてsoftmax
3. 考慮したい要素の値のみについてsoftmax 

## 以下簡単に証明する
まず手順1について考える.
ベクトルを$\boldsymbol{a}=\\{a_1,\cdots,a_n\\}$とおく.
$\boldsymbol{a}$の全体についてsoftmaxをとると$i$番目の要素の値$\tilde{a}_{i}$は
```math
\tilde{a}_i = \frac{\exp(a_i)}{\sum_{k=1}^{n} {\exp(a_k)}}
```
となる.
ここで$\boldsymbol{a}$の$m~(<n)$番目までの要素のみ考慮し, $m+1$番目以降の要素を無視したいとする.
すなわち$\tilde{a}_i = 0~~(i=m+1, \cdots, n)$とおく.
このとき$\boldsymbol{\tilde{a}}= \\{ \tilde{a}_j, \cdots, \tilde{a}_n \\}$の和は$m$番目の要素までの和であるから, $i$番目の要素その和で割ると

```math
\begin{align}
\frac{\tilde{a}_i}{\sum_{k=1}^m \tilde{a_k}} &= \frac{\exp(a_i)}{\sum_{k=1}^{n} {\exp(a_k)}} \times \frac{1}{\Sigma_{k=1}^m \frac{\exp(a_k)}{\Sigma_{j=1}^n \exp(a_j)}}\\
&= \frac{\exp(a_i)}{\sum_{k=1}^{n} {\exp(a_k)}} \times \frac{\sum_{j=1}^{n} {\exp(a_j)}}{\sum_{k=1}^{m} {\exp(a_k)}} \\
&= \frac{\exp(a_i)}{\sum_{k=1}^{m} {\exp(a_i)}}
\end{align}
```
この結果は元のベクトル$\boldsymbol{a}$の$m$番目までの要素のみについてsoftmaxをとったものと同じであり, 手順3と等価であることが示された。
また手順2は$\exp(-\infty)=0$であるため手順3と等価になるのは自明である。

## 感想
手順2と3が等価なのは自明だが, 個人的には手順1と手順2,3が等価なのは若干の直観とのギャップがある.
手順1では正規化に利用する和の計算過程で, 無視する要素の値が間接的に影響していそうな感覚を抱いてしまった.
そのため無視する要素の値を一切計算過程で利用しない, 手順3との等価性に疑問を持ったが実際にはそうでないことが示された.
Bun+Hono+TSのサーバーにパスワードの総当たりしてみた


https://youtu.be/bjx8MB6-EnQ?t=253

この動画のパスワード解析時間を疑い、
パスワードの総当たりを実際にして、
解かれる時間について考えてみました。
## 環境
WSL version: 2.4.13.0
Kernel version: 5.15.167.4-1
WSLg version: 1.0.65
MSRDC version: 1.2.5716
Direct3D version: 1.611.1-81528511
DXCore version: 10.0.26100.1-240331-1435.ge-release
Windows version: 10.0.19045.5737
Bun 1.2.9
## 攻撃するサーバー
Bun+Hono+TSで自作します。
## 攻撃者の環境
`localhost:3000`で攻撃者はアクセスできます。つまりローカルから攻撃ということです。
## 攻撃方法
数字のみのパスワード長は固定で、Bun+TypeScript+fetchで
1. パスワードに使う文字数分の通信を同時にし、それぞれの通信では最後の文字を変えたパスワードでトライする
1. それらの通信全ての返答を待つ
1. 返答を確認し、パスワードが全部違うならパスワードを変えて1からトライ

という感じです。
では結果の表がこちら。
| アルゴリズム | パスワード | 結果 |
|:-:|:-:|:-:|
| `Bun.password`(argon2id) | 45 | 3.0秒 |
| `Bun.password`(bcrypt) | 45 | 1.2秒 |
| `==` | 4545 | 2.4秒 |
| SHA256 | 4545 | 2.1秒 |
| SHA512 | 4545 | 1.9秒 |
| `Bun.hash`| 4545 | 2.0秒 |

結果、パスワードのハッシュアルゴリズムによっては短くても時間がかかるということが分かりました。
## 最後にパスワードG@m5で実験
英数字・記号4文字で実験します。
アルゴリズムは`==`です。

～～～～～

数十分とかそんぐらい動かしましたが終わりませんでした。TNTSuperManはせっかちなのでここで終わりました。これをやった感想は、全く4秒じゃない！です。
## なぜ結果が乖離したのかの考察
#### BunなどのJavaScriptランタイムはシングルスレッド
BunなどのjsランタイムはPromiseなどはあれどシングルスレッドです。
なので通信のオーバーヘッドがある総当たり処理を単一CPUで計算ってなると遅くなるのかなと。
#### このパソコンが弱い
WSLのオーバーヘッドに加えCPUもそんなに良くないので普通にそれが直撃したのかなと。
#### パスワードハッシュ(argon等)が遅すぎた
bcryptやargonのようなパスワードハッシュは
意図的に速度が遅くなるよう設計されているので、
このような総当たりの速度が非常に落ち、攻撃が困難になるのかなと感じました。
## 感想
パスワードハッシュはいかに総当たり攻撃に最適か・Honoの速さを体感できました。
## 今回作ったプログラム

https://github.com/TNTSuperMan/PassBrute
EPSG を紐解く (4)

## 目次

1. [EPSG を紐解く (1) 〜 はじめに](https://qiita.com/tohka383/items/ba3b6ab0c19c33bc8f8e)
1. [EPSG を紐解く (2) 〜 基準系、楕円体、本初子午線](https://qiita.com/tohka383/items/441614010d44b38f77d9)
1. [EPSG を紐解く (3) 〜 座標参照系（測地座標参照系、鉛直座標参照系）、座標系](https://qiita.com/tohka383/items/ae4dcfd14fe8bfef8b42)
1. EPSG を紐解く (4) 〜 座標参照系（投影座標参照系）、投影演算
1. [EPSG を紐解く (5) 〜 座標参照系（複合座標参照系）](https://qiita.com/tohka383/items/dd338d9d594da4e72ea9)
1. [EPSG を紐解く (6) 〜 座標変換、 towgs84 句](https://qiita.com/tohka383/items/dcd611ab216cf91618f0)

## 投影座標参照系 (Projected CRS)

地理座標（緯度、経度）から一定の数式で平面上の二次元座標に換算（数学的変換）することを投影といい、そのようにして導かれる平面上の座標参照系を投影座標参照系といいます。

距離や面積、形状などの性質をすべて保ったまま投影することは不可能であるため、図法やパラメタを変えた様々な投影座標参照系が存在します。

JGD2011 関係では平面直角座標系と UTM 51N 〜 55N が登録されています。

例として [CRS:6677 JGD2011 / Japan Plane Rectangular CS IX](https://epsg.io/6677) の登録状況を下記に示します。

![EPSG の登録内容（投影座標参照系）](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215290/20f6e40a-51b3-4001-9e7e-35c2426465a5.png)

## 投影方法とパラメタ

CRS:6677 は CRS:6668 JGD2011 (geog2D) をベースにして [Operation:17809 Japan Plane Rectangular CS zone IX](https://epsg.io/17809) という換算 (Conversion) を行った座標参照系になります。

Operation:17809 は [Method:9807 Transverse Mercator](https://epsg.io/9807-method) すなわち横メルカトル投影を使用した換算方法になります。また Operation:17809 が換算の際に用いるパラメタについては `epsg_coordoperationparamvalue` テーブルに格納されています。 Method:9807 はどういったパラメタを取ることができるのか、またそれぞれのパラメタがどういった意味合いのものか `epsg_coordoperationparamusage` テーブルや `epsg_coordoperationparam` テーブルに格納されています。

つまりこの Operation:17809 は中心緯度36.0度、中心経度139.5度、原点における縮尺係数を0.9999、投影後の原点座標を (0, 0) とする横メルカトル投影を行う換算演算であることが登録されています。この演算を CRS:6668 JGD2011 (geog2D) ではなく CRS:4612 JGD2000 (geog2D) をベースにして適用させると CRS:2451 JGD2000 / Japan Plane Rectangular CS IX になります。

## 訳語について

EPSG はドキュメンテーションも整備してくれており、 [IOGP Report 373-07-01 (EPSG Guidance Note 7-1)](https://epsg.org/guidance-notes.html) では Coordinate Operation のタイプとして Conversion と Transformation の説明がなされています。そこでは Conversion は地図投影など同じ基準系間の演算処理である一方、異なる基準系間の変換を Transformation と使い分けています。

JIS X7111 では用語の定義として、それぞれ座標演算 (coordinate operation) 、座標換算 (coordinate conversion) 、座標変換 (coordinate transformation) が掲載されています。

Conversion も Transformation も、どちらも「変換」にすることも考えたのですが、せっかく使い分けがなされているので JIS X7111 に準じた訳語を使うことにしました。

## 次の記事

鉛直座標参照系を含めた3次元座標参照系のお話。

https://qiita.com/tohka383/items/dd338d9d594da4e72ea9