Snowflake Data Clean Rooms에서 머신러닝을 해요

Snowflake Data Clean Rooms에서 머신러닝을 해요

Snowflake Data Clean Rooms: 머신 러닝

서비스 종료 공지

레거시 Provider 및 Consumer Data Clean Rooms는 중단될 예정이에요. 날짜와 마이그레이션 지침은 end-of-life timeline을 참고하세요.

이 항목에서는 clean room을 프로그래밍 방식으로 설정하고, 소비자와 공유하고, 고급 머신 러닝 알고리즘을 통해 분석을 실행하는 데 필요한 공급자 및 소비자 흐름을 설명해요. 공급자 흐름은 랜덤 포레스트 기반 XGBoost 머신 러닝 알고리즘을 구현하는 보안 Python 코드를 clean room에 로드해요. 이 코드는 완전히 기밀로 유지되며 공급자에게만 보여요. 소비자는 clean room에 로드된 Python 머신 러닝 코드를 볼 수 없어요.

이 흐름은 다음을 다루어요:

공급자:

a. Lookalike Modeling 분석을 실행하는 사용자 지정 템플릿을 추가해요.

b. XGBoost를 활용하는 머신 러닝 Python 코드 기반 템플릿을 안전하게 추가해요.

c. 사용자 지정 템플릿을 사용하여 clean room 내부에서 머신 러닝 UDF를 호출해요.

소비자:

a. 공급자가 정의한 ML 함수를 사용하는 사용자 지정 템플릿을 실행해요.

Lookalike Modeling은 소비자가 자신의 고가치 고객에 대해 통계 모델을 학습시켜 공급자의 데이터에서 "고가치" 고객을 찾으려는 분석 유형이에요. 이 모델은 소비자 데이터셋에서 특정 기준 이상의 지출과 같은 고가치 사용자를 나타내는 소비자 지정 플래그를 사용해요. 학습된 모델은 공급자의 데이터에서 어떤 고객이 소비자에게 잠재적으로 "고가치"가 될 수 있는지 추론하는 데 사용돼요.

출처: 문서

본문


사전 준비 사항

이 흐름을 완료하려면 두 개의 별도 Snowflake 계정이 필요해요. 첫 번째 계정으로 공급자(provider) 명령을 실행한 다음, 두 번째 계정으로 전환하여 소비자(consumer) 명령을 실행하세요.

공급자(Provider)

참고

다음 명령은 공급자 계정의 Snowflake 워크시트에서 실행해야 해요.

환경 설정

Snowflake Data Clean Room 작업에 개발자 API를 사용하기 전에 다음 명령을 실행하여 Snowflake 환경을 설정하세요. SAMOOHA_APP_ROLE 역할이 없다면 계정 관리자에게 문의하세요.

use role SAMOOHA_APP_ROLE;
use warehouse app_wh;

clean room 만들기

clean room의 이름을 만드세요. 기존 clean room 이름과 충돌하지 않도록 새 clean room 이름을 입력하세요. clean room 이름은 **영숫자(alphanumeric)**만 사용할 수 있어요. clean room 이름에는 공백과 밑줄 외의 특수 문자는 포함할 수 없어요.

set cleanroom_name = 'Machine Learning Demo Clean room';

위에서 설정한 clean room 이름으로 새 clean room을 만들 수 있어요. 위에서 설정한 clean room 이름이 이미 기존 clean room으로 존재하면 이 프로세스는 실패해요.

이 절차는 실행하는 데 시간이 조금 더 걸릴 수 있으며, 일반적으로 약 30초 정도 소요돼요.

provider.cleanroom_init의 두 번째 인자는 clean room의 배포(distribution) 방식이에요. 이 값은 INTERNAL 또는 EXTERNAL 중 하나일 수 있어요. 테스트 목적으로, 같은 조직 내 계정과 clean room을 공유하는 경우 INTERNAL을 사용하여 애플리케이션 패키지가 협업자에게 릴리스되기 전에 수행되어야 하는 자동 보안 검사를 건너뛸 수 있어요. 하지만 다른 조직의 계정과 clean room을 공유하는 경우에는 EXTERNAL clean room 배포 방식을 사용해야 해요.

