#最も使われているのはGoogleが公開しているTensorFlow(テンサーフロー)か、scikit-learn(サイキットラーン)でしょう。 from sklearn import datasets #scikit-learnのデータセットモジュールのインポート digits=datasets.load_digits() #手書き数字のデータセットの読み込み print(dir(digits)) #['DESCR', 'data', 'images', 'target', 'target_names'] #名前 データの内容 #DESCR データセットの説明文 #data 画像データ(訓練データとテストデータ) #images 画像データ(8行×8列にしたもの) #target 画像データの答えとなる数字(教師データと検証用データ) #target_names targetの画像データの数字の名前(数字の種類) print(digits.DESCR) #shape は,スカラーや,タプルによって配列の各次元の大きさを表す属性です. print(digits.data.shape) #(1797, 64)#8x8が1797文字分 print(digits.target.shape) #(1797,)#1797文字分の答え print(digits.images.shape) #(1797, 8, 8)#8x8の文字1797個のイメージ print(digits.target_names.shape) #(10,)#答えの種類 #画像データ print(digits.images[0]) #[[ 0. 0. 5. 13. 9. 1. 0. 0.] # [ 0. 0. 13. 15. 10. 15. 5. 0.] # [ 0. 3. 15. 2. 0. 11. 8. 0.] # [ 0. 4. 12. 0. 0. 8. 8. 0.] # [ 0. 5. 8. 0. 0. 9. 8. 0.] # [ 0. 4. 11. 0. 1. 12. 7. 0.] # [ 0. 2. 14. 5. 10. 12. 0. 0.] # [ 0. 0. 6. 13. 10. 0. 0. 0.]] #Matshow: 2次元配列を表示する。 import matplotlib.pyplot as plt plt.matshow(digits.images[1], cmap="Greys") #plt.show() #答えの種類 print(digits.target_names) #[0 1 2 3 4 5 6 7 8 9] #データを分ける n=len(digits.data)*1//2 #データを半分にわける print(n) #// a//b aをbで割った商の整数値 #リスト[開始位置:終了位置:スライス] X_training = digits.data[:n] #dataの前半分 Y_training = digits.target[:n] #targetの前半分 X_test = digits.data[n:] #dataの後半分 Y_test = digits.target[n:] #targetの後半分 #上記確認 print([i.shape for i in [X_training, Y_training, X_test, Y_test]]) #[(898, 64), (898,), (899, 64), (899,)] #scikit-learnのライブラリにあるsvmモジュールのSVCというアルゴリズムを使います。 #Classification #Regression #Clustering #Dimensionality reduction #Model selection #Preprocessing #svmモジュールは、この中のClassification(データの特徴を分析して、カテゴリー毎に分類する学習アルゴリズム)です #============================= # 学習 #============================= from sklearn import svm #svmモジュールをインポート lng = svm.SVC(gamma=0.001) #学習器を作る #SVC関数の引数のgammaは、関数計算のカーネル係数です。 lng.fit(X_training, Y_training) #学習器に訓練データと教師データを渡す #============================= # テスト #============================= #テストデータを使って性能を評価する print(lng.score(X_test, Y_test)) #0.9688542825361512 #学習器にpredict()メソッドを実行すると、次のようにテストデータの識別結果を numpy の配列で返してくれます predicted = lng.predict(X_test) #判別結果をNumpy配列で取り出す print(predicted) #[8 8 4 9 0 8 9 8 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 9 6 7 8 9 # 0 9 5 5 6 5 0 9 8 9 8 4 1 7 7 3 9 1 2 7 8 2 0 1 2 6 3 3 7 3 3 4 6 6 6 4 9 # 1 5 0 9 5 2 8 2 0 0 1 7 6 3 2 1 4 6 3 1 3 9 1 7 6 8 4 3 1 4 0 5 3 6 9 6 1 # 7 5 4 4 7 2 8 2 2 5 7 9 5 4 4 9 0 8 9 8 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 # 7 8 9 0 1 2 3 4 5 6 7 8 9 0 9 5 5 6 5 0 9 8 9 8 4 1 7 7 3 5 1 0 0 7 8 2 0 # 1 2 6 3 3 7 3 3 4 6 6 6 9 9 1 5 0 9 5 2 8 2 0 0 1 7 6 3 2 1 5 4 6 3 1 7 9 # 1 7 6 8 4 3 1 4 0 5 3 6 9 6 1 7 5 4 4 7 2 8 2 2 5 7 9 5 4 8 8 4 9 0 8 9 8 # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 9 5 5 6 5 0 # 9 8 9 8 4 1 7 7 3 5 1 0 0 2 2 7 8 2 0 1 2 6 3 3 7 3 3 4 6 6 6 4 9 1 5 0 9 # 5 2 8 2 0 0 1 7 6 3 2 2 7 4 6 3 1 3 9 1 7 6 8 4 3 1 4 0 5 3 6 9 6 8 7 5 4 # 4 7 2 8 2 2 5 7 9 5 4 8 8 4 9 0 8 9 8 0 9 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 # 8 9 0 1 2 3 4 5 6 7 8 9 0 9 5 5 6 5 0 9 8 9 8 4 1 7 7 3 5 1 0 0 2 2 7 8 2 # 0 1 2 6 3 3 7 3 3 4 6 6 6 4 9 1 5 0 9 6 2 8 3 0 0 1 7 6 3 2 1 7 4 6 3 1 3 # 9 1 7 6 8 4 3 1 4 0 5 3 6 9 6 1 7 5 4 4 7 2 8 2 2 5 7 9 5 4 8 8 4 9 0 8 0 # 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 9 5 5 6 5 0 9 # 8 9 8 4 1 7 7 3 5 1 0 0 2 2 7 8 2 0 1 2 6 3 3 7 3 3 4 6 6 6 4 9 1 5 0 9 5 # 2 8 2 0 0 1 7 6 3 2 1 7 4 6 3 1 3 9 1 7 6 8 4 3 1 4 0 5 3 6 9 6 1 7 5 4 4 # 7 2 8 2 2 5 7 9 5 4 8 8 4 9 0 8 9 8 0 1 2 3 4 5 1 7 8 9 0 1 2 3 4 5 6 9 0 # 1 2 3 4 5 6 7 8 9 4 9 5 5 6 5 0 9 8 9 8 4 1 7 7 3 5 1 0 0 2 2 7 8 2 0 1 2 # 6 8 7 7 7 3 4 6 6 6 9 9 1 5 0 9 5 2 8 0 1 7 6 3 2 1 7 9 6 3 1 3 9 1 7 6 8 # 4 3 1 4 0 5 3 6 9 6 1 7 5 4 4 7 2 2 5 7 3 5 9 4 5 0 8 9 8 0 1 2 3 4 5 6 7 # 8 9 0 1 2 8 4 5 6 7 8 9 0 1 2 5 4 5 6 7 8 9 0 9 5 5 6 5 0 9 8 9 8 4 1 7 7 # 7 5 1 0 0 2 2 7 8 2 0 1 2 6 8 8 7 5 8 4 6 6 6 4 9 1 5 0 9 5 2 8 2 0 0 1 7 # 6 3 2 1 7 4 6 3 1 3 9 1 7 6 8 4 5 1 4 0 5 3 6 9 6 1 7 5 4 4 7 2 8 2 2 5 7 # 9 5 4 8 8 4 9 0 8 9 8] print((Y_test != predicted).sum()) #教師データと一致しなかった数(誤答数)を合計 #numPy同士の演算 #https://www.headboost.jp/python-numpy-array-calculations/ #28 #sklearnモジュールのmetrics()メソッドのmetrics.classification_report()を使うと、それぞれの数字の正答率がわかります。 from sklearn import metrics print(metrics.classification_report(Y_test, predicted)) # precision recall f1-score support # # 0 1.00 0.99 0.99 88 # 1 0.99 0.97 0.98 91 # 2 0.99 0.99 0.99 86 # 3 0.98 0.87 0.92 91 # 4 0.99 0.96 0.97 92 # 5 0.95 0.97 0.96 91 # 6 0.99 0.99 0.99 91 # 7 0.96 0.99 0.97 89 # 8 0.94 1.00 0.97 88 # 9 0.93 0.98 0.95 92 # # accuracy 0.97 899 # macro avg 0.97 0.97 0.97 899 #weighted avg 0.97 0.97 0.97 899 #precision:正答率 #recall:再現率 #f1-score:F値 #support:個数 #例えば、人工知能がある手書き画像を「4」であると判別したとします。 #その時、実際に「4」だった正答率が98%です。 #そして、「4」の手書き画像を「4」と正しく分類できた割合が再現率である95%です。 #F値は判別結果の統計的な有効性です。 #metrics.confusion_matrix()を使うと、各文字ごとの正答数と誤答数がわかります。 #引数には教師データとpredicted()メソッドで作った判別結果を渡します。 from sklearn import metrics print(metrics.confusion_matrix(Y_test, predicted)) #[[87 0 0 0 1 0 0 0 0 0] # [ 0 88 1 0 0 0 0 0 1 1] # [ 0 0 85 1 0 0 0 0 0 0] # [ 0 0 0 79 0 3 0 4 5 0] # [ 0 0 0 0 88 0 0 0 0 4] # [ 0 0 0 0 0 88 1 0 0 2] # [ 0 1 0 0 0 0 90 0 0 0] # [ 0 0 0 0 0 1 0 88 0 0] # [ 0 0 0 0 0 0 0 0 88 0] # [ 0 0 0 1 0 1 0 0 0 90]] #1行目が「0」で最後の10行目が「9」です。そして1列目が「0」で最後の10列目が「9」です。 #1行目は「0」の判別結果です。87個正解して1個を「4」と誤答したことがわかります #それでは間違いが多かった箇所の手書き数字の画像と、判別結果を表示してみましょう。 import matplotlib.pyplot as plt imgs_yt_preds = list(zip(digits.images[n:], Y_test, predicted)) for index, (image, y_t, pred) in enumerate(imgs_yt_preds[704:716]): plt.subplot(3, 4, index+1) plt.axis('off') plt.tight_layout() plt.imshow(image, cmap="Greys", interpolation="nearest") plt.title(f'right:{y_t} result:{pred}', fontsize=12) plt.show()
#アヤメの品種判別の機械学習 from sklearn import datasets from sklearn import svm iris = datasets.load_iris() #データセッtの読み込み X=iris.data #訓練/テストデータ Y=iris.target #教師データ from sklearn.model_selection import ShuffleSplit ss = ShuffleSplit(train_size=0.5, test_size=0.5, random_state=0) #ShuffleSplit(ランダム置換相互検証) #概要 #独立した訓練用・テスト用のデータ分割セットを指定した数だけ生成する. #データを最初にシャッフルしてから,訓練用とテスト用にデータを分割する. #オプション(引数) #n_splits:生成する分割セット数 #test_size:テストに使うデータの割合(0~1の間で指定) #random_state:シャッフルする時の乱数のシード train_index, test_index = next(ss.split(X)) print(train_index) #[ 3 149 98 6 68 109 96 12 102 120 104 128 46 11 110 124 41 148 # 1 113 139 42 4 129 17 38 5 53 143 105 0 34 28 55 75 35 # 23 74 31 118 57 131 65 32 138 14 122 19 29 130 49 136 99 82 # 79 115 145 72 77 25 81 140 142 39 58 88 70 87 36 21 9 103 # 67 117 47] print(test_index) #[114 62 33 107 7 100 40 86 76 71 134 51 73 54 63 37 78 90 # 45 16 121 66 24 8 126 22 44 97 93 26 137 84 27 127 132 59 # 18 83 61 92 112 2 141 43 10 60 116 144 119 108 69 135 56 80 # 123 133 106 146 50 147 85 30 101 94 64 89 91 125 48 13 111 95 # 20 15 52] X_train, Y_train = X[train_index], Y[train_index] #訓練データ X_test, Y_test = X[test_index], Y[test_index] #テストデータ #================= #学習 #================= lng = svm.SVC() lng.fit(X_train, Y_train) #================= #評価 #================= print(lng.score(X_test, Y_test))
一致率の低い例
#アヤメの品種判別の機械学習 from sklearn import datasets iris = datasets.load_iris() #irisデータセットの読み込み print(dir(iris)) #['DESCR', 'data', 'feature_names', 'filename', 'frame', 'target', 'target_names'] print(iris.DESCR) X = iris.data #訓練/テストデータ Y = iris.target #教師データ print(X.shape) print(Y.shape) #(150, 4) #(150,) print(X) print(iris.feature_names) #['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)'] #このように、sepal length(がく片の長さ)、sepal width(がく片の幅)、 petal length(花弁の長さ)、 petal width(花弁の幅)の4つの属性があることがわかります。 print(Y) #[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 # 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 # 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 # 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 # 2 2] #0はsetosa、1はversicolour、2はvirginicaです。 #入っているデータを散布図で視覚化すると次のようになります(がく片の長さがx軸とがく片の幅がy軸)。 import matplotlib.pyplot as plt plt.scatter(X[:50, 0], X[:50, 1], color='r', marker='^', label='setosa') plt.scatter(X[50:100, 0], X[50:100, 1], color='g', marker='+', label='versicolour') plt.scatter(X[100:, 0], X[100:, 1], color='b', marker='x', label='virginica') plt.title("Iris Plants Database") plt.xlabel('sepal length(cm)') plt.ylabel('sepal width(cm)') plt.legend() #plt.show() #花弁の幅をx軸、花弁の長さをy軸にとった散布図では次のようになります。 import matplotlib.pyplot as plt plt.scatter(X[:50, 2], X[:50, 3], color='r', marker='^', label='setosa') plt.scatter(X[50:100, 2], X[50:100, 3], color='g', marker='+', label='versicolour') plt.scatter(X[100:, 2], X[100:, 3], color='b', marker='x', label='virginica') plt.title("Iris Plants Database") plt.xlabel('petal length(cm)') plt.ylabel('petal width(cm)') plt.legend() #plt.show() #==================== #学習開始 #==================== #from sklearn import datasets from sklearn import svm iris = datasets.load_iris() #データセッtの読み込み X=iris.data #訓練/テストデータ Y=iris.target #教師データ n = len(X)//2 #データを半分に分割 X_training, X_test = X[:n], X[n:] #dataの前半分を訓練データ、後半分をテストデータに Y_training, Y_test = Y[:n], Y[n:] #教師データを前半分と後半分に分ける lng = svm.SVC() #学習モデル lng.fit(X_training, Y_training) #データを学習器にかける #==================== #テスト #==================== print(lng.score(X_test, Y_test)) #0.3333333333333333 #正解率33%なのはデータの分割に誤りがある。 #scikit-learnのShuffleSplitメソッドを使用 from sklearn.model_selection import ShuffleSplit ss = ShuffleSplit(train_size=0.5, test_size=0.5, random_state=0) train_index, test_index = next(ss.split(X)) X_train, Y_train = X[train_index], Y[train_index] #訓練データ X_test, Y_test = X[test_index], Y[test_index] #テストデータ #==================== #学習開始 #==================== lng = svm.SVC() lng.fit(X_train, Y_train) print(lng.score(X_test, Y_test)) #0.9466666666666667