零售產業面臨日益激烈的市場競爭,傳統的經驗導向決策模式已無法滿足快速變化的商業環境需求。資料科學與商業智慧技術的成熟,為企業提供了更精確的績效評估與策略最佳化工具。透過系統化的資料分析方法,管理者能夠深入理解營運現況,識別影響績效的關鍵因素,並制定具有實證基礎的改善策略。

商店績效評估需要整合多個維度的指標,包含財務表現、客戶體驗與營運效率。收入增長率反映企業的市場競爭力與業務擴張能力,客戶滿意度評分揭示服務品質與品牌忠誠度,產能指標則衡量資源利用效率與營運成本控制。這些指標並非獨立運作,而是相互影響形成複雜的績效網絡。理解指標間的關聯性與因果關係,是制定有效管理策略的關鍵。

本文將運用 Python 資料分析技術,對多家商店橫跨三年的營運資料進行深度分析。透過探索性資料分析發現資料特徵與分佈模式,運用統計方法檢驗假設並量化關係強度,最後透過視覺化技術呈現分析結果,提供直觀的商業洞察。整個分析流程遵循嚴謹的資料科學方法論,確保結論的可靠性與實務應用價值。

資料架構設計與前置處理流程

資料品質是分析準確性的基石。在進行任何分析之前,必須建立完整的資料處理流程,包含資料載入、格式驗證、缺失值處理、異常值偵測與資料轉換。這個階段看似基礎,卻直接影響後續分析的可信度。不當的資料處理可能導致誤導性的結論,進而影響商業決策的品質。

本研究的資料集涵蓋五十四家商店橫跨三年的營運記錄,每筆記錄包含商店識別碼、年份、收入增長率、客戶滿意度評分與產能指標。這些欄位經過精心設計,能夠全面反映商店的營運狀況。商店識別碼採用連續編號,方便追蹤與比對;年份欄位記錄資料時間點,支援趨勢分析;收入增長率以小數形式呈現,便於數學運算;客戶滿意度採用百分制評分,直觀反映服務品質;產能指標使用整數量化營運效率。

資料載入過程需要特別注意編碼問題與資料型別轉換。Python Pandas 函式庫提供強大的資料處理能力,能夠自動識別資料型別並進行適當轉換。然而,對於特定業務邏輯的資料,仍需手動驗證與調整。例如,收入增長率應該是浮點數而非整數,客戶滿意度評分應該在合理範圍內,產能指標不應出現負值。這些業務規則的驗證,確保資料的邏輯一致性。

import pandas as pd
import numpy as np
from typing import Dict, List, Tuple
import warnings
warnings.filterwarnings('ignore')

