Type I. 프로그램 구현능력 평가

#. 자기학번으로 랜덤시드를 만들고 $N(0,1)$, $N(1,1)$인 2개의 정규분포에서 각각 10000개의 관측치를 생성한뒤 saeborn을 이용하여 히스토그램을 그려라.

힌트

  • 랜덤시드 생성: np.random.seed()를 이용
np.random.seed(201855393)
y1 = np.random.normal(loc=0, scale=1, size = 10000)
y2 = np.random.normal(loc=1, scale=1, size = 10000)
A = pd.DataFrame({'score':y1, 'class':['A']*len(y1)})
B = pd.DataFrame({'score':y2, 'class':['B']*len(y2)})
df = pd.concat([A,B], ignore_index=True)
sns.histplot(df,x='score', hue='class')
<AxesSubplot:xlabel='score', ylabel='Count'>

#. 주어진 자료를 바탕으로 예시와 같은 시각화를 구현하라.

자료

x=[1,2,3,4]
y=[1,2,4,3]

시각화예시

x=[1,2,3,4]
y=[1,2,4,3]
_, axs = plt.subplots(2,2)
axs[0,0].plot(x,y,'o:r') 
axs[0,1].plot(x,y,'Xb') 
axs[1,0].plot(x,y,'xm') 
axs[1,1].plot(x,y,'.--k') 

[<matplotlib.lines.Line2D at 0x7f9548413e80>]

Type II. 개념의 이해 평가

# 아래는 앤스콤의 플랏이다. 옳게 해석한 사람을 모두 고르라

x = [10, 8, 13, 9, 11, 14, 6, 4, 12, 7, 5]
y1 = [8.04, 6.95, 7.58, 8.81, 8.33, 9.96, 7.24, 4.26, 10.84, 4.82, 5.68]
y2 = [9.14, 8.14, 8.74, 8.77, 9.26, 8.10, 6.13, 3.10, 9.13, 7.26, 4.74]
y3 = [7.46, 6.77, 12.74, 7.11, 7.81, 8.84, 6.08, 5.39, 8.15, 6.42, 5.73]
x4 = [8, 8, 8, 8, 8, 8, 8, 19, 8, 8, 8]
y4 = [6.58, 5.76, 7.71, 8.84, 8.47, 7.04, 5.25, 12.50, 5.56, 7.91, 6.89]
fig, axs = plt.subplots(2,2)
axs[0,0].plot(x,y1,'o') 
axs[0,0].set_title('(a)')
axs[0,1].plot(x,y2,'o') 
axs[0,1].set_title('(b)')
axs[1,0].plot(x,y3,'o')  
axs[1,0].set_title('(c)')
axs[1,1].plot(x4,y4,'o') 
axs[1,1].set_title('(d)') 
fig.tight_layout()

(하니) 그림 (a)는 양의 상관계수를 가진다.

(나애리) 그림 (b)는 산점도가 직선이 아니라 곡선의 모양을 띄고 있으므로 상관계수는 0이다.

(홍두깨) 그림 (c)에서 상단의 이상치를 제외하면 상관계수는 1이다.

(고은혜) 그림 (c)와 (d)의 상관계수를 각각 $r_1, r_2$라고 하자. 그리고 (c)와 (d)에서 각각 이상치를 제외한뒤 구한 상관계수를 $\tilde{r}_1, \tilde{r}_2$ 이라고 하자. 그렇다면 $r_1 r_2 < \tilde{r}_1\tilde{r}_2$ 가 성립한다.

- 하니

n=len(x)
xx1 = (x-np.mean(x)) / (np.std(x) * np.sqrt(n))
yy1 = (y1-np.mean(y1)) / (np.std(y1) * np.sqrt(n))
sum(xx1*yy1)
0.81642051634484

#. 아래의 산점도를 보고 옳게 해석한 사람을 모두 고르라.

- 나애리

yy2 = (y2-np.mean(y2)) / (np.std(y2) * np.sqrt(n))
sum(xx1*yy2)
0.8162365060002429

