Pythonマスター講座:Pandasを使って従業員データを分析してみると

## 1. はじめに：データ分析ライブラリの概要

従業員管理におけるデータ分析は、効率的な意思決定と組織の成長に不可欠です。本記事では、Pandas、Matplotlib、Seaborn、NumPyという強力なPythonライブラリを活用して、従業員データを分析し可視化する方法を学びます。これらのライブラリは、データの操作、数値計算、そして美しいグラフの作成を可能にし、人事部門の業務を大幅に効率化します。

以下のコードで必要なライブラリをインポートしましょう：

```python
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np

# 警告メッセージを非表示にする
import warnings
warnings.filterwarnings('ignore')

# グラフのスタイルを設定
plt.style.use('seaborn')
```

## 2. データの読み込みと基本的な操作

まず、CSVファイルから従業員データを読み込み、基本的な情報を確認します。Pandasを使用すると、大量のデータを簡単に扱うことができます。

```python
# CSVファイルからデータを読み込む
df = pd.read_csv('employee_data.csv')

# データの最初の5行を表示
print(df.head())

# データの基本情報を表示
print(df.info())

# 数値データの基本統計量を表示
print(df.describe())
```

`employee_data.csv`の中身はこちらです。

```
employee_id,first_name,last_name,age,gender,department,job_title,salary,years_of_service,performance_score,hire_date
1,佐藤,太郎,35,男性,営業部,営業担当,5500000,5,3.8,2018-04-01
2,鈴木,花子,42,女性,マーケティング部,マーケティングマネージャー,7500000,8,4.2,2015-07-15
3,高橋,一郎,28,男性,IT部,ソフトウェア開発者,6500000,3,4.0,2020-01-10
4,田中,美咲,31,女性,人事部,人事スペシャリスト,5800000,4,3.9,2019-09-01
5,渡辺,健太,45,男性,財務部,財務アナリスト,7000000,10,4.1,2013-11-20
6,伊藤,さくら,39,女性,運営部,運営マネージャー,8000000,7,4.3,2016-03-05
7,山本,浩二,33,男性,営業部,営業マネージャー,7200000,6,4.0,2017-06-12
8,中村,由美,29,女性,マーケティング部,マーケティングスペシャリスト,5200000,2,3.7,2021-08-01
9,小林,誠,37,男性,IT部,ITマネージャー,8500000,9,4.4,2014-02-28
10,加藤,恵子,41,女性,人事部,人事マネージャー,7800000,11,4.2,2012-10-15
11,吉田,健太郎,30,男性,財務部,会計士,6000000,4,3.8,2019-05-20
12,山田,美香,36,女性,運営部,プロジェクトコーディネーター,6200000,5,3.9,2018-07-01
13,佐々木,隆,44,男性,営業部,営業ディレクター,9500000,12,4.5,2011-12-01
14,山口,愛,32,女性,マーケティング部,コンテンツクリエイター,5600000,3,3.8,2020-03-15
15,松本,大輔,38,男性,IT部,ネットワーク管理者,6800000,7,4.1,2016-09-01
16,井上,真理,34,女性,人事部,リクルーター,5900000,5,3.9,2018-11-10
17,木村,俊介,40,男性,財務部,財務マネージャー,8200000,9,4.3,2014-08-20
18,林,美穂,31,女性,運営部,運営アナリスト,6100000,4,3.8,2019-10-01
19,清水,拓也,36,男性,営業部,アカウントエグゼクティブ,7000000,6,4.0,2017-04-15
20,斎藤,優子,33,女性,マーケティング部,デジタルマーケティングスペシャリスト,5800000,4,3.9,2019-06-01
21,近藤,博,47,男性,IT部,システムアーキテクト,9200000,15,4.6,2008-03-01
22,石井,麻衣,39,女性,人事部,研修コーディネーター,6300000,7,4.0,2016-05-10
23,前田,健一,42,男性,財務部,シニアアカウンタント,7500000,10,4.2,2013-09-15
24,遠藤,直美,35,女性,運営部,サプライチェーンマネージャー,7600000,8,4.1,2015-11-01
25,藤田,翔太,29,男性,営業部,ジュニアセールスレップ,4800000,1,3.5,2022-04-01
26,青木,美咲,37,女性,マーケティング部,ブランドマネージャー,7200000,9,4.2,2014-10-15
27,上田,健太郎,43,男性,IT部,データベース管理者,7800000,11,4.3,2012-08-01
28,福田,理恵,31,女性,人事部,福利厚生スペシャリスト,5700000,3,3.8,2020-07-01
29,中島,洋平,39,男性,財務部,財務コントローラー,8800000,12,4.4,2011-06-15
30,原田,香織,34,女性,運営部,品質保証アナリスト,6400000,5,3.9,2018-09-01
31,柴田,隆之,45,男性,営業部,地域営業マネージャー,8500000,13,4.5,2010-05-10
32,竹内,明美,32,女性,マーケティング部,広報スペシャリスト,5900000,4,3.8,2019-11-01
33,久保,大樹,36,男性,IT部,DevOpsエンジニア,7600000,7,4.1,2016-10-15
34,岡田,由紀,41,女性,人事部,報酬アナリスト,6900000,9,4.0,2014-12-01
35,野村,健一,38,男性,財務部,投資アナリスト,7200000,8,4.2,2015-08-15
36,松田,真理子,33,女性,運営部,物流コーディネーター,6000000,5,3.9,2018-06-01
37,菊地,浩二,44,男性,営業部,ビジネス開発マネージャー,8200000,11,4.3,2012-04-01
38,大西,美香,30,女性,マーケティング部,ソーシャルメディアマネージャー,5800000,3,3.8,2020-09-15
39,長谷川,隆,37,男性,IT部,情報セキュリティアナリスト,7400000,6,4.0,2017-07-01
40,浜田,由美子,42,女性,人事部,従業員関係スペシャリスト,7100000,10,4.1,2013-05-15
41,森,健太郎,35,男性,財務部,予算アナリスト,6700000,7,4.0,2016-11-01
42,阿部,真由美,39,女性,運営部,プロセス改善スペシャリスト,7300000,8,4.2,2015-03-15
43,橋本,雄一,46,男性,営業部,主要アカウントマネージャー,8800000,14,4.5,2009-08-01
44,内田,美穂,33,女性,マーケティング部,市場調査アナリスト,6200000,5,3.9,2018-10-15
45,宮崎,健太,40,男性,IT部,クラウドソリューションアーキテクト,8600000,9,4.3,2014-06-01
46,小川,真理,37,女性,人事部,人材獲得スペシャリスト,6500000,6,4.0,2017-09-15
47,西田,隆司,41,男性,財務部,リスク管理アナリスト,7600000,10,4.2,2013-07-01
48,酒井,直子,34,女性,運営部,在庫管理スペシャリスト,5900000,4,3.8,2019-08-15
49,北村,健太,43,男性,営業部,インサイドセールスレップ,6800000,8,4.1,2015-05-01
50,中田,美香,36,女性,マーケティング部,マーケティングコミュニケーションスペシャリスト,6400000,7,4.0,2016-07-15
```