call samooha_by_snowflake_local_db.provider.cleanroom_init($cleanroom_name, 'INTERNAL');

보안 검사 상태를 확인하려면 다음을 사용하세요:

call samooha_by_snowflake_local_db.provider.view_cleanroom_scan_status($cleanroom_name);

clean room을 만든 후에는 협업자와 공유하려면 먼저 릴리스 지시문(release directive)을 설정해야 해요. 하지만 배포 방식을 EXTERNAL로 설정한 경우에는 릴리스 지시문을 설정하기 전에 보안 검사가 완료될 때까지 기다려야 해요. 검사가 실행되는 동안 나머지 단계를 계속 진행하고 provider.create_or_update_cleanroom_listing 단계 전에 이곳으로 돌아올 수 있어요.

릴리스 지시문을 설정하려면 다음을 호출하세요:

call samooha_by_snowflake_local_db.provider.set_default_release_directive($cleanroom_name, 'V1_0', '0');

중요

소비자와 공급자가 서로 다른 클라우드 리전에 있는 경우, 두 계정과 두 clean room 모두에서 Cross-cloud auto-fulfillment를 활성화해야 해요.

데이터셋 연결 및 데이터셋 조인 정책 설정

Snowflake 테이블을 clean room에 연결하세요. Snowflake 계정의 테이블 목록을 살펴보고 정규화된 테이블 이름(Database.Schema.Table)을 배열로 입력하세요. 이 절차는 clean room 내부에서 테이블의 보안 뷰를 생성하여 테이블을 clean room에서 자동으로 액세스할 수 있게 해주므로, 테이블 복사본을 만들 필요가 없어요.

call samooha_by_snowflake_local_db.provider.link_datasets($cleanroom_name, ['samooha_provider_sample_database.lookalike_modeling.customers']);

참고

테이블이 존재하는데도 이 단계가 작동하지 않는다면 SAMOOHA_APP_ROLE 역할에 아직 해당 테이블에 대한 액세스 권한이 부여되지 않았을 가능성이 커요. 그렇다면 ACCOUNTADMIN 역할로 전환하여 데이터베이스에서 아래 절차를 호출한 다음, 나머지 흐름을 위해 다시 전환하세요:

use role accountadmin;
call samooha_by_snowflake_local_db.provider.register_db('<DATABASE_NAME>');
use role SAMOOHA_APP_ROLE;

다음 절차를 호출하여 clean room에 연결된 데이터셋 이름을 확인할 수 있어요.

call samooha_by_snowflake_local_db.provider.view_provider_datasets($cleanroom_name);

다음 절차를 사용하여 clean room에 연결된 데이터셋을 볼 수 있어요:

select * from samooha_provider_sample_database.lookalike_modeling.customers limit 10;

clean room 내에서 템플릿을 실행할 때 소비자가 조인할 수 있는 열을 지정하세요. 이 절차는 email과 같은 식별 열에 대해 호출해야 해요. 조인 정책은 “replace only” 방식이라서, 함수를 다시 호출하면 이전에 설정된 조인 정책이 새 정책으로 완전히 대체돼요.

call samooha_by_snowflake_local_db.provider.set_join_policy($cleanroom_name, ['samooha_provider_sample_database.lookalike_modeling.customers:hashed_email']);

조인 정책 열을 결정하기 위해 모든 열을 확인하려면 다음 절차를 호출하세요.

call samooha_by_snowflake_local_db.provider.view_join_policy($cleanroom_name);

clean room에 기밀 머신러닝 Python 코드 추가

이 섹션에서는 lookalike ML 작업을 위해 일부 Python 함수를 clean room에 로드하는 방법을 보여드려요. clean room에 설치된 모든 Python 함수는 완전히 기밀로 유지되며, 소비자가 볼 수 없어요.

다음 API를 사용하면 Python 함수를 clean room에 인라인 함수로 직접 정의할 수 있어요. 또는 clean room 스테이지에 업로드한 스테이징 파일에서 Python을 로드할 수도 있어요. 예시는 API 참조 가이드를 참조하세요.

참고

