'Python'에 해당되는 글 17건
-
[Python] 비지도 학습 - 군집분석2019.09.04 -
[Python] PCA(주성분 분석)2019.09.03
-
[Python] Cross-validation + Grid Search2019.08.30 1 -
[Python] 분류분석 - logistic regression2019.08.28 -
[Python] LinearRegression(수치예측) - Lasso2019.08.28 -
[Python] LinearRegression(수치예측) - Ridge2019.08.28 -
[Python] LinearRegression(수치예측)2019.08.28 -
[Python] DecisionTree2019.08.27 -
[Python] k-nearest neighbor 예제2019.08.26 -
주소록 관리 프로그램.py2019.07.24
[Python] 비지도 학습 - 군집분석
[K-Means Clustering]
* 이 알고리즘은 비지도 학습의 가장 간단하면서 널리 사용하는 군집 기법이다.
[과정]
-
- 데이터의 특정 영역을 대표하는 클러스터 중심(cluster center)를 찾는다.
-
- 데이터 포인트를 가장 가까운 클러스터 중심에 할당하고,
-
- 새로 할당된 포인트를 포함한 평균값으로 클러스터 중심을 다시 지정.
-
- 클러스터에 할당되는 데이터 포인트에 변화가 없을 때 알고리즘 종료.
[단점]
-
계산 및 사용이 간단하여 널리 쓰이나, 클러스터의 개수를 지정해야 하므로, 선택에 어려움이 있을 수 있다.
--> 어느정도 데이터의 갯수에 대해 짐작하고 있어야 한다. 그래야 군집을 몇 개 넣을지 알 수 있음.
※ 시각화를 사용해서 데이터를 짐작할 수 있다. (PCA)
- 참고 : 클러스터링(Clustering)은 주어진 데이터 집합을 유사한 데이터들의 그룹으로 나누는 것이며, 예측 문제와 달리 특정한 독립변수와 종속변수의 구분도 없고, 학습을 위한 목표값도 필요로 하지 않는 비지도 학습이다.
from sklearn import datasets
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
import numpy as np
from sklearn.model_selection import train_test_split
import seaborn as sns
## 1. make_blobs toy data
X, y = datasets.make_blobs(random_state = 1)
kmeans = KMeans(n_clusters = 3) # 3개의 클래스를 나타내는 데이터를 만들어 줌.
kmeans.fit(X)
## 2. checking labels
kmeans.labels_
## 3. X predict
kmeans.predict(X)
## 4. scatter graph
%matplotlib inline
plt.scatter(X[:,0], X[:,1],
c = kmeans.labels_, marker = 'o', s = 10)
plt.scatter(kmeans.cluster_centers_[:,0],
kmeans.cluster_centers_[:,1],
c = ['r', 'k', 'b'], marker = '^', s = 50)
plt.show()
## k = 5
kmeans5 = KMeans(n_clusters = 5) # 5개의 클래스를 나타내는 데이터를 만들어 줌.
kmeans5.fit(X)
assign = kmeans5.labels_
# 시각화
%matplotlib inline
plt.scatter(X[:,0], X[:,1],
c = assign, marker = 'o', s = 10)
plt.scatter(kmeans5.cluster_centers_[:,0],
kmeans5.cluster_centers_[:,1],
c = ['r', 'k', 'b', 'gray', 'orange'], marker = '^', s = 50)
plt.show()


- K 의 값을 변경했을 때 결과는 위의 그래프와 같다. 여기서 적합한 k의 값을 찾기 위해서는 PCA를 사용하여 데이터의 형태가 어떻게 되어 있는지 판단하고 군집화 진행하는 것을 추천
[병합 군집]
- 시작할 때, 각각의 포인트 하나하나가 클러스터로 지정됨
- 종료 조건을 만족할 때까지 가장 비슷한 두 클러스터를 합쳐 나간다.
- 사이킷런의 종료 조건은 클러스터 개수
- linkage옵션에서 가장 비슷한 클러스터를 측정하는 방법 지정
- ward: 기본값인 ward연결은 클로스터의 분산을 가장 작게 증가시키는 두 클러스터를 합침
- average: 클러스터 포인트 사이의 평균 거리가 가장 짧은 두 클러스터 병합
- complete: 클러스터 포인트 사이의 최대 거리가 가장 짧은 두 클러스터 병합
- 계층적 클러스터링 : 군집 하나의 데이터 샘플을 하나의 클러스터로 보고 가장 유사도가 높은 클러스터를 합치면서 클러스터 갯수를 줄여 가는 방법을 말한다.
1. Agglomerative Clustering : scikit-learn 패키지
from sklearn.cluster import AgglomerativeClustering
from sklearn import datasets
import matplotlib.pyplot as plt
X, y = datasets.make_blobs(random_state = 1)
agg = AgglomerativeClustering(n_clusters = 3)
assign = agg.fit_predict(X)
%matplotlib inline
fig, ax = plt.subplots()
scatter = ax.scatter(X[:,0], X[:,1],
c = assign, marker="o", s=10)
ax.legend(*scatter.legend_elements(),
loc = 'lower right', title = 'classes')

2. 덴드로그램(dendrogram) 사용 : SciPy 패키지 -> 결과를 시각화 해줌
from scipy.cluster.hierarchy import dendrogram, ward
import seaborn as sns
X,y = datasets.make_blobs(random_state=0, n_samples=12)
linkage_array = ward(X) # 분산을 최소화하는 방향으로 클러스터 함
dendrogram(linkage_array) # 위계를 가지는 형태로 만들어줌
ax = plt.gca()
bounds = ax.get_xbound()
ax.plot(bounds, [7.25, 7.25], '--', c='k')
ax.plot(bounds, [4, 4], '--', c='k')
ax.text(bounds[1], 7.25, 'two clusters', va='center', fontdict={'size':15})
ax.text(bounds[1], 4, 'three clusters', va='center', fontdict={'size':15})
plt.xlabel('sample No.')
plt.ylabel('cluster distance')

