返回文章列表

資料驅動的團隊管理:員工滿意度與投入度的深度分析與優化策略

深入探討員工滿意度與投入度的測量方法與影響因素,結合團隊任期分析與工作量評估,透過Python建構完整的人力資源分析系統,從部門層級到個人層級的多維度分析,提供資料驅動的團隊管理優化策略與實務建議。

人力資源 資料分析 團隊管理

現代企業管理正經歷從直覺決策到資料驅動決策的轉型,人力資源管理領域同樣需要這種典範轉移。員工滿意度與投入度不僅是人力資源部門關注的軟性指標,更是直接影響組織績效、創新能力與競爭優勢的關鍵因素。高滿意度與高投入度的員工展現更強的工作動機、更低的離職傾向、更高的生產力以及更積極的組織公民行為。然而許多企業在評估與提升員工滿意度時面臨挑戰,包含缺乏系統性的測量工具、無法識別影響因素的優先順序、難以量化改善措施的成效以及跨部門差異的複雜性。資料驅動的分析方法提供了解決這些挑戰的途徑,透過結構化的資料收集、多維度的統計分析、視覺化的洞察呈現以及預測模型的建構,協助管理者全面理解員工狀態並制定有效的干預策略。

員工滿意度與投入度的理論基礎與測量方法

員工滿意度與投入度雖然密切相關但代表不同的心理狀態與行為傾向。員工滿意度反映員工對工作各個面向的評價性態度,包含對工作內容、薪酬福利、主管領導、同事關係、工作環境、職涯發展等要素的滿意程度。滿意度較高的員工對現狀感到愉悅與認可,但不一定會主動付出額外努力。員工投入度則是一種更積極主動的心理狀態,代表員工對工作的熱情、專注與奉獻程度,高投入度員工不僅滿意於現狀更願意為組織目標付出超越職責要求的努力。研究顯示滿意度是投入度的必要但非充分條件,員工可能因為穩定的薪資與友善的同事而滿意但缺乏對工作的熱情投入。

測量員工滿意度與投入度需要科學的工具與方法。量化測量通常採用問卷調查,滿意度問卷涵蓋多個維度如工作本身、薪酬、主管、晉升機會、同事、工作條件等,每個維度包含多個題項使用李克特量表評分。投入度問卷則著重於測量活力、奉獻與專注三個核心成分,活力反映工作時的精力充沛與韌性,奉獻代表對工作的熱情與意義感,專注則是沉浸於工作的心流狀態。除了問卷調查外,行為指標提供客觀的測量補充,包含出勤率、遲到早退頻率、主動加班意願、參與公司活動的積極性、提出改善建議的數量、協助同事的頻率等。績效資料如KPI達成率、專案完成品質、創新產出等也能間接反映投入度。質性方法如深度訪談、焦點團體與開放式問題回饋提供豐富的情境資訊,協助理解量化資料背後的原因。

影響員工滿意度與投入度的因素可以分為個人層次、工作層次、團隊層次與組織層次。個人層次因素包含人格特質如外向性與盡責性較高者通常展現更高滿意度,價值觀與工作價值契合度影響意義感與投入度,職涯階段如新進員工與即將退休員工的需求不同。工作層次因素涵蓋工作特性模型的五個核心維度即技能多樣性、任務完整性、任務重要性、自主性與回饋性,這些特性影響工作的內在動機。工作負荷需要適中過低導致無聊過高造成壓力,角色明確性與角色衝突影響工作壓力,工作資源如設備工具與資訊可得性影響工作效率。團隊層次因素包含團隊氛圍、同事支持、團隊凝聚力與人際衝突,主管的領導風格如轉型領導與支持型領導能夠提升投入度。組織層次因素涵蓋組織文化、薪酬福利制度、職涯發展機會、訓練資源、工作生活平衡政策以及組織變革管理。

# 員工滿意度與投入度分析系統
# 完整的問卷設計、資料收集、分析與視覺化功能

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from scipy import stats
from scipy.stats import pearsonr, spearmanr
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.cluster import KMeans
import warnings
warnings.filterwarnings('ignore')

# 設定繁體中文顯示
plt.rcParams['font.sans-serif'] = ['Microsoft JhengHei']
plt.rcParams['axes.unicode_minus'] = False

