본문 바로가기

ML/인공지능

bigquery ML Titanic

해당 예제는 bigquery의 bgml을 사용해서 타이타닉을 예측하는 예제이다. 

 

 

 

데이터 다운로드 

https://www.kaggle.com/competitions/titanic/data

 

Titanic

Kaggle profile for Titanic

www.kaggle.com

 

 

파일 업로드로 빅쿼리에 테이블로 변환

 

 

생성 완료 

 

 

모델 생성 

CREATE OR REPLACE MODEL `project.dataset.titanic_logistic_model`
OPTIONS (
  model_type = 'logistic_reg',
  input_label_cols = ['Survived']
) AS
SELECT
  Survived,
  Pclass,
  IF(Sex = 'male', 1, 0) AS Sex,
  Age,
  SibSp,
  Parch,
  Fare
FROM
  `project.dataset.titanic_train`
WHERE
  Age IS NOT NULL AND Fare IS NOT NULL;

 

 

 

6번 만에 종료됨 

 

 

 

모델 평가 

SELECT
  *
FROM
  ML.EVALUATE(
    MODEL `project.dataset.titanic_logistic_model`,
    (
      SELECT
        Survived,
        Pclass,
        IF(Sex = 'male', 1, 0) AS Sex,
        Age,
        SibSp,
        Parch,
        Fare
      FROM
        `project.dataset.titanic_train`
    )
  );

 

정확도 0.79로 꽤나 높은걸 알수 있다. 

실제 test.csv를 통해서 결과값을 뽑아보자 

 

 

 

sql의 predict 값은 배열값으로 나와서 파이썬으로 한번 정제 후에  업로드 하였다. 

import pandas as pd
import ast

# CSV 재로드
df = pd.read_csv("titnic_predict.csv")

# JSON 문자열을 파싱하고, 확률이 더 높은 label을 label 컬럼으로 지정
# 정확한 JSON 파싱 및 label 추출 로직
def extract_label_from_nested_json(row):
    try:
        outer_json = ast.literal_eval(row["predicted_Survived_probs"])
        probs = outer_json["predicted_Survived_probs"]
        best_label = max(probs, key=lambda x: float(x["prob"]))
        return int(best_label["label"])
    except Exception as e:
        return None

# label 컬럼 재생성
df["label"] = df.apply(extract_label_from_nested_json, axis=1)

# 다시 확률 JSON 컬럼 제거
df_final = df.drop(columns=["predicted_Survived_probs"])


df_final.to_csv("predict.csv")

 

 

submission 결과물 

 

겨우 0.54%가 나왔다. 

 


 

두번째 모델 생성

where 절의 age가 null 이면 제거 했는데, 데이터가 많이 누락된것으로 보였다. 

모델도 바꿨는데, xgboost classifition 으로 보면 된다. 

CREATE OR REPLACE MODEL `project.test.titanic_logistic_model`
OPTIONS (
  model_type = 'boosted_tree_classifier',
  input_label_cols = ['Survived'],
  auto_class_weights = TRUE
) AS
SELECT
  Survived,
  Pclass,
  IF(Sex = 'male', 1, 0) AS Sex,
  COALESCE(Age, AVG(Age) OVER (PARTITION BY Pclass, Sex)) AS Age,
  SibSp,
  Parch,
  Fare,
  Fare / (SibSp + Parch + 1) AS FarePerPerson,
  IF(SibSp + Parch = 0, 1, 0) AS IsAlone,
  REGEXP_EXTRACT(Name, r'(Mr|Mrs|Miss|Master)') AS Title
FROM
  `project.test.titanic_train`

 

 

굳!! 잘된다.

 

 

 

번외

학습시 너무 시간이 오래 걸린다...

굳이 데이터가 빅쿼리에 적재되어 있다면 그냥 gcp의 다른 AI 모듈을 사용하는게 더 좋을떄도 있다.