class StoreDataProcessor:
    """
    商店績效資料處理系統
    負責資料載入、清理、驗證與轉換
    """
    
    def __init__(self):
        """
        初始化資料處理器
        設定資料驗證規則與處理參數
        """
        # 定義資料欄位與預期型別
        self.column_types = {
            '商店ID': int,
            '年份': int,
            '收入增長率': float,
            '客戶滿意度': float,
            '產能指標': int
        }
        
        # 定義資料範圍限制
        self.value_ranges = {
            '年份': (2020, 2025),
            '收入增長率': (-1.0, 2.0),  # 允許負增長與超過100%的增長
            '客戶滿意度': (0.0, 100.0),
            '產能指標': (0, 10)
        }
        
        # 儲存處理後的資料
        self.df = None
        
        # 記錄資料品質問題
        self.quality_issues = []
    
    def load_data(self, data_dict: Dict[str, List]) -> pd.DataFrame:
        """
        載入並初步處理資料
        
        參數:
            data_dict: 包含各欄位資料的字典
            
        回傳:
            處理後的 DataFrame
        """
        # 建立 DataFrame
        self.df = pd.DataFrame(data_dict)
        
        print(f"成功載入 {len(self.df)} 筆資料")
        print(f"資料欄位: {list(self.df.columns)}")
        
        return self.df
    
    def validate_data_types(self) -> bool:
        """
        驗證資料型別是否符合預期
        
        回傳:
            驗證是否通過
        """
        validation_passed = True
        
        for column, expected_type in self.column_types.items():
            if column in self.df.columns:
                # 檢查資料型別
                actual_type = self.df[column].dtype
                
                # 嘗試轉換型別
                try:
                    if expected_type == int:
                        self.df[column] = self.df[column].astype(int)
                    elif expected_type == float:
                        self.df[column] = self.df[column].astype(float)
                    
                    print(f"✓ {column}: 型別驗證通過 ({expected_type.__name__})")
                    
                except Exception as e:
                    self.quality_issues.append(
                        f"欄位 {column} 無法轉換為 {expected_type.__name__}: {str(e)}"
                    )
                    validation_passed = False
                    print(f"✗ {column}: 型別驗證失敗")
        
        return validation_passed
    
    def validate_data_ranges(self) -> bool:
        """
        驗證資料值是否在合理範圍內
        
        回傳:
            驗證是否通過
        """
        validation_passed = True
        
        for column, (min_val, max_val) in self.value_ranges.items():
            if column in self.df.columns:
                # 檢查是否有超出範圍的值
                out_of_range = self.df[
                    (self.df[column] < min_val) | (self.df[column] > max_val)
                ]
                
                if len(out_of_range) > 0:
                    self.quality_issues.append(
                        f"欄位 {column}{len(out_of_range)} 筆資料超出範圍 "
                        f"[{min_val}, {max_val}]"
                    )
                    validation_passed = False
                    print(f"✗ {column}: 發現 {len(out_of_range)} 筆異常值")
                else:
                    print(f"✓ {column}: 數值範圍驗證通過")
        
        return validation_passed
    
    def check_missing_values(self) -> Dict[str, int]:
        """
        檢查缺失值情況
        
        回傳:
            各欄位的缺失值數量
        """
        missing_counts = self.df.isnull().sum()
        
        print("\n缺失值統計:")
        print("-" * 50)
        
        for column, count in missing_counts.items():
            if count > 0:
                percentage = (count / len(self.df)) * 100
                print(f"{column}: {count} 筆 ({percentage:.2f}%)")
                self.quality_issues.append(
                    f"欄位 {column}{count} 筆缺失值"
                )
            else:
                print(f"{column}: 無缺失值")
        
        return missing_counts.to_dict()
    
    def handle_missing_values(self, strategy: str = 'mean') -> pd.DataFrame:
        """
        處理缺失值
        
        參數:
            strategy: 處理策略 ('mean', 'median', 'mode', 'drop')
            
        回傳:
            處理後的 DataFrame
        """
        if strategy == 'mean':
            # 使用平均值填補數值型欄位
            numeric_columns = self.df.select_dtypes(include=[np.number]).columns
            self.df[numeric_columns] = self.df[numeric_columns].fillna(
                self.df[numeric_columns].mean()
            )
            print(f"使用平均值填補缺失值")
            
        elif strategy == 'median':
            # 使用中位數填補
            numeric_columns = self.df.select_dtypes(include=[np.number]).columns
            self.df[numeric_columns] = self.df[numeric_columns].fillna(
                self.df[numeric_columns].median()
            )
            print(f"使用中位數填補缺失值")
            
        elif strategy == 'mode':
            # 使用眾數填補
            for column in self.df.columns:
                if self.df[column].isnull().any():
                    mode_value = self.df[column].mode()[0]
                    self.df[column].fillna(mode_value, inplace=True)
            print(f"使用眾數填補缺失值")
            
        elif strategy == 'drop':
            # 刪除含有缺失值的列
            original_length = len(self.df)
            self.df.dropna(inplace=True)
            dropped_count = original_length - len(self.df)
            print(f"刪除 {dropped_count} 筆含有缺失值的記錄")
        
        return self.df
    
    def detect_outliers(self, method: str = 'iqr') -> Dict[str, List[int]]:
        """
        偵測異常值
        
        參數:
            method: 偵測方法 ('iqr', 'zscore')
            
        回傳:
            各欄位的異常值索引
        """
        outliers = {}
        numeric_columns = self.df.select_dtypes(include=[np.number]).columns
        
        for column in numeric_columns:
            if method == 'iqr':
                # 使用四分位距法偵測異常值
                Q1 = self.df[column].quantile(0.25)
                Q3 = self.df[column].quantile(0.75)
                IQR = Q3 - Q1
                
                # 定義異常值範圍
                lower_bound = Q1 - 1.5 * IQR
                upper_bound = Q3 + 1.5 * IQR
                
                # 找出異常值
                outlier_indices = self.df[
                    (self.df[column] < lower_bound) | 
                    (self.df[column] > upper_bound)
                ].index.tolist()
                
                if outlier_indices:
                    outliers[column] = outlier_indices
                    print(f"{column}: 發現 {len(outlier_indices)} 個異常值")
            
            elif method == 'zscore':
                # 使用 Z-score 法偵測異常值
                z_scores = np.abs(
                    (self.df[column] - self.df[column].mean()) / 
                    self.df[column].std()
                )
                
                # Z-score > 3 視為異常值
                outlier_indices = self.df[z_scores > 3].index.tolist()
                
                if outlier_indices:
                    outliers[column] = outlier_indices
                    print(f"{column}: 發現 {len(outlier_indices)} 個異常值")
        
        return outliers
    
    def get_data_summary(self) -> pd.DataFrame:
        """
        生成資料摘要統計
        
        回傳:
            包含統計資訊的 DataFrame
        """
        summary = self.df.describe()
        
        # 加入額外的統計指標
        summary.loc['中位數'] = self.df.median(numeric_only=True)
        summary.loc['變異數'] = self.df.var(numeric_only=True)
        summary.loc['峰度'] = self.df.kurtosis(numeric_only=True)
        summary.loc['偏度'] = self.df.skew(numeric_only=True)
        
        return summary
    
    def generate_quality_report(self) -> str:
        """
        生成資料品質報告
        
        回傳:
            格式化的報告內容
        """
        report = "資料品質檢測報告\n"
        report += "=" * 60 + "\n\n"
        
        report += f"資料筆數: {len(self.df)}\n"
        report += f"欄位數量: {len(self.df.columns)}\n"
        report += f"記憶體使用: {self.df.memory_usage(deep=True).sum() / 1024:.2f} KB\n\n"
        
        if self.quality_issues:
            report += "發現的品質問題:\n"
            report += "-" * 60 + "\n"
            for i, issue in enumerate(self.quality_issues, 1):
                report += f"{i}. {issue}\n"
        else:
            report += "未發現資料品質問題\n"
        
        return report