このコードでは、`read_csv()`関数でCSVファイルを読み込み、`head()`メソッドでデータの先頭を確認します。`info()`メソッドはデータの構造を、`describe()`メソッドは数値データの統計情報を提供します。これにより、データセットの概要を素早く把握できます。

## 3. データのクリーニングと前処理

データ分析の精度を高めるには、欠損値の処理や不要なデータの削除が重要です。Pandasを使用して、これらの作業を効率的に行うことができます。

```python
# 欠損値の確認
print(df.isnull().sum())

# 欠損値を含む行を削除
df_cleaned = df.dropna()

# 特定の列の欠損値を平均値で埋める
df['salary'] = df['salary'].fillna(df['salary'].mean())

# 重複データの削除
df_unique = df.drop_duplicates()

# データ型の変換（例：入社日を日付型に）
df['hire_date'] = pd.to_datetime(df['hire_date'])
```

このコードでは、`isnull()`と`sum()`メソッドで欠損値を確認し、`dropna()`で欠損値を含む行を削除します。`fillna()`メソッドは欠損値を特定の値（この場合は平均値）で埋めます。`drop_duplicates()`は重複行を削除し、`to_datetime()`は文字列を日付型に変換します。

## 4. 基本的な統計分析

従業員データの基本的な統計分析は、組織の現状を理解する上で重要です。Pandasを使用して、様々な統計量を簡単に計算できます。

