<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>파프리카 농장</title>
    <link>https://paprikafarm.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Wed, 24 Jun 2026 23:31:49 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>몽골리안 파프리카</managingEditor>
    <image>
      <title>파프리카 농장</title>
      <url>https://tistory1.daumcdn.net/tistory/5878447/attach/846721032a4d4151b819dc01c6aa8bad</url>
      <link>https://paprikafarm.tistory.com</link>
    </image>
    <item>
      <title>[Project] 파라메트릭 시뮬레이션 기반 최적 토지이용 제안 &amp;ndash; 보행권을 중심으로</title>
      <link>https://paprikafarm.tistory.com/60</link>
      <description>&lt;h3 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;1. &lt;/b&gt;&lt;b&gt;서론&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;1) &lt;/b&gt;&lt;b&gt;연구 배경 및 목적&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;1, 2기 신도시는 학교&amp;middot;생활 편의시설 도보 접근성 저하, 단지&amp;middot;생활권 간 단절, 낮은 공원&amp;middot;녹지 접근성으로 인한 미흡한 보행 환경에 더불어 자동차 중심 설계로 인한 문제점이 지적되어 왔다. 이를 극복하기 위한 3기 신도시 계획이 &amp;lsquo;사람 중심 보행 친화&amp;rsquo;를 기치로 내걸고 있는 점에서 도시 계획의 보행 환경 조성과 연결성 확보는 가장 중요한 고려 사항 중 하나라고 볼 수 있다. (성현곤, 2019; 윤신희&amp;middot;이세훈, 2021; 백일순&amp;middot;최선영, 2022) &lt;span style=&quot;color: #000000;&quot;&gt;이러한 신도시 조성 사업 중 공공택지지구는 &amp;lsquo;가로공간 중심 공유도시&amp;rsquo; 조성을 기치로 가로공간을 생활 중심으로 하여 생활 공간의 유기적 연결성을 강조하고 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;동시에 3기 신도시 계획에 대한 평가 지표 역시 개발되고 있다. (윤정중, 2019 ;박지영 외, 2022; 남성우 외, 2022) 하지만 이러한 평가 지표들은 필연적으로 계획 수립 이후 적용이 가능하다. 중점 사항이 설계 단계부터 반영되지 않을 경우 사후적인 설계 변경이 어렵기 때문에 계획 단에서 평가 기준을 선제적으로 반영하려는 시도가 지속적으로 이루어지고 있다. (전연수&amp;middot;정재헌, 2024) &lt;span style=&quot;color: #000000;&quot;&gt;또한 지금까지의 도시계획은 경험적 설계와 사후 평가 방식에 많은 비중을 두고 있으며, 계획 초기에 정량적 근거를 확보하기 어려운 한계가 존재했다. (한재원&amp;middot;이수기, 2021) &lt;/span&gt;따라서 보행 환경 조성 및 단지 간 연결성 확보를 중심으로 한 3기 신도시 역시 계획 수립 초기 단계부터 보행권과 단지 및 생활권 간 유기적 연결을 평가하여 반영할 필요가 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;h4 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;2)&amp;nbsp;&lt;/b&gt;&lt;b&gt;선행연구 검토&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;지구단위계획 또는 건축설계에 시뮬레이션 기술을 적용하는 연구는 지속적으로 이루어졌다. 대부분 파라메트릭 기반 도시설계 연구는 토지이용의 합리화보다 필지와 건축물의 조화, 환경영향평가 등 물리적 최적화에 집중되어 있다. 또한 국외에서 이루어진 연구가 많아 매개변수가 국내 실정과는 달라 적용이 힘든 경우가 많다. (전연수&amp;middot;정재헌, 2024)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;토지이용을 최적화하려는 시도들은 초기 선형 모델부터 비선형 모델까지 다양하게 시도되었다. 초기 Linear Programming 최적화 모델로 도시계획 시스템 문제를 해결하려는 연구가 시도되었다. (Guldmann, 1979) 하지만, 선형 모델은 선형성에서 벗어난 비수치적 복잡성을 반영하기 어렵고, 공간적 상호작용 문제를 다룰 수 없다. (고충석&amp;middot;이병철, 1989; Stewart et al., 2004)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;이에 따라 비선형적이고 복잡한 도시 문제를 다루기 위해 비선형 모델이 도입되었다. 특히 유전 알고리즘을 활용한 문제 해결 시도가 다수 있었다. 박윤선 외(2017)는 유전 알고리즘을 적용해 양평군의 토지이용 최적화를 통해 비교적 넓은 지역에 상충하는 목적들을 달성하는 방법을 제안했다. 하지만 분석단위가 너무 넓고, 토지피복을 개발지역, 농업지역, 산림지역, 수공간으로 제한하여 도시지역 적용이 어렵다는 한계를 가진다. 정종철(2017)은 유전 알고리즘을 이용하여 소규모 토지개발에 따른 문제를 최소화하며 목적을 달성하기 위한 실험적 개념을 제시하였다. 이는 법 중심의 질적 매개변수를 정량적으로 평가할 수 있는 개념적 토대를 제공하였지만 실험적 개념에 그쳤다는 점에서 현실 적용성이 떨어진다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;본 연구는 3기 신도시의 개발 목적에 따라&lt;span style=&quot;color: #000000;&quot;&gt; 계획상 중점 사항과 평가 지표를 매개변수로 하는 파라메트릭 모델 기반 다중 시뮬레이션 비교를 통해 도시 공간을 정량적으로 분석하고 최적의 토지이용을 도출한다. 나아가 실질적으로 적용 가능한 모델을 통해 사람 중심의 지속 가능한 도시 구조 구현에 기여할 것을 기대한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;2. &lt;/b&gt;&lt;b&gt;연구방법&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;1) &lt;/b&gt;&lt;b&gt;연구 대상지&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;연구 대상지는 인천계양 공공주택지구로 하였다. 총 면적은 약 3.33㎢이며, 약 17,000호의 주택과 약 41,700명의 인구 수용을 목표로 한다. 공공주택공급 확대와 수도권 서북부 균형 발전을 목적으로 지정되었으며, 주요 계획 방향은 친환경 녹지 중심 도시 구조, 공공성 중심 주거단지 구성에 있다. 전체 면적 중 약 50% 이상이 주거 용지이고, 공원 및 녹지 면적은 1인당 약 18.8m&amp;sup2;로 높은 수준의 녹지 보급 계획을 가진다. 인근에 인천 1호선 박촌역과 신도시 내부를 통과하는 S-BRT로 교통 접근성을 확보하고, ICT 및 디지털 콘텐트 중심의 업무 기능, 주거 기능을 동시에 배치하여 자족 기능을 확보한다. 이를 바탕으로 북부 산업 클러스터, 서부 박촌 역세권, 중앙 S-BRT 복합 환승센터에 각각 특별계획구역을 설치하여 도시의 핵심 축 기능을 유도한다. 또한, 도심을 통과하는 &amp;lsquo;계양벼리&amp;rsquo; 공원을 통해 보행 환경과 연결성을 확보한다. 근린(자족) 시설과 공공 시설은 모두 집적을 원칙으로 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;인천 계양신도시를 적용 대상지로 선정한 이유는 다음과 같다. 첫째, 계양신도시는 3기 신도시 중 가장 먼저 발표된 선도 지구로, 개발이 타지구에 비해 빠르게 진행되고 있다. 이에 따라 토지이용계획 등 주요 개발 자료에 접근이 상대적으로 용이하다. 둘째, 계양신도시는 면적이 약 3.33㎢로 3기 신도시 중 규모가 작은 편에 속하고 주거, 업무, 상업, 녹지 기능이 복합적으로 작동하는 자족형 도시로 계획되었다. 작은 공간 내에서 각 용도의 적합도 합을 최대화하면서 서로가 복합적으로 작동해야 함을 의미한다. 이러한 조건은 한정된 공간 조건 내의 최적의 토지 이용을 찾아야 한다는 점에서 넓은 지역 보다 본 연구의 테스트 베드로 적합하다. 마지막으로, 계양신도시는 도심 인접성과 공항철도 및 GTX-B 등 대중교통 기반의 접근성을 바탕으로 &amp;lsquo;직주근접형 자족도시&amp;rsquo;를 표방하고, 도시 내부 연결성은 선형 공원 &amp;lsquo;계양벼리&amp;rsquo;를 통해 확보한다. 정량적 평가가 수월하고 기능이 강조된 도시 외부 교통에 비해 도시 내부 연결성은 평가가 힘들고 기능이 덜 강조되었다. 본 연구를 통해 보행 환경의 정량적 평가와 &amp;lsquo;사람 중심&amp;rsquo;의 3기 신도시 개발 방향성 실현 대안을 기대할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;h4 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;2)&amp;nbsp;&amp;nbsp; &lt;/b&gt;&lt;b&gt;연구 모형&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;(1) 모형 개요&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;본 연구는 파라메트릭 시뮬레이션 모델을 통해 계획 단계에서의 토지 이용 최적화를 목적으로 한다. 3기 신도시 계획의 주안점, 특히 보행 환경과 연결성을 중심으로 한 유기적 설계를 중심으로 평가 기준을 매개변수로 두고 토지 이용 시뮬레이션을 시행한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;연구 대상지역을 10*10(m2)의 Grid 형태로 변환하여 가상 공간을 만든다. 가상 공간 상 구획에 랜덤으로 용도를 부여한 뒤, 적합도 평가를 통해 평가 점수가 높은 토지이용계획 후보를 반복적으로 구한다. 시뮬레이션을 통해 구한 계획 후보들의 패턴을 추출하여 최적의 토지이용계획 안을 제안한다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;299&quot; data-origin-height=&quot;769&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SN6qj/btsPS6XySrR/arJxxg3330RLodm6Sep5Q0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SN6qj/btsPS6XySrR/arJxxg3330RLodm6Sep5Q0/img.png&quot; data-alt=&quot;&amp;amp;lt; 그림 1 연구 모형 알고리즘 &amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SN6qj/btsPS6XySrR/arJxxg3330RLodm6Sep5Q0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSN6qj%2FbtsPS6XySrR%2FarJxxg3330RLodm6Sep5Q0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;299&quot; height=&quot;769&quot; data-origin-width=&quot;299&quot; data-origin-height=&quot;769&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt; 그림 1 연구 모형 알고리즘 &amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;div&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;(2) 초기 조건&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;연구 대상지 중 북부 산업 클러스터와 서부 박촌 역세권은 초기 조건에서 제외한다. 두 구역은 명확히 정해진 용도가 있고, 토지 이용이 단일 용도로 정해졌기 때문에 최적화 여지가 적다고 판단하였다. 따라서 북부와 서부를 제외한 구역을 초기 조건으로 설정하고 모형을 적용하였다. 도로의 경우 사업 대상지 외부와 연결되는 중심도로와 간선도로만 초기 고정 값으로 사용하였다. 특별계획용지 역시 초기 고정 값으로 두었다.&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;262&quot; data-origin-height=&quot;264&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SpGiN/btsPTz521f7/TYxtPbIruSkEC55r82BaPK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SpGiN/btsPTz521f7/TYxtPbIruSkEC55r82BaPK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SpGiN/btsPTz521f7/TYxtPbIruSkEC55r82BaPK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSpGiN%2FbtsPTz521f7%2FTYxtPbIruSkEC55r82BaPK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;300&quot; height=&quot;302&quot; data-origin-width=&quot;262&quot; data-origin-height=&quot;264&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;262&quot; data-origin-height=&quot;264&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dMBevc/btsPTP1Tt3T/ASYdp0PKy9rZsu5AI2av50/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dMBevc/btsPTP1Tt3T/ASYdp0PKy9rZsu5AI2av50/img.png&quot; data-alt=&quot;&amp;amp;lt; 그림2 초기조건 -사업대상지 &amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dMBevc/btsPTP1Tt3T/ASYdp0PKy9rZsu5AI2av50/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdMBevc%2FbtsPTP1Tt3T%2FASYdp0PKy9rZsu5AI2av50%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;300&quot; height=&quot;302&quot; data-origin-width=&quot;262&quot; data-origin-height=&quot;264&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt; 그림2 초기조건 -사업대상지 &amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1180&quot; data-origin-height=&quot;385&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5K7h5/btsPTCuUZuh/grmLXT6Yk82lD85dXLQq60/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5K7h5/btsPTCuUZuh/grmLXT6Yk82lD85dXLQq60/img.png&quot; data-alt=&quot;&amp;amp;lt; 표1 초기조건 -용도 및 면적 비율 &amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5K7h5/btsPTCuUZuh/grmLXT6Yk82lD85dXLQq60/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5K7h5%2FbtsPTCuUZuh%2FgrmLXT6Yk82lD85dXLQq60%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1180&quot; height=&quot;385&quot; data-origin-width=&quot;1180&quot; data-origin-height=&quot;385&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt; 표1 초기조건 -용도 및 면적 비율 &amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;div&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp; 본 연구에서는 토지 용도를 7가지로 분류한다. 연구의 목적이 큰 틀에서의 토지이용계획을 제안함에 있기 때문에, 용도를 단순화하여 제안하기 위해 기존 계획의 용도지역을 6개로 압축하고 초기 값인 미개발용지를 더해 토지를 총 7개 용도로 구분한 뒤, 고유 값을 아래와 같이 부여한다. 이 때, 고유 값은 명목 변수이다. 각 용도별 면적 비율은 기존 계획을 따른다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;&amp;lt;그림3&amp;gt; 은 위 정의한 초기 조건들을 적용하여 초기 가상공간을 구현한 결과이다. 초기 공간은 고정 값인 특별계획구역과 간선도로, 미개발 용지로 구성된다.&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;262&quot; data-origin-height=&quot;326&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bsQf99/btsPTzLJ3U5/HYtefVSxzwcx1B8nIQXT2K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bsQf99/btsPTzLJ3U5/HYtefVSxzwcx1B8nIQXT2K/img.png&quot; data-alt=&quot;&amp;amp;lt; 그림3 초기 가상공간 &amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bsQf99/btsPTzLJ3U5/HYtefVSxzwcx1B8nIQXT2K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbsQf99%2FbtsPTzLJ3U5%2FHYtefVSxzwcx1B8nIQXT2K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;300&quot; height=&quot;373&quot; data-origin-width=&quot;262&quot; data-origin-height=&quot;326&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt; 그림3 초기 가상공간 &amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;div&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;(3) 적합도 평가 지표&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;초기 가상공간 상 미개발 용지에 주거, 자족, 학교, 공원녹지가 배치된다. 이 때 토지의 용도 별로 적합도 평가가 이루어지며, 적합도 평가 점수 합이 가장 높은 토지 이용계획을 최적의 토지이용으로 판단한다. 적합도 평가 지표의 수립 근거는 3기 신도시 개발 계획 및 계양신도시 지구단위계획 상 중점 사항을 정량 지표로 변환하여 적용하였다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;계양신도시 지구단위계획 지침에 따르면 공공주택, 학교, 커뮤니티 시설을 보행권 내 배치하고 선형 공원 &amp;lsquo;계양벼리&amp;rsquo; 주변에 교육시설을 배치한다. 모든 시설은 집적 배치를 원칙으로 한다. 도시 중점거점 특별계획구역은 다층의 동선이 집적된 점층적 스카이라인의 입체도시 조성, S-BRT 등 신교통수단 및 간선도로 입체복합개발이라는 목적성을 가지고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;이를 바탕으로 용도 별 평가 기준을 수립한 결과는 다음과 같다. 자족 용지는 집적 효과를 위한 자족 용지 간 연결성이 기준에 포함되었다. 자족 용지가 업무 기능을 수행하는 공간이라는 점에서 차량과 교통 수단을 통한 접근성 역시 기준에 포함하였다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;주거 용지는 특별계획용지, 교육시설, 커뮤니티 시설, 공원녹지, 자족시설 모두에 대한 접근성이 좋아야 하기 때문에 이들 시설 및 용지에 대한 접근성을 평가지표로 사용하였다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;교육 시설과 공원녹지는 주거 용지의 맥락을 준용하여 전체 주거용지 대비 도보 3분 반경 내 주거 용지 비율을 평가 기준으로 사용하였다. 이들 시설의 반경 거리는 지구단위계획에서 밝힌 기준을 바탕으로 설정하였다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;이 때, 도보 접근성 계산은 네트워크 거리를 통해 계산한다. 일반 토지의 경우 성인 도보를 기준으로 Grid 1칸(10m)을 통과하는데 걸리는 시간을 약 6초로 가정하고, 도로는 통과 시간을 그 두 배로 상정하여 계산하였다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;교육시설의 경우, 학교보건법과 학교시설사업촉진법에 기반한 교육평가에서 학교용지를 확보할 때 교통 접근성 및 주변 도로 환경을 평가 요소로 삼는다. 또한 계양 신도시 지구단위계획에서 교육시설 연접 도로에 픽업 차량 진입을 돕는 설계를 포함한 점에서 교육시설의 차량 접근성을 평가 기준으로 사용하였다.&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;299&quot; data-origin-height=&quot;371&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cngTSF/btsPUjuQYsc/OL7KkZ6tcxiPH0MXROpfO1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cngTSF/btsPUjuQYsc/OL7KkZ6tcxiPH0MXROpfO1/img.png&quot; data-alt=&quot;&amp;amp;lt; 그림 4 최적 토지이용 후보 &amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cngTSF/btsPUjuQYsc/OL7KkZ6tcxiPH0MXROpfO1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcngTSF%2FbtsPUjuQYsc%2FOL7KkZ6tcxiPH0MXROpfO1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;300&quot; height=&quot;372&quot; data-origin-width=&quot;299&quot; data-origin-height=&quot;371&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt; 그림 4 최적 토지이용 후보 &amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;299&quot; data-origin-height=&quot;370&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FNVNM/btsPSZYwybQ/S9uKmJYScEBkqtwSlRXWzk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FNVNM/btsPSZYwybQ/S9uKmJYScEBkqtwSlRXWzk/img.png&quot; data-alt=&quot;&amp;amp;lt; 그림 5 최적 토지이용 패턴 &amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FNVNM/btsPSZYwybQ/S9uKmJYScEBkqtwSlRXWzk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFNVNM%2FbtsPSZYwybQ%2FS9uKmJYScEBkqtwSlRXWzk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;300&quot; height=&quot;371&quot; data-origin-width=&quot;299&quot; data-origin-height=&quot;370&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt; 그림 5 최적 토지이용 패턴 &amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1183&quot; data-origin-height=&quot;307&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZpUUU/btsPTmFVzQO/k7VJMFt4r6AIQjRirPca7K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZpUUU/btsPTmFVzQO/k7VJMFt4r6AIQjRirPca7K/img.png&quot; data-alt=&quot;&amp;amp;lt; 표 3 평가기준 별 평가내용 &amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZpUUU/btsPTmFVzQO/k7VJMFt4r6AIQjRirPca7K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZpUUU%2FbtsPTmFVzQO%2Fk7VJMFt4r6AIQjRirPca7K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1183&quot; height=&quot;307&quot; data-origin-width=&quot;1183&quot; data-origin-height=&quot;307&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt; 표 3 평가기준 별 평가내용 &amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light'; font-size: 0.87em; text-align: justify; letter-spacing: 0px;&quot;&gt;&amp;nbsp;최적 토지이용 패턴을 바탕으로 세부 조정을 거쳐 산출한 최종 가이드 라인은 다음과 같다&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Sans Light'; font-size: 0.87em; text-align: justify; letter-spacing: 0px;&quot;&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;329&quot; data-origin-height=&quot;386&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oyTiI/btsPS6wykmg/zwF889MFnvRfxnhThnk691/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oyTiI/btsPS6wykmg/zwF889MFnvRfxnhThnk691/img.png&quot; data-alt=&quot;&amp;amp;lt; 그림 5 최종 토지이용 가이드라인 제안 &amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oyTiI/btsPS6wykmg/zwF889MFnvRfxnhThnk691/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoyTiI%2FbtsPS6wykmg%2FzwF889MFnvRfxnhThnk691%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;350&quot; height=&quot;411&quot; data-origin-width=&quot;329&quot; data-origin-height=&quot;386&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt; 그림 5 최종 토지이용 가이드라인 제안 &amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;div&gt;
