[기획&개발] 아동 장난감 색감 분석하기

soryeongk·2022년 4월 25일
0
post-thumbnail

  1. 팀원: 2명
  2. 주요역할: 기술리딩
  3. 사용기술: 데이터정제 및 크롤링(Python)
  4. 프로젝트 기간: 2018.10.04 ~ 2018.12.31

본 프로젝트는 2018년 서울시 인기 카페 색감 분석 프로젝트의 스핀오프로 진행되었습니다.
제 프로젝트를 본 윤경님께서 아이디어를 내고 PM을 맡으셨습니다.
색데이터 정제와 관련한 코드는 강규영님의 도움을 받았습니다.
2018년 당시 홈페이지에서의 문제를 발견하고 진행하였으나, 현재는 개선된 것으로 보입니다.

0. 목적

이 프로젝트는 한국에서 판매되고 있는 장난감들의 색상을 분석한 결과를 정리한 것입니다.

세계적인 장난감 체인점 토이저러스(Toys"R"Us)의 홈페이지를 보면 다음과 같이 여아 Toys와 남아 Toys로 분류되어 있습니다. 아래 사진은 2018년에 캡쳐한 것으로 현재는 변경되었습니다.

상위 카테고리하위 카테고리
여아 Toys역할놀이, 인형, 꾸미기, DIY/취미
남아 Toys역할놀이, 액션, 조종, 자동차/기차, 프라모델/피규어

어려서부터 '여자 장난감' '남자 장난감'의 구분이 만들어지는 것부터가 문제라고 생각했습니다. 이러한 분류는 여자 아이들도 액션, 조종, 자동차에 관심을 가질 수 있고, 남자 아이들도 인형, 꾸미기에 관심을 가질 수 있다는 생각 자체를 막아버릴 수 있습니다.

혹, 여아 Toys와 남아 Toys 하위 카테고리의 장난감들이 어떤 특징을 가지는지를 확인했습니다. 전반적으로 훑었을 때도 여아 Toys에는 분홍색이, 남아 Toys에는 파란색이 대부분이라는 느낌을 주었습니다. 하지만, 우리 개인적인 편견으로 판단하는 것은 옳지 않다고 생각해 데이터로 이 문제를 풀어보았습니다.

이전 카페 색감 분석 프로젝트에서도 느꼈지만, 색은 정말 복잡하고 다양한 조건에 의해 결정됩니다. 색상, 명도, 채도를 모두 고려해야 하는데, 이것을 컴퓨터에게 이해시키는 것은 쉽지 않았습니다.
여러 방법 중 강규영님의 도움을 받아 HSV 색 공간와 코사인 유사도(cosine similarity)를 활용했습니다.

1. 색(Color) 공간 이해하기

HSV 색 공간이란,
HSV 색 공간 또는 HSV 모델이라고도하며, 색을 표현하는 하나의 방법이자, 그 방법에 따라 색을 배치하는 방식입니다. 색상(Hue), 채도(Saturation), 명도(Value)의 좌표를 써서 특정한 색을 지정합니다.

여아 Toys에서 Pink색의 장난감이 몇 개가 있는지를 확인하기 위해서는 "Pink가 무엇인가?"라는 질문의 답을 찾는 것이 중요했습니다.
Pink를 떠올렸을 때, 사람들이 하나의 색만 떠올린다면 좋겠지만 인터넷에 Pink를 검색했을 때 나오는 색도 아주 가지각색입니다. 아래 처럼 말이죠.

이상에서 말한 것처럼 색상, 채도, 명도에 따라 달라지는 Pink를 컴퓨터에게 알려줄 수 있게 코사인 유사도를 활용했습니다.

2. 코사인 유사도

참고
코사인 유사도: 티스토리 블로그-자비스가 필요해

코사인 유사도는 vector 간의 코사인 각도를 이용하여 비교 대상이 얼마나 유사한지를 측정합니다. 코사인 유사도는 -1 ~ 1 사이의 값을 가집니다. 벡터들의 방향이 완전히 다른 경우(서로 간 각도가 180°)에는 -1, 완전히 동일한 경우(각도가 0°) 1을 가집니다.

