작업한 내용을 대상으로 중분류 내용 추가하기
# 레시피 데이터베이스 불러오기
from muyong.nlp import mdx_to_df
df = mdx_to_df('backup/recipe.db')
menus = df.entry.values.tolist()
len(menus), " ".join(menus)[:200]
(908, '가오리조림 가오리찜 가자미야채탕 가자미찜 가지냉채 가지불고기 가지선 가지오징어냉채 가지조림 가지회 각색두부전골 각색버섯덮밥 간장 갈비구이 갈비구이찜 갈비찜 갈비탕 감자가자미구이 감자갈비탕 감자고로케 감자그라땡 감자대구오븐구이 감자두부조림 감자막튀김 감자맑은국 감자밥 감자베이컨볶음 감자보트샐러드 감자볶음 감자볶음밥 감자볶음밥치즈구이 감자부침 감자새우그라땡 감')
food_recipes = df.paraphrase.values.tolist()
result = []
import re
for _ in food_recipes:
result += re.findall("[가-힣]+", _)
len(result), len(list(set(result)))
(88636, 10574)
from konlpy.tag import Hannanum, Okt, Mecab, Komoran
food_text = " ".join(list(set(result)))
food_tokens = Mecab().nouns(food_text)
len(food_tokens)
9514
from nltk import Text
food_tokens_text = Text(food_tokens)
food_nouns = [_[0] for _ in food_tokens_text.vocab().most_common()]
len(food_nouns)
2626
import pickle
with open('data/nerDict.pk', 'rb') as handle:
nerDict = pickle.load(handle)
query = "한천" # 원문 내용의 확인
q_data = nerDict[nerDict.Text == query].Data.values.tolist()
q_data
[[('명사', ['1', '몹시 가문 여름 하늘.']), ('명사', ['2', '몹시 가문 날씨.\r\n'])], [('명사', ['1', '겨울의 차가운 하늘.', '¶ 뿌옇게 흐렸던 한천에서 희끗희끗 눈발이 날리기 시작했다.≪이원규, 훈장과 굴레≫']), ('명사', ['2', ' =한절02.\r\n'])], [('명사', ['명사', '찬물이 솟는 샘.\r\n'])], [('명사', ['명사', '땀을 흘리며 헐떡거림.', '한천-하다01(汗喘--) [한ː---]']), ('동사', ['동사', '땀을 흘리며 헐떡거리다.\r\n'])], [('명사', ['명사', ' =우무01. ‘우무01’, ‘우뭇가사리’로 순화.\r\n'])], [('명사', ['명사', '『인명』', '‘이재04’의 호.\r\n'])]]
# 명사 추출사전 데이터 호출
with open("data/nouns_tokens.txt", "r") as f:
valid_token = f.read()
valid_token = valid_token.split(",")
len(valid_token)
689
# 분석할 메뉴데이터 호출
import pandas as pd # 분석을 의뢰할 메뉴 데이터 [list]
menus_muyong = pd.read_csv('data/menu_muyong.csv', encoding='ms949')
menus_muyong = menus_muyong.dropna(subset=['메인1', '메인2'])
menus_muyong = menus_muyong.fillna('') # NaN 값을 지운다
tokens = [] # DataFrame 에서 Token List 추출
for _ in menus_muyong.columns[4:]:
tokens += menus_muyong[_].values.tolist()
import re
from nltk import Text
menus_muyong = re.findall(r"[가-힣]+", " ".join(tokens))
menus_muyong = list(set(menus_muyong))
len(menus_muyong), " ".join(menus_muyong[:5])
(2880, '청경채겉절이 봉추찜닭 버섯파프리카잡채 매콤돈사태찜 날치알참치야채비빔밥')
# 메뉴 명사추출기
menu_token = menus_muyong[1828]
print("원본내용:", menu_token)
from muyong.nlp import food_nouns
food_nouns(menu_token, valid_token)
원본내용: 수제하트맛살계란전
['맛살', '계란', '전']
긴 제목에서 레시피만 추출/ 나머지 구분하기
import pandas as pd
menus_man = pd.read_csv("data/menu_1000recipe.csv", sep="|")
menus_man = menus_man.fillna('')
menus_man = menus_man.Menu.values.tolist()
menus_man[:3]
['호불호 없는 토마토파스타는 역시 ~! 토마토냉파스타 ★', '달콤 촉촉 달걀 푸딩 만들기, 만드는 법 ( 부드러운 달걀 요리 기본 원리 )', '손이가요 손이가~~자꾸 손이 가는 [가지전]']
# 메뉴 명사추출기
menu_token = menus_man[4528]
print("원본내용:", menu_token)
from muyong.nlp import food_nouns
food_nouns(menu_token, valid_token)
원본내용: 아이볶음밥 김치볶음밥 카레가루를 넣어봐요!
['볶음밥', '김치', '카레']
잡일보단 머신러닝 분석 으로 우선 모델 만들기 (30일 발표용)
%%time
# # 10,000 개 레시피 분석
# result = ["_".join(sorted(food_nouns(menu, valid_token)))
# for menu in menus_man
# if "_".join(sorted(food_nouns(menu, valid_token)))]
# result = list(sorted(set(result)))
# print(len(menus_man), len(result))
# with open("backup/menus_unique_tokens_10000.txt", 'w') as f:
# f.write(",".join(result))
# print("file saved")
# Muyong 레시피 분석
result = ["_".join(sorted(food_nouns(menu, valid_token)))
for menu in menus_muyong
if "_".join(sorted(food_nouns(menu, valid_token)))]
result = list(sorted(set(result)))
print(len(menus_muyong), len(result))
with open("backup/menus_unique_tokens_muyong.txt", 'w') as f:
f.write(",".join(result))
print("file saved")
2880 2336 file saved CPU times: user 658 ms, sys: 4.43 ms, total: 663 ms Wall time: 662 ms
특징을 대상으로 네이버 블로그 데이터 대상 수집하기
%%time
import os, sqlite3, json, time
con = sqlite3.connect("backup/food_api_muyong.db")
import pandas as pd
df = pd.read_sql("select * from 'foods'", con, index_col=None).drop('index', axis=1)
con.close()
food_links = df.data.values.tolist()
df.data = [json.loads(_) for _ in food_links] # json 디코딩
index_err = [no for no,_ in enumerate(df.data.values.tolist()) if len(_) == 0]
print(df.iloc[index_err, :])
title data 6 가쓰오국_어묵_유부 [] 7 가쓰오국_유부 [] 8 가쓰오국_유부_팽이 [] 136 감자_미트볼_알감_자미_조림 [] 1209 돈육_불고기_육간장 [] 1362 떡_물부추_해물 [] 1587 무침_물부추_콩나물 [] 1666 물부추_전_해물 [] 2209 오징어탕_탕수 [] CPU times: user 14.1 s, sys: 1.97 s, total: 16.1 s Wall time: 17.9 s
%%time
import os, sqlite3, json, time
con = sqlite3.connect("backup/food_api_10000_01.db")
tables = [_[0] for _ in con.execute("SELECT name FROM sqlite_master WHERE type='table';")]
print(tables) # 테이블 이름의 확인
import pandas as pd
df = pd.read_sql("SELECT * FROM '{}'".format(tables[0]), con, index_col=None).drop('index', axis=1)
con.close()
# 내부 Json String 을 Decoding
food_links = df.data.values.tolist()
df.data = [json.loads(_) for _ in food_links] # json 디코딩
index_err = [no for no,_ in enumerate(df.data.values.tolist()) if len(_) == 0]
print(df.iloc[index_err, :]) # 자료수집시 오류가 난 Key Word 선별
['foods'] title data 20910 곰_배추찜_양배추 [] CPU times: user 29.2 s, sys: 3.41 s, total: 32.6 s Wall time: 35.3 s
# 수집값이 없는 인덱스를 새로 수정하기
# Token Index 값이 유용한지를 Naver OpenAPI 결과값으로 구분하는 방법도 유용할 듯!!
index_err = [no for no,_ in enumerate(df.data.values.tolist()) if len(_) == 0]
token_temp_list = ["가쓰오_어묵_유부","가쓰오_유부","가쓰오_유부_팽이","감자_미트볼_알감자_조림",\
"돈육_불고기_간장","떡_부추_해물","무침_부추_콩나물","부추_전_해물","오징어_탕수"]
for no, i in enumerate(index_err):
df.iloc[i, [0]] = token_temp_list[no]
%%time
from muyong.naver import get_blog_list
from tqdm import tqdm
result = {}
for _ in tqdm(token_temp_list):
temp = []
query_token = _+"_만들기"
for i in range(1, 500, 100):
temp += get_blog_list(query_token, i)['items']
time.sleep(.3)
result[_] = temp
100%|██████████| 9/9 [00:23<00:00, 2.60s/it]
CPU times: user 551 ms, sys: 67.8 ms, total: 619 ms Wall time: 23.4 s
for no, i in enumerate(index_err):
df.iloc[i, 1] = result[token_temp_list[no]]
import pickle
with open('data/naver_key_list.pk', 'wb') as handle:
pickle.dump(df, handle, protocol=pickle.HIGHEST_PROTOCOL)
print("save is done")
save is done
# with open("menus_unique_token.txt", "r") as f:
with open("data/nouns_tokens.txt", "r") as f:
word_tokens = f.read().split(",")
# get_blog_list("가슴살_닭_매콤_볶음_우동"+"_만들기", 101)["items"][:2]
# len(word_tokens), word_tokens[1000]
list(result.keys())
['가쓰오_어묵_유부', '가쓰오_유부', '가쓰오_유부_팽이', '감자_미트볼_알감자_조림', '돈육_불고기_간장', '떡_부추_해물', '무침_부추_콩나물', '부추_전_해물', '오징어_탕수']
import pandas as pd
len(result[list(result.keys())[0]])
500
%%time
import pandas as pd
from tqdm import tqdm
from muyong.naver import get_blog_list
import time, json, os, sqlite3
file_db = "foods.db"
token_temp_list = ["가쓰오_어묵_유부","가쓰오_유부","가쓰오_유부_팽이","감자_미트볼_알감자_조림",\
"돈육_불고기_간장","떡_부추_해물","무침_부추_콩나물","부추_전_해물","오징어_탕수"]
for _ in tqdm(token_temp_list):
# web link 목록 수집하기
result, temp = [], []
query_token = _+"_만들기"
for i in range(1, 500, 100):
temp += get_blog_list(query_token, i)['items']
time.sleep(.3)
result.append([_, temp])
# sqlite3 저장하기 (단어별 결과를 Json으로 저장 (list는 저장시 오류))
df = pd.DataFrame(result)
df.columns = ['title', 'data']
df.data = [ json.dumps(_) for _ in df.data ]
con = sqlite3.connect(file_db)
df.to_sql('foods', con, if_exists='append')
con.commit()
time.sleep(.1)
df
100%|██████████| 9/9 [00:18<00:00, 2.04s/it]
CPU times: user 1.53 s, sys: 272 ms, total: 1.8 s Wall time: 18.3 s
title | data | |
---|---|---|
0 | 오징어_탕수 | [{"title": "[\ub3c4\uc2dd\ub2f9]<b>\ud0d5\uc21... |
API 수집결과 중 Link Url 만 저장하기
import pickle
with open('backup/temp/naver_api_org.pk', 'rb') as handle:
df = pickle.load(handle)
# data 에서 naver 링크만 찾아서 정리하기
df.head(3)
title | data | |
---|---|---|
0 | 가슴살_계란_닭_장조림 | [{'title': '부드러운 닭<b>가슴살</b> <b>장조림</b> <b>만들기... |
1 | 가슴살_굴소스_닭_볶음밥 | [{'title': '수비드 닭<b>가슴살</b> 요리 : 돈까스 & <b>... |
2 | 가슴살_닭_라이스_카레 | [{'title': '닭의품격 초간편 냉동닭<b>가슴살</b> <b>카레</b><b... |
df.head(20)
title | data | |
---|---|---|
0 | 가슴살_계란_닭_장조림 | [{'title': '부드러운 닭<b>가슴살</b> <b>장조림</b> <b>만들기... |
1 | 가슴살_굴소스_닭_볶음밥 | [{'title': '수비드 닭<b>가슴살</b> 요리 : 돈까스 & <b>... |
2 | 가슴살_닭_라이스_카레 | [{'title': '닭의품격 초간편 냉동닭<b>가슴살</b> <b>카레</b><b... |
3 | 가슴살_닭_매콤_볶음_우동 | [{'title': '닭<b>가슴살</b> <b>매콤</b> <b>볶음</b><b>... |
4 | 가슴살_닭_볶음밥_파인애플 | [{'title': '닭<b>가슴살</b>캔햄 치팸 <b>파인애플</b> <b>볶음... |
5 | 가슴살_닭_샐러드 | [{'title': '닭<b>가슴살</b> 샌드위치 <b>만들기</b> <b>샐러드... |
6 | 가쓰오_어묵_유부 | [{'title': '참치<b>유부</b>초밥 <b>가쓰오</b>부시볶음우동 <b>... |
7 | 가쓰오_유부 | [{'title': '참치<b>유부</b>초밥 <b>가쓰오</b>부시볶음우동 <b>... |
8 | 가쓰오_유부_팽이 | [{'title': '<b>유부</b>초밥 맛있게 만드는 법, 냉면과 <b>유부</... |
9 | 가오리_무침_회 | [{'title': '<b>가오리</b>요리- 명절에 손님맞이 밑반찬<b>만들기</... |
10 | 가오리_미나리_초무침_회 | [{'title': '<b>가오리</b> <b>초무침</b>, <b>가오리</b>회... |
11 | 가자미_강정 | [{'title': '매콤새콤달콤 깐풍 <b>가자미</b><b>강정</b> <b>만... |
12 | 가자미_강정_파채 | [{'title': '삼겹살튀김<b>강정</b> 만드는 법바쁜 맛있는 집밥> ... |
13 | 가자미_구이 | [{'title': '에어프라이어 <b>가자미</b><b>구이</b> 맛있게 굽는법... |
14 | 가자미_구이_카레 | [{'title': '<b>가자미</b> <b>카레</b><b>구이</b>, 아이 ... |
15 | 가자미_유린기 | [{'title': '색다른생선요리 <b>가자미</b> <b>유린기</b> <b>만... |
16 | 가자미_칠리소스 | [{'title': '아기반찬 : <b>칠리소스</b> 닭가슴살 레시피(18,19개... |
17 | 가자미_카레_튀김 | [{'title': '바삭한 <b>가자미</b> <b>카레</b><b>튀김</b> ... |
18 | 가자미_튀김 | [{'title': '뉴질랜드 타우랑가에서 <b>가자미</b><b>튀김</b> <b... |
19 | 가자미조림 | [{'title': '<b>가자미조림</b> <b>만들기</b> <b>가자미</b>... |
from tqdm import tqdm for datum in tqdm(df.data.values.tolist()): temp = [] for _ in datum: # 500개 개별확인 if ['link'].find("https://blog.naver.com/") != -1: temp.append(['link']) elif len(_) < 3: print("데이터가 없습니다"); pass result.append("|".join(temp)) df.data = result df.to_csv('data/naver_links_muyong.csv', index=None) df.head()
err_index = [no for no, _ in enumerate(df.data) if len(_.split('|')) < 10]
err_index
[369, 453, 880, 914]
df_sum = df.drop(err_index, axis=0).reset_index(drop=True)
df_sum.to_csv("data/naver_links_muyong.csv", index=None)
df.shape, df_sum.shape
((2335, 2), (2331, 2))
from tqdm import tqdm
from muyong.naver import get_blog_list
def error_api(token_list):
for _ in tqdm(token_list):
# web link 목록 수집하기
result, temp = [], []
query_token = _+"_만들기"
for i in range(1, 500, 100):
temp += get_blog_list(query_token, i)['items']
time.sleep(.3)
result.append([_, temp])
return result
token_temp_list = ["계란찜_알새우", "고추_마늘_무침", "깐풍_어묵", "깻잎_볶음_나물"]
error_data = error_api(token_temp_list)
len(df.data[0].split('|'))
487
# Today
# 단어 Token 을 나열된 순서대로 정리하여 문법구조 분석 알고리즘 적용
# CFG 와 유사한 방식으로 불필요한 단어 및 묶음 정리하기
# 묶음 기준을 설정한 뒤, 크롤링을 통해 단어별 문서 300개를 수집 분석하여 연관단어 찾기
명엽채(명태채)/청포북(녹두묵)
마요 => 마요네즈
소시지 => 소세지
꺳잎 => 깻잎
게란 => 계란
배춧 => 배추
불낙 => 낙지
콘 => 옥수수
돈 => 돼지
탕수 => 탕수육
우무 => 우묵
중국식/
한국식/
# import pandas as pd
# links_org = pd.read_csv('backup/naver_link_temp.csv')
# links_org = links_org.fillna('')
# import sqlite3
# conn = sqlite3.connect("backup/naver.db")
# df = pd.read_sql('SELECT * FROM "foods"', conn, index_col=None).drop('index', axis=1)
# conn.close()
# df.columns = links_org.columns
# df.title = links_org.title[:df.shape[0]].tolist()
# df.to_csv("data/naverPost2.csv", index=None)
# df.head(2)
# import pandas as pd
# from glob import glob
# file_list = glob("data/naverPost*.*")
# result = []
# for _ in file_list:
# result.extend(pd.read_csv(_).values.tolist())
# df = pd.DataFrame(result)
# df.columns = ['Query', 'Posts']
# df.to_csv("data/naverPost.csv", index=None)
# df.head(2)
import pandas as pd
# df = pd.read_csv("data/naverPost_muyong_fixed.csv")
# df = df.iloc[:,1:]
df = pd.read_csv("data/naverPost_muyong.csv")
df.shape, len(df.Posts[1].split("|")), df.head(3)
((2333, 2), 100, Query Posts 0 가슴살_계란_닭_장조림 반찬 볶음 조림.부드러운 닭가슴살 장조림 만들기.베리츄..2017.9.1.22 32... 1 가슴살_굴소스_닭_볶음밥 아임닭 7기 종료.수비드 닭가슴살 요리 돈까스 볶음밥 만들기.주니호맘..2019.4... 2 가슴살_닭_라이스_카레 food.닭의품격 초간편 냉동닭가슴살 카레라이스 만들기.유누네..2018.9.22....)
Word2vec 을 만들기 위해서는 문장 데이터로 전처리가 필요하다
# link_temp = links_org.iloc[370:1200,:] # .to_csv('naver_links_temp.csv')
# link_temp = link_temp.reset_index(drop=True)
# link_temp = link_temp.drop([544], axis=0).reset_index(drop=True)
# link_temp.head(2)
import re
def dot_fixer(sent):
dot_to_nun = re.compile(r"(?P<num>(\d+)).(?P<dot>(\d+))")
nun_to_dot = re.compile(r"(?P<num>(\d+))=(?P<dot>(\d+))")
post_temp = dot_to_nun.sub("\g<num>=\g<dot>", sent)
post_temp = "\n".join(post_temp.split(".")).replace("^"," ").replace("["," ").replace("]"," ").replace("("," ").replace(")"," ")
post_temp = nun_to_dot.sub("\g<num>.\g<dot>", post_temp)
return post_temp
# # 크롤링 잘못된 소숫점 숫자를 치환후 줄바꿈 처리 모두 바꾸기
# import pandas as pd
# df = pd.read_csv("data/naverPost_muyong.csv")
# from tqdm import tqdm
# posts = df.Posts.tolist()
# df.Posts = [dot_fixer(_) for _ in tqdm(posts)]
# df.head(3)
# df.to_csv("data/naverPost_muyong.csv", index=None)
# print("dot fixed")
from konlpy.tag import Mecab, Okt
text = "오늘의 김치찌개는 싱거워서 고유한 텁텁한 단맛이 잘 안난다"
Mecab().pos(text)
[('오늘', 'NNG'), ('의', 'JKG'), ('김치찌개', 'NNG'), ('는', 'JX'), ('싱거워서', 'VA+EC'), ('고유', 'NNG'), ('한', 'XSA+ETM'), ('텁텁', 'XR'), ('한', 'XSA+ETM'), ('단맛', 'NNG'), ('이', 'JKS'), ('잘', 'MAG'), ('안', 'MAG'), ('난다', 'VV+EC')]
Okt().pos(text)
[('오늘', 'Noun'), ('의', 'Josa'), ('김치찌개', 'Noun'), ('는', 'Josa'), ('싱거워서', 'Adjective'), ('고유', 'Noun'), ('한', 'Josa'), ('텁텁', 'Noun'), ('한', 'Josa'), ('단맛', 'Noun'), ('이', 'Josa'), ('잘', 'Verb'), ('안', 'VerbPrefix'), ('난다', 'Verb')]