5日目

41883 ワード

マルチデータプリプロセッシング技術


学習目標


重複データを検索して削除するか、欠落したデータを削除または入力できます.
データを正規化できます.例外値(クラスタ外値)を検索して処理できます.
カテゴリデータは1対1の熱符号化が可能である.連続データを区間に分割し、カテゴリデータに変換できます.

検出:値が表示されない(Missing Data,Missing Feature, NA(Not Available))

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import os

csv_file_path = os.getenv('HOME')+'/aiffel/data_preprocess/data/trade.csv'
trade = pd.read_csv(csv_file_path) 
trade.head()

# 전체 데이터 건수
print('전체 데이터 건수:', len(trade))
# 컬럼별 결측치 개수
print('컬럼별 결측치 개수')
len(trade) - trade.count()
# 기타사항 삭제
trade = trade.drop('기타사항', axis=1)
trade.head()

DataFrame.isnull() # 데이터마다 결측치 여부를 True, False로 반환합니다. 
DataFrame.any(axis=1) # 행마다 하나라도 True가 있으면 True, 그렇지 않으면 False를 반환한다
# 각 행이 결측치가 하나라도 있는지 여부를 불리언 값으로 가진 Series가 출력됩니다
trade[trade.isnull().any(axis=1)] 
# 다시 DataFrame에 넣어주면 값이 True인 데이터만 추출해 줍니다

trade.dropna(how='all', subset=['수출건수', '수출금액', '수입건수', '수입금액', '무역수지'], inplace=True)
print("👽 It's okay, no biggie.")
# dropna는 결측치를 삭제해 주는 메서드입니다. 
# subset 옵션으로 특정 컬럼들을 선택했습니다. 
# how 옵션으로 선택한 컬럼 전부가 결측치인 행을 삭제하겠다는 의미로 
# 'all'을 선택합니다('any': 하나라도 결측치인 경우). 
# inplace 옵션으로 해당 DataFrame 내부에 바로 적용시켰습니다.

 # DataFrame.loc[행 라벨, 열 라벨]을 입력하면 해당 라벨을 가진 데이터를 출력해 줍니다
trade.loc[[188, 191, 194]]

重複データ


DataFrame.dullated():重複するデータをブール値に返すかどうか
trade.drop_duplicates(inplace=True): 중복된 데이터를 삭제 해준다

df = pd.DataFrame({'id':['001', '002', '003', '004', '002'], 
                   'name':['Park Yun', 'Kim Sung', 'Park Jin', 'Lee Han', 'Kim Min']})
df # 002인 id가 2개있다 둘중에 하나를 삭제하려면?
# DataFrame.drop_duplicates의 subset, keep 옵션으로 중복을 제거할 수 있습니다
df.drop_duplicates(subset=['id'], keep='last') # last 마지막 유지 first 첫번째 유지

異常値(Outlier)


Outlier(異常値)
多値の範囲を超えて、極大または極小の値を表す
異常値を探す方法は?最も簡単で、最もよく使われる方法は平均と標準偏差を使用することです. z score に道を教える
z-scoreは統計的な予測値であり,距離平均値がどのくらい離れているかを計算する.標準化された数値(Standard Score)と呼ばれています.
数式

x:個別数値
μ: へいきん
σ : ひょうじゅんへんさ
z-scoreは、各X値と平均値との距離を表し、募集団の標準偏差(σ)割り勘の値段したがって、z−scoreは、各値の分布全体における相対的な位置を表す.
z−scoreが−値を有するほど、その値は相対的に減少する傾向を有し、+値が相対的に増加する傾向を有する.
標準点-ウィキペディア、私たち全員の百科事典
z-score method
이상치인 데이터의 인덱스를 리턴하는 outlier라는 함수를 만들었습니다. 
데이터프레임 df, 컬럼 col, 기준 z를 인풋으로 받습니다.