# 建立完整的資料集
complete_data = {
    '商店ID': [32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
               52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
               72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85],
    '年份': [2021, 2022, 2022, 2022, 2023, 2022, 2023, 2023, 2021, 2022, 2023, 2021, 2022, 2023,
            2021, 2022, 2023, 2021, 2022, 2023, 2021, 2022, 2023, 2023, 2023, 2022, 2021, 2022,
            2023, 2022, 2023, 2022, 2023, 2023, 2023, 2021, 2021, 2022, 2021, 2022, 2021, 2022,
            2023, 2021, 2022, 2023, 2021, 2022, 2023, 2021, 2022, 2023, 2021, 2022],
    '收入增長率': [0.10, 0.16, 0.04, 0.04, 0.05, 0.08, 0.05, 0.18, 0.12, 0.09, 0.07, 0.15, 0.11,
                   0.06, 0.13, 0.10, 0.08, 0.14, 0.12, 0.09, 0.16, 0.13, 0.10, 0.17, 0.16, 0.05,
                   0.03, 0.13, 0.19, 0.17, 0.01, 0.05, 0.03, 0.19, 0.05, 0.07, 0.08, 0.09, 0.11,
                   0.14, 0.05, 0.10, 0.12, 0.06, 0.09, 0.11, 0.15, 0.13, 0.08, 0.10, 0.12, 0.09,
                   0.14, 0.11],
    '客戶滿意度': [59.63, 92.90, 81.11, 71.76, 64.48, 96.21, 93.39, 52.56, 78.45, 85.32, 70.89,
                   88.76, 79.54, 67.23, 82.34, 75.67, 69.45, 91.23, 84.56, 72.34, 87.65, 80.23,
                   74.56, 92.29, 86.13, 86.19, 74.44, 76.31, 60.44, 62.26, 89.64, 93.93, 80.56,
                   98.61, 50.67, 97.99, 73.45, 78.90, 82.34, 88.76, 68.45, 79.23, 85.67, 72.34,
                   81.45, 87.23, 94.56, 83.45, 76.89, 79.34, 84.67, 77.23, 90.45, 82.67],
    '產能指標': [7, 5, 1, 5, 2, 8, 2, 7, 6, 4, 3, 8, 5, 2, 7, 4, 3, 8, 6, 4, 7, 5, 3, 8, 6, 2, 8,
                4, 7, 1, 1, 6, 3, 8, 5, 1, 3, 4, 8, 6, 5, 7, 4, 2, 5, 6, 8, 7, 4, 5, 6, 4, 8, 7]
}

