Python 支持向量机在性别识别中的问题

Python 支持向量机在性别识别中的问题,python,Python,这几天我一直在使用SVM进行一个性别识别项目(python),但我对我得到的结果感到迷茫: 为什么男性召回率为0.09,女性召回率为1?还是女性的精确度只有50% SVM Accuracy: 0.540041067762 Classification report: precision recall f1-score support Females 0.52 1.00 0.68 242 Males 1.0

这几天我一直在使用SVM进行一个性别识别项目(python),但我对我得到的结果感到迷茫:

为什么男性召回率为0.09,女性召回率为1?还是女性的精确度只有50%

SVM Accuracy: 0.540041067762
Classification report:
           precision   recall  f1-score   support
Females       0.52      1.00      0.68       242
Males         1.00      0.09      0.16       245

avg / total       0.76      0.54      0.42       487
我有所有的图像裁剪,对齐和灰度 如何提高精度

我需要更改:clf=svm.SVC()的参数

我的代码:

import os, sys
import numpy as np
import PIL.Image as Image
import cv2
from sklearn import svm
from sklearn.externals import joblib
from sklearn.cross_validation import train_test_split
from sklearn.metrics import classification_report
from sklearn.metrics import accuracy_score


def read_images(path, id, sz=None):
    c = id
    X,y = [], []
    for dirname, dirnames, filenames in os.walk(path):
        for subdirname in dirnames:
            subject_path = os.path.join(dirname, subdirname)
            for filename in os.listdir(subject_path):
                try:
                    im = Image.open(os.path.join(subject_path, filename))
                    im = im.convert("L")
                    # resize to given size (if given)
                    if (sz is not None):
                        im = im.resize(sz, Image.ANTIALIAS)
                    X.append(np.asarray(im, dtype=np.uint8).ravel())
                    y.append(c)
                except IOError as e:
                    print "I/O error({0}): {1}".format(e.errno, e.strerror)
                except:
                    print "Unexpected error:", sys.exc_info()[0]
                    raise
                        #c = c+1

    return [X,y]


def main():

    contador = 0;

    # check arguments
    if len(sys.argv) != 3:
        print "USAGE: example.py </path/to/images/males> </path/to/images/females>"
        sys.exit()

    # read images and put them into Vectors and id's
    [X,x] = read_images(sys.argv[1], 1)
    [Y, y] = read_images(sys.argv[2], -1)

    # R all images and r all id's
    [R, r] = [X+Y, x+y]
    R_train, R_test, r_train, r_test = train_test_split(R, r)

    # Default svm
    clf = svm.SVC()   

    clf.fit(R_train, r_train)

    r_pred = clf.predict(R_test)

    target_names = ['Female', 'Male']
    print "SVM Accuracy:", accuracy_score(r_test, r_pred)
    print "Classification report:\n", classification_report(r_test, r_pred, target_names=target_names) 




if __name__ == '__main__':
    main()
一段时间后,我得到了以下结果:

{'n_jobs': 1, 'verbose': 0, 'estimator__gamma': 0.0, 'estimator__probability': False, 'param_grid': [{'kernel': ['linear'], 'C': [1, 10, 100, 1000]}, {'kernel': ['rbf'], 'C': [1, 10, 100, 1000], 'gamma': [0.001, 0.0001]}], 'cv': None, 'scoring': None, 'estimator__cache_size': 200, 'estimator__verbose': False, 'pre_dispatch': '2*n_jobs', 'estimator__kernel': 'rbf', 'fit_params': {}, 'estimator__max_iter': -1, 'refit': True, 'iid': True, 'estimator__shrinking': True, 'score_func': None, 'estimator__degree': 3, 'estimator__class_weight': None, 'loss_func': None, 'estimator__random_state': None, 'estimator': SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0, degree=3, gamma=0.0,
  kernel='rbf', max_iter=-1, probability=False, random_state=None,
  shrinking=True, tol=0.001, verbose=False), 'estimator__coef0': 0.0, 'error_score': 'raise', 'estimator__tol': 0.001, 'estimator__C': 1.0}

