/PEAMO

🌸 빅데이터 기반 ν–₯수 μΆ”μ²œ μ„œλΉ„μŠ€

Primary LanguageJavaScript

PE' AMO [ λ‹Ήμ‹ μ˜ μ·¨ν–₯을 μ°Ύμ•„λ“œλ¦½λ‹ˆλ‹€ ]

Perfume(ν–₯수) κ³Ό TI Amo(μ‚¬λž‘ν•΄) 의 κ²°ν•©

주제 : 빅데이터 기반 ν–₯수 μΆ”μ²œ μ‚¬μ΄νŠΈ

개발 κΈ°κ°„ : 2021.08.30 ~ 2021.10.08 [7μ£Ό]

λͺ©μ°¨

0. νŒ€μ†Œκ°œ

1. μ„œλΉ„μŠ€ μ†Œκ°œ

2. κΈ°μˆ μŠ€νƒ

3. μΆ”μ²œ μ•Œκ³ λ¦¬μ¦˜

4. μ•„ν‚€ν…μ²˜ 및 ERD

5. μ‚¬μ΄νŠΈ λ ˆμ΄μ΄μ›ƒ 및 λ””μžμΈ

0. νŒ€μ†Œκ°œ

νŒ€μ›λ“€μ˜ μž₯점이 ν™•μ‹€ν–ˆκ³  κ·Έ μž₯점듀이 잘 μ–΄μš°λŸ¬μ§„ νŒ€μ΄μ—ˆμŠ΅λ‹ˆλ‹€. 열정이 λ„˜μΉ˜λŠ” ꢌ였우 νŒ€μ›, μ–΄λ €μš΄ μ„ νƒμ˜ κ°ˆλ¦ΌκΈΈμ—μ„œ 항상 μ˜³μ€ 선택을 ν•˜λ„λ‘ λ¦¬λ“œν•˜λŠ” μ„œμ˜ˆλ¦¬ νŒ€μ›, λ‹€λ₯Έ νŒ€μ›λ“€μ˜ μ˜κ²¬μ„ 잘 μ •λ¦¬ν•΄μ£ΌλŠ” μ‹ μ§€μˆ˜ νŒ€μ›, κΉ”λ”ν•˜κ²Œ μ½”λ“œλ₯Ό λ¦¬νŒ©ν† λ§ ν•΄μ£ΌλŠ” 솑상민 νŒ€μ›, κΌΌκΌΌν•˜κ²Œ μƒˆλ‘œμš΄ κΈ°μˆ μ„ μ •λ¦¬ν•΄μ£ΌλŠ” μœ€μ§€μ˜ νŒ€μ› 그리고 ν”„λ‘ νŠΈμ™€ λ°±μ—”λ“œλ₯Ό 가리지 μ•Šμ•„ μ†Œν†΅μ˜ 창ꡬ가 λ˜μ–΄μ€€ μž₯ν˜„μ›… νŒ€μ›κΉŒμ§€ μ–΄λŠ ν•œ λͺ… μ„œλ‘œμ˜ 뢀쑱함을 νƒ“ν•˜μ§€ μ•Šκ³  κ·Έ 뢀쑱함을 μ±„μ›Œλ‚˜κ°ˆ 수 μžˆλ„λ‘ 완벽에 κ°€κΉŒμš΄ ν˜‘λ ₯을 ν–ˆλ˜ νŒ€μ΄μ—ˆμŠ΅λ‹ˆλ‹€.

members

  • ꢌ였우(FE) : 빅데이터 μΆ”μ²œ μ•Œκ³ λ¦¬μ¦˜ κ΅¬ν˜„ / teller νŽ˜μ΄μ§€ κ΅¬ν˜„ / μ‚¬μ΄νŠΈ 배포 및 CI/CD μž‘μ—…
  • μ„œμ˜ˆλ¦¬(FE) : main, search, about νŽ˜μ΄μ§€ κ΅¬ν˜„ / UCC μ œμž‘ / 쀑간 λ°œν‘œ
  • 솑상민(FE) : social login/logout, detail, error, loading νŽ˜μ΄μ§€ κ΅¬ν˜„ / Reduxλ₯Ό μ΄μš©ν•œ μƒνƒœ 관리
  • μ‹ μ§€μˆ˜(BE) : ν–₯수 리슀트, ν–₯수 검색, ν–₯수 μ„ΈλΆ€ 정보, μ΄λ‹¬μ˜ ν–₯수 κ΅¬ν˜„ / μ΅œμ’… λ°œν‘œ
  • μœ€μ§€μ˜(BE) : social login/logout, λ§ˆμ΄νŽ˜μ΄μ§€, ν–₯수 μ’‹μ•„μš”, μ‚¬μš©μž μ·¨ν–₯ 탐색 κ΅¬ν˜„ / 데이터 크둀링 및 DB 관리
  • μž₯ν˜„μ›…(BE) : 빅데이터 μΆ”μ²œ μ•Œκ³ λ¦¬μ¦˜ κ΅¬ν˜„ / μ‚¬μš©μž μ·¨ν–₯ 탐색 κ΅¬ν˜„ / 데이터 크둀링 및 DB 관리 / AWS RDS
  • 곡톡 μž‘μ—… : ν”„λ‘œμ νŠΈ 기획 및 자료 정리 / λ°œν‘œ 자료 μ€€λΉ„ / 쀑간 λ°œν‘œ

