refactor: 重组项目目录结构
以讲义内容为骨架迁移到标准目录格式: - officefile/ 主内容(12章 + 附录 + CC4SI补充) - dofile/ 代码示例(11个Python脚本) - data/ 图片资源 - output/ 生成输出(忽略) - Archive/ 归档旧目录(忽略) - .claude/skills/ 保留markdown-to-docx工具链 - .pandoc/ 保留CSL和本地化配置 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,827 @@
|
||||
"""
|
||||
反馈与学习示例 (Feedback and Learning Example)
|
||||
=============================================
|
||||
|
||||
本示例展示如何在空间智能系统中实现反馈机制和学习能力。
|
||||
反馈和学习使系统能够从经验中改进,提高决策质量。
|
||||
|
||||
核心概念:
|
||||
1. 反馈循环 - 收集用户/系统的反馈
|
||||
2. 性能评估 - 评估决策效果
|
||||
3. 参数调整 - 根据反馈调整系统参数
|
||||
4. 经验存储 - 保存和检索历史经验
|
||||
5. 迁移学习 - 将知识应用到新场景
|
||||
|
||||
应用场景:
|
||||
- 自适应决策权重调整
|
||||
- 模型参数优化
|
||||
- 用户偏好学习
|
||||
- 决策效果跟踪
|
||||
|
||||
作者: CC4SI 项目组
|
||||
"""
|
||||
|
||||
import math
|
||||
import json
|
||||
from typing import List, Dict, Tuple, Optional, Any, Callable
|
||||
from dataclasses import dataclass, field
|
||||
from enum import Enum
|
||||
from datetime import datetime
|
||||
import random
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# 反馈类型定义
|
||||
# ============================================================================
|
||||
|
||||
class FeedbackType(Enum):
|
||||
"""反馈类型枚举"""
|
||||
EXPLICIT = "explicit" # 显式反馈 (用户评分/评价)
|
||||
IMPLICIT = "implicit" # 隐式反馈 (行为数据)
|
||||
OUTCOME = "outcome" # 结果反馈 (实际结果)
|
||||
CORRECTION = "correction" # 纠正反馈 (修正建议)
|
||||
RANKING = "ranking" # 排序反馈 (偏好排序)
|
||||
|
||||
|
||||
class FeedbackSource(Enum):
|
||||
"""反馈来源枚举"""
|
||||
HUMAN_EXPERT = "human_expert" # 人类专家
|
||||
SYSTEM_AUTO = "system_auto" # 系统自动
|
||||
SENSOR_DATA = "sensor_data" # 传感器数据
|
||||
CROWDSOURCING = "crowdsourcing" # 众包
|
||||
PEER_REVIEW = "peer_review" # 同行评审
|
||||
|
||||
|
||||
@dataclass
|
||||
class Feedback:
|
||||
"""
|
||||
反馈数据结构
|
||||
|
||||
表示一次具体的反馈事件。
|
||||
"""
|
||||
feedback_id: str
|
||||
feedback_type: FeedbackType
|
||||
source: FeedbackSource
|
||||
target_decision_id: str
|
||||
value: float # 反馈值 (如评分)
|
||||
content: Optional[str] = None # 反馈内容
|
||||
metadata: Dict[str, Any] = field(default_factory=dict)
|
||||
timestamp: datetime = field(default_factory=datetime.now)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"Feedback({self.feedback_type.value}, value={self.value:.2f})"
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# 决策记录
|
||||
# ============================================================================
|
||||
|
||||
@dataclass
|
||||
class Decision:
|
||||
"""
|
||||
决策记录
|
||||
|
||||
保存系统做出的一次决策的完整信息。
|
||||
"""
|
||||
decision_id: str
|
||||
context: Dict[str, Any] # 决策上下文
|
||||
alternatives: List[Dict[str, Any]] # 可选方案
|
||||
selected_alternative: int # 选择的方案索引
|
||||
model_version: str # 使用的模型版本
|
||||
parameters: Dict[str, Any] # 决策参数
|
||||
predicted_outcome: Optional[float] = None # 预测结果
|
||||
actual_outcome: Optional[float] = None # 实际结果
|
||||
feedback_list: List[Feedback] = field(default_factory=list)
|
||||
timestamp: datetime = field(default_factory=datetime.now)
|
||||
|
||||
def add_feedback(self, feedback: Feedback) -> None:
|
||||
"""添加反馈"""
|
||||
self.feedback_list.append(feedback)
|
||||
|
||||
def get_average_feedback(self) -> float:
|
||||
"""获取平均反馈分数"""
|
||||
if not self.feedback_list:
|
||||
return 0.0
|
||||
return sum(f.value for f in self.feedback_list) / len(self.feedback_list)
|
||||
|
||||
def get_outcome_error(self) -> Optional[float]:
|
||||
"""获取预测误差"""
|
||||
if self.predicted_outcome is not None and self.actual_outcome is not None:
|
||||
return abs(self.predicted_outcome - self.actual_outcome)
|
||||
return None
|
||||
|
||||
def calculate_regret(self) -> float:
|
||||
"""
|
||||
计算后悔值
|
||||
|
||||
后悔值 = 最优选择的结果 - 实际选择的结果
|
||||
"""
|
||||
if not self.alternatives or self.actual_outcome is None:
|
||||
return 0.0
|
||||
|
||||
# 假设alternatives中存储了各个选项的实际结果
|
||||
best_outcome = max(
|
||||
alt.get("actual_outcome", self.actual_outcome)
|
||||
for alt in self.alternatives
|
||||
)
|
||||
return best_outcome - self.actual_outcome
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# 经验存储
|
||||
# ============================================================================
|
||||
|
||||
class ExperienceStore:
|
||||
"""
|
||||
经验存储
|
||||
|
||||
存储和检索历史决策经验,用于学习和改进。
|
||||
"""
|
||||
|
||||
def __init__(self, capacity: int = 1000):
|
||||
"""
|
||||
初始化经验存储
|
||||
|
||||
Args:
|
||||
capacity: 最大存储容量
|
||||
"""
|
||||
self.capacity = capacity
|
||||
self.decisions: Dict[str, Decision] = {}
|
||||
self.decision_list: List[str] = [] # 按时间顺序的ID列表
|
||||
|
||||
def add_decision(self, decision: Decision) -> None:
|
||||
"""添加决策记录"""
|
||||
self.decisions[decision.decision_id] = decision
|
||||
self.decision_list.append(decision.decision_id)
|
||||
|
||||
# 超过容量时删除最旧的
|
||||
if len(self.decision_list) > self.capacity:
|
||||
oldest_id = self.decision_list.pop(0)
|
||||
del self.decisions[oldest_id]
|
||||
|
||||
def get_decision(self, decision_id: str) -> Optional[Decision]:
|
||||
"""获取决策记录"""
|
||||
return self.decisions.get(decision_id)
|
||||
|
||||
def get_recent_decisions(self, n: int = 10) -> List[Decision]:
|
||||
"""获取最近的n条决策"""
|
||||
recent_ids = self.decision_list[-n:]
|
||||
return [self.decisions[id] for id in recent_ids]
|
||||
|
||||
def find_similar_decisions(self, context: Dict[str, Any],
|
||||
threshold: float = 0.8) -> List[Decision]:
|
||||
"""
|
||||
查找相似上下文的决策
|
||||
|
||||
Args:
|
||||
context: 目标上下文
|
||||
threshold: 相似度阈值
|
||||
|
||||
Returns:
|
||||
相似决策列表
|
||||
"""
|
||||
similar = []
|
||||
|
||||
for decision in self.decisions.values():
|
||||
similarity = self._calculate_similarity(context, decision.context)
|
||||
if similarity >= threshold:
|
||||
similar.append((decision, similarity))
|
||||
|
||||
similar.sort(key=lambda x: x[1], reverse=True)
|
||||
return [d for d, _ in similar]
|
||||
|
||||
def _calculate_similarity(self, ctx1: Dict[str, Any],
|
||||
ctx2: Dict[str, Any]) -> float:
|
||||
"""计算上下文相似度 (简化版本)"""
|
||||
# 简化: 使用键的交集比例
|
||||
keys1 = set(ctx1.keys())
|
||||
keys2 = set(ctx2.keys())
|
||||
intersection = keys1 & keys2
|
||||
union = keys1 | keys2
|
||||
|
||||
if not union:
|
||||
return 0.0
|
||||
|
||||
# 值相似度
|
||||
value_similarity = 0.0
|
||||
count = 0
|
||||
|
||||
for key in intersection:
|
||||
v1 = ctx1.get(key)
|
||||
v2 = ctx2.get(key)
|
||||
if isinstance(v1, (int, float)) and isinstance(v2, (int, float)):
|
||||
# 归一化差异
|
||||
max_val = max(abs(v1), abs(v2), 1)
|
||||
diff = abs(v1 - v2) / max_val
|
||||
value_similarity += (1 - diff)
|
||||
count += 1
|
||||
|
||||
if count > 0:
|
||||
value_similarity /= count
|
||||
|
||||
# 组合相似度
|
||||
key_similarity = len(intersection) / len(union)
|
||||
return 0.3 * key_similarity + 0.7 * value_similarity
|
||||
|
||||
def get_statistics(self) -> Dict[str, Any]:
|
||||
"""获取统计信息"""
|
||||
total = len(self.decisions)
|
||||
|
||||
if total == 0:
|
||||
return {"total_decisions": 0}
|
||||
|
||||
with_feedback = sum(1 for d in self.decisions.values() if d.feedback_list)
|
||||
with_outcome = sum(1 for d in self.decisions.values()
|
||||
if d.actual_outcome is not None)
|
||||
|
||||
avg_feedback = sum(d.get_average_feedback()
|
||||
for d in self.decisions.values()
|
||||
if d.feedback_list) / max(with_feedback, 1)
|
||||
|
||||
return {
|
||||
"total_decisions": total,
|
||||
"decisions_with_feedback": with_feedback,
|
||||
"decisions_with_outcome": with_outcome,
|
||||
"average_feedback_score": avg_feedback
|
||||
}
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# 学习器接口
|
||||
# ============================================================================
|
||||
|
||||
class Learner(ABC):
|
||||
"""学习器抽象基类"""
|
||||
|
||||
def __init__(self, name: str = ""):
|
||||
self.name = name
|
||||
|
||||
@abstractmethod
|
||||
def learn_from_feedback(self, decision: Decision, feedback: Feedback) -> None:
|
||||
"""从反馈中学习"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def learn_from_outcome(self, decision: Decision) -> None:
|
||||
"""从结果中学习"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def get_parameters(self) -> Dict[str, Any]:
|
||||
"""获取当前参数"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def update_parameters(self, params: Dict[str, Any]) -> None:
|
||||
"""更新参数"""
|
||||
pass
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# 权重学习器
|
||||
# ============================================================================
|
||||
|
||||
class WeightLearner(Learner):
|
||||
"""
|
||||
权重学习器
|
||||
|
||||
通过反馈学习多准则决策的权重。
|
||||
"""
|
||||
|
||||
def __init__(self, initial_weights: List[float],
|
||||
learning_rate: float = 0.1,
|
||||
min_weight: float = 0.05,
|
||||
max_weight: float = 0.5):
|
||||
"""
|
||||
初始化权重学习器
|
||||
|
||||
Args:
|
||||
initial_weights: 初始权重列表
|
||||
learning_rate: 学习率
|
||||
min_weight: 最小权重
|
||||
max_weight: 最大权重
|
||||
"""
|
||||
super().__init__("WeightLearner")
|
||||
self.weights = initial_weights.copy()
|
||||
self.learning_rate = learning_rate
|
||||
self.min_weight = min_weight
|
||||
self.max_weight = max_weight
|
||||
self.update_count = 0
|
||||
|
||||
def learn_from_feedback(self, decision: Decision, feedback: Feedback) -> None:
|
||||
"""
|
||||
从反馈中学习权重
|
||||
|
||||
使用梯度下降法调整权重:
|
||||
- 如果反馈为正,增加选中选项的优势准则权重
|
||||
- 如果反馈为负,减少选中选项的优势准则权重
|
||||
"""
|
||||
if not decision.alternatives or decision.selected_alternative >= len(decision.alternatives):
|
||||
return
|
||||
|
||||
selected = decision.alternatives[decision.selected_alternative]
|
||||
|
||||
# 计算调整方向
|
||||
feedback_normalized = (feedback.value - 0.5) * 2 # 转换到 [-1, 1]
|
||||
|
||||
# 获取准则值 (假设存储在criteria字段)
|
||||
criteria_values = selected.get("criteria", [])
|
||||
|
||||
if len(criteria_values) != len(self.weights):
|
||||
return
|
||||
|
||||
# 计算梯度
|
||||
# 简化: 增加高值准则的权重 (如果反馈为正)
|
||||
max_value = max(criteria_values) if criteria_values else 1
|
||||
gradients = []
|
||||
|
||||
for i, value in enumerate(criteria_values):
|
||||
# 归一化值
|
||||
norm_value = value / max_value if max_value > 0 else 0
|
||||
# 梯度: 高值准则应该有更大权重
|
||||
gradient = (norm_value - 0.5) * feedback_normalized
|
||||
gradients.append(gradient)
|
||||
|
||||
# 更新权重
|
||||
for i, gradient in enumerate(gradients):
|
||||
self.weights[i] += self.learning_rate * gradient
|
||||
|
||||
# 归一化权重
|
||||
self._normalize_weights()
|
||||
self.update_count += 1
|
||||
|
||||
def learn_from_outcome(self, decision: Decision) -> None:
|
||||
"""
|
||||
从结果中学习
|
||||
|
||||
如果实际结果好于预期,增加选中策略的权重
|
||||
"""
|
||||
if decision.predicted_outcome is None or decision.actual_outcome is None:
|
||||
return
|
||||
|
||||
# 计算结果误差
|
||||
error = decision.actual_outcome - decision.predicted_outcome
|
||||
|
||||
# 归一化误差
|
||||
error_normalized = math.tanh(error / 100) # 假设100为合理的误差范围
|
||||
|
||||
# 根据误差调整权重
|
||||
feedback = Feedback(
|
||||
feedback_id=f"outcome_{decision.decision_id}",
|
||||
feedback_type=FeedbackType.OUTCOME,
|
||||
source=FeedbackSource.SYSTEM_AUTO,
|
||||
target_decision_id=decision.decision_id,
|
||||
value=0.5 + error_normalized * 0.25 # 转换到合理范围
|
||||
)
|
||||
|
||||
self.learn_from_feedback(decision, feedback)
|
||||
|
||||
def _normalize_weights(self) -> None:
|
||||
"""归一化权重并限制范围"""
|
||||
# 限制范围
|
||||
self.weights = [
|
||||
max(self.min_weight, min(self.max_weight, w))
|
||||
for w in self.weights
|
||||
]
|
||||
|
||||
# 归一化使和为1
|
||||
total = sum(self.weights)
|
||||
self.weights = [w / total for w in self.weights]
|
||||
|
||||
def get_parameters(self) -> Dict[str, Any]:
|
||||
return {
|
||||
"weights": self.weights,
|
||||
"learning_rate": self.learning_rate,
|
||||
"update_count": self.update_count
|
||||
}
|
||||
|
||||
def update_parameters(self, params: Dict[str, Any]) -> None:
|
||||
if "weights" in params:
|
||||
self.weights = params["weights"].copy()
|
||||
if "learning_rate" in params:
|
||||
self.learning_rate = params["learning_rate"]
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# 自适应决策系统
|
||||
# ============================================================================
|
||||
|
||||
class AdaptiveDecisionSystem:
|
||||
"""
|
||||
自适应决策系统
|
||||
|
||||
结合反馈和学习的智能决策系统。
|
||||
"""
|
||||
|
||||
def __init__(self, criteria: List[str],
|
||||
initial_weights: List[float] = None):
|
||||
"""
|
||||
初始化自适应决策系统
|
||||
|
||||
Args:
|
||||
criteria: 决策准则列表
|
||||
initial_weights: 初始权重
|
||||
"""
|
||||
self.criteria = criteria
|
||||
self.n_criteria = len(criteria)
|
||||
|
||||
if initial_weights is None:
|
||||
# 均匀初始权重
|
||||
initial_weights = [1.0 / self.n_criteria] * self.n_criteria
|
||||
|
||||
# 归一化权重
|
||||
total = sum(initial_weights)
|
||||
self.weights = [w / total for w in initial_weights]
|
||||
|
||||
# 创建学习器
|
||||
self.learner = WeightLearner(self.weights)
|
||||
|
||||
# 创建经验存储
|
||||
self.experience_store = ExperienceStore()
|
||||
|
||||
# 决策计数器
|
||||
self.decision_counter = 0
|
||||
|
||||
print(f"[自适应决策系统] 初始化完成")
|
||||
print(f" 准则: {self.criteria}")
|
||||
print(f" 初始权重: {[f'{w:.3f}' for w in self.weights]}")
|
||||
|
||||
def make_decision(self, alternatives: List[Dict[str, float]],
|
||||
context: Dict[str, Any] = None) -> Tuple[int, Dict[str, Any]]:
|
||||
"""
|
||||
做出决策
|
||||
|
||||
Args:
|
||||
alternatives: 备选方案列表,每个方案包含各准则的值
|
||||
context: 决策上下文
|
||||
|
||||
Returns:
|
||||
(选中方案索引, 决策信息)
|
||||
"""
|
||||
if not alternatives:
|
||||
raise ValueError("没有备选方案")
|
||||
|
||||
# 计算每个方案的综合得分
|
||||
scores = []
|
||||
for alt in alternatives:
|
||||
score = self._calculate_score(alt)
|
||||
scores.append(score)
|
||||
|
||||
# 选择得分最高的
|
||||
selected_idx = max(range(len(scores)), key=lambda i: scores[i])
|
||||
|
||||
# 创建决策记录
|
||||
decision_id = f"decision_{self.decision_counter}"
|
||||
self.decision_counter += 1
|
||||
|
||||
decision = Decision(
|
||||
decision_id=decision_id,
|
||||
context=context or {},
|
||||
alternatives=[
|
||||
{"criteria": alt, "score": score}
|
||||
for alt, score in zip(alternatives, scores)
|
||||
],
|
||||
selected_alternative=selected_idx,
|
||||
model_version="1.0",
|
||||
parameters=self.get_parameters()
|
||||
)
|
||||
|
||||
decision_info = {
|
||||
"decision_id": decision_id,
|
||||
"selected_index": selected_idx,
|
||||
"selected_alternative": alternatives[selected_idx],
|
||||
"score": scores[selected_idx],
|
||||
"all_scores": scores,
|
||||
"weights": self.weights.copy()
|
||||
}
|
||||
|
||||
# 存储决策
|
||||
self.experience_store.add_decision(decision)
|
||||
|
||||
return selected_idx, decision_info
|
||||
|
||||
def _calculate_score(self, alternative: Dict[str, float]) -> float:
|
||||
"""
|
||||
计算方案的综合得分
|
||||
|
||||
使用加权求和模型
|
||||
"""
|
||||
score = 0.0
|
||||
for i, criterion in enumerate(self.criteria):
|
||||
if criterion in alternative:
|
||||
score += self.weights[i] * alternative[criterion]
|
||||
return score
|
||||
|
||||
def provide_feedback(self, decision_id: str, feedback_value: float,
|
||||
feedback_type: FeedbackType = FeedbackType.EXPLICIT,
|
||||
source: FeedbackSource = FeedbackSource.HUMAN_EXPERT,
|
||||
content: str = None) -> None:
|
||||
"""
|
||||
为决策提供反馈
|
||||
|
||||
Args:
|
||||
decision_id: 决策ID
|
||||
feedback_value: 反馈值 (通常在0-1范围)
|
||||
feedback_type: 反馈类型
|
||||
source: 反馈来源
|
||||
content: 反馈内容
|
||||
"""
|
||||
decision = self.experience_store.get_decision(decision_id)
|
||||
if not decision:
|
||||
print(f"警告: 找不到决策 {decision_id}")
|
||||
return
|
||||
|
||||
# 创建反馈
|
||||
feedback = Feedback(
|
||||
feedback_id=f"fb_{decision_id}_{len(decision.feedback_list)}",
|
||||
feedback_type=feedback_type,
|
||||
source=source,
|
||||
target_decision_id=decision_id,
|
||||
value=feedback_value,
|
||||
content=content
|
||||
)
|
||||
|
||||
# 添加到决策记录
|
||||
decision.add_feedback(feedback)
|
||||
|
||||
# 从反馈中学习
|
||||
self.learner.learn_from_feedback(decision, feedback)
|
||||
|
||||
# 更新系统权重
|
||||
self.weights = self.learner.weights.copy()
|
||||
|
||||
print(f"[反馈] 收到反馈: {feedback_value:.2f}")
|
||||
print(f"[学习] 更新后权重: {[f'{w:.3f}' for w in self.weights]}")
|
||||
|
||||
def report_outcome(self, decision_id: str, actual_outcome: float) -> None:
|
||||
"""
|
||||
报告实际结果
|
||||
|
||||
Args:
|
||||
decision_id: 决策ID
|
||||
actual_outcome: 实际结果值
|
||||
"""
|
||||
decision = self.experience_store.get_decision(decision_id)
|
||||
if not decision:
|
||||
print(f"警告: 找不到决策 {decision_id}")
|
||||
return
|
||||
|
||||
decision.actual_outcome = actual_outcome
|
||||
|
||||
# 从结果中学习
|
||||
self.learner.learn_from_outcome(decision)
|
||||
|
||||
# 更新系统权重
|
||||
self.weights = self.learner.weights.copy()
|
||||
|
||||
print(f"[结果] 决策 {decision_id} 实际结果: {actual_outcome:.2f}")
|
||||
|
||||
def get_parameters(self) -> Dict[str, Any]:
|
||||
"""获取当前系统参数"""
|
||||
return {
|
||||
"weights": self.weights.copy(),
|
||||
"criteria": self.criteria.copy()
|
||||
}
|
||||
|
||||
def set_parameters(self, params: Dict[str, Any]) -> None:
|
||||
"""设置系统参数"""
|
||||
if "weights" in params:
|
||||
self.weights = params["weights"].copy()
|
||||
|
||||
def get_performance_summary(self) -> Dict[str, Any]:
|
||||
"""获取性能摘要"""
|
||||
stats = self.experience_store.get_statistics()
|
||||
|
||||
# 计算平均反馈分数
|
||||
decisions = list(self.experience_store.decisions.values())
|
||||
if decisions:
|
||||
avg_feedback = sum(d.get_average_feedback()
|
||||
for d in decisions if d.feedback_list)
|
||||
feedback_count = sum(1 for d in decisions if d.feedback_list)
|
||||
avg_feedback = avg_feedback / feedback_count if feedback_count > 0 else None
|
||||
else:
|
||||
avg_feedback = None
|
||||
|
||||
# 计算平均后悔值
|
||||
regrets = [d.calculate_regret() for d in decisions
|
||||
if d.actual_outcome is not None]
|
||||
avg_regret = sum(regrets) / len(regrets) if regrets else None
|
||||
|
||||
return {
|
||||
"total_decisions": stats["total_decisions"],
|
||||
"decisions_with_feedback": stats["decisions_with_feedback"],
|
||||
"average_feedback_score": avg_feedback,
|
||||
"average_regret": avg_regret,
|
||||
"current_weights": self.weights.copy()
|
||||
}
|
||||
|
||||
def print_summary(self) -> None:
|
||||
"""打印系统摘要"""
|
||||
print("\n" + "="*60)
|
||||
print("自适应决策系统摘要")
|
||||
print("="*60)
|
||||
|
||||
print("\n决策准则:")
|
||||
for i, criterion in enumerate(self.criteria):
|
||||
print(f" {i+1}. {criterion:15s} 权重: {self.weights[i]:.4f}")
|
||||
|
||||
perf = self.get_performance_summary()
|
||||
print(f"\n性能统计:")
|
||||
print(f" 总决策数: {perf['total_decisions']}")
|
||||
print(f" 有反馈的决策: {perf['decisions_with_feedback']}")
|
||||
|
||||
if perf['average_feedback_score'] is not None:
|
||||
print(f" 平均反馈分数: {perf['average_feedback_score']:.3f}")
|
||||
|
||||
if perf['average_regret'] is not None:
|
||||
print(f" 平均后悔值: {perf['average_regret']:.3f}")
|
||||
|
||||
print("="*60 + "\n")
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# 主程序
|
||||
# ============================================================================
|
||||
|
||||
def main():
|
||||
"""主程序 - 演示反馈与学习的使用"""
|
||||
|
||||
print("="*70)
|
||||
print("反馈与学习示例演示")
|
||||
print("="*70)
|
||||
|
||||
# ========================================================================
|
||||
# 1. 创建自适应决策系统
|
||||
# ========================================================================
|
||||
print("\n[步骤 1] 创建自适应决策系统")
|
||||
print("-" * 50)
|
||||
|
||||
criteria = ["经济效益", "环境影响", "社会影响", "技术可行性"]
|
||||
initial_weights = [0.4, 0.3, 0.2, 0.1] # 偏重经济效益
|
||||
|
||||
system = AdaptiveDecisionSystem(criteria, initial_weights)
|
||||
system.print_summary()
|
||||
|
||||
# ========================================================================
|
||||
# 2. 第一次决策
|
||||
# ========================================================================
|
||||
print("\n[步骤 2] 第一次决策 - 工厂选址")
|
||||
print("-" * 50)
|
||||
|
||||
alternatives = [
|
||||
{"经济效益": 0.8, "环境影响": 0.3, "社会影响": 0.5, "技术可行性": 0.9}, # 位置A
|
||||
{"经济效益": 0.5, "环境影响": 0.7, "社会影响": 0.8, "技术可行性": 0.6}, # 位置B
|
||||
{"经济效益": 0.6, "环境影响": 0.9, "社会影响": 0.6, "技术可行性": 0.7}, # 位置C
|
||||
]
|
||||
|
||||
selected_idx, decision_info = system.make_decision(
|
||||
alternatives,
|
||||
context={"task": "工厂选址", "region": "华东地区"}
|
||||
)
|
||||
|
||||
print(f"\n决策结果:")
|
||||
print(f" 选中方案: 位置{chr(65 + selected_idx)}")
|
||||
print(f" 得分: {decision_info['score']:.3f}")
|
||||
print(f" 各方案得分: {[f'{s:.2f}' for s in decision_info['all_scores']]}")
|
||||
|
||||
decision_id_1 = decision_info['decision_id']
|
||||
|
||||
# ========================================================================
|
||||
# 3. 提供反馈
|
||||
# ========================================================================
|
||||
print("\n[步骤 3] 收集反馈")
|
||||
print("-" * 50)
|
||||
|
||||
# 专家反馈: 环境影响被低估了
|
||||
print("\n3.1 专家反馈: 环境影响应该更重视")
|
||||
system.provide_feedback(
|
||||
decision_id_1,
|
||||
feedback_value=0.6, # 中等偏下的评分
|
||||
feedback_type=FeedbackType.EXPLICIT,
|
||||
source=FeedbackSource.HUMAN_EXPERT,
|
||||
content="环境影响权重太低,应提高"
|
||||
)
|
||||
|
||||
# 更多反馈强化
|
||||
system.provide_feedback(
|
||||
decision_id_1,
|
||||
feedback_value=0.5,
|
||||
feedback_type=FeedbackType.CORRECTION,
|
||||
source=FeedbackSource.HUMAN_EXPERT
|
||||
)
|
||||
|
||||
# ========================================================================
|
||||
# 4. 第二次决策 (学习后的权重)
|
||||
# ========================================================================
|
||||
print("\n[步骤 4] 第二次决策 - 另一个选址")
|
||||
print("-" * 50)
|
||||
|
||||
alternatives_2 = [
|
||||
{"经济效益": 0.7, "环境影响": 0.4, "社会影响": 0.6, "技术可行性": 0.8}, # 位置D
|
||||
{"经济效益": 0.4, "环境影响": 0.9, "社会影响": 0.7, "技术可行性": 0.7}, # 位置E
|
||||
]
|
||||
|
||||
selected_idx_2, decision_info_2 = system.make_decision(
|
||||
alternatives_2,
|
||||
context={"task": "工厂选址", "region": "华南地区"}
|
||||
)
|
||||
|
||||
print(f"\n决策结果:")
|
||||
print(f" 选中方案: 位置{chr(68 + selected_idx_2)}")
|
||||
print(f" 得分: {decision_info_2['score']:.3f}")
|
||||
print(f" 当前权重: {[f'{w:.3f}' for w in system.weights]}")
|
||||
|
||||
decision_id_2 = decision_info_2['decision_id']
|
||||
|
||||
# ========================================================================
|
||||
# 5. 报告结果并学习
|
||||
# ========================================================================
|
||||
print("\n[步骤 5] 报告实际结果")
|
||||
print("-" * 50)
|
||||
|
||||
# 第一个决策的结果
|
||||
print(f"\n5.1 决策 {decision_id_1} 的实际结果")
|
||||
system.report_outcome(decision_id_1, actual_outcome=75) # 预测可能不同
|
||||
|
||||
# 第二个决策的结果
|
||||
print(f"\n5.2 决策 {decision_id_2} 的实际结果")
|
||||
system.report_outcome(decision_id_2, actual_outcome=85)
|
||||
|
||||
# ========================================================================
|
||||
# 6. 多轮学习
|
||||
# ========================================================================
|
||||
print("\n[步骤 6] 多轮学习")
|
||||
print("-" * 50)
|
||||
|
||||
# 模拟多次决策和反馈
|
||||
for i in range(10):
|
||||
alt1 = {
|
||||
"经济效益": random.uniform(0.5, 0.9),
|
||||
"环境影响": random.uniform(0.3, 0.7),
|
||||
"社会影响": random.uniform(0.4, 0.8),
|
||||
"技术可行性": random.uniform(0.5, 0.9)
|
||||
}
|
||||
alt2 = {
|
||||
"经济效益": random.uniform(0.3, 0.7),
|
||||
"环境影响": random.uniform(0.6, 0.95),
|
||||
"社会影响": random.uniform(0.5, 0.9),
|
||||
"技术可行性": random.uniform(0.4, 0.8)
|
||||
}
|
||||
|
||||
idx, info = system.make_decision([alt1, alt2])
|
||||
did = info['decision_id']
|
||||
|
||||
# 模拟反馈 (随着环境意识增强,对高环境影响的方案给低分)
|
||||
selected_env_impact = ([alt1, alt2][idx])["环境影响"]
|
||||
if selected_env_impact < 0.6:
|
||||
feedback_val = random.uniform(0.3, 0.5) # 低分
|
||||
else:
|
||||
feedback_val = random.uniform(0.7, 0.95) # 高分
|
||||
|
||||
system.provide_feedback(did, feedback_val)
|
||||
system.report_outcome(did, actual_outcome=random.uniform(60, 90))
|
||||
|
||||
print("\n多轮学习后:")
|
||||
system.print_summary()
|
||||
|
||||
# ========================================================================
|
||||
# 7. 权重变化分析
|
||||
# ========================================================================
|
||||
print("\n[步骤 7] 权重变化分析")
|
||||
print("-" * 50)
|
||||
|
||||
final_weights = system.weights
|
||||
print(f"\n初始权重: {[f'{w:.3f}' for w in initial_weights]}")
|
||||
print(f"最终权重: {[f'{w:.3f}' for w in final_weights]}")
|
||||
|
||||
print("\n权重变化:")
|
||||
for i, criterion in enumerate(criteria):
|
||||
change = final_weights[i] - initial_weights[i]
|
||||
arrow = "↑" if change > 0 else "↓" if change < 0 else "→"
|
||||
print(f" {criterion:15s}: {initial_weights[i]:.3f} → {final_weights[i]:.3f} "
|
||||
f"({arrow}{abs(change):.3f})")
|
||||
|
||||
# ========================================================================
|
||||
# 8. 经验检索
|
||||
# ========================================================================
|
||||
print("\n[步骤 8] 相似决策检索")
|
||||
print("-" * 50)
|
||||
|
||||
similar_decisions = system.experience_store.find_similar_decisions(
|
||||
{"task": "工厂选址", "region": "华东地区"},
|
||||
threshold=0.3
|
||||
)
|
||||
|
||||
print(f"\n找到 {len(similar_decisions)} 个相似决策:")
|
||||
for i, decision in enumerate(similar_decisions[:3], 1):
|
||||
print(f" {i}. {decision.decision_id} - "
|
||||
f"选中: {decision.selected_alternative}, "
|
||||
f"反馈: {decision.get_average_feedback():.2f}")
|
||||
|
||||
print("\n" + "="*70)
|
||||
print("演示完成!")
|
||||
print("="*70)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user