use super::result::ParetoResult;
use crate::error::Result;
pub fn analyze_pareto_distribution(numbers: &[f64], dataset_name: &str) -> Result<ParetoResult> {
ParetoResult::new(dataset_name.to_string(), numbers)
}
pub fn analyze_business_pareto(
numbers: &[f64],
dataset_name: &str,
) -> Result<BusinessParetoAnalysis> {
let pareto_result = analyze_pareto_distribution(numbers, dataset_name)?;
let business_insights = generate_business_insights(&pareto_result);
let action_recommendations = generate_action_recommendations(&pareto_result);
Ok(BusinessParetoAnalysis {
pareto_result,
business_insights,
action_recommendations,
})
}
fn generate_business_insights(pareto_result: &ParetoResult) -> Vec<BusinessInsight> {
let mut insights = Vec::new();
if pareto_result.pareto_ratio > 0.8 && pareto_result.pareto_ratio < 1.2 {
insights.push(BusinessInsight {
category: "Distribution".to_string(),
message: "データは典型的なパレート分布を示しています".to_string(),
impact_level: "High".to_string(),
});
}
if pareto_result.concentration_index > 0.6 {
insights.push(BusinessInsight {
category: "Concentration".to_string(),
message: "高度な集中が見られます - 少数の要素が大きな影響を持っています".to_string(),
impact_level: "Critical".to_string(),
});
}
insights
}
fn generate_action_recommendations(pareto_result: &ParetoResult) -> Vec<ActionRecommendation> {
let mut recommendations = Vec::new();
if pareto_result.top_20_percent_share > 80.0 {
recommendations.push(ActionRecommendation {
priority: "High".to_string(),
action: "上位20%の要素に集中的にリソースを配分してください".to_string(),
expected_impact: "効率的な成果向上が期待できます".to_string(),
});
}
recommendations
}
#[derive(Debug, Clone)]
pub struct BusinessInsight {
pub category: String,
pub message: String,
pub impact_level: String,
}
#[derive(Debug, Clone)]
pub struct ActionRecommendation {
pub priority: String,
pub action: String,
pub expected_impact: String,
}
#[derive(Debug, Clone)]
pub struct BusinessParetoAnalysis {
pub pareto_result: ParetoResult,
pub business_insights: Vec<BusinessInsight>,
pub action_recommendations: Vec<ActionRecommendation>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_perfect_pareto_distribution() {
let numbers = vec![
100.0, 90.0, 80.0, 70.0, 60.0, 10.0, 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0,
];
let result = analyze_pareto_distribution(&numbers, "test").unwrap();
assert_eq!(result.numbers_analyzed, 15);
assert!(result.top_20_percent_share > 50.0); }
#[test]
fn test_uniform_distribution() {
let numbers = vec![10.0; 20]; let result = analyze_pareto_distribution(&numbers, "uniform").unwrap();
assert_eq!(result.numbers_analyzed, 20);
assert!((result.top_20_percent_share - 20.0).abs() < 1.0); assert!(matches!(
result.risk_level,
crate::common::risk::RiskLevel::Critical
));
}
#[test]
fn test_business_analysis() {
let numbers = vec![
1000.0, 800.0, 600.0, 400.0, 200.0, 50.0, 40.0, 30.0, 20.0, 10.0,
];
let result = analyze_pareto_distribution(&numbers, "sales").unwrap();
assert_eq!(result.dataset_name, "sales");
assert_eq!(result.numbers_analyzed, 10);
}
#[test]
fn test_insufficient_data() {
let numbers = vec![1.0, 2.0]; let result = analyze_pareto_distribution(&numbers, "test");
assert!(result.is_err());
}
}