10월 20일 #CloudGuruChallenge

TLDR


acloud.guru은 기계학습 #CloudGuruChallenge을 발표하여 추천 엔진을 구축했다.나는 이 임무를 완수하고 서버가 없는 PHP 사이트를 구축했다. 이 사이트는 ML모델에서 나온 데이터로 영화 추천을 제공한다.
네가 직접 봐라!http://wheelerrecommends.com/

소개하다.


2020년 10월 19일, acloud.guru은 또 #CloudGuruChallenge을 발표했다.이번 도전은 AWS Sagemaker으로 넷플릭스 스타일의 추천 엔진을 구축하는 것이다.
처음에는 영화 기반 엔진이 되고 싶지 않았지만 다른 유형의 데이터를 위해 좋은 데이터 집합을 찾기가 정말 어려웠다.나의 첫 번째 생각은 어린이 도서 추천 엔진이다. 나는 그것으로 내 아들을 위해 책을 찾을 수 있다.비록, 나는 내가 쓸 수 있는 어떤 것도 찾지 못했다.
Kesha Williams는 IMDB Datasets을 권장하며 즉각적인 시작을 쉽게 할 수 있습니다.

프로세스


AWS 콘솔에 뛰어들어 SageMaker 노트북 인스턴스를 시작했습니다.나는 곧 내가 기계 학습에 대한 이해가 얼마나 적은지 깨달았다.이것은 절대로 공부할 좋은 기회다.

첫걸음S3에 IMDB 데이터 업로드


IMDB 데이터 세트를 사용하기 전에 액세스 가능한 저장소에 넣어야 합니다.제가 선택한 서비스는 AWS S3입니다.
나는 Jupyter 노트북과 Python과 셸 명령을 결합하여 이 점을 실현했다.나는 이전에 파이톤에서 boto3을 사용한 적이 있고, 이전에도 AWS CLI를 사용한 적이 있다.하지만 저는 Jupyter에 대해 풋내기입니다. 둘을 결합시킬 수 있는지 보고 싶습니다.어쩌면 이것은 나쁜 습관일지도 몰라...나는 인터넷에서 어떤 건의도 찾을 수 없다.
def s3_upload(filename):

    bucket_name = "wheeler-cloud-guru-challenges"
    object_name = f"1020/IMDB/{filename}"

    !aws s3 cp "{filename}" "s3://{bucket_name}/{object_name}"
IMDB-To-S3.ipynb
주의: 이 함수의 !은 Jupyter에게 bash를 사용하라고 알려 줍니다

두 번째 단계.특징 공정


나는 이전에 특징 공정을 배운 적이 있기 때문에 열 인코딩과 최소/최대 축소 등의 개념을 잘 알고 있다.그럼에도 불구하고 나는 지금까지 실천에서 그것들을 사용한 적이 없다.내가 직면한 가장 큰 장애는 나의 데이터를 저장할 수 없다는 것이다.데이터를 불러올 수 없다면, 데이터를 어떻게 만드는지 이해할 수 없기 때문에, 이것은 사람을 매우 낙담하게 한다.
그 예에서 나는 SQL이 유행하는 기능 공학 도구라는 것을 회상하고 나의 장점을 발휘하기로 결정했다.나는 AWS Athena을 사용하여 표준 SQL 조회로 S3에 저장된 데이터를 사용한다.
나는 "지금 우리는 불로 밥을 하고 있다!"라고 생각한다.🔥. 저는 SQL에 익숙하기 때문에 짧은 시간 안에 데이터 문제를 해결할 수 있다는 것도 이상할 게 없습니다.
select 
    res.*,
    contains(res.genres, 'Action') isaction,
    contains(res.genres, 'Adventure') isadventure,
    contains(res.genres, 'Comedy') iscomedy,
    contains(res.genres, 'Crime') iscrime,
    contains(res.genres, 'Documentary') isdocumentary,
    contains(res.genres, 'Drama') isdrama,
    contains(res.genres, 'Horror') ishorror,
    contains(res.genres, 'Mystery') ismystery,
    contains(res.genres, 'Romance') isromance,
    contains(res.genres, 'Thriller') isthriller
from (
select distinct 
    tbasics.tconst id,
    tbasics.primarytitle title,
    tbasics.startyear year,
    split(tbasics.genres, ',') genres,
    tratings.averagerating rating,
    tratings.numvotes votes
from title_basics tbasics
join title_akas takas on tbasics.tconst = takas.titleid
join title_ratings tratings on tbasics.tconst = tratings.tconst
where tbasics.startyear <= year(now()) 
and tbasics.titleType = 'movie' 
and tbasics.isadult = 0
and takas.language = 'en'
and takas.region = 'US'
) res;
data-exploration.sql
솔직히 이것은 내가 아테나에 대한 첫 번째 용례로 완벽하게 실현되었다.나의 아테나 계산서는 사실상 0.02달러다.비록 그것이 몇 시간의 시간을 절약했지만, 더욱 가치가 있다.