이 구현은 ARRAY_AGG로 집계할 수 있는 데이터 양에 대한 Snowflake 전체 크기 제약(128MB)에 의해 제한돼요. 요청 시, Snowflake는 배치 및 스트리밍 모델을 활용하여 임의 크기의 데이터 세트로 확장할 수 있는 구현을 제공해요.

call samooha_by_snowflake_local_db.provider.load_python_into_cleanroom(
    $cleanroom_name,
    'lookalike_train',
    ['input_data variant', 'labels variant'],
    ['pandas', 'numpy', 'xgboost'],
    'variant',
    'train',
    $$
import numpy as np
import pandas as pd
import xgboost
from sklearn import preprocessing
import sys
import os
import pickle
import codecs
import threading

class TrainXGBoostClassifier(object):
    def __init__(self):
        self.model = None
        self._params = {
            "objective": "binary:logistic",
            "max_depth": 3,
            "nthread": 1,
            "eval_metric": "auc",
        }
        self.num_boosting_rounds = 10

    def get_params(self):
        if self.model is not None and "updater" not in self._params:
            self._params.update(
                {"process_type": "update", "updater": "refresh", "refresh_leaf": True}
            )
        return self._params

    def train(self, X, y):
        """
        Train the model in a threadsafe way
        """
        # pick only the categorical attributes
        categorical = X.select_dtypes(include=[object])

        # fit a one-hot-encoder to convert categorical features to binary features (required by XGBoost)
        ohe = preprocessing.OneHotEncoder()
        categorical_ohe = ohe.fit_transform(categorical)
        self.ohe = ohe

        # get the rest of the features and add them to the binary features
        non_categorical = X.select_dtypes(exclude=[object])
        train_x = np.concatenate((categorical_ohe.toarray(), non_categorical.to_numpy()), axis=1)

        xg_train = xgboost.DMatrix(train_x, label=y)

        params = self.get_params()
        params["eval_metric"] = "auc"
        evallist = [(xg_train, "train")]
        evals_result = {}

        self.model = xgboost.train(
            params, xg_train, self.num_boosting_rounds, evallist, evals_result=evals_result
        )

        self.evals_result = evals_result

    def __dump_model(self, model):
        """
        Save down the model as a json string to load up for scoring/inference
        """
        pickle_jar = codecs.encode(pickle.dumps([model, self.ohe]), "base64").decode()
        return pickle_jar

    def dump_model(self):
        """
        Save down the model as a json string to load up for scoring/inference
        """
        if self.model is not None:
            return self.__dump_model(self.model)
        else:
            raise ValueError("Model needs to be trained first")

def train(d1, l1):

    # get take training features and put them in a pandas dataframe
    X = pd.DataFrame(d1)

    # get the labels into a Numpy array
    y = np.array(l1)

    trainer = TrainXGBoostClassifier()
    trainer.train(X, y)

    # return training stats, accuracy, and the pickled model and pickled one-hot-encoder
    return {
        "total_rows": len(d1),
        "total_bytes_in": sys.getsizeof(d1),
        "model": trainer.dump_model(),
        "iteration": trainer.num_boosting_rounds,
        "auc": np.max(trainer.evals_result["train"]["auc"]),
        "error": 1 - np.max(trainer.evals_result["train"]["auc"])
    }
    $$
);

이제 clean room에 scoring 함수를 설치해 볼게요.

call samooha_by_snowflake_local_db.provider.load_python_into_cleanroom(
    $cleanroom_name,
    'lookalike_score',
    ['pickle_jar variant', 'emails variant', 'features variant'],
    ['pandas', 'numpy', 'xgboost', 'scikit-learn'],
    'string',
    'score',
    $$
import numpy as np
import pandas as pd
import xgboost as xgb
import pickle
import codecs
import json

def score(model, emails, features):
    # load model
    model = model[0] if not isinstance(model, str) else model
    model = pickle.loads(codecs.decode(model.encode(), "base64"))

    # retrieve the XGBoost trainer from the pickle jar
    bst = model[0]

    # retrieve the fitted one-hot-encoder from the pickle jar
    ohe2 = model[1]

    # create pandas dataframe from the inference features
    Y = pd.DataFrame(features)

    # select the categorical attributes and one-hot-encode them
    Y1 = Y.select_dtypes(include=[object])
    Y2 = ohe2.transform(Y1)

    # select the non-categorical attributes
    Y3 = Y.select_dtypes(exclude=[object])

    # join the results of the one-hot encoding to the rest of the attributes
    Y_pred = np.concatenate((Y2.toarray(), Y3.to_numpy()), axis=1)

    # inference
    dscore = xgb.DMatrix(Y_pred)
    pred = bst.predict(dscore)

    retval = list(zip(np.array(emails), list(map(str, pred))))
    retval = [{"email": r[0], "score": r[1]} for r in retval]
    return json.dumps(retval)
    $$
);