class EmployeeSatisfactionAnalyzer:
    """
    員工滿意度與投入度分析系統
    提供全面的問卷分析、統計檢定與視覺化功能
    """
    
    def __init__(self):
        """初始化分析系統"""
        self.data = None
        self.satisfaction_dimensions = [
            '工作內容滿意度', '薪酬福利滿意度', '主管領導滿意度',
            '同事關係滿意度', '工作環境滿意度', '職涯發展滿意度'
        ]
        self.engagement_dimensions = [
            '工作活力', '工作奉獻', '工作專注'
        ]
        
    def generate_survey_data(self, n_employees=300):
        """
        生成範例員工問卷資料
        模擬真實的滿意度與投入度調查結果
        
        參數:
            n_employees: 員工數量
            
        回傳:
            data: 生成的DataFrame
        """
        np.random.seed(42)
        
        # 生成基本資訊
        employee_ids = np.arange(1, n_employees + 1)
        
        # 生成部門
        departments = np.random.choice(
            ['人力資源', '工程部', '業務部', '行銷部', '財務部', '客服部'],
            size=n_employees,
            p=[0.08, 0.25, 0.22, 0.15, 0.12, 0.18]
        )
        
        # 生成年資(影響滿意度與投入度)
        tenure_years = np.random.exponential(scale=4, size=n_employees)
        tenure_years = np.clip(tenure_years, 0.5, 20).round(1)
        
        # 生成年齡
        ages = (np.random.normal(loc=28, scale=6, size=n_employees) + 
                tenure_years * 0.8).astype(int)
        ages = np.clip(ages, 22, 60)
        
        # 生成職位層級(影響滿意度)
        position_levels = np.random.choice(
            ['基層員工', '資深員工', '主管', '經理'],
            size=n_employees,
            p=[0.45, 0.30, 0.15, 0.10]
        )
        
        # 建構滿意度分數的多因素模型
        # 每個維度受不同因素影響
        
        # 1. 工作內容滿意度(受職位、年資影響)
        position_content_map = {
            '基層員工': 0.55, '資深員工': 0.70, 
            '主管': 0.75, '經理': 0.80
        }
        base_content = pd.Series(position_levels).map(position_content_map).values
        tenure_effect = np.clip(tenure_years / 20, 0, 0.3)
        work_content_satisfaction = (base_content + tenure_effect + 
                                    np.random.normal(0, 0.15, n_employees))
        work_content_satisfaction = np.clip(work_content_satisfaction, 0, 1) * 10
        
        # 2. 薪酬福利滿意度(受職位、部門影響)
        dept_salary_map = {
            '人力資源': 0.65, '工程部': 0.75, '業務部': 0.70,
            '行銷部': 0.68, '財務部': 0.72, '客服部': 0.60
        }
        dept_effect = pd.Series(departments).map(dept_salary_map).values
        position_salary_map = {
            '基層員工': 0.50, '資深員工': 0.65, 
            '主管': 0.75, '經理': 0.85
        }
        position_effect = pd.Series(position_levels).map(position_salary_map).values
        compensation_satisfaction = ((dept_effect + position_effect) / 2 + 
                                    np.random.normal(0, 0.15, n_employees))
        compensation_satisfaction = np.clip(compensation_satisfaction, 0, 1) * 10
        
        # 3. 主管領導滿意度(部門差異大)
        dept_leadership_map = {
            '人力資源': 0.75, '工程部': 0.68, '業務部': 0.62,
            '行銷部': 0.72, '財務部': 0.70, '客服部': 0.65
        }
        leadership_base = pd.Series(departments).map(dept_leadership_map).values
        supervisor_satisfaction = (leadership_base + 
                                  np.random.normal(0, 0.2, n_employees))
        supervisor_satisfaction = np.clip(supervisor_satisfaction, 0, 1) * 10
        
        # 4. 同事關係滿意度(相對穩定)
        coworker_satisfaction = (np.random.beta(5, 2, n_employees) * 10)
        
        # 5. 工作環境滿意度(部門差異)
        dept_environment_map = {
            '人力資源': 0.70, '工程部': 0.75, '業務部': 0.60,
            '行銷部': 0.72, '財務部': 0.68, '客服部': 0.58
        }
        environment_base = pd.Series(departments).map(dept_environment_map).values
        environment_satisfaction = (environment_base + 
                                   np.random.normal(0, 0.15, n_employees))
        environment_satisfaction = np.clip(environment_satisfaction, 0, 1) * 10
        
        # 6. 職涯發展滿意度(受年資、職位影響)
        career_base = np.where(
            tenure_years < 2, 0.70,
            np.where(tenure_years < 5, 0.65,
            np.where(tenure_years < 10, 0.55, 0.45))
        )
        position_career_map = {
            '基層員工': 0.55, '資深員工': 0.60, 
            '主管': 0.70, '經理': 0.65
        }
        career_position = pd.Series(position_levels).map(position_career_map).values
        career_satisfaction = ((career_base + career_position) / 2 + 
                              np.random.normal(0, 0.18, n_employees))
        career_satisfaction = np.clip(career_satisfaction, 0, 1) * 10
        
        # 計算整體滿意度(各維度加權平均)
        overall_satisfaction = (
            work_content_satisfaction * 0.20 +
            compensation_satisfaction * 0.20 +
            supervisor_satisfaction * 0.15 +
            coworker_satisfaction * 0.15 +
            environment_satisfaction * 0.15 +
            career_satisfaction * 0.15
        )
        
        # 建構投入度分數
        # 投入度受滿意度影響,但有獨立變異
        
        # 1. 工作活力(與工作內容滿意度、年齡相關)
        age_vigor_effect = np.where(ages < 30, 0.8, 
                          np.where(ages < 40, 0.75,
                          np.where(ages < 50, 0.65, 0.55)))
        work_vigor = ((work_content_satisfaction / 10 * 0.5 + 
                      age_vigor_effect * 0.5) +
                     np.random.normal(0, 0.15, n_employees))
        work_vigor = np.clip(work_vigor, 0, 1) * 10
        
        # 2. 工作奉獻(與整體滿意度、主管領導相關)
        dedication = ((overall_satisfaction / 10 * 0.4 +
                      supervisor_satisfaction / 10 * 0.3 +
                      career_satisfaction / 10 * 0.3) +
                     np.random.normal(0, 0.15, n_employees))
        dedication = np.clip(dedication, 0, 1) * 10
        
        # 3. 工作專注(與工作內容、工作環境相關)
        absorption = ((work_content_satisfaction / 10 * 0.5 +
                      environment_satisfaction / 10 * 0.5) +
                     np.random.normal(0, 0.15, n_employees))
        absorption = np.clip(absorption, 0, 1) * 10
        
        # 計算整體投入度
        overall_engagement = (work_vigor + dedication + absorption) / 3
        
        # 建立DataFrame
        self.data = pd.DataFrame({
            'employee_id': employee_ids,
            'department': departments,
            'tenure_years': tenure_years,
            'age': ages,
            'position': position_levels,
            'work_content_satisfaction': work_content_satisfaction.round(1),
            'compensation_satisfaction': compensation_satisfaction.round(1),
            'supervisor_satisfaction': supervisor_satisfaction.round(1),
            'coworker_satisfaction': coworker_satisfaction.round(1),
            'environment_satisfaction': environment_satisfaction.round(1),
            'career_satisfaction': career_satisfaction.round(1),
            'overall_satisfaction': overall_satisfaction.round(1),
            'work_vigor': work_vigor.round(1),
            'work_dedication': dedication.round(1),
            'work_absorption': absorption.round(1),
            'overall_engagement': overall_engagement.round(1)
        })
        
        print(f"成功生成 {n_employees} 份員工問卷資料")
        print(f"平均整體滿意度: {overall_satisfaction.mean():.2f}/10")
        print(f"平均整體投入度: {overall_engagement.mean():.2f}/10")
        
        return self.data
    
    def department_analysis(self):
        """
        部門層級的滿意度與投入度分析
        比較各部門的差異
        """
        if self.data is None:
            print("錯誤: 尚未載入資料")
            return
        
        print("\n" + "="*70)
        print("部門層級分析")
        print("="*70)
        
        # 計算各部門統計指標
        dept_stats = self.data.groupby('department').agg({
            'employee_id': 'count',
            'overall_satisfaction': ['mean', 'std', 'min', 'max'],
            'overall_engagement': ['mean', 'std', 'min', 'max'],
            'tenure_years': 'mean'
        }).round(2)
        
        dept_stats.columns = [
            '人數', '平均滿意度', '滿意度標準差', '最低滿意度', '最高滿意度',
            '平均投入度', '投入度標準差', '最低投入度', '最高投入度', '平均年資'
        ]
        
        # 按平均滿意度排序
        dept_stats = dept_stats.sort_values('平均滿意度', ascending=False)
        
        print("\n各部門綜合指標:")
        print(dept_stats.to_string())
        
        # 計算滿意度與投入度的相關性
        print("\n各部門滿意度與投入度的相關係數:")
        print("-" * 50)
        
        for dept in self.data['department'].unique():
            dept_data = self.data[self.data['department'] == dept]
            if len(dept_data) >= 5:
                corr, p_value = pearsonr(
                    dept_data['overall_satisfaction'],
                    dept_data['overall_engagement']
                )
                print(f"{dept:10s}: r = {corr:>6.3f}, p = {p_value:.4f}")
        
        # 進行ANOVA檢定評估部門間差異的顯著性
        print("\n部門間差異顯著性檢定(ANOVA):")
        print("-" * 50)
        
        # 滿意度的ANOVA
        dept_groups_sat = [self.data[self.data['department'] == dept]['overall_satisfaction']
                          for dept in self.data['department'].unique()]
        f_stat_sat, p_value_sat = stats.f_oneway(*dept_groups_sat)
        
        print(f"滿意度: F統計量 = {f_stat_sat:.4f}, p值 = {p_value_sat:.4f}")
        if p_value_sat < 0.05:
            print("結論: 各部門滿意度存在顯著差異")
        else:
            print("結論: 各部門滿意度無顯著差異")
        
        # 投入度的ANOVA
        dept_groups_eng = [self.data[self.data['department'] == dept]['overall_engagement']
                          for dept in self.data['department'].unique()]
        f_stat_eng, p_value_eng = stats.f_oneway(*dept_groups_eng)
        
        print(f"投入度: F統計量 = {f_stat_eng:.4f}, p值 = {p_value_eng:.4f}")
        if p_value_eng < 0.05:
            print("結論: 各部門投入度存在顯著差異")
        else:
            print("結論: 各部門投入度無顯著差異")
        
        return dept_stats
    
    def dimension_analysis(self):
        """
        滿意度維度分析
        識別需要改善的面向
        """
        if self.data is None:
            print("錯誤: 尚未載入資料")
            return
        
        print("\n" + "="*70)
        print("滿意度維度分析")
        print("="*70)
        
        # 計算各維度的統計指標
        dimension_cols = [
            'work_content_satisfaction', 'compensation_satisfaction',
            'supervisor_satisfaction', 'coworker_satisfaction',
            'environment_satisfaction', 'career_satisfaction'
        ]
        
        dimension_names = [
            '工作內容', '薪酬福利', '主管領導',
            '同事關係', '工作環境', '職涯發展'
        ]
        
        dimension_stats = pd.DataFrame({
            '維度': dimension_names,
            '平均分數': [self.data[col].mean() for col in dimension_cols],
            '標準差': [self.data[col].std() for col in dimension_cols],
            '最低分': [self.data[col].min() for col in dimension_cols],
            '最高分': [self.data[col].max() for col in dimension_cols],
            '不滿意比例': [(self.data[col] < 5).mean() * 100 
                       for col in dimension_cols]
        }).round(2)
        
        # 按平均分數排序
        dimension_stats = dimension_stats.sort_values('平均分數', ascending=True)
        
        print("\n各維度統計指標(按平均分數升序):")
        print(dimension_stats.to_string(index=False))
        
        # 找出需要優先改善的維度
        print("\n需要優先改善的維度(平均分數<6.5或不滿意比例>30%):")
        priority_dims = dimension_stats[
            (dimension_stats['平均分數'] < 6.5) | 
            (dimension_stats['不滿意比例'] > 30)
        ]
        
        if len(priority_dims) > 0:
            print(priority_dims[['維度', '平均分數', '不滿意比例']].to_string(index=False))
        else:
            print("所有維度表現良好")
        
        return dimension_stats
    
    def visualize_satisfaction_engagement(self):
        """
        視覺化滿意度與投入度的關係
        """
        if self.data is None:
            print("錯誤: 尚未載入資料")
            return
        
        print("\n生成滿意度與投入度視覺化圖表...")
        
        fig, axes = plt.subplots(2, 2, figsize=(16, 12))
        
        # 子圖1: 滿意度與投入度散佈圖(按部門著色)
        ax1 = axes[0, 0]
        
        departments = self.data['department'].unique()
        colors = plt.cm.Set3(np.linspace(0, 1, len(departments)))
        
        for dept, color in zip(departments, colors):
            dept_data = self.data[self.data['department'] == dept]
            ax1.scatter(
                dept_data['overall_satisfaction'],
                dept_data['overall_engagement'],
                label=dept,
                alpha=0.6,
                s=60,
                color=color,
                edgecolors='black',
                linewidth=0.5
            )
        
        # 添加回歸線
        z = np.polyfit(self.data['overall_satisfaction'], 
                      self.data['overall_engagement'], 1)
        p = np.poly1d(z)
        x_line = np.linspace(
            self.data['overall_satisfaction'].min(),
            self.data['overall_satisfaction'].max(),
            100
        )
        ax1.plot(x_line, p(x_line), 'r--', linewidth=2, 
                label=f'趨勢線 (r={self.data["overall_satisfaction"].corr(self.data["overall_engagement"]):.3f})',
                alpha=0.8)
        
        ax1.set_xlabel('整體滿意度', fontsize=12)
        ax1.set_ylabel('整體投入度', fontsize=12)
        ax1.set_title('員工滿意度與投入度關係', 
                     fontsize=14, fontweight='bold')
        ax1.legend(loc='best', fontsize=8)
        ax1.grid(alpha=0.3)
        
        # 子圖2: 各部門平均滿意度與投入度比較
        ax2 = axes[0, 1]
        
        dept_avg = self.data.groupby('department').agg({
            'overall_satisfaction': 'mean',
            'overall_engagement': 'mean'
        }).sort_values('overall_satisfaction', ascending=True)
        
        x = np.arange(len(dept_avg))
        width = 0.35
        
        bars1 = ax2.barh(x - width/2, dept_avg['overall_satisfaction'], 
                        width, label='滿意度', color='steelblue', 
                        edgecolor='black')
        bars2 = ax2.barh(x + width/2, dept_avg['overall_engagement'], 
                        width, label='投入度', color='coral',
                        edgecolor='black')
        
        ax2.set_yticks(x)
        ax2.set_yticklabels(dept_avg.index)
        ax2.set_xlabel('平均分數', fontsize=12)
        ax2.set_title('各部門平均滿意度與投入度', 
                     fontsize=14, fontweight='bold')
        ax2.legend()
        ax2.grid(axis='x', alpha=0.3)
        
        # 在長條圖上顯示數值
        for bars in [bars1, bars2]:
            for bar in bars:
                width_val = bar.get_width()
                ax2.text(width_val + 0.1, bar.get_y() + bar.get_height()/2,
                        f'{width_val:.1f}', ha='left', va='center', fontsize=9)
        
        # 子圖3: 滿意度各維度雷達圖(全公司平均)
        ax3 = axes[1, 0]
        
        dimension_cols = [
            'work_content_satisfaction', 'compensation_satisfaction',
            'supervisor_satisfaction', 'coworker_satisfaction',
            'environment_satisfaction', 'career_satisfaction'
        ]
        dimension_short_names = [
            '工作內容', '薪酬福利', '主管領導',
            '同事關係', '工作環境', '職涯發展'
        ]
        
        values = [self.data[col].mean() for col in dimension_cols]
        values += values[:1]  # 閉合雷達圖
        
        angles = np.linspace(0, 2 * np.pi, len(dimension_short_names), endpoint=False).tolist()
        angles += angles[:1]
        
        ax3 = plt.subplot(2, 2, 3, projection='polar')
        ax3.plot(angles, values, 'o-', linewidth=2, color='steelblue')
        ax3.fill(angles, values, alpha=0.25, color='steelblue')
        ax3.set_xticks(angles[:-1])
        ax3.set_xticklabels(dimension_short_names)
        ax3.set_ylim(0, 10)
        ax3.set_title('滿意度各維度雷達圖', 
                     fontsize=14, fontweight='bold', pad=20)
        ax3.grid(True)
        
        # 子圖4: 投入度三維度比較
        ax4 = axes[1, 1]
        
        engagement_dims = ['work_vigor', 'work_dedication', 'work_absorption']
        engagement_names = ['工作活力', '工作奉獻', '工作專注']
        
        engagement_values = [self.data[col].mean() for col in engagement_dims]
        
        bars = ax4.bar(range(len(engagement_names)), engagement_values,
                      color=['lightcoral', 'lightgreen', 'lightblue'],
                      edgecolor='black', alpha=0.7)
        
        ax4.set_xticks(range(len(engagement_names)))
        ax4.set_xticklabels(engagement_names)
        ax4.set_ylabel('平均分數', fontsize=12)
        ax4.set_title('投入度三維度分析', 
                     fontsize=14, fontweight='bold')
        ax4.set_ylim(0, 10)
        ax4.grid(axis='y', alpha=0.3)
        
        # 在長條圖上顯示數值
        for bar, value in zip(bars, engagement_values):
            height = bar.get_height()
            ax4.text(bar.get_x() + bar.get_width()/2., height + 0.2,
                    f'{value:.2f}', ha='center', va='bottom', 
                    fontweight='bold', fontsize=11)
        
        plt.tight_layout()
        plt.show()
    
    def identify_risk_employees(self, satisfaction_threshold=5.0, 
                               engagement_threshold=5.0):
        """
        識別高風險員工
        低滿意度或低投入度的員工
        
        參數:
            satisfaction_threshold: 滿意度警戒線
            engagement_threshold: 投入度警戒線
        """
        if self.data is None:
            print("錯誤: 尚未載入資料")
            return
        
        print("\n" + "="*70)
        print("高風險員工識別")
        print("="*70)
        
        # 識別不同類型的風險員工
        low_satisfaction = self.data[
            self.data['overall_satisfaction'] < satisfaction_threshold
        ]
        low_engagement = self.data[
            self.data['overall_engagement'] < engagement_threshold
        ]
        double_low = self.data[
            (self.data['overall_satisfaction'] < satisfaction_threshold) &
            (self.data['overall_engagement'] < engagement_threshold)
        ]
        
        print(f"\n風險員工統計(閾值: 滿意度<{satisfaction_threshold}, 投入度<{engagement_threshold}):")
        print(f"低滿意度員工: {len(low_satisfaction)} 人 ({len(low_satisfaction)/len(self.data)*100:.1f}%)")
        print(f"低投入度員工: {len(low_engagement)} 人 ({len(low_engagement)/len(self.data)*100:.1f}%)")
        print(f"雙低員工(最高風險): {len(double_low)} 人 ({len(double_low)/len(self.data)*100:.1f}%)")
        
        # 分析雙低員工的部門分佈
        if len(double_low) > 0:
            print("\n雙低員工的部門分佈:")
            dept_dist = double_low['department'].value_counts()
            for dept, count in dept_dist.items():
                pct = count / len(double_low) * 100
                print(f"  {dept}: {count} 人 ({pct:.1f}%)")
            
            # 分析雙低員工的職位分佈
            print("\n雙低員工的職位分佈:")
            position_dist = double_low['position'].value_counts()
            for pos, count in position_dist.items():
                pct = count / len(double_low) * 100
                print(f"  {pos}: {count} 人 ({pct:.1f}%)")
        
        return {
            'low_satisfaction': low_satisfaction,
            'low_engagement': low_engagement,
            'double_low': double_low
        }
    
    def correlation_heatmap(self):
        """
        繪製滿意度與投入度各維度的相關性熱力圖
        """
        if self.data is None:
            print("錯誤: 尚未載入資料")
            return
        
        print("\n生成相關性熱力圖...")
        
        # 選擇要分析的欄位
        analysis_cols = [
            'work_content_satisfaction', 'compensation_satisfaction',
            'supervisor_satisfaction', 'coworker_satisfaction',
            'environment_satisfaction', 'career_satisfaction',
            'work_vigor', 'work_dedication', 'work_absorption',
            'overall_satisfaction', 'overall_engagement'
        ]
        
        col_names = [
            '工作內容', '薪酬福利', '主管領導', '同事關係',
            '工作環境', '職涯發展', '工作活力', '工作奉獻',
            '工作專注', '整體滿意度', '整體投入度'
        ]
        
        # 計算相關係數矩陣
        corr_matrix = self.data[analysis_cols].corr()
        
        # 繪製熱力圖
        plt.figure(figsize=(14, 12))
        sns.heatmap(
            corr_matrix,
            annot=True,
            fmt='.2f',
            cmap='RdYlGn',
            center=0,
            square=True,
            linewidths=0.5,
            cbar_kws={'label': '相關係數'},
            xticklabels=col_names,
            yticklabels=col_names
        )
        plt.title('滿意度與投入度各維度相關性分析', 
                 fontsize=16, fontweight='bold', pad=20)
        plt.xticks(rotation=45, ha='right')
        plt.yticks(rotation=0)
        plt.tight_layout()
        plt.show()

