【天池】新人赛-快来一起挖掘幸福感!

step_1:目标确定

  通过问卷调查数据,选取其中多组变量来预测其对幸福感的评价。

step_2:数据获取

  连接:

    https://tianchi.aliyun.com/competition/entrance/231702/information

  下载:

    train_set:happiness_train_complete.csv

    test_set:happiness_test_complete.csv

    index:文件中包含每个变量对应的问卷题目,以及变量取值的含义

    survey:文件是数据源的原版问卷,作为补充以方便理解问题背景

step_3:train_set数据清洗和整理

  使用matplotlib.pyplot依次画出id和其它列的scatter图

  

  通过图对数据进行操作:

  • happiness是样本标签(预测模型的真实值),通过问卷发现其类别只有1,2,3,4,5,通过图发现有-8,应当删除值为-8这些噪音数据
  • 删除id、survey_time、edu_other、join_party、property_other、invest_other列
  • 其它列所有小于0的值和空值均设置为-8
  • 均值归一化
# jupyter notebook下运行

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

# 导入训练数据集和测试集
# encoding='gbk',不能用utf-8
train_data = pd.read_csv('happiness_train_complete.csv', encoding='gbk')
test_data = pd.read_csv('happiness_test_complete.csv', encoding='gbk')

# 训练集样本个数8000,每个样本含有140个特征
# 测试集样本个数2968,每个样本含有139个特征
train_data.shape
test_data.shape

# 去除-8值
train_data = train_data[train_data.happiness>0]
train_data.shape

# 训练集标签
y = train_data.happiness

ind1 = ['id','happiness','survey_time','edu_other','join_party','property_other','invest_other']
# 训练集样本中删除指定列数据
X = train_data.drop(ind, axis=1)

# 删除测试集中删除指定列数据
ind2 = ['id','survey_time','edu_other','join_party','property_other','invest_other']
X_test_data = test_data.drop(ind, axis=1)

# 把DateFrame类型转为np.array
y = np.array(y, dtype=int)
X = np.array(X, dtype=float)
X_test_data = np.array(X_test_data, dtype=float)

# 把小于0的值设置为-8
X[X<0]=-8
X_test_data[X_test_data<0]=-8

from sklearn.impute import SimpleImputer

# 把样本中的值为空的特征设置为-8
X = SimpleImputer(fill_value=-8).fit_transform(X)
X_test_data = SimpleImputer(fill_value=-8).fit_transform(X_test_data)

from sklearn.model_selection import train_test_split

# 因为测试集没有标签,所以拆分训练集
X_train, X_test, y_train, y_test = train_test_split(X,y, random_state=666)

# 均值归一化
from sklearn.preprocessing import StandardScaler

std = StandardScaler().fit(X_train)
X_train_std = std.transform(X_train)
X_test_std = std.transform(X_test)
std_1 = StandardScaler().fit(X)
X_std = std_1.transform(X)
X_test_data = std_1.transform(X_test_data)
View Code

step_4:选择算法并实现模型

  这是一个分类问题初步定为使用KNN算法来进行建模

from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import GridSearchCV

param_grid = [
    {
         'weights': ['uniform'],
       'n_neighbors':[i for i in range(1,11)]
   },
    {
         'weights': ['distance'],
       'n_neighbors': [i for i in range(1,11)],
       'p': [i for i in range(1,6)]
}]

# 网格搜索优化超参数
knn_clf_grid = KNeighborsClassifier()
grid_search = GridSearchCV(knn_clf_grid, param_grid,n_jobs=-1, verbose=2).fit(X_train_std, y_train)

# 最优超参数为:{'n_neighbors': 10, 'p': 1, 'weights': 'distance'}
grid_search.best_estimator_
grid_search.best_params_
grid_search.best_score_

# 使用真正测试集加载模型
knn = KNeighborsClassifier(n_neighbors=10, p=1, weights='distance').fit(X_std, y)
y_pre = knn.predict(X_test_data)

# 把预测结果写入文件
df = pd.DataFrame({'id':test_data.id, 'happniess': y_pre})
df.to_csv('forecast_3.csv', index=None)
View Code

  提交结果到天池等待评测分数结果score=0.6814

  结果提交3次:

    第一次:score=1.3260

    第二次:数据均值归一化score=0.9629

    第三次:数据均值归一化+网格搜索优化超参数score=0.6814

    第四次:数据均值归一化+PCA+逻辑回归(OvO)score=0.6099

import numpy as np
import pandas as pd

# 导入train_set和test_set, encoding='gbk',不能用utf-8
train_set = pd.read_csv('happiness_train_complete.csv', encoding='gbk')
test_set = pd.read_csv('happiness_test_complete.csv', encoding='gbk')

# 去除标签中不合理的数据 -8
train_set = train_set[train_set.happiness>0]

y_label = train_set.happiness
ind1 = ['id','happiness','survey_time','edu_other','join_party','property_other','invest_other']
X_train_set = train_set.drop(ind1, axis=1)

ind2 = ['id','survey_time','edu_other','join_party','property_other','invest_other']
X_test_set = test_set.drop(ind2, axis=1)

y_label = np.array(y_label, dtype=int)
X_train_set = np.array(X_train_set, dtype=float)
X_test_set = np.array(X_test_set, dtype=float)

from sklearn.impute import SimpleImputer

# 空值设置为-1
X_train_set = SimpleImputer(fill_value=-1).fit_transform(X_train_set)
X_test_set = SimpleImputer(fill_value=-1).fit_transform(X_test_set)

# # 小于0的值设置为-1
X_train_set[X_train_set < 0] = -1
X_test_set[X_test_set < 0] = -1

from sklearn.preprocessing import StandardScaler

# 均值归一化
std = StandardScaler().fit(X_train_set)
X_train__std = std.transform(X_train_set)
X_test__std = std.transform(X_test_set)

# PCA降维
from sklearn.decomposition import PCA

# 包含95%的方差信息
pca = PCA(0.95)
pca.fit(X_train__std)

X_train_pca = pca.transform(X_train__std)
X_test_pca = pca.transform(X_test__std)

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X_train_pca, y_label, random_state=666)

from sklearn.linear_model import LogisticRegression

best_c = 0.
best_score = 0.
best_sum = 10.

for c in np.arange(0.001, 0.3, 0.001):
    log_reg2 = LogisticRegression(C=c, multi_class='multinomial', solver='newton-cg').fit(X_train, y_train)
    y_pre = log_reg2.predict(X_test)
    s = sum((y_pre-y_test)**2/len(y_test))
    score = log_reg2.score(X_test, y_test)
    if best_sum > s:
        best_sum = s
        best_c = c
        best_score = score
print('c:', best_c)
print('score:', best_score)
print('sum:', best_sum)

log_reg = LogisticRegression(C=0.01, multi_class='multinomial', solver='newton-cg').fit(X_train, y_train)
y_pre2 = log_reg.predict(X_test_pca)

df = pd.DataFrame({'id':test_set.id, 'happniess': y_pre2})
df.to_csv('log_reg_pca.csv', index=None)
View Code
原文地址:https://www.cnblogs.com/jp-mao/p/10487082.html