참고

clean room에 Python을 로드하면 clean room에 대한 새 패치가 생성돼요. clean room 배포 방식이 EXTERNAL로 설정된 경우 보안 검사가 완료될 때까지 기다린 후 다음을 사용하여 기본 릴리스 지시문을 업데이트해야 해요:

-- See the versions available inside the cleanroom
show versions in application package samooha_cleanroom_Machine_Learning_Demo_clean_room;

-- Once the security scan is approved, update the release directive to the latest version
call samooha_by_snowflake_local_db.provider.set_default_release_directive($cleanroom_name, 'V1_0', '2');

사용자 지정 Lookalike 모델링 템플릿 추가

clean room에 사용자 지정 분석 템플릿을 추가하려면 공급자 측과 소비자 측 모두의 테이블 이름에 대한 자리 표시자와 공급자 측의 조인 열이 필요해요. SQL Jinja 템플릿에서 이러한 자리 표시자는 항상 다음과 같아야 해요:

source_table: 공급자의 테이블 이름으로 구성된 array

my_table: 소비자의 테이블 이름으로 구성된 array



테이블 이름은 이러한 변수를 사용하여 동적으로 만들 수 있지만, 원한다면 클린룸에 연결된 뷰의 이름을 사용하여 템플릿에 하드코딩할 수도 있어요. 컬럼 이름도 원한다면 템플릿에 하드코딩하거나 매개변수를 통해 동적으로 설정할 수 있답니다. 매개변수로 설정하는 경우, 컬럼 정책에 대해 검사받으려면 매개변수 이름을 dimensions 또는 measure_column으로 지정해야 하고, 이들은 배열이어야 한다는 점을 기억하세요. 이러한 매개변수는 나중에 소비자가 쿼리할 때 전달할 수 있도록 템플릿에 SQL Jinja 매개변수로 추가해요. 조인 정책은 소비자가 승인된 컬럼 외의 다른 컬럼으로 조인할 수 없도록 보장합니다.

또는 사용자 지정 SQL Jinja 템플릿의 모든 인자는 다음 필터를 사용하여 조인 정책 및 컬럼 정책을 준수하는지 검사할 수 있어요.

  • join_policy: 문자열 값 또는 필터 절이 조인 정책을 준수하는지 검사해요.
  • column_policy: 문자열 값 또는 필터 절이 컬럼 정책을 준수하는지 검사해요.
  • join_and_column_policy: 필터 절에서 조인에 사용된 컬럼이 조인 정책을 준수하는지, 그리고 필터로 사용된 컬럼이 컬럼 정책을 준수하는지 검사해요.

예를 들어 {{ provider_id | sqlsafe | join_policy }} 절에서 p.HEM 입력값을 파싱하여 p.HEM이 조인 정책에 포함되어 있는지 확인해요. 참고: sqlsafe 필터는 주의해서만 사용하세요. 이 필터는 협업자가 템플릿에 순수 SQL을 넣을 수 있게 허용합니다.

참고

모든 공급자/소비자 테이블은 이러한 인자를 사용하여 참조해야 해요. 실제로 클린룸에 연결된 보안 뷰의 이름은 테이블 이름과 다르기 때문이에요. 중요한 점은 공급자 테이블 별칭은 반드시 p (또는 p1), p2, p3, p4 등이어야 하고, 소비자 테이블 별칭은 반드시 c (또는 c1), c2, c3 등이어야 한다는 거예요. 이는 클린룸에서 보안 정책을 적용하는 데 필요합니다.

