본문 바로가기
study/Python

[Python] 49. titanic_train.csv 분석하기, 분류 모델 평가, 카카오맵을 크롤링하여 맛집리뷰에 사용되는 용어 분석하기

by 금이패런츠 2022. 7. 13.
728x90
반응형

1. titanic_train.csv 분석하기

2.분류 모델 평가

3. 카카오맵을 크롤링하여 맛집리뷰에 사용되는 용어 분석하기

# -*- coding: utf-8 -*-
"""
Created on Tue Jul 12 09:01:03 2022

@author: KITCOOP
20220712.py
"""
'''
    titanic 속성
pclass : Passenger Class, 승객 등급
survived : 생존 여부
name : 승객 이름
sex : 승객 성별
age : 승객 나이
sibsp : 탑승 한 형제/배우자 수
parch : 탑승 한 부모/자녀 수
ticket : 티켓 번호
fare : 승객 지불 요금
cabin : 선실 이름
embarked : 승선항 (C = 쉘 부르그, Q = 퀸즈타운, S = 사우스 햄튼)
body : 사망자 확인 번호
home.dest : 고향/목적지
'''
########## 1. titanic_train.csv 분석하기
import pandas as pd
df_train = pd.read_csv("data/titanic_train.csv")
df_test = pd.read_csv("data/titanic_test.csv")
df_train.info()
df_test.info()
# df_train 데이터에서 생존여부를 그래프로 출력하기
df_train["survived"].value_counts()
df_train["survived"].value_counts().plot.bar()
df_train["survived"].value_counts().plot(kind="bar")

#좌석등급별 생존여부를 그래프로 출력하기
#1. 인원수 조회하기
df_train.groupby("pclass")["survived"].value_counts()
df_train[["pclass","survived"]].value_counts()
df_train[["pclass","survived"]].value_counts().sort_index()
#2 그래프 출력하기
#countplot : x축:pclass 데이터. y축:pclass의 건수
#           hue="survived" : survived 컬럼을 기준으로 분리
import seaborn as sns
sns.countplot(x="pclass",hue="survived",data=df_train)
#성별 생존여부를 그래프로 출력하기
df_train[["sex","survived"]].value_counts().sort_index()
sns.countplot(x="sex",hue="survived",data=df_train)
df_train.info()
df_test.info()
# 1. age 컬럼의 결측값을 df_train데이터의 평균값으로 변경하기 (df_train,df_test)
age_mean = df_train["age"].mean()
age_mean
df_train['age'] = df_train['age'].fillna(age_mean)
df_test['age'] = df_test['age'].fillna(age_mean)

df_train["age"].mean()
df_train.info()
df_test.info()
# 2. embarked 컬럼의 결측값을 최빈값으로 변경하기(df_train)
freq_embarked = df_train["embarked"].value_counts(dropna=False).idxmax()
freq_embarked = df_train["embarked"].value_counts(dropna=False).index[0]
freq_embarked
df_train['embarked'] = df_train['embarked'].fillna(freq_embarked)
df_train.info()
df_train["embarked"].value_counts(dropna=False)

#3. name,ticket,cabin,body,home.dest 컬럼 제거
df_train = df_train.drop(["name","ticket","cabin","body","home.dest"],axis=1)
df_test = df_test.drop(["name","ticket","cabin","body","home.dest"],axis=1)
df_train.info()
df_test.info()
#4. one-hot encoding을 위한 통합 데이터 프레임(whole_df)을 생성
whole_df = df_train.append(df_test)
whole_df.info()
#원핫인코딩하기
whole_df_encoded = pd.get_dummies(whole_df)
whole_df_encoded.info()
#whole_df_encoded 데이터를 다시 df_train,df_test로 분리하기
train_num = len(df_train)
train_num
df_train = whole_df_encoded[:train_num]
df_test = whole_df_encoded[train_num:]
df_train.info()
df_test.info()
#5. 설명변수,목표변수로 분리하기
# 설명변수 : survived외의 모든 컬럼.
# 목표변수 : survived 컬럼.
x_train = df_train.loc[:,df_train.columns != 'survived'].values
x_train
y_train = df_train['survived'].values
y_train
x_test = df_test.loc[:,df_test.columns != 'survived'].values
x_test
y_test = df_test['survived'].values
y_test
#로지스틱 회귀분석 모델을 이용하여 분류하기
#로지스틱 회귀분석 분류 알고리즘.
from sklearn.linear_model import LogisticRegression
#random_state=0 : 독립변수들의 가중치 선택. 임의 선택방식
#                 모델의 재현성을 위해서 설정
lr = LogisticRegression(random_state=0)
lr.fit(x_train,y_train) #학습하기
y_pred=lr.predict(x_test) #예측하기
y_pred[:10]  #예측된 데이터
y_test[:10]  #실제 데이터

