kaggleコンテストに参加してバグに取り組んだ最初の経験

kaggleコンペティション( Bag of Wordsのトレーニング)に初めて参加したときの経験を共有したいと思います。 そして、驚くべき結果を達成することはできませんでしたが、「教科書」の例を改善する方法を検索し、見つけた方法について話します(このため、例を簡単に説明します)また、誤算の分析にも焦点を当てます。 この記事は、主にテキストマイニングの分野の初心者を対象としています。 それでも、私の目標は理論ではなく実践を見直すことなので、ほとんどの方法を簡潔かつ単純に説明しますが、より正確な定義へのリンクを示します。 残念ながら、競争はすでに終了していますが、そのための資料を読むことは依然として有用です。 こちらの記事のコードへのリンク。



大会概要



タスク自体は、テキストの感情的な色付けを分析することにあります。 このために、IMDbサイトの映画のレビューと評価が行われました。 評価が> = 7のレビューは肯定的な色で、評価が少ない-否定的と見なされます。 目的:各テキストが評価される(負/正)トレーニングデータでモデルをトレーニングし、テストセットのテキストについてこのパラメーターを予測します。 予測品質は、 ROCカーブと呼ばれるパラメーターを使用して推定されます。 リンクを詳細に読むことができますが、このパラメーターが1に近いほど、予測はより正確になります。



すべての例はPythonで記述されており、 scikit-learnライブラリを使用しています。これにより、必要なすべての分類子とベクトライザーの既製の実装を使用できます。



問題を解決する方法



自由にテキストを使用でき、すべてのデータマイニング分類子には数値ベクトルを入力する必要があります。 したがって、最初のタスクは、テキストブロックをベクトルに変換(ベクトル化)する方法を決定することです。



最も簡単な方法は、Bag of Wordsです。これは、チュートリアルの最初の例から始まります。 この方法では、使用される単語の共通プールを作成し、それぞれに独自のインデックスを割り当てます。 2つの単純なテキストがあるとします。

ジョンは映画を見るのが好きです。 メアリーも映画が好きです。

ジョンはサッカーの試合を見るのも好きです。


一意の単語ごとに、インデックスを関連付けます。



「ジョン」:1、

「いいね」:2、

「宛先」:3

「ウォッチ」:4、

「映画」:5

「また」:6、

「サッカー」:7

「ゲーム」:8

メアリー:9

「あまりにも」:10



これで、これらの各文は次元10のベクトルとして表すことができます。ここで、i番目の位置の数字xは、数字iの下の単語がテキストにx回出現することを意味します。

[1、2、1、1、2、0、0、0、1、1]

[1、1、1、1、0、1、1、1、0、0]


ウィキペディアまたは同じコンテストのこのレビュー記事で詳細を確認してください



一般に、すべてが単純ですが、悪魔は細部にあります。 まず、この例では、セマンティックな意味を持たない単語(a、the、am、i、is ...)が削除されます。 第二に、このマトリックスを使用した操作はRAMで実行されるため、メモリーの量によってマトリックスの許容次元が制限されます。 「MemoryError」を回避するには、単語のプールを最も頻繁に使用される7000個に減らす必要がありました。 教科書のすべての例では、 Random Forest分類子が分類子として使用されています。



その後、さまざまなパラメーターを試してみることをお勧めします。 最初の明白な考えは、 見出し語化を追加することです 。 すべての単語を語彙形式にします。 これを行うには、nltkライブラリの関数を使用します。

from nltk import WordNetLemmatizer wnl = WordNetLemmatizer() meaningful_words = [wnl.lemmatize(w) for w in meaningful_words]
      
      





別の良いアイデアは、テキストのベクトル化方法をわずかに変更することです。 「テキスト内で単語が何回出現したか」という単純な特性の代わりに、少し複雑ですがよく知られているtf-idf (ドキュメントのコレクション内の希少性に応じて単語に値を割り当てます)を使用できます。

検証のために元のプログラムと変更されたプログラムの結果を送信すると、0.843から0.844に改善されます。 これはあまりありません。 この例を基礎として使用すると、十分に実験してより良い結果を得ることができます。 しかし、私は多くの時間を持っていなかったので、結果として、試行は1日5回に制限されています。 そこで、次の部分に進みました。



チュートリアルの次の部分は、 Word2vecというライブラリに基づいて構築されており、単語の数値ベクトルとしての表現を提供します。 さらに、これらのベクトルには興味深い特性があります。 たとえば、ベクトル間の最小距離は、意味が最も似ている単語になります。