이 함수는 동일한 이름의 기존 템플릿을 덮어써요. 기존 템플릿을 업데이트하려면 업데이트된 템플릿으로 이 함수를 다시 호출하기만 하면 됩니다.

공급자 데이터셋에서 피처 집합을 선택하고, 소비자 데이터셋에서 레이블 집합을 “고가치(high value)” 플래그( label_value라고 함)와 함께 선택해요. 그런 다음 이 두 테이블을 이메일을 기준으로 내부 조인(inner join)하여 Random Forest 학습 알고리즘에 전달합니다. 마지막으로 모델 학습 단계의 출력은 추론 함수에 전달되며, 이 함수는 학습된 모델을 사용하여 소비자 데이터셋에 없는 공급자 고객 중 “고가치”일 가능성이 있는 고객을 “추론”해요. 그런 다음 그러한 개인의 **수(count)**와 모델 오차를 반환합니다.

고객이 “고가치일 가능성이 높은” 점수 기준 임계값은 템플릿에서 0.5로 수동 설정되어 있어요. 이 값은 템플릿을 클린룸에 추가할 때 쉽게 변경할 수 있습니다.

call samooha_by_snowflake_local_db.provider.add_custom_sql_template(
    $cleanroom_name,
    'prod_custom_lookalike_template',
    $$
WITH
features AS (
    SELECT
        p.hashed_email,
        array_construct(identifier({{ dimensions[0] | column_policy }}) {% for feat in dimensions[1:] %} , identifier({{ feat | column_policy }}) {% endfor %}) as features
    FROM
        identifier({{ source_table[0] }}) as p
),
labels AS (
    SELECT
        c.hashed_email,
        {{ filter_clause | sqlsafe | column_policy }} as label_value
    FROM
        identifier({{ my_table[0] }}) as c
),
trained_model AS (
    SELECT
        train_out:model::varchar as model,
        train_out:error::float as error
    FROM (
      SELECT
        cleanroom.lookalike_train(array_agg(f.features), array_agg(l.label_value)) as train_out
      FROM features f, labels l
      WHERE f.hashed_email = l.hashed_email
    )
),
inference_output AS (
    SELECT
        MOD(seq4(), 100) as batch,
        cleanroom.lookalike_score(
            array_agg(distinct t.model),
            array_agg(p.hashed_email),
            array_agg(array_construct( identifier({{ dimensions[0] | column_policy }}) {% for feat in dimensions[1:] %} , identifier({{ feat | column_policy }}) {% endfor %}) )
        ) as scores
    FROM trained_model t, identifier({{ source_table[0] }}) p
    WHERE p.hashed_email NOT IN (SELECT c.hashed_email FROM identifier({{ my_table[0] }}) c)
    GROUP BY batch
),
processed_output AS (
    SELECT value:email::string as email, value:score::float as score FROM (select scores from inference_output), lateral flatten(input => parse_json(scores))
)
SELECT p.audience_size, t.error from (SELECT count(distinct email) as audience_size FROM processed_output WHERE score > 0.5) p, trained_model t;
    $$
);

참고

위의 samoaha_by_snowflake_local_db.provider.add_custom_sql_template 프로시저 호출에 마지막 매개변수로 Differential Privacy 민감도를 추가할 수 있어요 (추가하지 않으면 기본값은 1입니다).

클린룸에서 현재 활성화된 템플릿을 보려면 다음 프로시저를 호출하세요. 분석에 Differential Privacy 보장을 활성화하도록 수정할 수 있어요. 유사한 패턴은 직접 작성하려는 모든 사용자 지정 템플릿에 통합할 수 있습니다.

call samooha_by_snowflake_local_db.provider.view_added_templates($cleanroom_name);

각 테이블에 컬럼 정책 설정하기

테이블 안에 있는 컬럼을 확인하려면 연결된 데이터를 표시하세요. 상위 10개 행을 보려면 다음 프로시저를 호출해요.

select * from samooha_provider_sample_database.lookalike_modeling.customers limit 10;

