일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 카트폴
- kaggle
- 정치인
- 리액트네이티브
- TeachagleMachine
- 강화학습
- selenium
- 크롤링
- 사이드프로젝트
- 앱개발
- Ros
- 데이터분석
- 전국국밥
- FirebaseV9
- 클론코딩
- redux
- coding
- 딥러닝
- python
- 조코딩
- pandas
- JavaScript
- 강화학습 기초
- 머신러닝
- expo
- ReactNative
- Instagrame clone
- clone coding
- React
- App
- Today
- Total
qcoding
[데이터 분석 시 유용한 기능 정리] - 필요부분 검색 본문
* 참고자료 : https://github.com/rickiepark/handson-ml3/blob/main/02_end_to_end_machine_learning_project.ipynb
1) 데이터 분석
1-1) 설정 - font 나 기타 설정 관련
-> 그래프 그릴 때 font설정하기
import matplotlib.pyplot as plt
plt.rc('font', size=14)
plt.rc('axes', labelsize=14, titlesize=14)
plt.rc('legend', fontsize=14)
plt.rc('xtick', labelsize=10)
plt.rc('ytick', labelsize=10)
import sys
# 코랩의 경우 나눔 폰트를 설치합니다.
if 'google.colab' in sys.modules:
!sudo apt-get -qq -y install fonts-nanum
import matplotlib.font_manager as fm
font_files = fm.findSystemFonts(fontpaths=['/usr/share/fonts/truetype/nanum'])
for fpath in font_files:
fm.fontManager.addfont(fpath)
# 나눔 폰트를 사용합니다.
import matplotlib
matplotlib.rc('font', family='NanumBarunGothic')
matplotlib.rcParams['axes.unicode_minus'] = False
1-2) Colab에서 실제파일이나 url에 있을 때 파일 불러오기 (tgz -> csv로 압출 풀어서 풀러오기)
-> 파일이나 url에 있을 경우 받아서 압출풀어서 dataframe으로 불러옴
from pathlib import Path
import pandas as pd
import tarfile
import urllib.request
def load_housing_data():
tarball_path = Path("datasets/housing.tgz") ### 이미 파일이 해당 경로에 있을경우
if not tarball_path.is_file(): ## 파일 없을때
Path("datasets").mkdir(parents=True, exist_ok=True) ## 경로에 폴더 추가함
url = "https://github.com/ageron/data/raw/main/housing.tgz" ## url을 통해서
urllib.request.urlretrieve(url, tarball_path) ## tgz 파일을 받아옴
with tarfile.open(tarball_path) as housing_tarball: ## tgz 파일을 열어서 불러옴
housing_tarball.extractall(path="datasets") ## datasets 폴더에 압축을 품
return pd.read_csv(Path("datasets/housing/housing.csv")) ### 해당 path에 csv 파일을 불러옴
housing = load_housing_data()
1-3) 필터링
-> null 값이 있는 row를 조회 시 사용함.
df.loc[df.isnull().any(axis=1)]
-> null 값이 있는 columns 조회시 사용함.
df.columns[df.isnull().any()]
-> value_counts bins 사용 -> 범위별로 데이터를 count 할 수 있음
df['total_bill'].value_counts(bins=5)
-> 동일한 데이터 타입의 컬럼만 선택하기
수치형 / 범주형의 데이터를 분류할 때 유용하게 사용할 수 있음
위의 데이터 형태를 가질 때 incldue안에는 포함해야 되는 데이터 타입을 쓰고
df.select_dtypes(include=['float','int']).columns
exclude에는 포함하지 말아야 될 데이터 타입을 써준다.
df.select_dtypes(exclude=['float','int']).columns
-> 특정 문자가 포함된 데이터 필터링 하기
특정 칼럼내에 특정 문자가 포함되어 있는 지 여부를 확인하여 필터링함.
df_len = len(df)
df_fil = df.loc[df['time'].str.contains('Di')] ### 특정 문자를 포함하여 필터링
df_fil_len = len(df_fil)
print(df_len, df_fil_len)
df_fil.head(5)
-> 결측값 채우기
보통 fillna를 이용하여 결측값을 채운다. interpolation을 사용해서 채우는 채울 수 있음.
### 수치형 - interpolation
df['age']=df['age'].interpolate(method='linear',limit_direction='forward') ## linear
df['age']=df['age'].interpolate(method='nearest',limit_direction='forward') ## nearest
### 범주형 - interpolation
df['deck']=df['deck'].interpolate(method='pad',limit_direction='forward') ## pad 는 fillna의 'ffill'과 동일함, 앞의 값으로 채움
-> map / apply 사용법
① map ( 단일 칼럼 )
### 1) custom 함수 사용
def chk_male(val):
if val == "Male":
return 1
elif val =="Female":
return 0
df['smoker_value_1'] = df['sex'].map(chk_male)
df['smoker_value_2'] = df['sex'].map({"Male":1 , "Female":0})
### 2) lambda 함수 사용
df['smoker_value_3'] = df['sex'].map(lambda val:1 if val=='Male' else 0)
② apply (단일 & 여러개 칼럼 사용가능)
#### 1) custom 함수
def chk_male_smoker(row,weights_):
if row['sex']=="Male" and row['smoker']=='Yes':
return 1 * weights_
else:
return 0
weights_ = 2
df['male_smoker_value_1'] = df.apply(chk_male_smoker, args=(weights_,) ,axis=1) ########### 여기서 args = (,) comma 써줘야함!!!
#### 2) lambda 함수
df['male_smoker_value_2'] = df.apply(lambda row, weights_: 1 * weights_ if row['sex'] == 'Male' and row['smoker'] == 'Yes' else 0, args=(weights_,), axis=1)
### 3) return 2개 이상일 때
def chk_male_smoker(row,weights_):
if row['sex']=="Male" and row['smoker']=='Yes':
return 1 * weights_ , 1
else:
return 0 , 0
weights_ = 2
df[['male_smoker_value_3','male_smoker_value_4']] = df.apply(chk_male_smoker, args=(weights_,) ,axis=1, result_type='expand') ########### 여기서 args = (,) comma 써줘야함!!!
1-4) group by 사용시 2가지 방법
### transform을 활용하여 기존의 dataFrame에 필요한 항목을 추가하는 것
import numpy as np
#### transform 활용하여 기존의 df에 이어붙임
df['ocean_proximity'].value_counts()
### ocean 등급에 따른 소유주의 나이 평균
# df['age_avg_by_ocean_proxi'] = df.groupby(['ocean_proximity'])['housing_median_age'].transform('mean')
df['age_avg_by_ocean_proxi'] = df.groupby(['ocean_proximity'])['housing_median_age'].transform(lambda x:np.mean(x))
df
위에서 lambda 함수를 사용가능함.
### group이라는 새로운 data frame을 만들고 기존 dataframe에 merge함
1) group dataframe 생성
### 새로운 dataFrame 생성
group = df.groupby(['ocean_proximity'], as_index=False).agg(
# mean_avg = ('housing_median_age', lambda x:np.mean(x))
mean_avg = ('housing_median_age', 'mean')
)
group
여기서도 lambda 함수 사용가능함.
2) 기존 dataframe에 merge
-> 위의 group에 있는 mean_avg 이름으로 합쳐
### group 된거 원래 dataFrame으로 merge
df_merge = df.merge(group, how='left', on=['ocean_proximity'])
df_merge
1-5) 분포가 많은 수치형 변수의 경우 몇개 형태의 범주형 데이터로 처리하는 법
-> qcut / cut을 사용해서 몇개의 범주로 바꿔줌.
## cut 은 내가 범위를 지정하고 그 범위에 맞게 그륩핑해
housing["income_cat"] = pd.cut(housing["median_income"],
bins=[0., 1.5, 3.0, 4.5, 6., np.inf],
labels=[1, 2, 3, 4, 5])
housing["income_cat"].value_counts().sort_index(ascending=False)
sns.histplot(x='income_cat', data=housing)
## qcut 은 범위는 알아서 정해지고, 각 label에 수량이 비슷하게 나눠짐
housing["income_cat"] = pd.qcut(housing["median_income"],5,labels=[1, 2, 3, 4, 5])
housing["income_cat"].value_counts().sort_index(ascending=False)
sns.histplot(x='income_cat', data=housing)
1-6) pivot table
-> pivot table을 사용할 때, values / index / columns에 여러개의 값을 넣을 수 있음
aggfunc의 기본은 mean값으로 나타내는 데 aggfunc= count / mean/ max 등을 사용하여 값을 바꿀 수 있음.
margins= True를 하면 전체 ALL의 합계를 집계해줌.
df.pivot_table(values=['survived','fare'],
index='sex',
columns='pclass',
aggfunc={'survived':np.mean, 'fare':np.sum},
fill_value=0,
margins=True)
1-7) 시간 데이터 사용할 때
-> 아래와 같이 year, month, day가 따로 있을 때 결합할 수 있음.
이때 year / month / day가 다 있어야 에러가 안나고 합칠 수 있음.
## day가 없을 경우 임의로 day 값을 넣어줌
## df['day'] = 1
df['date'] = pd.to_datetime(df[['year','month','day']])
df['date_month'] = df.apply(lambda row:str(row['year'])+"-"+str(row['month']),axis=1)
df['date_fil'] = pd.to_datetime(df['date_month'])
위와 같이 apply를 써서 문자열 형태로 합칠 수 있음. 이 경우에 datetime을 사용하면 day값이 자동으로 1이 입력됨
2) 그래프
2-1) 상관관계 그래프 (Scatter matrix) 빨리 그리기
-> Corr를 이용하여 상관관계 그래프를 빨리 그리는 법 / 우리가 원하는 label에 대한 값을 넣어줌
corr_matrix = df.corr(numeric_only=True)
corr_matrix['median_house_value'].sort_values(ascending=False)
from pandas.plotting import scatter_matrix
import matplotlib.pyplot as plt
scatter_matrix(df[corr_matrix['median_house_value'].sort_values(ascending=False).index[1:5]],figsize=(12,8))
plt.show()
2-2) 그래프 저장하기 png 파일
--> save fig 함수를 이용하여 해당 위치 아래에 foler를 생성한 후 이미지 저장하기
def save_fig(fig_id, fig, tight_layout=True, fig_extension="png", resolution=300):
IMAGES_PATH = Path("images/this_save_path") #### 여기에 save 할 위치 지정함
IMAGES_PATH.mkdir(parents=True, exist_ok=True)
path = IMAGES_PATH / f"{fig_id}.{fig_extension}"
if tight_layout:
fig.tight_layout()
# Save the figure using the specified axis
fig.savefig(path, format=fig_extension, dpi=resolution)
위의 함수 사용 시 아래와 같이 subplots의 여러개 여부와 관계없이 fig를 넘겨서 저장함.
from pathlib import Path
import matplotlib.pyplot as plt
from pandas.plotting import scatter_matrix
# Assuming df and corr_matrix are defined earlier in your code
fig, axes = plt.subplots(nrows=2,ncols=1)
fig.set_size_inches(6, 3)
# scatter_matrix(df[corr_matrix['median_house_value'].sort_values(ascending=False).index[1:5]], ax=ax)
sns.scatterplot(x='longitude', y='latitude', data=df , ax=axes[0])
sns.barplot(x=df.index,y='ocean_proximity', data=df, ax=axes[1])
# Save the figure using the custom function
save_fig('subplots', fig)
2-3) 상관관계 그래프 예쁘게 그리기
fig, ax =plt.subplots()
housing.plot(kind="scatter", x="longitude", y="latitude", grid=True,
s=housing["population"] / 100, label="population",
c="median_house_value", cmap="jet", colorbar=True,
legend=True, figsize=(10, 7),ax=ax)
save_fig("housing_prices_scatterplot",fig) # extra code
plt.show()
import seaborn as sns
from pathlib import Path
import matplotlib.pyplot as plt
# Assuming df is your DataFrame
fig, ax = plt.subplots(figsize=(10, 7))
# Seaborn scatter plot
sns.scatterplot(data=housing, x="longitude", y="latitude", hue="median_house_value",
size=housing["population"] / 100, sizes=(20, 200), ax=ax)
# Additional settings
ax.set_title("Housing Prices Scatterplot")
ax.grid(True)
# ax.legend()
# Save the figure
save_fig("housing_prices_scatterplot", fig)
# Show the plot
plt.show()
2-4) 결측치 시각화하기
-> 결측값을 seaborn을 통해 시각화함. 아래의 그래프에서 하얀색의 부분이 결측값을 나타낸다.
import matplotlib.pyplot as plt
import seaborn as sns
fig, ax = plt.subplots()
fig.set_size_inches(11,3)
fig.patch.set_facecolor('xkcd:white')
### 결측값 시각화
sns.heatmap(df.isnull(),cbar=False)
3) 모델학습
3-1) 모델 학습 후 predict로 예측하기 전에 cross_val_score를 통해서 훈련 set으로 어느정도 확률인지 개선정도확인
--> cross_val_score를 사용하기
from sklearn.model_selection import cross_val_score
### 모델 학습
forest_clf = RandomForestClassifier(n_estimators=100, random_state=42)
forest_clf.fit(X_train, y_train)
### y_test 예측
X_test = preprocess_pipeline.transform(test_data)
y_pred = forest_clf.predict(X_test)
#### y_pred는 정답이없으므로 현재 model의 개선 정도를 확인할 때에는
####
## 회귀 일때
forest_scores = cross_val_score(forest_clf, X_train, y_train, cv=10)
forest_scores.mean()
### 분류 일때
forest_scores=cross_val_score(sgd_clf, X_train, y_train_5, cv=3, scoring="accuracy")
forest_scores.mean()
'Python 데이터분석' 카테고리의 다른 글
[데이터분석실습][다중분류_LR/XGB]공부 잘하는 것과 연관 된 연구 (0) | 2022.09.01 |
---|---|
[데이터분석실습][이진분류_LR/XGB]Heart Failure Prediction_kaggle (0) | 2022.08.13 |
[데이터분석실습][데이터전처리]스타벅스 고객 데이터 분석하기 (0) | 2022.08.06 |
[데이터분석 실습][데이터전처리]구글플레이스토어 데이터 분석 (1) | 2022.07.29 |
[데이터 분석실습]타이타닉 데이터 (0) | 2022.07.23 |