履歴書データに基づいてジョブ分類を実行するには、どのアルゴリズムを使用する必要がありますか?


28

Rですべてを行っていることに注意してください。

問題は次のようになります。

基本的に、履歴書(CV)のリストがあります。一部の候補者は以前に実務経験があり、いくつかはそうではありません。ここでの目標は、CVのテキストに基づいて、それらを異なる職種に分類することです。私は、候補者が経験を持たない/学生である場合に特に興味があり、卒業後にこの候補者がどの職種に属する可能性が高いかを予測する必要があります。

質問1:機械学習アルゴリズムを知っています。ただし、NLPを実行したことはありません。インターネットでLatent Dirichletの割り当てに出会いました。しかし、これが私の問題に取り組むための最良のアプローチであるかどうかはわかりません。

私の元のアイデア: これを教師付き学習問題にします。ラベル付けされたデータがすでに大量にあると仮定します。つまり、候補者のリストのジョブセクターに正しくラベル付けされています。MLアルゴリズム(つまり、最近傍...)を使用してモデルをトレーニングし、これらのラベルのないデータを入力します。これらのデータは、実務経験がない/学生である候補であり、所属するジョブセクターを予測しようとします。

質問2の更新:履歴書のすべてを抽出してテキストファイルを作成し、各履歴書が非構造化文字列を含むテキストファイルに関連付けられるようにテキストファイルを作成することをお勧めします。テキストマイニング手法をテキストファイルに適用し、データを構造化するか、テキストファイルから使用される用語の頻度マトリックスを作成しますか?たとえば、テキストファイルは次のようになります。

I deployed ML algorithm in this project and... Skills: Java, Python, c++ ...

これは私が「非構造化」、つまりすべてを1行の文字列に折りたたむことによって意味したものです。

このアプローチは間違っていますか?私のアプローチが間違っていると思われる場合は私を修正してください。

質問3:難しい部分は、キーワード識別して抽出する方法です。tmRでパッケージを使用しますか?tm パッケージはどのアルゴリズムに基づいていますか?NLPアルゴリズムを使用する必要がありますか?はいの場合、どのアルゴリズムを調べる必要がありますか?ご覧になる良いリソースをいくつか教えてください。

どんなアイデアでも素晴らしいでしょう。

回答:


14

チェックアウトこのリンクを。

ここでは、非構造化テキストを読み込んでワードクラウドを作成します。この戦略を適用して、ワードクラウドを作成する代わりに、使用する用語の頻度マトリックスを作成できます。アイデアは、構造化されていないテキストを受け取り、何らかの形で構造化することです。Document Term Matricesを使用して、すべてを小文字(または大文字)に変更し、ストップワードを削除し、各職務の頻出用語を見つけます。単語をステミングするオプションもあります。単語をステミングすると、さまざまな形式の単語を同じ単語として検出できます。たとえば、「programmed」と「programming」は「program」にステム処理できます。これらの頻出用語の出現を、MLモデルトレーニングの重み付き機能として追加することができます。

また、これを頻繁なフレーズに適合させて、職務ごとに2〜3語の共通グループを見つけることもできます。

例:

1)ライブラリをロードし、サンプルデータをビルドする

library(tm)
library(SnowballC)

doc1 = "I am highly skilled in Java Programming.  I have spent 5 years developing bug-tracking systems and creating data managing system applications in C."
job1 = "Software Engineer"
doc2 = "Tested new software releases for major program enhancements.  Designed and executed test procedures and worked with relational databases.  I helped organize and lead meetings and work independently and in a group setting."
job2 = "Quality Assurance"
doc3 = "Developed large and complex web applications for client service center. Lead projects for upcoming releases and interact with consumers.  Perform database design and debugging of current releases."
job3 = "Software Engineer"
jobInfo = data.frame("text" = c(doc1,doc2,doc3),
                     "job" = c(job1,job2,job3))

2)次に、テキストの構造化を行います。次のことを行うためのより速い/より短い方法があると確信しています。

# Convert to lowercase
jobInfo$text = sapply(jobInfo$text,tolower)

# Remove Punctuation
jobInfo$text = sapply(jobInfo$text,function(x) gsub("[[:punct:]]"," ",x))

# Remove extra white space
jobInfo$text = sapply(jobInfo$text,function(x) gsub("[ ]+"," ",x))

# Remove stop words
jobInfo$text = sapply(jobInfo$text, function(x){
  paste(setdiff(strsplit(x," ")[[1]],stopwords()),collapse=" ")
})

# Stem words (Also try without stemming?)
jobInfo$text = sapply(jobInfo$text, function(x)  {
  paste(setdiff(wordStem(strsplit(x," ")[[1]]),""),collapse=" ")
})