abs(df[col] - np.mean(df[col])) : 데이터에서 평균을 빼준 것에 절대값을 취합니다.
abs(df[col] - np.mean(df[col]))/np.std(df[col]) : 위에 한 작업에 표준편차로 나눠줍니다.
df[abs(df[col] - np.mean(df[col]))/np.std(df[col])>z].index
 # 값이 z보다 큰 데이터의 인덱스를 추출합니다.
def outlier(df, col, z): # 이상치
    return df[abs(df[col] - np.mean(df[col]))/np.std(df[col])>z].index

def not_outlier(df, col, z): # 이상치가 아닌 데이터만 추출
    return df[abs(df[col] - np.mean(df[col]))/np.std(df[col]) <= z].index
IQR method
四分位範囲数(IQR)も異常値を求めることができ,z score法の代替案とすることができる.
四分位数
四分位数は、データサンプルを4つの同じ部分に分割する値です.四分位数を使用すると、データセットの範囲と中心位置を迅速に評価できます.
四分位数の定義
四分位数の定義
四分位数の求め方
#iqrで異常値を求める方法 def outlier2(df, col): # [[YOUR CODE]] def outlier2(df, col): q1 = df[col].quantile(0.25) q3 = df[col].quantile(0.75) iqr = q3 - q1 return df[(df[col] < q1-1.5*iqr)|(df[col] > q3+1.5*iqr)] 離群値2(trade,「貿易収支」)

正規化


「正規化」(Normalization)の基本目標は、次のとおりです. つまり、テーブル間で重複するデータは許可されません.重複データは許可されていません. 整合性を維持したり、データベースのストレージ容量を削減したりできます.
正規化

x:元データXnew:正規化点数Xmin:元データ最小値Xmax:元データ最大値
データの最大値を0、最大値を1に変換
標準化

x:元のデータ(rawdata)z:標準点数(standard score,z-score)μ : へいきんちσ : 標準偏差(std)
データの平均値を0に変換し、偏差値を1に変換します.
[統計]標準化/標準化
# 정규분포를 따라 랜덤하게 데이터 x를 생성합니다. 
x = pd.DataFrame({'A': np.random.randn(100)*4+4,
                 'B': np.random.randn(100)-1})
x

# 데이터 x를 Standardization 기법으로 정규화합니다. 
x_standardization = (x - x.mean())/x.std()
x_standardization

# trade 데이터를 Standardization 기법으로 정규화합니다. 
cols = ['수출건수', '수출금액', '수입건수', '수입금액', '무역수지']
 # 정규화를 시켜야 할 수치형 컬럼들을 cols 변수에 담은 후, 
trade_Standardization= (trade[cols]-trade[cols].mean())/trade[cols].std()
 # 데이터에서 평균을 빼고, 표준편차로 나눠주도록 합니다
trade_Standardization.head()
 # 컬럼의 평균들을 보면 거의 0에 가깝고, 표준편차는 1에 가까운 것을 확인하실 수 있습니다

# 데이터 x를 min-max scaling 기법으로 정규화합니다. (표준화)
x_min_max = (x-x.min())/(x.max()-x.min())
x_min_max

# trade 데이터를 min-max scaling 기법으로 정규화합니다. 
trade[cols] = (trade[cols]-trade[cols].min())/(trade[cols].max()-trade[cols].min())
 # 데이터에서 최솟값을 빼주고, '최댓값-최솟값'으로 나눠줍니다
trade.head()

 # train 데이터와 test 데이터가 나눠져 있는 경우
train = pd.DataFrame([[10, -10], [30, 10], [50, 0]])
test = pd.DataFrame([[0, 1], [10, 10]])
print("👽 It's okay, no biggie.")

 # train 데이터를 정규화시켰던 기준 그대로 test 데이터도 정규화 시켜줘야 합니다
train_min = train.min()
train_max = train.max()
 # test를 min-max scaling할 때도 train 정규화 기준으로 수행
train_min_max = (train - train_min)/(train_max - train_min)
test_min_max =  (test - train_min)/(train_max - train_min) 

