質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

3回答

1924閲覧

【機械学習】予測系のモデルを作成する際、文字列が含んでいるデータでも処理することは可能か

essa

総合スコア81

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2019/09/04 12:54

お世話になります。

標記について、教えていただきたいことがあります。

予測系の機械学習モデルをする際、モデルにより色々有ると思いますが、だいたいが下記のような特徴があるかと思います。

  1. 欠損値がない
  2. カテゴリカルの文字列がない(文字が含まれる場合は0や1などに変換する)
  3. データが大量にある

などなどです。
(他にもたくさんあるかと思いますが、これ以上わからないので。。。)
大体が数値に変換して、モデルを作成していくものだと理解しています。
もし、データの中に文章があった場合、それをどうにかして特徴ある数字列に変換して学習することは可能なのでしょうか?

たとえば、下記のようなデータセットがあったとします。
|採用/不採用|性別|年齢|前職の給料|前職の経験年数|面接時の特徴|
|:--|:--:|--:|
|1|0|25|28|2|hogehogehogehogehoge|
|0|0|45|50|20|piyopiyopiyopiyopiyopiyopiyopiyopiyopiyo|
|0|1|32|38|15|foofoofoofoofoofoofoofoofoofoofoofoo|
|1|1|33|35|10|hohogepiyohogepiyohogepiyohogepiyohogepiyogepiyo|
|1|0|29|30|5|foohogefoohogefoohogefoohogefoohogefoohoge|

目的変数を「採用/不採用」だとして、説明変数をそれ以外のすべてだとします。
しかし、「面接時の特徴」に関しては面接官の所感が記載された文章データだとします。
この文章データをどうにかして特徴ある数字の列に変換し、「採用/不採用」の予測モデルを作成することは
可能なのでしょうか?

ご存じの方がいましたら、教えていただければと思います。
どうぞよろしくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

よくあるのがテキストのベクトル化です。

基本的なものにBoW(Bag of words)というものがあります。以下、簡単なイメージとコードです。BoWはscikit-learnのCountVectorizerで簡単に実行できます。

python

1from sklearn.feature_extraction.text import CountVectorizer 2import pandas as pd 3 4text_df = pd.DataFrame({'text':[ 5 '沖縄 福岡 広島', 6 'Go Python Java', 7 '西武 ソフトバンク 楽天', 8 '巨人 ヤクルト', 9 '西武', 10 '西武 ライオンズ ファン' 11 ]}) 12 13cv = CountVectorizer() 14cv_vec = cv.fit_transform(text_df['text']) 15 16print(cv_vec.toarray()) 17 18[out](結果) 19[[0 0 0 0 0 0 0 0 1 0 1 1 0] 20 [1 1 1 0 0 0 0 0 0 0 0 0 0] 21 [0 0 0 1 0 0 0 0 0 1 0 0 1] 22 [0 0 0 0 0 1 0 1 0 0 0 0 0] 23 [0 0 0 0 0 0 0 0 0 0 0 0 1] 24 [0 0 0 0 1 0 1 0 0 0 0 0 1]]

ベクトル化するモジュールはscipyのスパースマトリックス形式で返ってきます。なので結果が見たいときは上のように toarray()メソッドを使ってください。

また、長文に対しては上のBoWよりもTF-IDFがよく使われます。
TF-IDFはそれぞれ

TF(w, d): Term Frequencyの略。その文書dに含まれる単語tの数
IDF(w, d): Inverse Document Frequencyの略。その単語tのレア度みたいなもの。式で書くと

math

1\log \frac{文書の数}{単語????を含む文書の数}

となります。

python

1from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer 2tfidf = TfidfVectorizer() 3tfidf_vec = tfidf.fit_transform(text_df['text']) 4 5#結果の確認 6col = tfidf.get_feature_names() 7pd.DataFrame(tfidf_vec.toarray(), columns=col) 8 9[out](結果) 10 go java python ソフトバンク ファン ヤクルト ライオンズ 巨人 広島 楽天 沖縄 福岡 西武 110 0.00000 0.00000 0.00000 0.000000 0.000000 0.000000 0.000000 0.000000 0.57735 0.000000 0.57735 0.57735 0.000000 121 0.57735 0.57735 0.57735 0.000000 0.000000 0.000000 0.000000 0.000000 0.00000 0.000000 0.00000 0.00000 0.000000 132 0.00000 0.00000 0.00000 0.635091 0.000000 0.000000 0.000000 0.000000 0.00000 0.635091 0.00000 0.00000 0.439681 143 0.00000 0.00000 0.00000 0.000000 0.000000 0.707107 0.000000 0.707107 0.00000 0.000000 0.00000 0.00000 0.000000 154 0.00000 0.00000 0.00000 0.000000 0.000000 0.000000 0.000000 0.000000 0.00000 0.000000 0.00000 0.00000 1.000000 165 0.00000 0.00000 0.00000 0.000000 0.635091 0.000000 0.635091 0.000000 0.00000 0.000000 0.00000 0.00000 0.439681

この他にも色々あるので、是非調べて見てください

投稿2019/09/04 13:50

spider-man

総合スコア94

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

essa

2019/09/05 12:35

詳細な回答ありがとうございます。 cv_vec.toarray()を a = pd.DataFrame(cv.toarray())としてしまうと、 一つのカラムじゃなくて、複数のカラムになってしまいます。 上の例だと、カラム数が13になってしまいます。 これを1つのカラムに連結することは可能でしょうか? 上記の処理をしたい理由は、ベクトル化にしたあと、説明変数として使用したいからです。 どうぞよろしくお願い致します。
essa