&lt;h3 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;b&gt;4. &lt;/b&gt;&lt;b&gt;결론&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;span style=&quot;text-align: justify; letter-spacing: 0px;&quot;&gt;&amp;nbsp;기존 도시계획에서는 도로망이나 기존 간선 체계를 기반으로 블록을 획일적으로 설정하고&lt;/span&gt;&lt;span style=&quot;text-align: justify; letter-spacing: 0px;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;text-align: justify; letter-spacing: 0px;&quot;&gt;이후 도보 접근성이나 기능 연계성 등의 문제를 보완하는 방식이 일반적이었다&lt;/span&gt;&lt;span style=&quot;text-align: justify; letter-spacing: 0px;&quot;&gt;. &lt;/span&gt;&lt;span style=&quot;text-align: justify; letter-spacing: 0px;&quot;&gt;이로 인한 생활권 단절&lt;/span&gt;&lt;span style=&quot;text-align: justify; letter-spacing: 0px;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;text-align: justify; letter-spacing: 0px;&quot;&gt;미흡한 보행 환경은 차량 중심 도시 구조 확산의 원인으로 지목된다&lt;/span&gt;&lt;span style=&quot;text-align: justify; letter-spacing: 0px;&quot;&gt;. &lt;/span&gt;&lt;span style=&quot;text-align: justify; letter-spacing: 0px;&quot;&gt;이를 극복하기 위해 &lt;/span&gt;&lt;span style=&quot;text-align: justify; letter-spacing: 0px;&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;text-align: justify; letter-spacing: 0px;&quot;&gt;기 신도시를 포함한 최근 도시계획은 보행권을 중심으로 연결성을 강화한 &lt;/span&gt;&lt;span style=&quot;text-align: justify; letter-spacing: 0px;&quot;&gt;&amp;lsquo;&lt;/span&gt;&lt;span style=&quot;text-align: justify; letter-spacing: 0px;&quot;&gt;사람 중심 도시&lt;/span&gt;&lt;span style=&quot;text-align: justify; letter-spacing: 0px;&quot;&gt;&amp;rsquo;&lt;/span&gt;&lt;span style=&quot;text-align: justify; letter-spacing: 0px;&quot;&gt;를 표방한다&lt;/span&gt;&lt;span style=&quot;text-align: justify; letter-spacing: 0px;&quot;&gt;. &lt;/span&gt;&lt;span style=&quot;text-align: justify; letter-spacing: 0px;&quot;&gt;계획의 목적 달성 정도를 파악할 수 있는 평가 지표 역시 다수 개발되었지만&lt;/span&gt;&lt;span style=&quot;text-align: justify; letter-spacing: 0px;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;text-align: justify; letter-spacing: 0px;&quot;&gt;평가는 필연적으로 설계에 후행할 수밖에 없는 한계를 가졌다&lt;/span&gt;&lt;span style=&quot;text-align: justify; letter-spacing: 0px;&quot;&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;본 연구는 파라메트릭 기법을 활용해 도시 설계 단계에서 목적에 따른 최적의 토지이용을 가능하게 하는 시뮬레이션 모형을 제안한다. 토지 용도 별 지향점을 매개변수로 사용하여 계획 상의 지향점을 선행적으로 반영하여 기존 후행적으로 이루어지던 평가 과정을 설계와 동시에 수행해 시간과 비용 절약과 더불어 효과적인 목적 달성을 가능하게 한다. 또한, 본 연구 결과는 고가의 전용 시스템 구축 없이도 기존 작업환경에 쉽게 연동 가능한 파이썬 기반 프로그램으로서, 도입의 기술적&amp;middot;경제적 부담이 낮다. 특히 적용 대상지와 목적에 따라 초기 입력 값과 매개변수를 조정하여 다양한 상황에 적용할 수 있다는 점에서 높은 활용성을 가진다. 장기적으로는 이러한 알고리즘 기반 설계 시스템이 스마트시티, 디지털트윈, ESG 도시계획 등과 결합하여 차세대 도시 설계 표준 또는 설계 공모의 가이드라인, 평가 기준, 검토 매뉴얼 등 제도적 정착으로 발전할 것을 기대한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;기술적 한계로 인해 polygon 형태가 아닌 10*10(m2) Grid 형태로 시뮬레이션을 수행한 점, 분석 단위가 필지가 아닌 구획 별로 이루어졌다는 점은 한계로써 작용한다. 이는 추후 기술적 발전과 추가 연구를 통해 보완하여 보다 세밀한 분석이 가능할 것을 기대한다.&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Project</category>
      <category>3기신도시</category>
      <category>도시계획</category>
      <category>시뮬레이션</category>
      <category>토지이용계획</category>
      <category>파라메트릭</category>
      <author>몽골리안 파프리카</author>
      <guid isPermaLink="true">https://paprikafarm.tistory.com/60</guid>
      <comments>https://paprikafarm.tistory.com/60#entry60comment</comments>
      <pubDate>Thu, 14 Aug 2025 16:18:59 +0900</pubDate>
    </item>
    <item>
      <title>[Project] 장래인구 추계 모형 다각화를 위한 지역 유형 분류에 관한 연구</title>
      <link>https://paprikafarm.tistory.com/59</link>
      <description>&lt;h3 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;1. 서론&lt;/span&gt;&lt;/h3&gt;
