import lightgbm
import xgboost as xgb
from xgboost import XGBClassifier
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import xgboost as xgb
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import GradientBoostingClassifier, RandomForestClassifier
from sklearn.ensemble import BaggingClassifier
from sklearn.experimental import enable_hist_gradient_boosting
from sklearn.ensemble import HistGradientBoostingClassifier
from sklearn.ensemble import ExtraTreesClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import VotingClassifier
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score
from sklearn.ensemble import VotingClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import mean_squared_error
from sklearn.tree import plot_tree
from sklearn import metrics
import warnings
from lightgbm import LGBMClassifier
'''
Dimension Reduction
차원 축소
고차원(3차원 이상)은 직관적으로 상상하기 어렵다.
그래서 차원을 축소 시키는게 중요하다 .
1) 투영
2) 매니폴드 학습
''''''
PCA : 주성분 분석
-먼저 데이터에 가까운 초평면을 정의 한 다음, 데이터를 이 평면에 투영
-분산 보존 : 저 차원의 초평면에 훈련세트를 투영하기 전에 먼저 올바른 초평면을 선택해야한다 .
실선에 투영된 것은 분산을 최대로 보존하는 반면, 점선에 투영된 것은 분산을 매우 적게 유지
다중공선성 : 일반적으로 회귀 분석할때는
변수의 영향력을 파악할 때 다른 설명 변수들을 모두 일정하다고
생각한다. (독립이라고 가정)
하지만, 두 변수가 서로 영향을 주고 있다면
문제가 발생한다. 상관관계가 존재할 경우 갖다 버려야 된다 !
만약 --> 음주 운전을 할 확률을 예측 한다고 할 경우 ,
1.혈중 알코올 % , 2. 1주일에 몇번 음주 하는지 설정한다면
서로 상관관계가 겹치기때문에 제대로 된 예측이 되지 않는다
'''
warnings.filterwarnings('ignore')
df = pd.read_csv('./titanic/train.csv')
df_kg = pd.read_csv('./titanic/test.csv')
df1 = df.copy()
df1.set_index('PassengerId', inplace=True)
df_kg.set_index('PassengerId', inplace=True)
df1.drop(['Name'], axis=1, inplace=True)
df_kg.drop(['Name'], axis=1, inplace=True)
df_kg.Cabin.astype(str)
# 결측치 처리
df1.Cabin.fillna('N', inplace=True)
df1.Embarked.fillna('S', inplace=True)
df1.Age.fillna(df1.Age.median(), inplace=True)
df_kg.Cabin.fillna('N', inplace=True)
df_kg.Fare.fillna(df1.Fare.median(), inplace=True)
df_kg.Age.fillna(df1.Age.median(), inplace=True)
df1.Cabin = df1.Cabin.apply(lambda x:x[0])
df_kg.Cabin = df_kg.Cabin.apply(lambda x:x[0])
# 인코딩
og_columns = df1.columns[(df1.dtypes=='O')|(df1.dtypes=='category')|(df1.dtypes=='bool')]
for i in og_columns:
globals()[f'df1_{i}_encoder'] = LabelEncoder()
globals()[f'df1_{i}_encoder'].fit(df1[i])
globals()[f'df_kg_{i}_encoder'] = LabelEncoder()
globals()[f'df_kg_{i}_encoder'].fit(df_kg[i])
df1[i] = globals()[f'df1_{i}_encoder'].transform(df1[i])
df_kg[i] = globals()[f'df_kg_{i}_encoder'].transform(df_kg[i])
# X, y 분리
X = df1.drop('Survived', axis=1)
y = df1.Survived
# train, test 분리
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.1,random_state=12)
from sklearn.decomposition import PCA
#타이타닉 X데이터를 2차원으로 축소
pca = PCA(n_components=2)
X2D = pca.fit_transform(X)
result = pd.DataFrame(X2D)
result.columns = ['z1','z2']
result['y'] = y
result.plot(kind='scatter',x='z1',y='z2',cmap='viridis')
'''시각화를 할 경우, 2차원 축소를 사용한다 .'''
#2차원으로 축소한 상태에서 머신러닝 돌려보기 DecisionTree 사용 히기
dt_clf = RandomForestClassifier(criterion= 'gini', max_depth= 9, min_samples_split= 5, n_estimators= 100, random_state= 20)
dt_clf.fit(X2D,y)
print('점수',dt_clf.score(X2D,y))
#설명된 분산의 비율
#적절한 차원 수 선택 하기
pca = PCA()
pca.fit(X_train)
print(pca.explained_variance_ratio_)
cumsum = np.cumsum(pca.explained_variance_ratio_)
print(cumsum)
d = np.argmax(cumsum >=0.95) +1
PCA(n_components=d)
X2D = pca.fit_transform(X_train)
print(X2D.shape)
from sklearn.datasets import make_swiss_roll
X, t = make_swiss_roll(n_samples=1000, noise=0.2, random_state=42)
axes = [-11.5, 14, -2, 23, -12, 15]
fig = plt.figure(figsize=(6, 5))
ax = fig.add_subplot(111, projection='3d')
ax.scatter(X[:, 0], X[:, 1], X[:, 2], c=t, cmap=plt.cm.hot)
ax.view_init(10, -70)
ax.set_xlabel("$x_1$", fontsize=18)
ax.set_ylabel("$x_2$", fontsize=18)
ax.set_zlabel("$x_3$", fontsize=18)
ax.set_xlim(axes[0:2])
ax.set_ylim(axes[2:4])
ax.set_zlim(axes[4:6])
fig.savefig("swiss_roll_plot")
# plt.show()
plt.figure(figsize=(6,4))
plt.plot(cumsum, linewidth=3)
plt.axis([0, 100, 0, 1])
plt.xlabel("Dimensions")
plt.ylabel("Explained Variance")
plt.plot([d, d], [0, 0.95], "k:")
plt.plot([0, d], [0.95, 0.95], "k:")
plt.plot(d, 0.95, "ko")
plt.xlim(-1,15)
#plt.annotate("Elbow", xy=(65, 0.85), xytext=(70, 0.7),
# arrowprops=dict(arrowstyle="->"), fontsize=16)
plt.grid(True)
#save_fig("explained_variance_plot")
# plt.show()
'''전처리를 하고 레이블 인코딩을 한후, 변수들 전체간의 상관관계를 볼 수 있는데
머신러닝을 돌리기전에 상관관계가 높을 경우(0.8~0.9), 차원축소를 하고 진행 해야 한다.
''''''
압축을 위한 PCA
'''
pca = PCA(n_components=2)
X_reduced =pca.fit_transform(X_train)
X_recovered = pca.inverse_transform(X_reduced)
print(X_reduced.shape)
print(X_recovered.shape)
'''복원시 약간의 재구성 오차 발생
그러나 원본데이터와 비슷.
'''
'''랜덤 PCA
svd_solver 매개변수를 'randomized'로 지정하면 랜덤 PCA
확률적 알고리즘 사용으로 주성분에 대한 근사값을 빠르게 검색
'''
# rnd_pca =PCA(n_components=154,svd_solver="randomized")
# X_reduced = rnd_pca.fit_transform(X_train)
#기본값 auto
'''
1. auto 지정시, 자동으로 계산하여 랜덤으로 돌릴지 완전한 계산을 할 지 결정
2. 강제 계산시 full 옵션 지정
''''''
점진적 PCA
-대용량 데이터 메모리에 올리는 문제 해결
-훈련 데이터를 미니 배치로 나눠 한번에 하나씩 주입
-대용량 데이터 혹은 온라인으로 PCA 적용시 유리
'''
# from sklearn.decomposition import IncrementalPCA
# n_batches = 100
# inc_pca = IncrementalPCA(n_components=154)
# for X_batch in np.array_split(X_train, n_batches):
# inc_pca.partial_fit(X_batch)
# X_reduced = inc_pca.transform(X_train)
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
lda = LinearDiscriminantAnalysis()
lda.fit(X_train, y_train).transform(X_train)
print(lda.fit(X_train, y_train).score(X_test,y_test))
'''
비지도 학습 : 마케팅 분야에서 자주 쓰인다 .
클러스터링은 데이터에서 비슷한 객체를 한 그룹으로 묶는것 .
L2 DISTANCE = 유클리디안 거리(피타고라스)
K-means Clustering
1. K개의 포인트 만큼 좌표를 설정한다.
2. 반복 epoch=2 --> 2만큼 반복
3. 모든 점을 K 군집으로부터 가장 가까운 중심점에 할당
4. 각 클러스터의 중심 계산
단점 :
1.초기 포인트를 랜덤으로 지정하기 때문에 군집을 잘못 형성할 수 있다
2. 동그랗게 형성된 군집만 잘 맞추고 그외에는 ㅡㅡ;
3. 잘못된 데이터에 상당히 민감하다. (Noise 데이터 1개만 있을 경우에도 )
'''
#1. 타이타닉 Survived 제외
#2. X값으로 군집화 Kmeans
#3. 최적의 군집 개수는 몇 개 ? 실루엣 스코어
#4. 임의의 2개의 군집, Survived 비교 하기
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_samples, silhouette_score
kmeans = KMeans(n_clusters=8,
init='k-means++',
n_init =10,
max_iter=300,
tol=0.0001,
verbose=0,
random_state=None,
copy_x=True,
algorithm='lloyd',)
kmeans.fit(X)
'''
labels_ : 각 데이터 포인트가 속한 군집 중심점 레이블
cluster_centers_ : 각 군집 중심점 좌표. 이를 이용하면 군집 중심점 좌표가 어디인지 시각화할 수 있습니다.
n_iter_ : 수행된 이동 횟수
'''
#df_kg['Survived'] = kmeans.labels_
score_samples = silhouette_samples(X ,kmeans.labels_)
#silhouette_score가 높을 수록 좋은 군집의 수
average_score = silhouette_score(X ,kmeans.labels_)
print('점수',average_score)
print('score_samples.shape :',score_samples.shape)
print('score_samples :',score_samples)
print('kmeans.labels_ :',kmeans.labels_)
print('kmeans.cluster_centers_ :',kmeans.cluster_centers_)
print('kmeans.n_iter_ :',kmeans.n_iter_)
from sklearn.metrics import silhouette_samples
from matplotlib.ticker import FixedLocator, FixedFormatter
import matplotlib as mpl
kmeans_per_k = [KMeans(n_clusters=k, random_state=19).fit(X)
for k in range(1, 10)]
inertias = [model.inertia_ for model in kmeans_per_k]
silhouette_scores = [silhouette_score(X, model.labels_)
for model in kmeans_per_k[1:]]
plt.figure(figsize=(15, 30))
for k in range(2, 10):
plt.subplot(5, 2, k-1)
y_pred = kmeans_per_k[k-1].labels_
silhouette_coefficients = silhouette_samples(X, y_pred)
padding = len(X) // 30
pos = padding
ticks = []
for i in range(k):
coeffs = silhouette_coefficients[y_pred == i]
coeffs.sort()
color = mpl.cm.Spectral(i / k)
plt.fill_betweenx(np.arange(pos, pos + len(coeffs)), 0, coeffs,
facecolor=color, edgecolor=color, alpha=0.7)
ticks.append(pos + len(coeffs) // 2)
pos += len(coeffs) + padding
plt.gca().yaxis.set_major_locator(FixedLocator(ticks))
plt.gca().yaxis.set_major_formatter(FixedFormatter(range(k)))
if k in (3, 5):
plt.ylabel("Cluster")
if k in (5, 6):
plt.gca().set_xticks([-0.1, 0, 0.2, 0.4, 0.6, 0.8, 1])
plt.xlabel("Silhouette Coefficient")
else:
plt.tick_params(labelbottom=False)
plt.axvline(x=silhouette_scores[k - 2], color="red", linestyle="--")
plt.title("$k={}$".format(k), fontsize=16)
#save_fig("silhouette_analysis_plot")
# plt.show()
'''군집을 사용한 준지도 학습 '''
#군집의 또 다른 사용처는 레이블이 없는 샘플이 많고 레이블이 있는 샘플이 적을 때 사용
#타이타닉 학습 데이터의 개수를 50개로 제한
#나머지 학습 데이터의 레이블 삭제
#전체 학습 데이터세트를 kmeans로 20개의 군집화 진행
#각 센트로이드에서 가장 가까운
#100점 데이터 가져오기
answer_tit = pd.read_csv("./answer_tit.csv")
kg_up = answer_tit.copy()
a =4
new_rd2_dt = RandomForestClassifier(criterion= 'gini', max_depth= 9, min_samples_split= 5, n_estimators= 100, random_state= 20)
new_rd2_dt.fit(X_train[:a],y_train[:a])
new_rd2_pred= new_rd2_dt.predict(df_kg)
print('4개',accuracy_score(kg_up.Survived,new_rd2_pred))
# kg_up.set_index('PassengerId', inplace=True)
# kg_up.Survived.to_csv('kaggle_upload_asdasd_clf.csv')
k=4
kmeans=KMeans(n_clusters=k,random_state=20)
X_ts=kmeans.fit_transform(X_train)
an_swer=np.argmin(X_ts,axis=0)
X_ts_trn = X_train.iloc[an_swer]
y_ts_trn = y_train.iloc[an_swer]
#print(an_swer)
rt_semi = RandomForestClassifier(criterion= 'gini', max_depth= 9, min_samples_split= 5, n_estimators= 100, random_state= 20)
rt_semi.fit(X_ts_trn,y_ts_trn)
rt_pred = rt_semi.predict(df_kg)
print('대표군집 4개 예측 결과:',accuracy_score(kg_up.Survived,rt_pred))
'Python' 카테고리의 다른 글
Python - Regression(Ridge, LASSO, ELASTICNET) (0) | 2022.10.25 |
---|---|
Python - Regression 회귀 분석 (0) | 2022.10.24 |
Python - 모델 Stacking (0) | 2022.10.22 |
Python - XGB, HGBM 파라미터 튜닝 , 캐글 점수 (0) | 2022.10.21 |
Python - Grid Search Hyper parameter (0) | 2022.10.19 |