모든 테이블과 템플릿 조합에 대해 그룹화, 집계(예: SUM/AVG) 및 일반적으로 분석에 사용하려는 컬럼을 설정하세요. 이렇게 하면 동일한 테이블이 기본 템플릿에 따라 다른 컬럼 선택을 허용할 수 있어 유연성이 생겨요. 이 함수는 템플릿을 추가한 후에만 호출해야 합니다.

컬럼 정책은 **교체 전용(replace only)**이에요. 따라서 함수를 다시 호출하면 이전에 설정된 컬럼 정책이 새 정책으로 완전히 대체됩니다.

컬럼 정책은 email, HEM, RampID 등과 같은 식별 컬럼에는 사용하지 않아야 해요. 소비자가 이러한 컬럼으로 그룹화할 수 없기를 원하기 때문이에요. 프로덕션 환경에서는 시스템이 PII 컬럼을 지능적으로 추론하여 이 작업을 차단하지만, 샌드박스 환경에서는 이 기능을 사용할 수 없어요. 컬럼 정책은 Status, Age Band, Region Code, Days Active 등과 같이 소비자가 집계하고 그룹화할 수 있기를 원하는 컬럼에만 사용해야 합니다.

“column_policy” 및 “join_policy”가 소비자 분석 요청에 대한 검사를 수행하려면 모든 컬럼 이름이 SQL Jinja 템플릿에서 dimensions 또는 measure_columns로 참조되어야 해요. 사용자 지정 SQL Jinja 템플릿에서 검사받고 싶은 컬럼을 참조할 때 이러한 태그를 사용해야 합니다.

call samooha_by_snowflake_local_db.provider.set_column_policy($cleanroom_name, [
    'prod_custom_lookalike_template:samooha_provider_sample_database.lookalike_modeling.customers:status',
    'prod_custom_lookalike_template:samooha_provider_sample_database.lookalike_modeling.customers:age',
    'prod_custom_lookalike_template:samooha_provider_sample_database.lookalike_modeling.customers:region_code',
    'prod_custom_lookalike_template:samooha_provider_sample_database.lookalike_modeling.customers:days_active',
    'prod_custom_lookalike_template:samooha_provider_sample_database.lookalike_modeling.customers:income_bracket',
    'prod_custom_lookalike_template:samooha_provider_sample_database.lookalike_modeling.customers:household_size',
    'prod_custom_lookalike_template:samooha_provider_sample_database.lookalike_modeling.customers:gender'
]);

클린룸에 추가된 컬럼 정책을 보려면 다음 프로시저를 호출하세요.

call samooha_by_snowflake_local_db.provider.view_column_policy($cleanroom_name);

소비자와 공유하기

마지막으로 아래와 같이 데이터 소비자의 Snowflake 계정 로케이터와 계정 이름을 추가하여 클린룸에 데이터 소비자를 추가하세요. Snowflake 계정 이름은 <ORGANIZATION>.<ACCOUNT_NAME> 형식이어야 합니다.

참고

다음 프로시저를 호출하려면 먼저 provider.set_default_release_directive를 사용하여 릴리스 지시문을 설정했는지 확인하세요. 최신 사용 가능한 버전과 패치는 다음을 사용하여 확인할 수 있어요:

show versions in application package samooha_cleanroom_Machine_Learning_Demo_clean_room;
call samooha_by_snowflake_local_db.provider.add_consumers($cleanroom_name, '<CONSUMER_ACCOUNT_LOCATOR>', '<CONSUMER_ACCOUNT_NAME>');
call samooha_By_snowflake_local_db.provider.create_or_update_cleanroom_listing($cleanroom_name);


여러 소비자 계정 로케이터를 provider.add_consumers 함수에 쉼표로 구분된 문자열로 전달하거나, provider.add_consumers를 별도로 호출하여 전달할 수 있어요.

이 clean room에 추가된 소비자를 확인하려면 다음 프로시저를 호출해요.

call samooha_by_snowflake_local_db.provider.view_consumers($cleanroom_name);

최근에 생성된 clean room을 확인하려면 다음 프로시저를 사용해요.

call samooha_by_snowflake_local_db.provider.view_cleanrooms();