[DBSCAN]
- density-based spatial clustering of applications with nois
- 클러스터의 개수를 미리 정할 필요가 없음
- 복잡한 형상도 찾을 수 있으며, 어떤 클래스에도 속하지 않는 포인트를 비교적 잘 구분해낸다
- 병합군집, k-mean 보다는 느림
<방법>
- 특성 공간에서 가까이 있는 데이터가 많은, 밀도가 높은 지역의 포인트를 찾음
- 데이터 밀집 지역이 한 클러스터를 구성하며, 비교적 비어 있는 지역을 경계로 다른 클러스터와 구분된다는 아이디어
- min_sample, eps 2개의 매개변수
- 한 데이터 포인트에서 eps 거리 안에 데이터가 min_samples 만큼 있으면, 이 데이터 포인트를 핵심 샘플로 분류
- eps 거리 안에 min_samples보다 데이터가 적으면 잡음으로 분류
- 시작할 때는 모자이크 포인트 선택
from sklearn.cluster import DBSCAN
from sklearn import datasets
import matplotlib.pyplot as plt
X,y = datasets.make_blobs(random_state=0, n_samples=12)
dbscan = DBSCAN()
clusters = dbscan.fit_predict(X)
print("cluster label:{}".format(clusters))
# output : cluster label:[-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1]
# 해석 : 전부다 잡음이다 클러스터로 분류되지 않았다. 군집으로 분류되지 않았다.
# 그래프 확인(defualt)
%matplotlib inline
plt.scatter(X[:,0],X[:,1],c=clusters, marker = 'o',s=10)
dbscan1 = DBSCAN(min_samples=2, eps=2)
clusters1 = dbscan1.fit_predict(X)
print("cluster label:{}".format(clusters1))
# output : cluster label:[0 1 1 1 1 0 0 0 1 0 0 0]
# 해석 : 0으로 바뀐 두개가 군집화가 된 것을 확인 할 수 있음
# 그래프 확인(min_samples=2, eps=2)
%matplotlib inline
plt.scatter(X[:,0],X[:,1],c=clusters2, marker = 'o',s=10)


- 위 두개의 그래프를 확인해보면 default 그래프보다 매개변수를 조절한 그래프에서 군집화가 발생했다.
- min_sample의 수를 줄이, eps(거리)를 늘린 결과라고 생각하면 된다.
지금까지 본 군집방식에 있어 눈으로 확인하기 위해 다음을 시도해보았다.
from sklearn.metrics.cluster import adjusted_rand_score
from sklearn.preprocessing import StandardScaler
import numpy as np
X, y = datasets.make_moons(n_samples=200, noise = 0.05, random_state=0) # 초승달 데이터 -> 그래프가 초승달로 나옴
# 평균이 0, 분산이 1이 되도록 표준화
scaler = StandardScaler()
scaler.fit(X)
X_scaled = scaler.transform(X)
fig, axes = plt.subplots(1,4,figsize=(15,3),
subplot_kw={'xticks':(), 'yticks':()})
# 사용할 알고리즘 모델의 리스트 작성
algorithms = [KMeans(n_clusters=2), AgglomerativeClustering(n_clusters=2),
DBSCAN()]
# randomly assign에서 ARI=0인 그래프 작성 위해 무작위 클러스터 생성
random_state = np.random.RandomState(seed=0) # 랜덤넘버 생성기인 랜덤함수들을 포함하는 클래스
random_clusters = random_state.randint(low=0,high=2,size=len(X)) # 0 부터 2사이의 무작이 난수 생성
# 위에서 생성한 무작위 클러스터 plotting
axes[0].scatter(X_scaled[:,0],X_scaled[:,1], c=random_clusters, s=60, edgecolors = 'b')
axes[0].set_title("randomly assign - ARI: {:.2f}".format(adjusted_rand_score(y, random_clusters)))
# 3가지 군집 알고리즘 적용한 결과 plotting
for ax, algorithm in zip(axes[1:], algorithms):
clusters = algorithm.fit_predict(X_scaled)
ax.scatter(X_scaled[:,0], X_scaled[:,1], c=clusters,
s=60, edgecolors = 'b')
ax.set_title("{} - ARI: {:.2f}".format(algorithm.__class__.__name__,
adjusted_rand_score(y,clusters)))

- 그래프를 확인하면 DBSCAN 이 가장 잘 군집화 한 것이라고 생각할 수 있다. 하지만 더 확실하게 하기 위해서는 평가지표를 통한 확인이 필요하다. 이것은 다음 장에서 설명하겠습니다.
'Code > 머신러닝 in Python' 카테고리의 다른 글
| [Python] openCV 이용한 얼굴인식 (0) | 2019.09.03 |
|---|---|
| [Python] PCA(주성분 분석) (0) | 2019.09.03 |
| [Python] Cross-validation + Grid Search (1) | 2019.08.30 |
| [Python] Grid Search (0) | 2019.08.30 |
| [Python] Cross-validation(교차검증) (1) | 2019.08.30 |
[Python] PCA(주성분 분석)
Principal Component Analysis(PCA, 주성분 분석)
-
주성분 분석은 차원축소를 위해 사용됨 -> 고차원의 데이터를 저차원의 데이터로 변환
- 목적
- 차원(dimension)을 감소시켜 해석을 용이하게 하고, 시각화에 도움
- 기대효과
- 통계 : 적은 수의 특성으로 특정 현상을 설명
- 머신러닝 : 모델 성능 강화
- 목적
-
개념
- 여러개의 양적 변수들 사이의 분선-공분산 관계를 이용하여, 변수들의 선형결합으로 표시되는 주성분을 찾음(축의 개념)
- 2-3개의 주성분으로 전체 분산(variance)의 대부분을 설명하고자 하는 다변량 분석법
- 원 데이터의 손실을 최소화하면서 데이터를 잘 설명할 수 있는 변수들의 선형 조합을 찾는 것이 목표
- 라면 데이터를 이용한 PCA()
import pandas as pd
import numpy as np
from sklearn import datasets
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler
lamen = dict({'name':['쇠고기라면','해물라면','얼큰라면','떡라면','짬뽕라면','만두라면','치즈라면','된장라면','볶음라면','김치라면'],
'noodle':[2,1,5,2,3,4,4,1,3,5],
'bowl':[4,5,3,2,5,3,4,2,3,5],
'soup':[5,1,4,3,5,2,3,1,2,3]})
lamen
lamen1 = pd.DataFrame(lamen)
lamen1