したがって、すべての単語を変換すると、各レビューのベクトルのリストが取得されます。 それを単一のベクトルに変換する方法は? 最初のオプションは、算術平均( 平均ベクトル )を単純に計算することです。 結果はBag of Words(0.829)よりもさらに悪いです。



この方法はどのように改善できますか? すべての単語を平均化することは意味をなさないことは明らかです。テキストの感情的な色付けに影響を与えないゴミが多すぎます。 直観的には、評価的な形容詞とおそらく他の言葉が最も影響力があるようです。 幸いなことに、一般名の機能選択の下に、特定のパラメーター(この場合は単語)が結果の変数の値(感情的な色付け)とどの程度強く相関するかを評価できるメソッドがあります。 これらの方法のいずれかを適用し、選択した単語を確認します。

 from sklearn.feature_selection import chi2 from sklearn.feature_selection import SelectKBest select = SelectKBest(chi2, k=50) X_new = select.fit_transform(train_data_features, train["sentiment"]) names = count_vectorizer.get_feature_names() selected_words = np.asarray(names)[select.get_support()] print(', '.join(selected_words))
      
      





その結果、理論を確認する単語のリストを取得します。



演技、驚くべき、迷惑な、避ける、ひどい、悪い、ひどく、美しい、最高の、退屈な、華麗な、がらくた、鈍い、偶数、優れた、素晴らしい、好きな、素晴らしい、非常に、恐ろしい、ただ、ラメ、笑い、愛、愛し、混乱、分、お金、いいえ、何も、ああ、哀れな、完璧な、プロット、無意味な、貧しい、貧しい、ばかげた、保存、スクリプト、愚かな、素晴らしい、想定、ひどい、無駄、無駄、なぜ、素晴らしい、悪い、最悪


ここで平均ベクトルを計算し、最上位リストの単語のみを考慮に入れると(2、3回の実験後に500単語に拡張されます)、次の教育的な例の重心のバッグ(多くではありませんが)をバイパスします(0.846)競争。 このソリューション(トップワードの平均として表記)では、ランダムフォレストも分類子として使用されました。



エラー処理



これで、私の試みの数と競争自体が終わり、私はフォーラムに行って、経験豊富な人々がこの問題をどのように解決したかを調べました。 通常、非常に複雑でマルチパスであるため、本当に優れた結果(0.96以上)になったソリューションについては触れません。 しかし、簡単な方法で高い精度を得ることが可能になったいくつかのオプションを指摘します。



たとえば、単純なtf-idfとロジスティック回帰を使用して良い結果が得られたこと示すと、他の分類器を調べるようになりました。 他のものが等しい(7000列の制限を持つTfidfVectorizer)LogisticRegressionは、結果-0.88LinearRegression -0.91、 リッジ回帰 -0.92を返します。



ランダムフォレストの代わりに線形回帰(トップワードの平均)を使用すると、0.84ではなく0.93の結果が得られます。 したがって、私の最初の間違いは、ベクトル化の方法が分類子の選択以上に影響すると信じていたことです。 教育記事の資料は私に誤った考えを促しましたが、私はすべてを自分でチェックするべきでした。



この例のコードを詳しく見て、2番目のアイデアを取り出しました。 ニュアンスは、TfidfVectorizerが正確に使用された方法です。 テストとトレーニングの組み合わせデータからセットが取得され、列の最大数に制限はありませんでした。さらに、特徴は個々の単語だけでなく、単語のペアからも形成されました(パラメーターngram_range =(1、2))。 プログラムがそのようなボリュームからのMemoryErrorに該当しない場合、予測の精度が大幅に向上します(著者は結果が0.95であると述べています)。 結論2-いくつかの特に注意が必要な方法ではなく、計算量を増やすことで精度を向上させることができます。 このため、たとえば、自分のコンピューターがあまり強力ではない場合、クラウドコンピューティングの何らかのサービスに頼ることができます。



結論として、私はkaggleコンテストに参加することは非常に興味深いと言い、何らかの理由でまだ決定していない人たちを励まします。 もちろん、kaggleにははるかに複雑なコンテストもあります。初めて、自分の強さに応じてタスクを選択する価値があります。 最後のヒント-フォーラムを読んでください。 コンテスト中にも、役に立つヒント、アイデア、そして時にはソリューション全体を公開します。



All Articles