Skip to content

Instantly share code, notes, and snippets.

@kdmsnr
Last active July 25, 2023 14:26
Show Gist options
  • Save kdmsnr/9479fb9935e51e4bfab763b9a0ae6485 to your computer and use it in GitHub Desktop.
Save kdmsnr/9479fb9935e51e4bfab763b9a0ae6485 to your computer and use it in GitHub Desktop.
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