세 번째.데이터 탐색


지금 나는 내가 아테나에서 준비한 데이터를 형상화해야 한다.Jupyter 노트북에서 선택한 도구는 Seaborn입니다.
year_df = imdb_df.groupby('year')['id'].nunique()
seaborn.set(style='darkgrid')
seaborn.lineplot(data=year_df)

나는 데이터를 연도에 따라 도표로 그렸다. 이렇게 하면 나는 요 몇 년 동안의 데이터 분포가 고르는지 볼 수 있다.나는 최근 몇 년 동안 내가 더 많은 데이터를 가지고 있다는 것을 깨달았다. 이것은 일리가 있다. 왜냐하면 전년도에 비해 매년 통상적으로 더 많은 영화를 제작하기 때문이다.
imdb_df['rating'] = imdb_df['rating'].apply(lambda x: int(round(x)))
rating_df = imdb_df.groupby('rating')['id'].nunique()
seaborn.set(style='whitegrid')
seaborn.lineplot(data=rating_df)

다음에 나는 평점을 통해 데이터를 도표로 그렸다.나는 나의 가설이 정확한지 보고 싶다. 최대 수량의 기록이 중간에 떨어질 것이다.내가 맞았어!이 가설은 대부분의 영화가 일반 영화라는 사실에 기초를 두고 있다.

네 번째 단계.K-균일치 모델링


나는 내가 모델 업계에 뛰어들 준비가 되어 있다고 생각했다.나는 Amazon's Sagemaker Examples에게서 약간의 도움을 받았다.
💥 번영!💥
나는 아직 준비가 안 됐어...나는 약간의 재미있는 잘못을 저질렀다.나는 KMeans 함수가 모든 데이터가 float32이라는 것을 깨닫는 데 시간이 좀 걸렸다.이 모든 것?그래.

네 번째 단계.피쳐 엔지니어링(2차)


처음에 나는 모든 비숫자열을 삭제했지만, 나중에 모델은 그것들을 사용할 수 없었다.나의 첫 번째 예측은 정말 엉망이었다.
궁금하시면 Attempt 1.
나는 여전히 모델이 이 필드들을 사용하기를 원하기 때문에, 나는 그것들을 숫자로 바꾸어야 한다.나는 형식에 따라 데이터를 비추기 위해 사용자 정의 함수를 짰다.
나는 우선 정적 지도에 따라 이 유형들을 축소했다.
e,g.행동=1,모험=2,등등.
def map_genre_to_numeric(genres):

    genres_array = genres.replace('[', '').replace(']', '').split(', ')
    return ''.join([str(genre_map[g]) for g in genres_array])

train_df['genres'] = train_df['genres'].map(lambda g: map_genre_to_numeric(g))
이어서 시청률을 조정했는데 그게 제일 까다로운 부분이에요.인류에게 있어서 한 번의 평론이 있는 4성급 제품은 백만 번의 평론이 있는 4성급 제품과 다르다.나는 어떻게 모델에게 이 점을 전달해야 합니까?
나는 수표를 도입하여 표수에 따라 실제 평점의 백분율을 얻기로 결정했다.이 영화가 1000표가 넘을 때만 실제 시청률을 유지할 수 있다.
def map_rating_to_numeric(rating, votes):

    result = 0
    if votes is None:
        result = 0
    elif votes < 10:
        result = rating * 0.1
    elif votes < 100:
        result = rating * 0.3
    elif votes < 500:
        result = rating * 0.5
    elif votes < 1000:
        result = rating * 0.7
    elif votes >= 1000: 
        result = rating
    else:
        print(f"Unexpected # of Votes: {votes}")

    return result
다음에, 나는 내장된 ord() 함수를 사용하여 제목 값을 그들의 유니버설 대응 항목에 비추었다.처음에 나는 긴 제목이 무한히 재생될 때까지 전체 제목을 그렸다.
이렇게 하는 목적은 영화 시리즈를 한데 묶는 것이다.e, g. 사지 1과 사지 2.나는 같은 결과를 얻기 위해 경계를 넘지 않는 상황에서 제목의 서브집합을 얻을 수 있다고 결정했다.나는 제목의 하위 문자열을 아홉 글자로 제한했다.이유가 뭡니까?9는 내가 가장 좋아하는 숫자다.
def map_tilte_to_numeric(title):
    return ''.join([str(ord(c)) for c in title[:9]])
마지막으로, 나는 이 열들이 일치하는지 확인하기 위해 최소/최대 크기를 조정했다.
scaler = MinMaxScaler()
scaler_columns = ['genres', 'rating', 'title', 'year']
train_df[scaler_columns] = pd.DataFrame(scaler.fit_transform(train_df[scaler_columns]))

다섯 번째.K-균일치 모델링(2라운드)


이제 자신 있어요!훈련해야겠다.나는 하나의 실례와 9개의 집단으로 K-Means 모델을 초기화했다.
sage_session = sagemaker.Session()
sage_outputs = f"s3://{sage_session.default_bucket()}/imdb/"