# 主程式執行
if __name__ == "__main__":
    # 初始化分析系統
    analyzer = EmployeeSatisfactionAnalyzer()
    
    # 生成範例問卷資料
    print("生成員工滿意度與投入度問卷資料...")
    data = analyzer.generate_survey_data(n_employees=400)
    
    # 顯示前幾筆資料
    print("\n前5筆員工資料:")
    display_cols = ['employee_id', 'department', 'position', 
                   'overall_satisfaction', 'overall_engagement']
    print(data[display_cols].head().to_string())
    
    # 部門層級分析
    dept_stats = analyzer.department_analysis()
    
    # 維度分析
    dim_stats = analyzer.dimension_analysis()
    
    # 視覺化分析
    analyzer.visualize_satisfaction_engagement()
    
    # 識別高風險員工
    risk_employees = analyzer.identify_risk_employees(
        satisfaction_threshold=5.5,
        engagement_threshold=5.5
    )
    
    # 相關性分析
    analyzer.correlation_heatmap()
    
    print("\n員工滿意度與投入度分析完成!")

這段完整的員工滿意度與投入度分析系統展示了如何建構科學的人力資源評估工具。EmployeeSatisfactionAnalyzer類別實作從問卷設計到深度分析的完整流程,資料生成功能模擬真實的員工調查結果,考量六個滿意度維度與三個投入度維度的測量。工作內容滿意度受職位層級與年資影響,職位越高通常工作越有挑戰性與自主性。薪酬福利滿意度受部門與職位雙重影響,工程部與高階職位薪資較優。主管領導滿意度展現明顯的部門差異,反映不同部門的管理風格。同事關係滿意度相對穩定較少受外部因素影響。工作環境滿意度與部門工作性質相關,辦公室環境優於現場作業環境。職涯發展滿意度呈現倒U型曲線,新進員工充滿期待、中期員工遭遇瓶頸、資深員工接受現況。投入度的三個維度各有特性,工作活力與年齡相關年輕員工精力充沛,工作奉獻受整體滿意度與主管領導影響,工作專注則與工作內容趣味性和環境條件相關。