########## 2.분류 모델 평가
#1. 혼동행렬(Confusion Matrix)
from sklearn.metrics import confusion_matrix
conmat=confusion_matrix(y_true=y_test,y_pred=y_pred)
print(conmat)
#2. 정확도,정밀도,재현율,f1-score 출력하기
from sklearn.metrics import accuracy_score,recall_score,precision_score,f1_score
print("정확도:",accuracy_score(y_test,y_pred))
print("정밀도:",precision_score(y_test,y_pred))
print("재현율:",recall_score(y_test,y_pred))
print("f1-score:",f1_score(y_test,y_pred))
'''
[[214  32]
 [ 48  99]]
정확도: 0.7964376590330788
정밀도: 0.7557251908396947
재현율: 0.673469387755102
f1-score: 0.712230215827338
'''
# cabin(선실) 컬럼을  추가하여 예측하기
import pandas as pd
df_train = pd.read_csv("data/titanic_train.csv")
df_test = pd.read_csv("data/titanic_test.csv")
#cabin 데이터 조회하기
df_train["cabin"].value_counts()
# 1. age 컬럼의 결측값을 df_train데이터의 평균값으로 변경하기 (df_train,df_test)
age_mean = df_train["age"].mean()
df_train['age'] = df_train['age'].fillna(age_mean)
df_test['age'] = df_test['age'].fillna(age_mean)

# 2. embarked 컬럼의 결측값을 최빈값으로 변경하기(df_train)
freq_embarked = df_train["embarked"].value_counts(dropna=False).idxmax()
df_train['embarked'] = df_train['embarked'].fillna(freq_embarked)

#3. df_train,df_test 데이터를 하나의 데이터 whole_df 로 저장하기
whole_df = df_train.append(df_test)
whole_df.info()
train_num = len(df_train)

#4. cabin 컬럼의 결측값을 X로 변경하기
whole_df["cabin"] = whole_df["cabin"].fillna("X")
whole_df.info()
whole_df["cabin"].unique()

#cabin 컬럼의 첫번째 문자만 추출하여 cabin 컬럼에 저장
# "B57 B59 B63 B66" => B 저장하기
# "B96 B98'" => B 저장하기
# "F E69" => F 저장하기
whole_df["cabin"] = whole_df["cabin"].apply(lambda x:x[0])
whole_df["cabin"].value_counts()
#G,T 값은 빈도수가 작아서 X로 치환하기
whole_df["cabin"]=whole_df["cabin"].replace({"G":"X","T":"X"})
whole_df["cabin"].value_counts()
#cabin 별 생존자별 그래프 출력하기
sns.countplot(x="cabin",hue="survived", data=whole_df)

# name 피처 활용하기
whole_df['name'].head()

#name의 ,를 기준으로 두번째 문자열이 당시의 사회적 지위에 해당 하는 문자.
#name_grade 컬럼에 저장하기
#Mellinger, Miss. Madeleine Violet
name_grade = whole_df["name"].apply(lambda x:x.split(", ")[1].split(".")[0])
name_grade
name_grade.value_counts(dropna=False)
# 호칭에 따라, 사회적 지위를 나타냄
grade_dict = {
      'A' :['Rev','Col','Major','Dr','Capt','Sir'], #명예직
      'B' :['Ms','Mme','Mrs','Dona'], #여성
      'C' :['Jonkheer','the Countess'], #귀족
      'D' :['Mr','Don'], #남성
      'E' :['Master'], #젊은남성
      'F' :['Miss','Mlle','Lady'] #젊은여성
    }
#name 컬럼을 A~G까지의 값으로 변경하기
# G그룹:name_grade의 값이 A~F에 속하지 않으면
def give_grade(g) :  #g:이름의 지위부분. Miss
    for k,v in grade_dict.items() : #A,['Rev','Col','Major','Dr','Capt','Sir']
        for title in v:
            if g == title :
                return k
    return 'G'

name_grade = list(name_grade.map(lambda x:give_grade(x)))
name_grade[:10]
whole_df['name'] = name_grade     
whole_df['name'].value_counts() 

#name별로 생존여부를 그래프로 출력하기
sns.countplot(x="name",hue="survived", data=whole_df)
whole_df.info()

#ticket,body,home.dest 컬럼을 삭제하기
whole_df = whole_df.drop(["ticket","body","home.dest"],axis=1)
whole_df.info()
#one-hot 인코딩하여 whole_df_encoded 데이터 저장하기
whole_df_encoded = pd.get_dummies(whole_df)
whole_df_encoded.info()
# x_train,x_test, y_train, y_test 데이터 분리.
df_train = whole_df_encoded[:train_num]
df_test = whole_df_encoded[train_num:]