SVM Accuracy: 0.767326732673
Classification report:
             precision    recall  f1-score   support

    Females       0.76      0.77      0.76       294
    Males         0.78      0.77      0.77       312

avg / total       0.77      0.77      0.77       606
我不知道它是否是正确的使用方法,以及给出此结果的参数C和gamma是什么,但是分类器已经改进,有人能告诉我我是否做得很好,结果意味着什么,或者我如何做?谢谢

这张桌子

SVM Accuracy: 0.540041067762
Classification report:
           precision   recall  f1-score   support
Females       0.52      1.00      0.68       242
Males         1.00      0.09      0.16       245
清楚地表明您的分类器将几乎所有示例都标识为女性。为什么呢?100%的召回率意味着所有女性样本都被正确识别为女性,而男性样本的100%准确率意味着分类器认为男性的每个样本确实是男性。另一方面,女性人口50%的准确率意味着,平均而言,在你归类为女性的样本中,只有一半是真正的女性,而另一半是男性


如果你想一想,只有一个结论:你的分类器预测(几乎)任何显示的内容都会有一个“女性”标签。现在,您必须找出发生这种情况的原因。

您似乎正在将每个图像的像素转换为一个数字数组,并希望SVM能够以某种方式区分女性像素序列和男性像素序列


这种“黑魔法”的分类方法不太可能成功。对图像进行某种实际的分析似乎是一种更有前途的方法——可能尝试量化面部特征,甚至只是量化颜色或边缘的数量。但这不是一个简单的爱好项目,你可以在一个周末通过简单的现成工具成功地接近最新技术状态

深卷积网实际上是以这种“黑箱”方式(或你称之为黑魔法)工作的,因此OP可以原谅你尝试这样做。此外,有了免费提供的库,这是一个简单的爱好项目,可以在周末轻松完成,前提是你有一个功能相当强大的GPU。@cfh对,但这里没有神经网络,只有特定坐标下像素的灰度作为“特征”。如果(177413)是特别暗的,你认为是“男性”吗?当然不会,增加更多的像素并不能真正改变这一点。@cfh:对于设计深网的科学家来说,深网不是黑箱。一个实际的实现是黑箱操作,因为神经网络不能证明他们的选择是正确的,但是当你研究它时,理论机制已经很好地解释了,并且完全合理。在这种情况下,我不认为神经网络会提高结果,因为当你不知道它是如何工作的时候,它们很难正常工作(即使你知道了,也很难)。OP应尝试将数据投影到另一个表示形式上,例如使用PCA或随机森林,以便分类器在非线性空间上工作。77%使用最小工作量似乎与“黑箱不起作用”相矛盾,虽然我同意使用sklearn theano,同样多行代码和预训练的神经网络可以让你做得更好。好的,谢谢@cfh,我会尝试不同的裁剪,不同的大小,也许会使图像均衡,但参数:'clf=svm.SVC()'可以改变任何事情吗?一个问题@cfh,这意味着列'suppor',因为训练数据的数量也是487(242+245),我如何知道我创建的SVM模型中支持向量的数量?感谢您要求提供更适合此任务的库:任何支持卷积网络和GPU(假设您有一个像样的GPU)的坚实的深层神经网络库都应该可以工作。看看咖啡馆,火炬7,凯拉斯。。。(最后一个是Python,如果您愿意的话)。所有这些都有训练图像分类深网(通常是ImageNet或CIFAR-10)的示例。谢谢,然后我将使用keras,以便继续使用python,我目前正在使用带有Iris 1536 MB Intel GPU的MacbookPro,这是否足够?本周,我将与SVM一起工作,更改一些参数,然后尝试“keras”。非常感谢@cfhAlso查看千层面。顺便说一句,你应该搜索gamma和C并重新缩放你的特征。如果它们的灰度介于0和255之间,我建议除以255.0(确保得到实际的浮点数)
SVM Accuracy: 0.540041067762
Classification report:
           precision   recall  f1-score   support
Females       0.52      1.00      0.68       242
Males         1.00      0.09      0.16       245