Search

k-means Clustering

K-means 알고리즘은 주어진 데이터를 k개의 클러스터로 묶는 클러스터링 알고리즘입니다.
기계 학습에서는 비지도 학습에 속하며, 클러스터링 알고리즘에서 중요한 역할을 차지합니다.
K-means 알고리즘은 다음과 같은 절차로 작동합니다:
1.
랜덤으로 선택된 k개의 데이터를 기준으로, 가장 가까운 데이터 포인트들을 동일한 클러스터로 할당합니다.
2.
각 클러스터의 중심점을 계산하고, 해당 중심점을 기준으로 다시 클러스터를 재조정합니다.
3.
클러스터 중심점이 더 이상 변경되지 않을 때까지 이 과정을 반복하여 최적의 클러스터를 찾습니다.
K-means 알고리즘은 단순하고 효율적이지만, 클러스터 수 k를 사전에 정해야 하는 특징이 있습니다.
Scikit-learn과 같은 머신러닝 라이브러리를 사용하면 K-means 알고리즘을 직접 구현할 필요 없이 쉽게 클러스터링을 적용할 수 있습니다.
예를 들어, 100명의 고객의 위도와 경도 데이터를 이용해 최적의 창고 위치 3개를 선정하는 문제에서 K-means 클러스터링 알고리즘을 사용할 수 있습니다. 고객의 위치 데이터를 3개의 클러스터로 묶고, 각 클러스터의 중심점을 창고 위치로 설정하는 방식입니다.
전체 소스
from sklearn.cluster import KMeans import pandas as pd import folium def main(): #Warehouse 갯수 k = 3 restaurantDf = makeInput() locList = [[0]*2 for i in range(len(restaurantDf))] for idx, row in restaurantDf.iterrows(): locList[idx][0] = float(row['LAT']) locList[idx][1] = float(row['LON']) #Clustering clusteringModel = KMeans(n_clusters=k, init='k-means++') clusteringModel.fit(locList) map = folium.Map(location=[37.1382167251, 127.3114503751]) for i in range(len(restaurantDf)): color = "" if clusteringModel.labels_[i] == 0: color = "red" if clusteringModel.labels_[i] == 1: color = "blue" if clusteringModel.labels_[i] == 2: color = "orange" folium.Marker([locList[i][0], locList[i][1]], icon = folium.Icon(color=color)).add_to(map) #Warehouse Locations for element in clusteringModel.cluster_centers_: folium.Marker([element[0], element[1]], icon=folium.Icon(color='gray',icon='star')).add_to(map) map.save('kmeansResult.html') def makeInput(): restaurant = [ ['LOC_0001', '고양시', '37.6699528060', '126.8554585712'], ['LOC_0002', '고양시', '37.6971520856', '126.8196849679'], ['LOC_0003', '고양시', '37.6737965993', '126.7754243376'], ['LOC_0004', '고양시', '37.6821145400', '126.7535463209'], ['LOC_0005', '과천시', '37.4277514160', '126.9920513446'], ['LOC_0006', '과천시', '37.4410791763', '127.0104554264'], ['LOC_0007', '광주시', '37.4992915278', '127.3027287142'], ['LOC_0008', '광주시', '37.3456586222', '127.1817497660'], ['LOC_0009', '광주시', '37.3398340658', '127.3356487393'], ['LOC_0010', '광주시', '37.4988495961', '127.3025714906'], ['LOC_0011', '광주시', '37.4771884535', '127.1821089446'], ['LOC_0012', '광주시', '37.3969132174', '127.2335940567'], ['LOC_0013', '광주시', '37.4778648562', '127.3511585039'], ['LOC_0014', '김포시', '37.6598939546', '126.6656656950'], ['LOC_0015', '김포시', '37.7312343266', '126.5260317627'], ['LOC_0016', '김포시', '37.6219227553', '126.7226238685'], ['LOC_0017', '남양주시', '37.7496438017', '127.2086783633'], ['LOC_0018', '남양주시', '37.6463075748', '127.3058545873'], ['LOC_0019', '남양주시', '37.7450001929', '127.2079587740'], ['LOC_0020', '남양주시', '37.6580785222', '127.2948606613'], ['LOC_0021', '남양주시', '37.7493163194', '127.2074650581'], ['LOC_0022', '동두천시', '37.9052438433', '127.0526923103'], ['LOC_0023', '동두천시', '37.9035354078', '127.0513831636'], ['LOC_0024', '동두천시', '37.9064954987', '127.0644013502'], ['LOC_0025', '동두천시', '37.8908018400', '127.0566123836'], ['LOC_0026', '동두천시', '37.9029587869', '127.0538094986'], ['LOC_0027', '부천시', '37.5035236772', '126.7620258315'], ['LOC_0028', '부천시', '37.5063329471', '126.7515325472'], ['LOC_0029', '부천시', '37.5147426141', '126.8138873897'], ['LOC_0030', '부천시', '37.5269360205', '126.8058649020'], ['LOC_0031', '부천시', '37.5030341284', '126.7805625009'], ['LOC_0032', '부천시', '37.5198204179', '126.7900314838'], ['LOC_0033', '부천시', '37.5238039668', '126.8097303400'], ['LOC_0034', '성남시', '37.3589256866', '127.1230193698'], ['LOC_0035', '성남시', '37.4212308831', '127.1016185455'], ['LOC_0036', '성남시', '37.4630729599', '127.1689498109'], ['LOC_0037', '성남시', '37.4615481492', '127.1558057480'], ['LOC_0038', '성남시', '37.4169832834', '127.1344363205'], ['LOC_0039', '수원시', '37.3062283022', '127.0006673650'], ['LOC_0040', '수원시', '37.2780234393', '127.0406385621'], ['LOC_0041', '수원시', '37.2876000885', '127.0167086820'], ['LOC_0042', '수원시', '37.2468926793', '127.0557111821'], ['LOC_0043', '수원시', '37.3069449243', '127.0147568265'], ['LOC_0044', '수원시', '37.2915640479', '127.0504732206'], ['LOC_0045', '수원시', '37.2730696429', '126.9723723275'], ['LOC_0046', '수원시', '37.2737747878', '127.0492142019'], ['LOC_0047', '수원시', '37.2817865208', '126.9724694093'], ['LOC_0048', '수원시', '37.2742267822', '127.0287166267'], ['LOC_0049', '수원시', '37.2581805115', '127.0328989333'], ['LOC_0050', '수원시', '37.2808998463', '126.9737502924'], ['LOC_0051', '수원시', '37.2587743497', '127.0303466174'], ['LOC_0052', '수원시', '37.2759603301', '127.0294390047'], ['LOC_0053', '수원시', '37.2665453057', '127.0062077815'], ['LOC_0054', '수원시', '37.2855805568', '126.9583188924'], ['LOC_0055', '수원시', '37.3149390687', '127.0014674565'], ['LOC_0056', '시흥시', '37.3859529890', '126.8401627128'], ['LOC_0057', '시흥시', '37.3473228929', '126.7329946337'], ['LOC_0058', '시흥시', '37.3513047782', '126.7229955822'], ['LOC_0059', '안산시', '37.3584852392', '126.8220989209'], ['LOC_0060', '안산시', '37.3360457748', '126.8502513353'], ['LOC_0061', '안산시', '37.2916416855', '126.8304611688'], ['LOC_0062', '안산시', '37.2825222625', '126.8470568385'], ['LOC_0063', '안산시', '37.3136027749', '126.8326702103'], ['LOC_0064', '안산시', '37.2937728261', '126.8722884714'], ['LOC_0065', '안산시', '37.3016898071', '126.8510886317'], ['LOC_0066', '안산시', '37.3189003905', '126.8274543496'], ['LOC_0067', '안성시', '37.0149959069', '127.2034579297'], ['LOC_0068', '안성시', '37.0367419397', '127.3714092154'], ['LOC_0069', '안양시', '37.4118002524', '126.9111036546'], ['LOC_0070', '안양시', '37.4179241084', '126.9191133005'], ['LOC_0071', '안양시', '37.4023181615', '126.9504858297'], ['LOC_0072', '안양시', '37.3940395160', '126.9613578915'], ['LOC_0073', '양주시', '37.7811156739', '127.0295140877'], ['LOC_0074', '양주시', '37.9076372438', '127.0065728358'], ['LOC_0075', '양주시', '37.7934964587', '127.0888606835'], ['LOC_0076', '양주시', '37.7849242640', '126.9937618394'], ['LOC_0077', '양주시', '37.7758002468', '126.9356283570'], ['LOC_0078', '양평군', '37.5352268162', '127.4671754909'], ['LOC_0079', '양평군', '37.4936033784', '127.4734269154'], ['LOC_0080', '여주시', '37.2145722794', '127.5802137871'], ['LOC_0081', '여주시', '37.2568394331', '127.6531870348'], ['LOC_0082', '여주시', '37.3185910690', '127.6485946251'], ['LOC_0083', '여주시', '37.4031973764', '127.5489582384'], ['LOC_0084', '연천군', '37.9897043024', '126.9206352812'], ['LOC_0085', '오산시', '37.1785982389', '127.0244560122'], ['LOC_0086', '오산시', '37.1774158872', '127.0240804100'], ['LOC_0087', '오산시', '37.1819471000', '127.0370076234'], ['LOC_0088', '오산시', '37.1868046144', '127.0120339544'], ['LOC_0089', '용인시', '37.3274739465', '127.1737784768'], ['LOC_0090', '용인시', '37.3231024501', '127.0454433819'], ['LOC_0091', '용인시', '37.3280639271', '127.0962075693'], ['LOC_0092', '용인시', '37.1382167251', '127.3114503751'], ['LOC_0093', '용인시', '37.2608624281', '127.2799286839'], ['LOC_0094', '용인시', '37.2224807513', '127.1033876860'], ['LOC_0095', '용인시', '37.2364221748', '127.2039907925'], ['LOC_0096', '용인시', '37.3303506971', '127.1283772195'], ['LOC_0097', '의왕시', '37.3497876203', '126.9626000497'], ['LOC_0098', '의왕시', '37.3519805191', '126.9711656591'], ['LOC_0099', '의정부시', '37.7497577536', '127.0717920267'], ['LOC_0100', '의정부시', '37.7455788063', '127.0904425858']] restaurantDf = pd.DataFrame(restaurant, columns = ['ID', 'CITY', 'LAT', 'LON']) return restaurantDf if __name__ == '__main__': main()
Python
복사
결과는 아래와 같습니다.
빨간색, 파란색, 오랜지색의 3개의 색상으로 구분된 클러스터를 확인 할 수 있습니다.
창고의 위치는 각 클러스터의 중심점으로 생각 할 수 있습니다.
Keyword: Logistics Optimization, 물류 최적화, 파이썬, Python, 선형계획법, Linear Programming, Google OR Tools
Reference