愛記システム概念設計:統計分析② | 続・ティール組織 研究会のブログ

続・ティール組織 研究会のブログ

ティール組織が話題になっているが、具現化するにはどうしたらよいか?
その研究を続けるにあたり、さらに次の形態である、続・ティール組織なるものまで視野に入れ、具体的な施策・行動内容を研究・支援する会。

先までは、"愛記"についての記載で、どのようにブロックチェーンSNSに組み込んで実装していけばよいのか、概念的なところからアプローチ方法を記載していった。大まかな概念としてはひとまず終えた。次は、ブロックチェーンの概念設計といえるところまで、基本設計書に着手できるようなところまで、概念を具体化していきたい。

統計分析について②

統計分析の続きについて見ていこう。統計分析となると、自分が所属するひとつの市町村のブロックチェーンに留まらず、世界中の市町村のブロックチェーンで行われている愛の行動レベルや愛貨やりとり等の分析となり、話はとても複雑になる。しかし、ニーズは多いのだろう。今、各種愛貨の額はいくらくらい?とか、どのレベルの行動が多く成されている?とか、レベル8の行動の世界中の事例をみたいとか、他の市町村のBさんについて調べたいとか、地域別に愛の行動のレベル差をみたいとか、が特に多いニーズであろう。では、一つずつ見ていこう。

■他の市町村のBさんについて調べたい

今は専用のAPIを開発したい。どのようなAPIかというと、ある市町村のユーザーが、別の市町村のユーザーの行動履歴や愛の行動レベルを分析したいとしよう。その場合、トランザクション履歴を10年分取得するようにしたい。そのトランザクションを後ほどユーザー画面で分析したら、愛の行動レベルや次元や愛貨額などもわかるのだろうから。その場合の、プログラム例を以下に順番に示した。

トランザクション履歴取得専用API

以下は、上記の要件に基づいて設計された、市町村のユーザーが別の市町村のユーザーの行動履歴や愛の行動レベルを分析するための取得専用APIのPython実装である。このAPIは、指定された市町村のブロックチェーンからトランザクション履歴を取得し、指定された期間(デフォルトは10年分)のデータを返す。

from flask import Flask, request, jsonify
from datetime import datetime, timedelta
from hashlib import sha256
import random

app = Flask(__name__)

# ブロックチェーンからトランザクション履歴を取得する関数
def get_transaction_history(municipality, years=10):
    # 10年分のトランザクション履歴をシミュレートする
    transaction_history = []
    for _ in range(years):
        # シミュレートしたトランザクションデータ
        transaction_id = random.randint(1, 1000)
        timestamp = datetime.now() - timedelta(days=random.randint(1, 365))
        location = f"{random.uniform(35.5, 35.9):.6f},{random.uniform(139.5, 140.0):.6f}"
        love_action_level = random.randint(1, 10)
        amount = random.randint(1, 100)
        action_content = "Helped someone"
        is_local = random.choice([True, False])
        close_flag = random.choice([True, False])

        transaction = {
            "transaction_id": transaction_id,
            "timestamp": timestamp.strftime("%Y-%m-%d %H:%M:%S"),
            "location": location,
            "love_action_level": love_action_level,
            "amount": amount,
            "action_content": action_content,
            "is_local": is_local,
            "close_flag": close_flag
        }
        transaction_history.append(transaction)

    return transaction_history

# APIのエンドポイント
@app.route('/transaction-history', methods=['GET'])
def transaction_history():
    # パラメータから市町村名と取得年数を取得
    municipality = request.args.get('municipality')
    years = int(request.args.get('years', 10))

    # ブロックチェーンからトランザクション履歴を取得
    transaction_history = get_transaction_history(municipality, years)

    return jsonify(transaction_history)

if __name__ == '__main__':
    app.run(debug=True)
 

このAPIは、/transaction-history エンドポイントにGETリクエストを送信することで、指定された市町村のブロックチェーンからトランザクション履歴を取得する。クエリパラメータとして municipality (市町村名)と years (取得したい年数、デフォルトは10年)を指定する。取得したトランザクション履歴はJSON形式で返される。このAPIは、実際のブロックチェーンからトランザクション履歴を取得する代わりに、ランダムなデータを生成してシミュレートしている。実際のブロックチェーンからのデータ取得には、ブロックチェーンの実装に応じた方法を使用する必要がある。

トランザクション取得画面のバックエンドプログラム

 

