머신 러닝
# 데이터를 학습용과 테스트용으로 분할 from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(x, y, test_size=0.2, stratify=y) print("X's shape: {}".format(x.shape)) print("X_train's shape: {}".format(X_train.shape)) print("X_test's shape: {}".format(X_test.shape)) y_test.value_counts()
- 교차검증
cpu를 다 써서 병렬 처리from sklearn.model_selection import cross_val_score # 분류기 생성 clf = DecisionTreeClassifier(random_state=11) scores = cross_val_score(clf, x, y, scoring='accuracy', cv=3, n_jobs=-1) scores.sum()/len(scores)데이터 전처리
- 레이블 인코딩
from sklearn.preprocessing import LabelEncoder items = ['TV','냉장고','전자레인지','컴퓨터','선풍기','선풍기','냉장고'] encoder = LabelEncoder() encoder.fit(items) # 매핑키를 만들어준다. labels = encoder.transform(items) print(labels)import pandas as pd df = pd.read_csv('data/iris.csv') iris_encoder = LabelEncoder() iris_encoder.fit(df['variety']) df['variety_num'] = iris_encoder.transform(df['variety']) df['variety_num'].value_counts()
조회 하기iris_encoder.classes_원-핫 인코딩
data = {'item' : ['TV','냉장고','전자레인지','컴퓨터','선풍기','선풍기','냉장고']} df = pd.DataFrame(data) pd.get_dummies(df)
- 데이터 표준화 : x에 있는 숫자에 적용
iris_x = df_iris.drop(['variety_Setosa', 'variety_Versicolor', 'variety_Virginica'], axis=1) print('평균 값') print(iris_x.mean()) print('분산 값') print(iris_x.var())from sklearn.preprocessing import StandardScaler scaler = StandardScaler() scaler.fit(iris_x) iris_x_scaled = scaler.transform(iris_x) iris_x_scaled = pd.DataFrame(iris_x_scaled) print('평균 값') print(iris_x_scaled.mean()) print('분산 값') print(iris_x_scaled.var()) iris_x_scaled.head(5)
정규화와 분포화
- 데이터 정규화
from sklearn.preprocessing import MinMaxScaler scaler = MinMaxScaler() scaler.fit(iris_x) iris_minmax = scaler.transform(iris_x) iris_minmax = pd.DataFrame(iris_minmax) iris_minmax
이상치인지 판단
- 상자수염차트
import matplotlib.pyplot as plt df_eq = pd.read_csv('data/earthquakes.csv') df_eq['Depth'].plot(kind='box')
q1 = df_eq['Depth'].quantile(0.25) q3 = df_eq['Depth'].quantile(0.75) iqr = q3 - q1 q1 = df_eq['Depth'].quantile(0.25) q3 = df_eq['Depth'].quantile(0.75) iqr = q3 - q1 # 이상치 경계값 계산 upper_bound = q3 + 1.5 * iqr lower_bound = q1 - 1.5 * iqr # 필터 조건 cond1 = df_eq['Depth'] >= lower_bound cond2 = df_eq['Depth'] <= upper_bound df_eq_filtered = df_eq[cond1 & cond2] df_eq_filtered['Depth'].mean()실습
- 새로운 노트북 파일생성: 03_EuropeHotel.ipynb
- 다음 파일을 pandas dataframe 형태로 불러오기
- Europe Hotel Booking Satisfaction Score.csv
- 데이터 전처리
- id열 제거
- 레이블 인코딩: satisfaction 열
- 원-핫 인코딩: Gender, purpose_of_travel, Type of Travel, Type Of Booking
- 표준화 혹은 정규화: X의 모든 열
- 데이터 분할: 학습 7, 테스트 3
- 학습(DecisionTree)
- satisfaction: y
- 나머지: x
- 정확도 출력
import pandas as pd df = pd.read_csv('data/Europe Hotel Booking Satisfaction Score.csv') # df.head(5) df.info()from sklearn.preprocessing import LabelEncoder def preprocess(df, label_column, drop_columns=None, onehot_colums=None): if drop_columns: df.drop(drop_columns, axis=1, inplace=True) le = LabelEncoder() le.fit(df[label_column]) df[label_column] = le.transform(df[label_column]) # 원-핫 인코딩 if onehot_colums: df = pd.get_dummies(df, columns=onehot_colums) # X, y로 데이터 분할 X = df.drop(label_column, axis=1) y = df[label_column] return X, y X, y = preprocess(df, 'satisfaction', ['id'], ['Gender', 'purpose_of_travel', 'Type of Travel', 'Type Of Booking'])# id열 제거 df.drop('id', axis=1, inplace=True)# 레이블 인코딩: satisfaction 열 from sklearn.preprocessing import LabelEncoder le = LabelEncoder() le.fit(df['satisfaction']) df['satisfaction'] = le.transform(df['satisfaction'])# 원-핫 인코딩 df = pd.get_dummies(df, columns=['Gender', 'purpose_of_travel', 'Type of Travel', 'Type Of Booking'])df.columns# X, y로 데이터 분할 X = df.drop('satisfaction', axis=1) y = df['satisfaction']# 표준화 혹은 정규화: X의 모든 열 from sklearn.preprocessing import StandardScaler, MinMaxScaler scaler = StandardScaler() scaler.fit(X) scaled_value = scaler.transform(X) X = pd.DataFrame(scaled_value, columns=X.columns) Xfrom sklearn.model_selection import train_test_split from sklearn.tree import DecisionTreeClassifier from sklearn.linear_model import LogisticRegression X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, stratify=y, random_state=121) clf = LogisticRegression() clf.fit(X_train, y_train)from sklearn.metrics import accuracy_score pred = clf.predict(X_test) print('정확도: {}'.format(accuracy_score(y_test, pred)))타이타닉 생존자 예측
맷플롯립과 시본을 이용해 차트와 그래프를 함께 시각화 하면서 데이터 분석 시행
# 필요한 라이브러리 임포트 import numpy as np import pandas as pd import matplotlib.pyplot as plt import seaborn as sns # 타이타닉 탑승자 파일을 판다스의 read_scv()를 이용해 DataFrame으로 로딩 titanic_df = pd.read_csv('data/titanic_train.csv') titanic_df.head(3)
- 로딩된 데이터 칼럽 타입 확인 - info()메서드
print('\n### 학습 데이터 정보 ### \n') print(titanic_df.info())
- DataFrame의 fillna()함수를 사용해 간단하게 Null 값을 평균 또는 고정 값으로 변경
- Age는 평균 나이, 나머지 칼럼은 'N'값으로 변경
titanic_df['Age'].fillna(titanic_df['Age'].mean(), inplace=True) titanic_df['Cabin'].fillna('N',inplace=True) titanic_df['Embarked'].fillna('N',inplace=True) print('데이터 세트 Null 값 개수', titanic_df.isnull().sum().sum()) # 모든 칼럼의 Null값이 없는지 확인
- 현재 남아있는 문자열 피처는 Sex, Cabin, Embarked
- 이 피처들의 값 분류 확인
print('Sex 값 분포 : \n', titanic_df['Sex'].value_counts()) print('\n Cabin 값 분포 : \n', titanic_df['Cabin'].value_counts()) print('\n Embarked 값 분포 : \n', titanic_df['Embarked'].value_counts())
- Cabin의 경우 선실 번호 중 선실 등급을 나타내는 첫 번째 알파벳 중요
- 부자와 가난한 사람에 대한 차별이 있었던 시절
- 일등실에 투숙한 사람이 삼등실에 투숙한 사람보다 더 살아날 확률 높음
# Sex, Embarked 값은 문제 X # Cabin의 경우 N이 687건으로 가장 많으며 속성값 정리 X # Cabin 앞 문자 추출 titanic_df['Cabin'] = titanic_df['Cabin'].str[:1] print(titanic_df['Cabin'].head(3))
- 어떤 유형의 승객이 생존 확률이 높았는지 확인
- 여성, 아이들, 노약자 구조 대상
- 성별이 생존 확률에 어떤 영향을 미쳤는지, 성별에 따른 생존자 수 비교
titanic_df.groupby(['Sex','Survived'])['Survived'].count() # 0은 사망 1은 생존
- 시각화 : 시본 패키지
# x축에 'Sex' 칼럼, Y축은 'Survived'칼럼 sns.barplot(x='Sex', y='Survived', data=titanic_df)
- 부자와 가난한 사람 간의 생존 확률
- 일등실, 이등실, 삼등실 & 성별 생존 확률
sns.barplot(x='Pclass', y='Survived', hue='Sex',data=titanic_df)
여성의 경우 일, 이등실에 따른 생존 확률이 차이는 크지 않으나, 삼등실의 경우 생존 확률이 상대적으로 떨어짐
남성의 경우 일등실의 생존 확률이 이, 삼등실의 생존 확률보다 월등히 높음
- Age에 따른 생존확률
# 0 ~ 5 : Baby # 6 ~ 12 : Child # 13 ~ 18 : Teenager # 19 ~ 25 : Student # 26 ~ 35 : Young Adult # 36 ~ 60 : Adult # 61 ~ : Elderly # -1 이하 : Unkown # 입력 age에 따라 구분 값을 반환하는 함수 설정 # DataFrame의 apply lambda 식에 사용 def get_category(age): cat = '' if age <= -1: cat = 'Unkown' elif age <= 5: cat = 'Baby' elif age <= 12: cat = 'Child' elif age <= 18: cat = 'Teenager' elif age <= 25: cat = 'Student' elif age <= 35: cat = 'Young Adult' elif age <= 60: cat = 'Adult' else : cat = 'Elderly' return cat # 막대그래프의 크기 figure를 더 크게 설정 plt.figure(figsize=(10,6)) # X축의 값을 순차적으로 표시하기 위한 설정 group_names = ['Unkown','Baby','Child','Teenager','Student','Young Adult','Adult','Elderly'] # lambda 식에 위에서 생성한 get_category() 함수를 반환값으로 지정 # get_category(X)는 입력값으로 'Age' 칼럼 값을 받아서 해당하는 cat 반환 titanic_df['Age_cat'] = titanic_df['Age'].apply(lambda x : get_category(x)) sns.barplot(x='Age_cat', y='Survived', hue='Sex',data=titanic_df,order=group_names) titanic_df.drop('Age_cat',axis=1, inplace=True)
from sklearn.preprocessing import LabelEncoder def encode_features(dataDF): features = ['Cabin','Sex','Embarked'] for feature in features: le = LabelEncoder() le = le.fit(dataDF[feature]) dataDF[feature] = le.transform(dataDF[feature]) return dataDF titanic_df = encode_features(titanic_df) titanic_df.head()from sklearn.preprocessing import LabelEncoder # Null 처리 함수 def fillna(df): df['Age'].fillna(df['Age'].mean(), inplace=True) df['Cabin'].fillna('N', inplace=True) df['Embarked'].fillna('N', inplace=True) df['Fare'].fillna(0, inplace=True) return df # 머신러닝 알고리즘에 불필요한 피처 제거 def drop_features(df): df.drop(['PassengerId', 'Name', 'Ticket'], axis=1, inplace=True) return df # 레이블 인코딩 수행. def format_features(df): df['Cabin'] = df['Cabin'].str[:1] features = ['Cabin', 'Sex', 'Embarked'] for feature in features: le = LabelEncoder() le = le.fit(df[feature]) df[feature] = le.transform(df[feature]) return df # 앞에서 설정한 데이터 전처리 함수 호출 def transform_features(df): df = fillna(df) df = drop_features(df) df = format_features(df) return df# 원본 데이터를 재로딩 하고, feature데이터 셋과 Label 데이터 셋 추출. titanic_df = pd.read_csv('https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv') y_titanic_df = titanic_df['Survived'] X_titanic_df= titanic_df.drop('Survived',axis=1) X_titanic_df = transform_features(X_titanic_df)# 원본 데이터를 재로딩하고, 피처 데이터 세트와 레이블 데이터 세트 추출 titanic_df = pd.read_csv('data/titanic_train.csv') y_titanic_df = titanic_df['Survived'] X_titanic_df = titanic_df.drop('Survived', axis=1) X_titanic_df = transform_features(X_titanic_df)from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test=train_test_split(X_titanic_df, y_titanic_df, test_size=0.2, random_state=11)from sklearn.tree import DecisionTreeClassifier from sklearn.ensemble import RandomForestClassifier from sklearn.linear_model import LogisticRegression from sklearn.metrics import accuracy_score # 결정트리, Random Forest, 로지스틱 회귀를 위한 사이킷런 Classifier 클래스 생성 dt_clf = DecisionTreeClassifier(random_state=11) rf_clf = RandomForestClassifier(random_state=11) lr_clf = LogisticRegression(solver='liblinear') # DecisionTreeClassifier 학습/예측/평가 dt_clf.fit(X_train , y_train) dt_pred = dt_clf.predict(X_test) print('DecisionTreeClassifier 정확도: {0:.4f}'.format(accuracy_score(y_test, dt_pred))) # RandomForestClassifier 학습/예측/평가 rf_clf.fit(X_train , y_train) rf_pred = rf_clf.predict(X_test) print('RandomForestClassifier 정확도:{0:.4f}'.format(accuracy_score(y_test, rf_pred))) # LogisticRegression 학습/예측/평가 lr_clf.fit(X_train , y_train) lr_pred = lr_clf.predict(X_test) print('LogisticRegression 정확도: {0:.4f}'.format(accuracy_score(y_test, lr_pred)))
from sklearn.model_selection import KFold def exec_kfold(clf, folds=5): # 폴드 세트를 5개인 KFold객체를 생성, 폴드 수만큼 예측결과 저장을 위한 리스트 객체 생성. kfold = KFold(n_splits=folds) scores = [] # KFold 교차 검증 수행. for iter_count , (train_index, test_index) in enumerate(kfold.split(X_titanic_df)): # X_titanic_df 데이터에서 교차 검증별로 학습과 검증 데이터를 가리키는 index 생성 X_train, X_test = X_titanic_df.values[train_index], X_titanic_df.values[test_index] y_train, y_test = y_titanic_df.values[train_index], y_titanic_df.values[test_index] # Classifier 학습, 예측, 정확도 계산 clf.fit(X_train, y_train) predictions = clf.predict(X_test) accuracy = accuracy_score(y_test, predictions) scores.append(accuracy) print("교차 검증 {0} 정확도: {1:.4f}".format(iter_count, accuracy)) # 5개 fold에서의 평균 정확도 계산. mean_score = np.mean(scores) print("평균 정확도: {0:.4f}".format(mean_score)) # exec_kfold 호출 exec_kfold(dt_clf , folds=5)