# 使用範例
if __name__ == "__main__":
    # 建立資料處理器
    processor = StoreDataProcessor()
    
    # 載入資料
    df = processor.load_data(complete_data)
    
    print("\n" + "="*60)
    print("資料型別驗證")
    print("="*60)
    processor.validate_data_types()
    
    print("\n" + "="*60)
    print("資料範圍驗證")
    print("="*60)
    processor.validate_data_ranges()
    
    print("\n" + "="*60)
    print("缺失值檢查")
    print("="*60)
    missing_counts = processor.check_missing_values()
    
    print("\n" + "="*60)
    print("異常值偵測")
    print("="*60)
    outliers = processor.detect_outliers(method='iqr')
    
    print("\n" + "="*60)
    print("資料摘要統計")
    print("="*60)
    summary = processor.get_data_summary()
    print(summary)
    
    print("\n" + processor.generate_quality_report())

這個資料處理系統建立了完整的品質控制流程。系統首先驗證資料型別,確保每個欄位都符合預期的資料格式。接著檢查數值範圍,識別邏輯上不合理的數值。缺失值檢查統計每個欄位的完整性,並提供多種填補策略。異常值偵測採用四分位距法與 Z-score 法,從統計角度識別極端值。資料摘要統計計算各種描述性指標,包含平均值、標準差、四分位數、峰度與偏度,全面描繪資料分佈特徵。

@startuml
!define PLANTUML_FORMAT svg
!theme _none_

skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 100

start

:載入原始資料;

partition "資料驗證" {
    :型別驗證\n確認欄位格式;
    :範圍驗證\n檢查數值合理性;
    :缺失值檢查\n統計完整性;
}

partition "資料清理" {
    :缺失值處理\n填補或刪除;
    :異常值偵測\nIQR 與 Z-score;
    :資料轉換\n標準化與正規化;
}

:生成品質報告;

:輸出乾淨資料集;

stop

@enduml

這個流程圖呈現了資料前置處理的完整流程。從載入原始資料開始,系統執行三層驗證:型別驗證確保資料格式正確,範圍驗證檢查數值的邏輯合理性,缺失值檢查評估資料完整性。驗證完成後進入清理階段,系統根據業務需求處理缺失值,使用統計方法偵測異常值,並進行必要的資料轉換。最後生成詳細的品質報告,記錄所有處理步驟與發現的問題,確保資料處理的透明性與可追溯性。

探索性資料分析與統計檢驗

探索性資料分析是深入理解資料特徵的關鍵步驟。透過視覺化與統計方法,分析師能夠發現資料中隱藏的模式、趨勢與關聯性。這個階段不僅是為了驗證資料品質,更重要的是形成初步的商業洞察,指引後續的深度分析方向。

年份分佈分析揭示資料的時間結構。本研究的資料集橫跨二零二一年至二零二三年,不同年份的樣本數量存在差異。二零二一年的記錄數量最多,反映該年度可能是業務擴張期或資料收集系統完善期。二零二三年的記錄較少,可能是資料收集尚未完成或部分商店退出營運。這種時間分佈不均勻性,在進行趨勢分析時需要特別注意,避免樣本偏誤導致錯誤結論。

收入增長率的分佈分析顯示商店營運表現的多樣性。資料顯示收入增長率範圍從百分之一至百分之十九,中位數約為百分之十。這種變異性反映市場競爭的激烈程度與不同商店的經營策略差異。部分商店實現高速增長,可能得益於創新的商業模式或精準的市場定位;而增長緩慢的商店則可能面臨市場飽和或營運效率問題。透過分佈分析,管理者能夠識別表現優異的標竿商店,研究其成功因素並推廣至其他據點。

import pandas as pd
import numpy as np
from scipy import stats
from typing import Dict, List, Tuple
import matplotlib.pyplot as plt
import seaborn as sns

