PHP名前による男女の性別分析(PythonからPHPへ)

24300 ワード

PHPは姓名分析男女性別参考:https://github.com/observerss/ngender統計データのダウンロード:https://download.csdn.net/download/webben/11253847

$name = $argv[1];
$gender = new Gender();
$ret = $gender->guess( $name);
echo $name."\t".$ret[0]."\t".$ret[1];

class Gender
{
    /**
     * @var int     
     */
    protected $total = 0;

    /**
     * @var int   
     */
    protected $male_total = 0;

    /**
     * @var int   
     */
    protected $female_total = 0;

    /**
     * @var array   
     */
    protected $freq = array();

    protected $sample = './charfreq.csv';

    public function __construct()
    {
        $this->load_model();
    }

    public function guess( $name)
    {
        $name = $this->name_to_array( $this->to_utf8( $name));
        array_shift( $name);
        foreach( $name as $val)
        {
            if( !$this->is_chinese( $val)) {
                throw new Exception('       ');
            }
        }
        $pf = $this->prob_for_gender( $name, 0);
        $pm = $this->prob_for_gender( $name, 1);
        if( $pm > $pf){
            return array( 'male', $pm/( $pm+$pf));
        }elseif( $pm < $pf){
            return array( 'female', $pf/( $pm+$pf));
        }
        return array( 'unknown', 0);
    }

    protected function prob_for_gender( $name, $gender = 0)
    {
        $p = ( $gender == 0)
            ? $this->female_total  / $this->total
            : $this->male_total  / $this->total;
        foreach( $name as $val)
        {
            $p *= $this->freq[$val][$gender];
        }
        return $p;
    }

    protected function is_chinese( $name)
    {
        return preg_match('/^[\x{4e00}-\x{9fa5}]+$/u', $name) === 1;
    }

    protected function name_to_array( $name)
    {
        preg_match_all("/./u", $name, $matches);
        return $matches[0];
    }

    protected function load_model()
    {
    	if( !file_exists( $this->sample)) throw new Exception('       ,   :https://download.csdn.net/download/webben/11253847');
        $fp = fopen( $this->sample, 'r');
        fgetcsv( $fp);
        while( ($line = fgets( $fp)) !== false)
        {
            $line = trim( $line);
            list( $char, $male, $female) = explode(',', $line);
            $char = $this->to_utf8( $char);
            $this->male_total += $male;
            $this->female_total += $female;
            $this->freq[$char] = array( $female, $male);
        }
        $this->total = $this->male_total + $this->female_total;
        foreach( $this->freq as $char => $val)
        {
            list( $female, $male) = $val;
            $this->freq[ $char] = array( $female/$this->female_total,
                $male / $this->male_total);
        }
    }

    protected function to_utf8( $name)
    {
        return $name;
    }
}

NGender
中国語の名前から性別を推測する
  • 20行未満の純Pythonコード(コア部分)
  • 依存ライブラリなし
  • 82%の精度
  • は、性別を推測するために用いることができる
  • .
  • 名前の男性化/女性化の程度を判断するためにも用いることができる
  • 使用
    コマンドラインで
    $ ng        
    name:     => gender: male, probability: 0.9836229687547046
    name:     => gender: female, probability: 0.9759486128949907
    

    もちろんPythonプログラムでも使えます
    php ngender.php    
    ('male', 0.9836229687547046)
    
    php ngender.php    
    ('female', 0.9759486128949907)
    

    げんり
    数学
    ベイズの式:P(Y|X) = P(X|Y) * P(Y) / P(X)X条件が独立している場合、P(X|Y) = P(X1|Y) * P(X2|Y) * ...名前を当てる
    P(gender= |name=  ) 
    = P(name=  |gender= ) * P(gender= ) / P(name=  )
    = P(name has  |gender= ) * P(name has  |gender= ) * P(gender= ) / P(name=  )
    

    計算#ケイサン#
  • ファイルcharfreq.csvはどうやって来ましたか?開房記録というものがあった.avi(霧)、名前と性別、2000 w条、統計すると
  • はどうしてP(name has |gender= )ですか?「本」が男性名に出現する回数/男性字が出現する総回数
  • はどうしてP(gender= )ですか?男性名の出現回数/総回数
  • はどうしてP(name= )ですか?いいえ、確率を計算するときはお互いに
  • を約束します.
    くぼみ
    php ngender.php    
    ('male', 0.851334658742)
    

    どちらも男性寄りですが、合わせて女性名です