部門層級分析計算各部門的平均滿意度與投入度,並進行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 120

title 整合型團隊管理分析系統

package "資料收集模組" {
  [人資管理系統] as HRMS
  [專案管理系統] as PMS
  [時間追蹤系統] as TTS
  [績效評估系統] as PAS
  [問卷調查平台] as SURVEY
}

package "分析引擎" {
  [滿意度分析] as SAT_ANALYSIS
  [投入度分析] as ENG_ANALYSIS
  [任期分析] as TEN_ANALYSIS
  [工作量分析] as WORK_ANALYSIS
  [風險識別] as RISK_ID
}

package "視覺化儀表板" {
  [部門健康儀表板] as DEPT_DASH
  [個人發展儀表板] as IND_DASH
  [風險預警儀表板] as RISK_DASH
  [行動追蹤儀表板] as ACTION_DASH
}

package "干預行動模組" {
  [一對一面談] as ONE_ON_ONE
  [職涯輔導] as CAREER_COUNSEL
  [培訓發展] as TRAINING
  [薪酬調整] as COMP_ADJUST
  [工作重新設計] as JOB_REDESIGN
}

database "整合資料倉儲" as DW {
  [員工檔案]
  [滿意度歷史]
  [投入度歷史]
  [專案任務記錄]
  [績效評估記錄]
}