class PerformanceAnalyzer:
    """
    商店績效分析系統
    執行探索性分析、統計檢驗與相關性研究
    """
    
    def __init__(self, df: pd.DataFrame):
        """
        初始化分析器
        
        參數:
            df: 已清理的商店績效資料
        """
        self.df = df.copy()
        self.analysis_results = {}
        
    def analyze_temporal_distribution(self) -> Dict:
        """
        分析時間分佈特徵
        
        回傳:
            時間分佈統計結果
        """
        # 計算每年的商店數量
        year_counts = self.df['年份'].value_counts().sort_index()
        
        # 計算每年的佔比
        year_percentages = (year_counts / len(self.df) * 100).round(2)
        
        temporal_stats = {
            '年度分佈': year_counts.to_dict(),
            '佔比': year_percentages.to_dict(),
            '跨越年份': self.df['年份'].max() - self.df['年份'].min() + 1,
            '總商店數': len(self.df['商店ID'].unique())
        }
        
        print("時間分佈分析結果:")
        print("-" * 60)
        for year, count in year_counts.items():
            percentage = year_percentages[year]
            print(f"{year}年: {count} 家商店 ({percentage}%)")
        
        self.analysis_results['temporal'] = temporal_stats
        return temporal_stats
    
    def analyze_growth_rate_distribution(self) -> Dict:
        """
        分析收入增長率分佈
        
        回傳:
            增長率統計結果
        """
        growth_rates = self.df['收入增長率']
        
        # 計算描述統計量
        stats_dict = {
            '平均值': growth_rates.mean(),
            '中位數': growth_rates.median(),
            '標準差': growth_rates.std(),
            '最小值': growth_rates.min(),
            '最大值': growth_rates.max(),
            '第一四分位數': growth_rates.quantile(0.25),
            '第三四分位數': growth_rates.quantile(0.75),
            '變異係數': growth_rates.std() / growth_rates.mean()
        }
        
        # 進行常態分佈檢驗(Shapiro-Wilk 檢驗)
        statistic, p_value = stats.shapiro(growth_rates)
        stats_dict['常態檢驗統計量'] = statistic
        stats_dict['常態檢驗p值'] = p_value
        stats_dict['是否常態分佈'] = p_value > 0.05
        
        print("\n收入增長率分佈分析:")
        print("-" * 60)
        for key, value in stats_dict.items():
            if isinstance(value, float):
                print(f"{key}: {value:.4f}")
            else:
                print(f"{key}: {value}")
        
        self.analysis_results['growth_rate'] = stats_dict
        return stats_dict
    
    def analyze_satisfaction_distribution(self) -> Dict:
        """
        分析客戶滿意度分佈
        
        回傳:
            滿意度統計結果
        """
        satisfaction = self.df['客戶滿意度']
        
        # 計算描述統計量
        stats_dict = {
            '平均值': satisfaction.mean(),
            '中位數': satisfaction.median(),
            '標準差': satisfaction.std(),
            '最小值': satisfaction.min(),
            '最大值': satisfaction.max(),
            '第一四分位數': satisfaction.quantile(0.25),
            '第三四分位數': satisfaction.quantile(0.75),
            '變異係數': satisfaction.std() / satisfaction.mean()
        }
        
        # 分類統計(高、中、低滿意度)
        stats_dict['高滿意度商店數'] = len(satisfaction[satisfaction >= 85])
        stats_dict['中滿意度商店數'] = len(satisfaction[(satisfaction >= 70) & (satisfaction < 85)])
        stats_dict['低滿意度商店數'] = len(satisfaction[satisfaction < 70])
        
        print("\n客戶滿意度分佈分析:")
        print("-" * 60)
        for key, value in stats_dict.items():
            if isinstance(value, float):
                print(f"{key}: {value:.2f}")
            else:
                print(f"{key}: {value}")
        
        self.analysis_results['satisfaction'] = stats_dict
        return stats_dict
    
    def correlation_analysis(self) -> pd.DataFrame:
        """
        計算各指標間的相關係數
        
        回傳:
            相關係數矩陣
        """
        # 選擇數值型欄位
        numeric_columns = ['收入增長率', '客戶滿意度', '產能指標']
        
        # 計算 Pearson 相關係數
        pearson_corr = self.df[numeric_columns].corr(method='pearson')
        
        # 計算 Spearman 相關係數(適用於非線性關係)
        spearman_corr = self.df[numeric_columns].corr(method='spearman')
        
        print("\nPearson 相關係數矩陣:")
        print("-" * 60)
        print(pearson_corr.round(4))
        
        print("\nSpearman 相關係數矩陣:")
        print("-" * 60)
        print(spearman_corr.round(4))
        
        self.analysis_results['correlation'] = {
            'pearson': pearson_corr.to_dict(),
            'spearman': spearman_corr.to_dict()
        }
        
        return pearson_corr
    
    def test_growth_satisfaction_relationship(self) -> Dict:
        """
        檢驗收入增長率與客戶滿意度的關係
        
        回傳:
            統計檢驗結果
        """
        growth = self.df['收入增長率']
        satisfaction = self.df['客戶滿意度']
        
        # Pearson 相關係數檢驗
        pearson_r, pearson_p = stats.pearsonr(growth, satisfaction)
        
        # Spearman 等級相關檢驗
        spearman_r, spearman_p = stats.spearmanr(growth, satisfaction)
        
        # 線性迴歸分析
        slope, intercept, r_value, p_value, std_err = stats.linregress(growth, satisfaction)
        
        results = {
            'Pearson相關係數': pearson_r,
            'Pearson顯著性': pearson_p,
            'Pearson結論': '顯著相關' if pearson_p < 0.05 else '不顯著',
            'Spearman相關係數': spearman_r,
            'Spearman顯著性': spearman_p,
            'Spearman結論': '顯著相關' if spearman_p < 0.05 else '不顯著',
            '迴歸斜率': slope,
            '迴歸截距': intercept,
            'R平方值': r_value**2,
            '標準誤差': std_err
        }
        
        print("\n收入增長率與客戶滿意度關係檢驗:")
        print("-" * 60)
        for key, value in results.items():
            if isinstance(value, float):
                print(f"{key}: {value:.4f}")
            else:
                print(f"{key}: {value}")
        
        self.analysis_results['relationship_test'] = results
        return results
    
    def compare_year_performance(self) -> Dict:
        """
        比較不同年份的績效表現
        
        回傳:
            年度比較結果
        """
        results = {}
        
        for year in sorted(self.df['年份'].unique()):
            year_data = self.df[self.df['年份'] == year]
            
            results[year] = {
                '商店數量': len(year_data),
                '平均收入增長率': year_data['收入增長率'].mean(),
                '平均客戶滿意度': year_data['客戶滿意度'].mean(),
                '平均產能指標': year_data['產能指標'].mean()
            }
        
        print("\n年度績效比較:")
        print("-" * 60)
        
        comparison_df = pd.DataFrame(results).T
        print(comparison_df.round(4))
        
        # 執行 ANOVA 檢驗(檢驗不同年份間是否有顯著差異)
        years = sorted(self.df['年份'].unique())
        growth_by_year = [
            self.df[self.df['年份'] == year]['收入增長率'].values 
            for year in years
        ]
        
        f_stat, p_value = stats.f_oneway(*growth_by_year)
        
        print(f"\nANOVA 檢驗結果(收入增長率):")
        print(f"F統計量: {f_stat:.4f}")
        print(f"p值: {p_value:.4f}")
        print(f"結論: {'不同年份間存在顯著差異' if p_value < 0.05 else '不同年份間無顯著差異'}")
        
        self.analysis_results['year_comparison'] = results
        return results
    
    def identify_top_performers(self, metric: str = '客戶滿意度', top_n: int = 10) -> pd.DataFrame:
        """
        識別績效優異的商店
        
        參數:
            metric: 評估指標
            top_n: 前 N 名
            
        回傳:
            績效最佳的商店資料
        """
        top_stores = self.df.nlargest(top_n, metric)
        
        print(f"\n{metric}{top_n}名商店:")
        print("-" * 60)
        print(top_stores[['商店ID', '年份', '收入增長率', '客戶滿意度', '產能指標']])
        
        return top_stores
    
    def generate_comprehensive_report(self) -> str:
        """
        生成綜合分析報告
        
        回傳:
            格式化的報告內容
        """
        report = "商店績效綜合分析報告\n"
        report += "=" * 60 + "\n\n"
        
        # 基本統計資訊
        report += "一、資料概況\n"
        report += "-" * 60 + "\n"
        report += f"總商店數: {len(self.df)}\n"
        report += f"分析期間: {self.df['年份'].min()} - {self.df['年份'].max()}\n\n"
        
        # 收入增長率分析
        if 'growth_rate' in self.analysis_results:
            growth_stats = self.analysis_results['growth_rate']
            report += "二、收入增長率分析\n"
            report += "-" * 60 + "\n"
            report += f"平均增長率: {growth_stats['平均值']:.2%}\n"
            report += f"中位數: {growth_stats['中位數']:.2%}\n"
            report += f"標準差: {growth_stats['標準差']:.2%}\n"
            report += f"變異係數: {growth_stats['變異係數']:.4f}\n\n"
        
        # 客戶滿意度分析
        if 'satisfaction' in self.analysis_results:
            sat_stats = self.analysis_results['satisfaction']
            report += "三、客戶滿意度分析\n"
            report += "-" * 60 + "\n"
            report += f"平均滿意度: {sat_stats['平均值']:.2f}\n"
            report += f"高滿意度商店: {sat_stats['高滿意度商店數']}\n"
            report += f"中滿意度商店: {sat_stats['中滿意度商店數']}\n"
            report += f"低滿意度商店: {sat_stats['低滿意度商店數']}\n\n"
        
        # 關係檢驗
        if 'relationship_test' in self.analysis_results:
            rel_test = self.analysis_results['relationship_test']
            report += "四、增長率與滿意度關係\n"
            report += "-" * 60 + "\n"
            report += f"相關係數: {rel_test['Pearson相關係數']:.4f}\n"
            report += f"顯著性: {rel_test['Pearson結論']}\n"
            report += f"解釋變異比例: {rel_test['R平方值']:.2%}\n\n"
        
        report += "五、管理建議\n"
        report += "-" * 60 + "\n"
        report += "1. 持續追蹤高成長商店的經營策略,提煉成功經驗\n"
        report += "2. 針對低滿意度商店制定改善計畫,提升服務品質\n"
        report += "3. 平衡收入增長與客戶體驗,避免過度追求短期業績\n"
        report += "4. 建立績效預警機制,及時發現並解決營運問題\n"
        
        return report