- 데이터 프레임으로 변경하면 위와 같은 표가 나오게 된다. (면, 그릇, 국물에 대한 수치)
# 1. 데이터 분리
lamenEval = lamen1[['noodle','bowl','soup']]
lamenName = lamen1['name']
# 2. 스케일러로 값 변환
# scaling using StandardScaler
scaler = StandardScaler()
scaler.fit(lamenEval.values)
lamen_scaled = scaler.transform(lamenEval.values)
lamen_scaled.shape
# (10,3)
# 3. PCA 모델링
# - PCA.fit() : 주성분 찾음
# - PCA.transform() : 새로운 주성분으로 데이터 변환
# PCA modelling
from sklearn.decomposition import PCA
pca_lamen = PCA()
pca_lamen.fit(lamen_scaled)
# data transform
X_pca_lamen = pca_lamen.transform(lamen_scaled)
# look into data shape
print("original data : {}".format(str(lamen_scaled.shape)))
print("transform data : {}".format(str(X_pca_lamen.shape)))
# original data : (10, 3) transform data : (10, 3)
- 사이킷런에서 제공하는 PCA를 호출하여 적용을 시켰을 때 결과르 확인하면 전과 후의 데이터 형태가 같은 것을 확인할 수있다.
pca_lamen.components_
# output
array([[-0.571511 , -0.52211611, -0.63306393],
[-0.60447096, 0.78960694, -0.105526 ],
[-0.5549685 , -0.32235949, 0.76687308]])
- PCA 모델에 의해 산출된 값을 보면 --> pca_lamen.components_
- 첫 행부터 각 pc1, pc2, pc3 을 의미하며, 열은 각각 noodle, bowl, soup를 의미함
- 산출한 특성별 주성분 요소 값과 특성들의 평가 스코어를 이용하여, 역산을 해보고 PCA 모델링을 통해 변환된 최종 데이터와 일치하는지 확인해보세요
# PCA 1,2,3 에 대한 변환 스코어
pc1=0
pc2=0
pc3=0
for j in range(len(pca_lamen.components_)):
pc1 += pca_lamen.components_[0][j] * lamen_scaled[:,j] # 계수 3개에 있어서 스케일된 모든 열을 다 곱하고 더한 것 = pc1
pc2 += pca_lamen.components_[1][j] * lamen_scaled[:,j]
pc3 += pca_lamen.components_[2][j] * lamen_scaled[:,j]
pc1 = pc1.reshape(10,1)
pc2 = pc2.reshape(10,1)
pc3 = pc3.reshape(10,1)
np.round(np.hstack((pc1,pc2,pc3)),3) == np.round(X_pca_lamen,3)

- 결과가 모두 True로 pca_lamen.components_의 값들과 스케일링 된 lamen_scaled 데이터와 곱하고 더하면 PCA의 결과인 X_pca_lamen 과 데이터가 같은 것을 확인할 수 있다.
- 시각적으로 확인하고 싶을 때
def biplot2(score, coeff, label, pcax, pcay, labels = None):
pca1=pcax-1
pca2=pcay-1
ㅇ xs = score[:,pca1]
ys = score[:,pca2]
n=score.shape[1]
scalex = 1.0/(xs.max() - xs.min())
scaley = 1.0/(ys.max() - ys.min())
for i in range(len(xs)):
plt.scatter(xs[i]*scalex, ys[i]*scaley)
plt.annotate(label.iloc[i], xy=(xs[i]*scalex, ys[i]*scaley), ha='right')
for i in range(n):
plt.arrow(0, 0, coeff[i,pca1], coeff[i,pca2], color='r', alpha=1)
if labels is None:
plt.text(coeff[i,pca1]*1.15, coeff[i,pca2]*1.15, "Var"+str(i+1), color='g', ha = 'center', va='center')
else:
plt.text(coeff[i,pca1]*1.15, coeff[i,pca2]*1.15, labels[i], color='g', ha='center', va='center', size=15)
plt.xlim(-0.8, 0.75)
plt.ylim(-1,1)
plt.xlabel("PC{}".format(pcax))
plt.ylabel("PC{}".format(pcay))
plt.grid()
##한글 폰트 설정
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
font_path="C:\\Windows\\Fonts\\malgun.ttf"
font_name=fm.FontProperties(fname=font_path).get_name()
plt.rcParams['font.family']=font_name
%matplotlib inline
biplot2(X_pca_lamen, pca_lamen.components_, lamenName, 1,2,labels=lamenEval.columns)

