質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.51%

  • Python 2.7

    1413questions

    Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

pythonでの識別器でうまく識別できない

受付中

回答 0

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,051

taka_1105

score 4

pythonでベクトルを読み込み2クラス判別を行っています.
識別器はSVMを使用しているのですが,true_labelとpredicted_labelが見事にすべて反転してしまいaccuracyが0パーセントとなってしまいます.
SVMのパラメータなど見直しましたが,原因がわかりません.
解決策がありましたらよろしくお願いします.
(追記)
class_weight=balancedとしたいのですが,エラーが起きます.
ValueError: class_weight must be dict, 'auto', or None, got: 'balanced'
%%%%%%%%%%%%%%%%%%%%ソースコード始め%%%%%%%%%%%%%%%%%%%%%%%%%

 メイン関数

if name=="main":

print('\n\nCheck training samples\n')

 初期パラメータ設定ここから    

 訓練サンプルが入っているフォルダの指定

training_samples_folder_name = 'C:/AESD/Data/20161209_kizon_120s_1epoch/vector_out/bin_5/0.1s/'

 訓練サンプルの画像ファイルの拡張子を指定

training_samples_filename_extension = 'txt'

 読み込むクラス数

 注:クラスのラベルは1から始まる

class_num = 2

 各クラスで読み込む最大枚数

 指定した最大枚数に満たない場合は各クラスの枚数の最小値を用いる

    max_read_image_num = 1000000

max_read_image_num = 13

 識別器の種類を設定 

 NN:最近傍識別,RF:ランダム森,SVM:サポートベクタマシン

 GB:GradientBoostingClassifier,  LR:ロジスティック回帰

set_classifier_name = 'RF'

    set_classifier_name = 'NN'

set_classifier_name = 'SVM'

set_classifier_name = 'GB'

set_classifier_name = 'LR'

 初期パラメータ設定ここまで    

 画像とラベルを読み込み特徴ベクトルを生成

train_data_set = []
train_label_set = []
train_sample_num_set = []
for current_label in range(1,class_num+1):
current_path = training_samples_folder_name+str(current_label)+'/*.'+training_samples_filename_extension
print('\n\nClass', current_label, '\nLoad image files: ', current_path)
train_data_class, train_labels_class = mytools.read_attributes(current_path, current_label, max_read_image_num)
train_data_set.append(train_data_class)
train_label_set.append(train_labels_class)
train_sample_num_set.append(train_data_class.shape[0])

 各クラスのサンプル数の偏りは無視して全てのサンプルを利用

sample_num_all = 0
for current_label in range(0,class_num):   
sample_num_all += train_sample_num_set[current_label]

sample_dim = train_data_set[0].shape[1]       
print('Training dim.:', sample_dim)    
print('Num. of training samples of each class:', train_sample_num_set)
print('Num. of training samples:', train_sample_num_set)
print('All training sample num.:',sample_num_all)
print()
print()

train_data = np.zeros((sample_num_all,sample_dim))
train_labels = np.zeros(sample_num_all, dtype=int)
offset_sample_num = 0
for current_label in range(0,class_num):
train_data[offset_sample_num:offset_sample_num+train_sample_num_set[current_label],:] = train_data_set[current_label][:,:]
train_labels[offset_sample_num:offset_sample_num+train_sample_num_set[current_label]] = train_label_set[current_label][:]
offset_sample_num += train_sample_num_set[current_label]

 識別器設定

if set_classifier_name == 'NN':

 識別器を最近傍識別に設定

from sklearn.neighbors import KNeighborsClassifier
classifier = KNeighborsClassifier(n_neighbors=3, 
algorithm='brute',
metric = 'euclidean')

elif set_classifier_name == 'RF':

 識別器をランダム森に設定

from sklearn.ensemble import RandomForestClassifier
classifier = RandomForestClassifier(n_estimators=6, max_features=20, class_weight='auto')

elif set_classifier_name == 'SVM':

 識別器をサポートベクタマシンに設定

from sklearn import svm

        classifier = svm.SVC(kernel='linear', C=10, probability=True, class_weight='auto')

        classifier = svm.SVC(kernel='linear', C=10, probability=True, class_weight='balanced')

        classifier = svm.LinearSVC(C=3, fit_intercept=True, max_iter=5000, tol=1e-6, loss="l2", penalty="l1", dual=False, class_weight='auto')

        classifier = svm.LinearSVC(C=10, fit_intercept=True, max_iter=5000, tol=1e-6, loss='hinge', penalty="l2", class_weight='auto')

classifier = svm.SVC(C=10, cache_size=200, class_weight='auto', degree=3, gamma=0.0, kernel='linear', max_iter=-1, probability=True, random_state=None, shrinking=True, tol=0.001, verbose=False)

elif set_classifier_name == 'GB':

 識別器をGradient Boosting Decision Treeに設定