1. μ„œλΉ„μŠ€ μ†Œκ°œ

빅데이터λ₯Ό 기반으둜 ν–₯수λ₯Ό μΆ”μ²œν•΄μ£ΌλŠ” μ‚¬μ΄νŠΈ

1.1 기획 배경

μ½”λ‘œλ‚˜λ‘œ μΈν•œ μ •λΆ€ 방역지침에 따라 λ°±ν™”μ μ—μ„œλŠ” μ‹œμ‹, μ‹œμŒ, μ‹œν–₯ 등을 κΈˆμ§€ν–ˆμœΌλ©°, 이에 따라 ν™”μž₯ν’ˆ λ§€μΆœμ€ κ°μ†Œν–ˆμ§€λ§Œ ν–₯수 λ§€μΆœμ€ 였히렀 λŠ˜μ–΄λ‚¬λ‹€. μ—…κ³„μ—μ„œλŠ” ν™”μž₯ λŒ€μ‹  μžμ‹ μ„ ν‘œν˜„ν•  수 μžˆλŠ” μˆ˜λ‹¨μœΌλ‘œ ν–₯μˆ˜κ°€ 각광받고 μžˆλŠ” κ²ƒμœΌλ‘œ 보고 μžˆλ‹€. μ΄λŸ¬ν•œ 흐름에 발 λ§žμΆ”μ–΄ μ‚¬μš©μžμ—κ²Œ μ–΄μšΈλ¦¬λŠ” ν–₯수λ₯Ό μΆ”μ²œν•΄μ£ΌλŠ” μ‚¬μ΄νŠΈμ˜ ν•„μš”μ„±μ„ 느끼고 PE' AMO ν”„λ‘œμ νŠΈλ₯Ό κΈ°νšν•˜κ²Œ λ˜μ—ˆλ‹€.

1.2 μ£Όμš” νƒ€κ²Ÿ

1.2.1 ν–₯μˆ˜μ— λŒ€ν•΄ 잘 λͺ¨λ₯΄λŠ” μ‚¬νšŒ μ΄ˆλ…„μƒ

  • ν–₯수λ₯Ό 처음 κ΅¬λ§€ν•˜λ €λŠ” μ‚¬νšŒ μ΄ˆλ…„μƒμ—κ²ŒλŠ” λ§Žμ€ μ§„μž… μž₯벽이 μžˆλ‹€. 우리 μ‚¬μ΄νŠΈμ—μ„œλŠ” 이런 μ§„μž… μž₯벽을 ν—ˆλ¬Όκ³  κ°„λ‹¨ν•œ μ§ˆλ¬Έμ„ 톡해 μ‚¬μš©μžμ˜ μ„ ν˜Έλ„λ₯Ό νŒŒμ•…ν•˜κ³  그에 λ§žλŠ” ν–₯수λ₯Ό μΆ”μ²œν•΄μ€€λ‹€.

1.2.2 본인이 μ‚¬μš©ν–ˆλ˜ ν–₯μˆ˜μ™€ λΉ„μŠ·ν•œ ν–₯을 μ°ΎλŠ” ꡬ맀자

  • ν–₯μˆ˜λŠ” 같은 ν–₯을 λ‚Έλ‹€κ³  ν•˜λ”λΌλ„ ν¬ν•¨λœ λ…ΈνŠΈλ“€μ— 따라 μ „ν˜€ λ‹€λ₯Έ ν–₯κΈ°κ°€ λ‚œλ‹€. 이런 문제둜 고민을 ν•˜λŠ” κ΅¬λ§€μžλ“€μ—κ²Œ μžμ‹ μ΄ μ‚¬μš©ν–ˆλ˜ ν–₯수λ₯Ό κ²€μƒ‰ν•˜λ©΄ κ·Έ ν–₯μˆ˜μ™€ κ°€μž₯ λΉ„μŠ·ν•œ ν–₯수λ₯Ό μ°Ύμ•„μ„œ μΆ”μ²œν•΄μ€€λ‹€.