생성한 clean room에 대한 더 많은 인사이트를 얻으려면 다음 프로시저를 사용해요.

call samooha_by_snowflake_local_db.provider.describe_cleanroom($cleanroom_name);

생성된 clean room은 삭제할 수도 있어요. 다음 명령은 clean room을 완전히 삭제하므로, 이전에 clean room에 액세스 권한이 있던 소비자는 더 이상 사용할 수 없게 돼요. 나중에 같은 이름의 clean room이 필요하다면 위의 흐름을 사용하여 다시 초기화해야 해요.

call samooha_by_snowflake_local_db.provider.drop_cleanroom($cleanroom_name);

참고

공급자 흐름이 이제 끝났어요. 소비자 흐름을 계속하려면 소비자 계정으로 전환하세요.

소비자

참고

다음 명령은 소비자 계정의 Snowflake 워크시트에서 실행해야 해요.

환경 설정

Snowflake Data Clean Room에서 개발자 API를 사용하기 전에 다음 명령을 실행하여 Snowflake 환경을 설정하세요. SAMOOHA_APP_ROLE 역할이 없다면 계정 관리자에게 문의하세요.

use role SAMOOHA_APP_ROLE;
use warehouse app_wh;

clean room 설치

clean room 공유가 설치되면 아래 명령을 사용하여 사용 가능한 clean room 목록을 확인할 수 있어요.

call samooha_by_snowflake_local_db.consumer.view_cleanrooms();

공급자가 공유한 clean room에 이름을 지정하세요.

set cleanroom_name = 'Machine Learning Demo Clean room';

다음 명령은 연결된 공급자와 선택한 clean room을 사용하여 소비자 계정에 clean room을 설치해요.

이 프로시저는 실행하는 데 시간이 조금 더 걸릴 수 있으며, 일반적으로 약 30초 정도 소요돼요.

call samooha_by_snowflake_local_db.consumer.install_cleanroom($cleanroom_name, '<PROVIDER_ACCOUNT_LOCATOR>');

clean room이 설치된 후, 사용할 수 있게 활성화되기 전에 공급자가 자신의 쪽에서 clean room 설정을 완료해야 해요. 아래 함수를 사용하면 clean room의 상태를 확인할 수 있어요. 활성화되면 아래의 Run Analysis 명령을 실행할 수 있어요. clean room이 활성화되는 데는 보통 약 1분 정도 걸려요.

call samooha_by_snowflake_local_db.consumer.is_enabled($cleanroom_name);

데이터셋 연결

이제 공급자의 데이터와 안전한 계산을 수행하기 위해 일부 데이터셋을 clean room에 연결할 수 있어요.

call samooha_by_snowflake_local_db.consumer.link_datasets($cleanroom_name, ['samooha_consumer_sample_database.lookalike_modeling.customers']);

참고

이 단계가 테이블이 존재하는데도 작동하지 않는다면, SAMOOHA_APP_ROLE 역할에 아직 해당 테이블에 대한 액세스 권한이 부여되지 않았을 가능성이 높아요. 그렇다면 ACCOUNTADMIN 역할로 전환하여 데이터베이스에서 아래 프로시저를 호출한 다음, 나머지 흐름을 위해 다시 전환하세요:

use role accountadmin;
call samooha_by_snowflake_local_db.consumer.register_db('<DATABASE_NAME>');
use role SAMOOHA_APP_ROLE;

분석을 실행하려면 소비자 테이블을 전달해야 해요. clean room에 추가한 데이터셋을 확인하려면 다음 프로시저를 호출하세요.

call samooha_by_snowflake_local_db.consumer.view_consumer_datasets($cleanroom_name);

분석 실행

이제 clean room이 설치되었으므로, “run_analysis” 명령을 사용하여 공급자가 clean room에 추가한 분석 템플릿을 실행할 수 있어요. 각 필드가 어떻게 결정되는지는 아래 섹션에서 확인할 수 있어요.

“고가치” 사용자는 아래 쿼리의 filter_clause로 식별돼요. _c.SALES_DLR_가 사용자당 판매 금액을 나타낸다면, 유효한 필터는 c.HIGH_VALUE > 4000처럼 보일 수 있어요.

