핸즈온 머신러닝[2] 머신러닝 프로젝트 처음부터 끝까지(2)
https://www.youtube.com/watch?v=NK-poIeR9JY&list=PLJN246lAkhQjX3LOdLVnfdFaCbGouEBeb&index=8
데이터 이해를 위한 탐색과 시각화
housing = strat_train_set.copy()
지리적 데이터 시각화
housing.plot(kind="scatter", x="longitude", y="latitude")
housing.plot.scatter(x="longitude", y="latitude")
plt.scatter(housing["longtitude"], housing["latitude"])
save_fig("bad_visualization_plot")
plot 함수에 kind 파라미터를 scatter로 주면 산점도를 그려줌
save_fig 함수는 이미지를 로컬에 저장
housing.plot(kind="scatter", x="longitude", y="latitude", alpha=0.1)
save_fig("better_visualization_plot")
alpha 함수: 밀집도에 따라 색을 다르게 함
housing.plot(kind="scatter", x="longitude", y="latitude", alpha=0.4,
s=housing["population"]/100, label="population", figsize=(10,7),
c="median_house_value", cmap=plt.get_cmap("jet"), colorbar=True,
sharex=False)
plt.legend()
save_fig("housing_prices_scatterplot")
s 파라미터: 그리는 원의 크기
c: color
cmap: colormap
colorbar: 오른쪽의 그림, 색 참고용
# Download the California image
images_path = os.path.join(PROJECT_ROOT_DIR, "images", "end_to_end_project")
os.makedirs(images_path, exist_ok=True)
DOWNLOAD_ROOT = "https://raw.githubusercontent.com/ageron/handson-ml2/master/"
filename = "california.png"
print("Downloading", filename)
url = DOWNLOAD_ROOT + "images/end_to_end_project/" + filename
urllib.request.urlretrieve(url, os.path.join(images_path, filename))
위의 산점도를 실제 지도와 매핑하기 위해 이미지를 로컬에 저장
import matplotlib.image as mpimg
california_img=mpimg.imread(os.path.join(images_path, filename))
ax = housing.plot(kind="scatter", x="longitude", y="latitude", figsize=(10,7),
s=housing['population']/100, label="Population",
c="median_house_value", cmap=plt.get_cmap("jet"),
colorbar=False, alpha=0.4)
plt.imshow(california_img, extent=[-124.55, -113.80, 32.45, 42.05], alpha=0.5,
cmap=plt.get_cmap("jet"))
plt.ylabel("Latitude", fontsize=14)
plt.xlabel("Longitude", fontsize=14)
prices = housing["median_house_value"]
tick_values = np.linspace(prices.min(), prices.max(), 11)
cbar = plt.colorbar(ticks=tick_values/prices.max())
cbar.ax.set_yticklabels(["$%dk"%(round(v/1000)) for v in tick_values], fontsize=14)
cbar.set_label('Median House Value', fontsize=16)
plt.legend(fontsize=16)
save_fig("california_housing_prices_plot")
plt.show()
corr_matrix = housing.corr()
corr() 함수를 통해 상관계수 행렬을 얻을 수 있음
corr_matrix["median_house_value"].sort_values(ascending=False)
median_house_value를 기준으로 증가하지 않는 순으로 정렬 (non-ascending order)
# from pandas.tools.plotting import scatter_matrix # 옛날 버전의 판다스에서는
from pandas.plotting import scatter_matrix
attributes = ["median_house_value", "median_income", "total_rooms",
"housing_median_age"]
scatter_matrix(housing[attributes], figsize=(12, 8))
save_fig("scatter_matrix_plot")
산점도 행렬 그림
자기 자신과의 관계는 산점도가 아니라 히스토그램으로 표시됨
housing.plot(kind="scatter", x="median_income", y="median_house_value",
alpha=0.1)
plt.axis([0, 16, 0, 550000])
save_fig("income_vs_house_value_scatterplot")
특성 조합으로 실험
housing["rooms_per_household"] = housing["total_rooms"]/housing["households"]
housing["bedrooms_per_room"] = housing["total_bedrooms"]/housing["total_rooms"]
housing["population_per_household"]=housing["population"]/housing["households"]
새로운 특성들을 새로운 열을 추가
corr_matrix = housing.corr()
corr_matrix["median_house_value"].sort_values(ascending=False)
housing.plot(kind="scatter", x="rooms_per_household", y="median_house_value",
alpha=0.2)
plt.show()
rooms_per_household 산점도
housing.describe()
머신러닝 알고리즘을 위한 데이터 준비
housing = strat_train_set.drop("median_house_value", axis=1) # 훈련 세트를 위해 레이블 삭제
housing_labels = strat_train_set["median_house_value"].copy()
타깃값은 훈련셋에서 제외 housing_labels로 따로 복사해놓음
sample_incomplete_rows = housing[housing.isnull().any(axis=1)].head()
sample_incomplete_rows
null인 값이 하나라도 있는 경우를 뽑아서 그중 앞의 다섯개를 보여줌
sample_incomplete_rows.dropna(subset=["total_bedrooms"]) # 옵션 1
sample_incomplete_rows.drop("total_bedrooms", axis=1) # 옵션 2
median = housing["total_bedrooms"].median()
sample_incomplete_rows["total_bedrooms"].fillna(median, inplace=True) # 옵션 3
dropna: null 값이 포함된 행 또는 열을 drop
옵션 3번은 total_bedrooms 특성에서 null 값인 행들의 값을 중앙값으로 바꾸어주었다.
from sklearn.impute import SimpleImputer
imputer = SimpleImputer(strategy="median")
housing_num = housing.drop("ocean_proximity", axis=1)
# 다른 방법: housing_num = housing.select_dtypes(include=[np.number])
ocean_proximity가 수치형 특성이 아니므로 drop한다.
imputer.fit(housing_num)
# SimpleImputer(strategy='median')
imputer.statistics_
housing_num.median().values
X = imputer.transform(housing_num)
훈련 세트를 변환
housing_tr = pd.DataFrame(X, columns=housing_num.columns,
index=housing_num.index)
housing_tr.loc[sample_incomplete_rows.index.values]
imputer.strategy
housing_tr.head()
범주형 입력 특성인 ocean_proximity을 전처리
housing_cat = housing[["ocean_proximity"]]
housing_cat.head(10)
from sklearn.preprocessing import OrdinalEncoder
ordinal_encoder = OrdinalEncoder()
housing_cat_encoded = ordinal_encoder.fit_transform(housing_cat)
housing_cat_encoded[:10]
Ordinal Encoder 함수는 문자열 데이터를 순서대로 정수형 데이터로 바꾸어줌
ordinal_encoder.categories_
이러한 숫자가 의미를 가지지는 않음
from sklearn.preprocessing import OneHotEncoder
cat_encoder = OneHotEncoder()
housing_cat_1hot = cat_encoder.fit_transform(housing_cat)
housing_cat_1hot
하나의 특성을 다섯개로 만들어서 해당되면 1 아니면 0으로 표시되게끔 함
OneHotEncoder는 기본적으로 희소 행렬을 반환함 필요하면 toarray() 메서드를 사용해 밀집 배열로 변환할 수 있음
housing_cat_1hot.toarray()
from sklearn.base import BaseEstimator, TransformerMixin
# 열 인덱스
rooms_ix, bedrooms_ix, population_ix, households_ix = 3, 4, 5, 6
class CombinedAttributesAdder(BaseEstimator, TransformerMixin):
def __init__(self, add_bedrooms_per_room=True): # *args 또는 **kargs 없음
self.add_bedrooms_per_room = add_bedrooms_per_room
def fit(self, X, y=None):
return self # 아무것도 하지 않습니다
def transform(self, X):
rooms_per_household = X[:, rooms_ix] / X[:, households_ix]
population_per_household = X[:, population_ix] / X[:, households_ix]
if self.add_bedrooms_per_room:
bedrooms_per_room = X[:, bedrooms_ix] / X[:, rooms_ix]
return np.c_[X, rooms_per_household, population_per_household,
bedrooms_per_room]
else:
return np.c_[X, rooms_per_household, population_per_household]
attr_adder = CombinedAttributesAdder(add_bedrooms_per_room=False)
housing_extra_attribs = attr_adder.transform(housing.to_numpy())
추가 특성을 위한 사용자 정의 변환기
housing_extra_attribs = pd.DataFrame(
housing_extra_attribs,
columns=list(housing.columns)+["rooms_per_household", "population_per_household"],
index=housing.index)
housing_extra_attribs.head()
넘파이 배열이므로 열 이름이 없기 때문에 Dataframe으로 복원할때 다음과 같이 column을 추가
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
num_pipeline = Pipeline([
('imputer', SimpleImputer(strategy="median")),
('attribs_adder', CombinedAttributesAdder()),
('std_scaler', StandardScaler()),
])
housing_num_tr = num_pipeline.fit_transform(housing_num)
housing_num_tr
from sklearn.compose import ColumnTransformer
num_attribs = list(housing_num)
cat_attribs = ["ocean_proximity"]
full_pipeline = ColumnTransformer([
("num", num_pipeline, num_attribs),
("cat", OneHotEncoder(), cat_attribs),
])
housing_prepared = full_pipeline.fit_transform(housing)
housing_prepared
문제
- Plot 함수를 사용해서 산점도를 그리는 방법 두 가지를 설멍하시오. 그리고 income 이라는 dataframe에 age를 x축으로, height를 y축으로 하여 산점도를 그리는 코드를 작성하시오. 단, 데이터프레임은 이미 앞에서 코드가 작성되어있다고 가정한다.
- 앞에서 작성한 코드에 weight에 따라 산점도의 원의 크기를 조절할 수 있는 부분을 추가하여라. 또한 ‘jet’ 컬러맵을 사용해서 spending에 따라 color를 입히는 부분을 추가하여라.
- 피어슨 상관계수의 범위가 무엇이며 피어슨 상관계수가 양의 값을 가질 때와 음의 값을 가질 때, 0일때의 각각 의미하는 것이 무엇인지 작성하시오
- dropna 함수를 사용해서 데이터프레임의 null 값이 있는 행이나 열을 제거하는 방법을 소개하시오
- 판다스에서는 데이터프레임에 null 값이 있는 경우 이를 채워넣을 수 있는 함수를 제공한다. 이 함수의 이름은?
- 데이터프레임의 범주형 특성을 전처리 과정에서 수치형으로 변환하려 할때 하나의 범주형 특성을 여러개의 수치형 특성으로 바꾸어 해당되면 1, 해당되지 않으면 0으로 표시되게끔 하는 사이킷런의 함수는?