&lt;h4 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;1) 연구배경 및 목적&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;우리나라의 인구 감소 및 지역 소멸은 이미 국가적 추세이자 우리 사회가 직면한 중대한 문제로 나타나고 있다. 행정안전부에서 지정한 인구감소 지역은 2024년 기준 총 89개 시군구로, 대부분 비수도권 소규모 지방자치단체와 부산, 대구, 인천 일부 지역이 포함되었다. 특히, 2024년, 부산광역시가 산업연구원에서 조사한 인구소멸 위험지수 0.49를 기록하며 광역시 최초로 소멸 위험 지역에 들어섰으며, 감사원은 2047년에는 전국 모든 지역이 소멸 위험 단계에 진입할 것으로 전망했다. 이처럼, 인구 감소는 단순한 지역적 문제를 넘어서 국가적 위협으로 작용하고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;이러한 인구 감소 추세의 흐름에 발맞춰 합리적인 계획인구 추정을 바탕으로 하는 도시&amp;middot;군기본계획이 수립될 필요가 있음에도 불구하고 여전히 성장과 개발을 중심으로 하며(김명한, 2020), 현재의 인구추정 방식은 인구감소 추세와 지역적 특징을 반영하지 못하고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;현재 도시&amp;middot;군기본계획 수립 지침상 인구추정 방법은 모형에 의한 방법을 기본으로 하며 통계청이 제공하는 장래인구를 사용하거나 추세연장법을 사용하는 방법이 있다. 통계청은 코호트-요인법을 사용하고 있고, 장래인구추계 방법에 대해 통계정보보고서를 통해 설명한다. (통계청, 2019; 이명훈, 2023) 추세연장법을 사용하는 경우, 추세외삽법과 사회적 증가분에 의한 추정 방법을 함께 사용한다. 통계청에서는 광역시도 단위로 인구를 추계하고, 시군구 단위 인구 추계는 도시&amp;middot;군기본계획에서 시행하고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;다수의 연구에서 현행 인구추정 방식을 통한 예측 결과는 실제 인구와 차이가 크고, 지자체의 도시군기본계획(안)에서 설정한 계획인구는 미래 인구 전망에 비해 과다하게 설정되는 문제가 나타나는 것으로 지적한다(임병철, 2009; 김명한, 2020). 인구 규모는 도시계획수립에 있어 기본적인 선행 지표인 만큼, 잘못된 인구추정은 도시계획의 비효율과 비합리를 야기할 수 있으며(임병철, 2009) 지자체별 계획인구의 과다 추정으로 인해 난개발, 미분양 등 많은 비효율을 초래하고 있다(민성희, 2018).&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;권혁범(2012)은 특히 인구의 사회 증가분 추정 방식의 모호함을 지적했다. 인구추정 시 외부유입률 적용에 있어 가구원수 별 외부 유입 특성 차이가 영향이 있을 것으로 보고 새로운 적용 방안을 제시했다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;또한 현행 인구추정 방법은 인구통계학적 데이터만을 사용하고 있는 점을 지적하기도 한다. 인구 변동에는 기존에 사용되는 인구 통계 이외에 사업체 증감률, 인구 밀도, 가구, 주택 등 다양한 요인이 작용함을 여러 연구에서 밝히고 있다. (권혁범, 2012; 최현정, 2019; 이명훈, 2023)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;최현정 외(2019)는 보다 세밀한 인구분포 추정의 중요성을 강조하며 생잔법의 소단위 지역 적용 한계를 지적했다. 기존 인구통계를 사용한 단순 배분에서 벗어나 주택을 인구추정 변수로 사용하여 새로운 변수 사용의 가능성을 제시했다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;인구 감소 추세를 반영하기 힘든 기존 모형의 한계를 극복하기 위한 기존 연구들은 특정 지역을 중심으로 적용 가능한 모델만을 제시하였다. 지역적 특성을 반영한 인구 추계 연구는 통계적 유의성을 확보하기 쉬운 수도권 지역을 중심으로 이루어졌다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;반면, 비수도권 소규모 지역 인구 추계 방법에 대한 논의는 활발히 이루어지지 않은 측면이 있다. 또한 인구 추계에 있어 지역 특성을 적극적으로 반영한 다각적 접근을 다룬 연구 역시 많지 않다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;본 연구는 비수도권 소규모 지역을 포함한 전 국토를 대상으로 각 지역의 특성을 반영한 다각적 장래 인구 추계모형의 방향성을 제시하고자 한다. 이를 위해 지역의 특성을 정태, 동태 특성으로 구분하여 각 특성에 적합한 변수를 바탕으로 군집화 및 지역 유형 분류를 시도했다. 이를 통해 지역 소멸에 대비하는 장래인구 추계 모형의 다각화 방향성에 대한 시사점을 제공하는 데 목적을 두고, 나아가 지역 특성을 반영한 다각적 장래 인구 추계 모형을 제안하고자 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;본 연구의 구성은 다음과 같다. 2장에서는 장래인구 추계 모형과 지역 유형 분류에 대한 선행 연구를 살펴본다. 장래인구 추계 모형의 한계 지적과 해소 노력의 흐름을 파악하고, 지역 유형 분류에 대한 선행연구는 유형 분류에 사용한 변수와 대상 지역을 파악한다. 3장에서는 선행연구에서 논의된 내용과 한계점을 바탕으로 본 연구의 모형을 설계한다. 마지막으로, 분석 결과를 바탕으로 각 지역 유형의 특성을 밝히고 이를 통해 장래인구추계 모형의 방향성을 제시하고자 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;h3 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;2. 선행연구&lt;/span&gt;&lt;/h3&gt;
&lt;h4 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;1) 장래인구 추계 모형에 관한 연구&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;도시&amp;middot;군기본계획 수립 지침 상 장래인구 추계 모형의 문제점에 대한 지적은 지속적으로 제기되어왔다. 특히 인구의 사회적 증가분 추정 방식의 모호함과 과대 추정을 해소하기 위한 연구가 많이 이루어졌다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;이전 연구들은 주로 인구의 사회증감 추정 방식에 문제를 제기하며 보다 정확한 대안을 제시하였다. 안종욱(2002)은 수도권 집중 현상과 대규모 택지 개발로 인해 인구 이동이 잦아짐에 따른 유입 인구 추정의 중요성을 강조했다. 대규모 택지 개발사업으로 인한 유입 인구를 추정하기 위해 Markov chain을 이용한 모형을 적용하였다. 임병철(2009)은 비슷한 맥락에서 조성법을 이용한 자연 성장 예측과 비정상 Markov chain 인구이동 예측을 결합한 인구 예측 결합모형을 제시했다. 권혁범(2012)은 평택시를 중심으로 외부 유입률 산정에 가구특성을 적용하여 인구이동 예측의 정확도 제고를 시도했다. 한편, 박승용(2022)은 딥러닝 기법을 이용해 인위 가정 및 통계 모델 설정 없이 데이터 학습만으로 인구 예측을 시도했다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;비인구 통계를 활용한 인구 추계 방법을 제시한 연구도 있었다. 최현정(2019)은 도시&amp;middot;군기본계획에서 읍면동 단위 소규모 지역 인구를 추정하도록 하고 있으나, 단순 인구 배분에 그치고 있는 점을 지적했다. 소규모 지역에 적용하기 힘든 기존 인구 통계 중심 방법에서 벗어나 주택과 인구의 관계를 중심으로 한 예측 모형을 제시했다. 이명훈(2023)은 인구통계학적 데이터만을 이용한 모델의 문제점을 밝히며 비인구 통계 변수의 인구 추계 적용을 시도했다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;이들 연구는 그 적용 범위가 특정 지역에 한정된다는 한계를 가진다. 인구 규모가 큰 수도권 지역에 연구가 편중되었고 사회이동 추정의 대상이 평택 등 대도시 지역에 한정된다는 점에서 소규모 지역에 적용하기 힘든 한계점을 가진다. 소규모 지역의 인구 예측을 시도한 연구 역시 비수도권 소규모 지자체에 적용하기에는 한계가 있다. 최슬기&amp;middot;권다은(2024, 49p)은 비수도권 소규모 지자체 인구 예측이 지속적인 순전입을 가정하고 있지만, 순이동 규모 자체가 감소하고 있는 점을 고려해야 한다고 지적한다. 때문에 수원을 포함한 경기도를 대상으로 모형을 구축한 최현정(2019)과 모든 지역에 단일 모델을 적용한 이명훈(2023)의 예측 모형이 인구 3~5만의 소규모 비수도권 지자체에 적용 가능할 지는 미지수이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;또한 많은 경우 변수 선정에 있어 인구 통계만을 고려하고 각 지역적 특성을 간과하였다. 비인구 변수를 사용한 경우에도 지역적 특징을 충분히 반영한 변수 선정이 이루어진 연구는 많지 않다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;h4 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;2) 지역 유형 분류에 관한 연구&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;각 지역은 경제, 산업, 인구, 지리 등 특성에 따른 다양성을 가진다. 행정안전부 지정 인구감소 지역 89개에는 인구 10만 이상의 광역시 소속 자치구부터 인구 3~5만의 비도시지역까지 다양한 지역에 포함된다. 따라서 지역을 유형별로 구분하여 볼 필요가 있다. (최슬기&amp;middot;권다은, 2024, 49p)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;지역 유형 분류에 관한 연구는 크게 세 가지로 나뉜다. 대상을 한정하고 그 안에서 인구 변화와 특성을 분석한 연구, 인구구조 변화에 따라 도시를 유형화한 연구, 인구구조 변화와 도시의 경제 및 사회 분야 연계성을 확인하는 연구이다. (노재인&amp;middot;정주원, 2021)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;첫 번째 유형으로, 제현정(2019)은 정태, 동태 변화 요인을 변수로 사용하여 인구 감소 지역을 유형화하였다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;두 번째 유형은 유형별 특성 설명을 주목적으로 한다. 제현정&amp;middot;이희연(2017)은 지역 인구구조 변화 특성을 파악하기 위한 유형화를 시도했다. 인구 규모와 인구 증감량, 증감률을 포함한 다양한 지표를 사용해 전국적 차원의 획일적 인구정책보다 유형별로 적절한 대응 방안을 수립할 것을 제안했다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;세 번째 유형은 지역 유형을 특정 분야의 측면에서 조망한다. 노재인&amp;middot;정주원(2021)은 행정환경을 반영한 유형 분류를 통해 인구구조변화를 살피려 했다. 이성재 외(2020)는 인구감소 문제의 적극적 대응을 위해 지역을 유형별로 분류하였다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;첫 번째 유형의 연구는 특정 조건 하에 선택된 지역만을 대상으로 유형화를 시도한다는 점에서 한계가 있다. 두 번째 유형의 연구는 복합적 관점에서 유형을 파악하지 못한다. 세 번째 유형의 연구 중 이성재 외(2020)의 연구는 본 연구 주제와도 비슷한 방향성을 가지고 있다. 하지만 분석 대상을 전라북도 시군으로 한정한 점에서 차이가 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;본 연구는 도시 특성과 인구 특성을 반영하여 지역 유형 분류를 시도한 점, 전국 시군구 전체를 대상으로 군집화를 시도한 점, 그리고 장래 인구 추계 모형 설계의 방향성 제시를 목표로 한다는 점에서 기존 연구와의 차별점을 가진다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;h3 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;3. 연구모형&lt;/span&gt;&lt;/h3&gt;
&lt;h4 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;1) 분석 개요&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;본 연구에서는 도시 및 인구 관련 변수를 선정하고 총 2단계에 걸친 군집화를 거쳐 지역 유형을 분류한다. 군집 분석은 부분 공간 군집화(Subspace Clustering) 방식을 차용하였고, 1차 군집화는 K-means 알고리즘을, 2차 군집화는 Jaccard 거리 기반 집괴적 계층 군집화(Agglomerative Hierarchical Clustering)를 사용하였다. 군집 결과 평가를 위해 1차 군집화에서는 Elbow Method, Silhouette Score, Davis-Bouldin Index를, 2차 군집화에서는 덴드로그램(Dengrogram), Silhouette Score를 사용하였다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1198&quot; data-origin-height=&quot;839&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b8pQfi/btsPUGpLebU/0fbllOnNOdNpSV5g2akZWK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b8pQfi/btsPUGpLebU/0fbllOnNOdNpSV5g2akZWK/img.png&quot; data-alt=&quot;&amp;amp;lt;그림1 연구 모형 도식&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b8pQfi/btsPUGpLebU/0fbllOnNOdNpSV5g2akZWK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb8pQfi%2FbtsPUGpLebU%2F0fbllOnNOdNpSV5g2akZWK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1198&quot; height=&quot;839&quot; data-origin-width=&quot;1198&quot; data-origin-height=&quot;839&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;그림1 연구 모형 도식&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #777777; text-align: center; font-family: 'Noto Sans Light';&quot;&gt; 2) 변수 설정 &lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #777777; text-align: center; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;본 연구의 목적은 다각적 장래 인구 추정을 위해 각 지역의 특성을 파악하기 위함에 있다. 때문에 도시 특성 관련 변수와 인구 특성 관련 변수를 모두 사용했다. &amp;nbsp;도시의 경제, 사회, 행정적 요소는 인구 이동 결정 요인이다. (이외회, 2000; 임병철, 2009; 정주원&amp;middot;이아라, 2022) 특히 산업 등 경제적 요소는 인구변화와 밀접한 관련이 있다. (김병석&amp;middot;서원석, 2014) 따라서 지역 내 산업 총량을 반영하기 위한 변수로 GRDP를 선정하였다. &amp;nbsp;도시&amp;middot;군기본계획 수립지침은 도시 위상에 따른 유형을 거점도시, 강소도시, 자립도시로 분류한다. 분류 기준은 인구 규모와 주변 지역의 거점 역할을 수행하는지 여부이다. 후술하겠지만, 인구 규모는 이미 변수로 사용하였기 때문에 거점 역할을 수행하는지 여부에 집중하였다. 특별시, 광역시, 특별자치시, 특별자치도와 도청 소재지 같은 사회, 행정적 역할을 기준으로 분류한 점에 착안하여 특별시, 광역시, 나머지 도시로 나누어 가중치 변수를 만들었다. &amp;nbsp;인구 현상은 특정 시공간의 인구특성을 의미하는 정태현상과 정태현상의 변화를 야기하는 동태현상으로 나뉜다. (박경숙, 2017) 인구의 정태현상에는 인구 규모와 인구 비율이 있고, 동태현상에는 인구증감량, 인구증감률, 합계출산율, 전출입 인구 등이 있다. 본 연구에서는 인구 규모와 연령별 인구 구성 비율, 합계출산율, 합계출산율 변화율, 신생아 수, 연령별 순이동인구를 사용하였다. 인구 비율과 순이동인구 변수를 연령별로 사용한 이유는 연령에 따른 생애주기와 역할이 다르기 때문에 보다 정확한 특성 파악을 위해 제현정(2019)의 연구를 참고하여 10세 단위로 구분하였다. &amp;nbsp;이렇게 선정한 변수를 도시와 인구, 정태와 동태 현상에 따라 다시 4가지 분류군으로 나눴다. 인구의 규모와 인구증감은 다른 함의를 가지고 있기 때문에 이 또한 분류에 반영하였다. (제현정&amp;middot;이희연, 2017) 정태 측면의 도시 규모와 인구 비율, 동태 측면의 인구 자연증감 요인과 인구 사회증감 요인이 그 4가지 분류이다.첫째, 도시 규모 분류군에는 총인구, GRDP, 도시 위계 변수를 사용하였다. 정태 측면의 도시의 크기, 역할과 관련한 변수가 포함되었다. &amp;nbsp;둘째, 인구 비율 분류군에는 연령별 인구 구성 비율 변수가 포함되었다. 정태 측면의 인구 관련 변수이다. &amp;nbsp;셋째, 인구 자연증감 요인 분류군에는 합계출산율, 합계출산율 변화율, 신생아 수 변수가 포함되었다. 인구의 동태 측면의 변수로써, 인구 자연 변동의 규모와 추세를 모두 반영하려고 시도했다. &amp;nbsp;마지막으로, 인구 사회증감 요인 분류군에는 연령별 순이동 인구 변수가 포함되었다. 인구 측면의 변수로 인구 이동의 특성과 인구 구조 파악에 사용되었다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;741&quot; data-origin-height=&quot;233&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cAl7w1/btsPSs7Hqrd/jfrz0tvVKow1QvJl62eyA1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cAl7w1/btsPSs7Hqrd/jfrz0tvVKow1QvJl62eyA1/img.png&quot; data-alt=&quot;&amp;amp;lt; 표1 변수 구성&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cAl7w1/btsPSs7Hqrd/jfrz0tvVKow1QvJl62eyA1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcAl7w1%2FbtsPSs7Hqrd%2Fjfrz0tvVKow1QvJl62eyA1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;741&quot; height=&quot;233&quot; data-origin-width=&quot;741&quot; data-origin-height=&quot;233&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt; 표1 변수 구성&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;736&quot; data-origin-height=&quot;385&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbxPBl/btsPUhKxmei/1BIAB9ScTXcKSlLaYBvKKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbxPBl/btsPUhKxmei/1BIAB9ScTXcKSlLaYBvKKK/img.png&quot; data-alt=&quot;&amp;amp;lt;표2 변수 평균값&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbxPBl/btsPUhKxmei/1BIAB9ScTXcKSlLaYBvKKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbxPBl%2FbtsPUhKxmei%2F1BIAB9ScTXcKSlLaYBvKKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;736&quot; height=&quot;385&quot; data-origin-width=&quot;736&quot; data-origin-height=&quot;385&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;표2 변수 평균값&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;3) 군집화&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;본 연구에서는 앞서 선정한 변수와 분류 하에 총 2번의 군집화를 통해 지역 유형을 분류했다. 군집화 과정을 2차로 나눈 이유는 크게 두 가지이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;첫째, 어떤 변수 분류군이 지역 유형 구분에 영향을 미치는지 보다 간결하게 파악하기 위해서이다. 연구에 사용한 22개 변수 전체를 한 모델에 넣고 군집 분석을 한다면 변수와 결과의 상관관계 파악이 힘들다. 또한 시각화가 불가하기 때문에 직관적 이해와 구조 파악이 어려워진다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light';&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;둘째, 연산량 증가에 따른 문제를 피하기 위해서이다. 고차원 데이터의 군집화는 하위 공간의 열거가 어려워지는 차원의 저주(Curse of Dimensionality)가 발생한다. 고차원 데이터의 군집화는 데이터 간 거리가 과하게 멀어짐에 따라 모델의 성능 저하 우려가 있고, 또한 과적합 위험 역시 증가한다. (Kriegel.H.P.&amp;middot;Kr&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;ouml;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;ger.P.&amp;middot;Zimek.A., 2009)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;차원의 저주를 해소하기 위한 방법으로 부분공간 군집화(Subspace Clustering)가 있다. 부분공간 군집화는 고차원 데이터에서 의미 있는 특징들을 식별하고, 저차원 공간에서 밀도가 높은 영역을 찾아 점차 확장한다. 본 연구는 부분 공간 군집화의 방법을 차용해 전체 차원 중 연관성이 높은 차원을 4개 분류군으로 결합하여 군집화한 결과를 다시 군집화함으로써 차원의 저주를 해소하고자 했다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;1차 군집화는 K-means 알고리즘을 사용했다. K-means 알고리즘은 가장 대표적인 군집화 기법으로, 각 데이터 군집이 중심값을 기준으로 형성되기 때문에 각 군집의 특성 파악이 용이하다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;K-means 알고리즘은 군집의 개수를 사전에 결정해야 한다. 군집화는 비지도 학습이기 때문에 통계적 검증이 어렵다. (제현정, 2017) 때문에 본 연구에서는 군집 내 오차 제곱합(WCSS)을 이용한 Elbow Method, 군집의 내부 응집도와 타 군집과의 분리도를 측정하는 Silhoutte Score, Davis-Bouldin Index과 정성 분석을 통해 군집 개수를 결정했다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;1차 군집의 군집 개수는 각각 도시규모, 인구의 자연증감 요인, 인구의 사회증감 요인, 인구비율 순으로 각각 5개, 6개, 3개, 3개로 결정되었다. 그림2는 군집 개수에 따른 군집화 평가 지표 수치를 나타낸 자료이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;1차 군집화 결과는 수치형 데이터가 아닌 범주형 데이터이다. 범주형 데이터는 일반적 군집화 방법으로는 거리 계산이 불가하기 때문에 거리 연산 방식과 그에 적합한 군집화 방법이 선택되어야 한다. 범주형 데이터의 군집화 방법은 K-modes 알고리즘, Gower 거리 기반 군집화, Jaccard 거리 기반 군집화 등 방식이 있다. 그 중 K-mode 알고리즘과 Gower 거리 기반 군집화는 범주형 데이터와 수치형 데이터가 혼합된 데이터셋에 적합한 방식이다. (한지수&amp;middot;조형준, 2018) Jaccard 거리 기반 군집화는 앞선 두 방법보다 집합 간 유사성에 특화되어 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;따라서 Jaccard 거리를 기반으로 유사도를 계산했으며, 군집화 기법은 Jaccard 거리 기반 군집화에 많이 사용되는 집괴적 계층 군집화(Agglomerative Hierarchical Clustering)를 사용했다. (Teng.L.&amp;middot;Amin.R.&amp;middot;ElSayed.M., 2022)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;2차 군집의 군집 개수는 덴드로그램(dendrogram)과 Silhoutte Score, 정성 분석을 통해 결정했다. 그림3은 2차 군집 평가지표를 나타낸 그래프이다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;7500&quot; data-origin-height=&quot;2500&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2CROU/btsPUd9dZYb/jrfIUuqPV8BPo2qK9HATyk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2CROU/btsPUd9dZYb/jrfIUuqPV8BPo2qK9HATyk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2CROU/btsPUd9dZYb/jrfIUuqPV8BPo2qK9HATyk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2CROU%2FbtsPUd9dZYb%2FjrfIUuqPV8BPo2qK9HATyk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;7500&quot; height=&quot;2500&quot; data-origin-width=&quot;7500&quot; data-origin-height=&quot;2500&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;7500&quot; data-origin-height=&quot;2500&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ITUW8/btsPTF6fZER/e02FSKl1F1OG25fRS1XOI0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ITUW8/btsPTF6fZER/e02FSKl1F1OG25fRS1XOI0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ITUW8/btsPTF6fZER/e02FSKl1F1OG25fRS1XOI0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FITUW8%2FbtsPTF6fZER%2Fe02FSKl1F1OG25fRS1XOI0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;7500&quot; height=&quot;2500&quot; data-origin-width=&quot;7500&quot; data-origin-height=&quot;2500&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;7500&quot; data-origin-height=&quot;2500&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NkRM2/btsPSY6j1gW/40cmCykBXXJTXLPD5gGHM1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NkRM2/btsPSY6j1gW/40cmCykBXXJTXLPD5gGHM1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NkRM2/btsPSY6j1gW/40cmCykBXXJTXLPD5gGHM1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNkRM2%2FbtsPSY6j1gW%2F40cmCykBXXJTXLPD5gGHM1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;7500&quot; height=&quot;2500&quot; data-origin-width=&quot;7500&quot; data-origin-height=&quot;2500&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;7500&quot; data-origin-height=&quot;2500&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eIZ4Gv/btsPUOBhpzj/yMQzOK0XsrWFHHyKvajrz0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eIZ4Gv/btsPUOBhpzj/yMQzOK0XsrWFHHyKvajrz0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eIZ4Gv/btsPUOBhpzj/yMQzOK0XsrWFHHyKvajrz0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeIZ4Gv%2FbtsPUOBhpzj%2FyMQzOK0XsrWFHHyKvajrz0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;7500&quot; height=&quot;2500&quot; data-origin-width=&quot;7500&quot; data-origin-height=&quot;2500&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;7500&quot; data-origin-height=&quot;3750&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cjLhUz/btsPUB29yF7/eYBP2cpVAwuGOA8IG8FkRK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cjLhUz/btsPUB29yF7/eYBP2cpVAwuGOA8IG8FkRK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cjLhUz/btsPUB29yF7/eYBP2cpVAwuGOA8IG8FkRK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcjLhUz%2FbtsPUB29yF7%2FeYBP2cpVAwuGOA8IG8FkRK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;7500&quot; height=&quot;3750&quot; data-origin-width=&quot;7500&quot; data-origin-height=&quot;3750&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;4. 분석 결과&lt;/span&gt;&lt;/h3&gt;
&lt;h4 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;1) 1차 군집화 결과&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;1차 군집화 결과는 다음과 같다. 표3은 각 변수 분류군의 평균값이다. 분류군 별 군집화 결과는 다음과 같다. &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;736&quot; data-origin-height=&quot;572&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baPcY5/btsPTAw38dE/kTUgkVYotfNuDPrGlZQ2H0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baPcY5/btsPTAw38dE/kTUgkVYotfNuDPrGlZQ2H0/img.png&quot; data-alt=&quot;&amp;amp;lt; 표3 변수 분류군 별 평균값&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baPcY5/btsPTAw38dE/kTUgkVYotfNuDPrGlZQ2H0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaPcY5%2FbtsPTAw38dE%2FkTUgkVYotfNuDPrGlZQ2H0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;736&quot; height=&quot;572&quot; data-origin-width=&quot;736&quot; data-origin-height=&quot;572&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt; 표3 변수 분류군 별 평균값&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;첫 번째, 도시 규모 분류군은 군집의 구성이 불균일하게 나타났다. 비수도권 소규모 지자체라고 볼 수 있는 1번 군집에 112개 지자체가 포함되었다. 서울특별시 강남구, 서울특별시 중구, 경기도 화성시가 포함된 3번 군집과는 수치적 대비가 크다. 0번 군집은 지방 중소도시가, 4번 군집에는 수도권 대도시와 지방 수위도시들이, 2번 군집에는 주로 광역시 자치구가 속했다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;두 번째, 인구의 자연증감 분류군은 비교적 균일한 군집 분포를 보였다. 다만 신생아 수와 합계출산율이 반비례하는 경향을 보였다. 이는 신생아 출생이 적은 소규모 지역에서는 비교적 합계출산율이 높게 집계되고, 모수가 커질수록 합계출산율이 감소하는 현상을 반영한 결과로 보인다. 합계출산율 변화율은 전 군집이 (-) 값을 가졌다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;세 번째, 인구의 사회증감 분류군은 군집 별로 비교적 명확한 특성을 보인다. 0번 군집은 전 연령에 걸친 인구 순유출을 보이는 지역들이다. 1번 군집은 전 연령 대에서 순유입이 관찰된다. 특히 0~9세, 20~49세의 순유입이 높게 집계되었다. 자녀가 있는 가정의 순유입으로 추측된다. 2번 군집은 10~29세 인구는 순유입을, 나머지 연령대에서는 순유출을 보이는 지역이다. 서울시 대부분과 수도권 지역, 일부 광역시 자치구가 속해있다. 청년인구를 흡수하는 인구 쏠림 현상을 반영한 결과로 보인다. 각 군집이 198개, 6개, 25개 지역으로 매우 불균일한데, 이를 통해 지역 간 불균형 현상의 심각성과 특정 지역 인구 집중, 비수도권 청년 유출 등 인구 쏠림의 양상을 알 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;네 번째, 인구 비율 분류군은 비교적 균일한 분포를 보였다. 1번 군집은 20~59세의 비율 합은 약 40%이지만, 60세 이상 노인 인구 비율 합은 약 50%를 보이는 노인 중심 지역이다. 0번 군집은 20~59세 비율 합과 60세 이상 비율 합이 각각 약 50%와 36%이고, 2번 군집은 각각 58%, 25%로 나타났다. 1번, 0번, 2번 군집 순으로 생산인구 대비 노인인구 비율이 감소하였다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;2) 2차 군집화 결과&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;최종적인 군집은 4개로 결정하였다. 군집 분석 결과 도출된 네가지 군집을 각각 &amp;lsquo;소멸지역&amp;rsquo;, &amp;lsquo;성장지역&amp;rsquo;, &amp;lsquo;청년인구 흡수지역&amp;rsquo;, &amp;lsquo;청년인구 유출지역&amp;rsquo;으로 명명하려 한다. 표4는 최종 군집의 군집 별 평균이고, 표5는 각 군집의 구성 지역이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;735&quot; data-origin-height=&quot;397&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkOZcx/btsPUkN5NTn/sscN7A0Bvo4us3EzFhDSR0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkOZcx/btsPUkN5NTn/sscN7A0Bvo4us3EzFhDSR0/img.png&quot; data-alt=&quot;&amp;amp;lt; 표4 최종 군집 군집 별 평균값&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkOZcx/btsPUkN5NTn/sscN7A0Bvo4us3EzFhDSR0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkOZcx%2FbtsPUkN5NTn%2FsscN7A0Bvo4us3EzFhDSR0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;735&quot; height=&quot;397&quot; data-origin-width=&quot;735&quot; data-origin-height=&quot;397&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt; 표4 최종 군집 군집 별 평균값&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;602&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGPd8d/btsPSKUNB3J/hpsgfjF9y3fBQYOemD4k81/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGPd8d/btsPSKUNB3J/hpsgfjF9y3fBQYOemD4k81/img.png&quot; data-alt=&quot;&amp;amp;lt;표5 최종 군집 군집 별 구성 지역&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGPd8d/btsPSKUNB3J/hpsgfjF9y3fBQYOemD4k81/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGPd8d%2FbtsPSKUNB3J%2FhpsgfjF9y3fBQYOemD4k81%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;602&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;602&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;표5 최종 군집 군집 별 구성 지역&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;먼저 &amp;lsquo;소멸지역&amp;rsquo;이다. 4개 군집 중 도시 규모가 가장 작은 유형이다. 규모가 가장 큰 2번 군집과 비교하면 인구는 약 9배, GRDP는 18.5배 차이가 난다. 구성 지역은 108개로 가장 많으며, 대부분 비수도권 소규모 지자체로 구성되어 있다. 신생아 수 역시 4개 군집 중 가장 작지만, 합계출산율은 가장 높다. 앞선 1차 군집 결과 분석과 마찬가지로 모수가 작아서 합계출산율이 높게 계산되는 것으로 보인다. 인구 이동은 20대 순유출과 50, 60대 순유입이 가장 활발하게 이루어진다. 그 외에는 큰 인구이동이 이루어지지 않는다. 고령화는 심각한 수준이다. 60세를 전후로 고령인구를 나누었을 때, 고령인구는 약 44%이고 20대에서 50대까지 생산인구 역시 44%로 동률이다. 80세 이상 인구는 10%로 압도적으로 높은 수치를 보였다. 1번 군집의 지역들은 수치상 젊은 인구는 유출되고 고령화는 지속될 것으로 보인다. 이러한 추세가 계속된다면 소멸 위기가 높은 지역이기 때문에 소멸지역이라고 이름 붙였다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;두 번째는 &amp;lsquo;성장지역&amp;rsquo;이다. 구성 지역은 단 화성시, 평택시, 아산시로, 산업이 활발하고 서로 인접한 수도권 신도시 지역들이다. 인구와 GRDP 모두 다른 군집에 비해 압도적으로 크다. 신생아 수 역시 다른 군집에 비해 큰 폭으로 높은 수치를 보인다. 주목할 만한 점은 합계출산율이다. 1차 군집 결과 분석에서는 신생아 수와 합계출산율이 반비례하는 경향을 보였다. 하지만 성장지역은 신생아 수가 가장 많음에도 평균 합계출산율이 약 0.9333으로소멸지역과 비슷한 수치를 보였다. 인구 이동은 전 연령에 걸친 순유입을 보인다. 특히 0~9세의 아동과 20~59세에 걸친 생산인구의 순유입이 눈에 띈다. 아이를 가진 가정과 노동 인구가 다수 유입되는 것으로 보인다. 높은 합계출산율과 전입인구는 연관이 있어 보인다. 정확한 상관관계는 추후 조사가 필요하다. 60세 이상 고령인구는 약 19%, 20~50대 인구는 61%로 인구 구조 역시 지속적인 성장에 적합해 보인다. 이들 지역은 출산과 인구 유입, 젊은 인구와 노령 인구의 비율에 비추어 성장에 적합한 유형이기 때문에 성장 지역 유형이라고 이름 붙였다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;세 번째는 &amp;lsquo;청년인구 흡수지역&amp;rsquo;이다. 총 52개 지역으로, 서울 및 광역시 자치구로 구성되어 있다. 총인구, GRDP, 신생아 수는 청년인구 유출지역과 비슷하거나 낮은 정도이다. 합계출산율은 4개 군집 중 가장 낮은 약 0.6이다. 주목할 만한 점은 인구이동 양상이다. 10대와 20대 인구는 순유입을 보이고, 그 외 모든 연령대에서 순유출을 보인다. 유출 인구 중에선 30대의 순유출이 가장 크다. 모두 서울과 광역시로 구성된 점으로 미루어, 학업을 위해 유입된 인구가 직장에 들어가려고 할 때 타지역으로 밀려 나가는 것으로 추측할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;마지막으로 &amp;lsquo;청년인구 유출지역&amp;rsquo;이다. 대부분 비광역 지자체 중 중형에서 대형 도시로 구성되어 있다. 총인구와 신생아 수는 청년인구 흡수지역 보다 많지만, 합계출산율 역시 높은 것으로 나타난다. 역시 주목할 점은 청년인구 이동이다. 10대, 20대 인구는 순유출을 보이고 30대 인구는 순유입을, 그 외 인구는 큰 변화를 보이지 않는 것으로 나타났다. 청년인구 유입 지역 유형에서 10대, 20대의 순유입과 30대 인구의 순유출을 확인한 바가 있다. 청년인구 흡수지역과 청년인구 유출지역의 인구이동 양상을 함께 볼 때, 청년인구 유출지역의 청년인구가 교육 등을 이유로 청년인구 흡수지역으로 향하는 것으로 추측된다. 청년인구 유출지역과 청년인구 유입지역의 인구이동 관계 역시 추후 분석이 필요하다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1067&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjPW4N/btsPTQNdaZd/9KpyhYBYQn5sn1XGXrJ4ik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjPW4N/btsPTQNdaZd/9KpyhYBYQn5sn1XGXrJ4ik/img.png&quot; data-alt=&quot;&amp;amp;lt; 그림4 최종군집 시각화&amp;amp;gt;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjPW4N/btsPTQNdaZd/9KpyhYBYQn5sn1XGXrJ4ik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjPW4N%2FbtsPTQNdaZd%2F9KpyhYBYQn5sn1XGXrJ4ik%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;1067&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1067&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt; 그림4 최종군집 시각화&amp;gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;5. 결론 및 시사점&lt;/span&gt;&lt;/h3&gt;
&lt;h4 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;1) 지역간 불균형과 인구 이동 양상&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;분석 결과, 지역 간 격차는 매우 큰 것으로 나타났다. 최종 군집은 총 4개로 분류되었고, 각각 108개, 3개, 52개, 66개 지역으로 구성되어 있다. 소멸지역으로 이름 붙인 첫 번째 군집이 108개인데 반해, 비교적 건강한 지표를 보이며 성장하는 성장지역은 단 3개 지역으로 구성되었다. 그리고 그 두 지역 간 격차는 인구 약 9배, GRDP 약 18.5배, 신생아 수 약 16.6배로 압도적인 격차를 확인할 수 있다. 이는 시각화 자료를 보면 더욱 명확하게 확인할 수 있다. 성장, 청년인구 흡수지역은 주로 경부축을 중심으로 수도권에 집중 분포된 반면, 소멸지역은 경부축의 반대편인 호남, 강원 지역을 중심으로 분포한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;인구의 사회이동 변수를 보면, 유입되는 곳과 유출되는 곳이 정해져 있다는 것으로 보인다. 성장 지역은 전 연령이 향하고 있다. 청년인구 유입 지역은 10대&amp;middot;20대 인구를 흡수하고 그 외 인구를 배출한다. 소멸 지역과 청년인구 유출 지역은 10대&amp;middot;20대 인구를 배출하고 노령인구 일부를 흡수한다. 이를 바탕으로 추측해 보자면, 청년들은 비수도권 소규모 지자체를 떠나 서울과 광역시로 향한다. 학업을 마친 후에는 다시 서울과 광역시를 떠나 중형, 대형 도시로 향한다. 이때 비수도권 소규모 지역으로는 향하지 않는다. 노령 인구는 서울과 광역시를 벗어나 비교적 한적한 곳으로 향한다고 볼 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;이 같은 인구 이동은 지역 간 격차를 더욱 벌릴 것이다. 생산인구는 특정 대도시를 중심으로 모여들고, 고령화가 진행되는 곳에는 노인이 모여들며 고령화에 더욱 박차를 가한다. 노인 비중이 높은 지역은 부양 인구 압력이 강해질 것이고, 결국 지역의 자립성은 무너질 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;h4 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;2) 인구 변화&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;인구의 자연증감은 인구 변화에 큰 영향을 주지 않는 것으로 보인다. 총인구 대비 신생아 수는 유형별로 약 0.3%, 0.6%, 0.4%, 0.4%이다. 합계 출산율 또한 모든 유형에서 1에도 못 미치므로 1 대 1 재생산이 이루어지지 않는다. 그에 반해 순이동 인구의 절댓값은 각각 약 0.7%, 2.8%, 0.8%, 0.2%로 대체로 자연증감 보다 높은 비율을 보인다. 특히 성장지역은 자연증감 요인보다 사회증감 요인이 인구 변화에 큰 영향을 미친다. 소멸지역, 성장지역, 청년인구 흡수지역은 인구의 사회증감 요인에 대한 정확한 파악이 장래 인구 추계에 중요할 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;앞서 설명한 바와 같이 인구의 사회증감 양상은 매우 이질적이다. 성장지역은 압도적으로 많은 인구 순유입이 이루어지는 반면, 타 유형은 인구가 순유출한다. 청년들은 소멸지역과 청년인구 유출지역을 떠나 성장지역과 청년인구 흡수지역으로 향하고, 10대와 20대를 제외한 모든 연령이 청년인구 흡수지역을 떠난다. 이러한 이질적 인구 이동 양상을 예측하기 위해서는 인구의 사회증감 추계 방법이 다각화 되어야 한다. 또한 인구 통계 뿐만 아니라 지역 특성, 지역간 관계를 반영할 수 있는 변수가 사용되어야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;모든 유형에서 합계출산율이 2에 못 미치므로 인구 총량은 감소하고 있다. 즉, 인구의 마이너스 섬(minus sum) 상황이다. 인구 총량이 줄어드는 상황에서 인구의 사회적 성장으로 인해 인구가 증가했다고 해도, 타 지역에 비해 덜 잃었을 뿐 성과를 이루었다고 보기 힘들다. 비교적 높은 합계출산율을 가진 성장지역도 신생아 수에 비래 유입인구가 압도적으로 많다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;유입 인구는 무한정 공급되지 않는다. 인구 유입에 의한 성장은 장기적으로 한계에 부딪힐 수밖에 없다. 단순히 인구 성장을 위한 기존과 같은 개발 및 성장 주도 계획은 어떤 유형에도 효과적일 수 없다. 인구의 양적 성장을 위한 계획이 아니라 기존 인구에게 더 나은 삶을 제공할 수 있고, 나아가 출산이라는 선택지에 매력을 더할 수 있는 질적 접근이 필요하다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;h4 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;3) 장래인구 추계 모형 개선 방향&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;장래인구 추계 모형에 관한 연구들은 인구의 사회적 증가 추정 방식이 모호하고 부정확하다고 지적해 왔다. 대부분 유형에서 인구변동은 자연증감 보다 사회증감 영향이 더 크다는 점을 고려하면, 인구이동 추정 방식의 정확도 제고는 필수적이다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;성장지역을 제외한 3개 유형 모두 인구 순유출을 보였다. 하지만 현재 도시&amp;middot;군기본계획 상 사회적 증가분에 의한 추정 방법은 인구 유출을 상정하지 않는다. 인구 순유출을 반영할 대안적 방법도 제시하지 않는다. 즉, 인구의 순유출을 인구추계에 반영할 수 없다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;소멸지역은 모수가 작기 때문에 인구의 자연증감 추계에 있어 코호트 요인법과 같은 기존 방식을 적용하기 힘들다. 때문에 소규모 집단에 적용할 수 있는 인구 추정 모형이 필요하다. 지리적으로 인접하고 유사한 특성을 보이는 지역을 묶어서 인구를 추정한 뒤 배분하는 방식을 사용할 수 있다. 이를 통해 모수를 늘릴 수 있으므로 통계적 유의성을 확보할 수 있을 것이다. 또한, 고령 인구의 지속적인 순전입은 보장할 수 없다. 소멸지역의 인구의 사회증가 추정 모델은 인구 순유출을 예측할 수 있어야 한다. 더불어 총인구 규모가 작은 지역은 전입인구를 잘못 예측했을 때 영향이 크므로 보다 보수적인 접근이 필요하다. 주간활동인구 추정에 보다 힘을 쏟아야 한다. 소멸 지역의 경우 산간, 도서 지역인 경우가 많다. 이들 지역은 상주인구는 적지만 관광객으로 인해 주간활동인구는 많은 경우가 많다. 주간활동인구 추정을 통해 지역 인프라 수요 추정 등 적절한 도시계획을 수립할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;성장 지역은 인구 성장세가 감소하는 시기를 적절히 예측해야 한다. 추세연장법과 사회증가분 추정 방식은 현재까지 추세를 반영할 뿐 그 외 요소를 반영할 수 없다. 인구 유입은 무한정 이루어질 수 없다. 또한 인구 밀도가 지속해서 증가하면 도시 내 집적 불이익이 발생할 것이므로 장기적으로는 인구 증가 추세가 감소하고 서울의 경우처럼 인구가 감소할 가능성도 있다. 이러한 추세를 반영할 수 있는 모형이 필요하다. 성장 도시는 순전입 인구가 인구 증가에 큰 영향을 미치므로 도시 내부 변수 뿐만 아니라 잠재적 유입 인구를 추정할 수 있는 지역간 인구 이동 관계와 같은 외부 변수를 반영해야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;청년인구 유출지역과 청년인구 유입지역은 청년인구의 이동 원인 파악이 필요하다. 청년인구 유입지역은 고령 인구 유출 원인 파악 역시 필요하다. 유입 유출 원인 파악 결과를 바탕으로 인구의 사회증감 추정 방식을 재편해야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;소멸지역을 제외한 나머지 지역 중 인구 규모가 크고 관련 데이터 수집이 잘 이루어지는 지역의 경우에는, 큰 인구 규모로 담보되는 통계적 유의성과 데이터 수집의 이점을 적극 활용해야 한다. 보다 정밀한 추정과 논리적 접근으로 인구 동향을 파악하고 인구 추계 모형 발전 방향을 모색해야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;h4 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;4) 시사점 및 향후 연구&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;기존 논의는 수도권 및 대도시에 집중되었고, 현실적인 소멸 위기에 직면한 지방 소규모 지역들에 대한 연구는 활발히 이루어지지 않았다. 또는 지역을 특정하여 한정된 시공간 안에서 연구가 이루어졌다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;이에, 본 연구는 연구 대상을 전국으로 늘려 전반적 지역 특성을 조망하였다. 더불어 연구 결과를 바탕으로 부정확하고 과다하게 추정되어 오던 기존 장래인구 추정 방식의 한계를 극복하기 위한 방향성을 제시하였다. 이를 통해 보다 합리적인 추정 방식의 제고와 나아가 도시 계획의 개선 가능성에 기여할 것을 기대한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;다만, 몇 가지 한계점은 존재한다. 첫 번째로 각 유형의 특성은 파악할 수 있었으나 인구변화의 원인은 파악할 수 없었다. 청년인구 유출지역과 청년인구 유입지역의 상관관계나 소멸 지역의 인구 유출 원인은 단순히 추측할 뿐 정확한 진단은 내리지 못했다. 이는 추후 관련 연구를 통해 정확한 원인을 진단할 필요가 있어 보인다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;두 번째로 군집 분석의 유의성을 검증할 수 없다는 점이다. 비지도 학습이라는 군집화의 특성상 정답이 없기 때문에 결과의 유의성은 연구자의 주관에 의해 판단될 수밖에 없다. 이를 극복하기 위해 평가지표를 도입하였으나 여전히 오류 가능성이 있다는 점에서 한계점이 있었다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;마지막으로 도시 위계 변수의 근거 부족이다. 도시의 행정적 위계에 따라 가중치를 부여하기 위해 만든 변수였으나 관련 연구 자료 등에서 근거를 찾지 않고 주관에 의해 변수를 설정했다는 점에서 한계점을 가진다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Light';&quot;&gt;&amp;nbsp;향후 본 연구 결과를 바탕으로 유형별 인구이동 원인을 진단하는 연구가 필요하다. 또한 각 유형에 적합한 장래인구 추계 모형을 제안하는 연구가 필요하다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>Project</category>
      <category>K-means</category>
      <category>계층적군집화</category>
      <category>부분공간군집화</category>
      <category>소멸위험</category>
      <category>유형분류</category>
      <category>인구추계</category>
      <category>장래인구</category>
      <category>지방소멸</category>
      <category>클러스터링</category>
      <author>몽골리안 파프리카</author>
      <guid isPermaLink="true">https://paprikafarm.tistory.com/59</guid>
      <comments>https://paprikafarm.tistory.com/59#entry59comment</comments>
      <pubDate>Thu, 14 Aug 2025 16:03:11 +0900</pubDate>
    </item>
    <item>
      <title>[Algorithm] New Point 쓰레기 처리 시스템 구축 알고리즘 (2) Data Preprocessing</title>
      <link>https://paprikafarm.tistory.com/35</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;아래 Project Structure 에 나온 순서대로 데이터 전처리를 수행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;New Point_.png&quot; data-origin-width=&quot;720&quot; data-origin-height=&quot;405&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xkXaO/btrZLTnHdQq/oopYQW0vrQaDNieqakkkQ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xkXaO/btrZLTnHdQq/oopYQW0vrQaDNieqakkkQ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xkXaO/btrZLTnHdQq/oopYQW0vrQaDNieqakkkQ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxkXaO%2FbtrZLTnHdQq%2FoopYQW0vrQaDNieqakkkQ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;720&quot; height=&quot;405&quot; data-filename=&quot;New Point_.png&quot; data-origin-width=&quot;720&quot; data-origin-height=&quot;405&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;(1) 사당 4동 추출&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;프로젝트 대상지는 행정동 단위로 선정한다. 쓰레기 수거 업체가 행정동 단위로 선정되는 경우가 많기 때문이다. 때문에 행정동 경계 데이터 중 대상지를 추출하여 사용한다. 이번에는 사당 4동을 추출하여 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;행정동 경계를 추출한 뒤 서울시 전체 건물, 건물 출입구, 도로 데이터 중 대상지 (사당 4동) 만을 추출한다.&lt;/p&gt;