- 그래프 해석
-
면과 국물의 축이 가까우므로, 둘 사이에 비교적 강한 양의 상관관계가 있다
-
그릇은 나머지 변수와 비교적 상관관계가 적다(같은 방향 : 약한 양의 상관관계)
-
얼큰라면은 나머지 변수에 비해 면에서 높은 점수를 받았다
-
짬뽕라면과 김치라면은 전체적으로 점수가 높을 것이며, 짬뽕라면은 그릇의 점수도 높을 것이다
-
해물라면은 면, 국물과 반대방향이므로 음의 상관관계가 있다. 반면, 그릇의 점수는 상당히 높을 것
-
된장라면은 그릇의 점수가 낮을 것이며, 면과 국물의 점수 역시 낮을 것이다.
-
볶음, 만두, 떡은 전체적으로 점수가 고르며, 큰 특성을 보이지 않을 것
'Code > 머신러닝 in Python' 카테고리의 다른 글
| [Python] 비지도 학습 - 군집분석 (0) | 2019.09.04 |
|---|---|
| [Python] openCV 이용한 얼굴인식 (0) | 2019.09.03 |
| [Python] Cross-validation + Grid Search (1) | 2019.08.30 |
| [Python] Grid Search (0) | 2019.08.30 |
| [Python] Cross-validation(교차검증) (1) | 2019.08.30 |
[Python] Cross-validation + Grid Search
Cross-validation + Grid Search
- 데이터를 train, validation, test set으로 나누는 방법은 성능이 좋고 널리 사용되지만, 전 게시글과 같이 데이터를 나누는 방법에 매우 민감
- 일반화 성능을 더 잘 평가하기 위해서는 훈련세트와 검증세트를 한번만 나누지 않고, 교차 검증을 사용해서 각 매개 변수의 조합의 성능을 평가 할 수 있음
# 1. 데이터 분할
iris = datasets.load_iris()
X = iris.data
y = iris.target
X_trainval, X_test, y_trainval, y_test = train_test_split(X,y,test_size=0.25, random_state=0)
# 2. Cross-validation + Grid Search
best_score = 0
for gamma in [0.001,0.01,0.1,1,10,100]:
for C in [0.001,0.01,0.1,1,10,100]:
# train SVC using combination of gamma and C
svm = SVC(gamma = gamma, C = C)
# evaluate model
scores = cross_val_score(svm, X_trainval, y_trainval, cv=5) # svm 모델 사용, 검증 나누지 않고 train데이터 사용
# mean of cross-validation
score = np.mean(scores)
# restore the highest score with its parameter
if score > best_score:
best_score = score
best_parameter = {'gamma':gamma, 'C':C}
svm = SVC(**best_parameter)
svm.fit(X_trainval,y_trainval) # train + validation 모두 합한 데이터 가지고 평가
train_score = svm.score(X_trainval, y_trainval) # 테스트에 대한 점수
test_score = svm.score(X_test, y_test)
train_score,test_score
# output : (0.9821428571428571, 0.9736842105263158)
< GridSearchCV >
- 교차 검증을 사용한 그리드 서치를 매개변수 조정 방법으로 널리 사용하므로, scikit-learn은 GridSearchCV를 제공하고 있음
- 검색 대상이 되는 매개변수를 딕셔너리 자료형으로 구성해야 함
from sklearn.model_selection import GridSearchCV
# 1. parameter grid 생성
param_grid = {'C':[0.001,0.01,0.1,1,10,100],'gamma':[0.001,0.01,0.1,1,10,100] }
# 2. GridSearchCV 이용하여 객체 생성
grid_search = GridSearchCV(SVC(), param_grid, cv =5, return_train_score=True)
# 3. 데이터 분할
## 데이터가 과대적합 되는 것을 방지하기 위해, 또한 최종 모델의 객관적인 정확도 평가를 위해 test data를 분리하고
## gridsearch 및 cross-validation에 사용되지 않도록 한다
X_train, X_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=0 ,test_size=0.2)
# 4. gridsearch model
grid_search.fit(X_train, y_train)
# 5. model evaluation
print("test set score : {}".format(grid_search.score(X_test, y_test)))
# output : test set score : 1.0
# 6. best parameter and best score
print("best parameters : {}".format(grid_search.best_params_))
print("best score : {}".format(grid_search.best_score_))
# output : best parameters : {'C': 1, 'gamma': 0.1}
# best score : 0.9583333333333334
- 여기서 5. 과 6. 의 결과를 구분하는 것이 필요
- 5. : 교차 검증과 그리드 서치의 결과로 산정한 최적 매개변수를 적용하여 전체 훈련 데이터 셋에 대해 훈련한 최종 모델에 테스트 데이터로 적용했을 때의 결과
- 6. : best_score_ 속성은 훈련 세트에서 수행한 교차검증의 평균 정확도가 저장된 결과
* GridSearchCV.fit 메서드는 최적의 매개변수를 찾는 일뿐만 아니라, 교차 검증 성능이 가장 좋은 매개변수로 전체 훈련 데이터 세트에 대해 새로운 모델을 자동으로 만든다.
[교차 검증 결과 분석]
- 결과를 시각화하면 검색 대상 매개변수가 모델의 일반화에 영향을 주는 정도를 이해하는데 도움을 준다
- grid search는 연산 비용이 높으므로, 비교적 간격을 넓게 하여 적은 수의 그리드로 시작하는 것이 좋다.
- 이후 결과를 분석하여 검색을 확장해 나갈 수 있다
- 그리드 서치의 결과는 cv_results_ 속성에 있다
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# 1. cv_results_ dictionary -> dataFrame
results = pd.DataFrame(grid_search.cv_results_)
# 2. first 5 rows
results.head(5)
# 여기서 grid_search.cv_results_ 의 값들을 확인 할 수 있다.
# 3. heatmap
scores = np.array(results.mean_test_score.sort_values(ascending=False)).reshape(6,6)
fig, ax = plt.subplots()
im = ax.imshow(scores, cmap='PiYG')
cbar = ax.figure.colorbar(im, ax=ax)
cbar.ax.set_ylabel(ylabel="parameter C ", rotation=-90, va = "bottom")
ax.set_xticks(np.arange(len(set(results.param_gamma))))
ax.set_yticks(np.arange(len(set(results.param_C))))
ax.set_xticklabels(param_grid['gamma'])
ax.set_yticklabels(param_grid['C'])
for i in range(len(param_grid['C'])):
for j in range(len(param_grid['gamma'])):
text = ax.text(j,i,np.round(scores[i,j],2),ha='center', va='center',color='k')
ax.set_title("Mean Test Score Heatmap by GridSearchCV")
ax.set_xlabel("gamma")

