###前提
- Python 3.5.2
- Django 1.10.2
- その他ライブラリは自由に使用可能。
- 教師あり文書分類器は自分で作成。
###質問概要
フォームから記事URLを入力して、入力された記事URLのHTMLを取得して、この記事の文書を元に記事カテゴリを判定し、そのカテゴリを画面に出力するWEBアプリケーションを作成したいですが、方法がわかりません。詳しい方、ご教示願います。
###質問内容
このアプリを完成させるための流れは以下のような流れだと考えています。
- 教師データをスクレイピングしてcsvにカテゴリとテキストの内容を入れる。
- python使ってcsvファイルのカテゴリとテキストの内容をdataframeで呼び込む。
- 文書分類器を作成する。(参考:http://gihyo.jp/dev/serial/01/machine-learning/0003?page=1とhttp://aidiary.hatenablog.com/entry/20100613/1276389337)
- そのdataframeから分類器を訓練させる。(具体的にどのように訓練させていいのかわからないです。)
- djangoのアプリケーションに反映させる。(分類器のコードをどう反映させていいかわからないです。)
と考えています。
それぞれのご指摘or詳しいやり方or参考になるwebサイトを教えてください。
とくに分類器のコードをdjangoを利用してwebアプリケーション化して行くかがわかりません。
###試したこと
作成した分類器はこちらになります。これからhttp://aidiary.hatenablog.com/entry/20090415/1239802199を参考にして形態素解析していきたいと思っています。
python
1#coding:utf-8 2import math 3import sys 4from collections import defaultdict 5 6class NaiveBayes: 7 """Multinomial Naive Bayes""" 8 """クラスの初期化""" 9 def __init__(self): 10 self.categories = set() # カテゴリの集合 11 self.vocabularies = set() # ボキャブラリの集合 12 self.wordcount = {} # wordcount[cat][word] カテゴリでの単語の出現回数 13 self.catcount = {} # catcount[cat] カテゴリの出現回数(=総文章数) 14 self.denominator = {} # denominator[cat] P(word|cat)の分母の値 15 16 17 def train(self, data): 18 """ナイーブベイズ分類器の訓練""" 19 # 文書集合からカテゴリを抽出して辞書を初期化 20 print 21 for d in data: 22 cat = d[0] 23 self.categories.add(cat) 24 25 print "categories = ",self.categories 26 print 27 28 for cat in self.categories: 29 #カテゴリでの単語の出現回数(int型) 30 self.wordcount[cat] = defaultdict(int) 31 #それぞれのカテゴリの出現回数を0にします。 32 self.catcount[cat] = 0 33 34 print "wordcount[cat] = ",self.wordcount[cat] 35 print "catcount[cat] = ",self.catcount[cat] 36 print 37 print 38 39 40 # 文書集合からカテゴリと単語をカウント 41 42 for d in data: 43 cat, doc = d[0], d[1:] 44 self.catcount[cat] += 1 45 print "catcount[",cat,"] = ",self.catcount[cat] 46 print 47 print "cat = ",d[0] 48 print "doc = ",d[1:] 49 print 50 51 for word in doc: 52 print "word = ",word 53 self.vocabularies.add(word) 54 print "vocabularies = ",self.vocabularies 55 #カテゴリの中の出現回数に1追加します。 56 self.wordcount[cat][word] += 1 57 print "wordcount[",cat,"][",word,"] = ",self.wordcount[cat][word] 58 print 59 60 61 62 63 # 単語の条件付き確率の分母の値をあらかじめ一括計算しておく(高速化のため) 64 for cat in self.categories: 65 self.denominator[cat] = sum(self.wordcount[cat].values()) + len(self.vocabularies) 66 print "self.denominator",[cat]," = ",sum(self.wordcount[cat].values()) + len(self.vocabularies) 67 68 69 70 def classify(self, doc): 71 """事後確率の対数 log(P(cat|doc)) がもっとも大きなカテゴリを返す""" 72 best = None 73 max = -sys.maxint 74 for cat in self.catcount.keys(): 75 p = self.score(doc, cat) 76 if p > max: 77 max = p 78 best = cat 79 return best 80 81 def wordProb(self, word, cat): 82 """単語の条件付き確率 P(word|cat) を求める""" 83 # ラプラススムージングを適用 84 # wordcount[cat]はdefaultdict(int)なのでカテゴリに存在しなかった単語はデフォルトの0を返す 85 # 分母はtrain()の最後で一括計算済み 86 return float(self.wordcount[cat][word] + 1) / float(self.denominator[cat]) 87 88 def score(self, doc, cat): 89 """文書が与えられたときのカテゴリの事後確率の対数 log(P(cat|doc)) を求める""" 90 total = sum(self.catcount.values()) # 総文書数 91 score = math.log(float(self.catcount[cat]) / total) # log P(cat), catcount[cat]:記事数 ,total:総記事数 92 for word in doc: 93 # logをとるとかけ算は足し算になる 94 score += math.log(self.wordProb(word, cat)) # log P(word|cat) 95 return score 96 97 def __str__(self): 98 total = sum(self.catcount.values()) # 総文書数 99 return "documents: %d, vocabularies: %d, categories: %d" % (total, len(self.vocabularies), len(self.categories)) 100 101 102if __name__ == "__main__": 103 # Introduction to Information Retrieval 13.2の例題 104 data = [["yes", "Chinese", "Beijing", "Chinese"], 105 ["yes", "Chinese", "Chinese", "Shanghai"], 106 ["yes", "Chinese", "Macao"], 107 ["no", "Tokyo", "Japan", "Chinese"]] 108 109 # ナイーブベイズ分類器を訓練 110 nb = NaiveBayes() #ナイーブベイズクラスのオブジェクトを作成。 111 nb.train(data) 112 print nb 113 print "P(Chinese|yes) = ", nb.wordProb("Chinese", "yes") 114 print "P(Tokyo|yes) = ", nb.wordProb("Tokyo", "yes") 115 print "P(Japan|yes) = ", nb.wordProb("Japan", "yes") 116 print "P(Chinese|no) = ", nb.wordProb("Chinese", "no") 117 print "P(Tokyo|no) = ", nb.wordProb("Tokyo", "no") 118 print "P(Japan|no) = ", nb.wordProb("Japan", "no") 119 120 # テストデータのカテゴリを予測 121 test = ["Chinese", "Chinese", "Chinese", "Tokyo", "Japan"] 122 print "log P(yes|test) =", nb.score(test, "yes") 123 print "log P(no|test) =", nb.score(test, "no") 124 print nb.classify(test)
本当に困っています。ご相談よろしくお願いします。よろしくお願いいたします。
あなたの回答
tips
プレビュー