&lt;pre id=&quot;code_1676817591225&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#%% Data Preprocessing - (1) 사당 4동
# (1) SADANG 4
sd = gpd.read_file(load_dir + '/haengjeongdong/Z_SOP_BND_ADM_DONG_PG.shp', encoding='cp949')
sd = sd[sd['ADM_DR_NM'] == '사당4동']
sd.crs # EPSG 5181
sd = sd.geometry.iloc[0]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;(2) 건물 + 건축물대장&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;건물 데이터에 건축물대장 중 표제부 데이터를 결합한다. 건물 데이터의 geometry 데이터에 건축물대장 중 표제부 데이터를 결합하여 주용도, 기타 용도, 세대 및 가구 수 정보를 획득한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;표제부의 PPK (관리건축물대장 PK) 는 추후 건축물의 고유 번호로서 사용될 여지가 있기 때문에 남겨둔다. 도로명주소 기준 데이터의 BPK (Building PK) 데이터는 건물 출입구 데이터와 결합에서 사용될 예정이기 때문에 역시 남겨둔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;건축물대장에서 획득한 정보 중 주용도와 기타 용도를 활용하여 아파트와 그 부속 건물 데이터를 제거한다. 아파트의 경우 이미 거점형 쓰레기 처리 시스템을 가지고 있기 때문에 프로젝트의 대상에서 제외한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;가구 및 세대 수는 추후 쓰레기 배출 시뮬레이션 알고리즘에 활용될 예정이다. 세대와 가구를 결합하여 POP 컬럼으로 구성한다.&lt;/p&gt;
&lt;pre id=&quot;code_1676817608539&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#%% Data Preprocessing - (2) 건물
# (2) BUILDING + PJB
bd = gpd.read_file(load_dir + '/building/Z_KAIS_TL_SPBD_BULD_11000.shp', encoding='cp949')
bd = bd[['BUL_MAN_NO', 'SIG_CD', 'EMD_CD', 'LNBR_MNNM', 'LNBR_SLNO', 'geometry']]
bd.info()
bd.crs # EPSG 5181

bd['PNU'] = bd['SIG_CD'] + bd['EMD_CD'] + '00' + '1' + bd['LNBR_MNNM'].astype(str).str.zfill(4) + bd['LNBR_SLNO'].astype(str).str.zfill(4)
bd['BPK'] = bd['SIG_CD'].astype(str) + '-' + bd['BUL_MAN_NO'].astype(str)
bd = bd[['BPK', 'PNU', 'geometry']]

bd = bd[bd.intersects(sd)]
bd.plot()
bd = bd.reset_index(drop=True)


file_columns = pd.read_excel(load_dir + '/pjb/filecolumns.xlsx')
use_cols = ['관리_건축물대장_PK', '시군구_코드', '법정동_코드', '번', '지', '주_용도_코드_명', '기타_용도', '세대_수(세대)', '가구_수(가구)']
pjb = pd.read_csv(load_dir + '/pjb/mart_djy_03.txt', sep='|', names=file_columns['mart_djy_03(pjb)'].dropna(), header=None, usecols=use_cols, dtype=str, encoding='cp949')

pjb = pjb[pjb['시군구_코드'].str[:2] == '11']
pjb['PNU'] = pjb['시군구_코드'] + pjb['법정동_코드'] + '1' + pjb['번'] + pjb['지']
pjb = pjb[['관리_건축물대장_PK', 'PNU', '주_용도_코드_명', '기타_용도', '세대_수(세대)', '가구_수(가구)']]
pjb.columns = ['PPK', 'PNU', 'MN_CD', 'ETC_CD', 'SD', 'GG']


bd = pd.merge(bd, pjb, on=['PNU'], how='left')
bd.isna().sum()

bd = bd.fillna(0)
bd['POP'] = bd['SD'].astype(int) + bd['GG'].astype(int)
bd = bd[bd['POP'] != 0]
bd = bd.reset_index(drop=True)

apt = bd[bd['ETC_CD'].str.contains('아파트') == True]['PNU'].tolist()

for a in apt:
    bd = bd[bd['PNU'] != a]

bd = bd[['PPK', 'BPK', 'PNU', 'MN_CD', 'ETC_CD', 'POP', 'geometry']]

bd.to_file(save_dir + '/sadang_building/sadang_building.shp', encoding='cp949')


del file_columns, use_cols, pjb, a, apt&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;(3) 도로 + 도로 정보 + 횡단보도 데이터&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;도로 중심선 데이터에 상세 정보와 횡단보도 데이터를 결합하여 도로 별 도로폭과 횡단보도 포함 여부를 획득한다. 두 정보 모두 쓰레기 처리 거점 시설 설치 여부 판단에 사용된다.&lt;/p&gt;
&lt;pre id=&quot;code_1676817629539&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# (3) ROAD + ROAD_INFO + CROSS_WALK
road = gpd.read_file(load_dir + '/road/Z_KAIS_TL_SPRD_MANAGE_11000.shp', encoding='cp949')

road = road[['RN', 'geometry']]
road.columns = ['RNM', 'geometry']
road.crs # EPSG 5181

road = road[road.intersects(sd)]
road.plot()
road = road.reset_index(drop=True)


road_info = pd.read_csv(load_dir + '/road/서울시 도로노선 정보.csv', encoding='cp949')
road_info = road_info[['노선명(도로명)', '도로규모']]
road_info.columns = ['RNM', 'RD_SC']

road = pd.merge(road, road_info, on=['RNM'], how='left')
road = road[['RNM', 'RD_SC', 'geometry']]
road.duplicated().sum()


cross_walk = gpd.read_file(load_dir + '/seoul_cross walk/A004_A.shp', encoding='cp949')
cross_walk = cross_walk[['geometry']]
cross_walk = cross_walk.to_crs(epsg=5181) # EPSG 5186 &amp;gt; 5181

road = gpd.sjoin(road, cross_walk, how='left')
road = road.reset_index().drop_duplicates(subset=['index']).fillna(-1)
road['index_right'] = road['index_right'].apply(lambda x : 1 if x != -1 else 0)
road.columns = ['index', 'RNM', 'RD_SC', 'geometry', 'CR_TF']
road = road[['RNM', 'RD_SC', 'CR_TF', 'geometry']]

road.to_file(save_dir + '/sadang_road/sadang_road.shp', encoding='cp949')

del road_info&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;(4) ~ (5) 도로 데이터 분해&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;도로 중심선 데이터를 분해하여 최소단위로 분해한 ROAD_SPLIT 데이터와 VERTAX 데이터를 획득한다. 해당 데이터들은 추후 Network 알고리즘에서 Node 와 Edge로 사용될 예정이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;도로 데이터에 결합한 도로 폭 데이터는 '도시ㆍ군계획시설의 결정ㆍ구조 및 설치기준에 관한 규칙' 상 규모 별 분류 기준을 따른다. 추후 데이터 처리의 편의를 위해 Label Encoder 를 이용하여 해당 데이터를 숫자로 바꿔준다.&lt;/p&gt;
&lt;pre id=&quot;code_1676817650180&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# (4) ROAD_SPLIT
road = gpd.read_file(save_dir + '/sadang_road/sadang_road.shp', encoding='cp949')


road_spt = {'RNM':[], 'RNB':[], 'RD_SC':[], 'CR_TF':[], 'geometry':[]}

for idx, r in tqdm(enumerate(road['geometry']), leave=True):
    vtx = r.coords
    
    for v in range(len(vtx) - 1):
        road_spt['RNM'].append(road['RNM'][idx])
        road_spt['RNB'].append(v)
        road_spt['RD_SC'].append(road['RD_SC'][idx])
        road_spt['CR_TF'].append(road['CR_TF'][idx])
        road_spt['geometry'].append(LineString([vtx[v], vtx[v+1]]))
    
road_spt = gpd.GeoDataFrame(road_spt, geometry='geometry', crs=&quot;EPSG:5181&quot;)
road_spt = road_spt[road_spt.intersects(sd)]
road_spt = road_spt.reset_index(drop=True)

road_spt.to_file(save_dir + '/sadang_road/sadang_road_split.shp', encoding='cp949')

del idx, r, vtx, v


# (5)~(6) Vertax
road_spt = gpd.read_file(save_dir + '/sadang_road/sadang_road_split.shp', encoding='cp949')


vertax = {'geometry':[]}

for r in road_spt['geometry']:
    vertax['geometry'].append(r.coords[0])
    vertax['geometry'].append(r.coords[1])

vertax = pd.DataFrame(vertax)

del r


vertax['TP'] = 0 # Vertax Type : (0 : 일반) / (1 : 교차점) / (2 : Destinaion)
vertax['TP'][vertax.duplicated(subset=['geometry'], keep=False)] = 1
vertax = vertax.drop_duplicates(['geometry']).reset_index(drop=True)
vertax['geometry'] = vertax['geometry'].apply(lambda x : Point(x))
vertax['NN'] = vertax.index
vertax = vertax[['NN', 'TP', 'geometry']]

vertax = gpd.GeoDataFrame(vertax, geometry='geometry' , crs=&quot;EPSG:5181&quot;)


road_scale = ['소로', '소로1류', '소로2류', '소로3류',
              '중로1류', '중로2류', '중로3류',
              '대로1류', '대로2류', '대로3류',
              '광로1류', '광로2류', '광로3류']

encoder = LabelEncoder()
encoder.fit(road_scale)
road_spt['RD_SC'] = encoder.transform(road_spt['RD_SC'])&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;VERTAX 별 속성에 따른 타입을 부여한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;일반&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; :&amp;nbsp; 0&lt;/li&gt;
&lt;li&gt;교차점&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; :&amp;nbsp; 1&lt;/li&gt;
&lt;li&gt;거점 설치 가능 도로 교차점&amp;nbsp; &amp;nbsp;:&amp;nbsp; 2&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Type 2 는 폭이 소로 2류 이상이고 횡단보도가 지나지 않는 도로의 양 끝 점 중 교차점에 해당하는 VERTAX 가 해당한다.&lt;/p&gt;
&lt;pre id=&quot;code_1676820768710&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;destination = {'geometry':[]}

for d in tqdm(road_spt[(road_spt['RD_SC'] &amp;gt;= 9) &amp;amp; (road_spt['CR_TF'] == 0)]['geometry'], leave=True):
    d = d.coords
    
    for i in range(len(d)):
        destination['geometry'].append(d[i])

destination = pd.DataFrame(destination)
destination = destination.drop_duplicates(['geometry']).reset_index(drop=True)
destination['geometry'] = destination['geometry'].apply(lambda x : Point(x))
destination = gpd.GeoDataFrame(destination, geometry='geometry', crs=&quot;EPSG:5181&quot;)

vertax = gpd.sjoin(vertax, destination, how='left')
vertax['TP'][(vertax['TP'] == 1) &amp;amp; (vertax['index_right'].isna() == False)] = 2

vertax.to_file(save_dir + '/sadang_road/sadang_vertax.shp', encoding='cp949')

del road_scale, encoder, destination, d, i, vertax['index_right']&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;* (6) 도로 + 경사도&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;도로에 경사도를 추가하여 Network 알고리즘 상의 가중치로 활용할 예정이었으나 아직 적용하지 못 함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;(7) 건물 + 건물 출입구 데이터&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;앞서 서술했듯, 도로명주소 기준 데이터의 BPK 를 기준으로 결합한다. 출입구는 건물 내부 사람이 어느 도로 방향으로 출입하는지 판단하기 위해 사용된다.&lt;/p&gt;
&lt;pre id=&quot;code_1676817700041&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# (10) ENTERANCE + BUILDING
enter = gpd.read_file(load_dir + '/building/Z_KAIS_TL_SPBD_ENTRC_11000.shp', encoding='cp949')
enter = enter[['SIG_CD', 'BUL_MAN_NO', 'ENT_MAN_NO', 'geometry']]
enter.info()
enter.crs # EPSG 5181

enter['BPK'] = enter['SIG_CD'] + '-' + enter['BUL_MAN_NO'].astype(str)
enter = enter[['BPK', 'ENT_MAN_NO', 'geometry']]

enter = enter[enter.intersects(sd)]
enter.plot()
enter = enter.reset_index(drop=True)

col_nm = list(enter.columns)
enter = pd.merge(enter, bd, on=['BPK'], how='inner')
enter = enter.iloc[:, :len(col_nm)]
enter.columns = col_nm
enter = enter.drop_duplicates().reset_index(drop=True)

enter.to_file(save_dir + '/sadang_building/sadang_enterance.shp', encoding='cp949')

del col_nm&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;개 중에는 매칭된 출입구 데이터가 없는 건물들이 있다. 해당 건물들의 경우 따로 출입구 데이터를 만들어줘야 한다. 출입구 생성 알고리즘의 Pseudo code 는 다음과 같다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;건물 Polygon 을 LineString 단위로 분해한다.&lt;/li&gt;
&lt;li&gt;그 중 건물과 가장 가까운 도로와 가장 가까운 것을 찾는다.&lt;/li&gt;
&lt;li&gt;해당 LineString 의 중심점을 출입구로 지정한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 과정을 통해 출입구 데이터가 누락된 건물들에도 출입구 데이터를 생성해준다.&lt;/p&gt;
&lt;pre id=&quot;code_1676817719527&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;no_enter = pd.DataFrame(set(bd['BPK'].tolist()) - set(enter['BPK'].tolist()))  # Enterance 생성 (Enterance Data 누락된 경우)
no_enter.columns = ['BPK']

no_enter = pd.merge(no_enter, bd, on=['BPK'], how='left')
no_enter = no_enter[['BPK', 'geometry']]
no_enter = no_enter.drop_duplicates().reset_index(drop=True)

