ユーザー入力のデータを扱っていると、
ゆらぎが存在し、そこからも傾向を取り出したいことがあります。
そうした、文書と言うほどではないカテゴリデータの場合、形態素解析では十分に情報がとりださせないことが多いです。
そこで、最初や最後の文字、文字の長さなどで情報を増やしていくのですが、一番自分が信用しているのがngramです。
特に、日本語/中国語はn=2(バイグラム)でなんとなく、使える情報が取り出せる感じがします。
毎回書くのが面倒なのでまとめておきます。
挙動
targets= ['python','ruby','go'] char_ngram(targets,n=3)
こんな感じで入れると、こんな感じで帰ってきます。
words char1 char2 char3 ngram 0 python p y h pyh 1 python y t o yto 2 python t h n thn 3 python h o NaN ho 4 python o n NaN on ...
コード
いろいろ考えたのですが、普通にforループを回すのが一番楽と気づきました。
こんな関数を作っておきます
import pandas as pd #単語のリストとnを渡す def char_ngram(words,n=2): #文字で分割してDFに res = [] for word in words: res.extend([(word,n) for n in word]) df = pd.DataFrame(res,columns = ['words','char1']) #nの数だけずらしたカラムを生成 f = lambda x,i : x.shift(-1 * (i+1)) for i in range(n-1): df['char' + str(i+2)] = df.groupby('words')['char'+str(i+1)].transform(f,i) #n-gramを結合したカラムを生成 cols = [c for c in df.columns if c.startswith('char')] #charのカラムだけ用意 unit = lambda x : x.str.cat(), df['ngram'] = df[cols].apply(unit,axis=1) return df
ちょいちょい細かいテクニックを使っています。
transform
なんかはwindow関数を再現する時に使いましたが、今回もgroupby
で範囲を絞りつつ、大元の行数を崩さないために使っています。