본문 바로가기
Artificial Intelligence

[Python] Iris 데이터 분석

by 테리는당근을좋아해 2020. 1. 28.

Iris 데이터 분석

scikit-learn의 data set에 4가지 특성으로 Iris 꽃의 종류를 예측

label이 꽃의 종류이기 때문에 분류(Classification) 문제

 

데이터 불러오기

scikit-learn의 샘플데이터를 통해 iris 데이터를 불러온다

from sklearn.datasets import load_iris # scikit-learn의 샘플 데이터 로드를 위해 import

iris = load_iris() # sample data load

 

불러온 데이터 셋이 어떻게 표현되어 있는지 확인

print(iris) # 로드된 데이터가 속성-스타일 접근을 제공하는 딕셔너리와 번치 객체로 표현된 것을 확인
print(iris.DESCR) # Description 속성을 이용해서 데이터셋의 정보를 확인

# 각 key에 저장된 value 확인
# feature
print(iris.data)
print(iris.feature_names)

# label
print(iris.target)
print(iris.target_names)

 

데이터를 처리하기 위해 로드한 데이터 셋을 데이터프레임으로 변환

import pandas as pd # 데이터 프레임으로 변환을 위해 임포트
import numpy as np # 고수학 연산을 위해 임포트

# feature_names 와 target을 레코드로 갖는 데이터프레임 생성
df = pd.DataFrame(data=iris.data, columns=iris.feature_names)
df['target'] = iris.target

# 0.0, 1.0, 2.0으로 표현된 label을 문자열로 매핑
df['target'] = df['target'].map({0:"setosa", 1:"versicolor", 2:"virginica"})
print(df)

 

소스코드

from sklearn.datasets import load_iris # scikit-learn의 샘플 데이터 로드를 위해 import
import pandas as pd # 데이터 프레임으로 변환을 위해 임포트
import numpy as np # 고수학 연산을 위해 임포트

iris = load_iris() # sample data load

print(iris) # 로드된 데이터가 속성-스타일 접근을 제공하는 딕셔너리와 번치 객체로 표현된 것을 확인
print(iris.DESCR) # Description 속성을 이용해서 데이터셋의 정보를 확인

# 각 key에 저장된 value 확인
# feature
print(iris.data)
print(iris.feature_names)

# label
print(iris.target)
print(iris.target_names)

# feature_names 와 target을 레코드로 갖는 데이터프레임 생성
df = pd.DataFrame(data=iris.data, columns=iris.feature_names)
df['target'] = iris.target

# 0.0, 1.0, 2.0으로 표현된 label을 문자열로 매핑
df['target'] = df['target'].map({0:"setosa", 1:"versicolor", 2:"virginica"})
print(df)

scikit-learn dataset에서 iris의 sample data를 로드하고 데이터 프레임으로 변환하는 과정.

결측치가 존재하지 않기 때문에 매핑을 제외하고 특별한 전처리 과정을 거치지 않음

 

데이터 시각화

seaborn 패키지를 사용해서 산점도를 그리고 각 feature와 label의 상관관계 분석

# 시각화를 위한 패키지 임포트
import matplotlib.pyplot as plt
import seaborn as sns

# 슬라이싱을 통해 feature와 label 분리
x_data = df.iloc[:, :-1]
y_data = df.iloc[:, [-1]]

sns.pairplot(df, hue="target", height=3)
plt.show()

 

이외의 다른 그래프 그리기

sns.pairplot(df, x_vars=["sepal length (cm)"], y_vars=["sepal width (cm)"], hue="target", height=5)
plt.show()

 

sns.FacetGrid(df, hue="target", height=5).map(sns.kdeplot, "petal length (cm)").add_legend()
plt.show()

 

sns.boxplot(x="target", y="petal width (cm)", data=df)
plt.show()

 

sns.stripplot(x="target", y="sepal length (cm)", data=df, jitter=True, edgecolor="gray", size=5)
plt.show()

 

sns.violinplot(x="target", y="sepal width (cm)", data=df, size=5)
plt.show()

 

소스코드

from sklearn.datasets import load_iris # scikit-learn의 샘플 데이터 로드를 위해 import
import pandas as pd # 데이터 프레임으로 변환을 위해 임포트
import numpy as np # 고수학 연산을 위해 임포트

# 시각화를 위한 패키지 임포트
import matplotlib.pyplot as plt
import seaborn as sns

iris = load_iris() # sample data load

print(iris) # 로드된 데이터가 속성-스타일 접근을 제공하는 딕셔너리와 번치 객체로 표현된 것을 확인
print(iris.DESCR) # Description 속성을 이용해서 데이터셋의 정보를 확인