no_enter = gpd.GeoDataFrame(no_enter, geometry='geometry', crs=&quot;EPSG:5181&quot;)
no_enter = gpd.sjoin_nearest(no_enter, road_spt, how = 'left')
no_enter = no_enter[['BPK', 'RNM', 'geometry']]
no_enter['geometry'] = no_enter.boundary

road_unary = road_spt.unary_union
new_enter = []

for e in tqdm(no_enter['geometry'], leave=True):
    point = []
    distance = []
    
    for p in range(len(e.xy[0]) - 1):
        point.append(Point(e.xy[0][p], e.xy[1][p]))
    
    for p in point:
        distance.append(p.distance(road_unary))
    
    distance = np.array(distance)
    new_enter.append(Point( (point[np.where(distance == np.sort(distance)[0])[0][0]].x + point[np.where(distance == np.sort(distance)[1])[0][0]].x)/2
                            ,(point[np.where(distance == np.sort(distance)[0])[0][0]].y + point[np.where(distance == np.sort(distance)[1])[0][0]].y)/2 ))
    
no_enter['geometry'] = new_enter
no_enter = no_enter.reset_index().rename(columns={'index':'ENT_MAN_NO'})
no_enter['ENT_MAN_NO'] = 'no_ent' + ' ' + no_enter['ENT_MAN_NO'].astype(str)
no_enter = no_enter[['BPK', 'ENT_MAN_NO', 'geometry']]

enter = pd.concat([enter, no_enter])
enter = enter.reset_index(drop=True)

enter.to_file(save_dir + '/sadang_building/sadang_enterance.shp', encoding='cp949')

del no_enter, road_unary, new_enter, e, p, point, distance&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이렇게 데이터 전처리 과정이 마무리되었다. 이제 전처리가 완료된 데이터를 가공하여 원하는 결과물을 얻기 위한 알고리즘을 적용시킨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음은 코드 전문이다.&lt;/p&gt;
&lt;pre id=&quot;code_1676821172855&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#%% Library
import numpy as np
import pandas as pd
import geopandas as gpd
from shapely.geometry import Point, LineString
from sklearn.preprocessing import LabelEncoder

import os
import warnings
from tqdm import tqdm

#%% Setting &amp;amp; Directory
os.chdir(r'C:\Users\PC\Desktop\주영준\진행중인 프로젝트\PROJECT_NEW POINT\002 Source Code')
warnings.simplefilter(&quot;ignore&quot;)

load_dir = (r'C:\Users\PC\Desktop\주영준\진행중인 프로젝트\PROJECT_NEW POINT\001 Load Directory')
save_dir = (r'C:\Users\PC\Desktop\주영준\진행중인 프로젝트\PROJECT_NEW POINT\003 Save Directory')

#%% Data Preprocessing - (1) 사당 4동
# (1) SADANG 4
sd = gpd.read_file(load_dir + '/haengjeongdong/Z_SOP_BND_ADM_DONG_PG.shp', encoding='cp949')
sd = sd[sd['ADM_DR_NM'] == '사당4동']
sd.crs # EPSG 5181
sd = sd.geometry.iloc[0]


#%% Data Preprocessing - (2) 건물
# (2) BUILDING + PJB
bd = gpd.read_file(load_dir + '/building/Z_KAIS_TL_SPBD_BULD_11000.shp', encoding='cp949')
bd = bd[['BUL_MAN_NO', 'SIG_CD', 'EMD_CD', 'LNBR_MNNM', 'LNBR_SLNO', 'geometry']]
bd.info()
bd.crs # EPSG 5181

bd['PNU'] = bd['SIG_CD'] + bd['EMD_CD'] + '00' + '1' + bd['LNBR_MNNM'].astype(str).str.zfill(4) + bd['LNBR_SLNO'].astype(str).str.zfill(4)
bd['BPK'] = bd['SIG_CD'].astype(str) + '-' + bd['BUL_MAN_NO'].astype(str)
bd = bd[['BPK', 'PNU', 'geometry']]

bd = bd[bd.intersects(sd)]
bd.plot()
bd = bd.reset_index(drop=True)


file_columns = pd.read_excel(load_dir + '/pjb/filecolumns.xlsx')
use_cols = ['관리_건축물대장_PK', '시군구_코드', '법정동_코드', '번', '지', '주_용도_코드_명', '기타_용도', '세대_수(세대)', '가구_수(가구)']
pjb = pd.read_csv(load_dir + '/pjb/mart_djy_03.txt', sep='|', names=file_columns['mart_djy_03(pjb)'].dropna(), header=None, usecols=use_cols, dtype=str, encoding='cp949')

pjb = pjb[pjb['시군구_코드'].str[:2] == '11']
pjb['PNU'] = pjb['시군구_코드'] + pjb['법정동_코드'] + '1' + pjb['번'] + pjb['지']
pjb = pjb[['관리_건축물대장_PK', 'PNU', '주_용도_코드_명', '기타_용도', '세대_수(세대)', '가구_수(가구)']]
pjb.columns = ['PPK', 'PNU', 'MN_CD', 'ETC_CD', 'SD', 'GG']


bd = pd.merge(bd, pjb, on=['PNU'], how='left')
bd.isna().sum()

bd = bd.fillna(0)
bd['POP'] = bd['SD'].astype(int) + bd['GG'].astype(int)
bd = bd[bd['POP'] != 0]
bd = bd.reset_index(drop=True)

apt = bd[bd['ETC_CD'].str.contains('아파트') == True]['PNU'].tolist()

for a in apt:
    bd = bd[bd['PNU'] != a]

bd = bd[['PPK', 'BPK', 'PNU', 'MN_CD', 'ETC_CD', 'POP', 'geometry']]

bd.to_file(save_dir + '/sadang_building/sadang_building.shp', encoding='cp949')


del file_columns, use_cols, pjb, a, apt


#%% Data Preprocessing - (3) ~ (6) 도로
# (3) ROAD + ROAD_INFO + CROSS_WALK
road = gpd.read_file(load_dir + '/road/Z_KAIS_TL_SPRD_MANAGE_11000.shp', encoding='cp949')

road = road[['RN', 'geometry']]
road.columns = ['RNM', 'geometry']
road.crs # EPSG 5181

road = road[road.intersects(sd)]
road.plot()
road = road.reset_index(drop=True)


road_info = pd.read_csv(load_dir + '/road/서울시 도로노선 정보.csv', encoding='cp949')
road_info = road_info[['노선명(도로명)', '도로규모']]
road_info.columns = ['RNM', 'RD_SC']

road = pd.merge(road, road_info, on=['RNM'], how='left')
road = road[['RNM', 'RD_SC', 'geometry']]
road.duplicated().sum()


cross_walk = gpd.read_file(load_dir + '/seoul_cross walk/A004_A.shp', encoding='cp949')
cross_walk = cross_walk[['geometry']]
cross_walk = cross_walk.to_crs(epsg=5181) # EPSG 5186 &amp;gt; 5181

road = gpd.sjoin(road, cross_walk, how='left')
road = road.reset_index().drop_duplicates(subset=['index']).fillna(-1)
road['index_right'] = road['index_right'].apply(lambda x : 1 if x != -1 else 0)
road.columns = ['index', 'RNM', 'RD_SC', 'geometry', 'CR_TF']
road = road[['RNM', 'RD_SC', 'CR_TF', 'geometry']]

road.to_file(save_dir + '/sadang_road/sadang_road.shp', encoding='cp949')

del road_info



# (4) ROAD_SPLIT
road = gpd.read_file(save_dir + '/sadang_road/sadang_road.shp', encoding='cp949')


road_spt = {'RNM':[], 'RNB':[], 'RD_SC':[], 'CR_TF':[], 'geometry':[]}

for idx, r in tqdm(enumerate(road['geometry']), leave=True):
    vtx = r.coords
    
    for v in range(len(vtx) - 1):
        road_spt['RNM'].append(road['RNM'][idx])
        road_spt['RNB'].append(v)
        road_spt['RD_SC'].append(road['RD_SC'][idx])
        road_spt['CR_TF'].append(road['CR_TF'][idx])
        road_spt['geometry'].append(LineString([vtx[v], vtx[v+1]]))
    
road_spt = gpd.GeoDataFrame(road_spt, geometry='geometry', crs=&quot;EPSG:5181&quot;)
road_spt = road_spt[road_spt.intersects(sd)]
road_spt = road_spt.reset_index(drop=True)

road_spt.to_file(save_dir + '/sadang_road/sadang_road_split.shp', encoding='cp949')

del idx, r, vtx, v


# (5)~(6) Vertax
road_spt = gpd.read_file(save_dir + '/sadang_road/sadang_road_split.shp', encoding='cp949')


vertax = {'geometry':[]}

for r in road_spt['geometry']:
    vertax['geometry'].append(r.coords[0])
    vertax['geometry'].append(r.coords[1])

vertax = pd.DataFrame(vertax)

del r


vertax['TP'] = 0 # Vertax Type : (0 : 일반) / (1 : 교차점) / (2 : Destinaion)
vertax['TP'][vertax.duplicated(subset=['geometry'], keep=False)] = 1
vertax = vertax.drop_duplicates(['geometry']).reset_index(drop=True)
vertax['geometry'] = vertax['geometry'].apply(lambda x : Point(x))
vertax['NN'] = vertax.index
vertax = vertax[['NN', 'TP', 'geometry']]

vertax = gpd.GeoDataFrame(vertax, geometry='geometry' , crs=&quot;EPSG:5181&quot;)


road_scale = ['소로', '소로1류', '소로2류', '소로3류',
              '중로1류', '중로2류', '중로3류',
              '대로1류', '대로2류', '대로3류',
              '광로1류', '광로2류', '광로3류']

encoder = LabelEncoder()
encoder.fit(road_scale)
road_spt['RD_SC'] = encoder.transform(road_spt['RD_SC'])


destination = {'geometry':[]}

for d in tqdm(road_spt[(road_spt['RD_SC'] &amp;gt;= 9) &amp;amp; (road_spt['CR_TF'] == 0)]['geometry'], leave=True):
    d = d.coords
    
    for i in range(len(d)):
        destination['geometry'].append(d[i])

destination = pd.DataFrame(destination)
destination = destination.drop_duplicates(['geometry']).reset_index(drop=True)
destination['geometry'] = destination['geometry'].apply(lambda x : Point(x))
destination = gpd.GeoDataFrame(destination, geometry='geometry', crs=&quot;EPSG:5181&quot;)

vertax = gpd.sjoin(vertax, destination, how='left')
vertax['TP'][(vertax['TP'] == 1) &amp;amp; (vertax['index_right'].isna() == False)] = 2

vertax.to_file(save_dir + '/sadang_road/sadang_vertax.shp', encoding='cp949')

del road_scale, encoder, destination, d, i, vertax['index_right']


#%% Data Preprocessing - (7) 출입구
bd = gpd.read_file(save_dir + '/sadang_building/sadang_building.shp', encoding='cp949')
road_spt = gpd.read_file(save_dir + '/sadang_road/sadang_road_split.shp', encoding='cp949')


# (10) ENTERANCE + BUILDING
enter = gpd.read_file(load_dir + '/building/Z_KAIS_TL_SPBD_ENTRC_11000.shp', encoding='cp949')
enter = enter[['SIG_CD', 'BUL_MAN_NO', 'ENT_MAN_NO', 'geometry']]
enter.info()
enter.crs # EPSG 5181

enter['BPK'] = enter['SIG_CD'] + '-' + enter['BUL_MAN_NO'].astype(str)
enter = enter[['BPK', 'ENT_MAN_NO', 'geometry']]

enter = enter[enter.intersects(sd)]
enter.plot()
enter = enter.reset_index(drop=True)

col_nm = list(enter.columns)
enter = pd.merge(enter, bd, on=['BPK'], how='inner')
enter = enter.iloc[:, :len(col_nm)]
enter.columns = col_nm
enter = enter.drop_duplicates().reset_index(drop=True)

enter.to_file(save_dir + '/sadang_building/sadang_enterance.shp', encoding='cp949')

del col_nm


no_enter = pd.DataFrame(set(bd['BPK'].tolist()) - set(enter['BPK'].tolist()))  # Enterance 생성 (Enterance Data 누락된 경우)
no_enter.columns = ['BPK']

no_enter = pd.merge(no_enter, bd, on=['BPK'], how='left')
no_enter = no_enter[['BPK', 'geometry']]
no_enter = no_enter.drop_duplicates().reset_index(drop=True)

no_enter = gpd.GeoDataFrame(no_enter, geometry='geometry', crs=&quot;EPSG:5181&quot;)
no_enter = gpd.sjoin_nearest(no_enter, road_spt, how = 'left')
no_enter = no_enter[['BPK', 'RNM', 'geometry']]
no_enter['geometry'] = no_enter.boundary

road_unary = road_spt.unary_union
new_enter = []

for e in tqdm(no_enter['geometry'], leave=True):
    point = []
    distance = []
    
    for p in range(len(e.xy[0]) - 1):
        point.append(Point(e.xy[0][p], e.xy[1][p]))
    
    for p in point:
        distance.append(p.distance(road_unary))
    
    distance = np.array(distance)
    new_enter.append(Point( (point[np.where(distance == np.sort(distance)[0])[0][0]].x + point[np.where(distance == np.sort(distance)[1])[0][0]].x)/2
                            ,(point[np.where(distance == np.sort(distance)[0])[0][0]].y + point[np.where(distance == np.sort(distance)[1])[0][0]].y)/2 ))
    
no_enter['geometry'] = new_enter
no_enter = no_enter.reset_index().rename(columns={'index':'ENT_MAN_NO'})
no_enter['ENT_MAN_NO'] = 'no_ent' + ' ' + no_enter['ENT_MAN_NO'].astype(str)
no_enter = no_enter[['BPK', 'ENT_MAN_NO', 'geometry']]

enter = pd.concat([enter, no_enter])
enter = enter.reset_index(drop=True)

enter.to_file(save_dir + '/sadang_building/sadang_enterance.shp', encoding='cp949')

del no_enter, road_unary, new_enter, e, p, point, distance&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://paprikafarm.tistory.com/34&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2023.02.19 - [Algorithm] - [Algorithm] New Point 쓰레기 처리 시스템 구축 알고리즘 (1) Project Structure&lt;/a&gt;&lt;/p&gt;</description>
      <category>Algorithm</category>
      <category>NEW POINT</category>
      <category>공공데이터</category>
      <category>대학생</category>
      <category>쓰레기</category>
      <category>쓰레기 배출</category>
      <category>알고리즘</category>
      <category>프로젝트</category>
      <author>몽골리안 파프리카</author>
      <guid isPermaLink="true">https://paprikafarm.tistory.com/35</guid>
      <comments>https://paprikafarm.tistory.com/35#entry35comment</comments>
      <pubDate>Sun, 19 Feb 2023 23:38:31 +0900</pubDate>
    </item>
    <item>
      <title>[Algorithm] New Point 쓰레기 처리 시스템 구축 알고리즘 (1) Project Structure</title>
      <link>https://paprikafarm.tistory.com/34</link>
      <description>&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;NEW POINT 프로젝트는 기존 문전 수거방식이 주를 이루는 쓰레기 수거 시스템을 거점형 수거 방식으로 변경함으로써 보다 효율적, 경제적 쓰레기 처리 시스템을 구축하는 것을 목표로 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이전에 포스팅한 쓰레기 배출 시뮬레이션 역시 본 프로젝트의 일환으로 쓰레기 배출량을 예측하기 위해 고안되었다. 본 포스팅은 쓰레기 배출 시뮬레이션 알고리즘을 포함한 쓰레기 거점 설치 최적 장소 선별 및 수거 경로 추출 알고리즘 등을 결합한 단일의 프로젝트에 대한 설명을 기술한다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;edited_New Point_.png&quot; data-origin-width=&quot;720&quot; data-origin-height=&quot;405&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/basbYZ/btrZKp1k25d/irmNhqkmn9tU5iI6CAdUn1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/basbYZ/btrZKp1k25d/irmNhqkmn9tU5iI6CAdUn1/img.png&quot; data-alt=&quot;Project Structure&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/basbYZ/btrZKp1k25d/irmNhqkmn9tU5iI6CAdUn1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbasbYZ%2FbtrZKp1k25d%2FirmNhqkmn9tU5iI6CAdUn1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;720&quot; height=&quot;405&quot; data-filename=&quot;edited_New Point_.png&quot; data-origin-width=&quot;720&quot; data-origin-height=&quot;405&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Project Structure&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;프로젝트는 크게 3 파트로 구성된다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;1. 데이터 준비&lt;br /&gt;2. 데이터 전처리&lt;br /&gt;3. 알고리즘 적용&lt;/blockquote&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. 데이터 준비&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;위 도식도에는 1. 데이터 준비 과정은 포함되어 있지 않다.&amp;nbsp;프로젝트에서 사용되는 원천 데이터는 다음과 같다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 159px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 9.72873%; height: 20px; text-align: center;&quot;&gt;번호&lt;/td&gt;
&lt;td style=&quot;width: 22.8295%; text-align: center; height: 20px;&quot;&gt;변수 명&lt;/td&gt;
&lt;td style=&quot;width: 33.6435%; height: 20px; text-align: center;&quot;&gt;데이터 명&lt;/td&gt;
&lt;td style=&quot;width: 33.7983%; height: 20px; text-align: center;&quot;&gt;출처&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 9.72873%; text-align: center; height: 20px;&quot;&gt;1&lt;/td&gt;
&lt;td style=&quot;width: 22.8295%; text-align: center; height: 20px;&quot;&gt;행정동 (SADANG4)&lt;/td&gt;
&lt;td style=&quot;width: 33.6435%; text-align: center; height: 20px;&quot;&gt;(센서스경계) 행정동 경계&lt;br /&gt;(Z_SOP_BND_ADM_DONG_PG)&lt;/td&gt;
&lt;td style=&quot;width: 33.7983%; text-align: center; height: 20px;&quot;&gt;국가공간정보포털 오픈마켓&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 9.72873%; height: 17px; text-align: center;&quot;&gt;2&lt;/td&gt;
&lt;td style=&quot;width: 22.8295%; text-align: center; height: 17px;&quot;&gt;PJB&lt;/td&gt;
&lt;td style=&quot;width: 33.6435%; height: 17px; text-align: center;&quot;&gt;건축물대장 표제부&lt;br /&gt;(mart_djy_03)&lt;/td&gt;
&lt;td style=&quot;width: 33.7983%; height: 17px; text-align: center;&quot;&gt;건축데이터 민간개방 시스템&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 9.72873%; height: 17px; text-align: center;&quot;&gt;3&lt;/td&gt;
&lt;td style=&quot;width: 22.8295%; text-align: center; height: 17px;&quot;&gt;BUILDING&lt;/td&gt;
&lt;td style=&quot;width: 33.6435%; height: 17px; text-align: center;&quot;&gt;(도로명주소) 건물&lt;br /&gt;(Z_KAIS_TL_SPBD_BULD_11000)&lt;/td&gt;
&lt;td style=&quot;width: 33.7983%; height: 17px; text-align: center;&quot;&gt;국가공간정보포털 오픈마켓&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 9.72873%; height: 17px; text-align: center;&quot;&gt;4&lt;/td&gt;
&lt;td style=&quot;width: 22.8295%; text-align: center; height: 17px;&quot;&gt;ENTERANCE&lt;/td&gt;
&lt;td style=&quot;width: 33.6435%; height: 17px; text-align: center;&quot;&gt;(도로명주소) 출입&lt;br /&gt;(Z_KAIS_TL_SPBD_ENTRC_11000)&lt;/td&gt;
&lt;td style=&quot;width: 33.7983%; height: 17px; text-align: center;&quot;&gt;국가공간정보포털 오픈마켓&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 9.72873%; height: 17px; text-align: center;&quot;&gt;5&lt;/td&gt;
&lt;td style=&quot;width: 22.8295%; text-align: center; height: 17px;&quot;&gt;ROAD&lt;/td&gt;
&lt;td style=&quot;width: 33.6435%; height: 17px; text-align: center;&quot;&gt;(도로명주소) 도로구간&lt;br /&gt;(Z_KAIS_TL_SPRD_MANAGE_11000)&lt;/td&gt;
&lt;td style=&quot;width: 33.7983%; height: 17px; text-align: center;&quot;&gt;국가공간정보포털 오픈마켓&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 9.72873%; height: 17px; text-align: center;&quot;&gt;6&lt;/td&gt;
&lt;td style=&quot;width: 22.8295%; text-align: center; height: 17px;&quot;&gt;ROAD_INFO&lt;/td&gt;
&lt;td style=&quot;width: 33.6435%; height: 17px; text-align: center;&quot;&gt;서울시&amp;nbsp;도로노선&amp;nbsp;정보&lt;/td&gt;
&lt;td style=&quot;width: 33.7983%; height: 17px; text-align: center;&quot;&gt;서울 열린데이터 광장&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 9.72873%; height: 17px; text-align: center;&quot;&gt;7&lt;/td&gt;
&lt;td style=&quot;width: 22.8295%; text-align: center; height: 17px;&quot;&gt;CROSS_WALK&lt;/td&gt;
&lt;td style=&quot;width: 33.6435%; height: 17px; text-align: center;&quot;&gt;서울시 교통안전시설물 횡단보도&lt;br /&gt;(A004_A)&lt;/td&gt;
&lt;td style=&quot;width: 33.7983%; height: 17px; text-align: center;&quot;&gt;서울 열린데이터 광장&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 9.72873%; text-align: center; height: 17px;&quot;&gt;8&lt;/td&gt;
&lt;td style=&quot;width: 22.8295%; text-align: center; height: 17px;&quot;&gt;GRADIENT&lt;/td&gt;
&lt;td style=&quot;width: 33.6435%; text-align: center; height: 17px;&quot;&gt;서울특별시 경사도&lt;br /&gt;(N3L_F001)&lt;/td&gt;
&lt;td style=&quot;width: 33.7983%; text-align: center; height: 17px;&quot;&gt;공공데이터 포털&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;모두 무료로 개방 중인 공공데이터를 활용했다. 데이터 중 BUILDING, ENTERANCE, ROAD 는 데이터 명이 Z_KAIS 로 시작한다. 모두 도로명 주소를 기준으로 정리된 shp 파일들이다. 이들 데이터를 도로명 주소를 기준으로 통일한 이유는 간단하다. 대부분 geometry 데이터들은 서로 아귀가 맞지 않는 경우가 많다. 기준이 다른 경우 어긋남이 더 심해진다. 해서 제공 데이터의 기준을 맞췄고, 기준이 맞춰진 채 제공되는 데이터 들 중 건물, 건물 출입구, 도로 데이터를 모두 구할 수 있는 데이터셋이 도로명주소 기준 데이터셋이었기 때문에 도로명주소 기준 데이터 셋을 준비했다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2. 데이터 전처리 &amp;amp; 3. 알고리즘 적용&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;데이터 전처리와 알고리즘 적용 부분은 이 다음 포스팅에서 코드와 함께 자세히 설명할 예정이다. 본 포스팅에서는 데이터 처리 구조와 그 논리에 대한 내용을 다룬다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;프로젝트의 최종 목적은&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;쓰레기 배출 거점 시설 (New Point) 의 최적 입지 장소 찾기&lt;/li&gt;
&lt;li&gt;쓰레기 수거 차량의 이동 동선 구하기&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;이다. 이를 위해서는 주민과 수거 차량의 입장 모두를 고려해야 한다. 주민의 입장에서는 이동 거리가 많은 선에서 쓰레기를 버릴 수 있어야 한다. 이때, 평소 자주 가는 동선에 거점이 위치한다면 더 수월하게 쓰레기를 배출할 수 있다. 수거 차량 입장에서는 차량이 진입 가능한 곳이어야 하며, 가능한 간결한 동선으로 수거를 마쳐야 한다. 때문에 배출 거점 시설의 입지 요건은 다음과 같이 정리할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;도로폭이 충분히 넓은 곳에 위치한다.&lt;/li&gt;
&lt;li&gt;너무 멀지 않은 거리 안에 위치한다.&lt;/li&gt;
&lt;li&gt;평소 사람들이 자주 지나치는 곳에 위치한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 조건들을 만족하는 장소를 추출한 뒤 그 중에서도 적절한 장소를 선정하여 그 곳을 지나는 경로를 생성한다면 프로젝트의 목표를 달성할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이상으로 NEW POINT 프로젝트의 기본 개요에 대한 기술이 끝났다. 다음 포스팅 부터는 소스코드와 함께 보다 자세한 과정에 대해 기술한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://paprikafarm.tistory.com/35&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2023.02.19 - [Algorithm] - [Algorithm] New Point 쓰레기 처리 시스템 구축 알고리즘 (2) Data Preprocessing&lt;/a&gt;&lt;/p&gt;</description>
      <category>Algorithm</category>
      <category>NEW POINT</category>
      <category>공공데이터</category>
      <category>대학생</category>
      <category>쓰레기</category>
      <category>쓰레기 배출</category>
      <category>알고리즘</category>
      <category>프로젝트</category>
      <author>몽골리안 파프리카</author>
      <guid isPermaLink="true">https://paprikafarm.tistory.com/34</guid>
      <comments>https://paprikafarm.tistory.com/34#entry34comment</comments>
      <pubDate>Sun, 19 Feb 2023 17:00:08 +0900</pubDate>
    </item>
    <item>
      <title>[Algorithm] 쓰레기 배출 시뮬레이션 (2)</title>
      <link>https://paprikafarm.tistory.com/19</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;정제한 데이터에 필지 별로 거점을 부여한다. 정확히는 행위자가 이용할 것으로 예상되는 거점을 matching 한다. 17개 거점 중 행위자가 어떤 거점을 이용할까. 당연히 제일 가까운 곳을 이용할 가능성이 크다. 해서, 행위자 기준 100m 이내에 위치한 거점을 대상 거점으로 부여했다. 100m 이내에 거점이 없는 행위자는 150m 이내 가장 가까운 거점 한 곳을 부여했다.&lt;/p&gt;