# 使用範例
if __name__ == "__main__":
    # 假設已有處理好的資料
    analyzer = PerformanceAnalyzer(processor.df)
    
    # 執行各項分析
    analyzer.analyze_temporal_distribution()
    analyzer.analyze_growth_rate_distribution()
    analyzer.analyze_satisfaction_distribution()
    analyzer.correlation_analysis()
    analyzer.test_growth_satisfaction_relationship()
    analyzer.compare_year_performance()
    analyzer.identify_top_performers()
    
    # 生成綜合報告
    report = analyzer.generate_comprehensive_report()
    print("\n" + report)

這個分析系統執行全面的探索性資料分析。時間分佈分析揭示資料的時間結構與樣本特徵。收入增長率分析計算多種描述統計量,並透過常態性檢驗判斷資料分佈型態。客戶滿意度分析不僅計算統計指標,還將商店分類為高、中、低滿意度群組,便於針對性管理。相關性分析同時計算 Pearson 與 Spearman 係數,前者適用於線性關係,後者適用於單調關係。關係檢驗透過多種統計方法驗證收入增長與客戶滿意度的關聯性。年度比較使用 ANOVA 檢驗評估不同年份間的績效差異。

@startuml
!define PLANTUML_FORMAT svg
!theme _none_

skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 100