# 각 key에 저장된 value 확인
# feature
print(iris.data)
print(iris.feature_names)

# label
print(iris.target)
print(iris.target_names)

# feature_names 와 target을 레코드로 갖는 데이터프레임 생성
df = pd.DataFrame(data=iris.data, columns=iris.feature_names)
df['target'] = iris.target

# 0.0, 1.0, 2.0으로 표현된 label을 문자열로 매핑
df['target'] = df['target'].map({0:"setosa", 1:"versicolor", 2:"virginica"})
print(df)

# 슬라이싱을 통해 feature와 label 분리
x_data = df.iloc[:, :-1]
y_data = df.iloc[:, [-1]]

sns.pairplot(df, hue="target", height=3)
plt.show()

# sns.pairplot(df, x_vars=["sepal length (cm)"], y_vars=["sepal width (cm)"], hue="target", height=5)
# plt.show()

# sns.FacetGrid(df, hue="target", height=5).map(sns.kdeplot, "petal length (cm)").add_legend()
# plt.show()

# sns.boxplot(x="target", y="petal width (cm)", data=df)
# plt.show()

# sns.stripplot(x="target", y="sepal length (cm)", data=df, jitter=True, edgecolor="gray", size=5)
# plt.show()

# sns.violinplot(x="target", y="sepal width (cm)", data=df, size=5)
# plt.show()

 

Classifier

iris의 레이블은 연속값이 아닌 "setosa" (0.0), "versicolor" (1.0), "virginica" (2.0)인 이산값이기

때문에 분류(classification) 문제라는 것을 알 수 있음.

분류에 사용되는 classifier는 Logistic (Regression) Classifier, Decision Tree, Support Vector Machine, Naive Bayesian, K Nearest Neighbor, Random Forest, Gradient Boosing, Neural Network 등이 있다.

from sklearn.linear_model import LogisticRegression #Logistic(Regression)Classifier
from sklearn.tree import DecisionTreeClassifier #Decision Tree
from sklearn.svm import SVC #Support Vector Machine
from sklearn.naive_bayes import GaussianNB #Naive Bayesian
from sklearn.neighbors import KNeighborsClassifier #K Nearest Neighbor
from sklearn.ensemble import RandomForestClassifier #Random Forest
from sklearn.ensemble import GradientBoostingClassifier #Gradient Boosing
from sklearn.neural_network import MLPClassifier #Neural Network

#logistic (Regression) Classifier, Decision tree, support vector machine, naive bayesian, K Nearest Neighbor, Random Forest, Gradient Boosing, Neural Network
models = []
models.append(("LR", LogisticRegression()))
models.append(("DT", DecisionTreeClassifier()))
models.append(("SVM", SVC()))
models.append(("NB", GaussianNB()))
models.append(("KNN", KNeighborsClassifier()))
models.append(("RF", RandomForestClassifier()))
models.append(("GB", GradientBoostingClassifier()))
models.append(("ANN", MLPClassifier()))

 

모델 학습

from sklearn.metrics import accuracy_score

# 모델 학습 및 정확도 분석
for name, model in models:
    model.fit(x_data, y_data.values.ravel())
    y_pred = model.predict(x_data)
    print(name, "'s Accuracy is ", accuracy_score(y_data, y_pred))

결과값으로 높은 정확도를 보이지만 여기서 학습에 사용한 train set과 테스트에 사용된 test set이 같은 데이터이기 때문에 overfitting이 되었을 가능성이 높다. 따라서 전체 데이터를 2개로 나누어 하나는 train set, 나머지 하나는 test set으로 정확도를 분석한다. 이렇게 반복적으로 데이터를 나누어 정확도를 검증하는 방식을 교차검증이라고 한다.

 

from sklearn import model_selection

# 교차 검증
results = []
names = []

for name, model in models:
    kfold = model_selection.KFold(n_splits=5, random_state=7, shuffle=True)
    cv_results = model_selection.cross_val_score(model, x_data, y_data.values.ravel(), cv=kfold, scoring="accuracy")
    results.append(cv_results)
    names.append(name)

fig = plt.figure()

fig.suptitle('Classifier Comparison')
ax = fig.add_subplot(111)
plt.boxplot(results)
ax.set_xticklabels(names)
plt.show()

 

소스코드

from sklearn.datasets import load_iris # scikit-learn의 샘플 데이터 로드를 위해 import
import pandas as pd # 데이터 프레임으로 변환을 위해 임포트
import numpy as np # 고수학 연산을 위해 임포트

# 시각화를 위한 패키지 임포트
import matplotlib.pyplot as plt
import seaborn as sns

# 학습을 위한 라이브러리 임포트
from sklearn.linear_model import LogisticRegression #Logistic(Regression)Classifier
from sklearn.tree import DecisionTreeClassifier #Decision Tree
from sklearn.svm import SVC #Support Vector Machine
from sklearn.naive_bayes import GaussianNB #Naive Bayesian
from sklearn.neighbors import KNeighborsClassifier #K Nearest Neighbor
from sklearn.ensemble import RandomForestClassifier #Random Forest
from sklearn.ensemble import GradientBoostingClassifier #Gradient Boosing
from sklearn.neural_network import MLPClassifier #Neural Network

from sklearn.metrics import accuracy_score

from sklearn import model_selection

iris = load_iris() # sample data load

print(iris) # 로드된 데이터가 속성-스타일 접근을 제공하는 딕셔너리와 번치 객체로 표현된 것을 확인
print(iris.DESCR) # Description 속성을 이용해서 데이터셋의 정보를 확인

# 각 key에 저장된 value 확인
# feature
print(iris.data)
print(iris.feature_names)

# label
print(iris.target)
print(iris.target_names)

# feature_names 와 target을 레코드로 갖는 데이터프레임 생성
df = pd.DataFrame(data=iris.data, columns=iris.feature_names)
df['target'] = iris.target

# 0.0, 1.0, 2.0으로 표현된 label을 문자열로 매핑
df['target'] = df['target'].map({0:"setosa", 1:"versicolor", 2:"virginica"})
print(df)

# 슬라이싱을 통해 feature와 label 분리
x_data = df.iloc[:, :-1]
y_data = df.iloc[:, [-1]]

# sns.pairplot(df, hue="target", height=3)
# plt.show()

# sns.pairplot(df, x_vars=["sepal length (cm)"], y_vars=["sepal width (cm)"], hue="target", height=5)
# plt.show()

# sns.FacetGrid(df, hue="target", height=5).map(sns.kdeplot, "petal length (cm)").add_legend()
# plt.show()

# sns.boxplot(x="target", y="petal width (cm)", data=df)
# plt.show()

# sns.stripplot(x="target", y="sepal length (cm)", data=df, jitter=True, edgecolor="gray", size=5)
# plt.show()

# sns.violinplot(x="target", y="sepal width (cm)", data=df, size=5)
# plt.show()

#logistic (Regression) Classifier, Decision tree, support vector machine, naive bayesian, K Nearest Neighbor, Random Forest, Gradient Boosing, Neural Network
models = []
models.append(("LR", LogisticRegression()))
models.append(("DT", DecisionTreeClassifier()))
models.append(("SVM", SVC()))
models.append(("NB", GaussianNB()))
models.append(("KNN", KNeighborsClassifier()))
models.append(("RF", RandomForestClassifier()))
models.append(("GB", GradientBoostingClassifier()))
models.append(("ANN", MLPClassifier()))

# 모델 학습 및 정확도 분석
# for name, model in models:
#     model.fit(x_data, y_data.values.ravel())
#     y_pred = model.predict(x_data)
#     print(name, "'s Accuracy is ", accuracy_score(y_data, y_pred))

# 교차 검증
results = []
names = []

for name, model in models:
    kfold = model_selection.KFold(n_splits=5, random_state=7, shuffle=True)
    cv_results = model_selection.cross_val_score(model, x_data, y_data.values.ravel(), cv=kfold, scoring="accuracy")
    results.append(cv_results)
    names.append(name)

fig = plt.figure()

fig.suptitle('Classifier Comparison')
ax = fig.add_subplot(111)
plt.boxplot(results)
ax.set_xticklabels(names)
plt.show()

 

Logistic Regression 

라이브러리에 구현된 기계학습 모델의 매개변수를 변경해 정확도를 올리는 작업을 해보자

예제에 사용될 학습모델은 Logistic Regression으로 회귀처럼 보이지만 회귀를 이용한 분류 알고리즘이다.

Logistic Regression은 종속변수와 독립변수의 선형결합을 통해 발생 확률을 예측하는 알고리즘이다.(참고 softmax function)

model = LogisticRegression()
parameters = {
    'C' : [2**0, 2**3, 2**6, 2**9, 2**12],
    'random_state' : [0, 7, 13, 42]
}
gs = model_selection.GridSearchCV(model, parameters)
gs.fit(x_data, y_data.values.ravel())
model = gs.best_estimator_

kfold = model_selection.KFold(n_splits=5, random_state=7, shuffle=True)
cv_results = model_selection.cross_val_score(model, x_data, y_data.values.ravel(), cv=kfold, scoring="accuracy")
plt.boxplot(cv_results)
plt.show()

 

소스코드

from sklearn.datasets import load_iris # scikit-learn의 샘플 데이터 로드를 위해 import
import pandas as pd # 데이터 프레임으로 변환을 위해 임포트
import numpy as np # 고수학 연산을 위해 임포트

# 시각화를 위한 패키지 임포트
import matplotlib.pyplot as plt
import seaborn as sns

# 학습을 위한 라이브러리 임포트
from sklearn.linear_model import LogisticRegression #Logistic(Regression)Classifier
from sklearn.tree import DecisionTreeClassifier #Decision Tree
from sklearn.svm import SVC #Support Vector Machine
from sklearn.naive_bayes import GaussianNB #Naive Bayesian
from sklearn.neighbors import KNeighborsClassifier #K Nearest Neighbor
from sklearn.ensemble import RandomForestClassifier #Random Forest
from sklearn.ensemble import GradientBoostingClassifier #Gradient Boosing
from sklearn.neural_network import MLPClassifier #Neural Network

from sklearn.metrics import accuracy_score

from sklearn import model_selection

iris = load_iris() # sample data load

print(iris) # 로드된 데이터가 속성-스타일 접근을 제공하는 딕셔너리와 번치 객체로 표현된 것을 확인
print(iris.DESCR) # Description 속성을 이용해서 데이터셋의 정보를 확인

# 각 key에 저장된 value 확인
# feature
print(iris.data)
print(iris.feature_names)

# label
print(iris.target)
print(iris.target_names)

# feature_names 와 target을 레코드로 갖는 데이터프레임 생성
df = pd.DataFrame(data=iris.data, columns=iris.feature_names)
df['target'] = iris.target

# 0.0, 1.0, 2.0으로 표현된 label을 문자열로 매핑
df['target'] = df['target'].map({0:"setosa", 1:"versicolor", 2:"virginica"})
print(df)

# 슬라이싱을 통해 feature와 label 분리
x_data = df.iloc[:, :-1]
y_data = df.iloc[:, [-1]]

# sns.pairplot(df, hue="target", height=3)
# plt.show()

# sns.pairplot(df, x_vars=["sepal length (cm)"], y_vars=["sepal width (cm)"], hue="target", height=5)
# plt.show()

# sns.FacetGrid(df, hue="target", height=5).map(sns.kdeplot, "petal length (cm)").add_legend()
# plt.show()

# sns.boxplot(x="target", y="petal width (cm)", data=df)
# plt.show()

# sns.stripplot(x="target", y="sepal length (cm)", data=df, jitter=True, edgecolor="gray", size=5)
# plt.show()

# sns.violinplot(x="target", y="sepal width (cm)", data=df, size=5)
# plt.show()

#logistic (Regression) Classifier, Decision tree, support vector machine, naive bayesian, K Nearest Neighbor, Random Forest, Gradient Boosing, Neural Network
# models = []
# models.append(("LR", LogisticRegression()))
# models.append(("DT", DecisionTreeClassifier()))
# models.append(("SVM", SVC()))
# models.append(("NB", GaussianNB()))
# models.append(("KNN", KNeighborsClassifier()))
# models.append(("RF", RandomForestClassifier()))
# models.append(("GB", GradientBoostingClassifier()))
# models.append(("ANN", MLPClassifier()))

# 모델 학습 및 정확도 분석
# for name, model in models:
#     model.fit(x_data, y_data.values.ravel())
#     y_pred = model.predict(x_data)
#     print(name, "'s Accuracy is ", accuracy_score(y_data, y_pred))

# 교차 검증
# results = []
# names = []

# for name, model in models:
#     kfold = model_selection.KFold(n_splits=5, random_state=7, shuffle=True)
#     cv_results = model_selection.cross_val_score(model, x_data, y_data.values.ravel(), cv=kfold, scoring="accuracy")
#     results.append(cv_results)
#     names.append(name)

# fig = plt.figure()

# fig.suptitle('Classifier Comparison')
# ax = fig.add_subplot(111)
# plt.boxplot(results)
# ax.set_xticklabels(names)
# plt.show()

model = LogisticRegression()
parameters = {
    'C' : [2**0, 2**3, 2**6, 2**9, 2**12],
    'random_state' : [0, 7, 13, 42]
}
gs = model_selection.GridSearchCV(model, parameters)
gs.fit(x_data, y_data.values.ravel())
model = gs.best_estimator_

kfold = model_selection.KFold(n_splits=5, random_state=7, shuffle=True)
cv_results = model_selection.cross_val_score(model, x_data, y_data.values.ravel(), cv=kfold, scoring="accuracy")
plt.boxplot(cv_results)
plt.show()

댓글