1.3 μ£Όμš” κΈ°λŠ₯

1.3.1 μ·¨'ν–₯' μ°ΎκΈ°

image-20211007193038529

  • ν–₯수λ₯Ό 처음 μ ‘ν•˜λŠ” μ‚¬μš©μžλ“€ μœ„ν•œ ν–₯수 μΆ”μ²œ κΈ°λŠ₯으둜 총 3κ°€μ§€μ˜ ν–₯수λ₯Ό μΆ”μ²œν•˜μ—¬ μ€€λ‹€.
  • 6개의 κ°„λ‹¨ν•œ μ§ˆλ¬Έμ„ 톡해 ν•„ν„°λ§λœ ν–₯μˆ˜λ“€ 쀑 'μ’‹μ•„μš”' μˆ˜κ°€ κ°€μž₯ 높은 ν–₯수 ν•˜λ‚˜λ₯Ό 뽑아낸 ν›„, 이 ν–₯μˆ˜μ™€ κ°€μž₯ μœ μ‚¬λ„κ°€ 높은 ν–₯수 2개λ₯Ό CBF(Content Based Filtering) μΆ”μ²œ μ•Œκ³ λ¦¬μ¦˜μ„ μ΄μš©ν•˜μ—¬ μΆ”μΆœν•œλ‹€. μ΄λ ‡κ²Œ μ„ νƒλœ 3개의 ν–₯수λ₯Ό μ‚¬μš©μžμ—κ²Œ μ–΄μšΈλ¦¬λŠ” ν–₯수둜 μΆ”μ²œν•˜μ—¬ μ€€λ‹€.

1.3.2 ν–₯수 검색

image-20211007105344464

image-20211007193200636

  • 이미 μ‚¬μš©ν•˜κ³  μžˆλŠ” ν–₯μˆ˜κ°€ 있고 κΈ°μ‘΄ μ‚¬μš©ν•œ ν–₯μˆ˜μ™€ μœ μ‚¬ν•œ ν–₯수λ₯Ό μ°Ύκ³  싢은 μ‚¬μš©μžλ₯Ό μœ„ν•œ κΈ°λŠ₯이닀.
  • μ•½ 40,000 개의 ν–₯수λ₯Ό 검색 및 상세 정보λ₯Ό 확인할 수 μžˆλ‹€.
  • ν–₯수 μ΄λ¦„μœΌλ‘œ 검색을 ν•˜λ©΄ ν•΄λ‹Ή ν–₯수λ₯Ό 찾을 수 있고, 이미지λ₯Ό 클릭 μ‹œ ν•΄λ‹Ή ν–₯수의 상세 λͺ¨λ‹¬ 창이 뜨게 λœλ‹€. 이 λͺ¨λ‹¬ μ°½μ—μ„œ ν–₯수의 상세 정보(note 정보, 성별 λ“±)와 ν•¨κ»˜ CBF(Content Based Filtering) μΆ”μ²œ μ•Œκ³ λ¦¬μ¦˜μ„ μ΄μš©ν•˜μ—¬ 이 ν–₯μˆ˜μ™€ μœ μ‚¬λ„κ°€ κ°€μž₯ 높은 2개의 ν–₯수λ₯Ό 보여쀀닀.

2. κΈ°μˆ μŠ€νƒ

2.1 λ°±μ—”λ“œ

  • Spring Boot
  • My SQL
  • Amazon RDS

2.2 ν”„λ‘ νŠΈμ—”λ“œ

  • React.js
  • Redux
  • Material UI

2.3 데이터 μˆ˜μ§‘ 및 처리

  • Pandas
  • Numpy
  • Scikit-learn

2.4 배포

  • AWS EC2
  • Jenkins
  • Docker

2.5 ν˜‘μ—… Tool

  • Git

  • Notion

  • Jira

3. μΆ”μ²œ μ•Œκ³ λ¦¬μ¦˜