```python
# 部門ごとの平均給与を計算
avg_salary_by_dept = df.groupby('department')['salary'].mean()
print("部門ごとの平均給与:\n", avg_salary_by_dept)

# 年齢と給与の相関係数を計算
correlation = df['age'].corr(df['salary'])
print(f"年齢と給与の相関係数: {correlation:.2f}")

# 勤続年数の中央値を計算
median_tenure = df['years_of_service'].median()
print(f"勤続年数の中央値: {median_tenure:.1f}年")

# 給与の四分位数を計算
salary_quartiles = df['salary'].quantile([0.25, 0.5, 0.75])
print("給与の四分位数:\n", salary_quartiles)
```

このコードでは、`groupby()`メソッドを使用して部門ごとの平均給与を計算し、`corr()`メソッドで年齢と給与の相関を求めます。`median()`で中央値を、`quantile()`で四分位数を計算します。これらの統計量は、従業員データの傾向を把握するのに役立ちます。

## 5. データの可視化：棒グラフ

Matplotlibを使用して、従業員データを視覚的に表現することができます。棒グラフは、カテゴリ別のデータを比較するのに適しています。

```python
# 部門ごとの従業員数を棒グラフで表示
dept_counts = df['department'].value_counts()

plt.figure(figsize=(12, 6))
dept_counts.plot(kind='bar')
plt.title('部門ごとの従業員数')
plt.xlabel('部門')
plt.ylabel('従業員数')
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()

# 性別ごとの平均給与を棒グラフで表示
gender_salary = df.groupby('gender')['salary'].mean()

plt.figure(figsize=(8, 6))
gender_salary.plot(kind='bar')
plt.title('性別ごとの平均給与')
plt.xlabel('性別')
plt.ylabel('平均給与')
plt.xticks(rotation=0)
plt.tight_layout()
plt.show()
```

このコードでは、`value_counts()`メソッドで部門ごとの従業員数を計算し、`plot(kind='bar')`で棒グラフを作成します。`figsize`でグラフのサイズを、`title`、`xlabel`、`ylabel`でタイトルと軸ラベルを設定します。`xticks(rotation=45)`でx軸のラベルを45度回転させ、読みやすくしています。

## 6. データの可視化：折れ線グラフ

折れ線グラフは、時系列データの傾向を可視化するのに適しています。従業員の給与推移や採用トレンドなどを表現できます。

```python
# 年ごとの採用数の推移を折れ線グラフで表示
df['hire_year'] = df['hire_date'].dt.year
yearly_hires = df['hire_year'].value_counts().sort_index()

plt.figure(figsize=(12, 6))
plt.plot(yearly_hires.index, yearly_hires.values, marker='o')
plt.title('年ごとの採用数の推移')
plt.xlabel('年')
plt.ylabel('採用数')
plt.grid(True)
plt.tight_layout()
plt.show()

# 勤続年数と給与の関係を折れ線グラフで表示
salary_by_tenure = df.groupby('years_of_service')['salary'].mean()

plt.figure(figsize=(12, 6))
plt.plot(salary_by_tenure.index, salary_by_tenure.values, marker='o')
plt.title('勤続年数と平均給与の関係')
plt.xlabel('勤続年数')
plt.ylabel('平均給与')
plt.grid(True)
plt.tight_layout()
plt.show()
```

このコードでは、`dt.year`属性を使用して採用日から年を抽出し、`value_counts()`で年ごとの採用数を計算します。`plot()`関数で折れ線グラフを作成し、`marker='o'`でデータポイントを強調しています。`grid(True)`でグリッド線を追加し、データの読み取りを容易にしています。

## 7. データの可視化：散布図

散布図は、2つの数値変数間の関係を視覚化するのに適しています。Seabornを使用すると、美しい散布図を簡単に作成できます。

```python
# 年齢と給与の関係を散布図で表示
plt.figure(figsize=(12, 8))
sns.scatterplot(x='age', y='salary', hue='gender', data=df)
plt.title('年齢と給与の関係（性別ごと）')
plt.xlabel('年齢')
plt.ylabel('給与')
plt.legend(title='性別')
plt.tight_layout()
plt.show()

# 勤続年数とパフォーマンス評価の関係を散布図で表示
plt.figure(figsize=(12, 8))
sns.scatterplot(x='years_of_service', y='performance_score', hue='department', data=df)
plt.title('勤続年数とパフォーマンス評価の関係（部門ごと）')
plt.xlabel('勤続年数')
plt.ylabel('パフォーマンス評価')
plt.legend(title='部門', bbox_to_anchor=(1.05, 1), loc='upper left')
plt.tight_layout()
plt.show()
```