3)コーパスのソースとドキュメントの用語マトリックスを作成します。

# Create Corpus Source
jobCorpus = Corpus(VectorSource(jobInfo$text))

# Create Document Term Matrix
jobDTM = DocumentTermMatrix(jobCorpus)

# Create Term Frequency Matrix
jobFreq = as.matrix(jobDTM)

これで、頻度行列jobFreqができました。これは(3 x x)行列、3つのエントリ、X個の単語です。

ここからどこへ行くかはあなた次第です。特定の(より一般的な)単語のみを保持し、モデルの機能として使用できます。もう1つの方法は、「java」が「ソフトウェアエンジニア」で80%発生し、「品質保証」で50%しか発生しないなど、各ジョブの説明で使用する単語の割合を単純にすることです。

ここで、「保証」に1つの「r」があり、「発生」に2つの「r」がある理由を調べてみましょう。


あなたの例を見てみたいです。
user1769197 14

簡単な例を使用して更新。
nfmcclure 14

11

キーワードを抽出し、それらの分類子をトレーニングするだけです。これですべてです。

CVのテキストのほとんどは、実際にはスキルに関連していません。たとえば、「Javaの経験があり、非常に効率的です」という文を検討してください。ここでは、7ワードのうち1ワードのみがスキル名であり、残りは分類の精度を低下させるノイズにすぎません。

ほとんどのCVは実際には構造化されていません。または、構造が自由すぎる。または、セクションに通常とは異なる名前を使用します。または、テキストに変換されたときに構造を保持しないファイル形式。構造化されていないテキストから日付、時刻、名前、住所、さらには人々の意図を抽出した経験はありますが、スキル(または大学など)のリストは抽出できません。

CVをトークン化し(場合によってはステム化)、定義済みのリストから単語のみを選択し(LinkedInなどを使用してこのリストを取得できます)、特徴ベクトルを作成し、いくつかの分類子(SVMとNaive Bayesなど)を試してください。

(注:LinkedInのプロファイルを50を超えるクラスに90%以上の精度で分類するために同様のアプローチを使用したため、単純な実装でも十分に機能すると確信しています。)


リンクされたデータを分析しているとしましょう。以前の仕事の経験、教育に関する推奨事項、1つのプロファイルのスキルを1つのテキストファイルにマージし、そこからキーワードを抽出することをお勧めしますか?
user1769197

LinkedInには、ユーザーが自分で割り当てるスキルタグがあり、他のユーザーが承認できるため、基本的に手動でキーワードを抽出する必要はありません。しかし、構造化されていないデータの場合-はい、すべてをマージしてからキーワードを取得すると役立つ場合があります。ただし、主なルールを覚えておいてください試してみてください。理論は優れていますが、異なるアプローチを使用した実際の実験のみが最良のアプローチを示します。
ffriend

@ffriend、そのキーワードリストを取得する方法は?
NG_21

1
@ffriend次の文から "experience" = '5 years'、 "Language" = 'C'を抽出する最良の方法は何ですか。「バグ追跡システムの開発とCでのデータ管理システムアプリケーションの作成に5年を費やしました。」私はNLTKでレーキを使用し、それだけでストップワード+句読点を削除しますが、上記の文章から、私は、おかげで発展途上のような言葉、バグ追跡、システム、作成、データなどを必要としない
ハリド・ウスマン

3
@KhalidUsman:既にNLTLを使用しているため、名前付きエンティティ認識ツール、特に「正規表現によるチャンキング」セクションをご覧ください。通常、名前付きエンティティを抽出するには、キーワードの辞書(「年」、「C」など)と単純なルールセット(「Cを含む」または「<数字>年」など)を使用します。自由形式のテキストから。
-ffriend

7

これは難しい問題です。それを処理する方法はたくさんあります。履歴書は半構造化文書として扱うことができると思います。文書に最小限の構造を持たせることが有益な場合があります。履歴書には表形式のデータが表示されると思います。これらを属性値のペアとして扱うことができます。たとえば、属性「スキルセット」の用語のリストを取得します。

重要な考え方は、「スキル」、「教育」、「公開」などのキーフレーズのリストを手動で構成することです。次のステップは、何らかの方法で構造を活用することにより、これらのキーフレーズに関連する用語を抽出することですテーブルとして)またはこれらのキーフレーズの周りの用語の近接性を利用することにより、たとえば、「Java」という単語が「スキル」という用語に近接しているという事実は、その人がJavaに熟練していることを示します。