x_train = df_train.loc[:,df_train.columns != 'survived'].values
y_train = df_train['survived'].values
x_test = df_test.loc[:,df_test.columns != 'survived'].values
y_test = df_test['survived'].values
from sklearn.linear_model import LogisticRegression
lr = LogisticRegression(random_state=0)
lr.fit(x_train,y_train) #학습하기
y_pred=lr.predict(x_test) #예측하기
y_pred[:10]  #예측된 데이터
y_test[:10]  #실제 데이터
#분류 모델 평가
#1. 혼동행렬(Confusion Matrix)
from sklearn.metrics import confusion_matrix
conmat=confusion_matrix(y_true=y_test,y_pred=y_pred)
print(conmat)
#2. 정확도,정밀도,재현율,f1-score 출력하기
from sklearn.metrics import accuracy_score,recall_score,precision_score,f1_score
print("정확도:",accuracy_score(y_test,y_pred))
print("정밀도:",precision_score(y_test,y_pred))
print("재현율:",recall_score(y_test,y_pred))
print("f1-score:",f1_score(y_test,y_pred))
'''
[[214  32]
 [ 48  99]]
정확도: 0.7964376590330788
정밀도: 0.7557251908396947
재현율: 0.673469387755102
f1-score: 0.712230215827338


[[209  37]
 [ 44 103]]

정확도: 0.7938931297709924
정밀도: 0.7357142857142858
재현율: 0.7006802721088435
f1-score: 0.7177700348432055
'''
# 피처별 영향력을 그래프로 출력
import numpy as np
import matplotlib.pyplot as plt
cols = df_train.columns.tolist() #컬럼명 목록
cols.remove('survived') #survived 컬럼 제거. 설명변수 목록
y_pos = np.arange(len(cols)) #x축값
plt.rcParams['figure.figsize'] = [5, 4] #그래프크기 지정
fig, ax = plt.subplots()
#barh() : 수평막대그래프
#lr.coef_ : 회귀계수. 2차원배열. 
ax.barh(y_pos, lr.coef_[0], align='center', color='green', ecolor='black')
ax.set_yticks(y_pos) # y축데이터
ax.set_yticklabels(cols) #y축데이터의 이름
ax.invert_yaxis() #y축데이터를 위아래변경
ax.set_xlabel('Coef')
ax.set_title("Each Feature's Coef")
plt.show()
'''
   한글 분석을 위한 모듈 : konlpy
   pip install konlpy
   
   한글 형태소 분석기 : 
       Okt(Open Korean Text)
       Kkma(코코마)
       Komoran(코모란)
       Hannanum(한나눔)
  시스템환경변수 : JAVA_HOME 설정필요     
'''
from konlpy.tag import Okt,Kkma,Komoran,Hannanum
okt=Okt()
kkma=Kkma()
komoran = Komoran()
han=Hannanum()

import time

def sample_ko_pos(text):
    print(f"==== {text} ====") #f" {변수값}   "
    start = time.time() #현재 시간.
    #pos(text) : text를 형태소를 분리. 품사표시
    print("kkma:",kkma.pos(text),",실행시간:",time.time()-start)
    start = time.time()
    print("komoran:",komoran.pos(text),",실행시간:",time.time()-start)
    start = time.time()
    print("okt:",okt.pos(text),",실행시간:",time.time()-start)
    start = time.time()
    print("hannanum:",han.pos(text),",실행시간:",time.time()-start)
    print("\n")

text1 = "영실아 안녕 오늘 날씨 어때"
sample_ko_pos(text1)

text2 = "영실아안녕오늘날씨어때"
sample_ko_pos(text2)

text3 = "안녕 ㅎㅏㅅㅔ요 ㅈㅓ는ㄷㅐ학생입니다"
sample_ko_pos(text3)

########## 3. 카카오맵을 크롤링하여 맛집리뷰에 사용되는 용어 분석하기
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from selenium import webdriver #pip install selenium
from selenium.webdriver.common.by import By
from bs4 import BeautifulSoup
import re
import time
import selenium
selenium.__version__ #4.3.0
path = 'C:/setup/chromedriver.exe'
source_url = "https://map.kakao.com/"
driver = webdriver.Chrome(path)
driver.get(source_url)
# id="search.keyword.query" 태그 선택=> input 태그 
searchbox=driver.find_element(By.ID,"search.keyword.query") 
searchbox.send_keys("강남역 고기집") #강남역 고기집 값입력
# id="search.keyword.submit" 태그 선택=> input 태그 
searchbutton=driver.find_element(By.ID,"search.keyword.submit") 
#script를 실행
#arguments[0].click(); : 첫번째 매개변수값을 클릭
driver.execute_script("arguments[0].click();", searchbutton) #검색버튼클릭.
time.sleep(2) #2초동안 대기 => 강남역 고기집 검색 결과가 브라우저에 표시됨
html = driver.page_source
soup = BeautifulSoup(html, "html.parser")
moreviews = soup.find_all(name="a", attrs={"class":"moreview"})
page_urls = [] 
for moreview in moreviews:
    page_url = moreview.get("href") 
    page_urls.append(page_url)
driver.close()    
print(page_urls)
728x90
반응형