Pythonのコードをオブジェクト指向にして改良するまでの過程


#Pythonのコードをオブジェクト指向にして改良するまでの過程

Pythonではオブジェクト指向プログラミングをすることができます。利便性・可読性の向上のためにも活かしてみたいところです。
今回は自分で作成したスパゲッティーコードなプログラムをオブジェクト指向にするまでの過程を記録してみました。

##オブジェクト指向とは？

「オブジェクト志向」(Object-Oriented)とは、かなり大雑把に言えば**ある対象物(Object)をデータの集合体(Collection of data, Propaties)、そしてそれに関係する動作(Behavior, Method)を1パックにまとめたものとする**考え方です。
この考えをプログラミングに応用するには、オブジェクト指向な分析（Object-Oriented Analysis, OOA）、オブジェクト指向な設計（Object-Oriented Design, OOD）の2プロセスを必要とします。

##オブジェクト指向な分析

ここでは仮に先日の[Ethical Baysean Classifier](https://github.com/KSKNemoto/Ethical-Machine-Project/blob/master/Ethical%20Baysean%20Classifier.ipynb)をオブジェクト指向にしたいとします。
このプログラムの内容は要は簡単なナイーブベイズ分類器です。テキストを読み込んだのちにそれを学習させ、ユーザーの入力したテキストをラベリングするという流れになっています。このプログラムにまずはオブジェクト指向な分析を行ってみましょう。
「オブジェクト指向な分析」の段階で行うべきことは、**システムの仕組みと構造を理解し、それを一連のオブジェクトどうしの動作として解釈する**ことです。
この場合、オブジェクト自体は「分類器」１つのみで、学習用テキスト・判定用テキストがデータ、そして学習・判定を行うプロセスは動作であると理解できます。

##オブジェクト指向な設計

オブジェクト指向な分析でプログラムの仕組みを理解したら、次はその**要件定義**を行います。
オブジェクトは「分類器」１つのみ、データは学習用テキスト・判定用テキスト・各ラベル・学習後の整形したデータの4種類、動作は入力・学習・判定の3つに絞ることができました。

##改良後のコード

```python:Ethical_Baysean_Classifier-OOP.ipynb
import numpy as np
import matplotlib.pyplot as plt
from textblob import TextBlob
from textblob.classifiers import NaiveBayesClassifier 

class Classifier():
    
    def __init__(self):
        self.act_pos = []
        self.etc_pos = []
        self.etc_neg = []
        self.etc_user = []
        self.etc_user_label = []
        self.etc_user_label2 = []
        self.trained1 = []
        self.trained2 = []
    
        print("Classifier has initiated.")
    
    
    def input(self):
        with open("analysed/actual_statement_pos.txt","r", encoding="utf8", errors='ignore')as f:
            entire_txt = f.read()
            self.act_pos = entire_txt.splitlines()
            print("Text lines =", len(self.act_pos))    
        with open("analysed/ethical_statement_pos.txt","r", encoding="utf8", errors='ignore')as f:
            entire_txt2 = f.read()
            self.etc_pos = entire_txt2.splitlines()
            print("Text lines =", len(self.etc_pos)) 
        with open("analysed/ethical_statement_neg.txt","r", encoding="utf8", errors='ignore')as f:
            entire_txt3 = f.read()
            self.etc_neg = entire_txt3.splitlines()
            print("Text lines =", len(self.etc_neg))
        with open("analysed/ethical_statement_user.txt","r", encoding="utf8", errors='ignore')as f:
            entire_txt4 = f.read()
            self.etc_user = entire_txt4.splitlines()
            print("Text lines =", len(self.etc_user))
        
        
    def train(self):
        for i,item in enumerate(self.act_pos):
            self.trained1 = [ 
                (self.act_pos[i], "act"), 
                (self.etc_pos[i], "etc"), 
            ] 
        for i,item in enumerate(self.act_pos):
            self.trained2 = [ 
                (self.etc_pos[i], "etc_pos"), 
                (self.etc_neg[i], "etc_neg"), 
            ] 
        print("\n Classifier has trained for Actual/Ethical,Correct/Wrong distinction.")
        
        
    def classify(self):
        trained1 = self.trained1
        cl = NaiveBayesClassifier(trained1)
        
        print("\n Actual/Ethical distinction")
        
        for i,item in enumerate(self.act_pos):
            self.etc_user_label.append(cl.classify(self.etc_user[i]))
            print(self.etc_user[i],"<<- Text | Classified ->> ", self.etc_user_label[i])
            
            
        trained2 = self.trained2
        cl = NaiveBayesClassifier(trained2)
        
        print("\n Correct/Wrong distinction")
        
        for i,item in enumerate(self.act_pos):
            self.etc_user_label2.append(cl.classify(self.etc_user[i]))
            print(self.etc_user[i],"<<- Text | Classified ->> ", self.etc_user_label2[i])
            
clsf = Classifier()
clsf.input()
clsf.train()
clsf.classify()
```

##実行結果

>Classifier has initiated.
Text lines = 10
Text lines = 10
Text lines = 10
Text lines = 10

 >Classifier has trained for Actual/Ethical,Correct/Wrong distinction.

> Actual/Ethical distinction
We must not be late. <<- Text | Classified ->>  etc
We must fight against odds. <<- Text | Classified ->>  etc
We must take the evil with the good. <<- Text | Classified ->>  etc
We must consider the gravity of the situation. <<- Text | Classified ->>  etc
We must have high ideals. <<- Text | Classified ->>  etc
We must keep calm. <<- Text | Classified ->>  etc
We must try to find him, <<- Text | Classified ->>  etc
We must not forget that day. <<- Text | Classified ->>  etc
We must protect that. <<- Text | Classified ->>  etc
We must always provide against accidents. <<- Text | Classified ->>  etc

> Correct/Wrong distinction
We must not be late. <<- Text | Classified ->>  etc_neg
We must fight against odds. <<- Text | Classified ->>  etc_pos
We must take the evil with the good. <<- Text | Classified ->>  etc_pos
We must consider the gravity of the situation. <<- Text | Classified ->>  etc_pos
We must have high ideals. <<- Text | Classified ->>  etc_pos
We must keep calm. <<- Text | Classified ->>  etc_pos
We must try to find him, <<- Text | Classified ->>  etc_pos
We must not forget that day. <<- Text | Classified ->>  etc_neg
We must protect that. <<- Text | Classified ->>  etc_pos
We must always provide against accidents. <<- Text | Classified ->>  etc_pos

たった四行のコードでオブジェクト指向化したプログラムをすべて実行することができます。