actor "人力資源經理" as HR_MGR
actor "部門主管" as DEPT_MGR
actor "高階主管" as EXEC

HRMS --> DW : 人員資料
PMS --> DW : 專案任務
TTS --> DW : 工時記錄
PAS --> DW : 績效資料
SURVEY --> DW : 問卷結果

DW --> SAT_ANALYSIS : 滿意度資料
DW --> ENG_ANALYSIS : 投入度資料
DW --> TEN_ANALYSIS : 任期資料
DW --> WORK_ANALYSIS : 工作量資料

SAT_ANALYSIS --> RISK_ID : 滿意度風險
ENG_ANALYSIS --> RISK_ID : 投入度風險
TEN_ANALYSIS --> RISK_ID : 流失風險
WORK_ANALYSIS --> RISK_ID : 過載風險

SAT_ANALYSIS --> DEPT_DASH : 部門指標
ENG_ANALYSIS --> DEPT_DASH : 投入度指標
TEN_ANALYSIS --> DEPT_DASH : 任期分佈
WORK_ANALYSIS --> DEPT_DASH : 工作量統計

SAT_ANALYSIS --> IND_DASH : 個人滿意度
ENG_ANALYSIS --> IND_DASH : 個人投入度
PAS --> IND_DASH : 個人績效