&lt;pre id=&quot;code_1673247497262&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#%% New Point 좌표 생성
new_point = {'point_number':range(0, 17),
              'geometry':[Point(197386.30,442712.87), Point(197538.45,442701.02), Point(197443.36,442582.25), Point(197398.14,442500.79), Point(197847.41,442528.07),
                    Point(197546.34,442469.94), Point(197669.78,442467.06), Point(197737.24,442488.59), Point(197264.30,442434.05), Point(197270.76,442360.13),
                    Point(197440.13,442383.82), Point(197601.60,442335.01), Point(197519.07,442228.80), Point(197427.21,442180.00), Point(197380.56,442071.63),
                    Point(197326.74,442041.49), Point(197308.80,442511.56)]}

new_point = gpd.GeoDataFrame(new_point, geometry='geometry')
new_point = new_point.set_crs(epsg=5181, inplace=True)

new_point.to_file(save_dir + '/New Point/new_point.shp', encoding='cp949')


#%% 거리 연산
sd = gpd.read_file(save_dir + '/sadang4/sadang4.shp', encoding='cp949')
new_point = gpd.read_file(save_dir + '/New Point/new_point.shp', encoding='cp949')


def shortest_distance_func(df1, df2):
    nearest_point = []
    
    for t in tqdm(df1['geometry'], leave=True):
        point = []
        
        for idx, n in enumerate(df2['geometry']):
            d = t.distance(n)
            
            if d &amp;lt;= 100:
                point.append(idx)
            
            
        if len(point) == 0:
            for idx, n in enumerate(df2['geometry']):
                if t.distance(n) &amp;lt;= 150:
                    point.append(idx)
        
        nearest_point.append(point)    

    return nearest_point


near_point = shortest_distance_func(sd, new_point)
sd['near_point'] = near_point

sd = sd[['PNU', 'JIBUN', 'PPK', 'USE_CODE_0', 'USE_CODE_1', 'SD', 'GG', 'near_point', 'geometry']]

del near_point&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이제 데이터 정제가 끝났으니 본격적으로 쓰레기 배출 시뮬레이션 소스코드를 살펴본다. 시뮬레이션 규칙은 다음과 같다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;1. 행위자는 세대로 정한다.&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;2. 행위자는 1 ~ 7 일 중 랜덤으로 쓰레기 배출 주기를 부여받는다.&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;3. 쓰레기 배출일이 되면 0 ~ 23 시 중 랜덤으로 쓰레기 배출 시간을 부여받는다.&lt;/b&gt;&lt;br /&gt;* 쓰레기 수거는 21 시에 이루어지며, 21 시 이후에 쌓인 쓰레기는 다음날 수거된다.&lt;br /&gt;* 쓰레기 배출 시간은 아래와 같이 시간 별로 가중치를 가진다.&lt;br /&gt;[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ]&lt;br /&gt;[ 1 1 1 1 1 1 1 1 2 2&amp;nbsp; 2&amp;nbsp; &amp;nbsp;2&amp;nbsp; &amp;nbsp;2&amp;nbsp; &amp;nbsp;2&amp;nbsp; &amp;nbsp;2&amp;nbsp; &amp;nbsp;2&amp;nbsp; &amp;nbsp;2&amp;nbsp; &amp;nbsp;3&amp;nbsp; &amp;nbsp;3&amp;nbsp; &amp;nbsp;3&amp;nbsp; &amp;nbsp;3&amp;nbsp; &amp;nbsp;3&amp;nbsp; &amp;nbsp;2&amp;nbsp; &amp;nbsp;2&amp;nbsp; ]&lt;br /&gt;&lt;br /&gt;&lt;b&gt;4. 행위자는 쓰레기 배출 시 아래 식에 따른 양만큼의 쓰레기를 배출한다.&lt;/b&gt;&lt;br /&gt;(배출량) = (배출 주기) X (사당 4동 평균 세대 별 인구) X (동작구 일별 1인당 평균 쓰레기 배출량)&lt;br /&gt;ex) 3일 만에 쓰레기 배출하는 경우, 3 X 1.94 X 0.8 = 4.656 (kg) 배출&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;규칙을 알고리즘으로 구현한 코드는 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1673247582186&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def simulation_func(df1, df2, days, waste_type, seed):
    time_weight = np.array([1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 2])
    wt = {'일반':1.98*0.8*0.361, '재활용':1.98*0.8*0.361, '음식물':1.98*0.8*0.278}

    random.seed(seed)
    
    result = np.zeros((days, len(df2)))
    
    ems_cycle = []                                                             # 배출 주기 생성
    for e in range(len(df1)):
        ems_cycle.append(random.choices(range(1, 7))[0])
    ems_cycle = np.array(ems_cycle)
    ems_cycle_cal = ems_cycle.copy()
    
    for d in range(days):
        ems_cycle -= 1
        
        target = np.where(ems_cycle == 0)[0]                                   # 배출 행위자
        
        ems_time = []                                                          # 행위자 별 배출 시간
        ems_point = []                                                         # 배출 Point
        for ta in target:
            ems_time.append(random.choices(range(0, 24),                       
                                           weights=time_weight)[0])
            ems_point.append(random.choices(sd['near_point'][ta])[0])          
        ems_time = np.array(ems_time)
        ems_point = np.array(ems_point)
        
        for p in df2['point_numb']:
            t = np.where(ems_point == p)[0]
            
            for a in t:
                if ems_time[a] &amp;lt;= 21:
                    result[d, p] += df1['SD'][a] * wt[waste_type] * ems_cycle_cal[a]
                    
                elif d &amp;lt; days - 1:
                    result[d, p] += df1['SD'][a] * wt[waste_type] * ems_cycle_cal[a]
                    
        for ta in target:
            ems_cycle[ta] = random.choices(range(1, 7))[0]
            ems_cycle_cal[ta] = random.choices(range(1, 7))[0]
        
    return pd.DataFrame(result)

waste_general, waste_food, waste_recycle = simulation_func(sd, new_point, 30, '일반', 123), simulation_func(sd, new_point, 30, '음식물', 124), simulation_func(sd, new_point, 30, '재활용', 125)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;실제 시뮬레이션에서는 4 번 규칙이 약간 변경되었다. 쓰레기 종류를 구분했다. 평균적으로&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[ 음식물 쓰레기 : 일반 쓰레기 : 재활용 쓰레기 = 1 : 1.3 : 1.3 ] 비율로 배출되기 때문에 4.656 (kg) 을 해당 비율로 나눴다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;쓰레기 종류 별로 random seed 값을 다르게 준 이유는 쓰레기 배출을 한꺼번에 하지는 않는다고 생각했기 때문이다. 내가 아는 한, 그때그때 쓰레기통이 꽉 차면 버리는 경우가 많아서 seed 를 다르게 줬다. 아님 말고~ 고치면 된다. 사실 seed 값이 다르다고 해서 결과가 크게 달라지지는 않는다. 행위자 수가 가장 큰 영향을 미치는 모양이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;시뮬레이션 결과의 기술통계는 다음과 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;968&quot; data-origin-height=&quot;646&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1iqpT/btrVOA5IPe5/6JaGk6Qw2beNk2t02QVu70/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1iqpT/btrVOA5IPe5/6JaGk6Qw2beNk2t02QVu70/img.png&quot; data-alt=&quot;기술통계 [평균, 최댓값, 최솟값]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1iqpT/btrVOA5IPe5/6JaGk6Qw2beNk2t02QVu70/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1iqpT%2FbtrVOA5IPe5%2F6JaGk6Qw2beNk2t02QVu70%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;566&quot; height=&quot;378&quot; data-origin-width=&quot;968&quot; data-origin-height=&quot;646&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;기술통계 [평균, 최댓값, 최솟값]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1746&quot; data-origin-height=&quot;387&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dtz1jU/btrVO1osZwG/bpDbg1kC8DjuIm2o2vfaek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dtz1jU/btrVO1osZwG/bpDbg1kC8DjuIm2o2vfaek/img.png&quot; data-alt=&quot;Barplot (순서대로 음식물, 일반, 재활용 쓰레기)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dtz1jU/btrVO1osZwG/bpDbg1kC8DjuIm2o2vfaek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdtz1jU%2FbtrVO1osZwG%2FbpDbg1kC8DjuIm2o2vfaek%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1746&quot; height=&quot;387&quot; data-origin-width=&quot;1746&quot; data-origin-height=&quot;387&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Barplot (순서대로 음식물, 일반, 재활용 쓰레기)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;기술 통계량 중 평균치를 기준으로 위계를 설정했다. 하루 150 (kg) 까지는 0, 200 (kg) 까지는 1, 그 이상은 2로 설정하고 mapboxgl 라이브러리를 이용해 맵박스로 나타냈다.&lt;/p&gt;
&lt;pre id=&quot;code_1673249938036&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#%% 시각화
# Barplot
plt.figure(figsize = (15, 10))
sns.boxplot(data = waste_general)
plt.title('General_Waste', size = 15)
plt.savefig(save_dir + '/Img/General_Waste.png', dpi=100)
plt.show()

plt.figure(figsize = (15, 10))
sns.boxplot(data = waste_food)
plt.title('Food_Waste', size = 15)
plt.savefig(save_dir + '/Img/Food_Waste.png', dpi=100)
plt.show()

plt.figure(figsize = (15, 10))
sns.boxplot(data = waste_recycle)
plt.title('Recycle_Waste', size = 15)
plt.savefig(save_dir + '/Img/Recycle_Waste.png', dpi=100)
plt.show()

del waste_food, waste_general, waste_recycle, dsc_sts


new_point['geometry'] = new_point.buffer(5)

result = sd[['PNU', 'SD', 'geometry']]
result = pd.concat([result, new_point])
result = result.fillna('-')
result = result.to_crs(epsg=4326)

result.to_file(save_dir + '/Result/Result.shp', encoding='cp949')


# shp -&amp;gt; geojson 변환
sf = shapefile.Reader(save_dir + '/Result/Result')

field_names = ['PNU', 'SD', 'point_numb', 'hierachy']

fields = sf.fields[1:]
for idx, field in enumerate(fields):
    field[0] = field_names[idx]

del idx, field

geometry = []
for sr in sf.shapeRecords():
    atr = dict(zip(field_names, sr.record))

    geom = sr.shape.__geo_interface__
    geometry.append(dict(type=&quot;Feature&quot;, geometry=geom, properties=atr))

geojson = open(save_dir + '/Result/Result.geojson', &quot;w&quot;)
geojson.write(json.dumps({&quot;type&quot;: &quot;FeatureCollection&quot;, &quot;features&quot;: geometry}, indent=2, ensure_ascii=False))
geojson.close()


# Mapbox 시각화
geo_data = save_dir + '/Result/Result.geojson'

with open(geo_data) as f:
    data = json.loads(f.read())

token = 'pk.eyJ1IjoiZ2xvd2Z1ciIsImEiOiJjbDhpYXY4dzIwcDFxM3htcm4zcTZvNW5yIn0.BkTWPUipoFZZoCeifngJiw'
# 이건 내 토큰이니까 각자 발급해서 쓰세용
center = [126.9716483,37.4809714]

match_color_stops = [
    ['0', 'rgb(255,255,0)'],
    ['1', 'rgb(255,165,0)'],
    ['2', 'rgb(255,69,0)']]
match_height_stops = [
    ['0', 10],
    ['1', 10],
    ['2', 10]]

viz = ChoroplethViz(
    access_token = token,
    data = data,
    color_function_type = 'match',
    color_property = 'hierachy',
    color_stops = match_color_stops, 
    color_default ='rgb(128,128,128)',
    center = center,
    zoom = 16)

viz.bearing = -15
viz.pitch = 45
viz.height_function_type = 'match'
viz.height_property = 'hierachy'
viz.height_stops = match_height_stops


html = open(save_dir + '/Result/Visualization.html', &quot;w&quot;, encoding=&quot;utf-8&quot;)
html.write(viz.create_html())
html.close()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; 맵박스 시각화 결과는 다음과 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1901&quot; data-origin-height=&quot;897&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bUN9ow/btrVOSLWCms/oqXmJ0PpjEtnO6P2AAB230/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bUN9ow/btrVOSLWCms/oqXmJ0PpjEtnO6P2AAB230/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bUN9ow/btrVOSLWCms/oqXmJ0PpjEtnO6P2AAB230/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbUN9ow%2FbtrVOSLWCms%2FoqXmJ0PpjEtnO6P2AAB230%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1901&quot; height=&quot;897&quot; data-origin-width=&quot;1901&quot; data-origin-height=&quot;897&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;시뮬레이션 결과는 반복 수행에도 크게 변화하지 않았다. 거점 별 수용량이 적절하게 계산되었다고 볼 수 있을 것 같다. 다만, 음식점이나 시장, 편의점 등에서 배출되는 쓰레기 처리 실태를 모르다 보니, 꽤 큰 변수를 제외하고 만들어진 시뮬레이션이라는 점에서 문제가 있다고 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;시뮬레이션과는 별개로 거점들의 위치가 적절한지, 님비현상을 어떻게 해결할건 지 등 중차대한 문제가 남아있다. 지도 상에서 유휴부지를 걸러내는 알고리즘을 만들어서 거점을 보다 적절하게 배치해 볼 생각이다.&lt;/p&gt;</description>
      <category>Algorithm</category>
      <category>Mapbox</category>
      <category>도시재생</category>
      <category>사당 4동</category>
      <category>시각화</category>
      <category>시뮬레이션</category>
      <category>쓰레기</category>
      <category>알고리즘</category>
      <author>몽골리안 파프리카</author>
      <guid isPermaLink="true">https://paprikafarm.tistory.com/19</guid>
      <comments>https://paprikafarm.tistory.com/19#entry19comment</comments>
      <pubDate>Mon, 9 Jan 2023 16:46:45 +0900</pubDate>
    </item>
    <item>
      <title>[Algorithm] 쓰레기 배출 시뮬레이션 (1)</title>
      <link>https://paprikafarm.tistory.com/18</link>
      <description>&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;소위 '빌라촌'의 고질적 문제는 주차와 쓰레기 문제 등이 있다. 골목길을 넓히고 유휴부지를 충분히 확보하면 해결될 문제들이지만, 현실적으로 쉽지 않다. 동시에 꼭 해결되어야 할 문제이기도 하다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;해서, 지난 학기 도시재생 수업 중 '사당 4동 도시재생 프로젝트 과제' 를 통해 사당 4동의 쓰레기 문제를 해결하기 위한 방안으로 강구해낸 방법이 쓰레기 수거 방식의 변화였다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_20230109_154952394.jpg&quot; data-origin-width=&quot;1613&quot; data-origin-height=&quot;907&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Xa9zx/btrVOdXfa8L/APGN8opSs9t5DZ8rZuk9dk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Xa9zx/btrVOdXfa8L/APGN8opSs9t5DZ8rZuk9dk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Xa9zx/btrVOdXfa8L/APGN8opSs9t5DZ8rZuk9dk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXa9zx%2FbtrVOdXfa8L%2FAPGN8opSs9t5DZ8rZuk9dk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;360&quot; height=&quot;202&quot; data-filename=&quot;KakaoTalk_20230109_154952394.jpg&quot; data-origin-width=&quot;1613&quot; data-origin-height=&quot;907&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_20230109_154952394_01.jpg&quot; data-origin-width=&quot;1613&quot; data-origin-height=&quot;907&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/czvPLI/btrVIwceDiq/aHDN9Y8iknO8lkq6rKR4lk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/czvPLI/btrVIwceDiq/aHDN9Y8iknO8lkq6rKR4lk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/czvPLI/btrVIwceDiq/aHDN9Y8iknO8lkq6rKR4lk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FczvPLI%2FbtrVIwceDiq%2FaHDN9Y8iknO8lkq6rKR4lk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;364&quot; height=&quot;205&quot; data-filename=&quot;KakaoTalk_20230109_154952394_01.jpg&quot; data-origin-width=&quot;1613&quot; data-origin-height=&quot;907&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;우리나라의 쓰레기 수거 체계는 크게 3가지로 나눌 수 있다. 문전수거 방식 / 거점형 수거 방식 / 혼합형 수거 방식 이 그것이다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;먼저 문전수거 방식은 말 그대로 각자 집 앞에 쓰레기를 배출하는 방식이다. 배출 요일과 시간이 정해져 있어서 해당 시점에 쓰레기를 배출해야 한다. 대부분 빌라촌에서 사용되는 방식이며, 규칙만 존재할 뿐 관리인이 없으니 주민 갈등이 자주 일어나는 방식이기도 하다. 단순히 문 앞에 쓰레기를 모아두는 방식이기 때문에 미관상 좋지 않고 여름철 악취 문제도 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;거점형 수거 방식은 특정한 쓰레기 배출 장소, 즉, 거점을 두고 그 곳에 쓰레기를 배출하는 방식이다. 대부분 아파트에서 차용하는 방식이며, 보통은 관리인이 있기 때문에 부정적 외부효과가 비교적 덜하다. 하지만 거점을 설치할 공간이나 관리 인력이 필요하다는 점에서 아파트처럼 공간 확보가 용이하지 않은 주거 환경에는 적용하기 힘들다는 단점이 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;혼합형 수거 방식은 문전수거와 거점형 수거 방식이 합쳐진 방식이다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;본 프로젝트의 핵심은 기존 문전수거 방식이었던 쓰레기 수거 체계를 거점형 수거 방식으로 바꾸는 데 있다. 기존 체계에서 벗어나 새로운 체계를 도입하는 만큼 여러 경제적, 사회적 요인들을 고려해 득실을 따져야 한다. 쓰레기 배출 시뮬레이션 알고리즘 역시 이러한 맥락에서 만들어졌다. 한정된 공간과 예산을 가장 효율적으로 사용하기 위해서는 거점 별 쓰레기 수용량을 최적화해야 한다. 시뮬레이션을 통해 각각의 거점이 수용해야 할 쓰레기 용량이 어느정도 인지 가늠해 본다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;연구 모델은 크게 두 단계를 거친다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;1. 데이터 정제&lt;br /&gt;2. 시뮬레이션&lt;/blockquote&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;데이터 정제 단계에서는 사당 4동의 연속지적도와 건축물대장(표제부)을 결합하여 필지 별 세대 수를 추출한다. 그리고 필지 별 거점을 할당한다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;시뮬레이션 단계에서는 각 세대를 행위자로 설정한 후 쓰레기 배출 규칙을 부여해 거점 별 쓰레기 수용량을 확인한다.&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;작성한 코드를 보며 자세한 설명을 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1673242709053&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#%% Library
