僕は、タイムトラッキングはそれなりに必要なものだと思っています。タイムトラッキングをすることで、自分の時間の使い方を客観的に見ることができます。
私の観察によれば、成果をあげる者は仕事からスタートしない。時間からスタートする。計画からもスタートしない。何に時間がとられているかを明らかにすることからスタートする。 (中略) 重要なことは、記録することである。記憶によってあとで記録するのではなく、ほぼリアルタイムに記録していくことである。
打ち合わせの時間というのは、毎日それなりの時間を必要とします。ではそれがどれだけの時間なのかというのは気になるところです。 僕は毎日の時間の使い方をTaskChute Cloudを用いて記録しています。そして、TaskChute Cloudでは日々の時間をTSVでエクスポートできます。
このTSVを用いて、2023年の打ち合わせの時間をChatGPTで解析してみました。
1日の打ち合わせ時間
では1日あたりの打ち合わせ時間はどの程度でしょうか。1日あたりのミーティング時間を月毎に集計した上で、95%信頼区間、および、その回帰直線を示したのが次のグラフです。
月間の打ち合わせ時間
月間の打ち合わせ時間は次のグラフのようになりました。
大体、月当たり80-100時間程度の打ち合わせ時間があるようです。
打ち合わせの時間とそれに対する考察
グラフを見れば容易に分かる通り、一年を通して徐々に打ち合わせ時間が増加しています。さまざまなプロジェクトへ関わるようになり、それに伴って打ち合わせ時間が増えているということでしょう。
ChatGPTを用いたデータ解析
今回初めてChatGPTを用いてデータを解析しました。 僕自身はTSVからミーティングのデータを抽出するところまでで、他については一切コーディングを行なっていません。僕が書いたのは以下の抽出ワンライナーだけです。
$ cat tasks_*.csv | iconv -futf16le -t utf8 | awk -F"\t" '$7=="MTG" { print $1, $15 }' > mtg.dat $ head -5 mtg.dat 2023-01-06 00:30 2023-01-06 00:14 2023-01-06 00:16 2023-01-06 00:32 2023-01-10 00:15
上記通り抽出したデータファイルをChatGPTにアップロードし、ChatGPTにグラフを書いてもらいながら、そのグラフを見て「こういう解析を行なってほしい」とか指示をしただけです。ここまで簡単にデータ解析が行えるとは思っていませんでした。
こういうデータの解析・可視化については、今年はより力を入れていかないといけない状況です。 その中で、ChatGPTは非常に有用なツールになりそうです。
ChatGPTのコード
import matplotlib.pyplot as plt import numpy as np from collections import defaultdict from datetime import timedelta from scipy.stats import linregress # データを処理する関数 def process_data(data): # 日付ごとに時間を合計 daily_totals = defaultdict(timedelta) for line in data: try: date_str, time_str = line.split() hours, minutes = map(int, time_str.split(':')) daily_totals[date_str] += timedelta(hours=hours, minutes=minutes) except ValueError: # 不正な形式の行は無視 continue # 月ごとに日ごとのミーティング時間の平均と標準偏差を計算 monthly_data = defaultdict(list) for date, total in daily_totals.items(): month = date[:7] # YYYY-MM hours = total.seconds / 3600 monthly_data[month].append(hours) monthly_averages = {} for month, hours_list in monthly_data.items(): average = np.mean(hours_list) std_dev = np.std(hours_list) n = len(hours_list) ci_95 = 1.96 * std_dev / np.sqrt(n) monthly_averages[month] = (average, ci_95) return monthly_averages # 回帰直線を計算する関数 def calculate_regression_line(months, averages): months_numeric = [int(month.split('-')[1]) for month in months] slope, intercept, _, _, _ = linregress(months_numeric, averages) regression_line = [slope * x + intercept for x in months_numeric] regression_equation = f"y = {slope:.2f}x + {intercept:.2f}" return regression_line, regression_equation # グラフを作成する関数 def create_plot(monthly_averages, output_file_path): months = list(monthly_averages.keys()) averages = [avg for avg, _ in monthly_averages.values()] lower_bounds = [avg - ci for avg, ci in monthly_averages.values()] upper_bounds = [avg + ci for avg, ci in monthly_averages.values()] regression_line, regression_equation = calculate_regression_line(months, averages) plt.figure(figsize=(12, 6)) plt.plot(months, averages, marker='o', label='Monthly Average Hours') plt.fill_between(months, lower_bounds, upper_bounds, color='gray', alpha=0.2, label='95% Confidence Interval') plt.plot(months, regression_line, color='red', label='Regression Line') plt.text(0.05, 0.95, f'Regression Line: {regression_equation}', transform=plt.gca().transAxes, color='red') plt.title('Monthly Average Meeting Hours with 95% Confidence Interval and Regression Line') plt.xlabel('Month') plt.ylabel('Average Hours') plt.ylim(bottom=0) plt.xticks(rotation=45) plt.legend() plt.grid(True) plt.tight_layout() plt.savefig(output_file_path) # データの読み込み with open('/mnt/data/mtg.dat', 'r') as file: data = file.readlines() # データ処理 monthly_averages = process_data(data) # グラフ作成と保存 output_file_path_refactored = '/mnt/data/monthly_average_meeting_hours_refactored.png' create_plot(monthly_averages, output_file_path_refactored) output_file_path_refactored