作家は男性ですか、女性ですか。


8

このようなWebサイトの問題の1つは、男性と話しているのか女性なのかわからないことがよくあることです。ただし、テキストの作者の性別を判別するために使用できる簡単なNLP手法を考え出しました。

理論

英語で使用されている文字の約38.1%が母音[a、e、i、o、u]です(以下の参考文献を参照してくださいy。この場合は母音ではありません)。したがって、母音が40%以上の単語女性の単語として定義し、母音が40%未満の単語は男性の単語として定義します。

この定義の他に、単語の男らしさ女性らしさを見つけることもできます。してみましょうCは言葉で子音の数であり、Vは母音の数であります:

  • 単語が女性である場合、それは女性らしさです1.5*V/(C+1)
  • 単語が男性的である場合、それは男性らしさですC/(1.5*V+1)

たとえば、単語catchは男性です。その男らしさは4/(1.5*1+1) = 1.6。言葉phoneは女性的です。その女性らしさは1.5*2/(3+1) = .75

アルゴリズム

テキストの一部の作家の性別を把握する、我々はすべての男性的な単語(Σの男らしさの合計取るM)、およびすべての女性のワード(Σの女性らしさの合計Fを)。Σ場合はMF、私たちは、作家が男性であることを決定しました。それ以外の場合、著者は女性であると判断しました。

信頼レベル

最後に、信頼水準が必要です。ライターが女性であると判断した場合、信頼度はです。ライターが男性であると判断した場合、信頼度はです。2*ΣF/(ΣFM)-12*ΣM/(ΣFM)-1

入力

