def char_filters(self): """char_filters for janome tokenizer Args: None Returns: list: char_filers """ char_filters = [ UnicodeNormalizeCharFilter(), RegexReplaceCharFilter("[,\.\(\)\{\}\[\]\:\-\"\'\@\!\?]", " "), RegexReplaceCharFilter("\d", " ") ] return char_filters
def janome_document_summarize(document): # 形態素解析(単語単位に分割する) analyzer = Analyzer(char_filters=[ UnicodeNormalizeCharFilter(), RegexReplaceCharFilter(r'[(\)「」、。]', ' ') ], tokenizer=JanomeTokenizer(), token_filters=[ POSKeepFilter(['名詞', '形容詞', '副詞', '動詞']), ExtractAttributeFilter('base_form') ]) text = re.findall("[^。]+。?", document.replace('\n', '')) corpus = [' '.join(analyzer.analyze(sentence)) + u'。' for sentence in text] parser = PlaintextParser.from_string(''.join(corpus), Tokenizer('japanese')) summarizer = LexRankSummarizer() summarizer.stop_words = [' ', '。', '\n'] N = int(len(corpus) / 10 * 3) if N <= 0: N = 3 summary = summarizer(document=parser.document, sentences_count=N) rst = '' print('\n要約:') for sentence in summary: print(text[corpus.index(sentence.__str__())]) rst += text[corpus.index(sentence.__str__())] return summary, rst
def fn_start_document_summarize(text): # 形態素解析(単語単位に分割する) tokenizer = JanomeTokenizer('japanese') char_filters=[UnicodeNormalizeCharFilter(), RegexReplaceCharFilter(r'[(\)「」、。]', ' ')] token_filters=[POSKeepFilter(['名詞', '形容詞', '副詞', '動詞']), ExtractAttributeFilter('base_form')] analyzer = Analyzer( char_filters=char_filters, tokenizer=tokenizer, token_filters=token_filters ) corpus = [' '.join(analyzer.analyze(sentence)) + u'。' for sentence in text] #print(corpus, len(corpus)) # 文書要約処理実行 parser = PlaintextParser.from_string(''.join(corpus), Tokenizer('japanese')) # LexRankで要約を原文書の3割程度抽出 summarizer = LexRankSummarizer() summarizer.stop_words = [' '] # 文書の重要なポイントは2割から3割といわれている?ので、それを参考にsentences_countを設定する。 N = 3 summary = summarizer(document=parser.document, sentences_count = N if len(corpus) < 100 else int(len(corpus)/100)) #summary = summarizer(document=parser.document, sentences_count=1) str = '' for sentence in summary: str += (text[corpus.index(sentence.__str__())]) return str
def tense_analyze(self, text, sentences_count): # 1行1文となっているため、改行コードで分離 # sentences = [t for t in text.split('\n')] sentences = [t for t in text.split('。')] # 形態素解析器を作る analyzer = Analyzer( [ UnicodeNormalizeCharFilter(), RegexReplaceCharFilter(r'[(\)「」、。]', ' ') ], # ()「」、。は全>てスペースに置き換える JanomeTokenizer(), [ POSKeepFilter(['名詞', '形容詞', '副詞', '動詞']), ExtractAttributeFilter('base_form') ] # 名詞>・形容詞・副詞・動詞の原型のみ ) # 抽出された単語をスペースで連結 # 末尾の'。'は、この後使うtinysegmenterで文として分離させるため。 corpus = [' '.join(analyzer.analyze(s)) + '。' for s in sentences] # 連結したcorpusを再度tinysegmenterでトークナイズさせる parser = PlaintextParser.from_string(''.join(corpus), Tokenizer('japanese')) # LexRankで要約を2文抽出 summarizer = LexRankSummarizer() summarizer.stop_words = [' '] # スペースも1単語として認識されるため、ストップワードにすることで除外>する summary = summarizer(document=parser.document, sentences_count=sentences_count) return sentences, corpus, summary
def summarize(text): sentences = [t for t in text.split('\n')] analyzer = Analyzer( [ UnicodeNormalizeCharFilter(), RegexReplaceCharFilter(r'[(\)「」、。]', ' ') ], # ()「」、。は全てスペースに置き換える JanomeTokenizer(), [ POSKeepFilter(['名詞', '形容詞', '副詞', '動詞']), ExtractAttributeFilter('base_form') ] # 名詞・形容詞・副詞・動詞の原型のみ ) corpus = [' '.join(analyzer.analyze(s)) + '。' for s in sentences] parser = PlaintextParser.from_string(''.join(corpus), Tokenizer('japanese')) summarizer = LexRankSummarizer() summarizer.stop_words = [' '] summary = summarizer(document=parser.document, sentences_count=3) x = "" for sentence in summary: x += sentences[corpus.index(sentence.__str__())] return x
def make_corpus(docs, debug=False): """ 複数の文書からコーパスを作成する @docs 文書のリスト @return トークナイズされた文書のリスト """ docs = list( map( lambda d: list( filter(lambda x: x.strip() != "", re.split("\n|。", d.lower())) ), docs)) docs = [ list(map(lambda x: mojimoji.zen_to_han(x), lines)) for lines in docs ] analyzer = Analyzer([ UnicodeNormalizeCharFilter(), RegexReplaceCharFilter(r'[(\)、。「」]', ' ') ], JanomeTokenizer(), [ POSKeepFilter(['名詞', '形容詞', '副詞', '動詞']), ExtractAttributeFilter('base_form') ]) corpus = [ list( itertools.chain.from_iterable( [list(analyzer.analyze(l)) for l in lines])) for lines in docs ] if debug: print("\n".join(corpus)) return corpus
def preprocess(doc, debug=False): """ ドキュメントを引数にとってそれを前処理した上でトークナイズされた文のリストに分割する @param doc 対象のドキュメント @return 前処理されたドキュメントに含まれる文のリスト """ doc = doc.lower() lines = re.split("\n|。", doc) lines = list(filter(lambda x: x != "", map(lambda x: x.strip(), lines))) sentences = copy.deepcopy(lines) lines = list(map(lambda x: mojimoji.zen_to_han(x), lines)) analyzer = Analyzer([ UnicodeNormalizeCharFilter(), RegexReplaceCharFilter(r'[(\)、。「」]', ' ') ], JanomeTokenizer(), [ POSKeepFilter(['名詞', '形容詞', '副詞', '動詞']), ExtractAttributeFilter('base_form') ]) corpus = [' '.join(analyzer.analyze(l)) + '。' for l in lines] if debug: print("\n".join(corpus)) return sentences, corpus
def test_regex_replace_charfilter(self): cf = RegexReplaceCharFilter('蛇の目', 'janome') self.assertEqual('janomeは形態素解析器です。', cf.apply('蛇の目は形態素解析器です。')) cf = RegexReplaceCharFilter('\s+', '') self.assertEqual('abcd', cf.apply(' a b c d ')) cf = RegexReplaceCharFilter('', '') self.assertEqual('abc あいうえお', 'abc あいうえお')
def setUp(self): #aliases = get_word_aliases() char_filters = [ UnicodeNormalizeCharFilter(), RegexReplaceCharFilter('&[^&]+;', '') ] tokenizer = Tokenizer(mmap=True) token_filters = [ FootballCompoundNounFilter(), FootballNounFilter(), POSKeepFilter('名詞') ] self.analyzer = Analyzer(char_filters, tokenizer, token_filters)
def set_analyzer(self): # 形態素解析器を作る self.analyzer = Analyzer( [ UnicodeNormalizeCharFilter(), RegexReplaceCharFilter(r'[(\)「」、。]', ' ') ], # ()「」、。は全てスペースに置き換える JanomeTokenizer(), [ POSKeepFilter(['名詞', '形容詞', '副詞', '動詞']), ExtractAttributeFilter('base_form') ] # 名詞・形容詞・副詞・動詞の原型のみ )
def pros(self, stopwords=False, emojidict={}): self.stopwordslist = set('する') if stopwords: self.stopwordslist.add(stopwords) self.char_filters = [ EmojiCharFilter(emojidict), RegexReplaceCharFilter( r"https?://[\w!\?/\+\-_~=;\.,\*&@#\$%\(\)'\[\]]+|<[:@#]|>|\^[!-/:-@¥[-`\[\]{-~]*$|[!#$%&'()\*\+\-\.,\/:;<=>?@\[\\\]^_`{|}~]", '') ] self.wordclass2 = ['自立', 'サ変接続', '一般', '固有名詞'] self.token_filters = [POSKeepFilter(['名詞', '形容詞']), LowerCaseFilter()] return self.getwords()
def analyse_japanese(self, list_speech): char_filters = [UnicodeNormalizeCharFilter()] for reg in self.char_reg_filter: char_filters.append(RegexReplaceCharFilter(*reg)) a2 = Analyzer(char_filters, self.t, self.token_filters) list_token = [] for item in list_speech: list_token.append([str(token.base_form) for token in a2.analyze(item)]) list_str = [] for j in list_token: str2 = "" for i in j: str2 += i + ' ' list_str.append(str2) return list_str
def get_words(titles, stop_words): '''titlesを形態素解析し、下処理を適用した単語リストを作成する''' char_filters = [ UnicodeNormalizeCharFilter(), RegexReplaceCharFilter(r'text|[ -/:-@!0-9\[-~]', '') ] token_filters = [ POSKeepFilter(KEEP_FILTER), POSStopFilter(STOP_FILTER), LowerCaseFilter() ] tokenizer = Tokenizer(mmap=True) analyzer = Analyzer(tokenizer=tokenizer, char_filters=char_filters, token_filters=token_filters) title_list = [] for title in titles: word_list_per_title = [] for word in analyzer.analyze(title): # アルファベット、平仮名、カタカナ1文字の単語を除外 if (len(word.surface) == 1) \ and (re.compile('[~a-zあ-んア-ン]').fullmatch(word.surface)): continue # ストップワードを除外 if word.base_form in stop_words: continue hinshi_split = word.part_of_speech.split(',') hinshi_taple = (hinshi_split[0], hinshi_split[1]) if hinshi_taple in WEIGHTS_HINSHI_DICT.keys(): word_list_per_title += [word.base_form ] * WEIGHTS_HINSHI_DICT[hinshi_taple] else: word_list_per_title.append(word.base_form) title_list.append(word_list_per_title) # 全title中で1回しか出現しない単語を削除 dic = Dictionary(title_list) valid_word_list = [word_id for word_id, num in dic.dfs.items() if num > 1] title_list_2 = [] for title in title_list: word_list_per_title_2 = [ word for word in title if dic.token2id[word] in valid_word_list ] # 要素が0のtitleを除外 if len(word_list_per_title_2) > 0: title_list_2.append(word_list_per_title_2) return title_list_2, dic
def get_keyword(description: str, reject_symbol=[("[,\.\(\)\{\}\[\]\<\>\○]", " ")]): #analyzerの前処理フィルタ生成 char_filters = [UnicodeNormalizeCharFilter()] #reject_symbolは正規化し名詞判定されないようにする for i in reject_symbol: char_filters.append(RegexReplaceCharFilter(*i)) #tokenizerの初期化、tokenizerインスタンスは使い回す、ループの外で呼び出し初期化 tokenizer = Tokenizer(mmap=True) #品詞取得フィルタ token_filters = [POSKeepFilter(['名詞'])] #各種フィルタ設定でanalyze analyzer = Analyzer(char_filters, tokenizer, token_filters) #リストで返却 return [token.surface for token in analyzer.analyze(description)]
def get_summary(self): # 1行1文となっているため、改行コードで分離 sentences = [t for t in self._text.split('\n')] for i in range(1): print(sentences[i]) # 形態素解析器を作る analyzer = Analyzer( [ UnicodeNormalizeCharFilter(), RegexReplaceCharFilter(r'[(\)「」、。]', ' ') ], # ()「」、。は全てスペースに置き換える JanomeTokenizer(), [ POSKeepFilter(['名詞', '形容詞', '副詞', '動詞']), ExtractAttributeFilter('base_form') ] # 名詞・形容詞・副詞・動詞の原型のみ ) # 抽出された単語をスペースで連結 # 末尾の'。'は、この後使うtinysegmenterで文として分離させるため。 corpus = [' '.join(analyzer.analyze(s)) + '。' for s in sentences] """ for i in range(2): print(corpus[i]) """ # 転職 Advent Calendar 2016 - Qiita 14 日 目 なる 少し ポエム 含む。 # 今年 11 月 SIer Web サービス 会社 転職 する。 """ from sumy.parsers.plaintext import PlaintextParser from sumy.nlp.tokenizers import Tokenizer from sumy.summarizers.lex_rank import LexRankSummarizer """ # 連結したcorpusを再度tinysegmenterでトークナイズさせる parser = PlaintextParser.from_string(''.join(corpus), Tokenizer('japanese')) # LexRankで要約を2文抽出 summarizer = LexRankSummarizer() summarizer.stop_words = [' '] # スペースも1単語として認識されるため、ストップワードにすることで除外する self.summary = summarizer(document=parser.document, sentences_count=2) # 元の文を表示 for sentence in self.summary: print(sentences[corpus.index(sentence.__str__())])
def test_analyze(self): char_filters = [ UnicodeNormalizeCharFilter(), RegexReplaceCharFilter('蛇の目', 'janome') ] tokenizer = Tokenizer() token_filters = [ CompoundNounFilter(), POSStopFilter(['記号', '助詞']), LowerCaseFilter(), ExtractAttributeFilter('surface') ] a = Analyzer(char_filters=char_filters, tokenizer=tokenizer, token_filters=token_filters) tokens = a.analyze('蛇の目はPure Pythonな形態素解析器です。') self.assertEqual(['janome', 'pure', 'python', 'な', '形態素解析器', 'です'], list(tokens))
def janome_analyzer_tf(): """ ref: https://www.tensorflow.org/api_docs/python/tf/strings https://mocobeta.github.io/janome/api/janome.html#module-janome.tokenfilter """ # standarize texts char_filters = [RegexReplaceCharFilter(u'蛇の目', u'janome')] tokenizer = Tokenizer() token_filters = [CompoundNounFilter(), POSStopFilter(['記号', '助詞'])] analyze = Analyzer(char_filters, tokenizer, token_filters).analyze def _tokenizer(text, label): text = text.numpy().decode() tokenized_text = tf.strings.join( [wakati.surface for wakati in analyze(text)], separator=' ') tokenized_text = tf.strings.lower(tokenized_text) return tokenized_text, label return _tokenizer
def lexrank_sumy(text, lang_number): ''' LexRankを実行する text:要約したい文章 ''' text = text.strip() sentences = re.findall("[^。]+。?", text) analyzer = Analyzer( [ UnicodeNormalizeCharFilter(), RegexReplaceCharFilter(r'[(\)「」、。]', ' ') ], # ()「」、。は全てスペースに置き換える JanomeTokenizer(), [ POSKeepFilter(['名詞', '形容詞', '副詞', '動詞']), ExtractAttributeFilter('base_form') ] # 名詞・形容詞・副詞・動詞の原型のみ ) print(lang_number) if lang_number == '1': corpus = [' '.join(analyzer.analyze(s)) + '。' for s in sentences] parser = PlaintextParser.from_string(''.join(corpus), Tokenizer('japanese')) print("japanese") elif lang_number == '2': corpus = [' '.join(analyzer.analyze(s)) + '. ' for s in sentences] parser = PlaintextParser.from_string(''.join(corpus), Tokenizer('english')) summarizer = LexRankSummarizer() summarizer.stop_words = [' '] summary = summarizer(document=parser.document, sentences_count=3) summary_text = '' for sentence in summary: summary_text = summary_text + sentences[corpus.index( sentence.__str__())] + '\n' return summary_text
def janome_analyzer(): """ ref: https://mocobeta.github.io/janome/api/janome.html#module-janome.tokenfilter """ # standarize texts char_filters = [RegexReplaceCharFilter(u'蛇の目', u'janome')] tokenizer = Tokenizer() token_filters = [ CompoundNounFilter(), POSStopFilter(['記号', '助詞']), LowerCaseFilter() ] analyze = Analyzer(char_filters, tokenizer, token_filters).analyze def _tokenizer(text, label): tokenized_text = " ".join( [wakati.surface for wakati in analyze(text.numpy().decode())]) return tokenized_text, label return _tokenizer
def test_analyzer_custom(self): char_filters = [ UnicodeNormalizeCharFilter(), RegexReplaceCharFilter('\s+', '') ] tokenizer = Tokenizer() token_filters = [ CompoundNounFilter(), POSStopFilter(['記号', '助詞']), LowerCaseFilter() ] a = Analyzer(char_filters=char_filters, tokenizer=tokenizer, token_filters=token_filters) self.assertTrue(len(a.char_filters) == 2) self.assertIsInstance(a.char_filters[0], UnicodeNormalizeCharFilter) self.assertIsInstance(a.char_filters[1], RegexReplaceCharFilter) self.assertTrue(len(a.token_filters) == 3) self.assertIsInstance(a.token_filters[0], CompoundNounFilter) self.assertIsInstance(a.token_filters[1], POSStopFilter) self.assertIsInstance(a.token_filters[2], LowerCaseFilter)
def main(): text = '自然言語処理の基礎でも読もうかな。' char_filters = [ UnicodeNormalizeCharFilter(), RegexReplaceCharFilter('自然言語処理', 'NLP') ] tokenizer = Tokenizer() token_filters = [ CompoundNounFilter(), POSStopFilter(['記号', '助詞']), LowerCaseFilter() ] analyzer = Analyzer(char_filters=char_filters, tokenizer=tokenizer, token_filters=token_filters) print(text) for token in analyzer.analyze(text): print(token) print('DONE')
def preprocess_target(doc, debug=False): doc = list(filter(lambda x: x.strip() != "", re.split("\n|。", doc.lower()))) sentences = copy.deepcopy(doc) doc = [mojimoji.zen_to_han(line) for line in doc] analyzer = Analyzer([ UnicodeNormalizeCharFilter(), RegexReplaceCharFilter(r'[(\)、。「」]', ' ') ], JanomeTokenizer(), [ POSKeepFilter(['名詞', '形容詞', '副詞', '動詞']), ExtractAttributeFilter('base_form') ]) corpus = [list(analyzer.analyze(line)) for line in doc] if debug: print(corpus) return sentences, corpus
from janome.tokenfilter import POSKeepFilter, ExtractAttributeFilter text = """多くの会社(店)で営業マンに日報を書かせていることと思います。ですが、何のために日報を書かせているのか、もう一度確認してください。営業マンは社外にいる時間が多く、その行動を把握することはできません。そこで営業マンの行動を把握するために、1日の行動記録を日報にして提出させる場合が多いようですが、日報というのは行動記録を書くことなのでしょうか。そして、営業マンに行動記録をかかせることに、どれだけの意味があるのでしょう。例えば、毎日10件の顧客を訪問している営業マンと、毎日5件訪問している営業マンでは、どちらが評価できるでしょうか。きっと、多くのマネジャーが「もちろん10件の顧客を訪問している営業マンに決まっている」と答えるでしょう。しかし、訪問件数を多くすることだけを考え、準備もそこそこに、休む間もなく得意先を回っているかもしれません。 営業マンにとって問題意識をもつことは基本です。""" # 1行1文となっているため、改行コードで分離 sentences = [t for t in text.split('\n')] for i in range(2): print(sentences[i]) # 転職 Advent Calendar 2016 - Qiitaの14日目となります。 少しポエムも含みます。 # 今年11月にSIerからWebサービスの会社へ転職しました。 # 形態素解析器を作る analyzer = Analyzer( [UnicodeNormalizeCharFilter(), RegexReplaceCharFilter(r'[(\)「」、。]', ' ')], # ()「」、。は全てスペースに置き換える JanomeTokenizer(), [ POSKeepFilter(['名詞', '形容詞', '副詞', '動詞']), ExtractAttributeFilter('base_form') ] # 名詞・形容詞・副詞・動詞の原型のみ ) # 抽出された単語をスペースで連結 # 末尾の'。'は、この後使うtinysegmenterで文として分離させるため。 corpus = [' '.join(analyzer.analyze(s)) + '。' for s in sentences] for i in range(2): print(corpus[i]) # 転職 Advent Calendar 2016 - Qiita 14 日 目 なる 少し ポエム 含む。 # 今年 11 月 SIer Web サービス 会社 転職 する
from janome.tokenizer import Tokenizer from janome.analyzer import Analyzer from janome.charfilter import UnicodeNormalizeCharFilter, RegexReplaceCharFilter from janome.tokenfilter import LowerCaseFilter, CompoundNounFilter, POSKeepFilter, TokenCountFilter import logging logging.basicConfig(level='INFO') print('Analyzer example:') text = '蛇の目はPure Pythonな形態素解析器です。' char_filters = [ UnicodeNormalizeCharFilter(), RegexReplaceCharFilter('蛇の目', 'janome') ] tokenizer = Tokenizer() token_filters = [CompoundNounFilter(), LowerCaseFilter()] a = Analyzer(char_filters=char_filters, tokenizer=tokenizer, token_filters=token_filters) for token in a.analyze(text): print(token) print('') print('Analyzer example: Count nouns with POSKeepFilter and TokenCountFilter') text = 'すもももももももものうち' token_filters = [POSKeepFilter(['名詞']), TokenCountFilter()] a = Analyzer(token_filters=token_filters) for k, v in a.analyze(text): print('%s: %d' % (k, v))
result = connection.execute("TRUNCATE tokens") result = connection.execute( "UPDATE article_contents SET token_extracted = FALSE") connection.close() elif args.recount: connection = engine.connect() result = connection.execute("UPDATE tokens SET occurrence_count = 0") result = connection.execute( "UPDATE article_contents SET token_extracted = FALSE") connection.close() print('Start tokenize') char_filters = [ UnicodeNormalizeCharFilter(), RegexReplaceCharFilter('&[^&]+;', '') ] tokenizer = Tokenizer(mmap=True) token_filters = [ FootballCompoundNounFilter(), FootballNounFilter(), POSKeepFilter('名詞') ] analyzer = Analyzer(char_filters, tokenizer, token_filters) session_maker = sessionmaker(bind=db_connect()) session = session_maker() article_contents = session.query(ArticleContents).filter( Articles.hash == ArticleContents.article_hash, Articles.feed_id == Feeds.id, ArticleContents.token_extracted == False,
#改行で読み込み IDと行 for i, line in enumerate(tsv.split("\n")): if line == "": break #コラムタブで分ける columns = line.split("\t") index = columns[0].split("-")[0] if not index in texts: texts[index] = "" continue texts[index] = texts[index] + columns[1] #形態素解析 char_filters = [ UnicodeNormalizeCharFilter(), RegexReplaceCharFilter('\d+', '0') ] tokenizer = Tokenizer(mmap=True) token_filters = [ POSKeepFilter(["名詞", "形容詞", "副詞", "動詞"]), LowerCaseFilter(), ExtractAttributeFilter("base_form") ] analyzer = Analyzer(char_filters, tokenizer, token_filters) #単語抽出とストップワード stopwords = [] url = "http://svn.sourceforge.jp/svnroot/slothlib/CSharp/Version1/SlothLib/NLP/Filter/StopWord/word/Japanese.txt" with urllib.request.urlopen(url) as response:
text = """転職 Advent Calendar 2016 - Qiitaの14日目となります。 少しポエムも含みます。 今年11月にSIerからWebサービスの会社へ転職しました。 早くから退職することを報告していたこともあって、幸いにも有給消化として1ヶ月のお休みをいただくことができました(これでも10日ほど余らせてしまいました)。 # ・・・ (省略) ・・・ だからこそ、有給消化期間はなんとしてでももぎ取るようにしましょう。""" # 1行1文となっているため、改行コードで分離 sentences = [t for t in text.split('\n')] for i in range(2): print(sentences[i]) # 転職 Advent Calendar 2016 - Qiitaの14日目となります。 少しポエムも含みます。 # 今年11月にSIerからWebサービスの会社へ転職しました。 # 形態素解析器を作る analyzer = Analyzer( [UnicodeNormalizeCharFilter(), RegexReplaceCharFilter( r'[(\)「」、。]', ' ')], # ()「」、。は全てスペースに置き換える JanomeTokenizer(), [POSKeepFilter(['名詞', '形容詞', '副詞', '動詞']), ExtractAttributeFilter( 'base_form')] # 名詞・形容詞・副詞・動詞の原型のみ ) # 抽出された単語をスペースで連結 # 末尾の'。'は、この後使うtinysegmenterで文として分離させるため。 corpus = [' '.join(analyzer.analyze(s)) + '。' for s in sentences] for i in range(2): print(corpus[i]) # 転職 Advent Calendar 2016 - Qiita 14 日 目 なる 少し ポエム 含む。 # 今年 11 月 SIer Web サービス 会社 転職 する。 # 連結したcorpusを再度tinysegmenterでトークナイズさせる