2019/09/05 13:10

別の話題になってしまっているので、上記の件は別途質問させていただきます。
spider-man

2019/09/05 13:21

分かりづらくて申し訳ございませんでした。 お話しさている通り、別のカラムに入っている状態でかつその殆どが0になっています。疎行列と言います。カテゴリの数が多いカラムをOne-hot-encodingした時もそうですが、一般にそれとは比較にならないほど次元が増えるので、普通numpyの配列ではなく、scipyのスパースマトリックスとしてモデルに入れます。(元々、ベクトルはスカラーではないので一次元では表しきれない。) 一列にはなっていませんが、それでも特徴は出てくる感じです。面接の評価でよく出てくるネガティブワードに対しては、明らかに結果がよくない場合、その列に数値が入っていると結果に影響出るし、逆に合非とは関係ないようなワードの場合、結果には然程影響を与えないかもしれません。 もし、一列で表現したい場合、gnbrganchanさんの通り、ポジネガ判定をするなど色々な手法がかんがえられますが、何れにせよ一度ベクトルの形を挟むことが多いかと思います!
essa

2019/09/05 13:38

スパースマトリックスについて、ありがとうございます! なんとなくわかってきました!本来はスパースマトリックス形式で出力されますが、目に見える形にするようにtoarray()にしていたのですね! 今やりたいことは、文字列を何らかの法則に従ってベクトル化し、数値データを得たいということでした。 なので、toarray()でndarray型にしたデータに対し、 np.sum(df,axis=1) みたいなことをして、特徴量を求めることはできそうだなと思いました。 求めた特徴量を説明変数として、予測モデルは作成できるかなと思いました。 以上のような方法はどうでしょうか。。。 もし、「こうしたほうがいい!」みたいなことがあれば、教えていただけると嬉しいのですが。。
spider-man

2019/09/05 15:47

自分も自然言語処理は専門ではないので、最新の手法はあまり詳しくなくすいません。。。ただデータの現状と課題によって方法は色々考えられると思うので、思いついたり調べてりしたものは取り敢えず実装してみると面白いかと思います。 個人的には、通常のテーブルデータであるなら、ある程度のデータ量がある場合、そのまま疎行列をぶっ込んでも結構面白く、それなりの結果を返してくれる印象はあります。 それとBERTを使った感情分析とか、結構新しい手法で有名です。このサイトとか参考になるのではないでしょうか? https://www.ogis-ri.co.jp/otc/hiroba/technical/similar-document-search/part3.html
essa

2019/09/08 04:09

ご回答ありがとうございます。 >個人的には、通常のテーブルデータであるなら、ある程度のデータ量がある場合、そのまま疎行列をぶ >っ込んでも結構面白く、それなりの結果を返してくれる印象はあります。 上記に関して、マルチポストになってしまうのですが、教えて頂けないでしょうか? マルチポスト先:https://teratail.com/questions/210309 そのまま疎行列を使う方法がちょっとわからず。。。 もし、全てがすべてがDataFrame形式だった場合、 y = df["A"] X=df["B","C","D","E"] で定義できるのだと思います。 しかし、Eが文字列でBoWなどにより特徴量を計算した疎行列形式の場合 y = df["A"] X=df["B","C","D","E"] ではなく、違う記述になるのかなと思います。 疎行列をそのまま使うのはどのようにするのでしょうか? 現状は無理やり np.sum(df,axis=1) として疎行列を行単位で加算させ、特徴量っぽいものを出しています。 しかし、この方法だとせっかくBoWなどでだした特徴量を、意味のないものにしてしまっているのではないかなと思っています。 >BERTを使った感情分析 ありがとうございます。 理論は難しそうですね。 とりあえず手っ取り早く使うにはbert-as-serviceが使えそうですね。
spider-man

2019/09/09 04:31 編集

返信遅れてしまいすいません。。。全て足してします方法は確かに、情報量を減少させてしまう気がします!下記の記事はkaggleのメルカリコンペのチュートリアル的なものですが、疎行列のモデルへの食わし方について非常にわかりやすく書かれているので、参考になるかと思います!(記事の中盤あたりから出てきます。) http://rautaku.hatenablog.com/entry/2017/12/22/195649 カテゴリ変数のエンコーディングは永遠の課題で、色々な手法が検討されていますので、自然言語処理と合わせて是非色々見てみてください!
guest

0

spider-man さんの説明されている、テキストのベクトル化を理解するのに参考になるかもしれない、単純な方法を挙げておきます。

ベクトルとして、文字の出現頻度を使います。
(a, b, c, ..., z)
面接時の特徴が "aaa" ならば (3, 0, 0, ..., 0), "bc" ならば (0, 1, 1, ... , 0) になります。
質問にある採用/不採用のデータセットに対して、文字の出現頻度をベクトルにして入力とし、h の出現頻度が 0 なら不採用、1 以上なら採用という予測器を使うと、訓練データを 100% 分類することができます。

これは、カーネル法の1-スペクトラムカーネル(p-スペクトラムカーネルの p=1 の場合)と関連しています。

投稿2019/09/05 04:08

maq

総合スコア41

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

色々やり方はあってどれがベストというのは非常に難しい問題なのですが、一般的(古典的)なやり方としては形態素解析して抽出した単語からポジティブ・ネガティブなどラベリングして点数化する方法があるかと思います。
(「感情分析」などでぐぐると参考になるかと思います。)
形態素解析

感情分析

投稿2019/09/04 13:40

編集2019/09/04 13:41
gnbrganchan

総合スコア438

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問