PERI-AI-dev / src /peri /value_chains.py
Nelly-43's picture
Update src/peri/value_chains.py
6388917 verified
Raw History Blame Contribute Delete
5.31 kB
import numpy as np
import pandas as pd
from typing import Iterable, Dict, List
from src.llm import generate
from src.retriever import retrieve
from src.prompts import build_vc_analyzer_prompt
from src.query_engine import _parse_vc_analyzer_result
from .investments import normalize_scores
def score_value_chains(vc_dist_ref:pd.DataFrame,
val_chain_col:str,
ruling_opp_swing_share:Iterable):
vc_dist_ref["score"] = 0
vc_dist_ref.loc[(vc_dist_ref[val_chain_col].isin(ruling_opp_swing_share))&(vc_dist_ref['category']=="NRM safe")&(vc_dist_ref['share']>0.5), "score"] = 4
vc_dist_ref.loc[~vc_dist_ref[val_chain_col].isin(ruling_opp_swing_share), 'score'] = 3
vc_dist_ref.loc[(vc_dist_ref[val_chain_col].isin(ruling_opp_swing_share))&(vc_dist_ref['category']=="Swing")&(vc_dist_ref['share']>0.5), "score"] = 2
vc_dist_ref.loc[(vc_dist_ref[val_chain_col].isin(ruling_opp_swing_share))&(vc_dist_ref['category']=="Opp. safe")&(vc_dist_ref['share']>0.5), "score"] = 1
return vc_dist_ref[vc_dist_ref['score']>0]
def categorize_vc_production(vc_dist_ref:pd.DataFrame,
val_chain_col:str):
vc_dist_ref = vc_dist_ref[~vc_dist_ref['category'].str.lower().str.contains("plurality")].reset_index(drop=True)
ros_vc = vc_dist_ref.groupby([val_chain_col]).apply(lambda x: x[x["share"]>0.5]).reset_index()[val_chain_col].unique()
score_df = score_value_chains(vc_dist_ref, val_chain_col, ros_vc)
score_df = score_df.groupby(['score'], as_index=False)[val_chain_col].unique().explode(val_chain_col).reset_index(drop=True)
score_df = score_df[[val_chain_col, 'score']]
return normalize_scores(score_df)
def analyze_committment_to_vc(cfg:Dict, value_chain:str):
search_query = f"{value_chain} production in uganda"
retrieval_result = retrieve(search_query, cfg, route="both")
context = retrieval_result.get("context", "")
prompt = build_vc_analyzer_prompt(cfg.get("policy_docs", []), context, value_chain, cfg["chatbot"].get("domain"))
raw = generate(
"",
prompt,
cfg,
max_tokens=4096,
)
return _parse_vc_analyzer_result(raw)
def analyze_budget_trend(data:pd.DataFrame):
df = data.copy()
df["trend"] = (df["financial_commitment.budget_end_value"].replace("", np.nan).astype(float)-df["financial_commitment.budget_start_value"].replace("", np.nan).astype(float))/df["financial_commitment.budget_start_value"].replace("", np.nan).astype(float)
conditions = [
(df["trend"] <= -0.5),
(df["trend"] > -0.5) & (df["trend"] <= -0.1),
(df["trend"] > -0.1) & (df["trend"] <= 0.1),
(df["trend"] > 0.1) & (df["trend"] <= 0.5),
(df["trend"] > 0.5),
]
# 2. Define the corresponding choices/mapped values
choices = range(1, len(conditions)+1, 1)
# 3. Apply numpy.select with a default fallback value
df["trend"] = np.select(conditions, choices, default=np.nan)
return df, conditions
def get_scores(data:pd.DataFrame, conditions:List):
df = data.copy()
results = df[["value_chain", "trend"]].reset_index(drop=True)
strat_imp_cols = ["strategic_commitment.development_plan.value", "strategic_commitment.agricultural_strategy.value",
"strategic_commitment.flagship_project.value", "strategic_commitment.standalone_vc_strategy.value"]
results["strategic_importance"] = df[strat_imp_cols].mean(axis=1).reset_index(drop=True)
results["depth"] = df["strategic_commitment.documents_discussing_value_chain"]-df[strat_imp_cols].sum(axis=1).reset_index(drop=True)
results["breadth"] = (df["strategic_commitment.documents_discussing_value_chain"]/df["strategic_commitment.documents_examined"]).reset_index(drop=True)
results["metric"] = (0.5*results["breadth"])+(0.5*results["strategic_importance"]).reset_index(drop=True)
results["coverage"] = (results["depth"]/(df["strategic_commitment.documents_examined"]-df[strat_imp_cols].sum(axis=1))).reset_index(drop=True)
results["strategic_importance_score"] = (0.8*df[strat_imp_cols].sum(axis=1))+(0.2*results["breadth"]).reset_index(drop=True)
results["institutional_committment_score"] = df[[c for c in df.columns if "value" in c and "institutional_commitment" in c]].sum(axis=1)
return normalize_committment_scores(results, conditions)
def normalize_committment_scores(results:pd.DataFrame, conditions:List):
results["trend_normalized"] = (results["trend"]-min(1, results["trend"].min()))/max(len(conditions), results["trend"].max())
results["strategic_importance_normalized"] = results["strategic_importance_score"]/3.4
results["institutional_commitment_normalized"] = results["institutional_committment_score"]/3
return results
def analyze_vc_committment(llm_outputs:Dict):
print(llm_outputs)
c2vc_df = pd.json_normalize(llm_outputs.values())
c2vc_df.insert(0, "value_chain", llm_outputs.keys())
c2vc_df = c2vc_df.replace("YES", 1)
c2vc_df = c2vc_df.replace("NOT_FOUND", 0)
c2vc_df = c2vc_df.replace("NO", 0)
trend, conditions = analyze_budget_trend(c2vc_df)
return get_scores(trend, conditions)