3
$\begingroup$

Given an English sentence, I am looking for a programmatic way to tell whether the sentence is written in passive voice.

Currently, I just check if there is a was or were inside the sentence. If yes, then the function will say that the sentence is in passive voice (I do no not know even if this is true). Is there a better approach?


I just want to make a simple detector for passive voice, I do not care much for accuracy and efficiency. Here what I ended up with:

// http://english.stackexchange.com/questions/472/how-can-i-reliably-and-accurately-identify-the-passive-voice-in-writing-or-speec

// forms of be, have and get
int auxilary_verb(char* str) {
    if(strstr(str, "be ") || strstr(str, "been ") || strstr(str, "being ") ||
            strstr(str, "have ") || strstr(str, "had ") || strstr(str, "was ") || strstr(str, "were ")
            || strstr(str, "wasn") || strstr(str, "weren") || strstr(str, "got ") || strstr(str, "get ")
            || strstr(str, "getting ")) {
        return 1;
    } else {
        return 0;
    }
}

// past participles of the verbs here http://web2.uvcs.uvic.ca/elc/sample/beginner/gs/gs_10.htm
int past_participle_transitive_verb(char* str) {
    if(strstr(str, "brought ") || strstr(str, "cost ") || strstr(str, "given ") || strstr(str, "lent ")
            || strstr(str, "offered ") || strstr(str, "passed ") || strstr(str, "played ") || strstr(str, "read ")
            || strstr(str, "sent ") || strstr(str, "sung ") || strstr(str, "sent ") || strstr(str, "taught ") || strstr(str, "written ")
            || strstr(str, "bought ") || strstr(str, "get done ") || strstr(str, "left ") || strstr(str, "made ")
            || strstr(str, "owed ") || strstr(str, "paid ") || strstr(str, "promised ") || strstr(str, "refused ") || strstr(str, "shown ")
            || strstr(str, "taken ") || strstr(str, "told ") ) {
        return 1;
    } else {
        return 0;
    }
}

// Once a week, the house is cleaned by Tom. <- passive
// By the end of the week, I'll be gone. <- not passive, but ok.
int contains_by(char* str) {
    return (strstr(str, "by ") != NULL);
}

// how to find No direct object -> I don't know.
// The subject of the verb phrase is the entity undergoing an action or having its state changed -> I don't know.

int passive_voice(char* str) {
    // relax conditions, by applying || isntead of &&
    if(auxilary_verb(str) || past_participle_transitive_verb(str) || contains_by(str)) {
        return 1;
    } else {
        return 0;
    }
}
$\endgroup$
  • $\begingroup$ "The boys watch the girls while the girls watch the boys who watch the girls go by..." I think you have to think about the "by". Or think of a supreme being, the have's and the have not's, I Got Rhythm, and so on. $\endgroup$ – gnasher729 Nov 25 '16 at 16:19
  • 1
    $\begingroup$ I don't understand what you're asking. If you want something simple and don't care about accuracy, then detecting "was" and "were" is fine: it's simple and inaccurate. Indeed, just returning true for all inputs is also simple and inaccurate. So what are you actually looking for? $\endgroup$ – David Richerby Jan 16 '17 at 12:51
4
$\begingroup$

detecting passive voice is an AI application also used/ implemented in grammar checker/ correction software with proprietary algorithms. there is a complexity/ accuracy tradeoff. simpler algorithms can be useful and better accuracy requires more sophisticated algorithms. here are two papers on the subject including a masters thesis (60p). final link is an open source implementation of passive voice checking used in OpenOffice.

| cite | improve this answer | |
$\endgroup$
  • $\begingroup$ Thanks for the links! From the last link, I downloaded the package, but it has many things. Any help? The other links are also interesting. However, I was looking for something simple, like a pseudocode or something. $\endgroup$ – gsamaras Jan 5 '15 at 21:46
  • $\begingroup$ a simple approach could use part-of-speech tagging and maybe a small dictionary of verbs & variants & attempt to identify subj, look at where the verb is relative to the subject etc., but am not aware of a simple algorithm. an option might be to come up with a set of training sentences and just work up a solution via trial & error & see what accuracy is possible. $\endgroup$ – vzn Jan 5 '15 at 21:52
  • $\begingroup$ Yes, this trial & error is what I am trying to do, but I can't find any simple rules to apply to (like the ones in my post, which are wrong after all). I will keep searching. $\endgroup$ – gsamaras Jan 5 '15 at 22:09
6
$\begingroup$

I recommend you look at methods in the NLP literature for parsing a sentence and identifying its structure, classifying the tense of the sentence and the words present in it, and identifying the subject and object of the sentence. That should help you build a more accurate classifier. If you extract suitable features, given the parse tree, and then apply a suitable machine learning algorithm, you might get a more effective classifier.

| cite | improve this answer | |
$\endgroup$
  • $\begingroup$ This answer is very vague. You do not provide any specific solution. $\endgroup$ – nbro Aug 17 '19 at 14:07
  • $\begingroup$ @nbro, yeah. I accept that criticism. I wish I knew how to make the answer better, but I don't. $\endgroup$ – D.W. Aug 22 '19 at 17:38

Not the answer you're looking for? Browse other questions tagged or ask your own question.