- 홍두깨

xo1 = [10, 8, 13, 9, 11, 14, 6, 4, 7, 5]
yo1 = [7.46, 6.77, 7.11, 7.81, 8.84, 6.08, 5.39, 8.15, 6.42, 5.73]
nn=len(xo1)
xxx1 = (xo1-np.mean(xo1)) / (np.std(xo1) * np.sqrt(nn))
yyy1 = (yo1-np.mean(yo1)) / (np.std(yo1) * np.sqrt(nn))
sum(xxx1*yyy1)
0.16431217363167483

- 고은혜

yy3 = (y3-np.mean(y3)) / (np.std(y3) * np.sqrt(n))
yy4 = (y4-np.mean(y4)) / (np.std(y4) * np.sqrt(n))
sum(xx1*yy3)*sum(xx1*yy4)
-0.25635216209272227
xo2 = [8, 8, 8, 8, 8, 8, 8, 8, 8, 8]
yo2 = [6.58, 5.76, 7.71, 8.84, 8.47, 7.04, 5.25, 5.56, 7.91, 6.89]
xxx2 = 0
yyy2 = (yo2-np.mean(yo2)) / (np.std(yo2) * np.sqrt(nn))
sum(xxx1*yyy1)*sum(xxx2*yyy2)
0.0

x1=np.arange(0,10,0.1)
y1=x1+np.random.normal(loc=0,scale=1.0,size=len(x1))
plt.plot(x1,y1,'.')

[<matplotlib.lines.Line2D at 0x7f89537b79a0>]

(하니) 두 변수는 양의 상관관계에 있어 보인다.

(나애리) 완전한 직선 모양이 되지는 않았으므로 상관계수는 1보다 작다.

(홍두깨) 산점도를 파악하면 $x$가 증가할때 $y$도 증가하므로 $x$가 $y$를 유발하는 원인이라 해석할 수 있다.

(고은혜) $y$를 유지한채 $x$의 값을 모두 2배로 하면 상관계수의 값도 2배가 된다.

- 하니

n=len(x1)
xx1 = (x1-np.mean(x1)) / (np.std(x1) * np.sqrt(n))
yy1 = (y1-np.mean(y1)) / (np.std(y1) * np.sqrt(n))
sum(xx1*yy1)
0.9408508837759367

- 나애리

sum(xx1*yy1)
0.9408508837759367

- 고은혜

x2 = x1*2
xx2 = (x1-np.mean(x2)) / (np.std(x2) * np.sqrt(n))
sum(xx2*yy1)
0.47042544188796803

Type III. 자료분석 및 시각화 능력 종합평가

# 아래는 pandas cookbook에 수록된 employee 자료이다.

df=pd.read_csv('https://raw.githubusercontent.com/PacktPublishing/Pandas-Cookbook/master/data/employee.csv')
df
UNIQUE_ID POSITION_TITLE DEPARTMENT BASE_SALARY RACE EMPLOYMENT_TYPE GENDER EMPLOYMENT_STATUS HIRE_DATE JOB_DATE
0 0 ASSISTANT DIRECTOR (EX LVL) Municipal Courts Department 121862.0 Hispanic/Latino Full Time Female Active 2006-06-12 2012-10-13
1 1 LIBRARY ASSISTANT Library 26125.0 Hispanic/Latino Full Time Female Active 2000-07-19 2010-09-18
2 2 POLICE OFFICER Houston Police Department-HPD 45279.0 White Full Time Male Active 2015-02-03 2015-02-03
3 3 ENGINEER/OPERATOR Houston Fire Department (HFD) 63166.0 White Full Time Male Active 1982-02-08 1991-05-25
4 4 ELECTRICIAN General Services Department 56347.0 White Full Time Male Active 1989-06-19 1994-10-22
... ... ... ... ... ... ... ... ... ... ...
1995 1995 POLICE OFFICER Houston Police Department-HPD 43443.0 White Full Time Male Active 2014-06-09 2015-06-09
1996 1996 COMMUNICATIONS CAPTAIN Houston Fire Department (HFD) 66523.0 Black or African American Full Time Male Active 2003-09-02 2013-10-06
1997 1997 POLICE OFFICER Houston Police Department-HPD 43443.0 White Full Time Male Active 2014-10-13 2015-10-13
1998 1998 POLICE OFFICER Houston Police Department-HPD 55461.0 Asian/Pacific Islander Full Time Male Active 2009-01-20 2011-07-02
1999 1999 FIRE FIGHTER Houston Fire Department (HFD) 51194.0 Hispanic/Latino Full Time Male Active 2009-01-12 2010-07-12