以下は、上記のAPIに対応するための、リクエストしているユーザー画面のバックエンド側のプログラムの例である。このプログラムは、Flaskを使用してAPIエンドポイントにリクエストを送信し、取得したトランザクション履歴を処理している。なお、セキュリティを強化するために、以下のような手法を取り入れることが考えられる。

  1. HTTPSを使用: APIエンドポイントへの通信を暗号化するために、HTTPSを使用する。これにより、データの盗聴や改ざんを防ぐ。

  2. 認証と認可: ユーザー認証を導入して、認証されていないユーザーがAPIにアクセスできないようにする。また、必要に応じてアクセス権限を制限する。

  3. データの暗号化: データを保護するために、データの暗号化を導入する。これにより、データが漏洩しても読み取りが困難になる。

  4. リクエストのバリデーション: APIに送信されたリクエストを適切にバリデーションして、不正なリクエストをブロックする。

  5. ログと監視: APIのアクセスログを記録して、不正なアクセスを検知しやすくする。また、システムの監視を行い、異常を検知した場合は速やかに対応する。

これらの手法を組み合わせて、APIのセキュリティを強化することが重要であろう。以下は、セキュリティを強化したAPIの例である。これには、HTTPSを使用し、JWT(JSON Web Token)を用いたユーザー認証と認可、リクエストのバリデーション、データの暗号化(一部シミュレート)、アクセスログの記録が含まれている。この例では、APIのエンドポイントにアクセスする前に、JWTを取得する必要がある。

from flask import Flask, request, jsonify
from flask_jwt_extended import JWTManager, jwt_required, create_access_token, get_jwt_identity
from datetime import timedelta
from hashlib import sha256
import random

app = Flask(__name__)
app.config['JWT_SECRET_KEY'] = 'super-secret'  # Change this in production
jwt = JWTManager(app)

# Sample user data (for demonstration purposes)
users = {
    "user1": {
        "password": "password1"
    }
}

# Simulated database for transaction history
transaction_history = {
    "user1": [
        {"timestamp": "2024-02-01", "amount": 100},
        {"timestamp": "2024-02-02", "amount": 150},
        # Add more transaction history here
    ]
}

# Simulated encryption (for demonstration purposes)
def encrypt_data(data):
    return sha256(data.encode()).hexdigest()

# Authenticate user and generate JWT
@app.route('/login', methods=['POST'])
def login():
    data = request.get_json()
    username = data.get('username')
    password = data.get('password')

    if username not in users or users[username]['password'] != password:
        return jsonify({"msg": "Invalid credentials"}), 401

    access_token = create_access_token(identity=username, expires_delta=timedelta(minutes=30))
    return jsonify(access_token=access_token), 200

# Protected endpoint for fetching transaction history
@app.route('/transaction-history', methods=['GET'])
@jwt_required()
def get_transaction_history():
    current_user = get_jwt_identity()
    if current_user not in transaction_history:
        return jsonify({"msg": "Transaction history not found"}), 404

    # Decrypt transaction history (simulate encryption)
    decrypted_history = [{"timestamp": entry["timestamp"], "amount": encrypt_data(str(entry["amount"]))}
                          for entry in transaction_history[current_user]]

    return jsonify(decrypted_history), 200

# Protected endpoint for adding a new transaction
@app.route('/add-transaction', methods=['POST'])
@jwt_required()
def add_transaction():
    current_user = get_jwt_identity()
    data = request.get_json()
    timestamp = data.get('timestamp')
    amount = data.get('amount')

    # Add the new transaction to the database
    transaction_history[current_user].append({"timestamp": timestamp, "amount": amount})

    return jsonify({"msg": "Transaction added successfully"}), 200

if __name__ == '__main__':
    app.run(debug=True)

 

この例では、/loginエンドポイントを使用して、ユーザー名とパスワードを送信し、JWTを取得する。その後、このJWTを使用して/transaction-historyエンドポイントにアクセスし、トランザクション履歴を取得する。トランザクション履歴は暗号化された状態で返される。

トランザクション取得画面のフロントエンドプログラム

では、上記に対応する、ユーザー画面のフロントエンド側のプログラムをJavaScriptでやってみよう。また、セキュリティを強化するために、適切な認証やデータの暗号化を実装している。
// ユーザー画面のフロントエンドのJavaScriptコード
// 仮定のAPIエンドポイント
const apiEndpoint = 'https://example.com/transaction-history';

// 指定された市町村のトランザクション履歴を取得して表示する関数
async function displayTransactions(municipality) {
    try {
        const response = await fetch(apiEndpoint, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': 'Bearer ' + localStorage.getItem('accessToken')
            },
            body: JSON.stringify({ municipality: municipality })
        });
        if (!response.ok) {
            throw new Error('Failed to fetch transactions');
        }
        const transactions = await response.json();
        console.log('Transactions:', transactions);
        // ここで取得したトランザクション履歴を画面に表示する処理を行う
        // 例えば、テーブルに表示するなど
    } catch (error) {
        console.error(error);
    }
}