kmeans = KMeans(role=sagemaker.get_execution_role(),
                instance_count=1,
                instance_type='ml.c4.xlarge',
                output_path=sage_outputs,              
                k=9)
그리고 나는 모형을 훈련하고 배치했다.
train_data = train_df.values
kmeans.fit(kmeans.record_set(train_data))
model = kmeans.deploy(initial_instance_count=1,instance_type='ml.m4.xlarge')
일단 내가 모델이 생기면 나는 모델을 통해 훈련 데이터를 보내서 예측할 것이다.이 아이는 너무 빨리 뛴다!⚡
predictions = model.predict(train_data)

result_df['cluster'] = np.nan
result_df['distance'] = np.nan

for i, p in enumerate(predictions):
    result_df.at[i, 'cluster'] = p.label['closest_cluster'].float32_tensor.values[0]
    result_df.at[i, 'distance'] = p.label['distance_to_cluster'].float32_tensor.values[0]
지금, 다음 부분은 정말 중요합니다!시간당 청구를 중지하려면 Sagemaker 끝점을 삭제합니다.
sagemaker.Session().delete_endpoint(model.endpoint_name)
AWS Budgets은 이 단계를 잊었음을 알려줍니다.나처럼 너의 자원을 정리하지 마라.
거기서 나는 결과를 CSV로 저장했다.우리 망했어!맞습니까?기술적으로는 그렇지만 나는 멈출 수가 없다.
최종 결과:Attempt 2.

서버 PHP 웹 사이트 없음


나는 간단한 사이트를 만들어서 ML모델의 발견을 이용하고 싶다.웅대한 포부를 가지고 저는 최근 Pluralsight의 도움을 받아 PHP를 배웠고 이 기술을 테스트하는 것을 선택했습니다.
아, 잠깐만, 난 하녀야. 이건 안 돼...아니면?나는 발굴을 해서 Bref--진정한 하늘이 내려준 물건을 찾았다.이 소프트웨어는 서버 웹 사이트가 없는 AWS Lambda 엔드포인트 뒤의 AWS API Gateway 함수에서 PHP 어플리케이션을 실행할 수 있도록 합니다.🤯
자신에게 말했다: "내가 꿈을 꾸고 있습니까?"
사이트 구조
  • 트래픽은 CloudFront을 통해 Route53으로 라우팅
  • 정적 컨텐츠는 S3
  • 에서 가져옴
  • 동적 콘텐츠는 API 게이트웨이
  • 에서 제공
  • API 게이트웨이와 Lambda가 상호 작용하여 콘텐츠 생성
  • 이거 정말 효과가 있어요!정말 놀랐어요.API 게이트웨이가 클라이언트와 어떻게 상호 작용할지 약간 혼란스럽습니다.
    현재의 디자인은 실제로는 이전보다 더욱 간단해졌다.Bref 설명서에서 알 수 있듯이 6월 이후 Lambda Layers을 사용하면 가능합니다.이달 미국 용접학회는 연례 회의 Container Image Support for Lambda에서 re:Invent을 발표했다.
    지금 나는 "이것은 운명적으로 정해진 것이다."라고 생각하고 있다.
    자료 출처:
    https://aws.amazon.com/blogs/compute/introducing-the-new-serverless-lamp-stack/
    처음에 저는 클라우드 프론트 발행판에서 Geo Restrictions을 실현하여 미국으로 가는 데이터를 제한했습니다.
    내가 이렇게 하는 데는 세 가지 주요 원인이 있다.
  • 비용 절감
  • 미국 국외로부터의 공격 방지
  • 지리적 제약 이해
  • GeoPeeker가 블랙리스트에 올랐어요.

    이 기능은 잘 작동하여 설치하기 쉽다.이외에, 내 외국 친구가 나와 그들의 관점을 공유하고 싶을 때, 나는 이 기능을 지웠다.하지만 괜찮아, 내가 어떻게 하는지 배웠으니까.
    전반적으로 이번 도전은 나를 매우 즐겁게 했다.이것은 나로 하여금 그들이 다음에 우리에게 어떤 도전을 가져올지 간절히 보고 싶다.당신의 사랑에 감사 드립니다.굴루는 이번 도전의 마지막 기한을 연장하기로 결정했다. 그렇지 않으면 나는 이 바쁜 휴가를 마칠 시간이 없었다.
    이것은 사이트 링크, 원본 코드, 그리고 나의 링크드 인 페이지입니다.제발, 제발, 제발, 네 생각을 알려줘.링크드 인에 연락할 수 있을 정도로 당신의 피드백을 기꺼이 듣겠습니다.
    사이트
    https://wheelerrecommends.com/
    github
    https://github.com/wheelers-websites/CloudGuruChallenge_1020
    영을 받다


    즐거운 구름!

    좋은 웹페이지 즐겨찾기