import numpy as np
import random
import pandas as pd
import geopandas as gpd
from shapely.geometry import Point

from tqdm import tqdm
import warnings
import matplotlib.pyplot as plt
import seaborn as sns
import shapefile
import json
from mapboxgl.viz import *
from mapboxgl.utils import *

#%% Directory
load_dir = (r'C:\Users\PC\Desktop\주영준\진행중인 프로젝트\New Point\001 Load Directory')
save_dir = (r'C:\Users\PC\Desktop\주영준\진행중인 프로젝트\New Point\003 Save Directory')

warnings.filterwarnings(action='ignore')&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서울시 연속지적도와 센서스 행정동 경계 shp 파일을 이용해 사당 4동의 연속 지적도를 추출한 후, 표제부와 결합한다.&lt;/p&gt;
&lt;pre id=&quot;code_1673242788898&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 사당4동 연속지적도 생성
sd = gpd.read_file(load_dir + '/haengjeongdong/Z_SOP_BND_ADM_DONG_PG.shp', encoding='cp949')
sd = sd[sd['ADM_DR_NM'] == '사당4동']
sd = sd[['ADM_DR_NM', 'geometry']]

jijuk = gpd.read_file(load_dir + '/jijuk_dongjak/LSMD_CONT_LDREG_11590.shp', encoding='cp949')
jijuk = gpd.GeoDataFrame(jijuk, geometry='geometry', crs=5186)
jijuk = jijuk.to_crs(5181)


sd = gpd.overlay(jijuk, sd, how='intersection')
sd = sd[['pnu', 'jibun', 'geometry']]
sd.columns = ['PNU', 'JIBUN', 'geometry']
sd = sd.reset_index(drop=True)
sd.plot()

sd.to_file(save_dir + '/sadang4/sadang4.shp', encoding='cp949')


# 연속지적도 표제부 결합
file_columns = pd.read_excel(load_dir + '/filcolumns.xlsx')
use_cols = ['관리_건축물대장_PK', '시군구_코드', '법정동_코드', '대지_구분_코드', '번', '지', '주_용도_코드_명', '기타_용도', '세대_수(세대)', '가구_수(가구)']

pjb = pd.read_csv(load_dir + '/pjb/mart_djy_03.txt', sep='|', names=file_columns['mart_djy_03(pjb)'].dropna(), header=None, usecols=use_cols, dtype=str, encoding='cp949')
pjb.isna().sum()

pjb = pjb.dropna(axis=0, subset=['대지_구분_코드'])
pjb['대지_구분_코드'] = pjb['대지_구분_코드'].astype(int)
pjb['대지_구분_코드'] += 1
pjb['대지_구분_코드'] = pjb['대지_구분_코드'].astype(str)

pjb['PNU'] = pjb['시군구_코드'] + pjb['법정동_코드'] + pjb['대지_구분_코드'] + pjb['번'] + pjb['지']

pjb.columns = ['PPK', '시군구_코드', '법정동_코드', '대지_구분_코드', '번', '지', 'USE_CODE_0_NM', 'USE_CODE_1_NM', 'SD', 'GG', 'PNU']
pjb = pjb[['PNU', 'PPK', 'USE_CODE_0', 'USE_CODE_1', 'SD', 'GG']]

del file_columns, use_cols


sd = pd.merge(sd, pjb, on='PNU', how='left')&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결합 후 데이터를 정제한다.&lt;/p&gt;
&lt;pre id=&quot;code_1673244010330&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 데이터 정제
sd = sd[sd['JIBUN'].str.contains('대') == True]               # '대'만 남기기

apt = sd[sd['USE_CODE_1_NM'].str.contains('아파트') == True]['PNU'].unique().tolist()
for a in apt:
    sd = sd.drop(sd[sd['PNU'] == a].index.tolist(), axis=0)

del a, apt

sd = sd.dropna()
sd = sd.reset_index(drop=True)


sd['SD'] = sd['SD'].astype(int)
sd['GG'] = sd['GG'].astype(int)

sd['SD'] = sd['SD'] + sd['GG']
sd['GG'] = 0

sd['SD'].loc[(sd['USE_CODE_0'] == '단독주택') &amp;amp; (sd['USE_CODE_1'].str.contains('다중') == True) &amp;amp; (sd['SD'] == 0)] = 1

sd['GG'].loc[(sd['USE_CODE_0'].str.contains('근린') == True) | (sd['USE_CODE_1'].str.contains('근린|점포') == True)] = 1
sd['GG'].loc[(sd['USE_CODE_0'] != '단독주택') &amp;amp; (sd['USE_CODE_0'] != '공동주택')] = 1


sd.to_file(save_dir + '/sadang4/sadang4.shp', encoding='cp949')&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;결측치가 발생하는 경우는 하나의 건축물이 두 개 필지에 걸쳐 있는 경우였다. 해당 건축물의 건축물 대장상 필지고유 번호는 둘 중 한 필지에만 존재했기 때문에 다른 한 필지는 결측치가 발생한 것이다. 결측치는 제거했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 참고) 건축법 시행령 제 3조 1항 1, 2 목&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;지목이 '대' 가 아닌 필지 (도, 산, 천 ...) 에서는 쓰레기 배출이 이루어지지 않는다고 판단하여 제거했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;아파트의 경우 이미 거점이 존재하므로 연구 대상에서 제외했다. 이 과정에서 아파트와 필지고유번호를 공유하는 경비실, 기계실, 주차장 등 시설을 함께 제거했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이후 필지 별로 세대를 부여했다. (여기서 행위자가 되는 세대는 건축물 대장 상 세대와 다르다. 세대, 가구, 호를 통칭하는 말이다. 따로 부를 말이 없어서 이렇게 부른다.) 건축물 대장 상에서는&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;가구 : 단독주택&lt;br /&gt;세대 : 공동주택&lt;br /&gt;호&amp;nbsp; &amp;nbsp; &amp;nbsp;: 그 외&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로 구분하고 있다. 거의 대부분 결측치 없이 가구와 세대가 잘 mapping 되어 있었지만, 일부 데이터에 문제가 있었다. 단독주택 중 다중주택과 근린생활시설이 그것이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;다중주택은 단독 주택으로 분류되어 가구 수 1 로 표기되어 있지만, 실제로는 여러 사람이 거주하는 건축물이다. 호 수에 제한이 없어서 표제부만 봐서는 한 건축물 안에 몇 명이 사는 지 알 수 없고, 분류 상 단독주택이기 때문에 전유부에도 호 수가 기재되어 있지 않다. 하는 수 없이 가구 수 1로 처리했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;근린생활시설의 경우 세대와 가구 모두 결측치로 나오는 경우가 많았다. 전유부 데이터를 결합해서 가게 수를 세어보려고 했지만, 확인이 불가했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이외에도 건축물대장상 단독주택이고, 다중주택도 아닌데 세대와 가구가 모두 0 인 경우도 있었다. 확인 결과 공사 중인 필지였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이렇게 기본적 데이터 정제를 마쳤다. 세대 별 거점 부여 및 시뮬레이션 알고리즘은 다음 글에서 살펴본다.&lt;/p&gt;</description>
      <category>Algorithm</category>
      <category>건축물대장</category>
      <category>빌라촌</category>
      <category>사당4동</category>
      <category>시뮬레이션</category>
      <category>쓰레기</category>
      <category>알고리즘</category>
      <category>전유부</category>
      <category>표제부</category>
      <author>몽골리안 파프리카</author>
      <guid isPermaLink="true">https://paprikafarm.tistory.com/18</guid>
      <comments>https://paprikafarm.tistory.com/18#entry18comment</comments>
      <pubDate>Mon, 9 Jan 2023 15:29:45 +0900</pubDate>
    </item>
    <item>
      <title>[Algorithm] 도시화과정 시뮬레이션</title>
      <link>https://paprikafarm.tistory.com/16</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;b&gt;셀룰러 오토마타 (Cellular Automata)&lt;/b&gt; 는 유한한 격자 공간 내에서 세포(CA) 의 움직임을 구현한 알고리즘이다. 각 세포는 일정한 상태를 (예를 들면 생존/죽음 과 같은) 가지며, 시간의 흐름에 따라 일정한 규칙을 적용 받는다. 대표적 알고리즘 적용 사례로는 '생명게임' 이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;다음은 '생명게임' 을 구현한 코드와 결과이다.&lt;/p&gt;
&lt;pre id=&quot;code_1672644011561&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import cellpylib as cpl


cellular_automaton = cpl.init_simple2d(60, 60)


cellular_automaton[:, [28,29,30,30], [30,31,29,31]] = 1 # Glider

cellular_automaton[:, [40,40,40], [15,16,17]] = 1 # Blinker

cellular_automaton[:, [18,18,19,20,21,21,21,21,20], [45,48,44,44,44,45,46,47,48]] = 1 # Light Weight Space Ship (LWSS)


# evolve the cellular automaton for 60 time steps
cellular_automaton = cpl.evolve2d(cellular_automaton, timesteps=60, neighbourhood='Moore',
                                  apply_rule=cpl.game_of_life_rule, memoize='recursive')

cpl.plot2d_animate(cellular_automaton)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1100&quot; data-origin-height=&quot;825&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ai5A5/btrVeVJamua/6E4B6BUXb3eGxf0QqlcBsK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ai5A5/btrVeVJamua/6E4B6BUXb3eGxf0QqlcBsK/img.png&quot; data-alt=&quot;생명게임 구현 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ai5A5/btrVeVJamua/6E4B6BUXb3eGxf0QqlcBsK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAi5A5%2FbtrVeVJamua%2F6E4B6BUXb3eGxf0QqlcBsK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;420&quot; height=&quot;315&quot; data-origin-width=&quot;1100&quot; data-origin-height=&quot;825&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;생명게임 구현 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;여기서 행위자를 추가하여 각 행위자 간 상호작용을 관측하는 개념이 &lt;b&gt;행위자 기반 모델 (Agent Based Model) &lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;개념이 중요한 것은 아니니 간략하게 설명만 하고 넘어간다. 중요한 것은&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;행위자가 있다.&lt;/li&gt;
&lt;li&gt;행위자는 주어진 규칙에 의해 움직인다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;는 사실이다. 행위자 기반 모델에서 컨셉을 얻어서 도시화 과정을 시뮬레이션 하는 알고리즘을 만들어 본다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;도시화 과정은 다음과 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;847&quot; data-origin-height=&quot;749&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3c2ZB/btrVfrVm6Jm/IZRBJOZbn1Xgho6wtY64e1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3c2ZB/btrVfrVm6Jm/IZRBJOZbn1Xgho6wtY64e1/img.png&quot; data-alt=&quot;도시화 과정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3c2ZB/btrVfrVm6Jm/IZRBJOZbn1Xgho6wtY64e1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3c2ZB%2FbtrVfrVm6Jm%2FIZRBJOZbn1Xgho6wtY64e1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;437&quot; height=&quot;386&quot; data-origin-width=&quot;847&quot; data-origin-height=&quot;749&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;도시화 과정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;도시는 크게 &lt;b&gt;[도시화 &amp;gt; 교외화 &amp;gt; 역도시화 &amp;gt; 재도시화]&lt;/b&gt; 과정을 거친다. 초기 도시가 형성될 때 인구가 집중되어 도시화가 일어나고, 높은 인구밀도로 인한 불경제로 인해 고소득층이 교외로 빠져나간다. 인구 유출이 점점 심화되며 중심도시 인구가 줄어들고 중심지가 쇠퇴하다가, 젠트리피케이션을 통해 중심지가 다시 부흥하고 유출된 인구가 다시 중심지로 들어온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이제 이 일련의 과정에 참여하는 행위자와 이들의 행동을 설명할 수 있는 행동 규칙을 설정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;우선 행위자는 소득에 따라 3 개 주체로 구분한다. [Low Income / Middle Income / High Income] 이들은 기본적으로 같은 행동 규칙을 갖지만, 세부적인 변수 설정에 차이를 두어 이동 양상을 구분했다. 이번 알고리즘에서는 각각 30 / 50 / 20 명으로 인구비율을 구성해서 랜덤으로 배치했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;행동 규칙은 크게 [Move / Stay ] 두 가지 선택지를 가진다. 인구밀도가 높아질수록 집적 이익과 불이익이 동시에 높아지지만 밀도가 일정 수준 이상이 되면 불이익이 더 커진다. 집적 이익과 불이익은 각각 무작위 선택의 가중치가 되어 의사 결정에 절대적 영향을 미친다. 인구밀도에 따른 집적 이익과 불이익을 나타낸 함수는 다음과 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1060&quot; data-origin-height=&quot;1061&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDSUxy/btrU6YN3RGP/VVSBP1xRUkb3aWsqez4HEk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDSUxy/btrU6YN3RGP/VVSBP1xRUkb3aWsqez4HEk/img.png&quot; data-alt=&quot;Advantage / Disadvantage Graph&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDSUxy/btrU6YN3RGP/VVSBP1xRUkb3aWsqez4HEk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDSUxy%2FbtrU6YN3RGP%2FVVSBP1xRUkb3aWsqez4HEk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;354&quot; height=&quot;354&quot; data-origin-width=&quot;1060&quot; data-origin-height=&quot;1061&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Advantage / Disadvantage Graph&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파란 선은 집적 이익을, 빨간 선은 집적 불이익을 나타내는 그래프이다. 40을 기점으로 (총 인구수의 40%) 인구밀도가 너무 높다고 판단하여 집적 불이익이 더 높아지도록 함수를 설계했다. 여기에 소득에 따라 이동비용을 차등 적용했다.&amp;nbsp;저소득층은 이동이 자유롭지 않아 집적 불이익보다 집적 이익이 더 중요한 반면, 고소득층은 비교적 이동이 자유로우므로 집적 불이익에 더 민감하게 반응한다. 따라서 저소득층은 Advantage 함수에, 고소득층은 Disadvantage 함수에 각각 상수 10을 더해줬다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1324&quot; data-origin-height=&quot;845&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7TBSo/btrU44Ox20G/cCK6XbiejJPgcT41nxm94K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7TBSo/btrU44Ox20G/cCK6XbiejJPgcT41nxm94K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7TBSo/btrU44Ox20G/cCK6XbiejJPgcT41nxm94K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7TBSo%2FbtrU44Ox20G%2FcCK6XbiejJPgcT41nxm94K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;448&quot; height=&quot;286&quot; data-origin-width=&quot;1324&quot; data-origin-height=&quot;845&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;만약 Move 를 선택한 경우, 주변 8개 구역으로 이동한다. 이 때 각 구역의 인구밀도를 가중치로 두어 무작위 장소로 이동한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 설정들을 적용한 알고리즘을 총 20번의 Time Step 동안 반복해 보았다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Agent_Scatter_init.png&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;1000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDrw85/btrU9ebVTZt/a09vGWwBJO0KCCQUjk1N30/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDrw85/btrU9ebVTZt/a09vGWwBJO0KCCQUjk1N30/img.png&quot; data-alt=&quot;초기 상태&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDrw85/btrU9ebVTZt/a09vGWwBJO0KCCQUjk1N30/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDrw85%2FbtrU9ebVTZt%2Fa09vGWwBJO0KCCQUjk1N30%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;223&quot; height=&quot;223&quot; data-filename=&quot;Agent_Scatter_init.png&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;1000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;초기 상태&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1756&quot; data-origin-height=&quot;437&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bx3CDO/btrU8Fm77gS/jOAv6HBzMoBT3MFUwu4mH0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bx3CDO/btrU8Fm77gS/jOAv6HBzMoBT3MFUwu4mH0/img.png&quot; data-alt=&quot;Time Step 별 변화 양상 [ 0 &amp;amp;gt; 6 &amp;amp;gt; 14 &amp;amp;gt; 18 ]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bx3CDO/btrU8Fm77gS/jOAv6HBzMoBT3MFUwu4mH0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbx3CDO%2FbtrU8Fm77gS%2FjOAv6HBzMoBT3MFUwu4mH0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1495&quot; height=&quot;372&quot; data-origin-width=&quot;1756&quot; data-origin-height=&quot;437&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Time Step 별 변화 양상 [ 0 &amp;gt; 6 &amp;gt; 14 &amp;gt; 18 ]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;초반엔 무작위로 흩어져 있는 주체들이 점차 한 곳으로 모여서 도시를 형성하는 것을 볼 수 있다. step 0 에서 가장 인구밀도가 높았던 곳이 점차 쇠퇴하고, 우상단에 위치한 도시가 점차 발달한다. 그 외 중소 도시들은 큰 변화 없이 제 자리를 지키는 것을 볼 수 있다. step 14 부터는 큰 변화 없이 기존 상태를 답보하는 양상을 확인했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;재밌는 점은, step6 부터 발달하기 시작한 도시의 인구 구성을 살펴보면, 고소득자의 비율이 높다. 반대로 쇠퇴하는 도시에 남아있는 인구구성은 저소득층과 중간소득층의 비율이 높다. 전형적인 쇠퇴도시의 교외화 현상이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;도시화 과정 같은 복잡한 과정을 비교적 간단한 수식으로만 나타내려고 하다 보니 대단한 결과를 볼 수는 없었다. 다만 시뮬레이션의 컨셉을 파악하고 추후 다른 프로젝트에 적용할 아이디어를 얻었다는 점, 그리고 여타 라이브러리 없이 numpy 로만 알고리즘을 구성했다는 점에서 의미를 찾을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;반대로 한계점은 성능이 그리 뛰어나지 않다는 점과 초기 무작위 분포에 따라 양상이 크게 달라진다는 점에서 부족함을 느꼈다. 이 점들을 개선하여 New Point 프로젝트에도 적용해 볼 생각이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1672647759998&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#%%
import numpy as np
import random
import matplotlib.pyplot as plt
from tqdm import tqdm
import sympy as sy


#%%
# Create Field
field = np.zeros(shape=(1000, 1000))


# Functions
def create_agent(x, y, seed):
    random.seed
    agents = np.array([random.sample(range(1000), x), random.sample(range(1000), x), np.full((x), y)]).T
    return agents

def count_population(field, agents):
    field_count = field.copy()
    
    for a in agents:
        field_count[int(a[1]/100)*100 : int(a[1]/100)*100+100, int(a[0]/100)*100 : int(a[0]/100)*100+100] += 1
    return field_count

def population_func(pop):
    if pop &amp;lt; 5:
        advantage = 0
        disadvantage = 0
    elif pop &amp;lt;= 40:
        advantage = 2 * pop
        disadvantage = (1.1165)**pop - (1.1165)**5
    else:
        advantage = 3 * pop - 40
        disadvantage = (1.1165)**pop - (1.1165)**5
    
    return advantage, disadvantage

def neighbor_func(agent, neighbor):
    location = [int(agent[0]/100)*100, int(agent[1]/100)*100]
    
    if neighbor == 0:
        location[0] -= 100
        location[1] -= 100
    elif neighbor == 1:
        location[0] -= 100
    elif neighbor == 2:
        location[0] -= 100
        location[1] += 100
    elif neighbor == 3:
        location[1] -= 100
    elif neighbor == 4:
        location[1] += 100
    elif neighbor == 5:
        location[0] += 100
        location[1] -= 100
    elif neighbor == 6:
        location[0] += 100
    else:
        location[0] += 100
        location[1] += 100
        
    return location

