classifier.py

 설계부분의 classifier 모듈을 구현하였다. classifier 라는 클래스가 하나 있으며 그 클래스를 통해 댓글이 선플인지 악플인지 판단한다.  클래스 외부에서는 classify라는 멤버함수에 덧글을 넘겨 호출하면 숫자를 하나 리턴받는데 그 수가 양수면 선플이고 그렇지 않으면 악플이다.

def classify(self, comment):
  # build wordiddic -> { wordid:frequency, wordid:frequency, ... }
  worddic = getterms(comment)
  words = worddic.keys()
  wordiddic = {}

  for word in words:
    cur = self.con.execute("select rowid from wordlist where word = '%s'" % umbcs(word))
    res = cur.fetchone()
    if res == None: continue # ignore unadded words
    else: wordiddic[res[0]] = worddic[word]

  # build line -> "0 wordid:frequency worid:frequency ..." (wordid asc)
  line = "0 "
  for wordid, frequency in sorted(wordiddic.items(), key=lambda item:item[0]):
    line = line + str(wordid) + ":" + str(frequency) + " "

  return svmclassifier(line + "\n")

 getterms 은 댓글을 입력하면 명사와 그 댓글에서의 명사 출현회수를 담은 사전을 리턴하고 svmclassifier 는 댓글을 단어 출현횟수를 자질로 백터화해서 넘기면 악플 집단인지 선플집단인지 분류해준다.

analyzer.py

  설계부분의 analyzer 모듈을 구현하였다. analyzer 라는 클래스가 하나 있으며 그 클래스를 통해 데이터셋을 분석한다.  클래스 외부에서는 probability 라는 멤버함수에 단어를 넘겨 호출하면 문자열을 하나 리턴받는데 단어가 데이터셋에 없을 경우 "no data"를 그렇지 않을경우 단어가 악플에 포함되었을 확률이다.

def probability(self, term):
  # get wordid
  res = self.con.execute("select rowid from wordlist where word = '%s'" % umbcs(term)).fetchone()
  if res == None: return "no data"
  else: wordid = res[0]

  # get case -> [-1, 1, ...] (-1 : bad, 1 : good)
  case = []
  for commentid in self.con.execute("select commentid from wordlocation where wordid = %d" % wordid).fetchall():
    for status in self.con.execute("select status from commentlist where rowid = %d" % commentid[0]).fetchall():
      case.append(status[0])

  # return -> "no data" or "48%"
  return str(int((case.count(-1) / float(len(case))) * 100)) + "%"

 성능을 고려하지 않고 작성하였으며 댓글이 10만개가 넘어갈 경우 재작성 되어야 할 것이다. 아마 데이터 베이스를 갈아타거나 적절히 여러파일로 나눠서 처리해야 할 것이다. 데이터베이스에서 해당단어가 포함된 댓글을 가져와서 악플의 수를 모든댓글의 수로 나누었다.

result

 위 두함수를 이용해서 간단한 악플판별 웹페이지를 작성하였다. python 으로 작성하였고 django 프레임웍을 이용하였다. 국내호스팅중 django를 지원하는 호스팅이 없기때문에 안타깝게도 스크린샷을 으로 대체한다.

사용자 삽입 이미지

이올린에 북마크하기(0) 이올린에 추천하기(0)

2007. 10. 6 - 첫번째 설계를 토대로 작성하였다. 아래 나오는 그림중 calculate()함수를 구현하였고 이 함수는 숫자와 '.' 로만 이루어진 피연산자(실수) 그리고 사칙연산('+','-','*','/') 및 괄호['(',')'] 등만 포함하는 수식의 값을 구해주는 함수이다.

- in processor


void parser(char *);

void calculate(char *);



calculate가 계산해야하는 수식은 다음과 같이 간단하게 syntax 를 정의할 수 있다.

 expr = expr + term
       | expr - term
       | term

 term = term * factor
       | term / factor
       | factor

 factor = digit
       | (expr)


그리고 이 syntax는 다음과 같이 같단하게 구현될 수 있다
 

more..

위에서 보는바와 같이 caculrator() 구현을 위해 다음과 같은 함수가 추가되었다

int isExpression(const char *);
void getNextToken(void);
double expr(void);
double term(void);
double factor(void);

다음은 간단한 실행화면이다.

사용자 삽입 이미지





사용자 삽입 이미지

 




사용자 삽입 이미지







 이렇게 하여 프로젝트 스펙의 1번 기본적인 사칙연산 수행은 구현되었다. 풀코드는 후배들이 과제중이므로 나중에 공개하겠다.


프로젝트 메인으로

이올린에 북마크하기(0) 이올린에 추천하기(0)