前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >kaggle示例1—研究生录取判断问题

kaggle示例1—研究生录取判断问题

作者头像
bear_fish
发布2018-09-14 10:02:39
9180
发布2018-09-14 10:02:39
举报

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://cloud.tencent.com/developer/article/1338377

问题描述:

UCLA(加利福尼亚大学洛杉矶分校)研究生录取的二分类问题,数据来源:http://www.ats.ucla.edu/stat/data/binary.csv

使用的属性主要有下面四列(前三列为属性,最后一列为结果(类别能否被录用):

  1. gpa
  2. gre分数
  3. rank表示本科生母校的声望
  4. admit则是二分类目标变量(binary target variable),它表明考生最终是否被录取。

本文主要内容:
  1. 使用python pandas数据预处理,包括数据的统计信息,dummy variable(哑变量的处理),数据归一化
  2. 使用sklearn的不同分类方法:LogisticRegression, RandomForestClassifier, KNeighborsClassifier, xgboost对处理好的数据进行分类
  3. GridSearchCV自动参数寻优
  4. 对比数据不做dummy variable处理情况下的识别率。

开发环境建议使用anaconda(python2.7) + pychram


1 数据预处理

1.1 数据导入

下载上面连接的csv文件,命名为UCLA_dataset.csv

代码语言:javascript
复制
import pandas as pd
def get_data():
    f_path = "./dataset/UCLA_dataset.csv"
    df = pd.read_csv(f_path)
    print df.head()  ## 输出前五行

输出结果如下:

代码语言:javascript
复制
   admit  gre   gpa  rank
0      0  380  3.61     3
1      1  660  3.67     3
2      1  800  4.00     1
3      1  640  3.19     4
4      0  520  2.93     4

由于rank为pandas的DataFrame的列属性这里将其rename为prestige(n.

威望;声望)

代码语言:javascript
复制
    df.rename(columns={"rank": "prestige"}, inplace=True)
    print df.head()
    return df

前五行输出如下:

代码语言:javascript
复制
    admit gre   gpa  prestige
0      0  380  3.61         3
1      1  660  3.67         3
2      1  800  4.00         1
3      1  640  3.19         4
4      0  520  2.93         4
1.2 查看数据统计信息
代码语言:javascript
复制
def statistic_data(df):
    print df.describe()

输出如下:

代码语言:javascript
复制
            admit         gre         gpa   prestige
count  400.000000  400.000000  400.000000  400.00000
mean     0.317500  587.700000    3.389900    2.48500
std      0.466087  115.516536    0.380567    0.94446
min      0.000000  220.000000    2.260000    1.00000
25%      0.000000  520.000000    3.130000    2.00000
50%      0.000000  580.000000    3.395000    2.00000
75%      1.000000  660.000000    3.670000    3.00000
max      1.000000  800.000000    4.000000    4.00000
查看学校声望(1, 2, 3, 4)不同时,’admit’的情况:
代码语言:javascript
复制
print pd.crosstab(df['admit'], df['prestige'], rownames=['admit'])

输出如下:

代码语言:javascript
复制
prestige   1   2   3   4
admit                   
0         28  97  93  55
1         33  54  28  12

可见学校的声望越好(1最好),被录取的概率更高

查看gre不同时,’admit’的情况:
代码语言:javascript
复制
# 没有被录取的
no_admits = df[df.admit == 0]
print no_admits.shape
# 没有被录取的学生gre统计信息
print no_admits.gre.describe()

# 被录取的
admits = df[df.admit == 1]
print admits.shape
# 被录取的学生gre统计信息
print admits.gre.describe()

输出如下:

代码语言:javascript
复制
# 没有被录取的学生公有273个,的平均分为 573.18
(273, 4)
count    273.000000
mean     573.186813
std      115.830243
min      220.000000
25%      500.000000
50%      580.000000
75%      660.000000
max      800.000000
Name: gre, dtype: float64

# 被录取的学生公有127个,的平均分为 618.89
(127, 4)
count    127.000000
mean     618.897638
std      108.884884
min      300.000000
25%      540.000000
50%      620.000000
75%      680.000000
max      800.000000
Name: gre, dtype: float64

由此可见gre分数越高,越容易被录取。下面看下直方图:

代码语言:javascript
复制
f, (ax1, ax2) = plt.subplots(2, 1, sharex=True)
f.suptitle('gre per by class')
bins = 20
ax1.hist(no_admits.gre, bins=bins)
ax1.set_title('no_admits')

ax2.hist(admits.gre, bins=bins)
ax2.set_title('admits')

plt.xlabel('gre')
plt.ylabel('Number of gre')
plt.show()
查看数据的统计直方图
代码语言:javascript
复制
import matplotlib.pyplot as plt
import seaborn as sns
sns.set()

df.hist()
plt.show()
dummy variable(哑变量处理)

虚拟变量,也叫哑变量,可用来表示分类变量、非数量因素可能产生的影响。在计量经济学模型,需要经常考虑属性因素的影响。例如,职业、文化程度、季节等属性因素往往很难直接度量它们的大小。只能给出它们的“Yes—D=1”或”No—D=0”,或者它们的程度或等级。为了反映属性因素和提高模型的精度,必须将属性因素“量化”。通过构造0-1型的人工变量来量化属性因素。 pandas提供了一系列分类变量的控制。我们可以用get_dummies来将”prestige”一列虚拟化。 在本例中,prestige有四个级别:1,2,3以及4(1代表最有声望),prestige作为分类变量更加合适。当调用get_dummies时,会产生四列的dataframe,每一列表示四个级别中的一个。

代码语言:javascript
复制
def process_df(df):
    dummy_ranks = pd.get_dummies(df['prestige'], prefix='prestige')
    print dummy_ranks.tail()

输出如下:

代码语言:javascript
复制
      prestige_1    prestige_2   prestige_3  prestige_4
395         0.0         1.0         0.0         0.0
396         0.0         0.0         1.0         0.0
397         0.0         1.0         0.0         0.0
398         0.0         1.0         0.0         0.0
399         0.0         0.0         1.0         0.0

引入的虚拟变量列数应为虚拟变量总列数减1,减去的1列作为基准

.最终的构造数据如下:

代码语言:javascript
复制
cols_to_keep = ['admit', 'gre', 'gpa']

data = df[cols_to_keep].join(dummy_ranks.ix[:, 'prestige_2':])
print data.tail()

输出如下:

代码语言:javascript
复制
     admit  gre   gpa  prestige_2  prestige_3  prestige_4
395      0  620  4.00         1.0         0.0         0.0
396      0  560  3.04         0.0         1.0         0.0
397      0  460  2.63         1.0         0.0         0.0
398      0  700  3.65         1.0         0.0         0.0
399      0  600  3.89         0.0         1.0         0.0
数据集的归一化

考虑把gre, gpa两列数据归一化(数据的量级不是很大,大概100倍),不过实际使用中发现除了KNeighborsClassifier分类方法,对于其他的分类方法而言,归一化并没有提升分类准确率:

代码语言:javascript
复制
def process_df_norm(df):
    dummy_ranks = pd.get_dummies(df['prestige'], prefix='prestige')
    print dummy_ranks.tail()

    cols_to_keep = ['admit', 'gre', 'gpa']

    df = df[cols_to_keep].join(dummy_ranks.ix[:, 'prestige_2':])

    cols_norm = ['gre', 'gpa']
    f_norm = lambda x: (x - x.min()) / (x.max() - x.min())
    df[cols_norm] = df[cols_norm].apply(f_norm)
    print df.tail()
    return df

输出如下:

代码语言:javascript
复制
      admit     gre       gpa   prestige_2   prestige_3    prestige_4
395      0  0.689655  1.000000         1.0         0.0         0.0
396      0  0.586207  0.448276         0.0         1.0         0.0
397      0  0.413793  0.212644         1.0         0.0         0.0
398      0  0.827586  0.798851         1.0         0.0         0.0
399      0  0.655172  0.936782         0.0         1.0         0.0
数据集按照4:1划分
代码语言:javascript
复制
from sklearn.model_selection import train_test_split
def split_train_test(df):
    X = df.ix[:, 1:]
    Y = df.admit
    X_train, X_test, Y_train, Y_test = train_test_split(X, Y,
                                                        test_size=0.2, random_state=40)

    return X_train, X_test, Y_train, Y_test

2 模型训练以及测试

2.1 预测结果的准确率以及混淆矩阵输出
代码语言:javascript
复制
from sklearn.metrics import confusion_matrix, recall_score
from sklearn.metrics import accuracy_score

def print_cm_accuracy(Y_true, Y_pred):
    cnf_matrix = confusion_matrix(Y_true, Y_pred)
    print cnf_matrix
    accuracy_percent = accuracy_score(Y_true, Y_pred)
    print "accuracy is: %s%s" % (accuracy_percent * 100, '%')

2.2 LogisticRegression逻辑回归
代码语言:javascript
复制
from sklearn.linear_model import LogisticRegression
def lr_fit_test(X_train, X_test, Y_train, Y_test):
    lr = LogisticRegression()
    # lr = LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,
    #                         intercept_scaling=1, penalty='l2', random_state=None, tol=0.0001)

    lr.fit(X_train, Y_train)
    Y_pred = lr.predict(X_test)
    print_cm_accuracy(Y_test, Y_pred)

输出如下:

[53 0

23 4]

accuracy is: 71.25%

  1. 上面的:lr参数发现C=1.0时准确率最高
  2. 数据归一化之后,准确率竟然下降了1.25%

2.3 RandomForestClassifier随机森林
代码语言:javascript
复制
def rfc_fit_test(X_train, X_test, Y_train, Y_test):
    rf = RandomForestClassifier(n_jobs=4)
    rf.fit(X_train, Y_train)
    Y_pred = rf.predict(X_test)
    print_cm_accuracy(Y_test, Y_pred)

输出:

[46 7

17 10]

accuracy is: 70.0%

相同的数据集,随机森林的精度较低(逻辑回归为71.25%)

下面看下数据归一化后的准确率:(原有的基础上面下降了)

[48 5

20 7]

accuracy is: 68.75%


2.4 KNeighborsClassifier k近邻

下面给出K近邻的不同K值是准确度,以及数据是否归一化的对比:

代码语言:javascript
复制
def knn_fit_test(X_train, X_test, Y_train, Y_test):
    # 对比不同k值,准确率的变化
    ks = [1, 3, 5, 7]
    for k in ks:
        print 'KNeighborsClassifier k is %s' % k
        knn = KNeighborsClassifier(n_neighbors=k)
        knn.fit(X_train, Y_train)

        Y_pred = knn.predict(X_test)
        print_cm_accuracy(Y_test, Y_pred)

数据不归一化:

代码语言:javascript
复制
KNeighborsClassifier k is 1
[[41 12]
 [15 12]]
accuracy is: 66.25%
KNeighborsClassifier k is 3
[[44  9]
 [17 10]]
accuracy is: 67.5%
KNeighborsClassifier k is 5
[[47  6]
 [17 10]]
accuracy is: 71.25%
KNeighborsClassifier k is 7

……..太多了省略了

数据归一化:

代码语言:javascript
复制
KNeighborsClassifier k is 1
[[41 12]
 [15 12]]
accuracy is: 66.25%
KNeighborsClassifier k is 3
[[44  9]
 [14 13]]
accuracy is: 71.25%
KNeighborsClassifier k is 5
[[44  9]
 [15 12]]
accuracy is: 70.0%

当然K值也可以使用GridSearchCV网格参数寻优:

代码语言:javascript
复制
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import classification_report

def knn_fit_test(X_train, X_test, Y_train, Y_test):
    paras = {'n_neighbors': [1, 3, 5, 7]}
    knn = KNeighborsClassifier()
    clf = GridSearchCV(knn, paras, n_jobs=-1)
    clf.fit(X_train, Y_train)
    print 'The parameters of the best model are: '
    print clf.best_params_

    for params, mean_score, scores in clf.grid_scores_:
        print("%0.3f (+/-%0.03f) for %r"
              % (mean_score, scores.std() * 2, params))

    Y_pred = clf.predict(X_test)
    print classification_report(Y_test, Y_pred)

输出如下:

代码语言:javascript
复制
0.616 (+/-0.060) for {'n_neighbors': 1}
0.656 (+/-0.049) for {'n_neighbors': 3}
0.669 (+/-0.055) for {'n_neighbors': 5}
0.666 (+/-0.063) for {'n_neighbors': 7}
             precision    recall  f1-score   support

          0       0.75      0.89      0.81        53
          1       0.65      0.41      0.50        27

avg / total       0.71      0.72      0.71        80
2.5 xgboost已经不使用dummy variable

前面已经发现,学校声望越高越容易被录取,而且学校声望已经按照顺序排列,因此考虑,直接使用原来的值(试验发现,准确率更高了):

对于K近邻算法:

对于每种方法,直接使用学校声望的值,对于每种方法结果准确率跟高了。

下面给出xgboost的预测代码:

代码语言:javascript
复制
def xgb_fit_test(X_train, X_test, Y_train, Y_test):
    import os
    mingw_path = 'C:/Program Files/mingw-w64/x86_64-6.2.0-posix-seh-rt_v5-rev1/mingw64/bin'
    os.environ['PATH'] = mingw_path + ';' + os.environ['PATH']
    from xgboost import XGBClassifier

    model = XGBClassifier()
    model.fit(X_train, Y_train)

    Y_pred = model.predict(X_test)
    print_cm_accuracy(Y_test, Y_pred)

注:这个示例不是来源与kaggle,但是这里方便文字归类,将其命名为kaggle

转载注明出处哈。

参考:

http://blog.yhat.com/posts/logistic-regression-python-rodeo.html

http://www.powerxing.com/logistic-regression-in-python/

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017年12月10日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 问题描述:
  • 本文主要内容:
  • 1 数据预处理
    • 1.1 数据导入
      • 1.2 查看数据统计信息
        • 查看学校声望(1, 2, 3, 4)不同时,’admit’的情况:
          • 查看gre不同时,’admit’的情况:
            • 查看数据的统计直方图
              • dummy variable(哑变量处理)
                • 数据集的归一化
                  • 数据集按照4:1划分
                  • 2 模型训练以及测试
                    • 2.1 预测结果的准确率以及混淆矩阵输出
                      • 2.2 LogisticRegression逻辑回归
                        • 2.3 RandomForestClassifier随机森林
                          • 2.4 KNeighborsClassifier k近邻
                            • 2.5 xgboost已经不使用dummy variable
                            • 参考:
                            领券
                            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档