참고

분석을 실행하기 전에 웨어하우스 크기를 변경하거나, 테이블이 큰 경우 더 큰 새 웨어하우스 크기를 사용할 수 있어요.

call samooha_by_snowflake_local_db.consumer.run_analysis(
    $cleanroom_name,                     -- cleanroom
    'prod_custom_lookalike_template',    -- template name

    ['samooha_consumer_sample_database.lookalike_modeling.customers'],                -- consumer tables

    ['samooha_provider_sample_database.lookalike_modeling.customers'],                -- provider tables

    object_construct(                    -- Rest of the custom arguments needed for the template
        'dimensions', ['p.STATUS', 'p.AGE', 'p.REGION_CODE', 'p.DAYS_ACTIVE', 'p.INCOME_BRACKET'], -- Features used in training

        'filter_clause', 'c.SALES_DLR > 2000' -- Consumer flag for which customers are considered high value
    )
);

run_analysis 입력값 결정 방법

분석을 실행하려면 run_analysis 함수에 몇 가지 매개변수를 전달해야 해요. 이 섹션에서는 어떤 매개변수를 전달해야 하는지 결정하는 방법을 보여드릴게요.

템플릿 이름

먼저 다음 프로시저를 호출하여 지원되는 분석 템플릿을 확인할 수 있어요.

call samooha_by_snowflake_local_db.consumer.view_added_templates($cleanroom_name);

템플릿으로 분석을 실행하기 전에 지정해야 할 인수와 기대되는 유형을 알아야 해요. 사용자 지정 템플릿의 경우 다음을 실행할 수 있어요.

call samooha_by_snowflake_local_db.consumer.view_template_definition($cleanroom_name, 'prod_custom_lookalike_template');

여기에는 다양한 SQL Jinja 매개변수가 많이 포함되어 있을 수도 있어요. 다음 기능은 SQL Jinja 템플릿을 구문 분석하여 run_analysis에 지정해야 하는 인수를 목록으로 추출해요.

call samooha_by_snowflake_local_db.consumer.get_arguments_from_template($cleanroom_name, 'prod_custom_lookalike_template');

데이터셋 이름

공급자가 clean room에 추가한 데이터셋 이름을 확인하려면 다음 프로시저를 호출하세요. clean room의 보안 속성으로 인해 공급자가 clean room에 추가한 데이터셋에 포함된 데이터는 볼 수 없어요.

call samooha_by_snowflake_local_db.consumer.view_provider_datasets($cleanroom_name);

다음 호출을 사용하여 clean room에 연결한 테이블도 확인할 수 있어요:

call samooha_by_snowflake_local_db.consumer.view_consumer_datasets($cleanroom_name);

차원 및 측정값 열

분석을 실행하는 동안 특정 열을 기준으로 필터링, 그룹화, 집계하고 싶을 수 있어요. 공급자가 clean room에 추가한 열 정책을 확인하려면 다음 프로시저를 호출하세요.

call samooha_by_snowflake_local_db.consumer.view_provider_column_policy($cleanroom_name);

일반적인 오류

분석 실행 결과 Not approved: unauthorized columns used 오류가 발생한다면, 공급자가 설정한 조인 정책과 열 정책을 다시 확인하는 것이 좋아요.

call samooha_by_snowflake_local_db.consumer.view_provider_join_policy($cleanroom_name);
call samooha_by_snowflake_local_db.consumer.view_provider_column_policy($cleanroom_name);

또한 개인 정보 보호 예산을 모두 소진하여 더 이상 쿼리를 실행하지 못할 수도 있어요. 남은 개인 정보 보호 예산은 아래 명령으로 확인할 수 있어요. 이 예산은 매일 초기화되며, clean room 공급자가 원할 경우 직접 초기화할 수도 있어요.

call samooha_by_snowflake_local_db.consumer.view_remaining_privacy_budget($cleanroom_name);

다음 API를 사용하여 clean room에 Differential Privacy가 활성화되어 있는지 확인할 수 있어요:

call samooha_by_snowflake_local_db.consumer.is_dp_enabled($cleanroom_name);

더 알아보기 (Learn more)