μΆ”μ²œ μ•Œκ³ λ¦¬μ¦˜μ˜ λŒ€ν‘œμ μΈ 두 가지 방식인 CBF(Content Based Filtering) 방식과 CF(Collaborative Filtering) 방식 쀑 CBF 방식을 μ‚¬μš©

3.1 데이터 가곡

3.1.1 ν–₯수 데이터

[
    {
        'id': ν–₯수 id(int),
        'imgurl': ν–₯수 imgurl(string),
        'brand': λΈŒλžœλ“œ id(id),
        'name': ν–₯수 이름(string),
        'gender': ν–₯수 νƒ€κ²Ÿ 성별(int),
        'top_notes': [note id](int list),
		'middle_notes': [note id](int list),
		'base_notes': [note id](int list),
		'categories': [categort id](int, list)
    },
	...
]

3.1.2 데이터 가곡

# row : ν–₯수 id / column : ν–₯수 λ…ΈνŠΈ id 인 DataFrame 생성
df = pd.DataFrame(columns=note_nums, index=perfume_ids)

# 각 ν–₯μˆ˜κ°€ 가지고 μžˆλŠ” note 듀은 1둜 ν‘œμ‹œ
for perfume in perfumes:
    id, top_notes, middle_notes, base_notes = perfume['id'], perfume[
        'top_notes'], perfume['middle_notes'], perfume['base_notes']

    # λ…ΈνŠΈκ°€ μ—†λŠ” ν–₯μˆ˜λŠ” pass
    cnt = len(top_notes) + len(middle_notes) + len(base_notes)
    if cnt == 0:
        continue

    for note in top_notes:
        df.loc[id, note] = 1
    for note in middle_notes:
        df.loc[id, note] = 1
    for note in base_notes:
        df.loc[id, note] = 1

3.2 Content Based Filtering

Pandas 라이브러리λ₯Ό μ΄μš©ν•˜μ—¬ 행은 ν–₯수 id, 열은 ν–₯수 note둜 이루어진 DataFrame 생성

image-20211007200909629

ν•΄λ‹Ή DataFrame 을 μ΄μš©ν•˜μ—¬ 각 ν–₯μˆ˜λ“€ κ°„μ˜ μœ μ‚¬λ„λ₯Ό cosine similarity λ₯Ό μ΄μš©ν•˜μ—¬ κ³„μ‚°ν•œλ‹€. cosine similarity κ°€ 1에 κ°€κΉŒμšΈ 수둝 μœ μ‚¬λ„κ°€ λ†’κΈ° λ•Œλ¬Έμ— μœ μ‚¬λ„κ°€ 높은 2개의 ν–₯수λ₯Ό μ°Ύμ•„ μ‚¬μš©μžμ—κ²Œ μΆ”μ²œν•˜μ—¬ μ€€λ‹€.

image-20211007205806630

# μƒμ„±ν•œ DataFrame을 similarity 계산
similarity = cosine_similarity(df)

n_df = pd.DataFrame(similarity, columns=df.index, index=df.index)
n_df = n_df.drop_duplicates() # 쀑볡 제거
value = []
i = 0

# 각 ν–₯수 λ³„λ‘œ μœ μ‚¬λ„κ°€ 높은 2개의 ν–₯수 μΆ”μΆœ
for std in n_df.index:
    i += 1
    sort_df = n_df.loc[std, :].sort_values(ascending=False)
    id_list = sort_df.head(3).index
    value_list = sort_df.head(3).values
    temp = [std, id_list[1], value_list[1]]
    value.append(temp)
    temp = [std, id_list[2], value_list[2]]
    value.append(temp)

4. μ•„ν‚€ν…μ²˜ 및 ERD

  • μ•„ν‚€ν…μ²˜

architecture

  • ERD

    img

5. μ‚¬μ΄νŠΈ λ ˆμ΄μ•„μ›ƒ 및 λ””μžμΈ

  • Main νŽ˜μ΄μ§€

    image-20211007211256506 image-20211007211320027

  • μ·¨ν–₯ 검색 νŽ˜μ΄μ§€(1 / 7)

    image-20211007211535918

  • μ·¨ν–₯ 검색 κ²°κ³Ό νŽ˜μ΄μ§€

    image-20211007211837288


  • About νŽ˜μ΄μ§€(1 / 4)

    image-20211007211716168

  • Search νŽ˜μ΄μ§€

    image-20211007211903986


  • ν–₯수 상세 λͺ¨λ‹¬ μ°½

    image-20211007211938232


  • λ‚˜μ˜ ν–₯μˆ˜ν•¨(My Page)

    image-20211007212033196