2000 rows × 10 columns

(a) 결측치 제거 및 결측치의 갯수 파악하기

df자료에는 결측치가 존재한다. 예를들면 아래에서 9번자료의 RACE는 아무것도 입력되어있지 않아 NaN으로 처리되었다.

df.iloc[8:11,:]
UNIQUE_ID POSITION_TITLE DEPARTMENT BASE_SALARY RACE EMPLOYMENT_TYPE GENDER EMPLOYMENT_STATUS HIRE_DATE JOB_DATE
8 8 DEPUTY ASSISTANT DIRECTOR (EXECUTIVE LEV Public Works & Engineering-PWE 107962.0 White Full Time Male Active 1993-11-15 2013-01-05
9 9 AIRPORT OPERATIONS COORDINATOR Houston Airport System (HAS) 44616.0 NaN Full Time Male Active 2016-03-14 2016-03-14
10 10 FIRE FIGHTER Houston Fire Department (HFD) 52644.0 Hispanic/Latino Full Time Male Active 2007-05-21 2008-11-15

아래코드를 실행하여 결측치를 포함한 행을 제거하고 몇개의 결측치가 제거되었는지 답하라.

df=df.dropna()
df.isnull().sum()
UNIQUE_ID              0
POSITION_TITLE         0
DEPARTMENT             0
BASE_SALARY          114
RACE                  35
EMPLOYMENT_TYPE        0
GENDER                 0
EMPLOYMENT_STATUS      0
HIRE_DATE              0
JOB_DATE               3
dtype: int64
df=df.dropna(axis=0)
df.isnull().sum()
UNIQUE_ID            0
POSITION_TITLE       0
DEPARTMENT           0
BASE_SALARY          0
RACE                 0
EMPLOYMENT_TYPE      0
GENDER               0
EMPLOYMENT_STATUS    0
HIRE_DATE            0
JOB_DATE             0
dtype: int64

(b) 여성의 기본급여 평균과 남성의 기본급여 평균을 각각 구하여라. 즉 GENDER=Male인 행들의 BASE_SALARY의 평균과 GENDER=Female인 행들의 BASE_SALARY의 평균을 비교하라.

pd.Series(df.columns)
0            UNIQUE_ID
1       POSITION_TITLE
2           DEPARTMENT
3          BASE_SALARY
4                 RACE
5      EMPLOYMENT_TYPE
6               GENDER
7    EMPLOYMENT_STATUS
8            HIRE_DATE
9             JOB_DATE
dtype: object
df.groupby(by='GENDER').agg({'BASE_SALARY':'mean'})
BASE_SALARY
GENDER
Female 52474.665487
Male 57670.031832

(c) 인종과 성별로 자료를 그룹핑하고 기본급여의 평균값 최소값 최대값을 각각 구한뒤 barplot으로 시각화 하라.

시각화예시

tidy=df.groupby(['RACE','GENDER']).agg({'BASE_SALARY': [np.mean,max,min]}).stack().reset_index().rename(columns={'level_2':'aggtype'})
fig=ggplot(tidy)
bar=geom_bar(aes(x='aggtype',y='BASE_SALARY',fill='GENDER'),stat='identity',position='dodge')
fig+bar+coord_flip()+facet_wrap(facets="RACE") 

/Users/honghyeonki/opt/anaconda3/envs/ds2021/lib/python3.8/site-packages/plotnine/utils.py:371: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.
<ggplot: (8764243373517)>