Python によるシンプルな自然言語処理 この記事は、Python をベースにした簡単な自然言語処理タスクの紹介です。この記事のすべてのコードはここにあります。まずは『Python 構文クイックガイド』と『機械学習開発環境セットアップ』を読むことをお勧めします。機械学習に関する詳しい情報については、機械学習、ディープラーニング、自然言語処理分野の推奨書籍リストや、プログラマー向けのデータサイエンスと機械学習の知識体系と資料集を参照してください。 20 ニュース グループ コーパス処理 20 ニュースグループ データセットには、もともと Ken Lang によって収集された、さまざまなニュースグループからの約 20,000 件のドキュメントが含まれています。このセクションには、データセットのキャプチャ、特徴の抽出、単純な分類器のトレーニング、トピック モデルのトレーニングなどが含まれます。この部分のコードには、メイン処理コードのカプセル化ライブラリとノートブックベースのインタラクティブなデモンストレーションが含まれています。まずデータを取得する必要があります: - def fetch_data(self、サブセット= 'train' 、カテゴリ=なし):
- "" "戻りデータ
- データ取得操作を実行する
- 引数:
- subset -> 文字列
- 「」 「 」
- ランダム = np.random.mtrand.RandomState(8675309)
- データ = fetch_20newsgroups(サブセット=サブセット、
- カテゴリ=カテゴリ、
- シャッフル= True 、
- ランダム状態=rand)
-
- self.data[サブセット] = データ
次に、ノートブックでデータ形式をインタラクティブに表示します。 - # オブジェクトをインスタンス化する
- twp = トゥエンティニュースグループ()
- # データを取得
- twp.fetch_data()
- 20_train = twp.data[ 'train' ]
- print( "データセット構造" , "->" , teny_train.keys())
- print( "ドキュメント数" , "->" , len(twenty_train.data))
- print( "ターゲット分類" , "->" ,[twenty_train.target_names[t] for t in tenty_train.target[:10]])
-
- データセット構造 -> dict_keys([ 'data' , 'filenames' , 'target_names' , 'target' , 'DESCR' , 'description' ])
- 文書数 -> 11314
- 対象カテゴリ -> [ 'sci.space' 、 'comp.sys.mac.hardware' 、 'sci.electronics' 、 'comp.sys.mac.hardware' 、 'sci.space' 、 ' rec.sport.hockey' 、 'talk.religion.misc' 、 'sci.med' 、 'talk.religion.misc' 、 'talk.politics.guns' ]
次に、コーパスから特徴を抽出します。 - # 特徴抽出を実行する
-
- # 文書用語マトリックスを構築する
-
- sklearn.feature_extraction.textからCountVectorizer をインポートします
-
- count_vect = カウントベクター化()
-
- X_train_counts = count_vect.fit_transform(twenty_train.data)
-
- print( "DTM構造" , "->" , X_train_counts.shape)
-
- # 語彙内の単語の下付き文字を表示する
- print( "下付き文字に対応する単語" , "->" , count_vect.vocabulary_.get(u 'algorithm' ))
-
- DTM構造 -> (11314, 130107)
- 対応する単語の下付き文字 -> 27366
ドキュメントを分類タスクに使用するには、TF-IDF などの一般的な方法を使用してドキュメントを特徴ベクトルに変換することも必要です。 - # ドキュメントのTF特徴ベクトルを構築する
- sklearn.feature_extraction.textからTfidfTransformer をインポートします
-
- tf_transformer = TfidfTransformer(use_idf= False ).fit(X_train_counts)
- X_train_tf = tf_transformer.transform(X_train_counts)
-
- print( "文書のTF特徴ベクトル" , "->" , X_train_tf)
-
- # ドキュメントのTF-IDF特徴ベクトルを構築する
- sklearn.feature_extraction.textからTfidfTransformer をインポートします
-
- tf_transformer = TfidfTransformer().fit(X_train_counts)
- X_train_tfidf = tf_transformer.transform(X_train_counts)
-
- print( "文書のTF-IDF特徴ベクトル" , "->" , X_train_tfidf)
-
- 文書のTF特徴ベクトル -> (0, 6447) 0.0380693493813
- (0, 37842) 0.0380693493813
特徴抽出、分類器のトレーニング、予測を別々の関数にカプセル化できます。 - def extract_feature(自己):
- 「」 「 」
- コーパスから文書の特徴を抽出する
- 「」 「 」
-
- # トレーニングデータの文書-単語行列を取得する
- self.train_dtm = self.count_vect.fit_transform(self.data[ 'train' ].data)
-
- # ドキュメントのTF機能を取得する
-
- tf_transformer = TfidfTransformer(use_idf = False )
-
- self.train_tf = tf_transformer.transform(self.train_dtm)
-
- # ドキュメントのTF-IDF特徴を取得する
-
- tfidf_transformer = TfidfTransformer().fit(self.train_dtm)
-
- self.train_tfidf = tf_transformer.transform(self.train_dtm)
-
- 定義 train_classifier(自己):
- 「」 「 」
- トレーニングセットから分類器をトレーニングする
- 「」 「 」
-
- 自己抽出機能();
-
- self.clf = 多項式NB().fit(
- self.train_tfidf、self.data[ 'train' ].target)
-
- def predict(self, ドキュメント):
- 「」 「 」
- トレーニングセットから分類器をトレーニングする
- 「」 「 」
-
- X_new_counts = self.count_vect.transform(ドキュメント)
-
- tfidf_transformer = TfidfTransformer().fit(X_new_counts)
-
- X_new_tfidf = tfidf_transformer.transform(X_new_counts)
-
- self.clf.predict(X_new_tfidf)を返します。
次に、トレーニングを実行し、予測と評価を行います。 - # 分類器をトレーニングする
- twp.train_classifier()
-
- # 予測を実行する
- docs_new = [ '神は愛である' 、 'GPU 上の OpenGL は高速である' ]
- 予測 = twp.predict(docs_new)
-
- doc 、zip内のカテゴリ(docs_new、予測):
- print( '%r => %s' % (doc, teny_train.target_names[category]))
-
- # モデル評価を実行する
- twp.fetch_data(サブセット = 'テスト' )
-
- 予測 = twp.predict(twp.data[ 'test' ].data)
-
- numpyをnpとしてインポートする
-
- # エラー計算
-
- # 単純なエラーの意味
- np.mean(予測値 == twp.data[ 'テスト' ].target)
-
- # メトリクス
-
- sklearnからメトリックをインポート
-
- 印刷(metrics.classification_report(
- twp.data[ 'test' ].target、予測、
- ターゲット名 = twp.data[ 'test' ].target_names))
-
- # 混同マトリックス
- metrics.confusion_matrix(twp.data[ 'test' ].target, 予測)
-
- 「神は愛である」 => 社会宗教キリスト教
- 「GPU 上の OpenGL は高速です」 => rec.autos
- 精度再現率 F1スコア サポート
-
- 代替無神論 0.79 0.50 0.61 319
- ...
- トーク.宗教.その他 1.00 0.08 0.15 251
-
- 平均/ 合計 0.82 0.79 0.77 7532
-
- アウト[16]:
- 配列([[158, 0, 1, 1, 0, 1, 0, 3, 7, 1, 2, 6, 1,
- 8, 3, 114, 6, 7, 0, 0],
- ...
- [ 35, 3, 1, 0, 0, 0, 1, 4, 1, 1, 6, 3, 0,
- 6、5、127、30、5、2、21]])
ドキュメント セットからトピックを抽出することもできます。 # トピック抽出を実行する - # トピック抽出を実行する
-
- twp.topics_by_lda()
-
- トピック 0 : ストリーム s1 宇宙飛行士動物園 ローレンティアン メイナード s2 gtoal pem fpu
- トピック 1: 145 cx 0d bh sl 75u 6um m6 sy gld
- トピック 2: アパート WPI 火星 ナチス モナッシュ パレスチナ オスマン帝国 SAS 受賞者 ジェラルド
- トピック 3: リヴジー コンテスト 衛星 タム マシュー 軌道 wpd 結婚 ソルンツェ 教皇
- トピック 4: x11 コンテスト ライブラリ フォント 文字列 contrib visual xterm ahl ブレーキ
- トピック5: ax g9v b8f a86 1d9 pl 0t wm 34u giz
- トピック 6: printf null チャー・メインズ・ベハンナ上院議員拳銃民間人殺人マグパイ
- トピック 7: buf jpeg chi tor bos det que uwo pit blah
- トピック 8: Oracle di t4 risc nist 命令 msg postscript dma コンベックス
- トピック 9: カンジダ クレイ 酵母 バイキング 犬 ヴィーナス ブルーム 症状 観測所 ロビー
- トピック 10 : cx ck hz lk mv cramer adl optilink k8 uw
- トピック 11: リペム rsa サンドビック w0 ボスニア psuvm ハドソン utk ディフェンシブ ビール
- トピック 12: db espn sabbath br ウィジェット liar davidian urartu sdpa 冷却
- トピック 13: ripem dyer ucsu carleton adaptec tires chem alchemy lockheed rsa
- トピック 14: ingr sv alomar jupiter borland het intergraph factory paradox captain
- トピック 15: 民兵 パレスチナ CPR PTS ハンドヘルド シャーク IGC APC ジェイク リーハイ
- トピック 16: アラスカ デューク コル ロシア ウオクノール オーロラ プリンストン NSMCA 遺伝子ステレオ
- トピック 17 : uuencode msg ヘルメット eos サタン dseg 同性愛 ics ギア pyron
- トピック 18: エントリ マイヤーズ x11r4 レーダー 発言 暗号 メイン ハンバーグ シニア ボンチェフ
- トピック 19: カブス、UFL、ビタミン テンプル、GSFC、マッコール、アストロ、ベルコア、ウラン ウェズリアン
共通自然言語処理ツールのパッケージ 上記の 20NewsGroup コーパスの処理の紹介を通じて、一般的な自然言語処理タスクには、データ取得、データ前処理、データ特徴抽出、分類モデルのトレーニング、トピック モデル、または単語ベクトルなどの高度な特徴抽出などが含まれることがわかります。また、python-fire を使用してクラスをコマンド ラインから呼び出せるツールにすばやくカプセル化することに慣れており、外部モジュール呼び出しもサポートしています。このセクションでは、主に中国語のコーパスを例に挙げます。たとえば、中国語の Wikipedia データを分析する必要がある場合は、gensim の Wikipedia 処理クラスを使用できます。 - クラスWiki(オブジェクト):
- 「」 「 」
- Wikipedia コーパス処理
- 「」 「 」
-
- def wiki2texts(self, wiki_data_path, wiki_texts_path= './wiki_texts.txt' ):
- 「」 「 」
- Wikipediaデータをテキストデータに変換する
- 引数:
- wiki_data_path
- 「」 「 」
- wiki_data_pathでない場合は:
- print( "Wiki の圧縮ファイルのパスを入力するか、https://dumps.wikimedia.org/zhwiki/ にアクセスしてダウンロードしてください" )
- 出口()
-
- # Wikipedia コーパスを構築する
- wiki_corpus = WikiCorpus(wiki_data_path、辞書={})
- テキスト数 = 0
-
- と (wiki_text_path, 'w' , encoding= 'utf-8' )を次のように開きます。 出力:
- wiki_corpus.get_texts()内のテキストの場合:
- 出力.write(b ' ' . join (text).decode( 'utf-8' ) + '\n' )
- テキスト数 += 1
- テキスト数% 10000 == 0の場合:
- logging.info( "%d 件の記事が処理されました" % texts_num)
-
- print( "処理が完了しました。OpenCC を使用して簡体字中国語に変換してください" )
キャプチャが完了したら、OpenCC を使用して簡体字中国語に変換する必要があります。クロール後、Jieba 単語分割を使用して、生成されたテキスト ファイルを分割できます。コードはこちらです。python chinese_text_processor.py tokenize_file /output.txt を直接使用してタスクを実行し、出力ファイルを生成します。単語に分割されたファイルを取得したら、それを単純な bag-of-words 表現またはドキュメント単語ベクトルに変換できます。詳細なコードは次のとおりです。 - クラス CorpusProcessor:
- 「」 「 」
- コーパス処理
- 「」 「 」
-
- コーパス2bowを定義します。
- "" "は(vocab,corpus_in_bow)を返します。
- コーパスをBOW形式に変換する
- 引数:
- tokenized_corpus
- 戻る:
- 語彙
- corpus_in_bow
- 「」 「 」
- 辞書 = corpora.Dictionary(トークン化されたコーパス)
-
- # 語彙力をつける
- 語彙 = dictionary.token2id
-
- # 文書のbag-of-words表現を取得する
- corpus_in_bow = [dictionary.doc2bow(text) トークン化されたコーパス内のテキスト]
-
- 返す(語彙、corpus_in_bow)
-
- def corpus2dtm(self, tokenized_corpus=default_documents, min_df=10, max_df=100):
- "" "は(語彙、DTM)を返します
- コーパスを文書-単語マトリックスに変換する
- - dtm -> マトリックス: 文書-単語マトリックス
- 私はデータベースを憎むのが好きです
- 1 1 0 1
- 2 1 0 1 1
- 「」 「 」
-
- type(tokenized_corpus[0])がリストの場合:
- documents = [ " " . join (document) for document in tokenized_corpus]
- それ以外:
- ドキュメント = トークン化されたコーパス
-
- max_df == -1の場合:
- max_df = round(len(ドキュメント数) / 2)
-
- # コーパス統計ベクトルを構築する
- vec = CountVectorizer(min_df=min_df,
- 最大_df=最大_df、
- アナライザー = "単語" 、
- トークンパターン = "[\S]+" ,
- トークナイザー=なし、
- プリプロセッサ=なし、
- stop_words=なし
- )
-
- # データを分析する
- DTM = vec.fit_transform(ドキュメント)
-
- # 語彙力をつける
- 語彙 = vec.get_feature_names()
-
- 返す(語彙、DTM)
単語分割後の文書に対してトピックモデリングや単語ベクトル抽出を実行することもできます。ここでは、単語分割後の文書を使用することで、中国語と英語の違いを無視できます。 - def topics_by_lda(self、tokenized_corpus_path、num_topics=20、num_words=10、max_lines=10000、split= "\s+" 、max_df=100):
- 「」 「 」
- セグメント化されたファイルを読み取り、それに基づいてLDAをトレーニングする
- 引数:
- tokenized_corpus_path -> 文字列
- num_topics ->整数
- num_words ->整数
- max_lines ->整数
- split -> 文字列
- max_df ->整数
- 「」 「 」
-
- # すべてのコーパス情報を保存する
- コーパス = []
-
- と (tokenized_corpus_path、 'r' 、encoding= 'utf-8' )を tokenized_corpusとして開きます。
-
- フラグ = 0
-
- tokenized_corpus内のドキュメントの場合:
-
- # 十分な行が読み込まれたかどうかを判定する
- if(フラグ > max_lines):
- 壊す
-
- # 読んだ内容をコーパスに追加する
- corpus.append(re.split(split, document))
-
- フラグ = フラグ + 1
-
- # コーパスのBOW表現を構築する
- (語彙、DTM) = self.corpus2dtm(コーパス、max_df=max_df)
-
- # LDAモデルをトレーニングする
-
- lda = Ldaマルチコア(
- matutils.Sparse2Corpus(DTM、ドキュメント列 = False )、
- num_topics=トピック数、
- id2word = dict([(i, s) for i, s in enumerate(vocab)]),
- 労働者=4
- )
-
- # トピックデータを印刷して返す
- トピック = lda.show_topics(
- num_topics=num_topics、
- num_words=num_words、
- フォーマット済み = False 、
- ログ = False )
-
- tiの場合、 enumerate(topics)のトピック:
- print( "トピック" , ti, ":" , " " . join (word[0] for word in topic[1]))
この関数は、単語に分割されたファイルを渡して、コマンド ラインから直接呼び出すこともできます。コーパスの単語ベクトルを構築することもできます。コードはこちらです。単語ベクトルの基本的な使い方に慣れていない場合は、Gensim に基づく Word2Vec の実践を参照してください。 - wv_train を定義します(self、tokenized_text_path、output_model_path= './wv_model.bin' ):
- 「」 「 」
- テキストの単語ベクトルをトレーニングし、出力単語ベクトルを保存します。
- 「」 「 」
-
- 文 = word2vec.Text8Corpus(トークン化されたテキストパス)
-
- # モデルのトレーニングを実行する
- モデル = word2vec.Word2Vec(文、サイズ= 250)
-
- # モデルを保存する
- モデル.save(出力モデルパス)
-
- def wv_visualize(self, model_path, word=[ "中国" , "航空" ]):
- 「」 「 」
- 入力した単語に基づいて隣接する単語を検索し、視覚的に表示します
- パラメータ:
- model_path: Word2Vec モデルのアドレス
- 「」 「 」
-
- # モデルをロードする
- モデル = word2vec.Word2Vec.load (model_path )
-
- # 最も類似した単語を見つける
- words = [wp[0] for wp in model.most_similar(word, topn=20)]
-
- # 単語に対応する単語ベクトルを抽出する
- wordsInVector = [単語内の単語のモデル[単語] ]
-
- # PCA次元削減を実行する
- pca = PCA(n_components=2)
- pca.fit(単語をベクトルにフィット)
- X = pca.transform(単語ベクトル内)
-
- # グラフィックを描く
- xs = X[:, 0]
- ys = X[:, 1]
-
- plt.figure(図のサイズ=(12, 8))
- plt.scatter(xs, ys, マーカー= 'o' )
-
- # すべての単語をトラバースしてコメントを追加します
- enumerate(単語)のi、wの場合:
- plt.annotate(
- w、
- xy=(xs[i], ys[i]), xytext=(6, 6),
- textcoords= 'オフセットポイント' 、ha= '左' 、va= '上' 、
- **辞書(フォントサイズ=10)
- )
- plt.show()
[この記事は51CTOコラムニスト「張子雄」によるオリジナル記事です。転載が必要な場合は51CTOを通じて著者にご連絡ください] この著者の他の記事を読むにはここをクリックしてください |