RISK_ID --> RISK_DASH : 風險清單
RISK_ID --> ACTION_DASH : 行動建議

RISK_DASH --> HR_MGR : 風險警示
RISK_DASH --> DEPT_MGR : 團隊風險

ACTION_DASH --> ONE_ON_ONE : 面談安排
ACTION_DASH --> CAREER_COUNSEL : 輔導計畫
ACTION_DASH --> TRAINING : 培訓需求
ACTION_DASH --> COMP_ADJUST : 調薪建議
ACTION_DASH --> JOB_REDESIGN : 工作調整

ONE_ON_ONE --> DW : 面談記錄
CAREER_COUNSEL --> DW : 輔導記錄
TRAINING --> DW : 培訓記錄
COMP_ADJUST --> DW : 薪酬調整
JOB_REDESIGN --> DW : 工作變更

DEPT_DASH --> DEPT_MGR : 即時監控
DEPT_DASH --> EXEC : 摘要報告
IND_DASH --> DEPT_MGR : 團隊成員

note right of RISK_ID
  風險類型:
  - 雙低風險(滿意度與投入度皆低)
  - 流失風險(資深員工滿意度下降)
  - 倦怠風險(持續高工作量)
  - 停滯風險(缺乏發展機會)
end note

note right of ACTION_DASH
  行動優先級:
  1. 雙低員工(立即面談)
  2. 資深員工流失風險(留任計畫)
  3. 團隊工作量失衡(重新分配)
  4. 部門滿意度低落(改善專案)