'Code > 머신러닝 in Python' 카테고리의 다른 글
| [Python] openCV 이용한 얼굴인식 (0) | 2019.09.03 |
|---|---|
| [Python] PCA(주성분 분석) (0) | 2019.09.03 |
| [Python] Grid Search (0) | 2019.08.30 |
| [Python] Cross-validation(교차검증) (1) | 2019.08.30 |
| [Python] 분류분석 - SVM(Support Vector Machine) (1) | 2019.08.29 |
[Python] 분류분석 - logistic regression
로지스틱회귀(logistic regression)
- Parameter C를 조정해 과대적합 혹은 과소적합 문제를 해결
- C(cost function) 값이 크면( 높은 코스트) -> 훈련을 더 복잡하게 -> 약한 규제
- C 값이 작으면 (낮은 코스트) -> 훈련을 덜 복잡하게 -> 강한 규제
- 종속변수가 범주형인 경우에 적용하는 회귀분석 모형
- 새로운 설명변수의 값이 주어질 때 반응변수가 각 범주에 속할 확률이 얼마인지 추정하여 추정확률을 기준치에 따라 분류하는 목적으로 사용될 수도 있음. 이때, 모형의 적합을 통해 추정된 확률을 사후 확률이라고 부름
log(p/1-p) = ax - b ( p : 성공확률, 1-p : 실패확률)
- iris 데이터 이용
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn import datasets
# 1 데이터 불러오기
iris_dataset = datasets.load_iris()
# 2 데이터 분할 - 이항 분류
X = iris_dataset.data[50:,:]
y = iris_dataset.target[50:]
X_train, X_test, y_train, y_test = train_test_split(X,y,test_size = 0.3, random_state = 58)
# 3 모델링
logreg = LogisticRegression().fit(X_train, y_train)
logreg
# 4 결과 비교 C = 1.0
print("훈련 세트 점수 : {:.3f}".format(logreg.score(X_train,y_train)))
print("테스트 세트 점수 : {:.3f}".format(logreg.score(X_test,y_test)))
# 결과 : 훈련 세트 점수 : 0.986 테스트 세트 점수 : 0.933
# 5 parameter tuning
logreg001 = LogisticRegression(C=0.01).fit(X_train, y_train)
logreg100 = LogisticRegression(C=100).fit(X_train, y_train)
# 비용 적으면 훈련 약하게 -> 찍어 눌러서 0에 가깝게 만들어라 -> 강한 규제
# 비용 높으면 훈련 강하게 -> 0에 가깝게 만들지 말고 알아서 해라 ->약한 규제
# 5.1 C = 0.1 결과 비교 -> 낮은 코스트 -> 훈련 덜 복잡 -> 강한 규제 -> 과소적합
print("훈련 세트 점수 : {:.3f}".format(logreg001.score(X_train, y_train)))
print("테스트 세트 점수 : {:.3f}".format(logreg001.score(X_test, y_test)))
# 결과 : 훈련 세트 점수 : 0.529 테스트 세트 점수 : 0.500
# 5.2 C = 100 결과 비교 -> 높은 코스트 -> 훈련 더 복잡 -> 약한 규제 -> 과대적합
print("훈련 세트 점수 : {:.3f}".format(logreg100.score(X_train, y_train)))
print("테스트 세트 점수 : {:.3f}".format(logreg100.score(X_test, y_test)))
# 결과 : 훈련 세트 점수 : 0.986 테스트 세트 점수 : 0.933
# 6. 그래프
plt.plot(logreg.coef_.T, "o", label = "C = 1")
plt.plot(logreg001.coef_.T, "^", label = "C = 0.01")
plt.plot(logreg100.coef_.T, "v", label = "C = 100")
plt.xticks(range(iris_dataset.data.shape[1]), iris_dataset.feature_names, rotation=90)
plt.hlines(0,0,iris_dataset.data.shape[1])
plt.xlabel("feature")
plt.ylabel("coefficient")
plt.ylim(-10,10)
plt.legend()

- 그래프 결과가 0에 가까울 수록 규제가 강함 -> C값이 작을 수록 훈련 덜 복잡해서 강한 규제 (C = 0.01)
- 강한 규제는 피쳐(특징) 수를 줄이는 것
- 이후 예측값과 원래 값을 확인하기 위해
result = [logreg.predict(X_test), y_test]
# 7 적합 결과(예측 결과) 보기
logreg_result = pd.DataFrame(result).T
logreg_result.columns = ["prediction", "observation"]
logreg_result['assessment'] = logreg_result['prediction'] == logreg_result['observation']
logreg_result.head()