앞서 이야기한 색공간에서 "보편적인 Pink"의 Hue 각도를 찾아 코사인 유사도에 활용한다면, 컴퓨터에게 정확하게 Pink가 무엇인지를 알려주지는 못해도 "보편적인 Pink"에 얼마나 가까운지를 알려줄 수 있게 된 것입니다. 그래서 가장 먼저 "보편적인 Pink"를 생각했습니다.

위 사진이 저희가 정한 "보편적인 Pink"입니다. HSV 공간에서 Hue의 각도(0~360°)는 인터넷 검색을 통해서도 가능하고, rgb 값을 알고 있는 상황에서는 matplotlib.colors의 rgb_to_hsv를 사용할 수도 있습니다. rgb_to_hsv는 rgb 값을 [r, g, b]의 형식으로 전달하면 hsv값을 [h, s, v]의 형식으로 반환합니다.

이때 나온 h값이 hue 값인데, 이는 hue 각도를 360으로 나눈 0과 1사이의 값으로 되어 있습니다. 하지만 코사인 그래프는 0과 2pi 사이에서 하나의 주기를 완성하기 때문에, 여기에 2pi를 곱해줍니다. hue의 각도를 코드가 아닌 인터넷에서 검색하여 0~360°사이의 hue 각도를 알고 있는 상황이라면 360으로 나눈 후 2pi를 곱해주어야 합니다.

import numpy as np


hsv = rgb_to_hsv(rgb)
pink_hue = hsv[0] * np.pi * 2

이제 프로젝트에서 사용할 pink의 기준을 잡았으니 데이터를 불러옵니다.

3. 데이터 크롤링

2018년 당시 홈페이지를 대상으로 한 크롤링이었기에 현재는 캡쳐가 불가하여 생략합니다.
코드는 깃헙에서 확인할 수 있습니다.

크롤링에서 고려했던 것은 다음과 같습니다.
1. 홈페이지의 데이터 구조 파악하기 - 어떤 페이지에서 어떤 데이터를 가져올 수 있는가
2. 어떤 데이터가 필요한가

당시 홈페이지에서는 productName남아와 여아로 구분된 카테고리가 어떤 차이가 있는지, 카테고리 내 장난감의 색상은 어떻게 달라지는지 알기 위해 categoryID를 함께 가져왔습니다.

홈페이지에서 제품별로 부여된 categoryID와 productName을 먼저 가져왔습니다.

상기 내용을 다시 크롤러에 넣어 이미지와 productID를 가져옵니다. 파일명은 {categoryID}-{productID}로 정하였습니다.

4. 데이터 분석

