1200 lines
81 KiB
Text
1200 lines
81 KiB
Text
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Financial Sentiment Analysis\n",
|
|
"\n",
|
|
"[Dataset source](https://www.kaggle.com/datasets/sbhatti/financial-sentiment-analysis)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 1,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"\u001b[33mWARNING: You are using pip version 20.1.1; however, version 22.2.2 is available.\n",
|
|
"You should consider upgrading via the '/Users/andras/great-ai-interview-task/.env/bin/python -m pip install --upgrade pip' command.\u001b[0m\n",
|
|
"Note: you may need to restart the kernel to use updated packages.\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"!rm -f tracing_database.json\n",
|
|
"%pip install --upgrade great-ai > /dev/null"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<div>\n",
|
|
"<style scoped>\n",
|
|
" .dataframe tbody tr th:only-of-type {\n",
|
|
" vertical-align: middle;\n",
|
|
" }\n",
|
|
"\n",
|
|
" .dataframe tbody tr th {\n",
|
|
" vertical-align: top;\n",
|
|
" }\n",
|
|
"\n",
|
|
" .dataframe thead th {\n",
|
|
" text-align: right;\n",
|
|
" }\n",
|
|
"</style>\n",
|
|
"<table border=\"1\" class=\"dataframe\">\n",
|
|
" <thead>\n",
|
|
" <tr style=\"text-align: right;\">\n",
|
|
" <th></th>\n",
|
|
" <th>Sentence</th>\n",
|
|
" <th>Sentiment</th>\n",
|
|
" </tr>\n",
|
|
" </thead>\n",
|
|
" <tbody>\n",
|
|
" <tr>\n",
|
|
" <th>0</th>\n",
|
|
" <td>The GeoSolutions technology will leverage Bene...</td>\n",
|
|
" <td>positive</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>1</th>\n",
|
|
" <td>$ESI on lows, down $1.50 to $2.50 BK a real po...</td>\n",
|
|
" <td>negative</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>2</th>\n",
|
|
" <td>For the last quarter of 2010 , Componenta 's n...</td>\n",
|
|
" <td>positive</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>3</th>\n",
|
|
" <td>According to the Finnish-Russian Chamber of Co...</td>\n",
|
|
" <td>neutral</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>4</th>\n",
|
|
" <td>The Swedish buyout firm has sold its remaining...</td>\n",
|
|
" <td>neutral</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>5</th>\n",
|
|
" <td>$SPY wouldn't be surprised to see a green close</td>\n",
|
|
" <td>positive</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>6</th>\n",
|
|
" <td>Shell's $70 Billion BG Deal Meets Shareholder ...</td>\n",
|
|
" <td>negative</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>7</th>\n",
|
|
" <td>SSH COMMUNICATIONS SECURITY CORP STOCK EXCHANG...</td>\n",
|
|
" <td>negative</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>8</th>\n",
|
|
" <td>Kone 's net sales rose by some 14 % year-on-ye...</td>\n",
|
|
" <td>positive</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>9</th>\n",
|
|
" <td>The Stockmann department store will have a tot...</td>\n",
|
|
" <td>neutral</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>10</th>\n",
|
|
" <td>Circulation revenue has increased by 5 % in Fi...</td>\n",
|
|
" <td>positive</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>11</th>\n",
|
|
" <td>$SAP Q1 disappoints as #software licenses down...</td>\n",
|
|
" <td>negative</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>12</th>\n",
|
|
" <td>The subdivision made sales revenues last year ...</td>\n",
|
|
" <td>positive</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>13</th>\n",
|
|
" <td>Viking Line has canceled some services .</td>\n",
|
|
" <td>neutral</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>14</th>\n",
|
|
" <td>Ahlstrom Corporation STOCK EXCHANGE ANNOUNCEME...</td>\n",
|
|
" <td>neutral</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>15</th>\n",
|
|
" <td>$FB gone green on day</td>\n",
|
|
" <td>positive</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>16</th>\n",
|
|
" <td>$MSFT SQL Server revenue grew double-digit wit...</td>\n",
|
|
" <td>positive</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>17</th>\n",
|
|
" <td>According to L+ñnnen Tehtaat 's CEO Matti Karp...</td>\n",
|
|
" <td>neutral</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>18</th>\n",
|
|
" <td>The company 's share is quoted on NASDAQ OMX H...</td>\n",
|
|
" <td>neutral</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>19</th>\n",
|
|
" <td>Elcoteq SE is listed on the Nasdaq OMX Helsink...</td>\n",
|
|
" <td>neutral</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>20</th>\n",
|
|
" <td>Two of these contracts are for turntable anode...</td>\n",
|
|
" <td>neutral</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>21</th>\n",
|
|
" <td>Aviva, Friends Life top forecasts ahead of 5.6...</td>\n",
|
|
" <td>positive</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>22</th>\n",
|
|
" <td>In stead of being based on a soft drink , as i...</td>\n",
|
|
" <td>neutral</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>23</th>\n",
|
|
" <td>The company plans to increase the unit 's spec...</td>\n",
|
|
" <td>neutral</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>24</th>\n",
|
|
" <td>The company closed last year with a turnover o...</td>\n",
|
|
" <td>neutral</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>25</th>\n",
|
|
" <td>Shire CEO steps up drive to get Baxalta board ...</td>\n",
|
|
" <td>positive</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>26</th>\n",
|
|
" <td>Costco: A Premier Retail Dividend Play https:/...</td>\n",
|
|
" <td>positive</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>27</th>\n",
|
|
" <td>The five-storey , eco-efficient building will ...</td>\n",
|
|
" <td>neutral</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>28</th>\n",
|
|
" <td>The first installment of the Cinema Series con...</td>\n",
|
|
" <td>neutral</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>29</th>\n",
|
|
" <td>All are welcome .</td>\n",
|
|
" <td>neutral</td>\n",
|
|
" </tr>\n",
|
|
" </tbody>\n",
|
|
"</table>\n",
|
|
"</div>"
|
|
],
|
|
"text/plain": [
|
|
" Sentence Sentiment\n",
|
|
"0 The GeoSolutions technology will leverage Bene... positive\n",
|
|
"1 $ESI on lows, down $1.50 to $2.50 BK a real po... negative\n",
|
|
"2 For the last quarter of 2010 , Componenta 's n... positive\n",
|
|
"3 According to the Finnish-Russian Chamber of Co... neutral\n",
|
|
"4 The Swedish buyout firm has sold its remaining... neutral\n",
|
|
"5 $SPY wouldn't be surprised to see a green close positive\n",
|
|
"6 Shell's $70 Billion BG Deal Meets Shareholder ... negative\n",
|
|
"7 SSH COMMUNICATIONS SECURITY CORP STOCK EXCHANG... negative\n",
|
|
"8 Kone 's net sales rose by some 14 % year-on-ye... positive\n",
|
|
"9 The Stockmann department store will have a tot... neutral\n",
|
|
"10 Circulation revenue has increased by 5 % in Fi... positive\n",
|
|
"11 $SAP Q1 disappoints as #software licenses down... negative\n",
|
|
"12 The subdivision made sales revenues last year ... positive\n",
|
|
"13 Viking Line has canceled some services . neutral\n",
|
|
"14 Ahlstrom Corporation STOCK EXCHANGE ANNOUNCEME... neutral\n",
|
|
"15 $FB gone green on day positive\n",
|
|
"16 $MSFT SQL Server revenue grew double-digit wit... positive\n",
|
|
"17 According to L+ñnnen Tehtaat 's CEO Matti Karp... neutral\n",
|
|
"18 The company 's share is quoted on NASDAQ OMX H... neutral\n",
|
|
"19 Elcoteq SE is listed on the Nasdaq OMX Helsink... neutral\n",
|
|
"20 Two of these contracts are for turntable anode... neutral\n",
|
|
"21 Aviva, Friends Life top forecasts ahead of 5.6... positive\n",
|
|
"22 In stead of being based on a soft drink , as i... neutral\n",
|
|
"23 The company plans to increase the unit 's spec... neutral\n",
|
|
"24 The company closed last year with a turnover o... neutral\n",
|
|
"25 Shire CEO steps up drive to get Baxalta board ... positive\n",
|
|
"26 Costco: A Premier Retail Dividend Play https:/... positive\n",
|
|
"27 The five-storey , eco-efficient building will ... neutral\n",
|
|
"28 The first installment of the Cinema Series con... neutral\n",
|
|
"29 All are welcome . neutral"
|
|
]
|
|
},
|
|
"execution_count": 2,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"import pandas as pd\n",
|
|
"\n",
|
|
"data = pd.read_csv('data/data.csv')\n",
|
|
"\n",
|
|
"pd.set_option(\"display.max_rows\", 30)\n",
|
|
"pd.set_option(\"display.max_columns\", 30)\n",
|
|
"data.head(30)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 3,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stderr",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"\u001b[38;5;226mEnvironment variable ENVIRONMENT is not set, defaulting to development mode ‼️\u001b[0m\n",
|
|
"\u001b[38;5;226mCannot find credentials files, defaulting to using ParallelTinyDbDriver\u001b[0m\n",
|
|
"\u001b[38;5;226mThe selected tracing database (ParallelTinyDbDriver) is not recommended for production\u001b[0m\n",
|
|
"\u001b[38;5;226mCannot find credentials files, defaulting to using LargeFileLocal\u001b[0m\n",
|
|
"\u001b[38;5;39mGreatAI (v0.1.10): configured ✅\u001b[0m\n",
|
|
"\u001b[38;5;39m 🔩 tracing_database: ParallelTinyDbDriver\u001b[0m\n",
|
|
"\u001b[38;5;39m 🔩 large_file_implementation: LargeFileLocal\u001b[0m\n",
|
|
"\u001b[38;5;39m 🔩 is_production: False\u001b[0m\n",
|
|
"\u001b[38;5;39m 🔩 should_log_exception_stack: True\u001b[0m\n",
|
|
"\u001b[38;5;39m 🔩 prediction_cache_size: 512\u001b[0m\n",
|
|
"\u001b[38;5;39m 🔩 dashboard_table_size: 50\u001b[0m\n",
|
|
"\u001b[38;5;226mYou still need to check whether you follow all best practices before trusting your deployment.\u001b[0m\n",
|
|
"\u001b[38;5;226m> Find out more at https://se-ml.github.io/practices\u001b[0m\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"from great_ai import add_ground_truth, delete_ground_truth\n",
|
|
"\n",
|
|
"X = data['Sentence'].to_list()\n",
|
|
"y = data['Sentiment'].to_list()\n",
|
|
"\n",
|
|
"add_ground_truth(X, y, train_split_ratio=0.85, test_split_ratio=0.15)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 4,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"from great_ai import query_ground_truth\n",
|
|
"\n",
|
|
"train_split = query_ground_truth('train')\n",
|
|
"test_split = query_ground_truth('test')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 5,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stderr",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"100%|██████████| 4965/4965 [00:01<00:00, 3023.88it/s]\n",
|
|
"100%|██████████| 877/877 [00:01<00:00, 718.68it/s]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"from great_ai.utilities import clean, simple_parallel_map\n",
|
|
"import re\n",
|
|
"from great_ai import Trace\n",
|
|
"\n",
|
|
"def normalize(text: str) -> str:\n",
|
|
" cleaned = clean(text, convert_to_ascii=True).lower()\n",
|
|
" return re.sub(r\"[^a-z]+\", \" \", cleaned)\n",
|
|
"\n",
|
|
"X_train = simple_parallel_map(normalize, [t.input for t in train_split])\n",
|
|
"X_test = simple_parallel_map(normalize, [t.input for t in test_split])\n",
|
|
"\n",
|
|
"y_train = [t.output for t in train_split]\n",
|
|
"y_test = [t.output for t in test_split]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 6,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"from sklearn.pipeline import Pipeline, make_pipeline\n",
|
|
"from sklearn.linear_model import SGDClassifier\n",
|
|
"from sklearn.feature_extraction.text import TfidfVectorizer\n",
|
|
"\n",
|
|
"\n",
|
|
"def create_pipeline() -> Pipeline:\n",
|
|
" return make_pipeline(\n",
|
|
" TfidfVectorizer(min_df=5, max_df=0.3, ngram_range=(1, 3), sublinear_tf=True),\n",
|
|
" SGDClassifier(max_iter=10000, tol=1e-4, penalty=\"elasticnet\")\n",
|
|
" )"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 7,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Fitting 4 folds for each of 150 candidates, totalling 600 fits\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<div>\n",
|
|
"<style scoped>\n",
|
|
" .dataframe tbody tr th:only-of-type {\n",
|
|
" vertical-align: middle;\n",
|
|
" }\n",
|
|
"\n",
|
|
" .dataframe tbody tr th {\n",
|
|
" vertical-align: top;\n",
|
|
" }\n",
|
|
"\n",
|
|
" .dataframe thead th {\n",
|
|
" text-align: right;\n",
|
|
" }\n",
|
|
"</style>\n",
|
|
"<table border=\"1\" class=\"dataframe\">\n",
|
|
" <thead>\n",
|
|
" <tr style=\"text-align: right;\">\n",
|
|
" <th></th>\n",
|
|
" <th>mean_fit_time</th>\n",
|
|
" <th>std_fit_time</th>\n",
|
|
" <th>mean_score_time</th>\n",
|
|
" <th>std_score_time</th>\n",
|
|
" <th>param_sgdclassifier__alpha</th>\n",
|
|
" <th>param_sgdclassifier__l1_ratio</th>\n",
|
|
" <th>params</th>\n",
|
|
" <th>split0_test_score</th>\n",
|
|
" <th>split1_test_score</th>\n",
|
|
" <th>split2_test_score</th>\n",
|
|
" <th>split3_test_score</th>\n",
|
|
" <th>mean_test_score</th>\n",
|
|
" <th>std_test_score</th>\n",
|
|
" <th>rank_test_score</th>\n",
|
|
" </tr>\n",
|
|
" </thead>\n",
|
|
" <tbody>\n",
|
|
" <tr>\n",
|
|
" <th>141</th>\n",
|
|
" <td>0.557538</td>\n",
|
|
" <td>0.036277</td>\n",
|
|
" <td>0.079557</td>\n",
|
|
" <td>0.001859</td>\n",
|
|
" <td>0.000139</td>\n",
|
|
" <td>0.74698</td>\n",
|
|
" <td>{'sgdclassifier__alpha': 0.0001386590973076251...</td>\n",
|
|
" <td>0.602778</td>\n",
|
|
" <td>0.583447</td>\n",
|
|
" <td>0.609218</td>\n",
|
|
" <td>0.617713</td>\n",
|
|
" <td>0.603289</td>\n",
|
|
" <td>0.012621</td>\n",
|
|
" <td>1</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>62</th>\n",
|
|
" <td>0.517736</td>\n",
|
|
" <td>0.017173</td>\n",
|
|
" <td>0.075006</td>\n",
|
|
" <td>0.008921</td>\n",
|
|
" <td>0.000123</td>\n",
|
|
" <td>0.633796</td>\n",
|
|
" <td>{'sgdclassifier__alpha': 0.0001230949372392475...</td>\n",
|
|
" <td>0.603052</td>\n",
|
|
" <td>0.592701</td>\n",
|
|
" <td>0.595310</td>\n",
|
|
" <td>0.615232</td>\n",
|
|
" <td>0.601574</td>\n",
|
|
" <td>0.008756</td>\n",
|
|
" <td>2</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>44</th>\n",
|
|
" <td>0.586568</td>\n",
|
|
" <td>0.034125</td>\n",
|
|
" <td>0.075711</td>\n",
|
|
" <td>0.015189</td>\n",
|
|
" <td>0.000101</td>\n",
|
|
" <td>0.744511</td>\n",
|
|
" <td>{'sgdclassifier__alpha': 0.0001008328469921404...</td>\n",
|
|
" <td>0.605709</td>\n",
|
|
" <td>0.586259</td>\n",
|
|
" <td>0.592400</td>\n",
|
|
" <td>0.614393</td>\n",
|
|
" <td>0.599690</td>\n",
|
|
" <td>0.011022</td>\n",
|
|
" <td>3</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>15</th>\n",
|
|
" <td>0.503485</td>\n",
|
|
" <td>0.052601</td>\n",
|
|
" <td>0.076652</td>\n",
|
|
" <td>0.005708</td>\n",
|
|
" <td>0.000101</td>\n",
|
|
" <td>0.717281</td>\n",
|
|
" <td>{'sgdclassifier__alpha': 0.0001012954906445695...</td>\n",
|
|
" <td>0.596920</td>\n",
|
|
" <td>0.590612</td>\n",
|
|
" <td>0.589020</td>\n",
|
|
" <td>0.608695</td>\n",
|
|
" <td>0.596312</td>\n",
|
|
" <td>0.007736</td>\n",
|
|
" <td>4</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>120</th>\n",
|
|
" <td>0.626889</td>\n",
|
|
" <td>0.037078</td>\n",
|
|
" <td>0.087496</td>\n",
|
|
" <td>0.013705</td>\n",
|
|
" <td>0.000104</td>\n",
|
|
" <td>0.521099</td>\n",
|
|
" <td>{'sgdclassifier__alpha': 0.0001043130639528788...</td>\n",
|
|
" <td>0.592821</td>\n",
|
|
" <td>0.585763</td>\n",
|
|
" <td>0.582623</td>\n",
|
|
" <td>0.613523</td>\n",
|
|
" <td>0.593683</td>\n",
|
|
" <td>0.012036</td>\n",
|
|
" <td>5</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>77</th>\n",
|
|
" <td>0.657004</td>\n",
|
|
" <td>0.020389</td>\n",
|
|
" <td>0.086646</td>\n",
|
|
" <td>0.021849</td>\n",
|
|
" <td>0.000072</td>\n",
|
|
" <td>0.869767</td>\n",
|
|
" <td>{'sgdclassifier__alpha': 7.2395771533531e-05, ...</td>\n",
|
|
" <td>0.585078</td>\n",
|
|
" <td>0.587727</td>\n",
|
|
" <td>0.582360</td>\n",
|
|
" <td>0.600486</td>\n",
|
|
" <td>0.588913</td>\n",
|
|
" <td>0.006946</td>\n",
|
|
" <td>6</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>124</th>\n",
|
|
" <td>0.458076</td>\n",
|
|
" <td>0.003328</td>\n",
|
|
" <td>0.081067</td>\n",
|
|
" <td>0.003202</td>\n",
|
|
" <td>0.000286</td>\n",
|
|
" <td>0.729062</td>\n",
|
|
" <td>{'sgdclassifier__alpha': 0.0002860219318437106...</td>\n",
|
|
" <td>0.599120</td>\n",
|
|
" <td>0.565035</td>\n",
|
|
" <td>0.583109</td>\n",
|
|
" <td>0.604000</td>\n",
|
|
" <td>0.587816</td>\n",
|
|
" <td>0.015255</td>\n",
|
|
" <td>7</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>4</th>\n",
|
|
" <td>0.423889</td>\n",
|
|
" <td>0.014550</td>\n",
|
|
" <td>0.070364</td>\n",
|
|
" <td>0.010887</td>\n",
|
|
" <td>0.00034</td>\n",
|
|
" <td>0.793499</td>\n",
|
|
" <td>{'sgdclassifier__alpha': 0.0003401382442436040...</td>\n",
|
|
" <td>0.574158</td>\n",
|
|
" <td>0.551240</td>\n",
|
|
" <td>0.580991</td>\n",
|
|
" <td>0.593687</td>\n",
|
|
" <td>0.575019</td>\n",
|
|
" <td>0.015414</td>\n",
|
|
" <td>8</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>113</th>\n",
|
|
" <td>0.428109</td>\n",
|
|
" <td>0.023082</td>\n",
|
|
" <td>0.083129</td>\n",
|
|
" <td>0.010922</td>\n",
|
|
" <td>0.00044</td>\n",
|
|
" <td>0.682686</td>\n",
|
|
" <td>{'sgdclassifier__alpha': 0.0004397417391475943...</td>\n",
|
|
" <td>0.560192</td>\n",
|
|
" <td>0.534955</td>\n",
|
|
" <td>0.567035</td>\n",
|
|
" <td>0.556430</td>\n",
|
|
" <td>0.554653</td>\n",
|
|
" <td>0.011991</td>\n",
|
|
" <td>9</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>51</th>\n",
|
|
" <td>0.376192</td>\n",
|
|
" <td>0.008471</td>\n",
|
|
" <td>0.073243</td>\n",
|
|
" <td>0.005655</td>\n",
|
|
" <td>0.000497</td>\n",
|
|
" <td>0.624651</td>\n",
|
|
" <td>{'sgdclassifier__alpha': 0.0004970440243574691...</td>\n",
|
|
" <td>0.556448</td>\n",
|
|
" <td>0.525659</td>\n",
|
|
" <td>0.557745</td>\n",
|
|
" <td>0.535856</td>\n",
|
|
" <td>0.543927</td>\n",
|
|
" <td>0.013662</td>\n",
|
|
" <td>10</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>65</th>\n",
|
|
" <td>0.403297</td>\n",
|
|
" <td>0.019218</td>\n",
|
|
" <td>0.081735</td>\n",
|
|
" <td>0.008557</td>\n",
|
|
" <td>0.000654</td>\n",
|
|
" <td>0.790485</td>\n",
|
|
" <td>{'sgdclassifier__alpha': 0.0006536354435155366...</td>\n",
|
|
" <td>0.494568</td>\n",
|
|
" <td>0.494890</td>\n",
|
|
" <td>0.521074</td>\n",
|
|
" <td>0.498299</td>\n",
|
|
" <td>0.502208</td>\n",
|
|
" <td>0.010990</td>\n",
|
|
" <td>11</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>43</th>\n",
|
|
" <td>0.376818</td>\n",
|
|
" <td>0.015721</td>\n",
|
|
" <td>0.082944</td>\n",
|
|
" <td>0.011949</td>\n",
|
|
" <td>0.000687</td>\n",
|
|
" <td>0.72785</td>\n",
|
|
" <td>{'sgdclassifier__alpha': 0.0006872056831731454...</td>\n",
|
|
" <td>0.486892</td>\n",
|
|
" <td>0.480204</td>\n",
|
|
" <td>0.518121</td>\n",
|
|
" <td>0.490073</td>\n",
|
|
" <td>0.493823</td>\n",
|
|
" <td>0.014474</td>\n",
|
|
" <td>12</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>136</th>\n",
|
|
" <td>0.430972</td>\n",
|
|
" <td>0.022091</td>\n",
|
|
" <td>0.081294</td>\n",
|
|
" <td>0.013143</td>\n",
|
|
" <td>0.000752</td>\n",
|
|
" <td>0.677539</td>\n",
|
|
" <td>{'sgdclassifier__alpha': 0.0007522879894549428...</td>\n",
|
|
" <td>0.465951</td>\n",
|
|
" <td>0.465331</td>\n",
|
|
" <td>0.504155</td>\n",
|
|
" <td>0.483493</td>\n",
|
|
" <td>0.479732</td>\n",
|
|
" <td>0.015874</td>\n",
|
|
" <td>13</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>9</th>\n",
|
|
" <td>0.372205</td>\n",
|
|
" <td>0.012770</td>\n",
|
|
" <td>0.073653</td>\n",
|
|
" <td>0.008134</td>\n",
|
|
" <td>0.000817</td>\n",
|
|
" <td>0.83729</td>\n",
|
|
" <td>{'sgdclassifier__alpha': 0.0008166269999644726...</td>\n",
|
|
" <td>0.458828</td>\n",
|
|
" <td>0.454415</td>\n",
|
|
" <td>0.487819</td>\n",
|
|
" <td>0.471793</td>\n",
|
|
" <td>0.468214</td>\n",
|
|
" <td>0.012997</td>\n",
|
|
" <td>14</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>13</th>\n",
|
|
" <td>0.365807</td>\n",
|
|
" <td>0.025005</td>\n",
|
|
" <td>0.069653</td>\n",
|
|
" <td>0.006056</td>\n",
|
|
" <td>0.000875</td>\n",
|
|
" <td>0.858839</td>\n",
|
|
" <td>{'sgdclassifier__alpha': 0.0008750004969715541...</td>\n",
|
|
" <td>0.454365</td>\n",
|
|
" <td>0.440285</td>\n",
|
|
" <td>0.477297</td>\n",
|
|
" <td>0.459960</td>\n",
|
|
" <td>0.457977</td>\n",
|
|
" <td>0.013260</td>\n",
|
|
" <td>15</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>82</th>\n",
|
|
" <td>0.377183</td>\n",
|
|
" <td>0.020059</td>\n",
|
|
" <td>0.080263</td>\n",
|
|
" <td>0.004296</td>\n",
|
|
" <td>0.000866</td>\n",
|
|
" <td>0.681585</td>\n",
|
|
" <td>{'sgdclassifier__alpha': 0.0008664113622514768...</td>\n",
|
|
" <td>0.451383</td>\n",
|
|
" <td>0.437788</td>\n",
|
|
" <td>0.470605</td>\n",
|
|
" <td>0.458012</td>\n",
|
|
" <td>0.454447</td>\n",
|
|
" <td>0.011839</td>\n",
|
|
" <td>16</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>99</th>\n",
|
|
" <td>0.402863</td>\n",
|
|
" <td>0.014800</td>\n",
|
|
" <td>0.080705</td>\n",
|
|
" <td>0.008275</td>\n",
|
|
" <td>0.000934</td>\n",
|
|
" <td>0.885396</td>\n",
|
|
" <td>{'sgdclassifier__alpha': 0.0009337381961170587...</td>\n",
|
|
" <td>0.444663</td>\n",
|
|
" <td>0.433931</td>\n",
|
|
" <td>0.469451</td>\n",
|
|
" <td>0.456795</td>\n",
|
|
" <td>0.451210</td>\n",
|
|
" <td>0.013279</td>\n",
|
|
" <td>17</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>109</th>\n",
|
|
" <td>0.390509</td>\n",
|
|
" <td>0.021212</td>\n",
|
|
" <td>0.075047</td>\n",
|
|
" <td>0.010354</td>\n",
|
|
" <td>0.000909</td>\n",
|
|
" <td>0.618578</td>\n",
|
|
" <td>{'sgdclassifier__alpha': 0.0009094221175006189...</td>\n",
|
|
" <td>0.441668</td>\n",
|
|
" <td>0.426130</td>\n",
|
|
" <td>0.465321</td>\n",
|
|
" <td>0.448866</td>\n",
|
|
" <td>0.445496</td>\n",
|
|
" <td>0.014090</td>\n",
|
|
" <td>18</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>91</th>\n",
|
|
" <td>0.398750</td>\n",
|
|
" <td>0.011765</td>\n",
|
|
" <td>0.083176</td>\n",
|
|
" <td>0.008070</td>\n",
|
|
" <td>0.000965</td>\n",
|
|
" <td>0.735892</td>\n",
|
|
" <td>{'sgdclassifier__alpha': 0.0009645020235766322...</td>\n",
|
|
" <td>0.431957</td>\n",
|
|
" <td>0.419680</td>\n",
|
|
" <td>0.456291</td>\n",
|
|
" <td>0.442121</td>\n",
|
|
" <td>0.437512</td>\n",
|
|
" <td>0.013442</td>\n",
|
|
" <td>19</td>\n",
|
|
" </tr>\n",
|
|
" <tr>\n",
|
|
" <th>19</th>\n",
|
|
" <td>0.340692</td>\n",
|
|
" <td>0.017618</td>\n",
|
|
" <td>0.075392</td>\n",
|
|
" <td>0.015913</td>\n",
|
|
" <td>0.00109</td>\n",
|
|
" <td>0.572366</td>\n",
|
|
" <td>{'sgdclassifier__alpha': 0.0010901894985476288...</td>\n",
|
|
" <td>0.418186</td>\n",
|
|
" <td>0.405171</td>\n",
|
|
" <td>0.432716</td>\n",
|
|
" <td>0.422689</td>\n",
|
|
" <td>0.419690</td>\n",
|
|
" <td>0.009896</td>\n",
|
|
" <td>20</td>\n",
|
|
" </tr>\n",
|
|
" </tbody>\n",
|
|
"</table>\n",
|
|
"</div>"
|
|
],
|
|
"text/plain": [
|
|
" mean_fit_time std_fit_time mean_score_time std_score_time \\\n",
|
|
"141 0.557538 0.036277 0.079557 0.001859 \n",
|
|
"62 0.517736 0.017173 0.075006 0.008921 \n",
|
|
"44 0.586568 0.034125 0.075711 0.015189 \n",
|
|
"15 0.503485 0.052601 0.076652 0.005708 \n",
|
|
"120 0.626889 0.037078 0.087496 0.013705 \n",
|
|
"77 0.657004 0.020389 0.086646 0.021849 \n",
|
|
"124 0.458076 0.003328 0.081067 0.003202 \n",
|
|
"4 0.423889 0.014550 0.070364 0.010887 \n",
|
|
"113 0.428109 0.023082 0.083129 0.010922 \n",
|
|
"51 0.376192 0.008471 0.073243 0.005655 \n",
|
|
"65 0.403297 0.019218 0.081735 0.008557 \n",
|
|
"43 0.376818 0.015721 0.082944 0.011949 \n",
|
|
"136 0.430972 0.022091 0.081294 0.013143 \n",
|
|
"9 0.372205 0.012770 0.073653 0.008134 \n",
|
|
"13 0.365807 0.025005 0.069653 0.006056 \n",
|
|
"82 0.377183 0.020059 0.080263 0.004296 \n",
|
|
"99 0.402863 0.014800 0.080705 0.008275 \n",
|
|
"109 0.390509 0.021212 0.075047 0.010354 \n",
|
|
"91 0.398750 0.011765 0.083176 0.008070 \n",
|
|
"19 0.340692 0.017618 0.075392 0.015913 \n",
|
|
"\n",
|
|
" param_sgdclassifier__alpha param_sgdclassifier__l1_ratio \\\n",
|
|
"141 0.000139 0.74698 \n",
|
|
"62 0.000123 0.633796 \n",
|
|
"44 0.000101 0.744511 \n",
|
|
"15 0.000101 0.717281 \n",
|
|
"120 0.000104 0.521099 \n",
|
|
"77 0.000072 0.869767 \n",
|
|
"124 0.000286 0.729062 \n",
|
|
"4 0.00034 0.793499 \n",
|
|
"113 0.00044 0.682686 \n",
|
|
"51 0.000497 0.624651 \n",
|
|
"65 0.000654 0.790485 \n",
|
|
"43 0.000687 0.72785 \n",
|
|
"136 0.000752 0.677539 \n",
|
|
"9 0.000817 0.83729 \n",
|
|
"13 0.000875 0.858839 \n",
|
|
"82 0.000866 0.681585 \n",
|
|
"99 0.000934 0.885396 \n",
|
|
"109 0.000909 0.618578 \n",
|
|
"91 0.000965 0.735892 \n",
|
|
"19 0.00109 0.572366 \n",
|
|
"\n",
|
|
" params split0_test_score \\\n",
|
|
"141 {'sgdclassifier__alpha': 0.0001386590973076251... 0.602778 \n",
|
|
"62 {'sgdclassifier__alpha': 0.0001230949372392475... 0.603052 \n",
|
|
"44 {'sgdclassifier__alpha': 0.0001008328469921404... 0.605709 \n",
|
|
"15 {'sgdclassifier__alpha': 0.0001012954906445695... 0.596920 \n",
|
|
"120 {'sgdclassifier__alpha': 0.0001043130639528788... 0.592821 \n",
|
|
"77 {'sgdclassifier__alpha': 7.2395771533531e-05, ... 0.585078 \n",
|
|
"124 {'sgdclassifier__alpha': 0.0002860219318437106... 0.599120 \n",
|
|
"4 {'sgdclassifier__alpha': 0.0003401382442436040... 0.574158 \n",
|
|
"113 {'sgdclassifier__alpha': 0.0004397417391475943... 0.560192 \n",
|
|
"51 {'sgdclassifier__alpha': 0.0004970440243574691... 0.556448 \n",
|
|
"65 {'sgdclassifier__alpha': 0.0006536354435155366... 0.494568 \n",
|
|
"43 {'sgdclassifier__alpha': 0.0006872056831731454... 0.486892 \n",
|
|
"136 {'sgdclassifier__alpha': 0.0007522879894549428... 0.465951 \n",
|
|
"9 {'sgdclassifier__alpha': 0.0008166269999644726... 0.458828 \n",
|
|
"13 {'sgdclassifier__alpha': 0.0008750004969715541... 0.454365 \n",
|
|
"82 {'sgdclassifier__alpha': 0.0008664113622514768... 0.451383 \n",
|
|
"99 {'sgdclassifier__alpha': 0.0009337381961170587... 0.444663 \n",
|
|
"109 {'sgdclassifier__alpha': 0.0009094221175006189... 0.441668 \n",
|
|
"91 {'sgdclassifier__alpha': 0.0009645020235766322... 0.431957 \n",
|
|
"19 {'sgdclassifier__alpha': 0.0010901894985476288... 0.418186 \n",
|
|
"\n",
|
|
" split1_test_score split2_test_score split3_test_score mean_test_score \\\n",
|
|
"141 0.583447 0.609218 0.617713 0.603289 \n",
|
|
"62 0.592701 0.595310 0.615232 0.601574 \n",
|
|
"44 0.586259 0.592400 0.614393 0.599690 \n",
|
|
"15 0.590612 0.589020 0.608695 0.596312 \n",
|
|
"120 0.585763 0.582623 0.613523 0.593683 \n",
|
|
"77 0.587727 0.582360 0.600486 0.588913 \n",
|
|
"124 0.565035 0.583109 0.604000 0.587816 \n",
|
|
"4 0.551240 0.580991 0.593687 0.575019 \n",
|
|
"113 0.534955 0.567035 0.556430 0.554653 \n",
|
|
"51 0.525659 0.557745 0.535856 0.543927 \n",
|
|
"65 0.494890 0.521074 0.498299 0.502208 \n",
|
|
"43 0.480204 0.518121 0.490073 0.493823 \n",
|
|
"136 0.465331 0.504155 0.483493 0.479732 \n",
|
|
"9 0.454415 0.487819 0.471793 0.468214 \n",
|
|
"13 0.440285 0.477297 0.459960 0.457977 \n",
|
|
"82 0.437788 0.470605 0.458012 0.454447 \n",
|
|
"99 0.433931 0.469451 0.456795 0.451210 \n",
|
|
"109 0.426130 0.465321 0.448866 0.445496 \n",
|
|
"91 0.419680 0.456291 0.442121 0.437512 \n",
|
|
"19 0.405171 0.432716 0.422689 0.419690 \n",
|
|
"\n",
|
|
" std_test_score rank_test_score \n",
|
|
"141 0.012621 1 \n",
|
|
"62 0.008756 2 \n",
|
|
"44 0.011022 3 \n",
|
|
"15 0.007736 4 \n",
|
|
"120 0.012036 5 \n",
|
|
"77 0.006946 6 \n",
|
|
"124 0.015255 7 \n",
|
|
"4 0.015414 8 \n",
|
|
"113 0.011991 9 \n",
|
|
"51 0.013662 10 \n",
|
|
"65 0.010990 11 \n",
|
|
"43 0.014474 12 \n",
|
|
"136 0.015874 13 \n",
|
|
"9 0.012997 14 \n",
|
|
"13 0.013260 15 \n",
|
|
"82 0.011839 16 \n",
|
|
"99 0.013279 17 \n",
|
|
"109 0.014090 18 \n",
|
|
"91 0.013442 19 \n",
|
|
"19 0.009896 20 "
|
|
]
|
|
},
|
|
"execution_count": 7,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"from sklearn.model_selection import RandomizedSearchCV\n",
|
|
"import scipy.stats\n",
|
|
"\n",
|
|
"optimisation_pipeline = RandomizedSearchCV(\n",
|
|
" create_pipeline(),\n",
|
|
" {\n",
|
|
" \"sgdclassifier__alpha\": scipy.stats.uniform(0.00005, 0.01),\n",
|
|
" \"sgdclassifier__l1_ratio\": scipy.stats.uniform(0.5, 0.4),\n",
|
|
" },\n",
|
|
" cv=4,\n",
|
|
" n_iter=150,\n",
|
|
" verbose=1,\n",
|
|
" scoring='f1_macro',\n",
|
|
" n_jobs=-1\n",
|
|
")\n",
|
|
"\n",
|
|
"optimisation_pipeline.fit(X_train, y_train)\n",
|
|
"results = pd.DataFrame(optimisation_pipeline.cv_results_)\n",
|
|
"results.sort_values(\"rank_test_score\").head(20)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 8,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/html": [
|
|
"<style>#sk-container-id-1 {color: black;background-color: white;}#sk-container-id-1 pre{padding: 0;}#sk-container-id-1 div.sk-toggleable {background-color: white;}#sk-container-id-1 label.sk-toggleable__label {cursor: pointer;display: block;width: 100%;margin-bottom: 0;padding: 0.3em;box-sizing: border-box;text-align: center;}#sk-container-id-1 label.sk-toggleable__label-arrow:before {content: \"▸\";float: left;margin-right: 0.25em;color: #696969;}#sk-container-id-1 label.sk-toggleable__label-arrow:hover:before {color: black;}#sk-container-id-1 div.sk-estimator:hover label.sk-toggleable__label-arrow:before {color: black;}#sk-container-id-1 div.sk-toggleable__content {max-height: 0;max-width: 0;overflow: hidden;text-align: left;background-color: #f0f8ff;}#sk-container-id-1 div.sk-toggleable__content pre {margin: 0.2em;color: black;border-radius: 0.25em;background-color: #f0f8ff;}#sk-container-id-1 input.sk-toggleable__control:checked~div.sk-toggleable__content {max-height: 200px;max-width: 100%;overflow: auto;}#sk-container-id-1 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {content: \"▾\";}#sk-container-id-1 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-1 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-1 input.sk-hidden--visually {border: 0;clip: rect(1px 1px 1px 1px);clip: rect(1px, 1px, 1px, 1px);height: 1px;margin: -1px;overflow: hidden;padding: 0;position: absolute;width: 1px;}#sk-container-id-1 div.sk-estimator {font-family: monospace;background-color: #f0f8ff;border: 1px dotted black;border-radius: 0.25em;box-sizing: border-box;margin-bottom: 0.5em;}#sk-container-id-1 div.sk-estimator:hover {background-color: #d4ebff;}#sk-container-id-1 div.sk-parallel-item::after {content: \"\";width: 100%;border-bottom: 1px solid gray;flex-grow: 1;}#sk-container-id-1 div.sk-label:hover label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-1 div.sk-serial::before {content: \"\";position: absolute;border-left: 1px solid gray;box-sizing: border-box;top: 0;bottom: 0;left: 50%;z-index: 0;}#sk-container-id-1 div.sk-serial {display: flex;flex-direction: column;align-items: center;background-color: white;padding-right: 0.2em;padding-left: 0.2em;position: relative;}#sk-container-id-1 div.sk-item {position: relative;z-index: 1;}#sk-container-id-1 div.sk-parallel {display: flex;align-items: stretch;justify-content: center;background-color: white;position: relative;}#sk-container-id-1 div.sk-item::before, #sk-container-id-1 div.sk-parallel-item::before {content: \"\";position: absolute;border-left: 1px solid gray;box-sizing: border-box;top: 0;bottom: 0;left: 50%;z-index: -1;}#sk-container-id-1 div.sk-parallel-item {display: flex;flex-direction: column;z-index: 1;position: relative;background-color: white;}#sk-container-id-1 div.sk-parallel-item:first-child::after {align-self: flex-end;width: 50%;}#sk-container-id-1 div.sk-parallel-item:last-child::after {align-self: flex-start;width: 50%;}#sk-container-id-1 div.sk-parallel-item:only-child::after {width: 0;}#sk-container-id-1 div.sk-dashed-wrapped {border: 1px dashed gray;margin: 0 0.4em 0.5em 0.4em;box-sizing: border-box;padding-bottom: 0.4em;background-color: white;}#sk-container-id-1 div.sk-label label {font-family: monospace;font-weight: bold;display: inline-block;line-height: 1.2em;}#sk-container-id-1 div.sk-label-container {text-align: center;}#sk-container-id-1 div.sk-container {/* jupyter's `normalize.less` sets `[hidden] { display: none; }` but bootstrap.min.css set `[hidden] { display: none !important; }` so we also need the `!important` here to be able to override the default hidden behavior on the sphinx rendered scikit-learn.org. See: https://github.com/scikit-learn/scikit-learn/issues/21755 */display: inline-block !important;position: relative;}#sk-container-id-1 div.sk-text-repr-fallback {display: none;}</style><div id=\"sk-container-id-1\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>Pipeline(steps=[('tfidfvectorizer',\n",
|
|
" TfidfVectorizer(max_df=0.3, min_df=5, ngram_range=(1, 3),\n",
|
|
" sublinear_tf=True)),\n",
|
|
" ('sgdclassifier',\n",
|
|
" SGDClassifier(alpha=0.0001386590973076251,\n",
|
|
" l1_ratio=0.7469804305005836, max_iter=100000,\n",
|
|
" penalty='elasticnet', tol=1e-05))])</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item sk-dashed-wrapped\"><div class=\"sk-label-container\"><div class=\"sk-label sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-1\" type=\"checkbox\" ><label for=\"sk-estimator-id-1\" class=\"sk-toggleable__label sk-toggleable__label-arrow\">Pipeline</label><div class=\"sk-toggleable__content\"><pre>Pipeline(steps=[('tfidfvectorizer',\n",
|
|
" TfidfVectorizer(max_df=0.3, min_df=5, ngram_range=(1, 3),\n",
|
|
" sublinear_tf=True)),\n",
|
|
" ('sgdclassifier',\n",
|
|
" SGDClassifier(alpha=0.0001386590973076251,\n",
|
|
" l1_ratio=0.7469804305005836, max_iter=100000,\n",
|
|
" penalty='elasticnet', tol=1e-05))])</pre></div></div></div><div class=\"sk-serial\"><div class=\"sk-item\"><div class=\"sk-estimator sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-2\" type=\"checkbox\" ><label for=\"sk-estimator-id-2\" class=\"sk-toggleable__label sk-toggleable__label-arrow\">TfidfVectorizer</label><div class=\"sk-toggleable__content\"><pre>TfidfVectorizer(max_df=0.3, min_df=5, ngram_range=(1, 3), sublinear_tf=True)</pre></div></div></div><div class=\"sk-item\"><div class=\"sk-estimator sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-3\" type=\"checkbox\" ><label for=\"sk-estimator-id-3\" class=\"sk-toggleable__label sk-toggleable__label-arrow\">SGDClassifier</label><div class=\"sk-toggleable__content\"><pre>SGDClassifier(alpha=0.0001386590973076251, l1_ratio=0.7469804305005836,\n",
|
|
" max_iter=100000, penalty='elasticnet', tol=1e-05)</pre></div></div></div></div></div></div></div>"
|
|
],
|
|
"text/plain": [
|
|
"Pipeline(steps=[('tfidfvectorizer',\n",
|
|
" TfidfVectorizer(max_df=0.3, min_df=5, ngram_range=(1, 3),\n",
|
|
" sublinear_tf=True)),\n",
|
|
" ('sgdclassifier',\n",
|
|
" SGDClassifier(alpha=0.0001386590973076251,\n",
|
|
" l1_ratio=0.7469804305005836, max_iter=100000,\n",
|
|
" penalty='elasticnet', tol=1e-05))])"
|
|
]
|
|
},
|
|
"execution_count": 8,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"model = create_pipeline()\n",
|
|
"model.set_params(\n",
|
|
" **optimisation_pipeline.best_params_,\n",
|
|
" sgdclassifier__max_iter=100000,\n",
|
|
" sgdclassifier__tol=1e-5,\n",
|
|
")\n",
|
|
"\n",
|
|
"model.fit(X_train, y_train)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 9,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
" precision recall f1-score support\n",
|
|
"\n",
|
|
" negative 0.41 0.17 0.24 132\n",
|
|
" neutral 0.73 0.88 0.79 465\n",
|
|
" positive 0.79 0.74 0.76 280\n",
|
|
"\n",
|
|
" accuracy 0.73 877\n",
|
|
" macro avg 0.64 0.60 0.60 877\n",
|
|
"weighted avg 0.70 0.73 0.70 877\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"image/png": "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",
|
|
"text/plain": [
|
|
"<Figure size 720x720 with 2 Axes>"
|
|
]
|
|
},
|
|
"metadata": {
|
|
"needs_background": "light"
|
|
},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"import matplotlib.pyplot as plt\n",
|
|
"from sklearn import metrics\n",
|
|
"\n",
|
|
"%matplotlib inline\n",
|
|
"plt.rcParams[\"figure.figsize\"] = (10, 10)\n",
|
|
"plt.rcParams[\"font.size\"] = 16\n",
|
|
"\n",
|
|
"y_predicted = model.predict(X_test)\n",
|
|
"\n",
|
|
"print(metrics.classification_report(y_test, y_predicted))\n",
|
|
"metrics.ConfusionMatrixDisplay.from_predictions(\n",
|
|
" y_true=y_test,\n",
|
|
" y_pred=y_predicted,\n",
|
|
" xticks_rotation=\"vertical\",\n",
|
|
" normalize=\"pred\",\n",
|
|
" values_format=\".2f\",\n",
|
|
")\n",
|
|
"None"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 10,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"There are 501 features for the`negative` class.\n",
|
|
" short: 4.8667\n",
|
|
" lower: 4.4908\n",
|
|
" fall: 4.3363\n",
|
|
" down: 4.2191\n",
|
|
" iwm: 4.1660\n",
|
|
" bhp: 3.1163\n",
|
|
" drop: 3.1113\n",
|
|
" bearish: 3.0749\n",
|
|
" fears: 2.8873\n",
|
|
" falls: 2.8422\n",
|
|
" sbux: 2.7157\n",
|
|
" rivals: 2.2257\n",
|
|
" puts: 2.1955\n",
|
|
" recalls: 2.1673\n",
|
|
" downgraded: 2.1668\n",
|
|
"\n",
|
|
"There are 1501 features for the`neutral` class.\n",
|
|
" is: 2.9445\n",
|
|
" electricity: 2.9423\n",
|
|
" includes: 2.9332\n",
|
|
" to the: 2.3651\n",
|
|
" will: 2.2602\n",
|
|
" eps in: 2.2093\n",
|
|
" to remain: 1.9904\n",
|
|
" sole: 1.9867\n",
|
|
" information: 1.9632\n",
|
|
" while: 1.9388\n",
|
|
" approximately: 1.8945\n",
|
|
" share capital: 1.8895\n",
|
|
" buy the: 1.8574\n",
|
|
" were: 1.8406\n",
|
|
" marketing: 1.8366\n",
|
|
"\n",
|
|
"There are 1495 features for the`positive` class.\n",
|
|
" increased: 6.4743\n",
|
|
" increase: 6.2415\n",
|
|
" positive: 6.2387\n",
|
|
" won: 6.0361\n",
|
|
" signed: 6.0156\n",
|
|
" grew: 5.7388\n",
|
|
" up from: 5.2212\n",
|
|
" rise: 4.9845\n",
|
|
" awarded: 4.5971\n",
|
|
" double: 4.3849\n",
|
|
" higher: 4.3683\n",
|
|
" buy: 4.3043\n",
|
|
" improved: 4.2427\n",
|
|
" breakout: 4.2076\n",
|
|
" good: 4.1502\n",
|
|
"\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"features = model.named_steps[\"tfidfvectorizer\"].get_feature_names_out()\n",
|
|
"\n",
|
|
"for i, name in enumerate(model.named_steps[\"sgdclassifier\"].classes_):\n",
|
|
" weight = model.named_steps[\"sgdclassifier\"].coef_[i]\n",
|
|
"\n",
|
|
" print(f'There are {len([w for w in weight if w != 0])} features for the`{name}` class.')\n",
|
|
"\n",
|
|
" for w, f in sorted(zip(weight, features), reverse=True)[:15]:\n",
|
|
" if w == 0:\n",
|
|
" break\n",
|
|
" print(f\" {f}: {w:.4f}\")\n",
|
|
"\n",
|
|
" print()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 11,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"('negative',\n",
|
|
" [('bearish', 0.3701555869078035),\n",
|
|
" ('share price', 0.13607210434349515),\n",
|
|
" ('tesla', 0.10278360011073003),\n",
|
|
" ('get', 0.06469031891901218),\n",
|
|
" ('back', 0.060203369146000676),\n",
|
|
" ('below', 0.05252493885654123),\n",
|
|
" ('moving', 0.033521891021244074),\n",
|
|
" ('price', 0.02861155787080013),\n",
|
|
" ('only', 0.021472501474463123),\n",
|
|
" ('there', 0.012862225410731364)])"
|
|
]
|
|
},
|
|
"execution_count": 11,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"def predict(text: str):\n",
|
|
" text = normalize(text)\n",
|
|
" features = model.named_steps[\"tfidfvectorizer\"].transform([text])\n",
|
|
" prediction = model.named_steps[\"sgdclassifier\"].predict(features)[0]\n",
|
|
"\n",
|
|
" explanation = [\n",
|
|
" (feature_name, weight)\n",
|
|
" for weight, feature_name in sorted(\n",
|
|
" (\n",
|
|
" (feature_weight * feature, feature_name)\n",
|
|
" for feature_name, feature_weight, feature in zip(\n",
|
|
" model.named_steps[\"tfidfvectorizer\"].get_feature_names_out(),\n",
|
|
" model.named_steps[\"sgdclassifier\"].coef_[list(model.named_steps[\"sgdclassifier\"].classes_).index(prediction)],\n",
|
|
" features.toarray()[0],\n",
|
|
" )\n",
|
|
" if feature * feature_weight != 0\n",
|
|
" ),\n",
|
|
" reverse=True,\n",
|
|
" )\n",
|
|
" ][:10]\n",
|
|
"\n",
|
|
" return prediction, explanation\n",
|
|
"\n",
|
|
"predict('''\n",
|
|
" The last 12 months for Tesla shares have been fairly but positively volatile. \n",
|
|
" The stock is up in the past year, as it was trading at just under $700 per share back in early August 2021. \n",
|
|
" The share price spent much of late 2021 and early 2022 over the $1,000 mark. \n",
|
|
" Prices dipped below $1,000—and stayed there—starting in late April.\n",
|
|
"\n",
|
|
" I have been bearish on Tesla lately, owing to its elevated share price and its growing competition in the electric vehicle field.\n",
|
|
" The competition part isn't changing much. \n",
|
|
" That's really only gotten worse thanks to most of the major automakers looking to get in on the market.\n",
|
|
"\n",
|
|
" However, Tesla's move to make its shares more reasonably priced should catch some attention. Thus, I'm moving to neutral on Tesla stock.\n",
|
|
"''')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 12,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stderr",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"\u001b[38;5;39mFetching cached versions of financial-sentiment\u001b[0m\n",
|
|
"\u001b[38;5;39mCopying file for financial-sentiment-1\u001b[0m\n",
|
|
"\u001b[38;5;39mCompressing financial-sentiment-1\u001b[0m\n",
|
|
"\u001b[38;5;39mModel financial-sentiment uploaded with version 1\u001b[0m\n"
|
|
]
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"'financial-sentiment:1'"
|
|
]
|
|
},
|
|
"execution_count": 12,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"from great_ai import save_model\n",
|
|
"\n",
|
|
"save_model(model, 'financial-sentiment')"
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "Python 3.8.5 ('.env': venv)",
|
|
"language": "python",
|
|
"name": "python3"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": {
|
|
"name": "ipython",
|
|
"version": 3
|
|
},
|
|
"file_extension": ".py",
|
|
"mimetype": "text/x-python",
|
|
"name": "python",
|
|
"nbconvert_exporter": "python",
|
|
"pygments_lexer": "ipython3",
|
|
"version": "3.8.5"
|
|
},
|
|
"orig_nbformat": 4,
|
|
"vscode": {
|
|
"interpreter": {
|
|
"hash": "2d14168167fa54a6b45c0bc59cb2c3f9a595bd48203d3180b96450e9d825e160"
|
|
}
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 2
|
|
}
|