def moving_func(field, agents):
    new_agents = []
    
    for a in agents:
        pop = field[a[0], a[1]]
        
        field_state = np.unique(field)
        
        if pop &amp;lt; 5:
            ms = 'move'
            
            dtn = random.choices(field_state, weights=field_state)
            dtn = np.where(field == dtn)
            dtn = np.concatenate([dtn[0].reshape(dtn[0].shape[0], 1), dtn[1].reshape(dtn[0].shape[0], 1)], axis=1)
            dtn = random.choices(dtn)[0]
            dtn = np.array([dtn[0], dtn[1], a[2]])
            
            new_agents.append(dtn)
            
        else:
            advantage, disadvantage = population_func(pop)
            
            if a[2] == 0:
                advantage += 10
            elif a[2] == 2:
                disadvantage += 10
            
            ms = random.choices(['move', 'stay'], weights=[advantage, disadvantage])
            
            if ms == 'move':
                a = agents[0]
                
                field_state = []
                field_state.append(field[a[0]-100, a[1]-100])
                field_state.append(field[a[0], a[1]-100])
                field_state.append(field[a[0]+100, a[1]-100])
                field_state.append(field[a[0]-100, a[1]])
                field_state.append(field[a[0]+100, a[1]])
                field_state.append(field[a[0]-100, a[1]+100])
                field_state.append(field[a[0], a[1]+100])
                field_state.append(field[a[0]+100, a[1]+100])
                                
                dtn = random.choices(range(0, 8), weights=field_state)[0]
                dtn = np.array(neighbor_func(a, dtn))
                x, y = random.choices(range(dtn[0], dtn[0]+100))[0], random.choices(range(dtn[1], dtn[1]+100))[0]
                dtn = np.array([x, y, a[2]])
                
                new_agents.append(dtn)
            else:
                new_agents.append(a)
      
    new_agents = np.array(new_agents)
    
    return new_agents


#%%
# Advantage / Disadvantage Function
x0 = np.linspace(5, 40, 200)
x1 = np.linspace(40, 50, 100)
x2 = np.linspace(5, 50, 300)
y0 = 2 * x0
y1 = 3 * x1 - 40
y2 = 1.1165 ** x2 - 1.1165 ** 5

plt.figure(figsize=(10, 10))
plt.grid(color='gray', alpha=.5)
plt.plot(x0, y0, c='Blue', label='y = 2x')
plt.plot(x1, y1, c='Blue', label='y = 3x - 40')
plt.plot(x2, y2, c='Red', label = 'y = (1.1165)^x - (1.1165)^5')
plt.legend(loc = 'upper right')
plt.savefig(r&quot;C:\Users\PC\Desktop\주영준\진행중인 프로젝트\도시형성과정&quot; + '/Advantage_Disadvantage Function.png', dpi=100)
plt.show()

del x0, x1, x2, y0, y1, y2


# Create Agents
agent_0 = create_agent(30, 0, 123)
agent_1 = create_agent(50, 1, 124)
agent_2 = create_agent(20, 2, 125)

agents = np.concatenate([agent_0, agent_1, agent_2])
field_count = count_population(field, agents)


# Initial State
plt.figure(figsize=(10, 10))
plt.title(&quot;Agent_Scatter_init&quot;)
plt.scatter(agent_0[:, 0], agent_0[:, 1], label='0')
plt.scatter(agent_1[:, 0], agent_1[:, 1], label='1')
plt.scatter(agent_2[:, 0], agent_2[:, 1], label='2', c=&quot;Red&quot;)
plt.legend(loc = 'upper right')
plt.imshow(field_count, cmap='Greens')
plt.savefig(r&quot;C:\Users\PC\Desktop\주영준\진행중인 프로젝트\도시형성과정&quot; + '/Agent_Scatter_init.png', dpi=100)
plt.show()


# Simulation
for t in tqdm(range(0, 20), leave=True):
    if t == 0:
        new_agents = moving_func(field_count, agents)
        new_field = count_population(field, new_agents)
    else:
        new_agents = moving_func(new_field, agents)
        new_field = count_population(field, new_agents)

    plt.figure(figsize=(10, 10))
    plt.title(&quot;Agent_Scatter_{0}&quot;.format(t))
    plt.scatter(new_agents[:30,0], new_agents[:30, 1], label='0')
    plt.scatter(new_agents[30:80,0], new_agents[30:80, 1], label='1')
    plt.scatter(new_agents[80:,0], new_agents[80:, 1], label='2', c=&quot;Red&quot;)
    plt.legend(loc = 'upper right')
    plt.imshow(new_field, cmap='Greens')
    plt.savefig(r&quot;C:\Users\PC\Desktop\주영준\진행중인 프로젝트\도시형성과정&quot; + '/Agent_Scatter_{0}.png'.format(t), dpi=100)
    plt.show()

del agent_0, agent_1, agent_2, t&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;소스코드 전체이다.&lt;/p&gt;</description>
      <category>Algorithm</category>
      <category>Agent Based Model</category>
      <category>cellular automata</category>
      <category>도시화</category>
      <category>셀룰러 오토마타</category>
      <category>시뮬레이션</category>
      <category>알고리즘</category>
      <category>행위자 기반 모형</category>
      <author>몽골리안 파프리카</author>
      <guid isPermaLink="true">https://paprikafarm.tistory.com/16</guid>
      <comments>https://paprikafarm.tistory.com/16#entry16comment</comments>
      <pubDate>Mon, 2 Jan 2023 17:23:52 +0900</pubDate>
    </item>
    <item>
      <title>[Algorithm] 클러스터링 심화_이미지 처리 1 (2)</title>
      <link>https://paprikafarm.tistory.com/3</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이번엔 좌표 값을 부여한 뒤 DBSCAN 을 이용해서 테두리 부분만 남겨본다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빨간색만 남겨주기 위해 빨간색의 label 인 4 만 남긴다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;몰랐는데 np.where 를 쓰면 array 를 담은 tuple 이 반환된다. tuple 형태로는 아무것도 할 수 없으므로 tuple 속 array 를 꺼내서 2차원 numpy array 로 바꿔주었다.&lt;/p&gt;
&lt;pre id=&quot;code_1671946096511&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 빨간색만 남기기
target = np.where(pos == 4)
target = np.concatenate([target[1].reshape(target[1].shape[0], 1), target[0].reshape(target[0].shape[0], 1)], axis=1)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 다음, 좌표 값을 부여해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;좌표 값을 어떻게 부여해야 하나 고민하다가 픽셀 위치를 point 로 쓰기로 했다.&lt;/p&gt;
&lt;pre id=&quot;code_1671947032862&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;target_shp = []
i = 0

while True:
    target_shp.append(Point(target[i][0], result.shape[0] - target[i][1]))

    i += 3
    if i == len(target):
        break
    else:
        continue

target_shp = gpd.GeoDataFrame(target_shp)
target_shp = target_shp.reset_index().rename(columns={'index':'srl_num', 0:'geometry'})
target_shp = gpd.GeoDataFrame(target_shp, geometry='geometry')
target_shp['x'], target_shp['y'] = target_shp.geometry.x, target_shp.geometry.y

target_shp.to_file(save_dir + '/IMG2Polygon/Target_Point_{0}.shp'.format(name), encoding='cp949')

del i, target&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요로코롬.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;target_shp.append(Point(~~)) 에서 y 좌표를 그대로 부여하지 않고 result.shape[0] 에서 뺀 값을 넣어서 값을 반전해줬다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;무슨 말이냐면,&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Figure 2022-12-25 144729.png&quot; data-origin-width=&quot;324&quot; data-origin-height=&quot;248&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/daePxa/btrUuHe0Tmg/o6XteBlFX3KX6sYJIhTKKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/daePxa/btrUuHe0Tmg/o6XteBlFX3KX6sYJIhTKKk/img.png&quot; data-alt=&quot;반전 안했을 때&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/daePxa/btrUuHe0Tmg/o6XteBlFX3KX6sYJIhTKKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdaePxa%2FbtrUuHe0Tmg%2Fo6XteBlFX3KX6sYJIhTKKk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;324&quot; height=&quot;248&quot; data-filename=&quot;Figure 2022-12-25 144729.png&quot; data-origin-width=&quot;324&quot; data-origin-height=&quot;248&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;반전 안했을 때&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Figure 2022-12-25 144954.png&quot; data-origin-width=&quot;324&quot; data-origin-height=&quot;248&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNRSco/btrUutgXbxK/PrlKIzCGGk9QDjkR1FlOW0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNRSco/btrUutgXbxK/PrlKIzCGGk9QDjkR1FlOW0/img.png&quot; data-alt=&quot;반전 했을 때&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNRSco/btrUutgXbxK/PrlKIzCGGk9QDjkR1FlOW0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNRSco%2FbtrUutgXbxK%2FPrlKIzCGGk9QDjkR1FlOW0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;324&quot; height=&quot;248&quot; data-filename=&quot;Figure 2022-12-25 144954.png&quot; data-origin-width=&quot;324&quot; data-origin-height=&quot;248&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;반전 했을 때&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 수직 기준으로 뒤집어 줬다는 말이다. 왜 인지 모르겠는데, 이미지 파일은 y 축 값이 반대로 되어 있어서 수직반전을 안해주면 결과가 위아래 뒤집혀서 나온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어쨌든 좌표 값도 줬고, shp 파일로 만들었으니 DBSCAN 을 돌려주면 되는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 전에 min_sample 값과 eps 을 결정해줘야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;K-means 에서 가장 귀찮은 게 K 값 결정이었다면 DBSCAN 의 경우엔 min_sample 과 eps 이 그렇다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테두리 속 글씨를 제거하는 것이 목적이므로, min_sample은 7 정도로 줘서 글씨들이 군집으로 취급되지 않게 해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Eps 은 Elbow Method 를 사용하기로 한다. K-means 알고리즘에 Elbow Method 를 적용하면 최적 군집 수 결정에 사용되지만, DBSCAN 에서는 Eps 결정에도 사용된다.&lt;/p&gt;
&lt;pre id=&quot;code_1671947953513&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Eps 결정 (Elbow Method)
neigh = NearestNeighbors(n_neighbors=7)
neigh.fit(target_shp[['x', 'y']])
distances, indices = neigh.kneighbors(target_shp[['x', 'y']])
plt.figure(figsize=(12, 6))
plt.plot(np.sort(distances[:, 4]))
plt.savefig(save_dir + '/IMG2Polygon/IMG/DBSCAN_Elbow_{0}.png'.format(name), dpi=300)
plt.show()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요렇게 min_sample 값을 주면,&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;DBSCAN_Elbow_영등포시장_지형도면 고시.png&quot; data-origin-width=&quot;3600&quot; data-origin-height=&quot;1800&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xHuNl/btrUuofKmh4/kRzog4bjnBQ1zoDiFzd84K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xHuNl/btrUuofKmh4/kRzog4bjnBQ1zoDiFzd84K/img.png&quot; data-alt=&quot;Elbow Method 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xHuNl/btrUuofKmh4/kRzog4bjnBQ1zoDiFzd84K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxHuNl%2FbtrUuofKmh4%2FkRzog4bjnBQ1zoDiFzd84K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;512&quot; height=&quot;256&quot; data-filename=&quot;DBSCAN_Elbow_영등포시장_지형도면 고시.png&quot; data-origin-width=&quot;3600&quot; data-origin-height=&quot;1800&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Elbow Method 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 차트를 준다. 대략 2.5 에서 3 사이에 확 꺾이는 걸 보니, Eps 은 그 사이 값을 주면 될 듯하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;min_sample 은 7, Eps 은 2.5로 설정하고 DBSCAN 모델을 만들어서 돌려봤더니&lt;/p&gt;
&lt;pre id=&quot;code_1671948179899&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cit = DBSCAN(eps=2.5, min_samples=7)
target_shp['cluster'] = cit.fit_predict(target_shp[['x', 'y']])

plt.scatter(target_shp.x, target_shp.y, c=target_shp.cluster, cmap='rainbow')
plt.savefig(save_dir + '/IMG2Polygon/IMG/DBSCAN_{0}_1st.png'.format(name), dpi=300)
plt.show()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;DBSCAN_영등포시장_지형도면 고시_1st.png&quot; data-origin-width=&quot;1800&quot; data-origin-height=&quot;1200&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGFkq5/btrUt1LSaw3/ZxGiOioGFoTCQ1hBC3dBYk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGFkq5/btrUt1LSaw3/ZxGiOioGFoTCQ1hBC3dBYk/img.png&quot; data-alt=&quot;DB SCAN 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGFkq5/btrUt1LSaw3/ZxGiOioGFoTCQ1hBC3dBYk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGFkq5%2FbtrUt1LSaw3%2FZxGiOioGFoTCQ1hBC3dBYk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;482&quot; height=&quot;321&quot; data-filename=&quot;DBSCAN_영등포시장_지형도면 고시_1st.png&quot; data-origin-width=&quot;1800&quot; data-origin-height=&quot;1200&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;DB SCAN 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쟌.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가운데 글씨들이 잘 분리되었다. (자세히 보면 맨 위 보라색이랑 다른 보라색이다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 필요 없는 가운데 글씨를 발라내고 필요한 테두리만 남기면,&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Final_Result_영등포시장_지형도면 고시.png&quot; data-origin-width=&quot;1800&quot; data-origin-height=&quot;1200&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/brTl1Q/btrUDjct4Iu/PjluZMUyP96gzKEe73aRSK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/brTl1Q/btrUDjct4Iu/PjluZMUyP96gzKEe73aRSK/img.png&quot; data-alt=&quot;결과!&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/brTl1Q/btrUDjct4Iu/PjluZMUyP96gzKEe73aRSK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbrTl1Q%2FbtrUDjct4Iu%2FPjluZMUyP96gzKEe73aRSK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1800&quot; height=&quot;1200&quot; data-filename=&quot;Final_Result_영등포시장_지형도면 고시.png&quot; data-origin-width=&quot;1800&quot; data-origin-height=&quot;1200&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;결과!&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나름 성공적! 사실 지금 쓰인 이미지는 색 사용이 비교적 얌전해서 쉽게 구분해냈지만, 색 사용도 복잡하고 사람 눈으로도 구분하기 어려운 지적도를 알고리즘에 적용하면 정신을 못 차린다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래도 클러스터링의 새로운 사용법을 찾았다는 점에 만족하려 한다.&lt;/p&gt;</description>
      <category>Algorithm</category>
      <category>DBSCAN</category>
      <category>머신러닝</category>
      <category>이미지처리</category>
      <category>클러스터링</category>
      <author>몽골리안 파프리카</author>
      <guid isPermaLink="true">https://paprikafarm.tistory.com/3</guid>
      <comments>https://paprikafarm.tistory.com/3#entry3comment</comments>
      <pubDate>Sun, 25 Dec 2022 15:08:47 +0900</pubDate>
    </item>
    <item>
      <title>[Algorithm] 클러스터링 심화_이미지 처리 1 (1)</title>
      <link>https://paprikafarm.tistory.com/2</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이미지 데이터에는 색깔을 표현하는 rgb 값들이 픽셀 단위로 들어있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 이 RGB 값에 클러스터링을 적용해서 원하는 색을 뽑아낸 뒤 좌표값을 부여하는 알고리즘을 만들어보려 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 적절한 이미지를 구한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;영등포시장_지형도면 고시.png&quot; data-origin-width=&quot;632&quot; data-origin-height=&quot;521&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PnmV7/btrUunHfQX7/mhNHeMkCp8ap37hNkom2UK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PnmV7/btrUunHfQX7/mhNHeMkCp8ap37hNkom2UK/img.png&quot; data-alt=&quot;영등포시장 정비구역 지형도면 (출처 : 토지이음 지형도면 고시정보 열람)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PnmV7/btrUunHfQX7/mhNHeMkCp8ap37hNkom2UK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPnmV7%2FbtrUunHfQX7%2FmhNHeMkCp8ap37hNkom2UK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;632&quot; height=&quot;521&quot; data-filename=&quot;영등포시장_지형도면 고시.png&quot; data-origin-width=&quot;632&quot; data-origin-height=&quot;521&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;영등포시장 정비구역 지형도면 (출처 : 토지이음 지형도면 고시정보 열람)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;토지이음에서 적당한 이미지를 하나 가져왔다. 영등포 시장 정비구역의 지형도면이다. 목표는 저 빨간색 점선만 남기기!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파이썬에서 이미지를 불러온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필요한 라이브러리를 불러오고,&lt;/p&gt;
&lt;pre id=&quot;code_1671860970716&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import numpy as np
from PIL import Image

from sklearn.cluster import KMeans
from sklearn.cluster import DBSCAN
from sklearn.neighbors import NearestNeighbors

from shapely.geometry import Point, Polygon
import pandas as pd
import geopandas as gpd
import matplotlib.pyplot as plt&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미지를 불러온뒤, numpy 행렬로 바꿔준다.&lt;/p&gt;
&lt;pre id=&quot;code_1671861069076&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 이미지 불러오기
img = Image.open(load_dir + &quot;/영등포시장_지형도면 고시.png&quot;)
name = &quot;영등포시장_지형도면 고시&quot;
pix = np.array(img)
pix = np.delete(pix, 3, axis=2)

plt.imshow(pix)
plt.show()

x_data = pix.reshape(pix.shape[0] * pix.shape[1], pix.shape[2])&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왜인지는 모르겠는데 3차원 shape이 3이 아니라 [255, 255, 255, 255] 이런식으로 4개로 구성되어 있었다. 어차피 전부 255 길래 맨 끝 값은 지워줬다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 클러스터링을 하기 위해 pix의 shape를 조정해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;shape 0 와 shape 1을 곱해줘서 2차원 행렬로 만들어 준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여담이지만, 이번 알고리즘 공부를 하면서 차원에 대해 감을 좀 잡은 것 같아서 좀 기분 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 다음 클러스터링을 돌려주면 완성.&lt;/p&gt;
&lt;pre id=&quot;code_1671861699968&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# K-means 모델 만들기
cit = KMeans(5, random_state=123).fit(x_data)

# 중심값 보기
centroid = cit.cluster_centers_.astype(np.int64())
centroid = centroid.reshape(centroid.shape[0], 1, centroid.shape[1])
plt.imshow(centroid)
plt.savefig(save_dir + '/IMG2Polygon/IMG/Centroid_{0}.png'.format(name), dpi=300)
plt.show()

# 결과 라벨링
labels = cit.predict(x_data)
labels = labels.reshape(x_data.shape[0], 1)
labels = labels.reshape(pix.shape[0], pix.shape[1], 1)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;K-means 클러스터링 할 때 가장 귀찮은 점 중 하나가 K 값 설정하기이지 않을까. 일단 넉넉하게 5개로 잡아 봤다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Centroid_영등포시장_지형도면 고시.png&quot; data-origin-width=&quot;1800&quot; data-origin-height=&quot;1200&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b2Ee9F/btrUuoTLBwx/9YwkiGnw0be7Atg67e7Ask/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b2Ee9F/btrUuoTLBwx/9YwkiGnw0be7Atg67e7Ask/img.png&quot; data-alt=&quot;중심점&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b2Ee9F/btrUuoTLBwx/9YwkiGnw0be7Atg67e7Ask/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb2Ee9F%2FbtrUuoTLBwx%2F9YwkiGnw0be7Atg67e7Ask%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;438&quot; height=&quot;292&quot; data-filename=&quot;Centroid_영등포시장_지형도면 고시.png&quot; data-origin-width=&quot;1800&quot; data-origin-height=&quot;1200&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;중심점&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과로 나온 중심점이다. 여기서 문제. 왜 K 값을 5개나 잡아서 필요없는 회색을 저렇게 구분해놨을까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 처음에 색깔이 4개니까 K 값도 4개로 잡았지만, 그 경우 색깔 분리가 잘 안 이루어진다. 그래서 5개로 조정했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 빨간색의 라벨이 4번인걸 알았으니 빨간색만 남겨서 시각화해보자.&lt;/p&gt;
&lt;pre id=&quot;code_1671862251712&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 시각화
result = pix.copy()
pos = np.concatenate([labels, labels, labels], axis=2)
result[np.where(pos != 4)] = 253
plt.imshow(result)
plt.savefig(save_dir + '/IMG2Polygon/IMG/Target_IMG_{0}.png'.format(name), dpi=300)
plt.show()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;label 4에 해당하는 픽셀만 남기고 나머지는 하얀색으로 바꿔준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 주의할 점. result의 shape은 (x, y, &lt;u&gt;&lt;b&gt;3&lt;/b&gt;&lt;/u&gt;)이고, labels의 shape은 (x, y, &lt;u&gt;&lt;b&gt;1&lt;/b&gt;&lt;/u&gt;) 이다. shape을 똑같이&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;(x, y,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;u&gt;&lt;b&gt;3&lt;/b&gt;&lt;/u&gt;) 으로 맞춰주지 않으면 [[[x1, x2, x3]... ]]] 중에 x1만 바뀐다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과는 다음과 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Target_IMG_영등포시장_지형도면 고시.png&quot; data-origin-width=&quot;1800&quot; data-origin-height=&quot;1200&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8xoT2/btrUuBeqO2u/awKLfDpyXviD2KLOV3eHwk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8xoT2/btrUuBeqO2u/awKLfDpyXviD2KLOV3eHwk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8xoT2/btrUuBeqO2u/awKLfDpyXviD2KLOV3eHwk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8xoT2%2FbtrUuBeqO2u%2FawKLfDpyXviD2KLOV3eHwk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;596&quot; height=&quot;397&quot; data-filename=&quot;Target_IMG_영등포시장_지형도면 고시.png&quot; data-origin-width=&quot;1800&quot; data-origin-height=&quot;1200&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빨간색만 잘 분리된 것을 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데, 가운데를 잘 보면 뭔가가 남아있다. '시장정비구역' 이라는 글씨도 빨간색이라서 같이 남아있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 포스팅에서는 가운데 글씨를 지우고 좌표값을 부여해 본다.&lt;/p&gt;</description>
      <category>Algorithm</category>
      <category>K-means</category>
      <category>머신러닝</category>
      <category>지적도</category>
      <category>클러스터링</category>
      <author>몽골리안 파프리카</author>
      <guid isPermaLink="true">https://paprikafarm.tistory.com/2</guid>
      <comments>https://paprikafarm.tistory.com/2#entry2comment</comments>
      <pubDate>Sat, 24 Dec 2022 15:22:15 +0900</pubDate>
    </item>
  </channel>
</rss>