크롤링된 데이터와 상기 코사인 유사도를 활용해 데이터 분석을 해보았습니다.
분석 과정은 비교적 간단합니다.

  1. 이미지를 가져옵니다.
  2. 픽셀단위로 이미지를 확인하면서 해당 색상이 앞서 설정한 pink(#FF0087)와 얼마나 가까운지를 확인합니다. 코사인 유사도를 사용하므로 값은 -1 ~ 1 사이 값이 됩니다.
  3. 그 값의 평균을 구합니다.

분석 코드

result = pd.DataFrame(columns=['파일명','cossim'])

for img in images[:100]:
    try:
        rgb = imread(f'../image/{img}')
        if rgb.shape[2] != 3:
            result = result.append({'파일명' : img, 'cossim' : 'Error'}, ignore_index=True)
            continue
        hsv = rgb_to_hsv(rgb)
        hue_list = []
        for i in range(500):
            for h, s, v in hsv[:,:,:][i]:
                if v >= 254 and s <= 2:
                    continue
                hue = h * np.pi * 2
                cossim = np.cos(hue-pink_hue)
                hue_list.append(cossim)
        result = result.append({'파일명' : img, 'cossim' : np.mean(hue_list)}, ignore_index=True)
    except:
        result = result.append({'파일명' : img, 'cossim' : 'Error2'}, ignore_index=True)

파일별로 pink의 유사도를 가지는 정도를 표로 나타내 일부를 확인해보니 다음과 같았습니다.

4295개의 제품을 모두 확인하여 코사인 값을 정리해보면 다음과 같은 양상을 보입니다.

평균적으로 pink는 0.26의 유사도를, blue는 -0.21의 유사도를 가지고 있습니다. 이는 기본적으로 pink에 가까운 색이 많다는 것을 의미하고, blue는 큰 편향을 보이지는 않습니다.

4-1. 남아/여아 카테고리별 색상 유사도

blue에 대해서도 같은 방식으로 분석을 진행했습니다. 그리고 남아/여아 카테고리에서 어떤 차이가 있는지를 확인해보았습니다. 코사인 유사도가 1에 가까울수록 해당 색감이 짙다는 것, -1에 가까울수록 멀다는 것을 의미합니다.

남아(boy)로 구분된 제품의 이미지에서는 pink가 약 0.18, blue는 약 -0.16이 나왔고, 여아(girl)로 구분된 제품의 이미지에서는 pink가 약 0.32로 평균을 넘었고, blue는 약 -0.25가 나왔습니다.

표준편차(다양성의 정도)의 경우 두 개의 카테고리 모두 비슷한 양상을 보였습니다.

4-2. 카테고리명 별 색상 유사도

카테고리명은 분석에서 영문을 사용하기 위해 임의로 번역하였습니다.
boy-Action: 액션, boy-Car/Train: 자동차/기차, boy-Control: 조종, boy-Figure: 프라모델/피규어, boy-RolePlay: 역할놀이, girl-DIY: DIY/취미, girl-Deco: 꾸미기, girl-Doll: 인형, girl-RolePlay: 역할놀이
성별구분별로 카테고리도 상이하다는 것도 알 수 있었습니다.

전반적으로 blue가 치우친 경우는 거의 없고, 남아의 경우 pink의 유사도도 높지 않습니다. 그런데 여아의 경우 blue의 유사도와 pink의 유사도의 격차가 현저히 벌어지는 것을 알 수 있습니다. 또한, 남아 제품은 평균 미만의 pink 유사도를 보이는 반면, 여아 카테고리의 대부분은 평균을 훌쩍 넘었습니다. 이를 통해, 여아 제품으로 분류된 장난감에 Pink가 많이 포함되어있으며, 남아 제품으로 분류된 장난감은 그다지 큰 차이를 보이지 않는 다는 것을 알 수 있습니다.

4-3. 시각화 해보기

여아와 남아의 색상 유사도 전체를 그래프로 그려보면 이상과 같습니다. 하지만 이 그래프만으로는 평향의 정도를 논하기는 어려워보입니다. 그래서 카테고리별로 박스 그래프를 그려보았습니다. 대체적으로 여아 제품의 편향이 짙고, 이상치도 많이 발견되는 것을 확인할 수 있습니다.

5. 여아 제품은 pink, 남아 제품은?

여아 장난감이 대체적으로 pink에 치우쳐진 것은 확인할 수 있었지만, 남아 제품에 대해서 이렇다할 결과는 얻지 못했습니다. 그래서 직접 남아 제품을 확인해보았습니다. 현재는 해당 사이트의 페이지가 개편되어서 사진을 첨부할 수는 없지만, 당시 기록에 의존해보자면, 남아 제품은 파란색만큼 초록색과 무채색(검정, 하양), 빨간색이 눈에 띄었습니다. 여아 제품만 pink에 편향되어있는 것이 답답하고 속상했던 기억이 있습니다. 이제는 이런식의 성별구분이나 역할구분 대신, 장난감의 특징과 기능만으로 구분될 수 있기를 바라봅니다.

profile
웹 프론트엔드 개발자 령이의 어쩌구 저쩌구

0개의 댓글