from sklearn.ensemble import GradientBoostingClassifier
classifier = GradientBoostingClassifier(n_estimators=1000)

elif set_classifier_name == 'LR':

 識別器をロジスティック回帰に設定

from sklearn.linear_model import LogisticRegression
classifier = LogisticRegression()

else:
print('Wrong classifier name')
exit

 識別器のパラメータを表示

print("Parameters: ", classifier)
print()

 leave-one-out 検定

names = list(set(train_labels)) 

print (names)

preds = np.zeros(sample_num_all, dtype=int)
preds[:] = -1
hits = 0
weight_mean = np.zeros(sample_dim)

from sklearn.cross_validation import LeaveOneOut
loo = LeaveOneOut(n=sample_num_all)
for train_index, test_index in loo:

print("TRAIN:", train_index, "TEST:", test_index)  

print('\n\nStart ID['+str(test_index)+']')
sys.stdout.flush()
X_train, X_test = train_data[train_index], train_data[test_index]
y_train, y_test = train_labels[train_index], train_labels[test_index]  
classifier.fit(X_train, y_train)
preds[test_index] = classifier.predict(X_test)

 テストサンプルの特徴量の表示

        print('Test feature vector ',X_test[0,:])

        pl.bar(range(len(X_test[0,:])), X_test[0,:])

        pl.show()

if(set_classifier_name == 'SVM'):
weight_mean += classifier.coef_[0]

            print('Minus weights (-) assigned to features: class 1')

            print('Plus weights (+) assigned to features: class 2')

            pl.bar(range(len(classifier.coef_[0])), classifier.coef_[0])

            pl.show()

if(preds[test_index] == y_test[0]):
hits += 1
print('ID'+str(test_index)+' OK, predicted label'+str(preds[test_index])+', true label '+str(y_test[0]))
else:
print('ID'+str(test_index)+' NG, predicted label'+str(preds[test_index])+', true label '+str(y_test[0]))

        print('predict_proba ',classifier.predict_proba(X_test))

        print('decision_function ',classifier.decision_function(X_test))

accuracy = hits/float(sample_num_all)*100.0

 SVMの重みの平均値を表示

if(set_classifier_name == 'SVM'):
weight_mean =  weight_mean/sample_num_all
print('\n\n average weights', weight_mean)
print('Minus weights (-) assigned to features: class 1')
print('Plus weights (+) assigned to features: class 2')
pl.bar(range(len(classifier.coef_[0])), classifier.coef_[0])
pl.show()

 leave-one-out 検定の結果を confusion matrix で表示

from sklearn.metrics import confusion_matrix
cmat_org = confusion_matrix(train_labels, preds)
print('Confusion matrix: [rows represent true outcome, columns predicted outcome]')
print(cmat_org)

 各クラスのテスト枚数が違うので,クラス毎に総数で割ることで正規化して表示

cmat_org_sum = cmat_org.astype(np.float).sum(axis=1)[:, np.newaxis]

print('Sum cmat\n',cmat_org_sum)

cmat = cmat_org.astype(np.float) / cmat_org_sum
print()
print('Normalized confusion matrix: [rows represent true outcome, columns predicted outcome]')
print(cmat)
pl.gray()
pl.imshow(cmat, interpolation='nearest')
pl.title('Confusion matrix')
tick_marks = np.arange(len(names))
pl.xticks(tick_marks, names, rotation=45)
pl.yticks(tick_marks, names)
pl.ylabel('True label')
pl.xlabel('Predicted label')
pl.colorbar()
pl.show()
print()

 leave-one-out 検定で求めた一位正解率の平均値を計算

print()
print('Average accuracy: {0:.3}'.format(accuracy))
print()
%%%%%%%%%%%%%%%%%%%%ソースコード終わり%%%%%%%%%%%%%%%%%%%%%%%%%
以下コンソールでの出力内容です.

Check training samples




(省略)

Training dim.: 5
Num. of training samples of each class: [13L, 13L]
Num. of training samples: [13L, 13L]
All training sample num.: 26

Parameters:  SVC(C=10, cache_size=200, class_weight='auto', coef0=0.0, degree=3, gamma=0.0,
kernel='linear', max_iter=-1, probability=True, random_state=None,
shrinking=True, tol=0.001, verbose=False)

average weights [ 0.05039592 -0.05110899 -0.80647023 -0.21696006  1.02414335]
Minus weights (-) assigned to features: class 1
Plus weights (+) assigned to features: class 2

Confusion matrix: [rows represent true outcome, columns predicted outcome]
[[ 0 13]
[13  0]]

Normalized confusion matrix: [rows represent true outcome, columns predicted outcome]
[[ 0.  1.]
[ 1.  0.]]

Average accuracy: 0.0

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

まだ回答がついていません

同じタグがついた質問を見る

  • Python 2.7

    1413questions

    Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。