[이전 글 보기]
2020/03/22 - [AI/자연어처리] - [생활속의 IT] 자연어 처리#1 - 아나콘다 설치하기
2020/03/22 - [AI/자연어처리] - [생활속의 IT] 자연어 처리 - 참고) Jupyter의 개념
2020/03/23 - [AI/자연어처리] - [생활속의 IT] 자연어 처리#2 - 크롤러 만들기
2020/03/23 - [AI/자연어처리] - [생활속의 IT] 자연어 처리#3 - 직방의 지리정보 Geohash 이해하기
이전 포스트에서 직방이 여러 정보를 전달할 때 인수로 Geohash를 이용한다는 것을 봤습니다.
우리는 텍스트마이닝을 위해 직방의 아파트 평가글을 수집할 겁니다.
전국 아파트를 대상으로 하겠습니다.
1. Geohash 정하기
2. 서울내 아파트 ID 가져오기
--------------------------------------------------------------------------------------------------------------------------
1. Geohash 정하기
이전 포스트에서 인접한 구(가령 서초구, 강남구)에 대한 geohash는 중복될 수 있다고 했습니다.
그래서 전국 아파트ID를 가져오기 위해 직접 geohash 값을 전달할 예정입니다.
http://geohash.gofreerange.com/사이트에 가보면 아래와 같이 geohash 값을 지도로 직접 클릭해서 정할 수 있습니다.
대략 서울을 담는 geohash 를 모아 List로 만들어보겠습니다.
geohash = ['wyd','wye','wy6','wy7']
|
그런데 3레벨의 geohash값을 전달하기에는 규모가 너무 크기 때문에
직방에는 5레벨의 geohash값을 전달하려고 합니다.
즉 wyd7e 같은 형태로 말이죠.
이전 포스트에 언급하였지만 상위 레벨은 하위 레벨을 32개로 분할한 크기입니다.
그리고 하위 레벨의 값을 공통적으로 가진다고 하였습니다.
따라서 geohash값을 string으로 전달하면
상위 레벨 geohash 값 32개를 리스트로 리턴하는 함수를 만들었습니다.
1
2
3
4
5
6
7
8
9
10
11
|
def getHigherGeohash(strgh): # string 형태의 geohash 입력시 상위 레벨의 geohash 32개를 리스트로 전달
returnList=[]
for i in range(10):
startIdx = ord('b')
endIdx = ord('z')
for i in range(startIdx, endIdx + 1):
if (chr(i) != 'i' and chr(i) != 'l' and chr(i) != 'o'):
returnList.append(strgh + chr(i))
return returnList
|
3레벨 geohash를 전달하면 4레벨 geohash 를 얻어올 수 있고 이를 한번 더 통과시키면 5레벨 geohash 값을 가져올 수 있습니다.
3레벨 geohash 개수는 4개이고 상위로 갈수록 32개씩 곱해지니 우리가 구할 5레벨 geohash 개수는
4*32*32 = 4096이 될 것이라 예상할 수 있습니다.
2. 전국 아파트 ID 가져오기
전국 ID를 얻기 전 일단 서울 은평구에 속하는 wydq0 geohash 값을 주어 아파트 리스트를 받는 과정을
보도록 하겠습니다.
1
2
3
4
5
6
7
8
|
import requests
import json
def getDanjiId(geohash):
req = requests.get(url)
items = req.json()
print(items)
|
그리고 메인에는 geohash 리스트를 만든 후 하나씩 던지도록 만들었습니다. (지금은 은평구 한개)
1
2
3
|
geohash = ['wydq0']
for i in geohash:
getDanjiId(i)
|
![](https://blog.kakaocdn.net/dn/bNXnvh/btqDkAqsAHU/g3eR4siTTkRnhsZWv5jSB0/img.png)
나타난 결과값은 json 사이트(http://json.parser.online.fr/)에서 정리해서 보도록 합니다.
결과를 보니 vrItems가 7건, RecommendItems가 26건, items가 6건인데 자세히 열어보면 danjiID가 들어있습니다.
RecommendItems, Items 모두 areaDanjiId가 들어가 있는데
이 세 가지 종류의 item에서 danjiId 값을 모두 가져오도록 하겠습니다.
데이터를 보니 danjiId가 중복되는 경우도 있어서 중복ID는 제외하고 구성하겠습니다.
아까 작성했던 함수를 좀 뜯어고쳐 보도록 하겠습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
def getDanjiList(geohash):
req = requests.get(url)
items = req.json()
danjiList=[]
if items["vrItems"] !=[]: ## vrItems 대상이 있으면 진행
for i in items["vrItems"]:
danjiList.append(i["areaDanjiId"])
if items["recommendItems"] !=[]: ## recommend 대상이 있으면 진행
for i in items["recommendItems"]:
danjiList.append(i["areaDanjiId"])
if items["items"] !=[]: ## Items 대상이 있으면 진행
for i in items["items"]:
danjiList.append(i["areaDanjiId"])
danjiList = list(set(danjiList))
return danjiList
|
vrItems, Recommend, Items 에서 Danji리스트는 중복될 수 있으므로 중복제거를 위해 list(set()) 함수를 썼습니다.
이제 위 함수는 string으로 된 geohash값을 주면 단지 ID를 리스트로 반환해줍니다.
#######################################################################################
메인함수는 아래와 같이 작성해서 돌려보겠습니다.
1
2
3
|
geohash = ['wydq0']
for i in geohash:
print(getDanjiList(i))
|
wydq0 geohash 영역의 아파트 리스트를 가져왔습니다. 30건을 리턴해 주는군요.
그런데 wydq0 영역은 5레벨로 아래 보시다시피 매우 큰 영역입니다.
이 영역의 직방을 봐도 아파트 개수는 30건은 넘을 것이라 볼 수 있습니다.
한마디로 직방은 아파트 리스트를 전부 주지는 않는 걸로 보인다는 겁니다.
geohash 값을 5레벨로 준게 너무 큰가 해서 6레벨 32개를 전달해서 받아봤는데
제가 테스트해본 결과 직방이 준 아파트 리스트는 동일했습니다.
결국 직방이 아파트 ID를 100% 주지는 않는듯 한데, 왜 그런지는 잘 모르겠습니다.
어쨌든 일부 아파트가 누락된다고 보고, 전국의 아파트 ID를 얻어오도록 하겠습니다.
getDanjiList함수는 그대로 두고 메인에서 5레벨 geohash를 만들어 인수로 주면 됩니다.
메인은 이렇게 만들었습니다.
1
2
3
4
5
6
7
8
9
10
11
12
|
geohash = ['wyd','wye','wy6','wy7']
tmp = []
for i in geohash:
tmp4Lv=getHigherGeohash(i)
for j in tmp4Lv:
tmp5Lv=getHigherGeohash(j)
totalGeohash = []
for i in tmp:
totalGeohash+=i
print(totalGeohash[:5], len(totalGeohash))
|
그러면 아래와 같이 4096개의 5레벨 geohash를 얻게 됩니다.
![](https://blog.kakaocdn.net/dn/bo7rLL/btqDjdQf7d1/POYbkb88F5RaZYYqzX49R0/img.png)
이제 4096개의 geohash 값을 던져 danjiList를 얻어보도록 하겠습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
import requests
def getHigherGeohash(strgh): # string 형태의 geohash 입력시 상위 레벨의 geohash 32개를 리스트로 전달
returnList=[]
for i in range(10):
startIdx = ord('b')
endIdx = ord('z')
for i in range(startIdx, endIdx + 1):
if (chr(i) != 'i' and chr(i) != 'l' and chr(i) != 'o'):
returnList.append(strgh + chr(i))
return returnList
def getDanjiList(geohash):
req = requests.get(url)
items = req.json()
danjiList=[]
if items["vrItems"] !=[]: ## vrItems 대상이 있으면 진행
for i in items["vrItems"]:
danjiList.append(i["areaDanjiId"])
if items["recommendItems"] !=[]: ## recommend 대상이 있으면 진행
for i in items["recommendItems"]:
danjiList.append(i["areaDanjiId"])
if items["items"] !=[]: ## Items 대상이 있으면 진행
for i in items["items"]:
danjiList.append(i["areaDanjiId"])
danjiList = list(set(danjiList))
return danjiList
#################################################################################################
geohash = ['wyd','wye','wy6','wy7'] # 5레벨 geohash 얻기
tmp = []
for i in geohash:
tmp4Lv=getHigherGeohash(i)
for j in tmp4Lv:
tmp5Lv=getHigherGeohash(j)
totalGeohash = []
for i in tmp:
totalGeohash+=i
totalDanjiList=[]
for i in totalGeohash:
DanjiListPerGeohash = getDanjiList(i)
totalDanjiList+=DanjiListPerGeohash
print(totalDanjiList[:10], len(totalDanjiList))
|
참고로 돌리면 매우 오래 걸립니다.
'AI > 자연어처리' 카테고리의 다른 글
[생활속의 IT] 자연어 처리#6 - 직방 부동산 평가데이터 전처리(1/2) (0) | 2020.03.26 |
---|---|
[생활속의 IT] 자연어 처리#5 - 직방 부동산 평가 크롤링하기 (1) | 2020.03.24 |
[생활속의 IT] 자연어 처리#3 - 직방의 지리정보 Geohash 이해하기 (1) | 2020.03.23 |
[생활속의 IT] 자연어 처리#2 - 크롤러 만들기 (0) | 2020.03.23 |
[생활속의 IT] 자연어 처리 - 참고) Jupyter의 개념 (0) | 2020.03.22 |
댓글