2017年9月24日 星期日
[戲劇] 大王不容易
又有一陣子沒看戲,更別說是大陸戲劇了。被室友推坑看了一下,前面還滿新鮮的,但後面的滋味有點難述 XD 論其喜好,我比較喜歡前半段的安排,酷酷的女主角很正,男主角娘的很流暢。除此之外,也有發現一位台灣女演員 袁子芸 。我覺得古裝有種像做實驗時,控制變因似的,當大家穿一樣的服裝時,天生麗質的就會被凸顯出來。
說說別的吧,一開始吸引人的是男主角詮釋女主角個性的演技,查了一下 WIKI 才知道男主角 张逸杰 1999 年 9月 2 號出生,前幾天才剛滿18歲而已!女主角 白鹿 是 1994 年 9 月 23 號出生的。原來演戲的跟看戲的都是處女座 XD
看著百度百科,讓人有點感到恐怖,年輕時期就很努力地打拼了,時間啊。
2017年9月19日 星期二
[Python] 機器學習筆記 - 使用 Pandas 處理 CSV 格式、過濾資料與自身 Index 更新問題
使用 Pandas 套件進行分析資料時,它提供的功能包括便利的資料過濾:
然而,預設 Pandas 會記錄原先的 raw index ,這也有不錯的功用,但有時希望照新的架構顯示,需要再多用 reset_index():
連續動作:
import seaborn as sns
import pandas as pd
dataset = sns.load_dataset("tips")
print(dataset)
print(dataset.shape)
print(dataset.columns)
print("list total_bill > 30:")
print(dataset[ dataset['total_bill'] > 30 ] )
然而,預設 Pandas 會記錄原先的 raw index ,這也有不錯的功用,但有時希望照新的架構顯示,需要再多用 reset_index():
print("list total_bill > 30 and tip < 4:")
print(dataset[ (dataset['total_bill'] > 30) & (dataset['tip'] < 4) ] )
print("rebuild index:")
dataset = dataset[ (dataset['total_bill'] > 30) & (dataset['tip'] < 4) ]
dataset = dataset.reset_index()
print(dataset)
連續動作:
$ python pandas_study.py
total_bill tip sex smoker day time size
0 16.99 1.01 Female No Sun Dinner 2
1 10.34 1.66 Male No Sun Dinner 3
2 21.01 3.50 Male No Sun Dinner 3
3 23.68 3.31 Male No Sun Dinner 2
4 24.59 3.61 Female No Sun Dinner 4
5 25.29 4.71 Male No Sun Dinner 4
6 8.77 2.00 Male No Sun Dinner 2
7 26.88 3.12 Male No Sun Dinner 4
8 15.04 1.96 Male No Sun Dinner 2
9 14.78 3.23 Male No Sun Dinner 2
10 10.27 1.71 Male No Sun Dinner 2
11 35.26 5.00 Female No Sun Dinner 4
12 15.42 1.57 Male No Sun Dinner 2
13 18.43 3.00 Male No Sun Dinner 4
14 14.83 3.02 Female No Sun Dinner 2
15 21.58 3.92 Male No Sun Dinner 2
16 10.33 1.67 Female No Sun Dinner 3
17 16.29 3.71 Male No Sun Dinner 3
18 16.97 3.50 Female No Sun Dinner 3
19 20.65 3.35 Male No Sat Dinner 3
20 17.92 4.08 Male No Sat Dinner 2
21 20.29 2.75 Female No Sat Dinner 2
22 15.77 2.23 Female No Sat Dinner 2
23 39.42 7.58 Male No Sat Dinner 4
24 19.82 3.18 Male No Sat Dinner 2
25 17.81 2.34 Male No Sat Dinner 4
26 13.37 2.00 Male No Sat Dinner 2
27 12.69 2.00 Male No Sat Dinner 2
28 21.70 4.30 Male No Sat Dinner 2
29 19.65 3.00 Female No Sat Dinner 2
.. ... ... ... ... ... ... ...
214 28.17 6.50 Female Yes Sat Dinner 3
215 12.90 1.10 Female Yes Sat Dinner 2
216 28.15 3.00 Male Yes Sat Dinner 5
217 11.59 1.50 Male Yes Sat Dinner 2
218 7.74 1.44 Male Yes Sat Dinner 2
219 30.14 3.09 Female Yes Sat Dinner 4
220 12.16 2.20 Male Yes Fri Lunch 2
221 13.42 3.48 Female Yes Fri Lunch 2
222 8.58 1.92 Male Yes Fri Lunch 1
223 15.98 3.00 Female No Fri Lunch 3
224 13.42 1.58 Male Yes Fri Lunch 2
225 16.27 2.50 Female Yes Fri Lunch 2
226 10.09 2.00 Female Yes Fri Lunch 2
227 20.45 3.00 Male No Sat Dinner 4
228 13.28 2.72 Male No Sat Dinner 2
229 22.12 2.88 Female Yes Sat Dinner 2
230 24.01 2.00 Male Yes Sat Dinner 4
231 15.69 3.00 Male Yes Sat Dinner 3
232 11.61 3.39 Male No Sat Dinner 2
233 10.77 1.47 Male No Sat Dinner 2
234 15.53 3.00 Male Yes Sat Dinner 2
235 10.07 1.25 Male No Sat Dinner 2
236 12.60 1.00 Male Yes Sat Dinner 2
237 32.83 1.17 Male Yes Sat Dinner 2
238 35.83 4.67 Female No Sat Dinner 3
239 29.03 5.92 Male No Sat Dinner 3
240 27.18 2.00 Female Yes Sat Dinner 2
241 22.67 2.00 Male Yes Sat Dinner 2
242 17.82 1.75 Male No Sat Dinner 2
243 18.78 3.00 Female No Thur Dinner 2
[244 rows x 7 columns]
(244, 7)
Index(['total_bill', 'tip', 'sex', 'smoker', 'day', 'time', 'size'], dtype='object')
list total_bill > 30:
total_bill tip sex smoker day time size
11 35.26 5.00 Female No Sun Dinner 4
23 39.42 7.58 Male No Sat Dinner 4
39 31.27 5.00 Male No Sat Dinner 3
44 30.40 5.60 Male No Sun Dinner 4
47 32.40 6.00 Male No Sun Dinner 4
52 34.81 5.20 Female No Sun Dinner 4
56 38.01 3.00 Male Yes Sat Dinner 4
59 48.27 6.73 Male No Sat Dinner 4
83 32.68 5.00 Male Yes Thur Lunch 2
85 34.83 5.17 Female No Thur Lunch 4
95 40.17 4.73 Male Yes Fri Dinner 4
102 44.30 2.50 Female Yes Sat Dinner 3
112 38.07 4.00 Male No Sun Dinner 3
141 34.30 6.70 Male No Thur Lunch 6
142 41.19 5.00 Male No Thur Lunch 5
156 48.17 5.00 Male No Sun Dinner 6
167 31.71 4.50 Male No Sun Dinner 4
170 50.81 10.00 Male Yes Sat Dinner 3
173 31.85 3.18 Male Yes Sun Dinner 2
175 32.90 3.11 Male Yes Sun Dinner 2
179 34.63 3.55 Male Yes Sun Dinner 2
180 34.65 3.68 Male Yes Sun Dinner 4
182 45.35 3.50 Male Yes Sun Dinner 3
184 40.55 3.00 Male Yes Sun Dinner 2
187 30.46 2.00 Male Yes Sun Dinner 5
197 43.11 5.00 Female Yes Thur Lunch 4
207 38.73 3.00 Male Yes Sat Dinner 4
210 30.06 2.00 Male Yes Sat Dinner 3
212 48.33 9.00 Male No Sat Dinner 4
219 30.14 3.09 Female Yes Sat Dinner 4
237 32.83 1.17 Male Yes Sat Dinner 2
238 35.83 4.67 Female No Sat Dinner 3
list total_bill > 30 and tip < 4:
print index:
index: 56
index: 102
index: 173
index: 175
index: 179
index: 180
index: 182
index: 184
index: 187
index: 207
index: 210
index: 219
index: 237
rebuild index:
index total_bill tip sex smoker day time size
0 56 38.01 3.00 Male Yes Sat Dinner 4
1 102 44.30 2.50 Female Yes Sat Dinner 3
2 173 31.85 3.18 Male Yes Sun Dinner 2
3 175 32.90 3.11 Male Yes Sun Dinner 2
4 179 34.63 3.55 Male Yes Sun Dinner 2
5 180 34.65 3.68 Male Yes Sun Dinner 4
6 182 45.35 3.50 Male Yes Sun Dinner 3
7 184 40.55 3.00 Male Yes Sun Dinner 2
8 187 30.46 2.00 Male Yes Sun Dinner 5
9 207 38.73 3.00 Male Yes Sat Dinner 4
10 210 30.06 2.00 Male Yes Sat Dinner 3
11 219 30.14 3.09 Female Yes Sat Dinner 4
12 237 32.83 1.17 Male Yes Sat Dinner 2
print index:
index: 0
index: 1
index: 2
index: 3
index: 4
index: 5
index: 6
index: 7
index: 8
index: 9
index: 10
index: 11
index: 12
2017年9月15日 星期五
[Python] 機器學習筆記 - 使用 準確率/召回率 (Precision-Recall) 評估分析成果
研究所時,算是第一次接觸這名詞,老闆的研究領域是 Search Engines ,用來評估索引成果好不好。最近則打算用在機器學習的成果分析,卻想不起當時老闆用來解釋索引成果的案例,還是容易忘記 XD 網路上打滾一下,發現這篇寫的廣告投放實際案例很好懂,也不容易忘,建議可以逛一下:準確率(Precision)與召回率(Recall)
回到本文,單純紀錄如何用既有函式庫計算:
成果:
需要更詳細的範例,請參考:http://scikit-learn.org/stable/auto_examples/model_selection/plot_precision_recall.html
回到本文,單純紀錄如何用既有函式庫計算:
import numpy as np
from sklearn.metrics import average_precision_score, precision_score, recall_score
# Classification metrics can't handle a mix of binary and continuous targets
#y = np.array([0, 0, 1, 1])
#scores = np.array([0.1, 0.3, 0.2, 0.8])
y = [0, 0, 1, 1]
scores = [0, 1, 1, 1]
#print(precision_score(y, scores, average='macro'))
#print(recall_score(y, scores, average='macro'))
#print(average_precision_score(y, scores))
#import sys
#sys.exit(0)
print('precision: %0.2f, recall: %0.2f, score: %0.2f' % (
precision_score(y, scores, average='macro'),
recall_score(y, scores, average='macro'),
average_precision_score(y, scores)
))
成果:
precision: 0.83, recall: 0.75, score: 0.67
需要更詳細的範例,請參考:http://scikit-learn.org/stable/auto_examples/model_selection/plot_precision_recall.html
[Python] 機器學習筆記 - 使用 ROC 曲線 (receiver operating characteristic curve) 評估分析成果
最近回想起兩年前走跳過的一場黑客松,當年的題目恰好是一個屬性的分類,就是一篇文章屬性給你,請告訴我它是不是 spam!所幸網路上還可以看到其他人的作品,逛了一下也順便研究別人的報告怎麼寫,其中有一組使用了 ROC 曲線來回報自己的分析成果,就來多多認識一下。
而 ROC 曲線是什麼?其實在 WIKI 或是 scikit-learn 文件(也引用WIKI資料)有很明確地解釋:
- https://zh.wikipedia.org/wiki/ROC%E6%9B%B2%E7%BA%BF
- http://scikit-learn.org/stable/modules/model_evaluation.html#receiver-operating-characteristic-roc
因此,只需設法把模型預測結果畫一下 ROC 曲線,在算出個面積,就收工啦!
範例請參考 http://scikit-learn.org/stable/auto_examples/model_selection/plot_roc.html ,在此只筆記畫圖的部分:
import numpy as np
from sklearn.metrics import roc_curve, auc
y = np.array([0, 0, 1, 1])
scores = np.array([0.1, 0.4, 0.35, 0.8])
fpr, tpr, _ = roc_curve(y, scores)
roc_auc = auc(fpr, tpr)
import matplotlib as mpl
#mpl.use('Agg')
import matplotlib.pyplot as plt
fig = plt.figure()
lw = 2
plt.plot(fpr, tpr, color='darkorange', lw=lw, label='ROC curve (area = %0.2f)' % roc_auc)
plt.plot([0, 1], [0, 1], color='navy', lw=lw, linestyle='--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver operating characteristic example')
plt.legend(loc="lower right")
#fig.savefig('/tmp/roc.png')
plt.show()
2017年9月14日 星期四
[MySQL] 從 JSON 抽取資料建立虛擬欄位 @ MySQL 5.7
同事反映 query 很慢,除了改進 SQL 語法外,也小試身手,對 JSON 資料抽出來建立虛擬欄位跟索引,順便筆記一下。
這邊 data column 是 text 型態,主因是這 DB server 從 5.6 升上來的 XD 且當初讓 data 有很多彈性,不一定是 json 格式。
但,要抽取成虛擬欄位時,建議要保持 data 是 json 格式,就先整理一下資料:
假想 data 的數值為 {"keyword":"value"},因此抽出 keyword 虛擬欄位來用:
如此一來,可以改對 keyword 欄位查詢了,可以再加快一點,而 table 狀態更新為:
CREATE TABLE `my_data` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`data` text,
PRIMARY KEY (`id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
這邊 data column 是 text 型態,主因是這 DB server 從 5.6 升上來的 XD 且當初讓 data 有很多彈性,不一定是 json 格式。
但,要抽取成虛擬欄位時,建議要保持 data 是 json 格式,就先整理一下資料:
mysql> UPDATE my_data SET data = '{}' WHERE data IS NULL OR data = ''
假想 data 的數值為 {"keyword":"value"},因此抽出 keyword 虛擬欄位來用:
mysql> ALTER TABLE my_data ADD keyword VARCHAR(64) AS (JSON_UNQUOTE(data->>"$. keyword"));
mysql> ALTER TABLE my_data ADD INDEX (keyword);
如此一來,可以改對 keyword 欄位查詢了,可以再加快一點,而 table 狀態更新為:
CREATE TABLE `my_data ` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`data` text,
`keyword` varchar(64) GENERATED ALWAYS AS (json_unquote(json_unquote(json_extract(`data`,'$. keyword')))) VIRTUAL,
PRIMARY KEY (`id`),
KEY `keyword ` (`keyword `),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
訂閱:
文章 (Atom)