start

:接收乾淨資料集;

partition "描述統計分析" {
    :時間分佈分析\n年度樣本統計;
    :收入增長率分析\n集中趨勢與離散程度;
    :客戶滿意度分析\n群組分類統計;
}

partition "推論統計檢驗" {
    :常態分佈檢驗\nShapiro-Wilk 檢驗;
    :相關性分析\nPearson 與 Spearman;
    :關係強度檢驗\n迴歸分析;
    :組間差異檢驗\nANOVA 檢驗;
}

:識別優異商店\n標竿分析;

:生成綜合報告;

stop

@enduml

這個流程圖展示探索性資料分析的系統化流程。分析從描述統計開始,透過時間分佈、收入增長率與客戶滿意度的多維度統計,建立對資料的基礎理解。接著進入推論統計檢驗階段,執行常態分佈檢驗評估資料分佈型態,相關性分析量化變數間關係,迴歸分析建立預測模型,ANOVA 檢驗評估組間差異。最後識別績效優異的標竿商店,並整合所有分析結果生成綜合報告,為管理決策提供實證基礎。

績效驅動因素與營運策略建議

資料分析的最終目的是提供可行的商業洞察與管理建議。透過前述的統計分析與關聯性研究,我們能夠識別影響商店績效的關鍵因素,並針對不同情境提出改善策略。這個階段需要結合定量分析結果與定性業務知識,確保建議的可行性與實用性。

收入增長率與客戶滿意度的關係分析顯示兩者並非完全正相關。部分商店在追求高收入增長的過程中,可能犧牲了服務品質與客戶體驗,導致滿意度下降。例如商店三十九在二零二三年實現百分之十八的高增長率,但客戶滿意度僅五十二點五六,遠低於平均水準。這種情況可能源於過度的促銷活動、服務人力不足或產品品質妥協。相反地,商店三十七在二零二二年達到九十六點二一的高滿意度,收入增長率為百分之八,展現了平衡增長的典範。

產能指標在績效評估中扮演重要但複雜的角色。理論上,較高的產能指標應該支持更好的營運效率與客戶服務品質。然而,資料顯示產能指標與客戶滿意度的相關性並不顯著。這可能反映產能的質量比數量更重要,或者產能配置不當導致資源浪費。管理者需要深入分析產能利用效率,而非單純增加產能投入。