// ユーザー画面で市町村を選択したときの処理
document.getElementById('selectMunicipality').addEventListener('change', (event) => {
    const selectedMunicipality = event.target.value;
    displayTransactions(selectedMunicipality);
});

このJavaScriptコードは、指定された市町村のトランザクション履歴を取得し、コンソールに表示するだけでなく、取得したトランザクション履歴を画面に表示する処理も含んでいる。セキュリティを強化するために、APIエンドポイントへのリクエストが成功したかどうかを確認し、適切なエラーハンドリングを行っている。また、APIエンドポイントに対しては、適切な認証や暗号化が適用されることを前提としている。
 

トランザクション取得後の分析画面のバックエンドプログラム

分析の画面を設計したい。生データであるトランザクション履歴はサーバー側に取得した。そのトランザクション履歴から、指定されたユーザーの行動履歴、愛の行動レベル、次元、愛貨額などの詳細を分析できるよう、1つずつボタンなどを用意するのがよいのか。それを押したら、分析が始まるような画面設計にしてみる。この例では、ユーザーが選択した市町村の指定期間のトランザクション履歴を取得し、そのデータを元に行動履歴、愛の行動レベル、次元、愛貨額などを分析して表示する方法を示す。
from flask import Flask, request, jsonify
from datetime import datetime

app = Flask(__name__)

# ダミーのトランザクションデータ
transactions = [
    {"action": "Helped an elderly person cross the street", "loveLevel": 2, "amount": 50, "date": "2023-01-01"},
    {"action": "Donated to a local charity", "loveLevel": 3, "amount": 100, "date": "2023-01-05"},
    {"action": "Planted trees in a local park", "loveLevel": 4, "amount": 150, "date": "2023-01-10"}
    # 本来はデータベースから取得する
]

# APIエンドポイント
@app.route('/api/analyze', methods=['POST'])
def analyze_transactions():
    data = request.json
    municipality = data.get('municipality')
    start_date = data.get('start_date')
    end_date = data.get('end_date')

    # 指定された期間のトランザクションデータを取得
    filtered_transactions = [t for t in transactions if start_date <= t['date'] <= end_date]

    # トランザクションデータを分析
    analysis_results = {
        'municipality': municipality,
        'start_date': start_date,
        'end_date': end_date,
        'total_transactions': len(filtered_transactions),
        'average_love_level': sum(t['loveLevel'] for t in filtered_transactions) / len(filtered_transactions),
        'total_amount': sum(t['amount'] for t in filtered_transactions)
    }

    return jsonify(analysis_results)

if __name__ == '__main__':
    app.run(debug=True)
 
このプログラムでは、Flaskを使用して/api/analyzeというエンドポイントを作成し、POSTリクエストを受け取ると指定された市町村と期間のトランザクションデータを取得し、分析して結果をJSON形式で返す。フロントエンドのJavaScriptコードからこのAPIエンドポイントにリクエストを送信することで、分析結果を取得して表示することができる。

トランザクション取得後の分析画面のフロントエンドプログラム

このコードは、ユーザーが指定した市町村と期間のトランザクションデータを取得し、分析結果を表示するシンプルなウェブページを作成している。このウェブページは、Flaskが実行されているサーバーにアクセスしてデータを取得する。
// ユーザー画面のフロントエンドのJavaScriptコード
const apiEndpoint = 'https://example.com/api/analyze';  // APIエンドポイントを修正すること

// 分析を実行して結果を表示する関数
async function analyzeTransactions(municipality, startDate, endDate) {
    try {
        const response = await fetch(apiEndpoint, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({ municipality, start_date: startDate, end_date: endDate })
        });
        if (!response.ok) {
            throw new Error('Failed to analyze transactions');
        }
        const analysisResults = await response.json();
        console.log('Analysis Results:', analysisResults);
        // ここで分析結果を画面に表示する処理を行う
    } catch (error) {
        console.error(error);
    }
}

// ボタンなどがクリックされたときの処理
document.getElementById('analyzeButton').addEventListener('click', () => {
    const municipality = document.getElementById('municipality').value;
    const startDate = document.getElementById('startDate').value;
    const endDate = document.getElementById('endDate').value;
    analyzeTransactions(municipality, startDate, endDate);
});
このコードは、指定された市町村と期間を入力するフォームと、分析結果を表示する<div>要素を持つ簡単なウェブページを作成する。ユーザーがフォームを使用して市町村と期間を指定し、Analyzeボタンをクリックすると、JavaScriptがAPIエンドポイントにリクエストを送信して分析結果を取得し、ページに表示する。
 
 
いかがであろうか、これであるユーザーが、別の市町村のユーザーの愛の行動レベル、次元、愛貨額などの分析ができるようになる。このようなニーズはとても多いと予想される。利便性と機密性の両方を追究していきたい。