入力は句読点を含む英語のテキストです。単語はすべてスペースで区切られます(改行や余分なスペースを気にする必要はありません)。一部の単語には文字以外の文字が含まれているため、無視する必要があります(「You're」など)。文字以外の単語(「5」や「!!!」など)に遭遇した場合は、無視してください。すべての入力には、少なくとも1つの使用可能な単語が含まれます。

出力

ライターの性別に応じてMまたはFを出力し、その後に信頼度を出力する必要があります。

  1. There's a snake in my boot.

    • 性別+各単語の男性性/女性性: [M1.0,F1.5,F.75,F.75,M2.0,F1.0]
    • Σ M = 3.0、Σ F = 4.0
    • CL:2*4.0/(4.0+3.0)-1= .143
    • 出力: F .143
  2. Frankly, I don't give a ^$*.

    • [M2.4,F1.5,M1.2,F1.0,F1.5]、Σ M = 3.6、Σ F = 4.0、CL:2*4.0/(4.0+3.6)-1= 0.053、出力:F .053
  3. I'm 50 dollars from my goal!

    • [F.75,M1.25,M1.2,M2.0,F1.0]、Σ M = 4.45、Σ F = 1.75、CL:2*4.45/(4.45+1.75)-1= 0.435、出力:M .435

参考文献

  1. 英語の辞書の単語における母音の割合(38.1%)
  2. 英語テキストにおける母音の割合(38.15%)

コメントは詳細な議論のためのものではありません。この会話はチャットに移動しました
デニス

回答:


5

Pythonの3320の 317 307 286 253 189バイト

h=S=0
for v in input().split():V=sum(map(v.count,'aeiouAEIOU'));C=sum(x.isalpha()for x in v);H=V<.4*C;C-=V;K=[1.5*V/(C+1),C/(1.5*V+1)][H];h+=K*H;S+=K-K*H
print('FM'[h>S],2*max(S,h)/(S+h)-1)

オンラインでお試しください!

Ungolfed

def evaluateWord(s):
    V = len([*filter(lambda c: c in 'aeiou', s.lower())])
    C = len([*filter(lambda c: c in 'bcdfghjklmnpqrstvxzwy', s.lower())])
    isMasculine = V < 0.4*(V+C)
    return C/(1.5*V+1) if isMasculine else 1.5*V/(C+1), isMasculine


def evaluatePhrase(s):
    scores = []
    for word in s.split():
        scores.append(evaluateWord(word))
    masc = 0
    fem = 0
    for score in scores:
        if score[1]:
            masc += score[0]
        else:
            fem += score[0]
    return ('M', 2*masc/(fem+masc)-1) if masc > fem else ('F', 2*fem/(fem+masc)-1)


print(evaluatePhrase("There's a snake in my boot."))

1
セミコロンを使用し、最初の関数をすべて1行に入れると、4バイトを節約できます。オンラインでお試しください!
同志SparklePony 2017

@ComradeSparklePonyありがとう!
wrymug 2017

1
map(e,s.split())代わりに[e(x)for x in s.split()]
Value Ink

1
また、return'FM'[h>S],2*max(S,h)/(S+h)-1最後のほうがよい
Value Ink

1
を介して母音/子音をカウントするより効率的な方法を調べsum(map(s.count,chars))、カウントを253バイトに
Value Ink


4

Pythonの3205 201 197 192バイト

4バイトのため-Thanks @valueインク:lower()予め
-Thanks @Cotyジョナサンサックスマン9バイトの場合:反転状態.4*(v+c)>v-~cするための(c+1)ビットシフトベース子音チェックの代わりにリテラル。

Python 3、192バイト

M=F=0
for i in input().lower().split():
 v=sum(j in'aeiou'for j in i);c=sum(33021815<<98>>ord(k)&1for k in i)
 if.4*(v+c)>v:M+=c/(1.5*v+1)
 else:F-=1.5*v/~c
print('FM'[M>F],2*max(M,F)/(F+M)-1)

オンラインでお試しください!


1
for i in input().lower().split():'aeiou'母音の数だけを調べlowerて、子音の数を減らすだけで済みます。
バリューインク

1
'else'では、除数(c + 1)を括弧なしで-〜cに短縮して、バイトを節約できます。次に、このネガティブを+ =に運び、-=にしてさらに1バイトを節約できます。F- = 1.5 * v /〜c
コティジョナサンサックスマン2017

1
(ifステートメントで)不等式の順序を切り替えると、スペースを削除できるため、1バイト節約できます。if.4 *(v + c)> v
コティジョナサンサックスマン2017

1
これはトリッキーなものですが、ハードコードされたバイナリルックアップテーブルの子音ルックアップを切り替えることで5バイトを節約できます。k in'bcdfghjklmnpqrstvxzwy'for k ...が33021815 << 98 >> ord(k)&1for k ...になる[ tio.run/…オンラインで試す!]
Coty Johnathan Saxman


0

Common Lisp、404バイト

(defun f(x &aux(a 0)c(f 0)m v u)(labels((w(x &aux(p(position #\  x)))(cons(#1=subseq x 0 p)(and p(w(#1#x(1+ p)))))))(dolist(e(w(coerce x'list)))(setf v(#2=count-if(lambda(x)(member x(coerce"aeiouAEIOU"'list)))e)u(#2#'alpha-char-p e)c(- u v)m(and(> c 0)(<(/ v c)4/6)))(and(> u 0)(if m(incf a(/ c(1+(* v 3/2))))(incf f(/ v 2/3(1+ c))))))(format t"~:[F~;M~] ~4f~%"(> a f)(-(/(* 2(if(> a f)a f))(+ a f))1))))

古き良き冗長なlisp!

オンラインでお試しください!

非ゴルフバージョン:

(defun f(x &aux (a 0) c (f 0) m v u)        ; parameter & auxiliary variables
  (labels ((w (x &aux (p (position #\  x))) ; recursive function to split input into words
              (cons (subseq x 0 p) (and p (w (subseq x (1+ p)))))))
    (dolist (e (w (coerce x 'list)))        ; for each word 
      (setf v (count-if (lambda (x) (member x(coerce"aeiouAEIOU"'list))) e) ; count vowels
            u (count-if 'alpha-char-p e)    ; count all alfabetic letters
            c (- u v)                       ; calculate consonants
            m (and (> c 0) (< (/ v c) 4/6))); is male or not?
      (and (> u 0)                          ; if non-empty word
           (if m
               (incf a (/ c (1+ (* v 3/2)))); increase masculinity
               (incf f (/ v 2/3 (1+ c)))))) ; increase femininity
    (format t "~:[F~;M~] ~4f"               ; print
              (> a f)                       ; “gender”
              (-(/ (* 2 (if (> a f)a f)) (+ a f)) 1))))  ; and confidence
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.