- 예측한 결과가 boolean 값으로 assessment 칼럼에 추가 된 것을 확인 할 수 있습니다.
'Code > 머신러닝 in Python' 카테고리의 다른 글
| [Python] Cross-validation(교차검증) (1) | 2019.08.30 |
|---|---|
| [Python] 분류분석 - SVM(Support Vector Machine) (1) | 2019.08.29 |
| [Python] LinearRegression(수치예측) - Lasso (0) | 2019.08.28 |
| [Python] LinearRegression(수치예측) - Ridge (0) | 2019.08.28 |
| [Python] LinearRegression(수치예측) (0) | 2019.08.28 |
[Python] LinearRegression(수치예측) - Lasso
Lasso
- 가중치의 절댓값의 합을 최소화하는 것을 추가적인 제약 조건임
- Ridge와 마찬가지로 모든 계수를 0으로 가깝게 만듦
- 규제 방식에 차이가 있음 --> L1 규제라 명명
- 어떤 계수 값은 0으로 산출 -> 완전 제외
- Lasso : boston 데이터 이용
# 0. 라이브러리 추가
from sklearn.datasets import load_boston
boston = load_boston()
# 1. 데이터 분리
X = boston.data
y = boston.target
X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=0.3,random_state = 12)
# 2. Lasso modelling
## 2-1 default -> alpha = 1.0
lasso = Lasso().fit(X_train, y_train)
print("훈련 세트 점수 : {:.3f}".format(lasso.score(X_train,y_train)))
print("테스트 세트 점수 : {:.3f}".format(lasso.score(X_test,y_test)))
print('사용한 특성의 수 : {}'.format(np.sum(lasso.coef_ != 0)))
# 결과 : 훈련 세트 점수 : 0.678 테스트 세트 점수 : 0.586 사용한 특성의 수 : 10
## 2-2 alpha = 0.1
lasso01 = Lasso(alpha=0.1).fit(X_train, y_train)
print("훈련 세트 점수 : {:.3f}".format(lasso01.score(X_train,y_train)))
print("테스트 세트 점수 : {:.3f}".format(lasso01.score(X_test,y_test)))
print('사용한 특성의 수 : {}'.format(np.sum(lasso01.coef_ != 0)))
# 결과 : 훈련 세트 점수 : 0.736 테스트 세트 점수 : 0.693 사용한 특성의 수 : 11
## 2-3 alpha = 0.01
lasso001 = Lasso(alpha=0.01).fit(X_train, y_train)
print("훈련 세트 점수 : {:.3f}".format(lasso001.score(X_train,y_train)))
print("테스트 세트 점수 : {:.3f}".format(lasso001.score(X_test,y_test)))
print('사용한 특성의 수 : {}'.format(np.sum(lasso001.coef_ != 0)))
# 결과 : 훈련 세트 점수 : 0.748 테스트 세트 점수 : 0.708 사용한 특성의 수 : 13
## 2-4 alpha = 10
lasso10 = Lasso(alpha=10).fit(X_train, y_train)
print("훈련 세트 점수 : {:.3f}".format(lasso10.score(X_train,y_train)))
print("테스트 세트 점수 : {:.3f}".format(lasso10.score(X_test,y_test)))
print('사용한 특성의 수 : {}'.format(np.sum(lasso10.coef_ != 0)))
# 결과 : 훈련 세트 점수 : 0.557 테스트 세트 점수 : 0.464 사용한 특성의 수 : 5
# 그래프 확인
plt.plot(lasso001.coef_,"^", label="alpha=0.01")
plt.plot(lasso01.coef_,"^", label="alpha=0.1")
plt.plot(lasso.coef_,"^", label="alpha=1.0")
plt.plot(lasso10.coef_,"^", label="alpha=10")
plt.xlabel("coef list")
plt.ylabel("coefficient")
plt.hlines(0,0,len(lr.coef_))
plt.ylim(-15,5)
plt.legend()
plt.show()

- alpha 값이 커질 수록 규제가 커지게 되며 복잡한 모델을 만든다.
- 위의 alpha값의 변화에 따라 점수를 확인하면 alpha가 작아질 수록 점수가 좋은 것을 확인 할 수있다.
이때, 값이 무한히 낮아지면 다시 점수가 나빠지는 과대적합이 발생 할 수도 있다.
- 그래프를 확인해보면 0의 값을 가진 것을 확인 할 수 있다. 이것이 Ridge와의 차이점이다.
'Code > 머신러닝 in Python' 카테고리의 다른 글
| [Python] 분류분석 - SVM(Support Vector Machine) (1) | 2019.08.29 |
|---|---|
| [Python] 분류분석 - logistic regression (0) | 2019.08.28 |
| [Python] LinearRegression(수치예측) - Ridge (0) | 2019.08.28 |
| [Python] LinearRegression(수치예측) (0) | 2019.08.28 |
| [Python] Gradient Boosting (0) | 2019.08.28 |
[Python] LinearRegression(수치예측) - Ridge
Ridge
- 일반 Linear Regression은 모델의 복잡도를 제어할 방법 없음(파라미터가 없기 때문)
- 릿지 회귀에서의 가중치 선택은 train data 에 대한 것 뿐만 아니라 추가 제약조건을 만족시키는 방향으로 진행
- 방법 : 가중치의 절대값을 가능한 작게 만듦 -> 모든 feature의 가중치를 0에 가깝게 만들어서 기울기를 최대한 작게 만든다 -> 규제
- Regularization : 모델이 과대적합 되지 않도록 강제로 제한 -> L2 규제
- 매개변수 조정 -> alpha 값을 높이면 규제를 강하게 하는 것 -> 계수를 더 0에 가깝게 만듦
앞에서 공부한 단순선형, 다중선형을 이어 Ridge 를 공부해보겠습니다.
낮은 train, test 점수를 보면서 더 높일 수 있는 방법이있지 않을까 생각이 들겁니다.
Ridge는 가중치를 조절하여 그래프의 기울기를 0으로 만들도록 하는 방식으로 모델에 있어 규제를 하는 방식입니다.
from sklearn.linear_model import Ridge
# 1. diabetes dataset loading 및 데이터 분할
diab = datasets.load_diabetes()
X = diab.data
y = diab.target
X_train , X_test , y_train, y_test = train_test_split(X , y , test_size=0.2,random_state=0)
# 2 object for modelling
rdg = Ridge()
rdg.fit(X_train, y_train)
# 3 훈련 결과 확인
print("훈련 세트 점수 : {:.3f}".format(rdg.score(X_train,y_train)))
print("테스트 세트 점수 : {:.3f}".format(rdg.score(X_test,y_test)))
# 결과 : 훈련 세트 점수 : 0.465 테스트 세트 점수 : 0.341
# 4 parameter tuning
rdg01 = Ridge(alpha=0.1)
# alpha 낮게 -> 규제 약하게 한다 -> 데이터에 더 많은 피팅 시켜라 -> 과대적합 방향으로 진행해라
# alpha 높게 -> 규제 강하게 한다 -> 모든 계수 값 0에 가깝게 -> 과소적합
rdg01.fit(X_train, y_train)
# 4-1 훈련 결과 확인
print("훈련 세트 점수 : {:.3f}".format(rdg01.score(X_train,y_train)))
print("테스트 세트 점수 : {:.3f}".format(rdg01.score(X_test,y_test)))
# 결과 : 훈련 세트 점수 : 0.548 테스트 세트 점수 : 0.342
# 5 parameter tuning
rdg02 = Ridge(alpha=0.01)
rdg02.fit(X_train, y_train)
# 5-1 훈련 결과 확인
print("훈련 세트 점수 : {:.3f}".format(rdg02.score(X_train,y_train)))
print("테스트 세트 점수 : {:.3f}".format(rdg02.score(X_test,y_test)))
# 결과 : 훈련 세트 점수 : 0.553 테스트 세트 점수 : 0.330
# 6 parameter tuning
rdg03 = Ridge(alpha=10)
rdg03.fit(X_train, y_train)
# 6-1 훈련 결과 확인
print("훈련 세트 점수 : {:.3f}".format(rdg03.score(X_train,y_train)))
print("테스트 세트 점수 : {:.3f}".format(rdg03.score(X_test,y_test)))
# 결과 : 훈련 세트 점수 : 0.176 테스트 세트 점수 : 0.141
# 그래프 확인
plt.plot(rdg.coef_,"^", label="alpha=0")
plt.plot(rdg01.coef_,"^", label="alpha=0.1")
plt.plot(rdg02.coef_,"^", label="alpha=0.01")
plt.plot(rdg03.coef_,"o", label="alpha=10")
plt.xlabel("coef list")
plt.ylabel("coefficient")
plt.hlines(0,0,len(lr.coef_))
plt.ylim(-500,500)
plt.legend()
plt.show()