from sklearn.preprocessing import MinMaxScaler 
# scikit-learn의 StandardScaler, MinMaxScaler를 사용하는 방법
train = [[10, -10], [30, 10], [50, 0]]
test = [[0, 1]]
scaler = MinMaxScaler()
# scaler 는 fit 과 transform 메서드를 지니고 있습니다
scaler.fit_transform(train) # 훈련 데이터에는 fit_transform() 메서드를 적용
scaler.transform(test)      # 테스트 데이터에는 transform() 메서드를 적용

いちじねつコーディング


1-ホットコーディング:カテゴリ固有のバイナリプロパティを1、残りは0にする方法
機械学習または深さ学習フレームワークがカテゴリをサポートしていない場合は、1対1の熱符号化が必要です.
pandasでは、スタック内の可変変数を容易に作成するために、 get dummies関数 提供する
#trade 데이터의 국가명 컬럼 원본
print(trade['국가명'].head())  

# get_dummies를 통해 국가명 원-핫 인코딩
country = pd.get_dummies(trade['국가명'])
country.head()
# pd.concat 함수로 데이터프레임 trade와 country를 합쳐줍니다
trade = pd.concat([trade, country], axis=1)
trade.head()
# 필요 없어진 국가명 컬럼을 삭제해 주고 나면 trade는 우리가 원하는 데이터프레임
trade.drop(['국가명'], axis=1, inplace=True)
trade.head()

区間化


データを区間別に区間化(databinningまたは bucketing)
# salary 소득데이터
salary = pd.Series([4300, 8370, 1750, 3830, 1840, 4220, 3020, 2290, 4740, 4600, 
                    2860, 3400, 4800, 4470, 2440, 4530, 4850, 4850, 4760, 4500, 
                    4640, 3000, 1880, 4880, 2240, 4750, 2750, 2810, 3100, 4290, 
                    1540, 2870, 1780, 4670, 4150, 2010, 3580, 1610, 2930, 4300, 
                    2740, 1680, 3490, 4350, 1680, 6420, 8740, 8980, 9080, 3990, 
                    4960, 3700, 9600, 9330, 5600, 4100, 1770, 8280, 3120, 1950, 
                    4210, 2020, 3820, 3170, 6330, 2570, 6940, 8610, 5060, 6370,
                    9080, 3760, 8060, 2500, 4660, 1770, 9220, 3380, 2490, 3450, 
                    1960, 7210, 5810, 9450, 8910, 3470, 7350, 8410, 7520, 9610, 
                    5150, 2630, 5610, 2750, 7050, 3350, 9450, 7140, 4170, 3090])

salary.hist() # hist() 히스토그램 : 도수분포표를 그래프로 나타낸 것이다
# 연속적인 데이터를 구간을 나눠 분석할 때 사용하는 방법

bins = [0, 2000, 4000, 6000, 8000, 10000] # 구간을 2000씩으로 설정
ctg = pd.cut(salary, bins=bins) 
# cut 함수에 데이터와 구간을 입력하면 데이터(salary)를 구간(bins)별로 나눠줍니다
print('salary[0]:', salary[0]) 
print('salary[0]가 속한 카테고리:', ctg[0]) # 샐러리0이 속한 카테고리 찾아줌
tg.value_counts().sort_index() # 구간마다 몇개가 속해 있는지 알려줌
# (0, 2000]        12

# bins 옵션에 정수를 입력하면
ctg = pd.cut(salary, bins=6) 
# 최솟값에서 최댓값을 균등하게 bins 개수만큼 나눠줍니다
ctg.value_counts().sort_index() # (1531.93, 2885.0]    27

ctg = pd.qcut(salary, q=5) # 0       (3544.0, 4648.0] ...
# qcut은 구간을 일정하게 나누는 것이 아니라 데이터의 분포를 비슷한 크기의 그룹으로 나눠줌
print(ctg.value_counts().sort_index()) # (1539.999, 2618.0]    20 ...