これらの情報を抽出した後、次のステップは、これらの各キーフレーズの特徴ベクトルを構築することです。その後、ドキュメントをさまざまなフィールド(キーフレーズごとに1つ)を持つベクトルとして表すことができます。たとえば、プロジェクト教育という2つのフィールドで表される次の2つの履歴書について考えてみましょう。

Doc1:{project:(java、3)(c、4)}、{education:(computer、2)、(physics、1)}

Doc2:{project:(java、3)(python、2)}、{education:(maths、3)、(computer、2)}

上記の例では、頻度とともに用語を示しています。もちろん、用語を抽出する際に、ストップワードを止めて削除する必要があります。例から、履歴書がDoc1である人はD2の人よりもCの方が熟練していることが明らかです。実装に関しては、ドキュメントをLuceneのフィールドベクトルとして表現するのは非常に簡単です。

さて、次のステップは、与えられた職務の履歴書のランク付きリストを取得することです。実際、クエリ(ジョブ仕様)をフィールドベクトルとしても表す場合、それはかなり簡単です。索引付き履歴書のコレクションからLuceneを使用して、候補者(履歴書)のランク付けされたリストを取得するだけです。


アルゴリズム面では、何をお勧めしますか?
user1769197 14

クエリジョブベクトルが与えられた場合、最も類似した履歴書ベクトルを計算するアルゴリズムを意味しますか?あなたは、このようなBM25や言語モデル...などの任意の標準的なアルゴリズムを使用することができます
Debasis

これらのアルゴリズムを聞いたことはありません。これらのNLPアルゴリズムまたはMLアルゴですか?
user1769197 14

これらは標準的な検索モデルです...検索モデルは、ドキュメント(ケースの場合は再開)とクエリ(ケースの場合はジョブ)の類似性を計算する方法を定義します。
デベーシス14

私は情報検索に関する知識を持っていませんが、クラスタリング/最近傍のような機械学習アルゴリズムも私の場合に機能すると思いますか?
user1769197 14

7

私はオンラインの求人サイトで働いており、履歴書に基づいて求人を推奨するソリューションを構築しています。私たちのアプローチでは、人の役職(または学生で知られている場合は望ましい役職)、履歴書から抽出したスキル、および場所(ほとんどの人にとって非常に重要)を取得し、それに基づいて仕事との一致を見つけます。

ドキュメントの分類に関しては、同様のアプローチをとります。標準履歴書モデルとして履歴書ごとにtf idfマトリックスを計算し、その人の役職とスキル(検索するスキルのリストを定義する必要がある)のみを抽出し、それをMLにフィードすることをお勧めしますアルゴリズム。knnとSVMを試してみることをお勧めします。後者は高次元のテキストデータで非常にうまく機能します。線形SVMは、非線形よりも優れた性能を発揮する傾向があります(RBfカーネルを使用するなど)。妥当な結果を出力できる場合は、自然言語パーサー\チャンカー、および正規表現に一致するカスタムビルドフレーズを使用して機能を抽出します。


3つ以上のクラスがある場合でもSVMを使用しますか?そして、自然言語パーサーを使用してどの機能を抽出したいですか?何のために?
user1769197 14

1対残りの戦略を使用して、nクラスのn個のsvmをトレーニングできます。SciKitLearnには、それを自動的に行うコードがあります。技術的にはn-1の分類器が必要ですが、nの方がうまく機能することがわかりました。
サイモン

@Simonこの推薦システムの完全なステップを書いてもらえますか?私はMLでほとんど経験がありません(MS論文を実装します)が、IR分野ではまったく新しいです。現在、私はこのシステムに取り組んでおり、次の手順を書きました。1. NLTKを使用してキーワードを抽出します。2。キーワードとフレーズのスコアを計算します。実装の正しい方法はありますか?おかげで
ハリド・ウスマン

@KhalidUsmanそれがどのように機能するか正確に言うことはできません。最も簡単な解決策は、データをSolrまたはElastic Searchに配置し、MLTレコメンダーの実装を使用することです。より洗練されたアプローチは、キーワードとフレーズを抽出し、LSAを介してドキュメントをプッシュし、結果のベクトルでk-nnを実行することです。次に、協調フィルタリングや全体的な人気など、他の信号を使用することをお勧めします。
サイモン

@Simon、ご指導ありがとうございます。私は2番目の方法を適用していますが、RAKE + NLTKを使用してキーワード/キーフレーズを抽出し、その後tf-idfまたはBM25を適用することを計画していました。私は正しいですか?KNNの方法をもう少し詳しく説明してください。キーワードにknnを適用する方法を意味します。機能としてキーワードを作成する必要がありますか。おかげで
ハリド・ウスマン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.