Last active
July 25, 2023 14:26
-
-
Save kdmsnr/9479fb9935e51e4bfab763b9a0ae6485 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from sklearn.cluster import KMeans | |
from sklearn.preprocessing import MinMaxScaler | |
import numpy as np | |
import random | |
# メンバーの生成(50人、ランダムな属性) | |
# カテゴリカルな属性の場合は、https://gist.github.com/kdmsnr/ed71e9dbbf228b3a03cca99183484ac2 を参照する | |
members = [ | |
{"name": f"member{i}", "attributes": [random.randint(1, 10), random.randint(1, 10), random.randint(1, 10)]} | |
for i in range(50) | |
] | |
# 属性のみを取り出し、numpy配列に変換 | |
attributes = np.array([member["attributes"] for member in members]) | |
# 属性の正規化(0から1の範囲にスケーリング) | |
scaler = MinMaxScaler() | |
normalized_attributes = scaler.fit_transform(attributes) | |
# 重み付け | |
weights = np.array([2, 1, 1]) # 属性1には重み2を、属性2と属性3には重み1を設定 | |
weighted_attributes = normalized_attributes * weights | |
# チームの最大メンバー数 | |
max_members_per_team = 5 | |
# メンバーの総数をチームの上限人数で割った数をクラスタの数として設定 | |
n_clusters = len(members) // max_members_per_team | |
# K-meansクラスタリングを行う | |
kmeans = KMeans(n_clusters=n_clusters, n_init=10, random_state=0).fit(weighted_attributes) | |
# 各メンバーがどのクラスタに属するかを取得 | |
labels = kmeans.labels_ | |
# クラスタごとのメンバーリストを作成 | |
clusters = [[] for _ in range(n_clusters)] | |
for member, label in zip(members, labels): | |
clusters[label].append(member) | |
# 各クラスタから順にメンバーを選び、各チームに割り当てていく | |
teams = [[] for _ in range(n_clusters)] | |
team_index = 0 | |
for cluster in clusters: | |
for member in cluster: | |
# チームのメンバー数が最大メンバー数を超えたら次のチームに進む | |
while len(teams[team_index]) >= max_members_per_team: | |
team_index = (team_index + 1) % n_clusters | |
teams[team_index].append(member) | |
team_index = (team_index + 1) % n_clusters | |
# チームのリストを出力 | |
for i, team in enumerate(teams, 1): | |
print(f"Team {i}:") | |
for member in team: | |
print(f" {member['name']} ({', '.join(map(str, member['attributes']))})") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment