본문 바로가기
Keras Deep Learning

[미니 프로젝트] 와인 품질 예측

by yj.yoon 2020. 12. 14.

개발환경&도구 : pycharm-community-2020.3 / Python3.8

 

데이터 : wine.csv

6497개의 데이터, 12개의 열을 사용

wine.csv
0.38MB

1. 라이브러리 설치

import pandas as pd
from keras.utils import np_utils
import numpy as np
import random as r
import matplotlib.pyplot as plt
from keras import layers, models

 

layers : 계층을 만드는 모듈
models : 각 layer을 연결해 신경망 모델을 만든 후 컴파일하고 학습시키는 역할, 학습 후 평가도 진행한다.

2. 파라미터 설정

        #기본 파라미터 설정
        Nin = 11 #입력 계층의 노드 수
        Nh_l = [100, 50] #은닉 계층의 노드 수
        number_of_class = 3 #3개의 클래스 : 상 중 하
        Nout = number_of_class #출력 계층의 노드 수

3. 분류 DNN 모델 구현

(1) 데이터 처리

각 값을 0~1사이로 변환

와인 수치 데이터 x_train 저장

 

(2) 종속변수 분류

3~9의 와인 등급을 0, 1, 2(상중하) 3가지로 분류

 

        for row_index, row in wine.iterrows():
            ran = r.randrange(1, 5, 1)
            if ran != 1:
                x_train.append([])
                x_train[train_count].append(row[0]/15.9)
                x_train[train_count].append(row[1]/1.58)
                x_train[train_count].append(row[2])
                x_train[train_count].append(row[3]/15.5)
                x_train[train_count].append(row[4]/0.611)
                x_train[train_count].append(row[5]/72.0)
                x_train[train_count].append(row[6]/289.0)
                x_train[train_count].append(row[7]/1.00369)
                x_train[train_count].append(row[8]/4.01)
                x_train[train_count].append(row[9]/2.0)
                x_train[train_count].append(row[10]/14.9)
                
                if row[11] == 3 or row[11] == 4 or row[11] == 5:
                    y_train.append(0)
                elif row[11] == 6 or row[11] == 7:
                    y_train.append(1)
                else:
                    y_train.append(2)
                train_count+=1

            else:
                x_test.append([])
                x_test[test_count].append(row[0]/15.9)
                x_test[test_count].append(row[1]/1.58)
                x_test[test_count].append(row[2])
                x_test[test_count].append(row[3]/15.5)
                x_test[test_count].append(row[4]/0.611)
                x_test[test_count].append(row[5]/72.0)
                x_test[test_count].append(row[6]/289.0)
                x_test[test_count].append(row[7]/1.00369)
                x_test[test_count].append(row[8]/4.01)
                x_test[test_count].append(row[9]/2.0)
                x_test[test_count].append(row[10]/14.9)
                
                if row[11] == 3 or row[11] == 4 or row[11] == 5:
                    y_test.append(0)
                elif row[11] == 6 or row[11] == 7:
                    y_test.append(1)
                else:
                    y_test.append(2)
                test_count += 1

 

(3) List 형태의 데이터를 numpy array로 변환

 

        for i in range(0, train_count):
            x_train2=np.append(x_train2, np.array([x_train[i]]), axis=0)

        for i in range(0, test_count):
            x_test2=np.append(x_test2, np.array([x_test[i]]), axis=0)

 

(4) 종속변수 categorical로 변환

출력값을 0과 1로 표현하는 벡터로 변환

 

        y_train = np_utils.to_categorical(y_train)
        y_test = np_utils.to_categorical(y_test)

4. 학습 및 성능 평가

x_train2, y_train : 학습에 사용할 입력(x), 출력(y)데이터

validation_split : 20%를 테스트에 씀

학습한 결과를 history에 저장

 

        # 분류 DNN 학습 및 성능 평가
        model = models.Sequential() #모델 초기화

        # 연쇄방식 모델링 구현
        model.add(layers.Dense(Nh_l[0], activation='relu', input_shape=(Nin,), name='Hidden-1'))
        model.add(layers.Dense(Nh_l[1], activation='relu', name='Hidden-2'))
        model.add(layers.Dense(Nout, activation='softmax'))
        model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

        history = model.fit(x_train2, y_train, epochs=100, batch_size=100, validation_split=0.2)
        perfomace_test = model.evaluate(x_test2, y_test, batch_size=100)
        print('Test loss and accuracy', perfomace_test)

5. 학습 입력과 결과

        #독립변수 입력
        example = np.array([[wine_value1,wine_value2,wine_value3,wine_value4,wine_value5,wine_value6,wine_value7,wine_value8,wine_value9,wine_value10,wine_value11]])

        #종속변수 예측
        result = model.predict(example) #각 클래스에 대한 확률

        print('<< 결과 >>')

        if result[0][0] > result[0][1] or result[0][0] > result[0][2]:
            print('<< 하(3, 4, 5) >>')

        elif result[0][1] > result[0][0] or result[0][1] > result[0][2]:
            print('<< 중(6, 7) >>')
        else:
            print('<< 상(8, 9) >>')

 

 

입력한 와인 정보에 대한 결과는 '하' 등급으로 나온다.

정확도 : 73% (반올림)

 

if __name__ == "__main__":
    #입력한 와인 정보
    Level(8.9,0.62,0.19,3.9,0.17,51,148,0.9986,3.17,0.93,9.2)

 

전체 코드

import pandas as pd
from keras.utils import np_utils
import numpy as np
import random as r
import matplotlib.pyplot as plt
from keras import layers, models


class Level():
    def __init__(self, wine_value1,wine_value2,wine_value3,wine_value4,wine_value5,wine_value6,wine_value7,wine_value8,wine_value9,wine_value10,wine_value11):
        # 기본 파라미터 설정
        Nin = 11 #입력 계층의 노드 수
        Nh_l = [100, 50] #은닉 계층의 노드 수
        number_of_class = 3 #3개의 클래스 : 상 중 하
        Nout = number_of_class #출력 계층의 노드 수


        # 분류 DNN 모델 구현
        wine=pd.read_csv("wine.csv",sep=",", header=0)

        x_train2 = np.empty((0,11), float)
        x_train=[]
        y_train=[]

        x_test2 = np.empty((0,11), float)
        x_test=[]
        y_test=[]

        train_count=0
        test_count=0

        for row_index, row in wine.iterrows():
            ran = r.randrange(1, 5, 1)
            if ran != 1:
                x_train.append([])
                x_train[train_count].append(row[0]/15.9)
                x_train[train_count].append(row[1]/1.58)
                x_train[train_count].append(row[2])
                x_train[train_count].append(row[3]/15.5)
                x_train[train_count].append(row[4]/0.611)
                x_train[train_count].append(row[5]/72.0)
                x_train[train_count].append(row[6]/289.0)
                x_train[train_count].append(row[7]/1.00369)
                x_train[train_count].append(row[8]/4.01)
                x_train[train_count].append(row[9]/2.0)
                x_train[train_count].append(row[10]/14.9)
                # 종속변수 분류
                if row[11] == 3 or row[11] == 4 or row[11] == 5:
                    y_train.append(0)
                elif row[11] == 6 or row[11] == 7:
                    y_train.append(1)
                else:
                    y_train.append(2)
                train_count+=1

            else:
                x_test.append([])
                x_test[test_count].append(row[0]/15.9)
                x_test[test_count].append(row[1]/1.58)
                x_test[test_count].append(row[2])
                x_test[test_count].append(row[3]/15.5)
                x_test[test_count].append(row[4]/0.611)
                x_test[test_count].append(row[5]/72.0)
                x_test[test_count].append(row[6]/289.0)
                x_test[test_count].append(row[7]/1.00369)
                x_test[test_count].append(row[8]/4.01)
                x_test[test_count].append(row[9]/2.0)
                x_test[test_count].append(row[10]/14.9)
                # 종속변수 분류
                if row[11] == 3 or row[11] == 4 or row[11] == 5:
                    y_test.append(0)
                elif row[11] == 6 or row[11] == 7:
                    y_test.append(1)
                else:
                    y_test.append(2)
                test_count += 1

        print(len(x_train))
        print(len(x_test))

        for i in range(0, train_count):
            x_train2=np.append(x_train2, np.array([x_train[i]]), axis=0)

        for i in range(0, test_count):
            x_test2=np.append(x_test2, np.array([x_test[i]]), axis=0)

        y_train = np_utils.to_categorical(y_train)
        y_test = np_utils.to_categorical(y_test)


        # 분류 DNN 학습 및 성능 평가
        model = models.Sequential() #모델 초기화

        # 연쇄방식 모델링 구현
        model.add(layers.Dense(Nh_l[0], activation='relu', input_shape=(Nin,), name='Hidden-1'))
        model.add(layers.Dense(Nh_l[1], activation='relu', name='Hidden-2'))
        model.add(layers.Dense(Nout, activation='softmax'))
        model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

        history = model.fit(x_train2, y_train, epochs=100, batch_size=100, validation_split=0.2) #validation_split : 20%를 테스트에 씀
        perfomace_test = model.evaluate(x_test2, y_test, batch_size=100)
        print('Test loss and accuracy', perfomace_test)


        #그래프
        fig, loss_ax = plt.subplots(figsize=(10,5))
        acc_ax = loss_ax.twinx()
        loss_ax.plot(history.history['loss'], 'y', label='train loss')
        loss_ax.plot(history.history['val_loss'], 'r', label='val loss')
        acc_ax.plot(history.history['accuracy'], 'b', label='train accuracy')
        acc_ax.plot(history.history['val_accuracy'], 'g', label='val accuracy')
        loss_ax.set_xlabel('epoch')
        loss_ax.set_ylabel('loss')
        acc_ax.set_ylabel('accuracy')
        loss_ax.legend(loc='upper left')
        acc_ax.legend(loc='lower left')
        plt.show()


        #독립변수 입력
        example = np.array([[wine_value1,wine_value2,wine_value3,wine_value4,wine_value5,wine_value6,wine_value7,wine_value8,wine_value9,wine_value10,wine_value11]])

        #종속변수 예측
        result = model.predict(example) #각 클래스에 대한 확률

        print('<< 결과 >>')

        if result[0][0] > result[0][1] or result[0][0] > result[0][2]:
            print('<< 하(3, 4, 5) >>')

        elif result[0][1] > result[0][0] or result[0][1] > result[0][2]:
            print('<< 중(6, 7) >>')
        else:
            print('<< 상(8, 9) >>')


if __name__ == "__main__":
    #입력한 와인 정보
    Level(8.9,0.62,0.19,3.9,0.17,51,148,0.9986,3.17,0.93,9.2)