このコードでは、Seabornの`scatterplot()`関数を使用して散布図を作成します。`x`と`y`パラメータで軸を指定し、`hue`パラメータでポイントの色分けを行います。`legend()`関数で凡例を追加し、`bbox_to_anchor`と`loc`パラメータで凡例の位置を調整しています。

## 8. データの可視化：ヒストグラム

ヒストグラムは、数値データの分布を視覚化するのに適しています。Seabornの`histplot()`関数を使用すると、美しいヒストグラムを簡単に作成できます。

```python
# 給与分布のヒストグラム
plt.figure(figsize=(12, 6))
sns.histplot(data=df, x='salary', kde=True)
plt.title('給与分布')
plt.xlabel('給与')
plt.ylabel('頻度')
plt.tight_layout()
plt.show()

# 年齢分布のヒストグラム（部門ごと）
plt.figure(figsize=(12, 6))
sns.histplot(data=df, x='age', hue='department', multiple='stack')
plt.title('部門ごとの年齢分布')
plt.xlabel('年齢')
plt.ylabel('頻度')
plt.legend(title='部門', bbox_to_anchor=(1.05, 1), loc='upper left')
plt.tight_layout()
plt.show()
```

このコードでは、`histplot()`関数を使用してヒストグラムを作成します。`kde=True`オプションでカーネル密度推定曲線を追加し、分布の形状をより明確に表示しています。2つ目のヒストグラムでは、`hue`パラメータで部門ごとに色分けし、`multiple='stack'`オプションで積み上げ表示にしています。

## 9. データの可視化：箱ひげ図

箱ひげ図は、データの分布や外れ値を視覚化するのに適しています。Seabornの`boxplot()`関数を使用して、簡単に作成できます。

```python
# 部門ごとの給与分布を箱ひげ図で表示
plt.figure(figsize=(12, 6))
sns.boxplot(x='department', y='salary', data=df)
plt.title('部門ごとの給与分布')
plt.xlabel('部門')
plt.ylabel('給与')
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()

# 性別と部門ごとのパフォーマンス評価を箱ひげ図で表示
plt.figure(figsize=(14, 6))
sns.boxplot(x='department', y='performance_score', hue='gender', data=df)
plt.title('部門と性別ごとのパフォーマンス評価分布')
plt.xlabel('部門')
plt.ylabel('パフォーマンス評価')
plt.xticks(rotation=45)
plt.legend(title='性別')
plt.tight_layout()
plt.show()
```

このコードでは、`boxplot()`関数を使用して箱ひげ図を作成します。1つ目のグラフでは部門ごとの給与分布を、2つ目のグラフでは部門と性別ごとのパフォーマンス評価分布を表示しています。`hue`パラメータを使用することで、1つのグラフ内で複数のカテゴリを比較できます。

## 10. 相関分析とヒートマップ

変数間の相関を分析することで、従業員のさまざまな特性間の関係を理解できます。Seabornの`heatmap()`関数を使用して、相関係数をヒートマップで視覚化します。

```python
# 数値データの相関係数を計算
correlation_matrix = df[['age', 'salary', 'years_of_service', 'performance_score']].corr()

# ヒートマップで相関係数を可視化
plt.figure(figsize=(10, 8))
sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm', vmin=-1, vmax=1, center=0)
plt.title('従業員データの相関係数ヒートマップ')
plt.tight_layout()
plt.show()
```

このコードでは、まず`corr()`メソッドで相関係数を計算し、その結果を`heatmap()`関数でヒートマップとして表示します。`annot=True`オプションで各セルに相関係数の値を表示し、`cmap=coolwarm'`オプションでカラーマップを設定しています。`vmin`、`vmax`、`center`パラメータで色の範囲と中心を調整し、相関の強さを明確に表現しています。

## 11. 時系列分析：従業員の成長トレンド