end note

@enduml

這張整合型系統架構圖呈現完整的團隊管理分析與干預流程。資料收集模組整合多個系統的資料,人資管理系統提供員工基本資料、任期、職位變動歷史,專案管理系統記錄專案分配、任務狀態與完成情況,時間追蹤系統收集工作時數與加班記錄,績效評估系統儲存定期考核結果與目標達成狀況,問卷調查平台定期收集滿意度與投入度評分。這些異質資料匯集至整合資料倉儲進行統一管理與歷史追蹤。

分析引擎包含五個核心模組各司其職。滿意度分析處理問卷資料計算各維度分數並識別低分面向,投入度分析評估員工的活力奉獻與專注程度,任期分析追蹤員工留任時間與流動率趨勢,工作量分析評估專案與任務分配的平衡性,風險識別模組整合前四個模組的輸出識別需要關注的員工與團隊。風險類型包含雙低風險即滿意度與投入度皆低的員工具有高離職可能性,流失風險指資深員工滿意度下降可能導致關鍵知識流失,倦怠風險代表員工長期承受高工作量出現疲勞徵兆,停滯風險則是員工感覺缺乏成長機會與職涯發展。

視覺化儀表板提供三個層級的監控介面。部門健康儀表板呈現各部門的整體指標包含平均滿意度投入度、任期分佈、工作量統計與高風險員工比例,協助主管掌握部門狀態並與其他部門比較。個人發展儀表板展示每位員工的滿意度投入度歷史趨勢、績效表現、職涯發展路徑與培訓記錄,支援個人化的發展規劃。風險預警儀表板以紅黃綠燈號標示不同風險等級,列出需要立即關注的高風險員工與團隊,並提供風險原因分析。行動追蹤儀表板記錄針對風險員工採取的干預措施、執行進度與成效評估,確保行動計畫落實。

