lawkit_core/laws/pareto/
analysis.rs1use super::result::ParetoResult;
2use crate::error::Result;
3
4pub fn analyze_pareto_distribution(numbers: &[f64], dataset_name: &str) -> Result<ParetoResult> {
6 ParetoResult::new(dataset_name.to_string(), numbers)
7}
8
9pub fn analyze_business_pareto(
11 numbers: &[f64],
12 dataset_name: &str,
13) -> Result<BusinessParetoAnalysis> {
14 let pareto_result = analyze_pareto_distribution(numbers, dataset_name)?;
15
16 let business_insights = generate_business_insights(&pareto_result);
17 let action_recommendations = generate_action_recommendations(&pareto_result);
18
19 Ok(BusinessParetoAnalysis {
20 pareto_result,
21 business_insights,
22 action_recommendations,
23 })
24}
25
26fn generate_business_insights(pareto_result: &ParetoResult) -> Vec<BusinessInsight> {
28 let mut insights = Vec::new();
29
30 if pareto_result.pareto_ratio > 0.8 && pareto_result.pareto_ratio < 1.2 {
32 insights.push(BusinessInsight {
33 category: "Distribution".to_string(),
34 message: "データは典型的なパレート分布を示しています".to_string(),
35 impact_level: "High".to_string(),
36 });
37 }
38
39 if pareto_result.concentration_index > 0.6 {
41 insights.push(BusinessInsight {
42 category: "Concentration".to_string(),
43 message: "高度な集中が見られます - 少数の要素が大きな影響を持っています".to_string(),
44 impact_level: "Critical".to_string(),
45 });
46 }
47
48 insights
49}
50
51fn generate_action_recommendations(pareto_result: &ParetoResult) -> Vec<ActionRecommendation> {
53 let mut recommendations = Vec::new();
54
55 if pareto_result.top_20_percent_share > 80.0 {
57 recommendations.push(ActionRecommendation {
58 priority: "High".to_string(),
59 action: "上位20%の要素に集中的にリソースを配分してください".to_string(),
60 expected_impact: "効率的な成果向上が期待できます".to_string(),
61 });
62 }
63
64 recommendations
65}
66
67#[derive(Debug, Clone)]
69pub struct BusinessInsight {
70 pub category: String,
71 pub message: String,
72 pub impact_level: String,
73}
74
75#[derive(Debug, Clone)]
77pub struct ActionRecommendation {
78 pub priority: String,
79 pub action: String,
80 pub expected_impact: String,
81}
82
83#[derive(Debug, Clone)]
85pub struct BusinessParetoAnalysis {
86 pub pareto_result: ParetoResult,
87 pub business_insights: Vec<BusinessInsight>,
88 pub action_recommendations: Vec<ActionRecommendation>,
89}
90
91#[cfg(test)]
92mod tests {
93 use super::*;
94
95 #[test]
96 fn test_perfect_pareto_distribution() {
97 let numbers = vec![
99 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,
100 ];
101 let result = analyze_pareto_distribution(&numbers, "test").unwrap();
102
103 assert_eq!(result.numbers_analyzed, 15);
104 assert!(result.top_20_percent_share > 50.0); }
106
107 #[test]
108 fn test_uniform_distribution() {
109 let numbers = vec![10.0; 20]; let result = analyze_pareto_distribution(&numbers, "uniform").unwrap();
112
113 assert_eq!(result.numbers_analyzed, 20);
114 assert!((result.top_20_percent_share - 20.0).abs() < 1.0); assert!(matches!(
116 result.risk_level,
117 crate::common::risk::RiskLevel::Critical
118 ));
119 }
120
121 #[test]
122 fn test_business_analysis() {
123 let numbers = vec![
124 1000.0, 800.0, 600.0, 400.0, 200.0, 50.0, 40.0, 30.0, 20.0, 10.0,
125 ];
126 let result = analyze_pareto_distribution(&numbers, "sales").unwrap();
127
128 assert_eq!(result.dataset_name, "sales");
129 assert_eq!(result.numbers_analyzed, 10);
130 }
131
132 #[test]
133 fn test_insufficient_data() {
134 let numbers = vec![1.0, 2.0]; let result = analyze_pareto_distribution(&numbers, "test");
136
137 assert!(result.is_err());
138 }
139}