時系列データを分析することで、従業員の成長や組織の変化を追跡できます。Pandasの日付機能とMatplotlibを組み合わせて、時間の経過に伴う変化を可視化します。

```python
# 入社日からの経過年数を計算
df['years_since_hire'] = (pd.Timestamp.now() - df['hire_date']).astype('<m8[Y]')

# 経過年数とパフォーマンス評価の関係をプロット
plt.figure(figsize=(12, 6))
sns.regplot(x='years_since_hire', y='performance_score', data=df, scatter_kws={'alpha':0.5})
plt.title('入社からの経過年数とパフォーマンス評価の関係')
plt.xlabel('入社からの経過年数')
plt.ylabel('パフォーマンス評価')
plt.tight_layout()
plt.show()

# 年ごとの平均給与の推移
yearly_avg_salary = df.groupby(df['hire_date'].dt.year)['salary'].mean()

plt.figure(figsize=(12, 6))
plt.plot(yearly_avg_salary.index, yearly_avg_salary.values, marker='o')
plt.title('採用年別の平均給与推移')
plt.xlabel('採用年')
plt.ylabel('平均給与')
plt.grid(True)
plt.tight_layout()
plt.show()
```

このコードでは、まず`Timestamp.now()`と`astype('<m8[Y]')`を使用して入社からの経過年数を計算します。`regplot()`関数で散布図と回帰直線を同時に描画し、経過年数とパフォーマンスの関係を視覚化しています。また、`groupby()`と`dt.year`を使用して年ごとの平均給与を計算し、折れ線グラフで表示しています。

## 12. 部門別分析：パフォーマンスと給与の関係

部門ごとの分析は、組織内の異なる部門の特性を理解するのに役立ちます。Seabornの`lmplot()`関数を使用して、部門別のパフォーマンスと給与の関係を可視化します。

```python
# 部門ごとのパフォーマンスと給与の関係をプロット
plt.figure(figsize=(15, 10))
sns.lmplot(x='performance_score', y='salary', hue='department', data=df, height=8, aspect=1.5, scatter_kws={'alpha':0.5})
plt.title('部門別：パフォーマンス評価と給与の関係')
plt.xlabel('パフォーマンス評価')
plt.ylabel('給与')
plt.tight_layout()
plt.show()

# 部門ごとの平均パフォーマンスと平均給与を計算
dept_performance = df.groupby('department')['performance_score'].mean()
dept_salary = df.groupby('department')['salary'].mean()

# 散布図で表示
plt.figure(figsize=(12, 8))
plt.scatter(dept_performance, dept_salary)
for i, dept in enumerate(dept_performance.index):
    plt.annotate(dept, (dept_performance[i], dept_salary[i]))
plt.title('部門別：平均パフォーマンスと平均給与の関係')
plt.xlabel('平均パフォーマンス評価')
plt.ylabel('平均給与')
plt.grid(True)
plt.tight_layout()
plt.show()
```

このコードでは、`lmplot()`関数を使用して部門ごとのパフォーマンスと給与の関係を散布図と回帰直線で表示しています。また、部門ごとの平均値を計算し、`scatter()`関数で散布図を作成しています。`annotate()`関数を使用して、各点に部門名をラベル付けしています。

## 13. 従業員セグメンテーション：K-means クラスタリング

従業員をグループ化することで、異なる特性を持つ従業員グループを識別できます。NumPyとScikit-learnを使用してK-meansクラスタリングを実行し、結果を可視化します。

```python
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler

# クラスタリングに使用する特徴量を選択
features = ['age', 'salary', 'performance_score', 'years_of_service']
X = df[features]

# データの標準化
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# K-meansクラスタリングの実行
kmeans = KMeans(n_clusters=3, random_state=42)
df['cluster'] = kmeans.fit_predict(X_scaled)

# クラスタリング結果の可視化
plt.figure(figsize=(12, 8))
scatter = plt.scatter(df['age'], df['salary'], c=df['cluster'], cmap='viridis')
plt.title('従業員クラスタリング：年齢 vs 給与')
plt.xlabel('年齢')
plt.ylabel('給与')
plt.colorbar(scatter)
plt.tight_layout()
plt.show()

# クラスタごとの特徴を表示
cluster_means = df.groupby('cluster')[features].mean()
print("クラスタごとの平均値:\n", cluster_means)
```

