精华内容
下载资源
问答
  • 机器学习系列(3)_逻辑回归应用之Kaggle泰坦尼克之灾

    万次阅读 多人点赞 2015-11-12 12:07:12
    手把手机器学习之逻辑回归应用——Kaggle泰坦尼克之灾1.引言先说一句,年末双十一什么的一来,真是非(mang)常(cheng)欢(gou)乐(le)!然后push自己抽出时间来写这篇blog的原因也非常简单: 写完前两篇逻辑回归的介绍...

    作者: 寒小阳
    时间:2015年11月。
    出处:http://blog.csdn.net/han_xiaoyang/article/details/49797143
    声明:版权所有,转载请注明出处,谢谢。

    1.引言

    先说一句,年末双十一什么的一来,真是非(mang)常(cheng)欢(gou)乐(le)!然后push自己抽出时间来写这篇blog的原因也非常简单:

    • 写完前两篇逻辑回归的介绍和各个角度理解之后,我们讨论群(戳我入群)的小伙伴们纷纷表示『好像很高级的样纸,but 然并卵 啊!你们倒是拿点实际数据来给我们看看,这玩意儿 有!什!么!用!啊!』
    • talk is cheap, show me the code!
    • no example say a jb!

    OK,OK,这就来了咯,同学们别着急,我们先找个简单的实际例子,来看看,所谓的数据挖掘或者机器学习实际应用到底是怎么样一个过程。

    『喂,那几个说要看大数据上机器学习应用的,对,就是说你们!别着急好么,我们之后拉点大一点实际数据用liblinear或者spark,MLlib跑给你们看,行不行?咱们先拿个实例入入门嘛』

    好了,我是一个严肃的技术研究和分享者,咳咳,不能废话了,各位同学继续往下看吧!

    2.背景

    2.1 关于Kaggle

    • 我是Kaggle地址,翻我牌子
    • 亲,逼格这么高的地方,你一定听过对不对?是!这就是那个无数『数据挖掘先驱』们,在回答"枪我有了,哪能找到靶子练练手啊?"时候的答案!
    • 这是一个要数据有数据,要实际应用场景有场景,要一起在数据挖掘领域high得不要不要的小伙伴就有小伙伴的地方啊!!!

    艾玛,逗逼模式开太猛了。恩,不闹,不闹,说正事,Kaggle是一个数据分析建模的应用竞赛平台,有点类似KDD-CUP(国际知识发现和数据挖掘竞赛),企业或者研究者可以将问题背景、数据、期望指标等发布到Kaggle上,以竞赛的形式向广大的数据科学家征集解决方案。而热爱数(dong)据(shou)挖(zhe)掘(teng)的小伙伴们可以下载/分析数据,使用统计/机器学习/数据挖掘等知识,建立算法模型,得出结果并提交,排名top的可能会有奖金哦!

    2.2 关于泰坦尼克号之灾

    • 带大家去该问题页面溜达一圈吧

      • 下面是问题背景页
        泰坦尼克号问题背景页
      • 下面是可下载Data的页面
        Data页面
      • 下面是小伙伴们最爱的forum页面,你会看到各种神级人物厉(qi)害(pa)的数据处理/建模想法,你会直视『世界真奇妙』。
        论坛页面
    • 泰坦尼克号问题之背景

      • 就是那个大家都熟悉的『Jack and Rose』的故事,豪华游艇倒了,大家都惊恐逃生,可是救生艇的数量有限,无法人人都有,副船长发话了『lady and kid first!』,所以是否获救其实并非随机,而是基于一些背景有rank先后的

      • 训练和测试数据是一些乘客的个人信息以及存活状况,要尝试根据它生成合适的模型并预测其他人的存活状况

      • 对,这是一个二分类问题,是我们之前讨论的logistic regression所能处理的范畴。

    3.说明

    接触过Kaggle的同学们可能知道这个问题,也可能知道RandomForest和SVM等等算法,甚至还对多个模型做过融合,取得过非常好的结果,那maybe这篇文章并不是针对你的,你可以自行略过。

    我们因为之前只介绍了Logistic Regression这一种分类算法。所以本次的问题解决过程和优化思路,都集中在这种算法上。其余的方法可能我们之后的文章里会提到。

    说点个人的观点。不一定正确。
    『解决一个问题的方法和思路不止一种』
    『没有所谓的机器学习算法优劣,也没有绝对高性能的机器学习算法,只有在特定的场景、数据和特征下更合适的机器学习算法。』

    4.怎么做?

    手把手教程马上就来,先来两条我看到的,觉得很重要的经验。

    1. 印象中Andrew Ng老师似乎在coursera上说过,应用机器学习,千万不要一上来就试图做到完美,先撸一个baseline的model出来,再进行后续的分析步骤,一步步提高,所谓后续步骤可能包括『分析model现在的状态(欠/过拟合),分析我们使用的feature的作用大小,进行feature selection,以及我们模型下的bad case和产生的原因』等等。

    2. Kaggle上的大神们,也分享过一些experience,说几条我记得的哈:

      • 『对数据的认识太重要了!』
      • 『数据中的特殊点/离群点的分析和处理太重要了!』
      • 『特征工程(feature engineering)太重要了!在很多Kaggle的场景下,甚至比model本身还要重要』
      • 『要做模型融合(model ensemble)啊啊啊!』

    更多的经验分享请加讨论群,具体方式请联系作者,或者参见《“ML学分计划”说明书》

    5.初探数据

    先看看我们的数据,长什么样吧。在Data下我们train.csv和test.csv两个文件,分别存着官方给的训练和测试数据。

    import pandas as pd #数据分析
    import numpy as np #科学计算
    from pandas import Series,DataFrame
    
    data_train = pd.read_csv("/Users/Hanxiaoyang/Titanic_data/Train.csv")
    data_train
    

    pandas是常用的python数据处理包,把csv文件读入成dataframe各式,我们在ipython notebook中,看到data_train如下所示:

    训练数据

    这就是典型的dataframe格式,如果你没接触过这种格式,完全没有关系,你就把它想象成Excel里面的列好了。
    我们看到,总共有12列,其中Survived字段表示的是该乘客是否获救,其余都是乘客的个人信息,包括:

    • PassengerId => 乘客ID
    • Pclass => 乘客等级(1/2/3等舱位)
    • Name => 乘客姓名
    • Sex => 性别
    • Age => 年龄
    • SibSp => 堂兄弟/妹个数
    • Parch => 父母与小孩个数
    • Ticket => 船票信息
    • Fare => 票价
    • Cabin => 客舱
    • Embarked => 登船港口

    逐条往下看,要看完这么多条,眼睛都有一种要瞎的赶脚。好吧,我们让dataframe自己告诉我们一些信息,如下所示:

    data_train.info()
    

    看到了如下的信息:
    数据信息

    上面的数据说啥了?它告诉我们,训练数据中总共有891名乘客,但是很不幸,我们有些属性的数据不全,比如说:

    • Age(年龄)属性只有714名乘客有记录
    • Cabin(客舱)更是只有204名乘客是已知的

    似乎信息略少啊,想再瞄一眼具体数据数值情况呢?恩,我们用下列的方法,得到数值型数据的一些分布(因为有些属性,比如姓名,是文本型;而另外一些属性,比如登船港口,是类目型。这些我们用下面的函数是看不到的):

    数值型数据基本信息

    我们从上面看到更进一步的什么信息呢?
    mean字段告诉我们,大概0.383838的人最后获救了,2/3等舱的人数比1等舱要多,平均乘客年龄大概是29.7岁(计算这个时候会略掉无记录的)等等…

    6.数据初步分析

    每个乘客都这么多属性,那我们咋知道哪些属性更有用,而又应该怎么用它们啊?说实话这会儿我也不知道,但我们记得前面提到过

    • 『对数据的认识太重要了!』
    • 『对数据的认识太重要了!』
    • 『对数据的认识太重要了!』

    重要的事情说三遍,恩,说完了。仅仅最上面的对数据了解,依旧无法给我们提供想法和思路。我们再深入一点来看看我们的数据,看看每个/多个 属性和最后的Survived之间有着什么样的关系呢。

    6.1 乘客各属性分布

    脑容量太有限了…数值看花眼了。我们还是统计统计,画些图来看看属性和结果之间的关系好了,代码如下:

    import matplotlib.pyplot as plt
    fig = plt.figure()
    fig.set(alpha=0.2)  # 设定图表颜色alpha参数
    
    plt.subplot2grid((2,3),(0,0))             # 在一张大图里分列几个小图
    data_train.Survived.value_counts().plot(kind='bar')# 柱状图 
    plt.title(u"获救情况 (1为获救)") # 标题
    plt.ylabel(u"人数")  
    
    plt.subplot2grid((2,3),(0,1))
    data_train.Pclass.value_counts().plot(kind="bar")
    plt.ylabel(u"人数")
    plt.title(u"乘客等级分布")
    
    plt.subplot2grid((2,3),(0,2))
    plt.scatter(data_train.Survived, data_train.Age)
    plt.ylabel(u"年龄")                         # 设定纵坐标名称
    plt.grid(b=True, which='major', axis='y') 
    plt.title(u"按年龄看获救分布 (1为获救)")
    
    
    plt.subplot2grid((2,3),(1,0), colspan=2)
    data_train.Age[data_train.Pclass == 1].plot(kind='kde')   
    data_train.Age[data_train.Pclass == 2].plot(kind='kde')
    data_train.Age[data_train.Pclass == 3].plot(kind='kde')
    plt.xlabel(u"年龄")# plots an axis lable
    plt.ylabel(u"密度") 
    plt.title(u"各等级的乘客年龄分布")
    plt.legend((u'头等舱', u'2等舱',u'3等舱'),loc='best') # sets our legend for our graph.
    
    
    plt.subplot2grid((2,3),(1,2))
    data_train.Embarked.value_counts().plot(kind='bar')
    plt.title(u"各登船口岸上船人数")
    plt.ylabel(u"人数")  
    plt.show()
    

    数据基本信息图示

    bingo,图还是比数字好看多了。所以我们在图上可以看出来,被救的人300多点,不到半数;3等舱乘客灰常多;遇难和获救的人年龄似乎跨度都很广;3个不同的舱年龄总体趋势似乎也一致,2/3等舱乘客20岁多点的人最多,1等舱40岁左右的最多(→_→似乎符合财富和年龄的分配哈,咳咳,别理我,我瞎扯的);登船港口人数按照S、C、Q递减,而且S远多于另外俩港口。

    这个时候我们可能会有一些想法了:

    • 不同舱位/乘客等级可能和财富/地位有关系,最后获救概率可能会不一样
    • 年龄对获救概率也一定是有影响的,毕竟前面说了,副船长还说『小孩和女士先走』呢
    • 和登船港口是不是有关系呢?也许登船港口不同,人的出身地位不同?

    口说无凭,空想无益。老老实实再来统计统计,看看这些属性值的统计分布吧。

    6.2 属性与获救结果的关联统计

    #看看各乘客等级的获救情况
    fig = plt.figure()
    fig.set(alpha=0.2)  # 设定图表颜色alpha参数
    
    Survived_0 = data_train.Pclass[data_train.Survived == 0].value_counts()
    Survived_1 = data_train.Pclass[data_train.Survived == 1].value_counts()
    df=pd.DataFrame({u'获救':Survived_1, u'未获救':Survived_0})
    df.plot(kind='bar', stacked=True)
    plt.title(u"各乘客等级的获救情况")
    plt.xlabel(u"乘客等级") 
    plt.ylabel(u"人数") 
    plt.show()
    

    各乘客等级的获救情况

    啧啧,果然,钱和地位对舱位有影响,进而对获救的可能性也有影响啊←_←
    咳咳,跑题了,我想说的是,明显等级为1的乘客,获救的概率高很多。恩,这个一定是影响最后获救结果的一个特征。

    #看看各性别的获救情况
    fig = plt.figure()
    fig.set(alpha=0.2)  # 设定图表颜色alpha参数
    
    Survived_m = data_train.Survived[data_train.Sex == 'male'].value_counts()
    Survived_f = data_train.Survived[data_train.Sex == 'female'].value_counts()
    df=pd.DataFrame({u'男性':Survived_m, u'女性':Survived_f})
    df.plot(kind='bar', stacked=True)
    plt.title(u"按性别看获救情况")
    plt.xlabel(u"性别") 
    plt.ylabel(u"人数")
    plt.show()
    

    各乘客等级的获救情况

    歪果盆友果然很尊重lady,lady first践行得不错。性别无疑也要作为重要特征加入最后的模型之中。

    再来个详细版的好了。

    
     #然后我们再来看看各种舱级别情况下各性别的获救情况
    fig=plt.figure()
    fig.set(alpha=0.65) # 设置图像透明度,无所谓
    plt.title(u"根据舱等级和性别的获救情况")
    
    ax1=fig.add_subplot(141)
    data_train.Survived[data_train.Sex == 'female'][data_train.Pclass != 3].value_counts().plot(kind='bar', label="female highclass", color='#FA2479')
    ax1.set_xticklabels([u"获救", u"未获救"], rotation=0)
    ax1.legend([u"女性/高级舱"], loc='best')
    
    ax2=fig.add_subplot(142, sharey=ax1)
    data_train.Survived[data_train.Sex == 'female'][data_train.Pclass == 3].value_counts().plot(kind='bar', label='female, low class', color='pink')
    ax2.set_xticklabels([u"未获救", u"获救"], rotation=0)
    plt.legend([u"女性/低级舱"], loc='best')
    
    ax3=fig.add_subplot(143, sharey=ax1)
    data_train.Survived[data_train.Sex == 'male'][data_train.Pclass != 3].value_counts().plot(kind='bar', label='male, high class',color='lightblue')
    ax3.set_xticklabels([u"未获救", u"获救"], rotation=0)
    plt.legend([u"男性/高级舱"], loc='best')
    
    ax4=fig.add_subplot(144, sharey=ax1)
    data_train.Survived[data_train.Sex == 'male'][data_train.Pclass == 3].value_counts().plot(kind='bar', label='male low class', color='steelblue')
    ax4.set_xticklabels([u"未获救", u"获救"], rotation=0)
    plt.legend([u"男性/低级舱"], loc='best')
    
    plt.show()
    
    

    各性别和舱位的获救情况

    恩,坚定了之前的判断。

    我们看看各登船港口的获救情况。

    fig = plt.figure()
    fig.set(alpha=0.2)  # 设定图表颜色alpha参数
    
    Survived_0 = data_train.Embarked[data_train.Survived == 0].value_counts()
    Survived_1 = data_train.Embarked[data_train.Survived == 1].value_counts()
    df=pd.DataFrame({u'获救':Survived_1, u'未获救':Survived_0})
    df.plot(kind='bar', stacked=True)
    plt.title(u"各登录港口乘客的获救情况")
    plt.xlabel(u"登录港口") 
    plt.ylabel(u"人数") 
    
    plt.show()
    

    各登船港口的获救情况

    下面我们来看看 堂兄弟/妹,孩子/父母有几人,对是否获救的影响。

    
    g = data_train.groupby(['SibSp','Survived'])
    df = pd.DataFrame(g.count()['PassengerId'])
    print df
    
    g = data_train.groupby(['SibSp','Survived'])
    df = pd.DataFrame(g.count()['PassengerId'])
    print df
    
    

    堂兄弟/妹影响

    父母/孩子影响

    好吧,没看出特别特别明显的规律(为自己的智商感到捉急…),先作为备选特征,放一放。

    
    #ticket是船票编号,应该是unique的,和最后的结果没有太大的关系,先不纳入考虑的特征范畴把
    #cabin只有204个乘客有值,我们先看看它的一个分布
    data_train.Cabin.value_counts()
    
    

    部分结果如下:
    Cabin分布

    这三三两两的…如此不集中…我们猜一下,也许,前面的ABCDE是指的甲板位置、然后编号是房间号?…好吧,我瞎说的,别当真…

    关键是Cabin这鬼属性,应该算作类目型的,本来缺失值就多,还如此不集中,注定是个棘手货…第一感觉,这玩意儿如果直接按照类目特征处理的话,太散了,估计每个因子化后的特征都拿不到什么权重。加上有那么多缺失值,要不我们先把Cabin缺失与否作为条件(虽然这部分信息缺失可能并非未登记,maybe只是丢失了而已,所以这样做未必妥当),先在有无Cabin信息这个粗粒度上看看Survived的情况好了。

    
    fig = plt.figure()
    fig.set(alpha=0.2)  # 设定图表颜色alpha参数
    
    Survived_cabin = data_train.Survived[pd.notnull(data_train.Cabin)].value_counts()
    Survived_nocabin = data_train.Survived[pd.isnull(data_train.Cabin)].value_counts()
    df=pd.DataFrame({u'有':Survived_cabin, u'无':Survived_nocabin}).transpose()
    df.plot(kind='bar', stacked=True)
    plt.title(u"按Cabin有无看获救情况")
    plt.xlabel(u"Cabin有无") 
    plt.ylabel(u"人数")
    plt.show()
    
    

    有无Cabin记录影响

    咳咳,有Cabin记录的似乎获救概率稍高一些,先这么着放一放吧。

    7.简单数据预处理

    大体数据的情况看了一遍,对感兴趣的属性也有个大概的了解了。
    下一步干啥?咱们该处理处理这些数据,为机器学习建模做点准备了。

    对了,我这里说的数据预处理,其实就包括了很多Kaggler津津乐道的feature engineering过程,灰常灰常有必要!

    『特征工程(feature engineering)太重要了!』
    『特征工程(feature engineering)太重要了!』
    『特征工程(feature engineering)太重要了!』

    恩,重要的事情说三遍。

    先从最突出的数据属性开始吧,对,Cabin和Age,有丢失数据实在是对下一步工作影响太大。

    先说Cabin,暂时我们就按照刚才说的,按Cabin有无数据,将这个属性处理成Yes和No两种类型吧。

    再说Age:

    通常遇到缺值的情况,我们会有几种常见的处理方式

    • 如果缺值的样本占总数比例极高,我们可能就直接舍弃了,作为特征加入的话,可能反倒带入noise,影响最后的结果了
    • 如果缺值的样本适中,而该属性非连续值特征属性(比如说类目属性),那就把NaN作为一个新类别,加到类别特征中
    • 如果缺值的样本适中,而该属性为连续值特征属性,有时候我们会考虑给定一个step(比如这里的age,我们可以考虑每隔2/3岁为一个步长),然后把它离散化,之后把NaN作为一个type加到属性类目中。
    • 有些情况下,缺失的值个数并不是特别多,那我们也可以试着根据已有的值,拟合一下数据,补充上。

    本例中,后两种处理方式应该都是可行的,我们先试试拟合补全吧(虽然说没有特别多的背景可供我们拟合,这不一定是一个多么好的选择)

    我们这里用scikit-learn中的RandomForest来拟合一下缺失的年龄数据(注:RandomForest是一个用在原始数据中做不同采样,建立多颗DecisionTree,再进行average等等来降低过拟合现象,提高结果的机器学习算法,我们之后会介绍到)

    
    from sklearn.ensemble import RandomForestRegressor
     
    ### 使用 RandomForestClassifier 填补缺失的年龄属性
    def set_missing_ages(df):
        
        # 把已有的数值型特征取出来丢进Random Forest Regressor中
        age_df = df[['Age','Fare', 'Parch', 'SibSp', 'Pclass']]
    
        # 乘客分成已知年龄和未知年龄两部分
        known_age = age_df[age_df.Age.notnull()].as_matrix()
        unknown_age = age_df[age_df.Age.isnull()].as_matrix()
    
        # y即目标年龄
        y = known_age[:, 0]
    
        # X即特征属性值
        X = known_age[:, 1:]
    
        # fit到RandomForestRegressor之中
        rfr = RandomForestRegressor(random_state=0, n_estimators=2000, n_jobs=-1)
        rfr.fit(X, y)
        
        # 用得到的模型进行未知年龄结果预测
        predictedAges = rfr.predict(unknown_age[:, 1::])
        
        # 用得到的预测结果填补原缺失数据
        df.loc[ (df.Age.isnull()), 'Age' ] = predictedAges 
        
        return df, rfr
    
    def set_Cabin_type(df):
        df.loc[ (df.Cabin.notnull()), 'Cabin' ] = "Yes"
        df.loc[ (df.Cabin.isnull()), 'Cabin' ] = "No"
        return df
    
    data_train, rfr = set_missing_ages(data_train)
    data_train = set_Cabin_type(data_train)
    
    

    处理Cabin和Age之后

    恩。目的达到,OK了。

    因为逻辑回归建模时,需要输入的特征都是数值型特征,我们通常会先对类目型的特征因子化。
    什么叫做因子化呢?举个例子:

    以Cabin为例,原本一个属性维度,因为其取值可以是[‘yes’,‘no’],而将其平展开为’Cabin_yes’,'Cabin_no’两个属性

    • 原本Cabin取值为yes的,在此处的"Cabin_yes"下取值为1,在"Cabin_no"下取值为0
    • 原本Cabin取值为no的,在此处的"Cabin_yes"下取值为0,在"Cabin_no"下取值为1

    我们使用pandas的"get_dummies"来完成这个工作,并拼接在原来的"data_train"之上,如下所示。

    
    dummies_Cabin = pd.get_dummies(data_train['Cabin'], prefix= 'Cabin')
    
    dummies_Embarked = pd.get_dummies(data_train['Embarked'], prefix= 'Embarked')
    
    dummies_Sex = pd.get_dummies(data_train['Sex'], prefix= 'Sex')
    
    dummies_Pclass = pd.get_dummies(data_train['Pclass'], prefix= 'Pclass')
    
    df = pd.concat([data_train, dummies_Cabin, dummies_Embarked, dummies_Sex, dummies_Pclass], axis=1)
    df.drop(['Pclass', 'Name', 'Sex', 'Ticket', 'Cabin', 'Embarked'], axis=1, inplace=True)
    df
    
    

    离散/因子化之后

    bingo,我们很成功地把这些类目属性全都转成0,1的数值属性了。

    这样,看起来,是不是我们需要的属性值都有了,且它们都是数值型属性呢。

    有一种临近结果的宠宠欲动感吧,莫急莫急,我们还得做一些处理,仔细看看Age和Fare两个属性,乘客的数值幅度变化,也忒大了吧!!如果大家了解逻辑回归与梯度下降的话,会知道,各属性值之间scale差距太大,将对收敛速度造成几万点伤害值!甚至不收敛! (╬▔皿▔)…所以我们先用scikit-learn里面的preprocessing模块对这俩货做一个scaling,所谓scaling,其实就是将一些变化幅度较大的特征化到[-1,1]之内。

    import sklearn.preprocessing as preprocessing
    scaler = preprocessing.StandardScaler()
    age_scale_param = scaler.fit(df['Age'])
    df['Age_scaled'] = scaler.fit_transform(df['Age'], age_scale_param)
    fare_scale_param = scaler.fit(df['Fare'])
    df['Fare_scaled'] = scaler.fit_transform(df['Fare'], fare_scale_param)
    df
    

    scaling

    恩,好看多了,万事俱备,只欠建模。马上就要看到成效了,哈哈。我们把需要的属性值抽出来,转成scikit-learn里面LogisticRegression可以处理的格式。

    8.逻辑回归建模

    我们把需要的feature字段取出来,转成numpy格式,使用scikit-learn中的LogisticRegression建模。

    from sklearn import linear_model
    
    # 用正则取出我们要的属性值
    train_df = df.filter(regex='Survived|Age_.*|SibSp|Parch|Fare_.*|Cabin_.*|Embarked_.*|Sex_.*|Pclass_.*')
    train_np = train_df.as_matrix()
    
    # y即Survival结果
    y = train_np[:, 0]
    
    # X即特征属性值
    X = train_np[:, 1:]
    
    # fit到RandomForestRegressor之中
    clf = linear_model.LogisticRegression(C=1.0, penalty='l1', tol=1e-6)
    clf.fit(X, y)
        
    clf
    

    good,很顺利,我们得到了一个model,如下:
    modeling

    先淡定!淡定!你以为把test.csv直接丢进model里就能拿到结果啊…骚年,图样图森破啊!我们的"test_data"也要做和"train_data"一样的预处理啊!!

    
    data_test = pd.read_csv("/Users/Hanxiaoyang/Titanic_data/test.csv")
    data_test.loc[ (data_test.Fare.isnull()), 'Fare' ] = 0
    # 接着我们对test_data做和train_data中一致的特征变换
    # 首先用同样的RandomForestRegressor模型填上丢失的年龄
    tmp_df = data_test[['Age','Fare', 'Parch', 'SibSp', 'Pclass']]
    null_age = tmp_df[data_test.Age.isnull()].as_matrix()
    # 根据特征属性X预测年龄并补上
    X = null_age[:, 1:]
    predictedAges = rfr.predict(X)
    data_test.loc[ (data_test.Age.isnull()), 'Age' ] = predictedAges
    
    data_test = set_Cabin_type(data_test)
    dummies_Cabin = pd.get_dummies(data_test['Cabin'], prefix= 'Cabin')
    dummies_Embarked = pd.get_dummies(data_test['Embarked'], prefix= 'Embarked')
    dummies_Sex = pd.get_dummies(data_test['Sex'], prefix= 'Sex')
    dummies_Pclass = pd.get_dummies(data_test['Pclass'], prefix= 'Pclass')
    
    
    df_test = pd.concat([data_test, dummies_Cabin, dummies_Embarked, dummies_Sex, dummies_Pclass], axis=1)
    df_test.drop(['Pclass', 'Name', 'Sex', 'Ticket', 'Cabin', 'Embarked'], axis=1, inplace=True)
    df_test['Age_scaled'] = scaler.fit_transform(df_test['Age'], age_scale_param)
    df_test['Fare_scaled'] = scaler.fit_transform(df_test['Fare'], fare_scale_param)
    df_test
    
    

    modeling

    不错不错,数据很OK,差最后一步了。
    下面就做预测取结果吧!!

    test = df_test.filter(regex='Age_.*|SibSp|Parch|Fare_.*|Cabin_.*|Embarked_.*|Sex_.*|Pclass_.*')
    predictions = clf.predict(test)
    result = pd.DataFrame({'PassengerId':data_test['PassengerId'].as_matrix(), 'Survived':predictions.astype(np.int32)})
    result.to_csv("/Users/Hanxiaoyang/Titanic_data/logistic_regression_predictions.csv", index=False)
    

    预测结果

    啧啧,挺好,格式正确,去make a submission啦啦啦!

    在Kaggle的Make a submission页面,提交上结果。如下:
    Kaggle排名

    0.76555,恩,结果还不错。毕竟,这只是我们简单分析处理过后出的一个baseline模型嘛。

    9.逻辑回归系统优化

    9.1 模型系数关联分析

    亲,你以为结果提交上了,就完事了?
    我不会告诉你,这只是万里长征第一步啊(泪牛满面)!!!这才刚撸完baseline model啊!!!还得优化啊!!!

    看过Andrew Ng老师的machine Learning课程的同学们,知道,我们应该分析分析模型现在的状态了,是过/欠拟合?,以确定我们需要更多的特征还是更多数据,或者其他操作。我们有一条很著名的learning curves对吧。

    不过在现在的场景下,先不着急做这个事情,我们这个baseline系统还有些粗糙,先再挖掘挖掘。

    • 首先,Name和Ticket两个属性被我们完整舍弃了(好吧,其实是因为这俩属性,几乎每一条记录都是一个完全不同的值,我们并没有找到很直接的处理方式)。

    • 然后,我们想想,年龄的拟合本身也未必是一件非常靠谱的事情,我们依据其余属性,其实并不能很好地拟合预测出未知的年龄。再一个,以我们的日常经验,小盆友和老人可能得到的照顾会多一些,这样看的话,年龄作为一个连续值,给一个固定的系数,应该和年龄是一个正相关或者负相关,似乎体现不出两头受照顾的实际情况,所以,说不定我们把年龄离散化,按区段分作类别属性会更合适一些。

    上面只是我瞎想的,who knows是不是这么回事呢,老老实实先把得到的model系数和feature关联起来看看。

    pd.DataFrame({"columns":list(train_df.columns)[1:], "coef":list(clf.coef_.T)})
    

    LR模型系数

    首先,大家回去前两篇文章里瞄一眼公式就知道,这些系数为正的特征,和最后结果是一个正相关,反之为负相关。

    我们先看看那些权重绝对值非常大的feature,在我们的模型上:

    • Sex属性,如果是female会极大提高最后获救的概率,而male会很大程度拉低这个概率。
    • Pclass属性,1等舱乘客最后获救的概率会上升,而乘客等级为3会极大地拉低这个概率。
    • 有Cabin值会很大程度拉升最后获救概率(这里似乎能看到了一点端倪,事实上从最上面的有无Cabin记录的Survived分布图上看出,即使有Cabin记录的乘客也有一部分遇难了,估计这个属性上我们挖掘还不够)
    • Age是一个负相关,意味着在我们的模型里,年龄越小,越有获救的优先权(还得回原数据看看这个是否合理
    • 有一个登船港口S会很大程度拉低获救的概率,另外俩港口压根就没啥作用(这个实际上非常奇怪,因为我们从之前的统计图上并没有看到S港口的获救率非常低,所以也许可以考虑把登船港口这个feature去掉试试)。
    • 船票Fare有小幅度的正相关(并不意味着这个feature作用不大,有可能是我们细化的程度还不够,举个例子,说不定我们得对它离散化,再分至各个乘客等级上?)

    噢啦,观察完了,我们现在有一些想法了,但是怎么样才知道,哪些优化的方法是promising的呢?

    因为test.csv里面并没有Survived这个字段(好吧,这是废话,这明明就是我们要预测的结果),我们无法在这份数据上评定我们算法在该场景下的效果…

    而『每做一次调整就make a submission,然后根据结果来判定这次调整的好坏』其实是行不通的…

    9.2 交叉验证

    重点又来了:

    『要做交叉验证(cross validation)!』
    『要做交叉验证(cross validation)!』
    『要做交叉验证(cross validation)!』

    恩,重要的事情说三遍。我们通常情况下,这么做cross validation:把train.csv分成两部分,一部分用于训练我们需要的模型,另外一部分数据上看我们预测算法的效果。

    我们用scikit-learn的cross_validation来帮我们完成小数据集上的这个工作。

    先简单看看cross validation情况下的打分

    from sklearn import cross_validation
    
     #简单看看打分情况
    clf = linear_model.LogisticRegression(C=1.0, penalty='l1', tol=1e-6)
    all_data = df.filter(regex='Survived|Age_.*|SibSp|Parch|Fare_.*|Cabin_.*|Embarked_.*|Sex_.*|Pclass_.*')
    X = all_data.as_matrix()[:,1:]
    y = all_data.as_matrix()[:,0]
    print cross_validation.cross_val_score(clf, X, y, cv=5)
    

    结果是下面酱紫的:
    [0.81564246 0.81005587 0.78651685 0.78651685 0.81355932]

    似乎比Kaggle上的结果略高哈,毕竟用的是不是同一份数据集评估的。

    等等,既然我们要做交叉验证,那我们干脆先把交叉验证里面的bad case拿出来看看,看看人眼审核,是否能发现什么蛛丝马迹,是我们忽略了哪些信息,使得这些乘客被判定错了。再把bad case上得到的想法和前头系数分析的合在一起,然后逐个试试。

    下面我们做数据分割,并且在原始数据集上瞄一眼bad case:

    # 分割数据,按照 训练数据:cv数据 = 7:3的比例
    split_train, split_cv = cross_validation.train_test_split(df, test_size=0.3, random_state=0)
    train_df = split_train.filter(regex='Survived|Age_.*|SibSp|Parch|Fare_.*|Cabin_.*|Embarked_.*|Sex_.*|Pclass_.*')
    # 生成模型
    clf = linear_model.LogisticRegression(C=1.0, penalty='l1', tol=1e-6)
    clf.fit(train_df.as_matrix()[:,1:], train_df.as_matrix()[:,0])
    
    # 对cross validation数据进行预测
    
    cv_df = split_cv.filter(regex='Survived|Age_.*|SibSp|Parch|Fare_.*|Cabin_.*|Embarked_.*|Sex_.*|Pclass_.*')
    predictions = clf.predict(cv_df.as_matrix()[:,1:])
    
    origin_data_train = pd.read_csv("/Users/HanXiaoyang/Titanic_data/Train.csv")
    bad_cases = origin_data_train.loc[origin_data_train['PassengerId'].isin(split_cv[predictions != cv_df.as_matrix()[:,0]]['PassengerId'].values)]
    bad_cases
    

    我们判定错误的 bad case 中部分数据如下:
    预测错误的原始数据

    大家可以自己跑一遍试试,拿到bad cases之后,仔细看看。也会有一些猜测和想法。其中会有一部分可能会印证在系数分析部分的猜测,那这些优化的想法优先级可以放高一些。

    现在有了"train_df" 和 “vc_df” 两个数据部分,前者用于训练model,后者用于评定和选择模型。可以开始可劲折腾了。

    我们随便列一些可能可以做的优化操作:

    • Age属性不使用现在的拟合方式,而是根据名称中的『Mr』『Mrs』『Miss』等的平均值进行填充。
    • Age不做成一个连续值属性,而是使用一个步长进行离散化,变成离散的类目feature。
    • Cabin再细化一些,对于有记录的Cabin属性,我们将其分为前面的字母部分(我猜是位置和船层之类的信息) 和 后面的数字部分(应该是房间号,有意思的事情是,如果你仔细看看原始数据,你会发现,这个值大的情况下,似乎获救的可能性高一些)。
    • Pclass和Sex俩太重要了,我们试着用它们去组出一个组合属性来试试,这也是另外一种程度的细化。
    • 单加一个Child字段,Age<=12的,设为1,其余为0(你去看看数据,确实小盆友优先程度很高啊)
    • 如果名字里面有『Mrs』,而Parch>1的,我们猜测她可能是一个母亲,应该获救的概率也会提高,因此可以多加一个Mother字段,此种情况下设为1,其余情况下设为0
    • 登船港口可以考虑先去掉试试(Q和C本来就没权重,S有点诡异)
    • 把堂兄弟/兄妹 和 Parch 还有自己 个数加在一起组一个Family_size字段(考虑到大家族可能对最后的结果有影响)
    • Name是一个我们一直没有触碰的属性,我们可以做一些简单的处理,比如说男性中带某些字眼的(‘Capt’, ‘Don’, ‘Major’, ‘Sir’)可以统一到一个Title,女性也一样。

    大家接着往下挖掘,可能还可以想到更多可以细挖的部分。我这里先列这些了,然后我们可以使用手头上的"train_df"和"cv_df"开始试验这些feature engineering的tricks是否有效了。

    试验的过程比较漫长,也需要有耐心,而且我们经常会面临很尴尬的状况,就是我们灵光一闪,想到一个feature,然后坚信它一定有效,结果试验下来,效果还不如试验之前的结果。恩,需要坚持和耐心,以及不断的挖掘。

    我最好的结果是在『Survived~C(Pclass)+C(Title)+C(Sex)+C(Age_bucket)+C(Cabin_num_bucket)Mother+Fare+Family_Size』下取得的,结果如下(抱歉,博主君commit的时候手抖把页面关了,于是没截着图,下面这张图是在我得到最高分之后,用这次的结果重新make commission的,截了个图,得分是0.79426,不是目前我的最高分哈,因此排名木有变…):

    做完feature engineering调整之后的结果

    9.3 learning curves

    有一个很可能发生的问题是,我们不断地做feature engineering,产生的特征越来越多,用这些特征去训练模型,会对我们的训练集拟合得越来越好,同时也可能在逐步丧失泛化能力,从而在待预测的数据上,表现不佳,也就是发生过拟合问题。

    从另一个角度上说,如果模型在待预测的数据上表现不佳,除掉上面说的过拟合问题,也有可能是欠拟合问题,也就是说在训练集上,其实拟合的也不是那么好。

    额,这个欠拟合和过拟合怎么解释呢。这么说吧:

    • 过拟合就像是你班那个学数学比较刻板的同学,老师讲过的题目,一字不漏全记下来了,于是老师再出一样的题目,分分钟精确出结果。but数学考试,因为总是碰到新题目,所以成绩不咋地。
    • 欠拟合就像是,咳咳,和博主level差不多的差生。连老师讲的练习题也记不住,于是连老师出一样题目复习的周测都做不好,考试更是可想而知了。

    而在机器学习的问题上,对于过拟合欠拟合两种情形。我们优化的方式是不同的。

    对过拟合而言,通常以下策略对结果优化是有用的:

    • 做一下feature selection,挑出较好的feature的subset来做training
    • 提供更多的数据,从而弥补原始数据的bias问题,学习到的model也会更准确

    而对于欠拟合而言,我们通常需要更多的feature,更复杂的模型来提高准确度。

    著名的learning curve可以帮我们判定我们的模型现在所处的状态。我们以样本数为横坐标,训练和交叉验证集上的错误率作为纵坐标,两种状态分别如下两张图所示:过拟合(overfitting/high variace),欠拟合(underfitting/high bias)

    过拟合

    欠拟合

    我们也可以把错误率替换成准确率(得分),得到另一种形式的learning curve(sklearn 里面是这么做的)。

    回到我们的问题,我们用scikit-learn里面的learning_curve来帮我们分辨我们模型的状态。举个例子,这里我们一起画一下我们最先得到的baseline model的learning curve。

    import numpy as np
    import matplotlib.pyplot as plt
    from sklearn.learning_curve import learning_curve
    
    # 用sklearn的learning_curve得到training_score和cv_score,使用matplotlib画出learning curve
    def plot_learning_curve(estimator, title, X, y, ylim=None, cv=None, n_jobs=1, 
                            train_sizes=np.linspace(.05, 1., 20), verbose=0, plot=True):
        """
        画出data在某模型上的learning curve.
        参数解释
        ----------
        estimator : 你用的分类器。
        title : 表格的标题。
        X : 输入的feature,numpy类型
        y : 输入的target vector
        ylim : tuple格式的(ymin, ymax), 设定图像中纵坐标的最低点和最高点
        cv : 做cross-validation的时候,数据分成的份数,其中一份作为cv集,其余n-1份作为training(默认为3份)
        n_jobs : 并行的的任务数(默认1)
        """
        train_sizes, train_scores, test_scores = learning_curve(
            estimator, X, y, cv=cv, n_jobs=n_jobs, train_sizes=train_sizes, verbose=verbose)
        
        train_scores_mean = np.mean(train_scores, axis=1)
        train_scores_std = np.std(train_scores, axis=1)
        test_scores_mean = np.mean(test_scores, axis=1)
        test_scores_std = np.std(test_scores, axis=1)
        
        if plot:
            plt.figure()
            plt.title(title)
            if ylim is not None:
                plt.ylim(*ylim)
            plt.xlabel(u"训练样本数")
            plt.ylabel(u"得分")
            plt.gca().invert_yaxis()
            plt.grid()
        
            plt.fill_between(train_sizes, train_scores_mean - train_scores_std, train_scores_mean + train_scores_std, 
                             alpha=0.1, color="b")
            plt.fill_between(train_sizes, test_scores_mean - test_scores_std, test_scores_mean + test_scores_std, 
                             alpha=0.1, color="r")
            plt.plot(train_sizes, train_scores_mean, 'o-', color="b", label=u"训练集上得分")
            plt.plot(train_sizes, test_scores_mean, 'o-', color="r", label=u"交叉验证集上得分")
        
            plt.legend(loc="best")
            
            plt.draw()
            plt.show()
            plt.gca().invert_yaxis()
        
        midpoint = ((train_scores_mean[-1] + train_scores_std[-1]) + (test_scores_mean[-1] - test_scores_std[-1])) / 2
        diff = (train_scores_mean[-1] + train_scores_std[-1]) - (test_scores_mean[-1] - test_scores_std[-1])
        return midpoint, diff
    
    plot_learning_curve(clf, u"学习曲线", X, y)
    

    学习曲线

    在实际数据上看,我们得到的learning curve没有理论推导的那么光滑哈,但是可以大致看出来,训练集和交叉验证集上的得分曲线走势还是符合预期的。

    目前的曲线看来,我们的model并不处于overfitting的状态(overfitting的表现一般是训练集上得分高,而交叉验证集上要低很多,中间的gap比较大)。因此我们可以再做些feature engineering的工作,添加一些新产出的特征或者组合特征到模型中。

    10.模型融合(model ensemble)

    好了,终于到这一步了,我们要祭出机器学习/数据挖掘上通常最后会用到的大杀器了。恩,模型融合。

    『强迫症患者』打算继续喊喊口号…
    『模型融合(model ensemble)很重要!』
    『模型融合(model ensemble)很重要!』
    『模型融合(model ensemble)很重要!』
    重要的事情说三遍,恩,噢啦。

    先解释解释,一会儿再回到我们的问题上哈。
    啥叫模型融合呢,我们还是举几个例子直观理解一下好了。

    大家都看过知识问答的综艺节目中,求助现场观众时候,让观众投票,最高的答案作为自己的答案的形式吧,每个人都有一个判定结果,最后我们相信答案在大多数人手里。

    再通俗一点举个例子。你和你班某数学大神关系好,每次作业都『模仿』他的,于是绝大多数情况下,他做对了,你也对了。突然某一天大神脑子犯糊涂,手一抖,写错了一个数,于是…恩,你也只能跟着错了。
    我们再来看看另外一个场景,你和你班5个数学大神关系都很好,每次都把他们作业拿过来,对比一下,再『自己做』,那你想想,如果哪天某大神犯糊涂了,写错了,but另外四个写对了啊,那你肯定相信另外4人的是正确答案吧?

    最简单的模型融合大概就是这么个意思,比如分类问题,当我们手头上有一堆在同一份数据集上训练得到的分类器(比如logistic regression,SVM,KNN,random forest,神经网络),那我们让他们都分别去做判定,然后对结果做投票统计,取票数最多的结果为最后结果

    bingo,问题就这么完美的解决了。

    模型融合可以比较好地缓解,训练过程中产生的过拟合问题,从而对于结果的准确度提升有一定的帮助。

    话说回来,回到我们现在的问题。你看,我们现在只讲了logistic regression,如果我们还想用这个融合思想去提高我们的结果,我们该怎么做呢?

    既然这个时候模型没得选,那咱们就在数据上动动手脚咯。大家想想,如果模型出现过拟合现在,一定是在我们的训练上出现拟合过度造成的对吧。

    那我们干脆就不要用全部的训练集,每次取训练集的一个subset,做训练,这样,我们虽然用的是同一个机器学习算法,但是得到的模型却是不一样的;同时,因为我们没有任何一份子数据集是全的,因此即使出现过拟合,也是在子训练集上出现过拟合,而不是全体数据上,这样做一个融合,可能对最后的结果有一定的帮助。对,这就是常用的Bagging。

    我们用scikit-learn里面的Bagging来完成上面的思路,过程非常简单。代码如下:

    from sklearn.ensemble import BaggingRegressor
    
    train_df = df.filter(regex='Survived|Age_.*|SibSp|Parch|Fare_.*|Cabin_.*|Embarked_.*|Sex_.*|Pclass.*|Mother|Child|Family|Title')
    train_np = train_df.as_matrix()
    
    # y即Survival结果
    y = train_np[:, 0]
    
    # X即特征属性值
    X = train_np[:, 1:]
    
    # fit到BaggingRegressor之中
    clf = linear_model.LogisticRegression(C=1.0, penalty='l1', tol=1e-6)
    bagging_clf = BaggingRegressor(clf, n_estimators=20, max_samples=0.8, max_features=1.0, bootstrap=True, bootstrap_features=False, n_jobs=-1)
    bagging_clf.fit(X, y)
    
    test = df_test.filter(regex='Age_.*|SibSp|Parch|Fare_.*|Cabin_.*|Embarked_.*|Sex_.*|Pclass.*|Mother|Child|Family|Title')
    predictions = bagging_clf.predict(test)
    result = pd.DataFrame({'PassengerId':data_test['PassengerId'].as_matrix(), 'Survived':predictions.astype(np.int32)})
    result.to_csv("/Users/HanXiaoyang/Titanic_data/logistic_regression_bagging_predictions.csv", index=False)
    

    然后你再Make a submission,恩,发现对结果还是有帮助的。

    ensemble之后的结果

    11.总结

    文章稍微有点长,非常感谢各位耐心看到这里。
    总结的部分,我就简短写几段,出现的话,很多在文中有对应的场景,大家有兴趣再回头看看。

    对于任何的机器学习问题,不要一上来就追求尽善尽美,先用自己会的算法撸一个baseline的model出来,再进行后续的分析步骤,一步步提高

    在问题的结果过程中:

    • 『对数据的认识太重要了!』
    • 『数据中的特殊点/离群点的分析和处理太重要了!』
    • 『特征工程(feature engineering)太重要了!』
    • 『模型融合(model ensemble)太重要了!』

    本文中用机器学习解决问题的过程大概如下图所示:
    机器学习解决问题的过程

    12.关于数据和代码

    本文中的数据和代码已经上传至github中,欢迎大家下载和自己尝试。

    展开全文
  • 6.for i in range(2,n):if n%i==0:breakif i==n-1:print('是素数')...8.对于有else子句的for循环和while循环,但循环因循环条件不成立而自然结束时__会__(会或不会)执行else的代码。10.已知x='hello world.',那...

    6.for i in range(2,n):

    if n%i==0:break

    if i==n-1:

    print('是素数')

    else:

    print('不是素数')

    7.'abcabcabc'.count('abc')的值为__3__。

    8.对于有else子句的for循环和while循环,但循环因循环条件不成立而自然结束时__会__(会或不会)执行else中的代码。

    10.已知x='hello world.',那么表达式x.find('x')和x.rfind('x')的值都为__-1__。

    12.print("{:#>4d}".format(23))的输出结果是__##23__。

    13.以下哪个选项不是Python中的合法名称(2_g):_ag,a_g,ag_,2_g

    14.以下哪个选项是python中的合法名称(num_1):2num,num-1,num_1,num 1

    15.print(3+5)语句的运行结果是(8)

    16.print(2**4+16%3)  __17__

    17.以下程序的输出结果是__0__。

    a=8

    a%=2

    print(a)

    18.print("**"*3)的输出结果是(******)。

    19.表达式True and False的值为:__False__。

    20.以下程序的输出结果是(7)

    x=371

    print(x%100//10)

    21.a,b=1,2则a的值为__1__。

    22.在循环语句中,__continue___语句的作用是提前结束本层循环。

    23.表达式"abc10'.isalnum()的值为__True__。

    24.表达式True*3的值为 __3__。

    25.表达式'c:\windows\notepad.exe'.endswith('.exe')的值为__True__。

    26.表达式'test.py'.endswith('.py')的值为__True__。

    27.表达式 int('123')的值为__123__。

    28.表达式 'Beautifule is better than ugly.'.startswith('Be',5)的值为__False__。

    29.假设a,b=10,50,则条件表达式a>10 and b<100的值为__False_____。

    30.python3.x语句 for i in range(3):print(i,end=',')的输出结果为__0,1,2,__。

    31.程序的基本结构:__顺序结构、选择结构和循环结构__。

    32.在python语言内置的random库中,哪个函数功能是从序列s中随即选择一个元素(A):A、choice(s),B、randint(m,n),C、shuffle(s),D、uniform(m,n)

    33.以下程序的输出结果(3

    5)

    print(3,end="")

    print()

    print(5)

    34.表达式int(False)的值为:__0__。

    35.以下程序的输出结果是(-3)

    a=-8

    a//=3

    print(a)

    36.print(15%4)的输出结果是(3)

    37.有python语句:

    for s in "abced":

    print(s,end=' ')

    的运行结果是(a b c d e)。

    38.print("{:&>8}".format("python"))的输出结果是($$python)

    39.有python语句:

    for i in range(100,999+1):

    a=i//100

    b=i//10%10

    c=i%10

    if a**3 + b**3 + c**3 == i:

    print(i,end="  ")

    的运行结果是(153  370  371  407)。

    40.下列Python语句:

    x,y=30,70

    min = x if x

    print(min)

    的运行结果是(30)。

    41.表达式'abc' in ('abcdefg')的值为__True__。

    42.已知x,y=3,5,那么执行x,y=y,x之后,x的值为__5__。

    43.表达式'aaasdf'.strip('a')的值为__'sdf'__。

    44.已知x=3,那么执行语句 x += 6之后,x的值为__9__。

    45.python用于表示逻辑与运算的关键字是__and__。

    46.表达式 int(4**0.5)的值为__2__。

    47.表达式len('aaaassddf'.strip('afds'))的值为__0__。

    48.在循环语句中,__continue__语句的作用是提前进入下一次循环。

    49.Python标准库random中的__choice()__方法作用是从序列中随机选择1个元素。

    50.已知x=3,那么执行语句 x*=6之后,x的值为__18__。

    51.以下程序的输出结果是(9630)。

    s="0123456789"

    print(s[::-3])

    52.在python语句中,条件表达式中判断相等用的关系运算符是(==)。

    53.表达式 chr(ord('A')+2)的值为__'C'__。

    54.表达式 sum(range(10))的值为__45__。

    55.x=-9

    print(x) if x>=0 else print(-x)

    的输出结果为__9__。

    56.python的内置函数__len()__可以返回列表、元组、字典、集合、字符串以及range对象中元素个数。

    57.表达式'apple.peach,banana,pear'.find('p')的值为__1__。

    58.表达式 len('SDIBT')的值为__5__。

    59.表达式':'.join('hello world.'.split())的值为__'hello:world.'__。

    60.python语句''.join(list('hello world!'))执行的结果是__'hello world!'__。

    61.表达式 3 or 5 的值为__3__。

    62.表达式 16**0.5的值为 __4.0__。

    63.有关for循环和while循环的退出(有两种方式:一是循环条件不成立或循环序列遍历结束,二是在循环过程中遇到break语句)。

    64.分支结构的类型:单分支、双分支、多分支和嵌套if结构。

    65.关于多分支结构if-elif-else语句的说法正确的是:最多只会执行一个分支。

    66.表达式not (True and False)的值为(True)。

    67.s.islower()方法是用来:判断字符串s中的字母是否全为小写。

    68.以下程序的输出结果为(bird-fish-monkey-rabbit)

    s=['bird','fish','monkey','rabbit']

    print("-".join(s))

    69.python语言的运行方式有__交互__式和文件式两种。

    70.表达式'a'+'b'的值为 __'ab'__。

    71.表达式'Hello world'.lower()的值为__'hello world'__。

    72.表达式 1234%1000//100的值为__2__。

    73.表达式'abc10'.isdigit()的值为__False__。

    74.表达式 'hello world, hellow every one'.replace('hello','hi')的值为__'hi world, hiw every one'__。

    75.表达式 5 if 5>6 else (6 if 3>2 else 5)的值为__6__。

    76.表达式 len(range(1,10))的值为__9__。

    77.表达式 'abcab'.replace('a','yy')的值为__'yybcyyb'__。

    78.Python标准库math中用来计算平方根的函数是__sqrt()__。

    79.以下程序的输出结果是(('bird,fish,monkey,rabbit,tiger,','monkey','')):

    s='bird,fish,monkey,rabbit,tiger,monkey'

    print(s.rpartition("monkey"))

    80.int(2<3)的值为__0__。

    81.gcd(27,42)的值为__3__。

    82.python语言的提示符是__>>>__。

    83.表达式':'.join('1,2,3,4,5'.split(','))的值为__'1:2:3:4:5'__。

    84.eval()函数可以将__字符串__解析成数值。

    85.表达式min(['11','2','3'])的值为__'11'__。

    86.print("{:=<8}".format("python"))的输出结果是__python==__。

    87.print(str(3+5))的输出结果是__8__。

    88.Python语言的主要应用领域是(人工智能,网络爬虫,数据分析与处理)

    89.判断三条线段a,b,c能否构成三角形的条件表达式,正确的是__(a>0)and(b>0)and(c>0)and(a+b>c)and(a+c>b)and(b+c>a)__。

    90.语句a,b=b,a的功能是__交换a和b的值__。

    91.下列Python语句:

    k=16

    while k>1:

    k=k/2

    print(k)

    的运行结果是__1.0__。

    92.在Python语句内置的random库中,哪个函数的功能是生成一个[m,n]之间的随机小数:__uniform(m,n)__。

    93.表达式'aaaassddf'.strip('af')的值为__'ssdd'__。

    94.Python语句中的当行注释语句以符号__#__作为开始。

    95.Python运算符中用来计算整商的是__//__。

    96.表达式True*3的值为 __3__。

    97.表达式 len('Hello world!'.ljust(20))的值为__20__。

    98.表达式'a'.join('abc',partition('a'))的值为__'aaabc'__。

    二、判断题

    1.s[1:5]可以去除字符串s中从索引值1开始到5结束的子字符串。(F)

    2.Python是一种跨平台、开源、免费的高级动态编程语言。(T)

    3.判断整数x是否偶数的条件表达式为x%2=0。(F)

    4.判断整数x是否偶数的条件表达式为x%2==0。(T)

    5.带有else子句的循环如果因为执行了break语句而退出的话,则会执行else子句中的代码。(F)

    6.print(1+'2')的输出结果是'3'。(F)

    7.编写多层循环时,为了提高运行效率,应尽量减少内循环中不必要的计算。(T)

    8.print(s[0,5,-1])输出的是字符串s左起6个字符的反向字符串。(F)

    9.python使用缩进来体现代码之间的逻辑关系。(T)

    10.在python的循环体内,continue语句的作用是结束该语句所在的循环。(F)

    11.如果仅仅是用于控制循环次数,那么使用for i in range(20)和 for i in range(20,40)的作用是等价的。(T)

    12.在python的循环体内,continue语句的作用是结束这一轮的循环,程序跳转到循环头部。(T)

    13.s[::-1]的功能是对字符串s反向取整串。(T)

    14.python变量名区分大小写,所以student和Student不是同一个变量。(T)

    15.python不允许使用关键字作为变量名,允许使用内置函数作为变量名,但这会改变函数名的含义。(T)

    16.放在一对三引号之间的任何内容将被认为是注释。(F)

    17.print(8,end="")的功能是输出8以后不换行。(T)

    18.a,b,c=10,20语句执行完以后,变量c的值为0。(F)

    19.如果需要连接大量字符串成为一个字符串,那么使用字符串对象的join()方法比运算符+具有更高的效率。(T)

    20.python标准库random的方法randint(m,n)用来生成一个[m,n]区间上的随机整数。(T)

    21.ord("c")-ord("a")的值为2。(T)

    22.Python运算符%不仅可以用来求余数,还可以用来格式化字符串。(T)

    23.a**=b等价于a=a**b。(T)

    24.s.replace(" ","")的功能是在字符串s尾部添加空格。(F)

    25.a=b=10语句执行完以后,变量a和b的值都是10。(T)

    26.在循环中continue语句的作用是跳出当前循环。(F)

    27.表达式 'a'+1的值为'b'。(F)

    28.Python语句只有一种运行方式——文件式。(F)

    29.加法运算符可以用来连接字符串并生成新字符串。(T)

    30.range(m,n)得到的迭代序列为:m,m+1,m+2,m+3,...,n-1。(T)

    31.在python中0xad是合法的十六进制数字表示形式。(T)

    32.当作为条件表达式时,空值、空字符串、空列表、空元组、空字典、空集合、空迭代对象以及任意形式的数字0都等价于False。(T)

    33.已知x=3,那么赋值语句x='abcedfg'是无法正常执行的。(F)

    34.在python中,变量不直接存储值,而是存储值的引用,也就是值在内存中的地址。(T)

    35.在random模块的函数randint(1,100)获取随机数时,有可能会得到100。(T)

    36.在python中可以使用for作为变量名。(F)

    37.Python代码的注释只有一种方式,那就是使用#符号。(F)

    38.random库中的函数random()返回左闭右开区间[0.0,0.1)中的一个随机浮点数。(T)

    39.在python的循环体内,break语句的作用是结束该语句所在的循环。(T)

    40.在python中,关系运算符可以连续使用,例如00并且a

    41."ABC">"ab"结果为False。(T)

    42.带有else子句的循环如果因为执行了break语句而退出的话,则会执行else子句的代码。(F)

    43.在python3.0中可以使用中文作为变量名。(T)

    44.Python中一切内容都可以称为对象。(T)

    45.Python语言的标示符只能以字母开头,后面可以跟字母、数字、下划线。(F)

    46.程序中异常处理结构在大多数情况下是没必要的。(F)

    三、编程题

    '''

    使用循环方法求解百钱买百鸡问题。假设公鸡5元一只,母鸡3元一只,小鸡1元三只,

    现有100元钱想买100只鸡,编程计算买鸡的方案,有多少种买法?

    '''

    for a in range(0,21):

    for b in range(0,34):

    for c in range(0,101):

    if a+b+c==100 and a*5+b*3+c/3==100:

    print(a,b,c)

    #韩信点兵

    for i in range(1000,1101):

    if i%3==2 and i%5==4 and i%7==6:

    print(i)

    #打印九九乘法表

    for i in range(1,10):

    for j in range(1,i+1):

    print("{}*{}={:2d}".format(i,j,i*j),end=" ")

    print()

    #从键盘输入任意一个正整数,编程计算该数的阶乘 如:输入5,阶乘结果120 。

    x=eval(input("请输入一个正整数"))

    t=1

    for i in range(1,x+1):

    t=t*i

    print(t)

    #编程分别计算100以内(含100)奇数与偶数的和。

    s1,s2=0,0

    for i in range(1,101):

    if i%2==1:

    s1=s1+i

    else:

    s2=s2+i

    print(s1,s2)

    #编程计算前30项的和:s=1+(1+2)+(1+2+3)+(1+2+3+4)+…+(1+2+3+4+…+n)

    s,y=0,0

    for i in range(1,31):

    s=s+i

    y=y+s

    print(y)

    #编程产生菲波拉契数列20项,例如:0  1   1  2  3   5   8   13    21    ……

    x1=0

    x2=1

    print(x1,end=" ")

    print(x2,end=" ")

    for i in range(1,18+1):

    x3=x1+x2

    print(x3,end=" ")

    x1=x2

    x2=x3

    #一小球从100米高度自由落下,每次落地后反跳回原高度的一半;再落下,求它在 第10次落地时,共经过多少米?第10次反弹多高?

    h=100

    s=0

    for i in range(1,11):

    s=s+h

    h=h/2

    s=s+h

    print(s-h,h)

    '''

    猴子第一天摘了若干个桃子,当天吃了一半,还不过隐,有多吃了一个,第二天早上又将剩下的桃子吃了一半,又多吃了一个,以后每天早上都吃了前一天剩下的一半零一个,到第10天早上想再吃时,见只剩下一个桃子,问第一天共摘了多少个桃子

    '''

    x=1

    for i in range(1,10):

    x=(x+1)*2

    print(x)

    #商场购物

    x=eval(input("x="))

    if x<1000:

    y=x

    elif x<2000:

    y=0.9*x

    elif x<3000:

    y=0.8*x

    else:

    y=0.7*x

    print(y)

    #分段函数1

    import math

    x=eval(input("x="))

    if x>5:

    y=math.sin(x)+(x**2+1)**0.5

    elif x>0:

    y=math.e**x+math.log(x,5)+x**(1/5)

    else:

    y=math.cos(x)-x**3+3*x

    print(y)

    #分段函数2

    x=eval(input("x="))

    if x<0:

    y=0

    elif x<5:

    y=x

    elif x<10:

    y=3*x-5

    elif x<20:

    y=0.5*x-2

    else:

    y=0

    print(y)

    #判断素数

    x=eval(input("x="))

    for i in range(2,x):

    if x%i==0:

    print("不是素数")

    break

    else:

    print("是素数")

    '''

    一个富翁试图与陌生人做一笔换钱生意,换钱规则为:陌生人每天给富翁10万元钱,直到满一个月(30天);而富翁第一天给陌生人1分钱,第2天给2分钱,第3天给4分钱,…,富翁每天给穷人的钱是前一天的两倍,直到满一个月,分别显示富翁给陌生人的钱和陌生人给富翁的钱各是多少?

    '''

    s1,s2=0,0

    x=0.01

    for i in range(1,31):

    s1=s1+100000

    s2=s2+x

    x=2*x

    print(s1,s2)

    #判断闰年

    x = eval(input('请输入一个年份'))

    if x%400==0 or (x%4==0 and not x%100==0):

    print('是闰年')

    else:

    print('不是闰年')

    四五章选择判断填空编程

    一、选择题

    1.下列表达式值为False的是:______。2 in {1:2,3:4}

    2.下列代码执行的正确结果为(.[1,4,9]

    lnum=[]

    for i in range(1,4)

    lnum.append(i**2)

    print(lnum)

    3. 执行语句x={},x的类型是:______.字典

    4.已知 x = {1:2, 2:3},那么表达式 x.get(3, 4) 的值为__.4

    5.列表guests=["萧峰","杨过","令狐冲","张无忌","郭靖"],下列删除"张无忌"的方法,哪种是错误的?(guests.remove[3]

    6. 下列元组定义正确的是(.tupScores=(“萧峰”,)

    7. 有关pop()方法的说法,正确的是:_____集合的pop()方法是从集合中随机删除一个元素

    8.已知s={1,2,3,4},以下操作执行会报错的是:___s.remove(5)

    9.下列集合运算的运算符,求交集的是:___.&

    10.以下哪种不是字典的遍历方式:___按"元素"遍历

    11.列表guests=[“萧峰”,”杨过”,”令狐冲”,”张无忌”,”郭靖”],下列哪种方法能够在”令狐冲”前插入”张三丰”?(guests.insert(2, ”张三丰”)

    12.假设d1,d2是两个字典,执行操作d1.update(d2)后,下列说法正确的是: d1的内容被更新,d2不变

    13.courses="计算机,数学",执行代码courses1=list(courses)后,courses1的值为()。

    .['计','算','机', ' , ', '数','学']

    14.下列关于列表与元组的说法正确的是( )。列表的元素能修改

    15.列表guests=["萧峰","杨过","令狐冲","张无忌","郭靖"],下列删除"张无忌"的方法,哪种是错误的?( )guests.remove[3]

    15.字典对象的________方法以"(键,值)"的形式返回字典中的所有条目的列表。.items()

    16下列代码执行结果为( )?.[6, 6, 6, 6, 6, 6, 6, 6, 6, 6]

    ls=[6]*10

    print(ls)

    17. 下列代码执行的正确结果为(.[1,4,9]

    )。

    lnum=[i**2 for i in range(1,4)]

    print(lnum)

    18. 下列有关字典条目的说法,错误的是:__字典中的值必须是不可变类型

    19. group=[("张三丰",95),("杨过",94)],下列操作不正确的是(group[1][0]="虚竹"将'杨过'修改为'虚竹'。)。

    20. score = eval(input("请输入3个学生的分数列表 "))

    maxScore = max(score)

    minScore = min(score)

    aveScore = sum(score)/len(score)

    print(maxScore,minScore,aveScore))

    如输入分数为[94,96,95],代码执行的正确结果为(96 94 95

    21. 列表guests=[”令狐冲”,”张无忌”,”郭靖”],ls=[“98”,”97”,”99”],guests+ls执行结果正确的是(.["令狐冲’,’张无忌’,’郭靖’, "98’,’97’,’99’]

    22.。下列列表定义错误的是(names=[萧峰,96,令狐冲]

    23. 表达式sorted({4:2,3:1,5:6})的值为___.[3,4,5]

    24. 下列代码执行的正确结果为(.[1,4,9]

    )。

    lnum=[]

    for i in range(1,4)

    lnum.append(i**2)

    print(lnum)

    25. 执行语句x={},x的类型是:____.字典

    26.已知 x = {1:2, 2:3},那么表达式 x.get(3, 4) 的值为___4

    27.列表guests=["萧峰","杨过","令狐冲","张无忌","郭靖"],下列删除"张无忌"的方法,哪种是错误的?(guests.remove[3]

    28. 下列元组定义正确的是(tupScores=(“萧峰”,)

    29. 有关pop()方法的说法,正确的是:____集合的pop()方法是从集合中随机删除一个元素

    s={1,2}

    s.add({2,3})

    print(s)

    31. guests=["李秋水","郭襄","赵敏"],彻底从内存中删除guests的方法是(del guests

    32.列表guests=["张三丰","萧峰","杨过","令狐冲","张无忌"],下列表达式用来判断指定的元素是否在列表中,下列描述正确的是?(."杨" not in guests,返回True。

    33. 列表courses=[”法律”,“管理”,”计算机”,”数学”],列表切片结果错误的是(courses[0:3:-2]切片结果为["法律’,’计算机’]。

    34. 执行下列代码的结果为:报错

    s={1,2}

    s.add({2,3})

    print(s)

    35.下列集合运算的运算符,求并集的是:___.|

    36. 下列哪种方法能够生成一份列表courses的备份?(courses.copy()

    37. 已知x={'a':2,'b':4},以下操作会报错的是:___x.pop('c')

    38. 以下说法正确的是:___集合可以作为字典的值

    39. 关于列表复制,下列说法错误的是(利用列表赋值实现复制会生成列表的备份。

    40. 执行下列代码的结果为:.{1:4,2:5,3:6}

    l1=[1,2,3]

    l2=[4,5,6]

    d={}

    for j in range(3):

    d[l1[i]]=l2[i

    41.已知x = {1:2, 2:3},那么表达式x.get(3, 4)的值为__4

    42.列表guests=["萧峰","杨过","令狐冲","张无忌","郭靖"],下列删除"张无忌"的方法,哪种是错误的?(guests.remove[3]

    43. 列表guests=["张三丰","萧峰","杨过","令狐冲","张无忌"],下列表达式用来判断指定的元素是否在列表中,下列描述正确的是?(."杨" not in guests,返回True。

    44. 下列关于列表与元组的说法不正确的是(列表的元素不能修改

    45. 按照指定的键访问字典中对应条目的值应采用的方法是:get()

    46,下列从输入设备获取数值列表的方法正确的是(lnum=eval(input(“请输入数值列表: ”))

    47. 字典对象的____keys()

    ____方法返回字典中的"键"的列表。

    48下列哪个函数可以将range()函数生成的数值对象转换成数值列表?(list()

    49. 以下创建集合的操作错误的是:____s={}

    50.已知x={1:2,3:4},以下选项返回False的是:_2 in x

    51. 以下哪种不是字典的遍历方式:__按"元素"遍历

    二、判断题

    1、del命令和pop命令删除列表元素的方式相同。F

    2、字典和集合属于无序序列。T

    3、Python字典中的“键”可以是列表。F

    4、使用del命令或者列表对象的remove()方法删除列表中元素时会影响列表中部分元素的索引。T

    5、可以使用del删除集合中的部分元素。F

    6、假设x为列表对象,那么x.pop()和x.pop(-1)的作用是一样的。T

    7、元组可以作为字典的“键”。T

    8、已知列表x中包含超过5个以上的元素,那么语句 x = x[:5]+x[5:] 的作用是将列表x中的元素循环左移5位。F

    9、字典中的值不允许重复。F

    10、Python字典中的“键”可以是元组。T

    11、字典可以通过索引访问所存储的条目。F

    12、Python集合可以包含相同的元素。F

    13、访问字典是通过键访问条目的值。T

    14、已知x = list(range(20)),那么语句print(x[100:200])无法正常执行。F

    15、Python集合中的元素可以是列表。F

    16、元组是不可变的,不支持列表对象的insert()、remove()等方法,也不支持del命令删除其中的元素,但可以使用del命令删除整个元组对象。T

    17、元组也是用来存放一组相关的数据,所以元组与列表相同。F

    18、集合中的元素不允许重复。T

    19、在Python 3.5中运算符+不仅可以实现数值的相加、字符串连接,还可以实现列表、元组的合并和集合的并集运算。F

    20、列表可以作为字典的“键”。F

    21、Python支持使用字典的“键”作为下标来访问字典中的值。T

    22、字典的“键”必须是不可变的。T

    23、Python集合中的元素可以是元组。T

    24、语句s1={}创建了一个空集合。F

    25、对于数字n>2,如果表达式 0 not in [n%d for d in range(2, n)] 的值为True则说明n是素数。T

    26、已知x = (1, 2, 3, 4),那么执行x[0] = 5之后,x的值为(5, 2, 3, 4)。F

    27、Python字典和集合属于无序序列。T

    28、同一个列表对象中所有元素必须为相同类型。F

    29、已知x = {1:1, 2:2},那么语句x[3] =3无法正常执行。F

    30、假设x是含有5个元素的列表,那么切片操作x[10:]是无法执行的,会抛出异常。F

    31、列表scores=[98,96,95,94,92],scores[::1]与scores[::-1]返回列表的值相等。F

    32、只能对列表进行切片操作,不能对元组和字符串进行切片操作。F

    33、Python列表、元组、字符串都属于有序序列。T

    34、列表的长度是列表中元素的个数减1。F

    35、字典中的键必须是不可变的类型,比如字符串、元祖或者列表。F

    36、字典的键一旦被加入到字典中,除非随着条目一起被删除,否则都是始终保持不变的。T

    37、已知x = {1:1, 2:2},那么语句x[3] =3无法正常执行F

    38、只能通过切片访问列表中的元素,不能使用切片修改列表中的元素。F

    39、在Python中元组的值是不可变的,因此,已知x = ([1], [2]),那么语句x[0].append(3)是无法正常执行的。F

    40、运算符“-”可以用于集合的差集运算。T

    41、删除列表中重复元素最简单的方法是将其转换为集合后再重新转换为列表。T

    42、遍历列表用for和range()函数配合可以减少代码的重复度。T

    43、已知x = list(range(20)),那么语句del x[::2]可以正常执行。T

    44、字典的“键”必须是不可变的。T

    45、无法删除集合中指定位置的元素,只能删除指定值的元素。T

    46、列表对象的pop()方法默认删除并返回最后一个元素,如果列表已空则抛出异常。T

    47、Python集合不支持使用下标访问其中的元素。T

    48、删除列表中重复元素最简单的方法是将其转换为集合后再重新转换为列表。T

    49、遍历列表用for和range()函数配合可以减少代码的重复度。T

    50、字典和集合都支持双向索引。F

    51、del命令和pop命令删除列表元素的方式相同。F

    52、字典和集合属于无序序列。T

    53、Python支持使用字典的“键”作为下标来访问字典中的值。T

    54、字典可以通过索引访问所存储的条目。F

    55、Python集合可以包含相同的元素。F

    56、已知x = list(range(20)),那么语句print(x[100:200])无法正常执行。F

    57、元组是不可变的,不支持列表对象的insert()、remove()等方法,也不支持del命令删除其中的元素,但可以使用del命令删除整个元组对象。T

    58、元组也是用来存放一组相关的数据,所以元组与列表相同。F

    59、集合中的元素不允许重复。T

    60、在Python 3.5中运算符+不仅可以实现数值的相加、字符串连接,还可以实现列表、元组的合并和集合的并集运算。F

    61、Python支持使用字典的“键”作为下标来访问字典中的值。T

    62、对于数字n>2,如果表达式0 not in [n%d for d in range(2, n)]的值为True则说明n是素数。T

    63、同一个列表对象中所有元素必须为相同类型。F

    64、假设x是含有5个元素的列表,那么切片操作x[10:]是无法执行的,会抛出异常。F

    65、del命令和pop命令删除列表元素的方式相同。F

    66、使用del命令或者列表对象的remove()方法删除列表中元素时会影响列表中部分元素的索引。I

    67、可以使用del删除集合中的部分元素。F

    68、假设x为列表对象,那么x.pop()和x.pop(-1)的作用是一样的。T

    69、字典中的值不允许重复。F

    70、Python字典中的“键”可以是元组。T

    71、使用列表对象的remove()方法可以删除列表中首次出现的指定元素,如果列表中不存在要删除的指定元素则抛出异常。T

    72、使用Python列表的方法insert()为列表插入元素时会改变列表中插入位置之后元素的索引。T

    73、使用pop()方法删除字典的指定键对应的条目时,如果缺省指定键参数,则随机删除一个条目。F

    74、表达式 list('[1, 2, 3]') 的值是[1, 2, 3]。F

    75、利用append()方法只能在列表尾部追加新的元素。T

    76、列表切片缺省“起始索引”时,切片默认从索引1元素开始。F

    77、已知x是个列表对象,那么执行语句y = x之后,对y增加一个元素的操作都会同样作用到x上。T

    78、采用copy()方法与列表之间赋值实现复制的过程相同。F

    79、无法删除集合中指定位置的元素,只能删除特定值的元素。T

    三、填空题

    1.已知列表对象x = ['11', '2', '3'],则表达式 max(x) 的值为_____'3'______。

    2.已知列表 x = [1, 2, 3],那么执行语句 x.pop(0) 之后,x的值为__[2,3]____

    3.已知 x = [3, 5, 7],那么执行语句 x[:3] = [2]之后,x的值为_______[2]_________。

    4.列表guests=[“萧峰”,”杨过”,”令狐冲”,”张无忌”,”郭靖”],删除”杨过”的方法是guests._____ remove______(”杨过”)。

    5.表达式 {1, 2, 3} | {3, 4, 5} 的值为_________{1,2,3,4,5}____________。

    6.表达式 (1,) + (2,) 的值为______(1,2)_______。

    7.表达式 {1, 2, 3} & {3, 4, 5} 的值为______{3}________。

    8.已知列表 x = [1, 2],那么连续执行命令 y = x[:] 和 y.append(3) 之后,x的值为___[1,2]_____。

    9.表达式 [1,2,3].count(4) 的值为________0_______。

    10.已知 x = (3,),那么表达式 x * 3 的值为________(3,3,3)_____。

    11.guests=[“赵敏”,”任盈盈”,”袁紫衣”],复制guests并生成备份的方法是guests.______copy____( )。

    12.列表、元组、字符串是Python的_____有序____(有序或无序)序列。

    13.guests=[“赵敏”,”任盈盈”,”袁紫衣”],执行guests___*__2的返回结果为["赵敏’,’任盈盈’,’袁紫衣’,"赵敏’,’任盈盈’,’袁紫衣’]。

    14.已知 x = {1:2},那么执行语句 x[2] = 3之后,x的值为_______{1:2,2:3}_________。

    15.已知x = [1, 2, 3],那么连续执行y = [1, 2, 3]和y.append(4)这两条语句之后,x的值为_________[1,2,3]___________。

    16.已知 x = [1, 2, 3, 2, 3],执行语句 x.remove(2) 之后,x的值为_____[1,3,2,3]_______。

    17.字典对象的______clear()_____方法可以一次性清空字典中所有条目。

    18.已知 x = [3, 5, 7],那么执行语句 x[len(x):] = [1, 2]之后,x的值为______[3,5,7,1,2]________。

    19.已知 x = [1, 2, 3, 2, 3],执行语句 x.pop() 之后,x的值为_______[1,2,3,2]______。

    20.列表group=[("郭靖",99),("杨过",98)],则group[0][1]=__99___。

    21.表达式 [1, 2] * 2 的值为________[1,2,1,2]______。

    22.已知 x = [3, 7, 5],那么执行语句 x.sort(reverse=True)之后,x的值为______[7,5,3]___________。

    23.表达式 set([1,2,3]) == {1, 2, 3} 的值为_____True_______。

    24.表达式type({3})的值为_________set___________。

    25.执行下列语句:

    x={1:1,2:2}

    x[1]=3

    print(len(x))

    显示结果为:2

    26.表达式 {1, 2, 3} - {3, 4, 5}的值为____{1,2}_______。

    27.表达式 sum(range(1, 10, 2)) 的值为_____25_______。

    28.列表courses=[”法律”,“管理”,”计算机”,”数学”],执行下列代码能对courses列表的元素降序排序,并改变原列表的顺序,courses._____sort____(reverse=False)。

    29.字典对象的______keys______方法返回字典的"键"列表。

    30.表达式sorted({'a':3, 'b':9, 'c':78}.values())的值为_____[3,9,78]________。

    31.表达式[1,2]*3的执行结果为_________[1,2,1,2,1,2]_____________。

    32.表达式 list(range(50, 60, 3)) 的值为________[50,53,56,59]_______________。

    33.表达式 len([i for i in range(10)]) 的值为______10____。

    34.已知列表 x = [1, 2, 3],那么执行语句 x.insert(1, 4)之后 ,x的值为_____[1,4,2,3]______。

    35.已知列表 x = list(range(10)),那么执行语句 del x[::2]之后,x的值为____[1,3,5,7,9]_____。

    36.已知 x = (3), 那么表达式 x * 3 的值为_____9_____。

    37.列表guests=[”a”,“b”,”cd”,”e”],表达式“d” in guests,返回结果为____False____。

    38.表达式 [1, 2] + [3] 的值为_________[1,2,3]_________。

    39.表达式 str([1, 2, 3]) 的值为__________'[1,2,3]'________。

    40.表达式type({}) == set的值为________False_______。

    41.已知列表 x = list(range(5)),那么执行语句 x.remove(3) 之后,表达式 x.index(4) 的值为____3____。

    42.已知列表 x = [1, 2],那么执行语句 x.append([3]) 之后,x的值为_____[1,2,[3]]________。

    43.已知列表 x = [1, 2, 3],那么执行语句 x.insert(1, 4)之后 ,x的值为____[1,4,2,3]_______。

    44.已知 x = [1, 2, 3, 4, 5],那么执行语句 del x[1:3] 之后,x的值为______[1,4,5]______。

    45.已知列表 x = [1, 2],那么执行语句 x.extend([3]) 之后, x的值为_____[1,2,3]_______。

    46.已知 x = [1, 2, 3, 2, 3],执行语句 x.remove(2) 之后,x的值为____[1,3,2,3]________。

    47.已知 x = {1:2, 2:3, 3:4},那么表达式 sum(x.keys()) 的值为____6_______。

    48.表达式sorted({3:'a',8:'b',5:'c'}.values())的值为:___ ['a','b','c']_____。

    49.已知 x = {1, 2, 3},那么执行语句 x.add(3) 之后,x的值为___{1,2,3}_______。

    50.guests=["令狐冲","张无忌","郭靖"],ls=["李秋水","郭襄","赵敏"],将guests列表的值修改为['令狐冲', '张无忌', '郭靖', '李秋水', '郭襄', '赵敏']的方法是guests.____ extend______(ls)。

    51.字典对象的________get___方法可以获取指定“键”对应的“值”,如果指定的键在字典中不存在,则返回默认值。

    52.清空列表guests=["赵敏","任盈盈","袁紫衣"]的命令是____del____guests[:]。

    53.已知 x = {'a':'b', 'c':'d'},那么表达式 'b' in x.values() 的值为_____True_________。

    54.执行下列语句:

    x={1:1,2:2}

    x[3]=1

    print(len(x))

    显示结果为:3

    55.已知x = ([1], [2]),那么执行语句x[0].append(3)后x的值为________([1,3],[2])________。

    56.执行下列代码可以创建数值列表:lnum=____list____(range(1,9))。

    57.已知 x = {'a':'b', 'c':'d'},那么表达式 'b' in x 的值为___False___。

    58.表达式sorted({3:'a',8:'b',5:'c'})的值为:___ [3,5,8]_____。

    59.已知x为非空且元素无序的列表,那么表达式 x.sort() == sorted(x) 的值为____False______。

    60.表达式[3] in [1, 2, 3, 4]的值为______False__________。

    61.表达式sorted({3:'a',8:'b',5:'c'})的值为:___ [3,5,8]_____。

    62.表达式 {1, 2, 3} ^ {3, 4, 5} 的值为___{1,2,4,5}________。

    63.表达式 list(range(5)) 的值为______[0,1,2,3,4]__________。

    64.已知 x = {'a':'b', 'c':'d'},那么表达式 'a' in x 的值为______True________。

    65.列表courses=[”Falv”,“Guanli”,”Jisuanji”,”Shuxue”,”Lishi”,’Dili’],courses[1:5:__2__]切片结果为[“Guanli”,”Shuxue”]。

    66.执行下列语句:

    67.x={1:1,2:2}

    x[3]=1

    print(len(x))

    显示结果为:3

    68.清空列表guests=["赵敏","任盈盈","袁紫衣"]的命令是____del____guests[:]。

    69.已知列表 x = [1, 2, 3],那么执行语句 x.insert(0, 4) 只有,x的值为_____[4,1,2,3]______。

    70.已知列表 x = [1, 2, 3],那么执行语句 x.pop(0) 之后,x的值为____[2,3]_____。

    71.已知 x = [3, 5, 7],那么表达式 x[10:]的值为______[]______。

    72.表达式type({}) == set的值为_______False________。

    73.已知 x = [1, 2],那么执行语句 x[0:1] = [3, 3]之后,x的值为_____[3,3,2]______。

    74.已知x = list(range(20)),那么表达式x[-1]的值为________19____________。

    75.______del________命令既可以删除列表中的一个元素,也可以删除整个列表。

    76.表达式 type(3.0) in (int, float, complex) 的值为______True______。

    77.表达式 3 not in [1, 2, 3]的值为____False______。

    78.表达式 3 in {1, 2, 3} 的值为_____True____。

    79.表达式 len(range(1, 10)) 的值为_____9______。

    字典对象的_______values_______方法返回字典的“值”列表。

    三、编程题

    '''

    编写一个程序,接受逗号分隔的单词序列作为输入,按字母顺序排序后按逗号分隔的序列打印单词。假设向程序提供以下输入:

    without,hello,bag,world

    则输出为:

    bag,hello,without,world

    '''

    x=input("x=")

    l=x.split(",")

    l.sort()

    print(",".join(l))

    '''

    编写一个程序来计算输入中单词的频率。 按字母顺序对键进行排序后输出。

    假设为程序提供了以下输入:

    New to Python or choosing between Python 2 and Python 3 Read Python 2 or Python 3

    然后,输出应该是:

    2:2

    3:2

    New:1

    Python:5

    Read:1

    and:1

    between:1

    choosing:1

    or:2

    to:1

    '''

    x=input("x=")

    l=x.split()

    d={}

    for i in l:

    d[i]=d.get(i,0)+1

    l2=sorted(d)

    for i in l2:

    print("{}:{}".format(i,d[i]))

    #依次输入三个整数放在一个列表中,请把这三个数由小到大输出。

    l=[]

    for i in range(3):

    x=int(input("x="))

    l.append(x)

    l.sort()

    for i in l:

    print(i,end=" ")

    '''

    使用列表生成式方法求解百钱买百鸡问题。

    假设大鸡5元一只,中鸡3元一只,小鸡1元三只,

    现有100元钱想买100只鸡,有多少种买法?

    '''

    l=[(i,j,k) for i in range(0,100) for j in range(0,100) for k in range(0,100) if i+j+k==100 and 5*i+3*j+k/3==100]

    for i in l:

    print(i)

    '''

    使用给定的整数n,编写一个程序生成一个包含(i, i*i)的字典,该字典包含1到n之间的整数(两者都包含)。然后程序应该打印字典。

    假设向程序提供以下输入:8

    则输出为:

    {1:1,2:4,3:9,4:16,5:25,6:36,,7:49,8:64}

    '''

    n=eval(input("n="))

    d={}

    for i in range(1,n+1):

    d[i]=i*i

    print(d)

    '''

    使用列表生成式随机产生10个两位的正整数,存入列表ls中,输出ls中的这10个随机数,

    然后对这10个随机数求平均值,并输出统计高于平均值的数有多少个。

    '''

    from random import *

    ls=[randint(10,99) for i in range(10)]

    print(ls)

    pj=sum(ls)/10

    n=0

    for i in ls:

    if i>pj:

    n=n+1

    print(n)

    #编写一个程序,输出2000到3200(含2000和3200)之间所有是7的倍数,但不是5的倍数的整数。要求:用列表保存符合条件的整数,输出结果各整数之间用逗号分隔,并输出在一行上。

    l=[]

    for i in range(2000,3201):

    if i%7==0 and i%5!=0:

    l.append(str(i))

    print(",".join(l))

    '''

    编写一个程序,接收一系列单个空格分隔的单词作为输入,在删除所有重复的单词并按字母升序排序后打印这些单词。

    假设向程序提供以下输入:

    hello world and practice makes perfect and hello world again

    则输出为:

    again and hello makes perfect practice world

    '''

    x=input("x=")

    l=x.split()

    s=set(l)

    l2=list(s)

    l2.sort()

    for i in l2:

    print(i,end=" ")

    '''

    编写一个接收句子并计算字母和数字的程序。假设为程序提供了以下输入:

    Hello world! 123

    然后,输出应该是:

    字母10

    数字3

    '''

    d={'字母':0,'数字':0}

    x=input("x=")

    for i in x:

    if i.isdigit():

    d['数字']=d['数字']+1

    elif i.isalpha():

    d['字母']=d['字母']+1

    for k,v in d.items():

    print("{} {}".format(k,v))

    '''

    使用列表生成式来求列表中的每个奇数。 该列表由一系列逗号分隔的数字输入。

    假设为程序提供了以下输入:

    [1,2,3,4,5,6,7,8,9]

    然后,输出应该是:

    [1,3,5,7,9]

    '''

    l=eval(input("l="))

    l2=[ i for i in l if i%2==1]

    print(l2)

    展开全文
  • 例如,您在进行C语言指针编程,能够读取指针变量本身值(&操作),实际上这个值就是逻辑地址,他是相对于您当前进程数据段的地址,不和绝对物理地址相干。只有在Intel实模式下,逻辑地址才和物理地址相等(因为实...
    逻辑地址(Logical 
    
    Address) 是指由程式产生的和段相关的偏移地址部分。例如,您在进行C语言 指针 编程中,能够读取指针变量本身值(&操作),实际上这个值就是逻辑地址,他是相对于您当前进程数据段的地址,不和绝对物理地址相干。 只有在Intel实模式下,逻辑地址才和物理地址相等(因为实模式没有分段或分页机制,Cpu不进行自动地址转换);逻辑也就是在Intel
    保护模式下程式执行代码段限长内的偏移地址(假定代码段、数据段假如完全相同)。应用程式员仅需和逻辑地址打交道,而分段和分页机制对您来说是完全透明
    的,仅由系统编程人员涉及。应用程式员虽然自己能够直接操作内存,那也只能在操作系统给您分配的内存段操作。
    线性地址(Linear
    Address) 是逻辑地址到物理地址变换之间的中间层。程式代码会产生逻辑地址,或说是段中的偏移地址,加上相应段的基地址就生成了一个线性地址。假如启用了分页机制,那么线性地址能够再经变换以产生一个物理地址。若没有启用分页机制,那么线性地址直接就是物理地址。Intel
    80386的线性地址空间容量为4G(2的32次方即32根地址总线寻址)。
    物理地址(Physical
    Address) 是指出现在CPU外部地址总线上的寻址物理内存的地址信号,是地址变换的最终结果地址。假如启用了分页机制,那么线性地址会使用页目录和页表中的项变换成物理地址。假如没有启用分页机制,那么线性地址就直接成为物理地址了。
    虚拟内存(Virtual
    Memory)
    是指电脑呈现出要比实际拥有的内存大得多的内存量。因此他允许程式员编制并运行比实际系统拥有的内存大得多的程式。这使得许多大型项目也能够在具备有限
    内存资源的系统上实现。一个很恰当的比喻是:您无需很长的轨道就能够让一列火车从上海开到北京。您只需要足够长的铁轨(比如说3公里)就能够完成这个任
    务。采取的方法是把后面的铁轨立即铺到火车的前面,只要您的操作足够快并能满足需要,列车就能象在一条完整的轨道上运行。这也就是虚拟内存管理需要完成的
    任务。在Linux
    0.11内核中,给每个程式(进程)都划分了总容量为64MB的虚拟内存空间。因此程式的逻辑地址范围是0x0000000到0x4000000。
    有时我们也把逻辑地址称为虚拟地址。因为和虚拟内存空间的概念类似,逻辑地址也是和实际物理内存容量无关的。
    逻辑地址和物理地址的“差距”是0xC0000000,是由于虚拟地址->线性地址->物理地址映射正好差这个值。这个值是由操作系统指定的。
    机理 逻辑地址(或称为虚拟地址)到线性地址是由CPU的段机制自动转换的。假如没有开启分页管理,则线性地址就是物理地址。假如开启了分页管理,那么系统程式需要参和线性地址到物理地址的转换过程。具体是通过配置页目录表和页表项进行的。
    展开全文
  • 一阶逻辑等值演算

    千次阅读 2015-04-22 22:11:47
    基本等值 第一组 代换实例 由于命题逻辑中的重言的代换实例都是一阶逻辑中的永真,因而第二章的16组等值给出的代换实例都是一阶逻辑的等值的模式。关于Discrete Mathematics更多讨论与交流,敬请关注本...

    主要内容


    1.等值式与基本的等值式
    ①在有限个体域中消去量词等值式
    ②量词否定等值式
    ③量词辖域收缩与扩张等值式
    ④量词分配等值式 
    2.基本规则
    ①置换规则
    ②换名规则
    ③代替规则 
    3.前束范式 
    4.推理理论
    ①推理的形式结构
    ②推理正确
    ③构造证明
    ④新的推理规则
         全称量词消去规则,记为UI
         全称量词引入规则,记为UG
         存在量词消去规则,记为EI
         存在量词引入规则,记为EG 
      
      

    学习要求


    1.深刻理解重要的等值式,并能熟练地使用它们。 
    2.熟练地使用置换规则、换名规则和代替规则。 
    3.准确地求出给定公式的前束范式(形式可不唯一)。 
    4.正确地使用UI、UG、EI、EG规则,特别地要注意它们之间的关系。 
    5.对于给定的推理,正确地构造出它的证明。

    一阶逻辑等值式与置换规则

    定义5.1 设A,B是一阶逻辑中任意两个公式,若AB是永真式,则称A与B是等值。记做AB,称AB是等值式

    谓词逻辑中关于联结词的等值式与命题逻辑中相关等值式类似。下面主要讨论关于量词的等值式。

    基本等值式

    第一组 代换实例

     由于命题逻辑中的重言式的代换实例都是一阶逻辑中的永真式,因而第二章的16组等值式给出的代换实例都是一阶逻辑的等值式的模式。例如:
            xF(x)┐┐xF(x)
            xy(F(x,y)→G(x,y))┐┐xy(F(x,y)→G(x,y))
    等都是(2.1)式的代换实例。又如:

            F(x)→G(y)┐F(x)∨G(y)
            x(F(x)→G(y))→zH(z)x(F(x)→G(y))∨zH(z))
    等都是(2.1)式的代换实例。

    第二组 消去量词等值式

    设个体域为有限域D={a1,a2,…,an},则有
        (1)xA(x)A(a1)∧A(a2)∧…∧A(an)
        (2)xA(x)A(a1)∨A(a2)∨…∨A(an) .........................(5.1) 

    第三组 量词否定等值式

    设A(x)是任意的含有自由出现个体变项x的公式,则
        (1)┐xA(x)x┐A(x)
        (2)┐xA(x)x┐A(x)  .........................(5.2) 
    (5.2)式的直观解释是容易的。对于(1)式,“并不是所有的x都有性质A”与“存在x没有性质A”是一回事。对于(2)式,“不存在有性质A的x”与“所有x都没有性质A”是一回事。

    第四组 量词辖域缩收与扩张等值式

    设A(x)是任意的含自由出现个体变项x的公式,B中不含x的出现,则
        (1)x(A(x)∨B)xA(x)∨B
           x(A(x)∧B)xA(x)∧B
           x(A(x)→B)xA(x)→B
           x(B→A(x))B→xA(x).........................(5.3) 
        (2)x(A(x)∨B)xA(x)∨B
           x(A(x)∧B)xA(x)∧B
           x(A(x)→B)xA(x)→B
           x(B→A(x))B→xA(x).........................(5.4) 
        注意:这些等值式的条件。

    第五组 量词分配等值式

       设A(x),B(x)是任意的含自由出现个体变项x的公式,则
        (1)x(A(x)∧B(x))xA(x)∧xB(x)
        (2)x(A(x)∨B(x))xA(x)∨xB(x) .........................(5.5) 

    基本规则

    1.置换规则

        设Φ(A)是含公式A的公式,Φ(B)是用公式B取代Φ(A)中所有的A之后的公式,若AB,则Φ(A)Φ(B).

        一阶逻辑中的置换规则与命题逻辑中的置换规则形式上完全相同,只是在这里A,B是一阶逻辑公式。

    2.换名规则

        设A为一公式,将A中某量词辖域中某约束变项的所有出现及相应的指导变元改成该量词辖域中未曾出现过的某个体变项符号,公式的其余部分不变,设所得公式为A',则A'A.

    3.代替规则     设A为一公式,将A中某个自由出现的个体变项的所有出现用A中未曾出现过的个体变项符号代替,A中其余部分不变,设所得公式为A',则A'A.

    等值演算

    例5.1 将下面公式化成与之等值的公式,使其没有既是约束出现又是自由出现的个体变项。
        (1)xF(x,y,z)→yG(x,y,z)
        (2)x(F(x,y)→yG(x,y,z))

         (1)xF(x,y,z)→yG(x,y,z)
            tF(t,y,z)→yG(x,y,z)    (换名规则)
            tF(t,y,z)→wG(x,w,z)    (换名规则)
    原公式中,x,y都是既约束出现又有自由出现的个体变项,只有z仅自由出现。而在最后得到的公式中,x,y,z,t,w中再无既是约束出现又有自由出现个体变项了。还可以如下演算,也可以达到要求。
             xF(x,y,z)→yG(x,y,z)
          xF(x,t,z)→yG(x,y,z)     (代替规则)
          xF(x,t,z)→yG(w,y,z)     (代替规则)

        (2)x(F(x,y)→yG(x,y,z))
        x(F(x,t)→yG(x,y,z))       (代替规则)
    或者
            x(F(x,y)→yG(x,y,z))
         x(F(x,y)→tG(x,t,z))       (换名规则)

    例5.2   证明
        (1)x(A(x)∨B(x))xA(x)∨xB(x)
        (2)x(A(x)∧B(x))xA(x)∧xB(x)
    其中A(x),B(x)为含x自由出现的公式。

         (1)只要证明在某个解释下两边的式子不等值。
        取解释I:个体域为自然数集合N;取F(x):x是奇数,代替A(x);取G(x):x是偶数,代替B(x). 则x(F(x)∨G(x))为真命题,而x F(x)∨x G(x)为假命题。两边不等值。

        对于(2)可以类似证明。 例5.2说明,全称量词""对"∨"无分配律。同样的,存在量词""对"∧"无分配律。但当B(x)换成没有x出现的B时,则有

            x(A(x)∨B)xA(x)∨B
            x(A(x)∧B)xA(x)∧B

    这是式(5.3)和式(5.4)中出现的两个等值式。

    例5.3 设个体域为D={a,b,c},将下面各公式的量词消去:
        (1)x(F(x)→G(x))
        (2)x(F(x)∨yG(y))
        (3)xyF(x,y)

        解 (1) x(F(x)→G(x))    (F(a)→G(a))∧(F(b)→G(b))∧(F(c)→G(c))

          (2) x(F(x)∨yG(y))
          xF(x,a)∨yG(y)                       (公式5.3)
          (F(a)∧F(b)∧F(c))∨(G(a)∨G(b)∨G(c))

    如果不用公式(5.3)将量词的辖域缩小,演算过程较长。注意,此时yG(y)是与x无关的公式B.

        (3) xyF(x,y) x(F(x,a)∧F(x,b)∧F(x,c)) (F(a,a)∧F(a,b)∧F(a,c))∨(F(b,a)∧F(b,b)∧F(b,c))∨(F(c,a)∧F(c,b)∧F(c,c))
    在演算中先消去存在量词也可以,得到结果是等值的。

    一阶逻辑的前束范式

    一阶逻辑公式的标准形——前束范式

    定义5.2 设A为一个一阶逻辑公式,若A具有如下形式
                               Q1x1Q2x2…QkxkB
    则称A为前束范式,其中Qi(1≤i≤k)为,B为不含量词的公式。

        例如,   xy(F(x)∧G(y)→H(x,y))
                 xyz(F(x)∧G(y)∧H(z)→L(x,y,z))

    等公式都是前束范式,而
                 x(F(x)→y(G(y)∧H(x,y)))
                 x(F(x)∧y(G(y)→H(x,y)))
    等都不是前束范式。

    可证明每个一阶逻辑公式都能找到与之等价的前束范式。

    定理5.1 (前束范式存在定理)一阶逻辑中的任何公式都存在与之等值的前束范式。

    下面用一阶逻辑的等值演算求前束范式。

    例5.6 求下面公式的前束范式:
        (1)xF(x)∧┐xG(x)
        (2)xF(x)∨┐xG(x)

         (1)xF(x)∧┐xG(x)
            xF(x)∧┐yG(y)   (换名规则)
            xF(x)∧y┐G(y)   ((5.2)第二式)
            x(F(x)∧y┐G(y)) ((5.3)第二式)
            xy(F(x)∧┐G(y)) ((5.3)第二式)     
    或者
              xF(x)∧┐xG(x)
           xF(x)∧x┐G(x)    ((5.2)第二式)
           xy(F(x)∧┐G(x))  ((5.5)第一式)
    由此可知,(1)中公式的前束范式是不唯一的。

        另外,yx(F(x)∧┐G(y))

    也是(1)中公式的前束范式。

        (2)xF(x)∨┐xG(x)
        xF(x)∨x┐G(x)   ((5.2)第二式)
        xF(x)∨y┐G(y)   (换名规则)
        x(F(x)∨y┐G(y)) ((5.3)第一式)
        xy(F(x)∨┐G(x)) ((5.3)第一式)

        问:(2)的下述求法是否正确?
           xF(x)∨┐xG(x)
        xF(x)∨x┐G(x)
        x(F(x)∨┐G(y))

    一阶逻辑推理理论

    等值演算理论,本节进一步讨论推理理论。

    推理定律

    第一组 命题逻辑推理定律的代换实例。例如:
            xF(x)∧yG(y)xF(x)
            xF(x)xF(x)∨yG(y)∨…
    分别为命题逻辑中化简律和附加律的代换实例。

        第二组 由基本等值式生成的推理定律。上一节给出的两组等值式中的每个等值式可生成两个推理定律。例如:
            xF(x)┐┐xF(x)
            ┐┐xF(x)xF(x)

     和
            ┐xF(x)x┐F(x)
            x┐F(x)xF(x)
    分别由双重否定律和量词否定等值式生成。

        第三组 还有下面各重要推理定律。例如:
        (1)xA(x)∨xB(x)x(A(x)∨B(x))
        (2)x(A(x)∧B(x))xA(x)∧xB(x)
        (3)x(A(x)→B(x))x A(x)→x B(x)
        (4)x(A(x)→B(x))xA(x)→xB(x)

    推理规则

    1.全称量词消去规则(简记为UI规则或UI)
                
    两式成立的条件是:
        (1)在第一式中,取代x的y应为任意的不在A(x)中约束出现的个体变项。
        (2)在第二式中,c为任意个体变项。
        (3)用y或c去取代A(x)中自由出现的x时,一定要在x自由出现的一切地方进行取代。


         2.全称量词引入规则(简记为UG规则或UG)
              

    该式成立的条件是:
        (1)无论A(y)中自由出现的个体变项y取何值,A(y)应该均为真。
        (2)取代自由出现的y的x也不能在A(y)中约束出现。
         3.存在量词引入规则(简称EG规则或EG)
              

    该式成立的条件是:
        (1)c是特定的个体常项。
        (2)取代c的x不能在A(c)中出现过。
         4.存在量词消去规则(简记为EI规则或EI)
                 
    该式成立的条件是:
        (1)c是使A为真的特定的个体常项。
        (2)c不在A(x)中出现。
        (3)若A(x)中除自由出现的x外,还有其它自由出现的个体变项,此规则不能使用。

    一阶逻辑自然推理系统F

    定义5.3 自然推理系统F定义如下:
        1 字母表。同一阶语言的字母表(见定义4.1)。
        2 合式公式。同合式公式的定义(见定义4.1)。
        3 推理规则:
        (1) 前提引入规则。
        (2) 结论引入规则。
        (3) 置换规则。
        (4) 假言推理规则。
        (5) 附加规则。
        (6) 化简规则。
        (7) 拒取式规则。
        (8) 假言三段论规则。
        (9) 析取三段论规则。
        (10)构造性二难推理规则。
        (11)合取引入规则。
        (12)UI规则。
        (13)UG规则。
        (14)EI规则。
        (15)EG规则。

        F中的推理过程类似命题演算自然推理系统P。

    例5.8 设个体域为实数集合,F(x,y)为x>y. 指出在推理系统F中,以xyF(x,y)(真命题)为前提,推出xF(x,c)(假命题)的下述推理证明中的错误。
        ① xyF(x,y) 前提引入
        ② yF(z,y)    ①UI规则
        ③ F(z,c)       ②EI规则
        ④ xF(x,c)    ③UG规则

         由于c为特定的个体常项,所以xF(x,c)(即为x(x>c))为假命题。如果按F中推理规则进行推理,不会从真命题推出假命题。在以上推理证明中,第三步错了,由于F(z,y)中除有自由出现的y,还有自由出现的z,按EI规则应该满足的条件(3),此处不能用EI规则。用了EI规则,导致了从真命题推出假命题的错误。

     例5.9 在自然推理系统F中,构造下面推理的证明:
        任何自然数都是整数;存在着自然数。所以存在着整数。个体域为实数集合R

         先将原子命题符号化。
        设 F(x):x为自然数,G(x):x为整数。
        前提:x(F(x)→G(x)), xF(x)
        结论:xG(x)
        证明:

        ① xF(x)         前提引入
        ② F(c)            ①EI规则
        ③ x(F(x)→G(x)) 前提引入
        ④ F(c)→G(c)      ③UI规则
        ⑤ G(c)            ②④假言推理
        ⑥ xG(x)         ⑤EG规则
        以上证明的每一步都是严格按推理规则及应满足的条件进行的。因此,前提的合取为真时,结论必为真。但如果改变命题序列的顺序会产生由真前提推出假结论的错误。如果证明如下进行:
        ① x(F(x)→G(x)) 前提引入
        ② F(c)→G(c)      ①UI规则
        ③ xF(x)         前提引入
        ④ F(c)            ③E1规则
    在②中取c=,则F()→G()为真(前件假),于是④中F()为假,这样从前件真推出了假的中间结果。


    习题

    1.设个体域D={a,b,c},消去下列各式的量词:
      (1) xy(F(x)∧G(y))
      (2) xy(F(x)∨G(y))
      (3) xF(x)→yG(y)
      (4) x(F(x,y)→yG(y))
    2.设个体域D={1,2},请给出两种不同的解释I1I2,使得下面公式在I1下都是真命题,而在I2下都是假命题。
      (1) x(F(x)→G(x))
      (2) x(F(x)∧G(x))
    3.给定解释I如下:
      (a) 个体域D={3,4}。
      (b) (x)为(3)=4,(4)=3。
      (c) (x,y)为(3,3)=(4,4)=0,(3,4)=(4,3)=1。

    试求下列公式在 I下的真值:
      (1) x yF(x,y)
      (2) x yF(x,y)
      (3) x y(F(x,y)→F(f(x),f(y)))
    4.在自然推理系统 F中构造下面推理的证明:
      (1) 前提: x(F(x)→(G(a)∧R(x))), xF(x)
          结论: x(F(x)∧R(x))
      (2) 前提: x(F(x)∨G(x)),┐ xG(x)
          结论: xF(x)
      (3) 前提: x(F(x)∨G(x)), x(┐G(x)∨┐R(x)), xR(x)
          结论: xF(x)
    5.在自然推理系统 F中,证明下面推理:
      (1) 每个有理数都是实数,有的有理数是整数,因此有的实数是整数。
      (2) 有理数、无理数都是实数,虚数不是实数,因此虚数既不是有理数、也不是无理数。
      (3) 不存在能表示成分数的无理数,有理数都能表示成分数,因此有理数都不是无理数。

     

    答案

    1.
    (1) xy(F(x)∧G(y))
     xF(x)∧yG(y)
     (F(a)∧F(b))∧F(c))∧(G(a)∨G(b)∨G(c))
    (2) xy(F(x)∨G(y))
     xF(x)∨yG(y)
     (F(a)∧F(b)∧F(c))∨(G(a)∧G(b)∧G(c))
    (3) xF(x)→yG(y)
     (F(a)∧F(b)∧F(c))→(G(a)∧G(b)∧G(c))
    (4) x(F(x,y)→yG(y))
     xF(x,y)→yG(y)
     (F(a,y)∨F(b,y)∨F(c,y))→(G(a)∨G(b)∨G(c))

    2.(1)
    I1: F(x):x≤2,G(x):x≤3
    F(1),F(2),G(1),G(2)均为真,所以
       x(F(x)→G(x))
    (F(1)→G(1)∧(F(2)→G(2))为真。
    I2: F(x)同I1,G(x):x≤0
    则F(1),F(2)均为真,而G(1),G(2)均为假,
    x(F(x)→G(x))为假。
    (2)留给读者自己做。

    3.

    (1) xyF(x,y) (F(3,3)∨F(3,4))∧(F(4,3)∨F(4,4)) (0∨1)∧(1∨0)1
    (2) xyF(x,y) (F(3,3)∧F(3,4))∨(F(4,3)∧F(4,4)) (0∧1)∨(1∧0)0
    (3) xy(F(x,y)→F(f(x),f(y)))
     (F(3,3)→F(f(3),f(3)))∧(F(4,3)→F(f(4),f(3)))∧(F(3,4)→F(f(3),f(4)))∧(F(4,4)→F(f(4),f(4)))
     (0→0)∧(1→1)∧(1→1)∧(0→0)1

    4.(1)

    证明:xF(x)前提引入
     ② F(c)①EI
     x(F(x)→(G(a)∧(R(x)))前提引入
     ④ F(c)→(G(a)∧R(c))④UI
     ⑤ G(a)∧R(c)②④假言推理
     ⑥ R(c)⑤化简
     ⑦ F(c)∧R(c)②⑥合取
     x(F(x)∧R(x))⑥EG

    (2)
    证明:① ┐xG(x)前提引入
     x┐G(x)①置换
     ③ ┐G(c)②UI
     x(F(x)∨G(x)前提引入
     ⑤ F(c)∨G(c)④UI
     ⑥ F(c)③⑤析取三段论
     xF(x)⑥EG

    (3)
    证明:x(F(x)∨G(x))前提引入
     ② F(y)∨G(y)①UI
     x(┐G(x)∨┐R(x))前提引入
     ④ ┐G(y)∨┐R(y)③UI
     xR(x)前提引入
     ⑥ R(y)⑤UI
     ⑦ ┐G(y)④⑥析取三段论
     ⑧ F(y)②⑦析取三段论
     xF(x)UG

    5.(1)

    设F(x):x为有理数,R(x):x为实数,G(x):x是整数。
    前提:x(F(x)→R(x)),x(F(x)∧G(x))
    结论:x(R(x)∧G(x))
    证明:x(F(x)∧G(x))前提引入
     ② F(c)∧G(c)①EI
     ③ F(c)②化简
     ④ G(c)②化简
     x(F(x)→R(x))前提引入
     ⑥ F(c)→R(c)⑤UI
     ⑦ R(c)③⑥假言推理
     ⑧ R(c)∧G(c)④⑦合取
     x(R(x)∧G(x))⑧EG

    (2)
    设:F(x):x为有理数,G(x):x为无理数,R(x)为实数,    H(x)为虚数
    前提:x((F(x)∨G(x))→R(x)),x(H(x)→┐R(x))
    结论:x(H(x)→(┐F(x)∧┐G(x)))
    证明:x((F(x)∨G(x)→R(x))前提引入
      F(y)∨G(y))→R(y)UI
     x(H(x)→┐R(x))前提引入
      H(y)→┐R(y)UI
      ┐R(y)→┐(F(y)∨G(y))置换
      H(y)→┐(F(y)∨G(y))④⑤假言三段论
      H(y)→(┐F(y)∧┐G(y))置换
     x(H(x)→(┐F(x)∧┐G(x)))UG

    (3)
    设:F(x):x能表示成分数, G(x):x为无理数,        H(x)为有理数
    前提:x(G(x)→┐F(x)),x(H(x)→F(x))
    结论:x(H(x)→┐G(x))
    证明:x(H(x)→F(x))前提引入
      H(y)→F(y)UI
     x(G(x)→┐F(x))前提引入
      G(y)→┐F(y)UI
      F(y)→┐G(y)置换
      H(y)→┐G(y)②⑤假言三段论
     x(H(x)→┐G(x))UG



    关于Discrete Mathematics更多讨论与交流,敬请关注本博客和新浪微博songzi_tea.


    展开全文
  • 逻辑的偷换概念谈起

    千次阅读 2019-05-19 13:57:00
    本次讲讲逻辑的偷换概念, 因为偷换概念这个坏的很的糟老头出现在当今生活的各方各面(各种媒体通过各种媒介传播的各种信息内容)的频次实在是太高了(潜匿于各种精神爽文); 他无处不在, 他兴风作浪, 他作恶多端, ...
  • 6.for i in range(2,n):if n%i==0:breakif i==n-1:print('是素数')...8.对于有else子句的for循环和while循环,但循环因循环条件不成立而自然结束时__会__(会或不会)执行else的代码。10.已知x='hello world.',那...
  • android面试经典的75道逻辑思维题

    万次阅读 2016-04-20 20:50:28
    在这里说说面试逻辑思维题,我在面试的时候,碰到不少的逻辑思维题,很多都是只是单纯的换了数字,但是如果没有接触过逻辑题目的话,我相信你 肯定和我一样分分钟爆炸团灭。。。。。。 我在这里说说,我刚开始...
  • 一阶逻辑基本概念

    万次阅读 2015-04-21 20:43:48
    设A为一个公式,若A在任何解释下均为真,则称A为永真(或称逻辑有效)。若A在任何解释下均为假,则称A为矛盾(或永假)。若至少存在一个解释使A为真,则称A为可满足。设A0是含有命题变项p1,p2,…,pn的命题公式...
  • 命题逻辑的推理理论

    万次阅读 2015-04-18 19:40:52
    数理逻辑的主要任务是用数学的方法来研究数学的推理。所谓推理是指从前提出发推出结论的思维过程,而前提是已知命题公式集合,结论是从前提出发应用推理规则推出的命题公式。要研究推理就应该给出推理的形式结构,...
  • 命题逻辑基本概念

    万次阅读 2015-04-14 07:46:00
    由于简单命题是真值唯一确定的命题逻辑中最基本的研究单位,所以也称简单命题为命题常项或命题常元。从本节开始对命题进一步抽象,首先称真值可以变化的陈述句为命题变项或命题变元,也用p,q,r,…表示命题变项。当p,...
  • 什么是同步逻辑和异步逻辑,同步电路和异步电路的区别是什么
  • 第一组:命题逻辑中基本等值的代换实例 第二组:一阶逻辑中的重要公式 (1)在有限个体域的重要等值 设个体域D={a₁,a₂,…,an},则:∀xA(x)⇔A(a₁)∧A(a₂)∧…∧A(an),∃xA(x)⇔A(a₁)∨A(a₂)∨…∨A...
  • 计算理论入门 1.1 命题逻辑

    万次阅读 2017-08-01 19:20:03
    在命题逻辑中,我们将命题看做基础,看看我们能做什么。 既然这是数学,我们需要能够谈论命题,而不是说我们在说什么特定的命题,所以我们用符号来代表它们。 我们始终使用小写字母,如p,q和r来表
  • 组合逻辑设计

    千次阅读 2007-07-26 13:53:00
    数字逻辑设计可以归纳为由下列步骤组成:• 问题的确定。• 产生实现逻辑函数的逻辑网络。• 网络的构造。• 逻辑电路的测试与验证。本章我们将讨论逻辑设计的基础。它是讨论大系统设计的基础。3.1 问题的确定正确地...
  • 接上文 游戏开发的人工智能(十):模糊逻辑本文内容:技术上而言,有限状态机和模糊逻辑都落在基于规则的方法这个大伞之下。本章将谈这些方法,以及其他变化的方法。规则 AI本章我们要研讨基于规则的 AI 系统。...
  • 模态逻辑

    千次阅读 2008-11-14 14:56:00
    模态逻辑,或者叫(不很常见)内涵逻辑,是处理用模态如“可能”、“或许”、“可以”、“一定”、“必然”等限定的句子的逻辑。模态逻辑可以用语义的“内涵性”来描述其特征: 复杂公式的真值不能由子公式的真值来决定...
  • 75道面试逻辑智力测试题内附详细答案

    万次阅读 多人点赞 2018-01-15 20:47:19
    设杯子编号为ABCDEF,ABC为满,DEF为空,把B的水倒进E即可。 【3】三个小伙子同时爱上了一个姑娘,为了决定他们谁能娶这个姑娘,他们决定用手枪进行一次决斗。小李的命中率是30%,小黄比他好些,命中率是50...
  • 【清华大学】《逻辑学概论》笔记

    千次阅读 多人点赞 2020-09-04 01:32:03
    教学视频来源 概要 讲师介绍 陈为蓬 清华大学人文学院 副教授 ...第9讲 传统逻辑中基本命题的推理 第10讲 基本命题的推理 第11讲 非经典逻辑的初步 第12讲 余论 第1讲 什么是逻辑学? 1.1 “逻辑逻辑学 什么是逻辑
  • 数字电路信号逻辑电平标准详解

    万次阅读 2019-05-03 21:00:34
    信号的逻辑电平经历了从单端信号到差分信号、从低速信号到高速信号的发展过程。最基本的单端信号逻辑电平为CMOS、... 而什么是逻辑电平呢,个人的理解是,在数字电路的高低电平都是相对与某个特定的电压来说的,...
  • 马尔科夫逻辑网络

    千次阅读 2018-11-15 14:30:09
    马修 理查德森(mattr@cs.washington.edu) 和佩德罗 多明戈斯 (pedrod@cs....马尔科夫逻辑网就是一个每个准则或语句都有权重的一阶逻辑知识库,其中常数代表库对象,还约定了一个基本马尔科夫网知识库中一个一阶...
  • OWL与描述逻辑

    千次阅读 2012-05-10 20:11:15
    描述逻辑(DescriptionLogic)是基于对象...在众多知识表示的形式化方法,描述逻辑在十多年来受到人们的特别关注,主要原因在于:它们有清晰的模型-理论机制;很适合于通过概念分类学来表示应用领域;并提供了很多有用
  • 数字电子技术逻辑运算

    千次阅读 2020-04-23 01:45:49
    数字电子技术学习笔记第一章 数制与编码第二章 基本逻辑运算与集成逻辑门2.1 基本概念2.1.1逻辑变量与逻辑函数2.1.2真值表2.2 三种基本逻辑运算2.2.1与逻辑(与运算、逻辑乘)2.2.2 或逻辑(或运算、逻辑加)2.2.3 ...
  • 文章目录KBA(Knowledge based agent)与逻辑KBAWumpus世界知识库KB的完备性、可靠性命题逻辑:一种简单逻辑语法语义区分⇒和╞命题逻辑定理的证明推导和证明归结证明(只针对文字的析取:子句)单元归结全归结合取...
  • 逻辑思维训练500题

    万次阅读 多人点赞 2014-12-14 14:57:04
    逻辑思维训练500题(修订版) 正文前序:思维训练让你更高、更强! 前 言 第一章 假设法 第二章 计算法 第三章 排除法 第四章 分析法 第五章 观察法 ...
  • 职场逻辑能力提升

    千次阅读 2017-05-08 16:33:30
    为什么逻辑能力强的人看上去更有“大公司的范儿”? 好逻辑就是最科学的逻辑吗? “沟通的逻辑”与“思考的逻辑”有什么不同?为什么真正的沟通高手,说话的理解难度都是小学水平的?到底是什么阻碍了我们,说出一句...
  • 逻辑思维题

    千次阅读 2020-06-01 23:12:43
    那么下列的评论正确的是: a.所有老鼠都偷了奶酪; b.所有的老鼠都没有偷奶酪; c.有些老鼠没偷奶酪; d.老鼠B偷了一颗樱桃。 11.一句问路的话 一个人站在岔道口,分别通向A国和B国,这两个国家的人非常奇怪,A...
  • 数理逻辑—推理理论

    千次阅读 2019-04-28 23:46:30
    1 推理的通俗解释 ...构造证明法是按照给定的规则进行,其中有些规则建立在推理定律(即重言蕴含)的基础之上。 推理定律: 推理定律 名称 A⇒(A∨B)A\Rightarrow(A\lor B)A⇒(...
  • CMOS逻辑电路

    千次阅读 2007-07-26 13:56:00
    下载第6章CMOS逻辑电路现在我们已经学习了逻辑网络的理论和实践这两个方面的内容,下一步我们将看看如何用称为C M O S的工艺来产生现代数字逻辑网络。这种特殊的逻辑种类可使我们在一小片硅片上设计出极其密集的数字...
  • 逻辑推理系统

    千次阅读 2005-07-23 15:32:00
    逻辑推理系统,即Logical Reasoning Systems,我们都知道,逻辑既有诱人的优点,又有恼人的缺点,就优点方面而言,逻辑观念因为已经发展了好几个世纪,所以它是一个简单明了而又普遍能懂的工具,当一个问题经过逻辑...
  • 实验一 组合逻辑电路的设计与测试

    千次阅读 2021-04-20 01:12:14
    目录一、实验预习要求二、实验目的三、实验原理四、实验设备与器件五、实验内容与步骤六、实验报告要求...组合逻辑电路的设计就是根据给定的逻辑要求,设计出能够实现该功能的最佳组合逻辑电路,一般按下列步骤进行设计

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 34,052
精华内容 13,620
关键字:

下列逻辑式中正确的是