年度比較分析揭示市場環境與營運策略的演變。二零二一年至二零二三年間,整體市場呈現成長態勢,但不同商店的表現差異顯著。成功的商店通常具備幾個共同特徵:清晰的市場定位、穩定的服務品質、持續的創新能力與靈活的策略調整。這些軟性因素難以直接量化,但對長期績效至關重要。

基於分析結果,管理者應採取差異化的管理策略。對於高增長低滿意度的商店,首要任務是穩定服務品質,避免為追求短期業績而損害品牌價值。可以透過增加服務人力、強化品質管控、優化客戶體驗流程來提升滿意度。對於低增長高滿意度的商店,需要在維持服務水準的前提下,探索業務增長機會。可以透過精準行銷、產品創新、市場擴張來刺激收入增長。對於雙低表現的商店,需要全面檢視營運模式,可能需要進行策略性重組或退出決策。

建立績效預警機制是持續改善的關鍵。管理者應該定期追蹤關鍵指標,設定合理的預警閾值。當商店的收入增長率或客戶滿意度出現異常波動時,立即啟動調查與干預機制。預警系統不僅能及時發現問題,更能預防潛在風險,保護企業的長期競爭力。

最後,資料驅動的決策文化需要在組織內部扎根。管理者應該培養團隊的資料素養,鼓勵基於證據的討論與決策。定期分享分析結果與成功案例,形成學習型組織。同時,建立回饋機制,持續優化分析方法與指標體系,確保分析工作能夠真正創造商業價值。

@startuml
!define PLANTUML_FORMAT svg
!theme _none_

skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 100

start

:績效資料分析結果;

if (收入增長率) then (高)
    if (客戶滿意度) then (高)
        :標竿商店\n維持策略並推廣;
    else (低)
        :增長優先型\n提升服務品質;
    endif
else (低)
    if (客戶滿意度) then (高)
        :體驗優先型\n探索增長機會;
    else (低)
        :雙低績效\n策略性重組;
    endif
endif

:制定改善計畫;

:執行與追蹤;

:定期評估成效;

if (達成目標?) then (是)
    :標準化成功經驗;
else (否)
    :調整策略;
endif

stop

@enduml

這個決策流程圖提供系統化的管理策略框架。根據收入增長率與客戶滿意度的組合,商店被分為四種類型。標竿商店同時實現高增長與高滿意度,應該維持現有策略並將成功經驗推廣至其他據點。增長優先型商店需要在維持業績的同時提升服務品質,避免短視行為損害長期價值。體驗優先型商店應該在保持服務水準的基礎上探索增長機會,透過創新與行銷刺激業績提升。雙低績效商店需要全面檢視營運模式,可能需要進行策略性重組。

結語

零售業績效管理是一個持續演進的過程,需要整合定量分析與定性洞察。本文透過 Python 資料分析技術,建立了完整的商店績效評估框架,從資料前置處理到探索性分析,從統計檢驗到管理建議,形成閉環的決策支援系統。資料顯示,商店績效受多重因素影響,收入增長與客戶滿意度需要平衡發展,單一指標的最佳化往往無法帶來長期成功。

成功的績效管理需要建立在可靠的資料基礎上。完整的資料品質控制流程,確保分析結果的準確性與可信度。探索性分析揭示資料中隱藏的模式與關聯,為深度研究指引方向。統計檢驗提供科學的證據支持,避免主觀判斷導致的決策偏誤。視覺化技術將複雜的分析結果轉化為直觀的商業洞察,促進跨部門的溝通與協作。

未來的研究可以從幾個方向深化。首先,整合更多維度的資料,包含市場環境、競爭態勢、營運成本等外部與內部因素,建立更全面的績效模型。其次,引入機器學習技術,開發預測模型預估未來績效趨勢,提供前瞻性的決策支援。第三,建立即時監控系統,實現績效資料的自動收集與分析,縮短從資料到洞察的時間延遲。第四,發展因果推論方法,識別真正的績效驅動因素,而非僅僅發現相關性。

資料驅動的決策文化是企業持續競爭力的源泉。管理者應該投資於資料基礎設施建設,培養團隊的資料分析能力,建立鼓勵實驗與學習的組織氛圍。透過系統化的績效分析,企業能夠更清晰地理解自身優勢與不足,更精準地配置資源,更快速地回應市場變化。在數位化轉型的浪潮中,掌握資料分析技術的企業,將在激烈的市場競爭中佔據優勢地位。