このコードでは、まず`StandardScaler`を使用してデータを標準化し、`KMeans`クラスを使用してクラスタリングを実行します。結果を散布図で可視化し、各クラスタの特徴を平均値で表示しています。これにより、異なる特性を持つ従業員グループを識別できます。

## 14. 予測モデル：給与予測

機械学習モデルを使用して、従業員の特性に基づいて給与を予測できます。ここでは、線形回帰モデルを使用して簡単な給与予測モデルを作成します。

```python
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score

# 特徴量とターゲット変数の準備
X = df[['age', 'years_of_service', 'performance_score']]
y = df['salary']

# データを訓練セットとテストセットに分割
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# モデルの訓練
model = LinearRegression()
model.fit(X_train, y_train)

# テストデータで予測
y_pred = model.predict(X_test)

# モデルの評価
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)

print(f"平均二乗誤差: {mse:.2f}")
print(f"決定係数: {r2:.2f}")

# 実際の給与と予測給与の散布図
plt.figure(figsize=(10, 6))
plt.scatter(y_test, y_pred, alpha=0.5)
plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], 'r--', lw=2)
plt.xlabel('実際の給与')
plt.ylabel('予測給与')
plt.title('給与予測：実際 vs 予測')
plt.tight_layout()
plt.show()
```

このコードでは、`LinearRegression`クラスを使用して線形回帰モデルを訓練し、給与を予測しています。`train_test_split`関数でデータを訓練セットとテストセットに分割し、モデルの性能を評価しています。最後に、実際の給与と予測給与の散布図を作成して、モデルの予測精度を視覚的に確認しています。

## 15. レポート生成と自動化

データ分析の結果を定期的にレポートとして生成することで、人事部門や経営陣に有用な情報を提供できます。Pythonを使用してレポート生成プロセスを自動化する例を示します。

```python
import datetime

def generate_employee_report(df):
    report = f"従業員データ分析レポート - {datetime.date.today()}\n\n"
    
    # 基本統計
    report += "1. 基本統計\n"
    report += f"総従業員数: {len(df)}\n"
    report += f"平均年齢: {df['age'].mean():.1f}歳\n"
    report += f"平均給与: ¥{df['salary'].mean():,.0f}\n"
    report += f"平均勤続年数: {df['years_of_service'].mean():.1f}年\n\n"
    
    # 部門別統計
    report += "2. 部門別統計\n"
    dept_stats = df.groupby('department').agg({
        'employee_id': 'count',
        'salary': 'mean',
        'performance_score': 'mean'
    }).rename(columns={'employee_id': '従業員数', 'salary': '平均給与', 'performance_score': '平均パフォーマンス'})
    
    report += dept_stats.to_string()
    report += "\n\n"
    
    # 給与分布
    report += "3. 給与分布\n"
    salary_quartiles = df['salary'].quantile([0.25, 0.5, 0.75])
    report += f"第1四分位数: ¥{salary_quartiles[0.25]:,.0f}\n"
    report += f"中央値: ¥{salary_quartiles[0.5]:,.0f}\n"
    report += f"第3四分位数: ¥{salary_quartiles[0.75]:,.0f}\n\n"
    
    # 最高パフォーマンス従業員
    report += "4. 最高パフォーマンス従業員（上位5名）\n"
    top_performers = df.nlargest(5, 'performance_score')[['employee_id', 'department', 'performance_score']]
    report += top_performers.to_string(index=False)
    
    return report

# レポートの生成と保存
report_text = generate_employee_report(df)
with open('employee_report.txt', 'w', encoding='utf-8') as f:
    f.write(report_text)

print("レポートが生成され、'employee_report.txt'として保存されました。")
```

このコードでは、`generate_employee_report`関数を定義して、従業員データの主要な統計情報をテキスト形式でまとめています。基本統計、部門別統計、給与分布、最高パフォーマンス従業員などの情報を含むレポートを自動生成し、テキストファイルとして保存します。このスクリプトを定期的に実行することで、最新の従業員データ分析レポートを簡単に作成できます。

以上で、従業員管理のためのPandas、Matplotlib、Seaborn、NumPyを使用したデータ分析と可視化の詳細な解説を終わります。これらのツールと技術を活用することで、人事データからより深い洞察を得ることができ、効果的な意思決定をサポートすることができます。