728x90
반응형
# dbscan density based clustering => 데이터 위치로부터 공간밀집도중심 클러스터 구분
noise 처리
import pandas as pd
import numpy as np
import folium
file_path = '2016_middle_shcool_graduates_report.xlsx'
df = pd.read_excel(file_path, engine='openpyxl', header = 0,)
pd.set_option('display.width', None)
pd.set_option('display.max_rows', 100)
pd.set_option('display.max_columns', 10)
pd.set_option('display.max_colwidth', 20)
df.columns.values
array(['지역', '학교명', '코드', '유형', '주야', '남학생수', '여학생수', '일반고', '특성화고',
'과학고', '외고_국제고', '예고_체고', '마이스터고', '자사고', '자공고', '기타진학', '취업',
'미상', '위도', '경도'], dtype=object)
df.head()
지역 학교명 코드 유형 주야 ... 기타진학 취업 미상 위도 경도
0 성북구 서울대학교사범대학부설중학교 3 국립 주간 ... 0.004 0 0.000 37.594942 127.038909
1 종로구 서울대학교사범대학부설여자중학교 3 국립 주간 ... 0.031 0 0.000 37.577473 127.003857
2 강남구 개원중학교 3 공립 주간 ... 0.009 0 0.003 37.491637 127.071744
3 강남구 개포중학교 3 공립 주간 ... 0.019 0 0.000 37.480439 127.062201
4 서초구 경원중학교 3 공립 주간 ... 0.010 0 0.000 37.510750 127.008900
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 415 entries, 0 to 414
Data columns (total 20 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 지역 415 non-null object
1 학교명 415 non-null object
2 코드 415 non-null int64
3 유형 415 non-null object
4 주야 415 non-null object
5 남학생수 415 non-null int64
6 여학생수 415 non-null int64
7 일반고 415 non-null float64
8 특성화고 415 non-null float64
9 과학고 415 non-null float64
10 외고_국제고 415 non-null float64
11 예고_체고 415 non-null float64
12 마이스터고 415 non-null float64
13 자사고 415 non-null float64
14 자공고 415 non-null float64
15 기타진학 415 non-null float64
16 취업 415 non-null int64
17 미상 415 non-null float64
18 위도 415 non-null float64
19 경도 415 non-null float64
dtypes: float64(12), int64(4), object(4)
memory usage: 65.0+ KB
# 중학교 정보 지도표시
import folium
import json
mschool_map = folium.Map(location=[37.55, 126.98], zoom_start=12)
for name, lat, lng in zip(df.학교명, df.위도, df.경도):
folium.CircleMarker([lat, lng],
radius = 5,
color = 'brown',
fill = True,
fill_color = 'coral',
fill_opacity = 0.7,
popup = name,
tooltip=name).add_to(mschool_map)
mschool_map.save('./seoul_mschool_loca.html')
# 전처리 : 지역, 유형, 주야 컬럼 원핫인코디변환
df['코드'].unique()
# array([3, 5, 9], dtype=int64)
from sklearn import preprocessing as pp
label_encoder = pp.LabelEncoder()
# 문자열 => 수치형, 숫자의 크기저오는 의미없음, 단순 종류표시
label_location = label_encoder.fit_transform(df['지역'])
label_code = label_encoder.fit_transform(df['코드'])
label_type = label_encoder.fit_transform(df['유형'])
label_day = label_encoder.fit_transform(df['주야'])
# onehot_encoder = pp.OneHotEncoder()
df['location'] = label_location
df['location'] = label_location
df['type'] = label_type
df['code'] = label_code
df['day'] = label_day
df.head()
지역 학교명 코드 유형 주야 ... 경도 location type code day
0 성북구 서울대학교사범대학부설중학교 3 국립 주간 ... 127.038909 16 1 0 0
1 종로구 서울대학교사범대학부설여자중학교 3 국립 주간 ... 127.003857 22 1 0 0
2 강남구 개원중학교 3 공립 주간 ... 127.071744 0 0 0 0
3 강남구 개포중학교 3 공립 주간 ... 127.062201 0 0 0 0
4 서초구 경원중학교 3 공립 주간 ... 127.008900 14 0 0 0
5 rows × 24 columns
label_location
array([16, 22, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 0,
14, 14, 14, 14, 14, 0, 0, 0, 14, 14, 0, 14, 0, 0, 0, 14, 14,
0, 14, 0, 0, 0, 0, 17, 17, 1, 17, 1, 1, 1, 1, 1, 17, 17,
17, 17, 1, 17, 17, 1, 17, 1, 1, 17, 17, 1, 1, 17, 17, 17, 17,
17, 17, 17, 17, 17, 17, 1, 1, 17, 17, 1, 1, 18, 3, 3, 3, 18,
3, 3, 3, 3, 3, 3, 18, 18, 3, 3, 3, 18, 3, 3, 3, 18, 18,
18, 18, 18, 3, 18, 18, 18, 18, 18, 18, 3, 18, 18, 3, 3, 7, 6,
6, 6, 6, 6, 7, 19, 19, 19, 19, 7, 19, 7, 7, 7, 7, 6, 7,
19, 19, 19, 19, 6, 6, 19, 6, 6, 6, 6, 19, 7, 10, 10, 10, 10,
10, 24, 24, 24, 24, 10, 24, 10, 24, 24, 24, 24, 24, 10, 10, 10, 10,
10, 24, 24, 10, 24, 24, 10, 10, 11, 11, 4, 4, 11, 4, 4, 4, 11,
4, 11, 11, 11, 11, 4, 4, 4, 11, 11, 11, 4, 11, 4, 4, 4, 4,
11, 4, 11, 11, 8, 8, 9, 8, 8, 8, 9, 9, 9, 9, 8, 8, 8,
8, 8, 8, 9, 8, 9, 9, 8, 8, 8, 8, 8, 8, 9, 8, 8, 8,
9, 9, 9, 8, 8, 8, 8, 12, 12, 21, 21, 21, 12, 13, 13, 21, 21,
13, 12, 21, 21, 12, 12, 12, 12, 21, 12, 13, 12, 13, 21, 21, 21, 13,
21, 21, 21, 13, 13, 13, 12, 13, 21, 21, 13, 13, 12, 5, 15, 5, 5,
5, 5, 15, 5, 5, 15, 5, 15, 15, 15, 5, 15, 5, 5, 15, 15, 2,
16, 16, 16, 16, 2, 16, 16, 2, 16, 16, 2, 2, 2, 2, 2, 16, 16,
2, 16, 16, 2, 16, 16, 2, 22, 23, 23, 22, 22, 23, 22, 20, 22, 20,
22, 20, 20, 11, 20, 20, 20, 20, 23, 23, 22, 23, 22, 20, 23, 23, 17,
2, 8, 4, 15, 15, 16, 5, 3, 9, 12, 3, 21, 18, 2, 13, 17, 1,
1, 21, 12, 6, 13, 16, 3, 16, 0, 17, 22, 12, 22, 3, 14, 0, 4,
5, 8, 11, 2, 9, 4, 8, 2, 6, 6, 13, 0, 1, 1, 17, 2, 21,
22, 16, 0, 7, 5, 23, 8])
#
from sklearn import cluster
#분석에 사용할 속성을 선택( 과고, 외고, 자사고)
columns_list = [9,10,13]
x = df.iloc[:,columns_list]
x = pp.StandardScaler().fit(x).transform(x)
print(x[:5])
[[ 2.02375287 -0.57972902 1.84751715]
[-0.65047921 1.84782097 -0.48039958]
[ 0.68663683 -0.14623795 0.11423133]
[ 1.28091062 -0.05953974 -0.20206171]
[ 0.38949993 -0.31963438 2.54336183]]
#dbscan 모형
# eps 반지름값, min_samples 클러슽터의 포인트가 최소 5개는 되어야 클러스터로 인정
dbm = cluster.DBSCAN(eps=0.2, min_samples = 5)
# 데이터 학습
dbm.fit(x)
cluster_label = dbm.labels_
print(cluster_label)
[-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 0 -1 -1 -1 -1 -1 -1 2 -1 0 -1
-1 -1 -1 -1 0 -1 -1 -1 -1 -1 0 3 -1 -1 -1 -1 -1 -1 -1 0 -1 -1 1 0
-1 -1 -1 0 -1 -1 -1 -1 0 -1 0 0 -1 -1 0 -1 -1 -1 0 0 -1 -1 0 -1
-1 -1 0 -1 -1 -1 0 2 0 0 0 0 0 -1 -1 -1 0 -1 0 -1 -1 0 -1 0
-1 0 0 -1 -1 -1 -1 1 0 -1 0 0 -1 -1 -1 0 -1 -1 -1 -1 -1 0 1 -1
-1 0 2 0 -1 -1 1 -1 -1 -1 0 0 0 -1 -1 0 -1 -1 -1 0 0 -1 -1 -1
-1 0 -1 -1 -1 0 -1 -1 -1 0 -1 0 0 -1 -1 -1 -1 -1 0 -1 0 0 -1 -1
-1 -1 -1 0 -1 -1 -1 1 0 3 1 -1 0 0 -1 0 -1 -1 0 0 2 -1 -1 3
0 0 -1 -1 -1 -1 0 -1 0 0 -1 0 0 0 -1 -1 0 -1 -1 -1 -1 -1 2 0
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 0 -1 -1 -1 0 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1 0 -1 -1 -1 0 0 -1 -1 0 -1 3 0 2 -1 -1
-1 -1 0 -1 -1 -1 0 -1 0 0 -1 -1 -1 -1 -1 1 -1 0 1 -1 0 0 1 -1
2 -1 0 -1 -1 -1 -1 0 -1 -1 1 0 -1 0 -1 -1 0 3 0 -1 -1 -1 2 -1
-1 -1 -1 0 0 0 1 -1 -1 -1 -1 -1 -1 -1 -1 0 -1 0 -1 0 -1 -1 0 0
-1 -1 -1 0 -1 0 -1 -1 0 -1 -1 -1 0 1 -1 -1 -1 0 1 1 1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 0 -1 -1 -1 0 -1 0
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 0]
df['Cluster'] = cluster_label
df.head()
지역 학교명 코드 유형 주야 ... location type code day Cluster
0 성북구 서울대학교사범대학부설중학교 3 국립 주간 ... 16 1 0 0 -1
1 종로구 서울대학교사범대학부설여자중학교 3 국립 주간 ... 22 1 0 0 -1
2 강남구 개원중학교 3 공립 주간 ... 0 0 0 0 -1
3 강남구 개포중학교 3 공립 주간 ... 0 0 0 0 -1
4 서초구 경원중학교 3 공립 주간 ... 14 0 0 0 -1
# 클러스터별 그룹
# -1 노이즈 그룹, 어디에도 속하지 못함
grouped = df.groupby('Cluster')
grouped.sum()
코드 남학생수 여학생수 일반고 특성화고 ... 경도 location type code day
Cluster
-1 765 38505 30866 170.996 35.234 ... 32395.479457 2877 142 0 0
0 312 10314 13927 69.275 21.253 ... 12956.408362 1124 64 2 0
1 211 1790 1891 9.968 3.613 ... 5715.272378 489 53 34 0
2 24 1174 1069 5.268 1.157 ... 1016.535379 60 2 0 0
3 15 728 459 3.071 0.862 ... 634.912972 49 0 0 0
5 rows × 20 columns
for k, g in grouped:
print("* key :", k)
print("* g :", len(g))
print(g.iloc[:,[0,1,3,9,10,13]].head())
print('\n')
* key : -1
* g : 255
지역 학교명 유형 과학고 외고_국제고 자사고
0 성북구 서울대학교사범대학부설중학교 국립 0.018 0.007 0.227
1 종로구 서울대학교사범대학부설여자중학교 국립 0.000 0.035 0.043
2 강남구 개원중학교 공립 0.009 0.012 0.090
3 강남구 개포중학교 공립 0.013 0.013 0.065
4 서초구 경원중학교 공립 0.007 0.010 0.282
* key : 0
* g : 102
지역 학교명 유형 과학고 외고_국제고 자사고
13 서초구 동덕여자중학교 사립 0.0 0.022 0.038
22 강남구 수서중학교 공립 0.0 0.019 0.044
28 서초구 언남중학교 공립 0.0 0.015 0.050
34 강남구 은성중학교 사립 0.0 0.016 0.065
43 송파구 거원중학교 공립 0.0 0.021 0.054
* key : 1
* g : 45
지역 학교명 유형 과학고 외고_국제고 자사고
46 강동구 동신중학교 사립 0.0 0.0 0.044
103 양천구 신원중학교 공립 0.0 0.0 0.006
118 구로구 개봉중학교 공립 0.0 0.0 0.012
126 영등포구 대림중학교 공립 0.0 0.0 0.050
175 중랑구 혜원여자중학교 사립 0.0 0.0 0.004
* key : 2
* g : 8
지역 학교명 유형 과학고 외고_국제고 자사고
20 서초구 서초중학교 공립 0.003 0.013 0.085
79 강동구 한영중학교 사립 0.004 0.011 0.077
122 구로구 구일중학교 공립 0.004 0.012 0.079
188 동작구 대방중학교 공립 0.003 0.015 0.076
214 도봉구 도봉중학교 공립 0.004 0.011 0.072
* key : 3
* g : 5
지역 학교명 유형 과학고 외고_국제고 자사고
35 서초구 이수중학교 공립 0.0 0.004 0.100
177 동대문구 휘경중학교 공립 0.0 0.004 0.094
191 동작구 문창중학교 공립 0.0 0.004 0.084
259 마포구 성사중학교 공립 0.0 0.004 0.078
305 강북구 강북중학교 공립 0.0 0.004 0.088
# 지도색 표시
colors = {-1 : 'gray', 0 : 'coral', 1 : 'blue', 2 : 'green', 3 : 'red',
4 : 'purple', 5 : 'orange', 6 : 'brown', 7 : 'brick',
8 : 'yellow', 9 : 'magenta', 10 : 'cyan', 11 : 'tan' }
cluster_map = folium.Map(location=[37.55, 126.98], zoom_start=12)
for name, lat, lng, clus in zip(df.학교명, df.위도, df.경도, df.Cluster) :
folium.CircleMarker([lat, lng],
radius = 5,
color=colors[clus],
fill=True,
fill_color=colors[clus],
fill_opacity = 0.7,
popup = name,
tooltip=name).add_to(cluster_map)
cluster_map.save('seoul_school_cluster.html')
# 설명변수
# 과학고 외고 국제고 + 유형
col_list2 = [9,10,13,22]
x2 = df.iloc[:, col_list2]
print(x2[:5])
x2 = pp.StandardScaler().fit(x2).transform(x2)
dbm2 = cluster.DBSCAN(eps=0.2, min_samples=5)
dbm2.fit(x2)
df['Cluster2'] = dbm2.labels_
grouped2_cols = [0,1,3] + col_list2
grouped2_cols
과학고 외고_국제고 자사고 code
0 0.018 0.007 0.227 0
1 0.000 0.035 0.043 0
2 0.009 0.012 0.090 0
3 0.013 0.013 0.065 0
4 0.007 0.010 0.282 0
[0, 1, 3, 9, 10, 13, 22]
df['Cluster2'].value_counts()
-1 260
0 101
4 26
1 15
2 8
3 5
Name: Cluster2, dtype: int64
grouped2 = df.groupby('Cluster2')
for k, g in grouped2:
print("* key :", k)
print("* g :", len(g))
print(g.iloc[:,[0,1,3,9,10,13]].head())
print('\n')
* key : -1
* g : 260
지역 학교명 유형 과학고 외고_국제고 자사고
0 성북구 서울대학교사범대학부설중학교 국립 0.018 0.007 0.227
1 종로구 서울대학교사범대학부설여자중학교 국립 0.000 0.035 0.043
2 강남구 개원중학교 공립 0.009 0.012 0.090
3 강남구 개포중학교 공립 0.013 0.013 0.065
4 서초구 경원중학교 공립 0.007 0.010 0.282
* key : 0
* g : 101
지역 학교명 유형 과학고 외고_국제고 자사고
13 서초구 동덕여자중학교 사립 0.0 0.022 0.038
22 강남구 수서중학교 공립 0.0 0.019 0.044
28 서초구 언남중학교 공립 0.0 0.015 0.050
34 강남구 은성중학교 사립 0.0 0.016 0.065
43 송파구 거원중학교 공립 0.0 0.021 0.054
* key : 1
* g : 15
지역 학교명 유형 과학고 외고_국제고 자사고
46 강동구 동신중학교 사립 0.0 0.0 0.044
103 양천구 신원중학교 공립 0.0 0.0 0.006
118 구로구 개봉중학교 공립 0.0 0.0 0.012
126 영등포구 대림중학교 공립 0.0 0.0 0.050
175 중랑구 혜원여자중학교 사립 0.0 0.0 0.004
* key : 2
* g : 8
지역 학교명 유형 과학고 외고_국제고 자사고
20 서초구 서초중학교 공립 0.003 0.013 0.085
79 강동구 한영중학교 사립 0.004 0.011 0.077
122 구로구 구일중학교 공립 0.004 0.012 0.079
188 동작구 대방중학교 공립 0.003 0.015 0.076
214 도봉구 도봉중학교 공립 0.004 0.011 0.072
* key : 3
* g : 5
지역 학교명 유형 과학고 외고_국제고 자사고
35 서초구 이수중학교 공립 0.0 0.004 0.100
177 동대문구 휘경중학교 공립 0.0 0.004 0.094
191 동작구 문창중학교 공립 0.0 0.004 0.084
259 마포구 성사중학교 공립 0.0 0.004 0.078
305 강북구 강북중학교 공립 0.0 0.004 0.088
* key : 4
* g : 26
지역 학교명 유형 과학고 외고_국제고 자사고
384 종로구 서울농학교 국립 0.0 0.0 0.0
385 마포구 한국우진학교 국립 0.0 0.0 0.0
386 종로구 서울맹학교 국립 0.0 0.0 0.0
387 강서구 교남학교 사립 0.0 0.0 0.0
388 서초구 다니엘학교 사립 0.0 0.0 0.0
cluster2_map = folium.Map(location = [37.55, 126.98], zoom_start=12)
for name, lat, lng, clus in zip(df.학교명, df.위도, df.경도, df.Cluster2) :
folium.CircleMarker([lat, lng],
radius=5,
color=colors[clus],
fill=True,
fill_color=colors[clus],
fill_opacity=0.7,
popup=name,
tooltip=name).add_to(cluster2_map)
cluster2_map.save('./seoul_mschool_cluster2.html')
반응형
'Data_Science > Data_Analysis_Py' 카테고리의 다른 글
28. 비트코인 가격 시계열 분석 || Arima, fbProphet (0) | 2021.11.24 |
---|---|
27. 프로야구 연봉 예측 분석 || OLS, Heatmap (0) | 2021.11.24 |
25. 판매 데이터 분석 || kmeans (0) | 2021.11.24 |
24. 위스콘신 유방안데이터 분석 || DT (0) | 2021.11.24 |
23. titanic 분류 예측 | KNN, SVM (0) | 2021.11.24 |