Open inh2613 opened 3 years ago
제가 표현하는 방법은 데이터 자동 크롤링. 어떻게 할지 정해만 주면 알아서 크롤링합니다.
크롤링 배우기 좋은 참고입니다. 유튜브
그리고 이게 colab에서는 진행이 안되더라구요. 뭐가 문제인지는 모르겠습니다. local에서 돌렸습니다.
자신이 사용하는 크롬 정보에 맞게 다운 : 크롬 웹 드라이버
def crawl_weather() :
weather_data_10 = pd.DataFrame(columns=['현재일기_10','현재기온_10','체감온도_10','일강수_10'])
# 이 부분에 path가 들어가야합니다. Chrome('../chromedriver_win32/chromedriver.exe') 이런식으로요.
browser = Chrome()
url = 'http://www.weather.go.kr/weather/observation/currentweather.jsp?auto_man=m&type=t99®=184&tm=2019.10.25.16%3A00&x=19&y=7'
browser.get(url)
for i in range(0,46):
i+=1
# find_element_by_id는 id로 찾는다는뜻입니다. f12 키로 ctrl+f 로 observation_text를 찾아보세요.
elem=browser.find_element_by_id('observation_text')
# 비우고, 값을 넣어줍니다.
elem.clear()
elem.send_keys("2019.9.{}.10:00".format(i))
# 아이템을 찾는 방법이 여러가지 있습니다. 그 중 쉬운게 이번에는 class name인거같애요.
# 이미지들은 아래에 있습니다.
btn=browser.find_elements_by_class_name('btn')
btn[2].click()
time.sleep(1)
weathers = browser.find_elements_by_css_selector('td')
# 보통 class나 id가 있는데 얘는 없네요. 그래서 이렇게 인덱스로 빼온것같습니다.
weather_data_10 = weather_data_10.append(pd.DataFrame([[weathers[40].text,weathers[44].text, weathers[46].text, weathers[47].text]],columns=['현재일기_10','현재기온_10','체감온도_10','일강수_10']))
print('success !')
browser.close()
return weather_data_10
머신러닝에서 받아들여지는건 숫자다. 그래서 문자열은 고유의 숫자를 가질 수 있다.
train['station_code'].astype(str) + ',' + train['weekday'].astype(str)
같이 숫자형태의 카테고리형데이터를 형변환 후 ,
로 묶었다.
예를 들어, 6개의 weekday와 100개의 station_code라면 총 600개의 다양한 값을 갖는 새로운 파생변수가 생기는 것이다.
문제의 target은 18~20_ride다. 2시간을 예측하므로, 1시간 features들을 합쳐셔 2시간으로 한다.
예측하려는 것은 일자별(date), 버스 노선(bus_route_id) 상의 정류장(station_name)의 퇴근시간 하차인원(18~20_ride)이기 때문에 각종 통계량을 많이 넣었다.
웬만하면 map이 편할 수 있다.
pandas map과 replace가 있는데 둘다 쓴다. 이제 replace는 dictionary 형태의 값, 문자열 등을 받지만,
map은 dictionary와 series 같이 인덱스와 값을 갖는 형태. 그리고 함수도 받는다.
이제 자주 쓰이는 쪽이 frequency encoding 이다. 참고링크
def freq_encode(train_data, test_data, columns):
'''Returns a DataFrame with encoded columns'''
encoded_cols = []
nsamples = train_data.shape[0]
for col in columns:
# 결국 선택한 column의 value_counts 이다.
freqs_cat = train_data.groupby(col)[col].count()/nsamples
encoded_col_train = train_data[col].map(freqs_cat)
encoded_col_test = test_data[col].map(freqs_cat)
encoded_col = pd.concat([encoded_col_train, encoded_col_test], axis=0)
encoded_col[encoded_col.isnull()] = 0
encoded_cols.append(pd.DataFrame({'freq_'+col:encoded_col}))
all_encoded = pd.concat(encoded_cols, axis=1)
return (all_encoded.loc[train_data.index,:],
all_encoded.loc[test_data.index,:])
정확한 의미는 모르지만, deep learning의 dropout과 같다고 한다. 인공신경망에서 학습할 때 일부 노드를 사용하지 않고 학습한다고 한다.
정규화의 의미를 갖고, 과적합을 막는다고 했다. 그런 의미다.
그런데 구글에 lightgbm dart라고 검색했는데 poor accuracy도 보이고, too long to run 도 보인다.
이번 1등도 그렇고, 아마 빡빡한 모델(변수 많고, 데이터의 양도 많은)에서 사용하면 dart를 사용하는게 좋은거 같다.
가만 보니 정규화랑 식이 비슷하다.
앙상블을 할때 적절한 가중치값을 찾지 못한다면 위와같이 멱평균 앙상블을 하면 좋다고 한다. 참고
Selenium은 주로 웹앱을 테스트하는데 이용하는 프레임워크다. webdriver라는 API를 통해 운영체제에 설치된 Chrome등의 브라우저를 제어하게 된다. ‘눈에 보이는’ 컨텐츠라면 모두 가져올 수 있다.
전체 코드 : 1등_코드_날씨데이터_크롤링(colab_버전)
패키지 설치 - selenium과 chromedriver
!pip install selenium
!apt-get update # apt install을 정확히 실행하기 위해 설치된 패키지 업데이트
!apt install chromium-chromedriver #패키지 설치
!cp /usr/lib/chromium-browser/chromedriver /usr/bin
cp : 유닉스 셸에서 한 파일을 어떤 장소에서 다른 장소로 또는 다른 파일 시스템으로 옮길때 사용하는 명령어 /usr/lib/chromium-browser/chromedriver 파일을 /usr/bin로 복사한다.
webdriver Chrome Headless : Chrome 브라우저를 GUI 없이 사용할 수 있는 모드 리눅스 서버와 같이 GUI를 제공하지 않는 환경에서 '--no-sandbox' 옵션 추가 disable-dev-shm-usage도 마찬가지로 GUI를 사용할 수 없어서 추가하는 것 같다. 참고 링크
sys.path.insert : 다른 폴더(경로)에 있는 python 파일 import 가능하도록 경로를 환경변수로 지정 --> 경로를 환경변수로 설정하게 해주면 그 경로 안의 프로그램을 실행시킬 때 마다 경로를 매번 입력하지 않아도 된다.
확인해보니 아래 코드 부분을 실행한 후에만 뒤의 날씨 데이터 크롤링 부분이 돌아간다. 다시 날씨 데이터 크롤링을 재실행하는 경우 "invalid session id"라는 오류가 발생한다.
import sys
sys.path.insert(0,'/usr/lib/chromium-browser/chromedriver')
from selenium import webdriver
#chrome의 option 설정
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--headless') #chrome 창이 나오지 않게 해준다.
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--disable-dev-shm-usage')
#1등 코드에서의 browser == driver
driver = webdriver.Chrome('chromedriver', chrome_options=chrome_options)
import pandas as pd
import time
weather_data_10 = pd.DataFrame(columns = ['현재일기_10','현재기온_10','체감온도_10','일강수_10']) url = 'http://www.weather.go.kr/weather/observation/currentweather.jsp?auto_man=m&type=t99®=184&tm=2019.10.25.16%3A00&x=19&y=7' driver.get(url) #browser == driver
for i in range(0, 46): i+=1
elem = driver.find_element_by_id('observation_text') elem.clear() elem.send_keys("2019.9.{}.10:00".format(i))
btn = driver.find_elements_by_class_name('btn') btn[2].click()
time.sleep(1) weathers = driver.find_elements_by_css_selector('td') weather_data_10 = weather_data_10.append(pd.DataFrame([[weathers[40].text,weathers[44].text, weathers[46].text, weathers[47].text]],columns=['현재일기_10','현재기온_10','체감온도_10','일강수_10']))
print('success !') driver.close()
크롤링에 사용되는 id, class 등등 개인적으로 어디인지 궁금해서 스크린샷 찍어봤습니다 🙂
- observation_text
![image](https://user-images.githubusercontent.com/44529556/106382041-10d36880-6400-11eb-80f2-f8a2bc46afc5.png)
- btn[2]
![image](https://user-images.githubusercontent.com/44529556/106382119-d3bba600-6400-11eb-8ae7-c132d641e206.png)
- weather_data_10
![image](https://user-images.githubusercontent.com/44529556/106382307-0e720e00-6402-11eb-83d1-9bf3dd039898.png)
날씨데이터 크롤링할 때 궁금한 점이 있습니다.
elem.send_keys("2019.9.{}.10:00".format(i))
에서 i가 30일이 넘어가면 자동으로 10월로 되는 것인가요 ??
출력을 했을때는 그냥 31, 32 --- 이렇게 넘어가는 것 같은데 혹시 아시는 분 있으면 이슈 남겨주세요 !
찾아도 안나오네요. 자동으로 넘어가는건 맞는거 같아요. 결과도 그렇고. selenium 화면도 그렇고. 말도 안되는 날짜는 넘어간만큼 더해지나봐요. 한번 10월 30일부터 46일까지 돌려봤는데 31일이후로 11월1일이 돼요.
@98hyun 감사합니다 :)
먼저 Geocoding이란 고유명칭(주소, 산, 호수 이름등)을 가지고 위도와 경도의 좌표값을 얻는 것을 말한다. 반대로 위도와 경도값으로부터 고유명칭을 얻는것은 리버스 지오코딩(reverse Geocoding)이된다.
geopy는 여러 유명한 Geocoding 웹 서비스를 위한 파이썬 client이다. geopy를 사용하면 파이썬 개발자가 타사 지오코더 및 기타 데이터 소스를 사용하여 전 세계의 주소, 도시, 국가 및 랜드마크 좌표를 쉽게 찾을 수 있다.
import geopy.distance #거리 계산해주는 패키지 사용
classgeopy.distance.vincenty(*args, **kwargs)
: Thaddeus Vincenty가 고안한 공식을 사용하여 두 점 사이의 측지(위도경도 정확한 위치?) 거리를 계산한다.
coords_jejusi = (33.500770, 126.522761) #제주시의 위도 경도
data['dis_jejusi'] = [geopy.distance.vincenty((data['latitude'].iloc[i],data['longitude'].iloc[i]), coords_jejusi).km for i in range(len(data))]
data의 위도 경도와 제주시의 위도경도의 거리를 계산한다. 여기서 km은 kilometers
참고 출처 : 공식문서
[퇴근시간버스승차인원예측] 1등 코드에 대한 질문이나 공유해주셨으면 하는 것들 올려주시면 됩니다👏
데이콘 코드공유 : https://dacon.io/competitions/official/229255/codeshare/511?page=1&dtype=recent&ptype=pub