假期結束,你的狀態有沒有迴歸?那麼,放空腦殼後,先來學習學習,歡迎你們繼續關注騰訊雲技術社區。python
做者:趙成龍 算法
這是一篇很難寫的文章,由於我但願這篇文章能對你們有所幫助。我不會給你們介紹機器學習,數據挖掘的行業背景,也不會具體介紹邏輯迴歸,SVM,GBDT,神經網絡等學習算法的理論依據和數學推導,本文更多的是在流程化上幫助你們快速的入門機器學習和數據建模。數組
本文主要分爲四個部分(限於時間關係會分爲上下兩篇):bash
上篇:網絡
下篇:數據結構
整個sklearn的實驗環境是:python 2.7 + pycharm + Anaconda。app
這裏只能你們介紹下面會用到的pandas知識,有興趣的能夠去具體的學習。給你們推薦一本參考書:《Python for Data Analysis》。有基礎的能夠直接跳到應用篇。dom
pandas主要會用到Series 和DataFrame兩種數據結構。Series像是一維的數組,而DataFrame更像是一種二維的表結構。機器學習
Series的構造方法:學習
label=[1,0,1,0,1]
data = pd.Series(data=label,index=['a','b','c','d','e'],dtype=int,name="label")
print data
複製代碼
Series取數據,經過index取數
data['a']
data[['a','b']]
複製代碼
DataFrame的構造
(1)以字典的形式構造
frame = pd.DataFrame({'name':['Time','Jack','Lily'],'Age':[20,30,12],"weight":[56.7,64.0,50.0]})
複製代碼
(2)由DataFrame 構建DataFrame
frame1 = pd.DataFrame(frame,columns=["name","Age"])
複製代碼
從frame中讀取了兩列構成新的DataFrame。
DataFrame的操做
1 增長列
frame1["friends_num"]=[10,12,14]
複製代碼
2 刪除列
frame2 = frame1.drop(["name","Age"],axis=1)
複製代碼
3 查找數據行
frame1[frame1["friends_num"]>10]
複製代碼
結果以下:
DataFrame的統計方法
1 apply 配合lambda 處理列,如將frame1的Age列進行分段。
frame1["Age_group"] = frame1["Age"].apply(lambda x: 0 if x < 20 else 1)
複製代碼
2 describe輸出統計信息,很是強大
frame1.describe()
複製代碼
給出了8個統計量,對咱們的數據處理特別有用。有個問題,直接使用describe方法只能統計數值類的列,對於字符類的變量沒有統計。加個參數就行。
frame1.describe(include=['O'])
複製代碼
3 缺失值處理
pandas 對缺失值通常填充NAN。
#以0填充缺失值
frame1.fillna(0)
#丟掉任何包含NAN的行
frame1.dropna()
#刪除全爲nan的行
frame1.dropna(how="all")
複製代碼
本例以Titanic做爲數據源。你們能夠在附件獲取到數據。
data = pd.DataFrame(pd.read_csv(train_path))
data_test = pd.DataFrame(pd.read_csv(test_path))
data_test = data_test[["Pclass","Name","Sex","Age","SibSp","Parch","Ticket","Fare","Cabin","Embarked"]]
x = data[["Pclass","Name","Sex","Age","SibSp","Parch","Ticket","Fare","Cabin","Embarked"]]
y = data[["Survived"]]
print x.describe()
print x.describe(include=['O'])
print data_test.describe()
print data_test.describe(include=['O'])
複製代碼
數據的初始統計信息:
1 缺失值處理。
Age和Embarked列存在少許缺失值,分別處理。
#用衆數填充缺失值
data_set["Embarked"]=data_set["Embarked"].fillna('S')
#用均值填充Age缺失值
data_set["Age"]=data_set["Age"].fillna(data_set["Age"].mean())
複製代碼
2 刪除缺失率較大的列(初步處理時)
Cabin列的缺失率達到了75%,刪除改列。
data_set = data_set.drop([ "Cabin"], axis=1)
複製代碼
特徵處理是基於具體的數據的,因此在特徵處理以前要對數據作充分的理解。特徵處理沒有固定方法之說,主要靠我的的經驗與觀察,經過不斷的嘗試和變換,以指望挖掘出較好的特徵變量。因此說,特徵處理是模型創建過程當中最耗時和耗神的工做。
1)單變量特徵提取。
#根據name的長度,抽象出name_len特徵
data_set["name_len"] = data_set["Name"].apply(len)
複製代碼
觀察name列
經過觀察Name列數據,能夠發現名字中帶有性別和婚否的稱謂信息。提取這些信息(多是有用的特徵)。
data_set["name_class"] = data_set["Name"].apply(lambda x : x.split(",")[1]).apply(lambda x :x.split()[0])
複製代碼
2)多變量的組合
sibsp 表明兄弟姐妹和配偶的數量
parch 表明父母和子女的數量
所以能夠將sibsp和parch結合得到家庭成員的數量
data_set["family_num"] = data_set["Parch"] + data_set["SibSp"] +1
複製代碼
3)名義變量轉數值變量
#Embarked
data_set["Embarked"]=data_set["Embarked"].map({'S':1,'C':2,'Q':3}).astype(int)
#Sex
data_set["Sex"] = data_set["Sex"].apply(lambda x : 0 if x=='male' else 1)
複製代碼
4)數據分段
根據統計信息和經驗分段
#[7.91,14.45,31.0]根據Fare的統計信息進行分段
data_set["Fare"] = data_set["Fare"].apply(lambda x:cutFeature([7.91,14.45,31.0],x))
#[18,48,64]按照經驗分段
data_set["Age"] = data_set["Age"].apply(lambda x:cutFeature([18,48,64],x))
複製代碼
簡單的數據處理後,咱們獲得了以下12維數據:
初步選取了5種模型進行試驗
RandomForestClassifier
ExtraTreesClassifier
AdaBoostClassifier
GradientBoostingClassifier
SVC
模型參數:
#隨機森林
rf_params = {
'n_jobs': -1,
'n_estimators': 500,
'warm_start': True,
# 'max_features': 0.2,
'max_depth': 6,
'min_samples_leaf': 2,
'max_features': 'sqrt',
'verbose': 0
}
# Extra Trees 隨機森林
et_params = {
'n_jobs': -1,
'n_estimators': 500,
# 'max_features': 0.5,
'max_depth': 8,
'min_samples_leaf': 2,
'verbose': 0
}
# AdaBoost
ada_params = {
'n_estimators': 500,
'learning_rate': 0.75
}
# GBDT
gb_params = {
'n_estimators': 500,
# 'max_features': 0.2,
'max_depth': 5,
'min_samples_leaf': 2,
'verbose': 0
}
# SVC
svc_params = {
'kernel': 'linear',
'C': 0.025
}
複製代碼
模型選擇代碼:
classifiers = [
("rf_model", RandomForestClassifier(**rf_params)),
("et_model", ExtraTreesClassifier(**et_params)),
("ada_model", AdaBoostClassifier(**ada_params)),
("gb_model", GradientBoostingClassifier(**gb_params)),
("svc_model", SVC(**svc_params)),
]
heldout = [0.95, 0.90, 0.75, 0.50, 0.01]
rounds = 20
xx = 1. - np.array(heldout)
for name, clf in classifiers:
print("training %s" % name)
rng = np.random.RandomState(42)
yy = []
for i in heldout:
yy_ = []
for r in range(rounds):
X_train_turn, X_test_turn, y_train_turn, y_test_turn = \
train_test_split(x_train, labels_train, test_size=i, random_state=rng)
clf.fit(X_train_turn, y_train_turn)
y_pred = clf.predict(X_test_turn)
yy_.append(1 - np.mean(y_pred == y_test_turn))
yy.append(np.mean(yy_))
plt.plot(xx, yy, label=name)
plt.legend(loc="upper right")
plt.xlabel("Proportion train")
plt.ylabel("Test Error Rate")
plt.show()
複製代碼
選擇結果以下:
從上圖能夠看出,randomForest的通常表現要優於其餘算法。初步選擇randomforest算法。
模型的在訓練集上的表現:
def modelScore(x_train,labels_train,x_test,y_test,model_name,et_params):
print("--------%s------------")%(model_name)
model = model_name(**et_params)
model.fit(x_train, labels_train)
if "feature_importances_" in dir(model):
print model.feature_importances_
print classification_report(
labels_train,
model.predict(x_train))
print classification_report(
y_test,
model.predict(x_test))
return model
modelScore(x_train, labels_train, x_test, y_test, RandomForestClassifier, rf_params)
複製代碼
訓練集的混淆矩陣以下圖:
測試集的混淆矩陣以下圖:
到此,初步的學習模型就創建起來了,測試集的準確度爲83%。因爲時間關係,優化篇和思考篇將放在下篇文章與你們分享,敬請期待。
若有任何錯誤或疑問,歡迎你們留言。期待與你們共同成長,共同進步!
舒適提示:文章相關的資料請閱讀原文獲取
此文已由做者受權騰訊雲技術社區發佈,轉載請註明文章出處原文連接:https://cloud.tencent.com/community/article/229506