그래프를 해석하면, 가중치를 조절하기 위해 alpha를 조정하게 된다.
alpha는 클 수록 규제가 많이 들어가며, 복잡해진다. 또한, 커질수록 계수의 크기가 줄어들게 되며, 영향을 끼치는 변수가 줄어들게 됩니다.(alpha = 10을 보면 확인 가능)
'Code > 머신러닝 in Python' 카테고리의 다른 글
| [Python] 분류분석 - logistic regression (0) | 2019.08.28 |
|---|---|
| [Python] LinearRegression(수치예측) - Lasso (0) | 2019.08.28 |
| [Python] LinearRegression(수치예측) (0) | 2019.08.28 |
| [Python] Gradient Boosting (0) | 2019.08.28 |
| [Python] RandomForest 예제 (0) | 2019.08.27 |
[Python] LinearRegression(수치예측)
Linear Regression(수치예측) : 선형회귀분석
- 종속변수 y와 한 개 이상의 독립변수(설명변수) x와의 선형 상관 관계를 모델링 하는 회귀분석 기법
- 선형 회귀를 사용해 데이터에 적합한 예측 모형을 개발해 값 예측 가능
- 일반적으로 최소제곱법을 이용해 모델 세움( 손실 함수도 사용 가능)
- 단순 선형 회귀, 다중 선형 회귀
1. 단순 선형 회귀 - diabetes 데이터 이용
# 0. 라이브러리 불러오기
from sklearn.linear_model import LinearRegression
from sklearn import datasets
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
# 1. diabetes dataset loading
diab = datasets.load_diabetes()
# 2. 네번째 feature 선택 -> 선형이기 때문에 하나의 x에 대해서만!
diab_X = diabetes.data[:,np.newaxis,3] # 네번째 있는 칼럼을 수직방향으로 뽑아줌
# 3. 데이터 추출 확인
diab_X[0]
# 4. split data
diab_X_train = diab_X[:-20]
diab_X_test = diab_X[-20:]
diab_y_train = diab.target[:-20]
diab_y_test = diab.target[-20:]
# 5 모델 객체 생성 및 fitting
lr = LinearRegression()
lr.fit(diab_X_train, diab_y_train)
# 6 prediction
diab_pred = lr.predict(diab_X_test)
# 7 훈련 결과 확인
print("훈련 세트 점수 : {:.3f}".format(lr.score(diab_X_train,diab_y_train)))
print("테스트 세트 점수 : {:.3f}".format(lr.score(diab_X_test,diab_y_test)))
# 결과 : 훈련 세트 점수 : 0.192 테스트 세트 점수 : 0.160
# 그래프
plt.scatter(diab_X_test, diab_y_test, color='black')
plt.plot(diab_X_test, diab_pred, color="blue", linewidth=3)
plt.show()

단순 선형 회귀를 통한 결과를 그래프로 보면 위와 같다.
2. 다중 선형 회귀 - boston 데이터 이용
# 0. 라이브러리 추가
from sklearn.datasets import load_boston
boston = load_boston()
# 1. 데이터 분류
X = boston.data
y = boston.target
X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=0.3,random_state = 12)
# 2. 모델링
lr = LinearRegression().fit(X_train, y_train)
# 3. 결과 확인
print("훈련 세트 점수 : {:.3f}".format(lr.score(X_train,y_train)))
print("테스트 세트 점수 : {:.3f}".format(lr.score(X_test,y_test)))
# 훈련 세트 점수 : 0.748 테스트 세트 점수 : 0.709
다중 회귀 방식이기 때문에 선형 회귀와 다르게 그래프를 그리지 못해 생략했습니다.
'Code > 머신러닝 in Python' 카테고리의 다른 글
| [Python] LinearRegression(수치예측) - Lasso (0) | 2019.08.28 |
|---|---|
| [Python] LinearRegression(수치예측) - Ridge (0) | 2019.08.28 |
| [Python] Gradient Boosting (0) | 2019.08.28 |
| [Python] RandomForest 예제 (0) | 2019.08.27 |
| [Python] RandomForest (0) | 2019.08.27 |
[Python] DecisionTree
DecisionTree : 의사결정나무
- 어떤 항목에 대한 관측값과 목표값을 연결시켜주는 예측모델
- 시각적이고 명시적인 방법으로 의사 결정 과정과 결정된 의사를 보여주는 데 사용
- 데이터 분할을 하기 위해, 가장 훌륭한 변수가 무엇인지 찾아야함
간단한 파이썬으로 iris 데이터를 의사결정나무로 에측해본 것입니다.
# Decision Tree
# 필요 모듈 import
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_iris
from sklearn import tree
from sklearn.model_selection import train_test_split
# 사이킷런의 iris 데이터 불러오기
iris_dataset = load_iris()
# data split
X = iris_dataset.data
y = iris_dataset.target
X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=0.3, random_state = 25)
# 객체 생성
# max_depth : 사용자 설정에 따라 tree의 레벨 조정 가능
clf = tree.DecisionTreeClassifier(max_depth=None, random_state=0)
# 모델링
clf.fit(X_train, y_train)
print("훈련 세트 점수 {:3f}".format(clf.score(X_train, y_train)))
print("테스트 세트 점수 {:3f}".format(clf.score(X_test, y_test)))
여기서 해당 모델에 대해 시각적으로 확인하고 싶으면
# 아나콘다에서 설치 필요
#conda install graphviz
#conda install python-graphviz
import os
# 환경변수 조정
os.environ['PATH']+=os.pathsep+'C:/Anaconda3/Library/bin/graphviz/'
# 모델 저장
export_graphviz(clf, out_file = "iris.dot",
feature_names=cancer.feature_names,
class_names=cancer.target_names,
rounded=True, proportion=False,
filled=True, precision=2)
# 파일로 불러오기
with open("iris.dot") as f:
dot_graph=f.read()
dot_graph
graphviz.Source(dot_graph)

