lolamontes69

Ch6 Ex3-Programming Collective Intelligence.

Jul 17th, 2013
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.57 KB | None | 0 0
  1. """ Chapter 6 Exercise 3: A POP-3 email filter
  2.  
  3.    Python comes with a library called poplib for downloading email messages.
  4.    Write a script that downloads email messages from a server and attempts to classify them.  *see end of file for usage.
  5.  
  6.    What are the different properties of an email message, and how might you build a feature-extraction function to take advantage of them?     *I incorporated a couple of features into the script. Also see end of file.
  7. """
  8.  
  9. import poplib, email, string
  10. import getpass as getpass
  11. import re as re
  12.  
  13. def getwords(doc):
  14.     # Adds intact emails and urls. Removes numbers. Splits words by non-alpha.
  15.     splitter=re.compile('\\W*')
  16.     emails = re.findall("[\w.]+@[\w.]+", doc)
  17.     for a in range(len(emails)):  
  18.         if emails[a][-1] == '>':emails[a]= emails[a][:-1]
  19.     urls = re.findall('http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', doc)
  20.     for a in range(len(urls)):  
  21.         if urls[a][-1] == '>':urls[a]= urls[a][:-1]
  22.  
  23.     for a in urls:
  24.         doc = doc.replace(a," ")
  25.     for a in emails:
  26.         doc = doc.replace(a," ")
  27.  
  28.     doc = ''.join(i for i in doc if not i.isdigit())
  29.     words=[s.lower() for s in splitter.split(doc) if len(s)>2 and len(s)<20]
  30.     words = words + urls + emails
  31.     # Return the unique set of words only
  32.     return dict([(w,1) for w in words])
  33.  
  34. def read(message,fulltext,classifier):
  35.     print message
  36.  
  37.     # Print the best guess at the current category
  38.     guess = str(classifier.classify(fulltext))
  39.     print '\nGuess: '+ guess
  40.  
  41.     # Ask the user to specify the correct category and train on that
  42.     cl=raw_input('Enter category: ')
  43.     if cl == "": cl = guess                                # If the guess is correct just press enter as a timesaver
  44.     classifier.train(fulltext,cl)
  45.  
  46. def get_mails(classifier):
  47.     # Made for usage with gmail.
  48.     username = str(raw_input('Enter username >'))          # 'recent:YOURUSERNAME' limits it to last months mail
  49.     password = getpass.getpass(prompt='Enter password >')
  50.  
  51.     mailserver = poplib.POP3_SSL('pop.gmail.com')
  52.     mailserver.user(username)                  
  53.     mailserver.pass_(password)
  54.     (numMsgs, totalSize) = mailserver.stat()               # Print some stats...
  55.     print "numMsgs =",numMsgs,"\ntotalSize =",totalSize    # just so you know what's coming :)
  56.     paused = raw_input('Press <ENTER> to continue')        # Dramatic pause
  57.  
  58.     numMessages = len(mailserver.list()[1])
  59.     for i in reversed(range(numMessages)):
  60.         fulltext = ""
  61.         message = "_________________________________\ni =" + str(i)
  62.         message += "\n_________________________________\n" # reversed runs the range in reverse
  63.         msg = mailserver.retr(i+1)
  64.         str1 = string.join(msg[1], "\n")
  65.         mail = email.message_from_string(str1)
  66.         try:
  67.             message += "From: " + mail["From"] + "\n" + "Subject: " + mail["Subject"] + "\n" + "Date: " + mail["Date"] + "\n"
  68.             fulltext += mail["From"] + " " + mail["Subject"] + " "
  69.         except: pass
  70.         for part in mail.walk():
  71.             if part.get_content_type() == 'text/plain':
  72.                 message += "Body: " + part.get_payload()   # adds the raw text to message
  73.                 fulltext += part.get_payload()
  74.         read(message,fulltext,classifier)                  # train the database
  75.  
  76. """
  77. ###############################################################################
  78.  
  79. #############
  80.   Usage:
  81. #############
  82. import docclass_ex1 as docclass
  83. import emailfilter as emailfilter
  84. cl=docclass.fisherclassifier(emailfilter.getwords)
  85. cl.setdb('emails.db')
  86.  
  87. emailfilter.get_mails(cl)         # get mails and run the training function
  88.  
  89. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  90.   Improving performance:
  91. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  92. #    set_ap() in docclass_ex1 can be used to add extra assumed probability.
  93. #    example emails from rosalyn always come from the same address
  94. #    and she always signs them rosalyn so we can weight them accordingly
  95.  
  96. cl.set_ap('[email protected]','rosalyn',7.0)
  97. cl.set_ap('rosalyn','rosalyn',2.0)
  98.  
  99. #    URL's are saved which should help classifying if they are always used in
  100. #    signatures or elsewhere in the messages from a certain contact.
  101.  
  102. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  103.   Some entry correcting commands:
  104. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  105. cl.con.execute("update fc set category='french' where category='None'")
  106. cl.con.execute("update cc set count=236 where category='french'")
  107. cl.con.execute("delete from cc where category='None'")
  108.  
  109. ###############################################################################
  110.  
  111. ##############################
  112. Properties of an email message
  113. ##############################
  114.  
  115. Emails contain a sender address and many also contain signatures in the body
  116. of the message. These properties will be handy in helping to classify.
  117. The messages have a subject field that often reveals the subject of the mail;
  118. I rarely fill it in with useful info and wouldn't base a spam filter around it.
  119. There's a date field, and there is also a field containing the ipaddress of
  120. the sender, in case you are getting spammed from a certain server's SMTP.
  121. Incorporating any feature would be simply a matter of extracting it from the
  122. message either with the regex or email modules, and adding it to the database.
  123.  
  124. ###############################################################################
  125. """
Advertisement
Add Comment
Please, Sign In to add comment