干預行動模組提供系統化的問題解決機制。一對一面談是最直接的溝通方式,主管與員工深入討論工作困擾與職涯期望,面談記錄回饋至系統追蹤問題解決進度。職涯輔導針對感到停滯的員工提供發展建議,包含內部轉調機會、晉升路徑規劃、跨部門專案參與等選項。培訓發展根據員工需求與組織需要安排技能訓練、領導力培養或專業認證課程。薪酬調整處理因薪資不滿而產生的離職風險,系統根據市場薪資水準與個人績效提供調薪建議。工作重新設計解決工作量失衡或工作內容單調問題,透過任務重分配、職責擴展或工作輪調增加工作豐富性。所有干預行動的記錄回饋至資料倉儲,累積組織學習並評估不同干預措施的有效性。

人力資源經理負責整體系統運作與風險預警回應,部門主管使用儀表板監控團隊狀態並執行干預行動,高階主管檢視跨部門摘要報告制定組織層級的人才策略。這種多層級的分析與干預機制確保問題能夠及時發現並得到適當處理,從資料收集、分析、預警到行動形成完整的閉環管理系統,持續優化組織的人力資源管理效能。

資料驅動的團隊管理方法為人力資源部門提供科學的決策支援,透過系統性收集員工滿意度與投入度資料並結合任期與工作量分析,管理者能夠全面掌握團隊健康狀態。統計分析揭示部門間的差異與各維度的相對表現,協助識別需要改善的優先領域。視覺化工具使複雜的資料變得易於理解,支援快速的決策制定。風險識別機制提前標示潛在的人才流失與團隊問題,讓管理者有時間採取預防措施。然而資料分析只是工具而非目的,真正的價值在於基於洞察採取有效的行動。建議企業建立定期的資料檢視機制如每季的團隊健康檢查,將資料分析結果轉化為具體的改善計畫如培訓專案、流程優化或文化變革,追蹤干預措施的成效並持續調整,最重要的是培養資料驅動的管理文化讓各層級管理者習慣運用資料支援決策。透過結合量化資料與質性洞察、短期干預與長期策略、個人關懷與組織目標,企業能夠建構健康高效的團隊並實現可持續的組織發展。