소스를 돌리면 위와 같은 트리 그래프가 출력되게 됩니다.
'Code > 머신러닝 in Python' 카테고리의 다른 글
| [Python] RandomForest 예제 (0) | 2019.08.27 |
|---|---|
| [Python] RandomForest (0) | 2019.08.27 |
| [Python] k-nearest neighbor 예제 (0) | 2019.08.26 |
| [Python]k-nearest neighbor (0) | 2019.08.26 |
| 텍스트 분석_BOW (0) | 2019.08.14 |
[Python] k-nearest neighbor 예제
사이킷런의 load_breast_cancer 데이터를 이용하여 n_neighbors를 1~11까지 변화시켜가며
train 정확도와 test 정확도 그래프를 확인하고 가장 적절한 k값을 판단해보세요.
import numpy as np
import pandas as pd
from sklearn.datasets import load_breast_cancer
# 사이킷런에서 제공하는 심장병 데이터 불러오기
breast_cancer = load_breast_cancer()
# 데이터 키 확인
breast_cancer.keys()
# 데이터 분류
Xd_train, Xd_test, yd_train, yd_test = train_test_split(breast_cancer['data'],breast_cancer['target'],test_size=0.3, random_state=40)
# 리스트 형태로 1~ 11까지의 train, test 정확도 그래프
train_acc,test_acc = [],[]
for i in range(1,12):
clf3 = KNeighborsClassifier(n_neighbors=i)
clf3.fit(Xd_train, yd_train)
predict_label = clf3.predict(Xd_test)
train_acc.append(clf3.score(Xd_train, yd_train))
test_acc.append(clf3.score(Xd_test, yd_test))
plt.plot(range(1,12),train_acc, label="train")
plt.plot(range(1,12),test_acc, label = "test")
plt.legend()

'Code > 머신러닝 in Python' 카테고리의 다른 글
| [Python] RandomForest (0) | 2019.08.27 |
|---|---|
| [Python] DecisionTree (0) | 2019.08.27 |
| [Python]k-nearest neighbor (0) | 2019.08.26 |
| 텍스트 분석_BOW (0) | 2019.08.14 |
| 텍스트 분석_텍스트 전처리 2 (0) | 2019.08.14 |
주소록 관리 프로그램.py
1. main menu
- 연락처 등록
- 연락처 조회
- 연락처 삭제 : 이름으로 검색 후 동일 이름 전화번호 출력시켜서 삭제할 이름의 번호 입력하면 삭제되도록
- 연락처 출력
- (연락처 변경도 해보자)
- 프로그램 종료
2. 등록
- 이름
- 연락처
- 이메일
|
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
user = []
def start():
while True:
num = int(input("\n연락처 메뉴 [1.등록 2.조회 3.삭제 4.출력 5.수정 6.종료] 선택 = "))
if num == 1:
print("\n================= 연락처 등록 ================")
elif num == 2:
name = input("조회할 이름을 입력하세요 : ")
print("\n================= 연락처 조회 ================")
if not user_print(name):
print("\n조회 결과가 없습니다.")
elif num == 3:
print("\n================= 연락처 삭제 ================")
name = input("\n삭제할 이름을 입력하세요 : ")
if user_print(name):
delnum = int(input("\n삭제할 번호를 입력하세요 :"))
del(user[delnum-1])
print("\n삭제되었습니다.")
elif num == 4:
print("\n================= 연락처 전체 조회 ================")
if len(user) != 0 :
user_print("all")
else :
print("\n조회 결과가 없습니다.")
elif num == 5:
print("\n================= 연락처 수정 ================")
name = input("\n변경할 이름을 입력하세요 : ")
if user_print(name):
delnum = int(input("\n변경할 번호를 입력하세요 :"))
chnum = int(input("\n변경할 항목 선택 (1. 이름, 2. 전화번호, 3.이메일) : "))
if chnum == 1:
user[delnum-1].setname(input("변경 이름 : "))
elif chnum == 2:
user[delnum-1].settell(input("변경 전화번호 : "))
elif chnum == 3:
user[delnum-1].setemail(input("변경 이메일 : "))
else:
print("\n잘못입력하셨습니다")
else:
print("\n변경할 이름이 없습니다.")
elif num == 6:
break
else:
print("다시 입력하세요")
def user_print(name):
if name == "all":
for i in range(0, len(user)):
print(i+1,end=" ")
user[i].disp()
return
else:
for i in range(0, len(user)):
if user[i].name == name :
print(i+1,end=" ")
user[i].disp()
return True
return False
class Address:
def __init__(self):
def setname(self, name):
self.name = name
def settell(self, tell):
self.tell = tell
def setemail(self, email):
self.email = email
def disp(self):
if __name__ == "__main__":
start()
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
|